mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 23:29:58 -07:00
general: snapshot
This commit is contained in:
3
app/src/scripts/datasets/types.d.ts
vendored
3
app/src/scripts/datasets/types.d.ts
vendored
@@ -34,6 +34,9 @@ interface ResourceDataset<
|
||||
drop: VoidFunction;
|
||||
}
|
||||
|
||||
type AnyDataset<Scale extends ResourceScale> = Dataset<Scale> &
|
||||
Partial<ResourceDataset<Scale>>;
|
||||
|
||||
interface FetchedResult<
|
||||
Scale extends ResourceScale,
|
||||
Type extends number | OHLC,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { chartState } from "./state";
|
||||
|
||||
export function cleanChart() {
|
||||
console.log("chart: clean");
|
||||
|
||||
try {
|
||||
chartState.chart?.remove();
|
||||
} catch {}
|
||||
|
||||
chartState.chart = null;
|
||||
}
|
||||
@@ -5,14 +5,14 @@ import {
|
||||
} from "lightweight-charts";
|
||||
|
||||
import { colors } from "../../utils/colors";
|
||||
import { priceToUSLocale } from "../../utils/locale";
|
||||
import { cleanChart } from "./clean";
|
||||
import { valueToString } from "../../utils/locale";
|
||||
import { HorzScaleBehaviorHeight } from "./horzScaleBehavior";
|
||||
import { chartState } from "./state";
|
||||
|
||||
export function createChart(scale: ResourceScale) {
|
||||
cleanChart();
|
||||
|
||||
export function createChart(
|
||||
scale: ResourceScale,
|
||||
element: HTMLElement,
|
||||
priceScaleOptions?: DeepPartialPriceScaleOptions,
|
||||
) {
|
||||
console.log(`chart: create (scale: ${scale})`);
|
||||
|
||||
const { white } = colors;
|
||||
@@ -29,19 +29,19 @@ export function createChart(scale: ResourceScale) {
|
||||
vertLines: { visible: false },
|
||||
horzLines: { visible: false },
|
||||
},
|
||||
leftPriceScale: {
|
||||
// borderColor: white,
|
||||
},
|
||||
rightPriceScale: {
|
||||
// borderColor: white,
|
||||
borderColor: "#332F24",
|
||||
},
|
||||
timeScale: {
|
||||
borderColor: "#332F24",
|
||||
minBarSpacing: scale === "date" ? 0.05 : 0.005,
|
||||
shiftVisibleRangeOnNewBar: false,
|
||||
allowShiftVisibleRangeOnWhitespaceReplacement: false,
|
||||
},
|
||||
handleScale: {
|
||||
axisDoubleClickReset: false,
|
||||
axisDoubleClickReset: {
|
||||
time: false,
|
||||
},
|
||||
},
|
||||
crosshair: {
|
||||
mode: CrosshairMode.Normal,
|
||||
@@ -55,17 +55,31 @@ export function createChart(scale: ResourceScale) {
|
||||
},
|
||||
},
|
||||
localization: {
|
||||
priceFormatter: priceToUSLocale,
|
||||
priceFormatter: valueToString,
|
||||
locale: "en-us",
|
||||
},
|
||||
};
|
||||
|
||||
let chart: IChartApi;
|
||||
|
||||
if (scale === "date") {
|
||||
chartState.chart = createClassicChart("chart", options);
|
||||
chart = createClassicChart(element, options);
|
||||
} else {
|
||||
const horzScaleBehavior = new HorzScaleBehaviorHeight();
|
||||
|
||||
// @ts-ignore
|
||||
chartState.chart = createCustomChart("chart", horzScaleBehavior, options);
|
||||
chart = createCustomChart(element, horzScaleBehavior, options);
|
||||
}
|
||||
|
||||
chart.priceScale("right").applyOptions({
|
||||
...priceScaleOptions,
|
||||
scaleMargins: {
|
||||
top: 0.05,
|
||||
bottom: 0.05,
|
||||
...priceScaleOptions?.scaleMargins,
|
||||
},
|
||||
minimumWidth: 78,
|
||||
});
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { colors } from "/src/scripts/utils/colors";
|
||||
import { priceToUSLocale } from "/src/scripts/utils/locale";
|
||||
import { ONE_DAY_IN_MS } from "/src/scripts/utils/time";
|
||||
|
||||
import { chartState } from "./state";
|
||||
@@ -101,12 +100,11 @@ export const setMinMaxMarkers = ({
|
||||
candle &&
|
||||
markers.push({
|
||||
...markerOptions,
|
||||
// date: candle.date,
|
||||
number: candle.number,
|
||||
time: candle.time,
|
||||
color: lowerOpacity ? colors.darkWhite : colors.white,
|
||||
size: 0,
|
||||
text: priceToUSLocale(value),
|
||||
text: value.toLocaleString("en-us"),
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { colors } from "../../utils/colors";
|
||||
import { getNumberOfDaysBetweenTwoDates } from "../../utils/date";
|
||||
import { debounce } from "../../utils/debounce";
|
||||
import { webSockets } from "../../ws";
|
||||
import { createCandlesticksSeries } from "../series/creators/candlesticks";
|
||||
import { createSeriesLegend } from "../series/creators/legend";
|
||||
import { createLineSeries } from "../series/creators/line";
|
||||
import { setMinMaxMarkers } from "./markers";
|
||||
import { chartState } from "./state";
|
||||
import { initTimeScale } from "./time";
|
||||
|
||||
export const PRICE_SCALE_MOMENTUM_ID = "momentum";
|
||||
@@ -18,76 +12,32 @@ export const applyPriceSeries = <
|
||||
T extends SingleValueData,
|
||||
>({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
dataset: _dataset,
|
||||
dataset,
|
||||
seriesType,
|
||||
valuesSkipped,
|
||||
options,
|
||||
activeResources,
|
||||
}: {
|
||||
chart: IChartApi;
|
||||
datasets: Datasets;
|
||||
preset: Preset;
|
||||
valuesSkipped: Accessor<number>;
|
||||
seriesType: Accessor<"Candlestick" | "Line">;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
dataset?: Dataset<Scale, T>;
|
||||
dataset: Dataset<Scale, T>;
|
||||
options?: PriceSeriesOptions;
|
||||
}) => {
|
||||
const id = options?.id || "price";
|
||||
const title = options?.title || "Price";
|
||||
|
||||
const dataset = _dataset || datasets[preset.scale].price;
|
||||
|
||||
const url = "url" in dataset ? (dataset as any).url : undefined;
|
||||
|
||||
const priceScaleOptions: DeepPartial<PriceScaleOptions> = {
|
||||
...(options?.halved
|
||||
? {
|
||||
scaleMargins: {
|
||||
top: 0.05,
|
||||
bottom: 0.55,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(options?.id || options?.title
|
||||
? {}
|
||||
: {
|
||||
mode: 1,
|
||||
}),
|
||||
const priceScaleOptions: DeepPartialPriceScaleOptions = {
|
||||
mode: 1,
|
||||
...options?.priceScaleOptions,
|
||||
};
|
||||
|
||||
const seriesType = createRWS(
|
||||
checkIfUpClose(chart, chartState.range) || "Candlestick",
|
||||
);
|
||||
|
||||
const debouncedCallback = debounce((range: TimeRange | null) => {
|
||||
try {
|
||||
seriesType.set((previous) => checkIfUpClose(chart, range) || previous);
|
||||
} catch {}
|
||||
}, 50);
|
||||
|
||||
chart?.timeScale().subscribeVisibleTimeRangeChange(debouncedCallback);
|
||||
|
||||
onCleanup(
|
||||
() =>
|
||||
chart === chartState.chart &&
|
||||
chartState.chart
|
||||
?.timeScale()
|
||||
.unsubscribeVisibleTimeRangeChange(debouncedCallback),
|
||||
);
|
||||
|
||||
const lowerOpacity = options?.lowerOpacity || options?.halved || false;
|
||||
|
||||
if (options?.halved) {
|
||||
options.seriesOptions = {
|
||||
...options.seriesOptions,
|
||||
priceScaleId: "left",
|
||||
};
|
||||
}
|
||||
|
||||
const [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, {
|
||||
...options,
|
||||
lowerOpacity,
|
||||
});
|
||||
const [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, options);
|
||||
|
||||
const ohlcLegend = createSeriesLegend({
|
||||
id,
|
||||
@@ -103,7 +53,7 @@ export const applyPriceSeries = <
|
||||
|
||||
// ---
|
||||
|
||||
const lineColor = lowerOpacity ? colors.darkWhite : colors.white;
|
||||
const lineColor = colors.white;
|
||||
|
||||
const lineSeries = createLineSeries(chart, {
|
||||
color: lineColor,
|
||||
@@ -139,11 +89,10 @@ export const applyPriceSeries = <
|
||||
|
||||
createEffect(() => {
|
||||
const values = dataset.values();
|
||||
// const values = computeDrawnSeriesValues(dataset.values(), valuesSkipped());
|
||||
|
||||
if (values) {
|
||||
lineSeries.setData(values);
|
||||
ohlcSeries.setData(values);
|
||||
}
|
||||
lineSeries.setData(values);
|
||||
ohlcSeries.setData(values);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
@@ -159,20 +108,3 @@ export const applyPriceSeries = <
|
||||
|
||||
return { ohlcLegend, lineLegend };
|
||||
};
|
||||
|
||||
function checkIfUpClose(chart: IChartApi, range?: TimeRange | null) {
|
||||
if (!range) return undefined;
|
||||
|
||||
const from = new Date(range.from);
|
||||
const to = new Date(range.to);
|
||||
|
||||
const width = chart.timeScale().width();
|
||||
|
||||
const difference = getNumberOfDaysBetweenTwoDates(from, to);
|
||||
|
||||
return width / difference >= 2.05
|
||||
? "Candlestick"
|
||||
: width / difference <= 1.95
|
||||
? "Line"
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { createChart } from "./create";
|
||||
import { chartState } from "./state";
|
||||
import { setWhitespace } from "./whitespace";
|
||||
|
||||
export function renderChart({
|
||||
datasets,
|
||||
legendSetter,
|
||||
preset,
|
||||
activeResources,
|
||||
}: {
|
||||
datasets: Datasets;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
preset: Preset;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
const scale = preset.scale;
|
||||
|
||||
createChart(scale);
|
||||
|
||||
const chart = chartState.chart;
|
||||
|
||||
if (!chart) return;
|
||||
|
||||
try {
|
||||
setWhitespace(chart, scale);
|
||||
|
||||
console.log(`preset: ${preset.id}`);
|
||||
|
||||
const legend = preset.applyPreset({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
activeResources,
|
||||
});
|
||||
|
||||
legendSetter(legend);
|
||||
} catch (error) {
|
||||
console.error("chart: render: failed", error);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
interface PriceSeriesOptions {
|
||||
halved?: boolean;
|
||||
placement?: "top" | "bottom";
|
||||
title?: string;
|
||||
id?: string;
|
||||
lowerOpacity?: boolean;
|
||||
inverseColors?: boolean;
|
||||
seriesOptions?: DeepPartial<SeriesOptionsCommon>;
|
||||
priceScaleOptions?: DeepPartial<PriceScaleOptions>;
|
||||
|
||||
@@ -2,25 +2,13 @@ import { colors } from "/src/scripts/utils/colors";
|
||||
|
||||
export const createCandlesticksSeries = (
|
||||
chart: IChartApi,
|
||||
options: PriceSeriesOptions,
|
||||
options: PriceSeriesOptions = {},
|
||||
): [ISeriesApi<"Candlestick">, string[]] => {
|
||||
const { inverseColors, lowerOpacity } = options;
|
||||
const { inverseColors } = options;
|
||||
|
||||
const upColor = lowerOpacity
|
||||
? inverseColors
|
||||
? colors.darkLoss
|
||||
: colors.darkProfit
|
||||
: inverseColors
|
||||
? colors.loss
|
||||
: colors.profit;
|
||||
const upColor = inverseColors ? colors.loss : colors.profit;
|
||||
|
||||
const downColor = lowerOpacity
|
||||
? inverseColors
|
||||
? colors.darkProfit
|
||||
: colors.darkLoss
|
||||
: inverseColors
|
||||
? colors.profit
|
||||
: colors.loss;
|
||||
const downColor = inverseColors ? colors.profit : colors.loss;
|
||||
|
||||
const candlestickSeries = chart.addCandlestickSeries({
|
||||
baseLineVisible: false,
|
||||
@@ -34,7 +22,6 @@ export const createCandlesticksSeries = (
|
||||
borderColor: "",
|
||||
borderDownColor: "",
|
||||
borderUpColor: "",
|
||||
// lastValueVisible: false,
|
||||
...options.seriesOptions,
|
||||
});
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ import {
|
||||
} from "/src/scripts/utils/urlParams";
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { chartState } from "../../chart/state";
|
||||
import { setTimeScale } from "../../chart/time";
|
||||
|
||||
export function createSeriesLegend({
|
||||
id,
|
||||
presetId,
|
||||
@@ -44,15 +41,20 @@ export function createSeriesLegend({
|
||||
|
||||
const disabled = createMemo(_disabled || (() => false));
|
||||
|
||||
const drawn = createMemo(() => visible() && !disabled());
|
||||
|
||||
createEffect(() => {
|
||||
const v = visible();
|
||||
const d = disabled();
|
||||
|
||||
series.applyOptions({
|
||||
visible: !d && v,
|
||||
visible: drawn(),
|
||||
});
|
||||
});
|
||||
|
||||
setTimeScale(chartState.range);
|
||||
createEffect(() => {
|
||||
if (disabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const v = visible();
|
||||
|
||||
if (v !== defaultVisible) {
|
||||
writeURLParam(id, v);
|
||||
@@ -70,6 +72,7 @@ export function createSeriesLegend({
|
||||
color,
|
||||
visible,
|
||||
disabled,
|
||||
drawn,
|
||||
url,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
export const resetRightPriceScale = (
|
||||
chart: IChartApi,
|
||||
options?: FullPriceScaleOptions,
|
||||
) => {
|
||||
const finalOptions = {
|
||||
...options,
|
||||
scaleMargins: {
|
||||
...(options?.halved
|
||||
? {
|
||||
top: 0.5,
|
||||
bottom: 0.05,
|
||||
}
|
||||
: {
|
||||
top: 0.1,
|
||||
bottom: 0.1,
|
||||
}),
|
||||
...options?.scaleMargins,
|
||||
},
|
||||
};
|
||||
|
||||
chart.priceScale("right").applyOptions(finalOptions);
|
||||
|
||||
return finalOptions;
|
||||
};
|
||||
|
||||
export const resetLeftPriceScale = (
|
||||
chart: IChartApi,
|
||||
options?: FullPriceScaleOptions,
|
||||
) =>
|
||||
chart.priceScale("left").applyOptions({
|
||||
visible: false,
|
||||
...options,
|
||||
scaleMargins: {
|
||||
...(options?.halved
|
||||
? {
|
||||
top: 0.475,
|
||||
bottom: 0.025,
|
||||
}
|
||||
: {
|
||||
top: 0.25,
|
||||
bottom: 0.25,
|
||||
}),
|
||||
...options?.scaleMargins,
|
||||
},
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
interface FullPriceScaleOptions extends DeepPartial<PriceScaleOptions> {
|
||||
halved?: boolean;
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
} from "../../datasets/consts/address";
|
||||
import { liquidities } from "../../datasets/consts/liquidities";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
import { createCohortPresetList } from "../templates/cohort";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
|
||||
export function createPresets({
|
||||
scale,
|
||||
@@ -22,12 +22,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerWallet,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Non Empty Address`,
|
||||
color: colors.bitcoin,
|
||||
@@ -45,12 +42,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerSparkles,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `New Addresses`,
|
||||
color: colors.white,
|
||||
@@ -67,12 +61,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerArchive,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Addresses Created`,
|
||||
color: colors.bitcoin,
|
||||
@@ -90,12 +81,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerTrash,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Empty Addresses`,
|
||||
color: colors.darkWhite,
|
||||
@@ -191,12 +179,9 @@ export function createAddressCountPreset<Scale extends ResourceScale>({
|
||||
title: `${name} Address Count`,
|
||||
icon: IconTablerAddressBook,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Address Count",
|
||||
color,
|
||||
|
||||
357
app/src/scripts/presets/apply.ts
Normal file
357
app/src/scripts/presets/apply.ts
Normal file
@@ -0,0 +1,357 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { createChart } from "../lightweightCharts/chart/create";
|
||||
import { applyPriceSeries } from "../lightweightCharts/chart/price";
|
||||
import { chartState } from "../lightweightCharts/chart/state";
|
||||
import { setWhitespace } from "../lightweightCharts/chart/whitespace";
|
||||
import { createAreaSeries } from "../lightweightCharts/series/creators/area";
|
||||
import {
|
||||
createBaseLineSeries,
|
||||
DEFAULT_BASELINE_COLORS,
|
||||
} from "../lightweightCharts/series/creators/baseLine";
|
||||
import { createHistogramSeries } from "../lightweightCharts/series/creators/histogram";
|
||||
import { createSeriesLegend } from "../lightweightCharts/series/creators/legend";
|
||||
import { createLineSeries } from "../lightweightCharts/series/creators/line";
|
||||
import { debounce } from "../utils/debounce";
|
||||
import { stringToId } from "../utils/id";
|
||||
|
||||
export enum SeriesType {
|
||||
Normal,
|
||||
Based,
|
||||
Area,
|
||||
Histogram,
|
||||
}
|
||||
|
||||
type SeriesConfig<Scale extends ResourceScale> =
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: undefined;
|
||||
seriesType: SeriesType.Based;
|
||||
title: string;
|
||||
options?: BaselineSeriesOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: string[];
|
||||
seriesType: SeriesType.Histogram;
|
||||
title: string;
|
||||
options?: DeepPartialHistogramOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color: string;
|
||||
colors?: undefined;
|
||||
seriesType?: SeriesType.Normal | SeriesType.Area;
|
||||
title: string;
|
||||
options?: DeepPartialLineOptions;
|
||||
defaultVisible?: boolean;
|
||||
};
|
||||
|
||||
export function applySeriesList<Scale extends ResourceScale>({
|
||||
parentDiv,
|
||||
charts: reactiveChartList,
|
||||
top,
|
||||
bottom,
|
||||
preset,
|
||||
priceScaleOptions,
|
||||
datasets,
|
||||
priceDataset,
|
||||
priceOptions,
|
||||
activeResources,
|
||||
legendSetter,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: HTMLDivElement;
|
||||
preset: Preset;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
priceDataset?: AnyDataset<Scale>;
|
||||
priceOptions?: PriceSeriesOptions;
|
||||
priceScaleOptions?: DeepPartialPriceScaleOptions;
|
||||
top?: SeriesConfig<Scale>[];
|
||||
bottom?: SeriesConfig<Scale>[];
|
||||
datasets: Datasets;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
reactiveChartList.set((charts) => {
|
||||
charts.forEach((chart) => {
|
||||
chart.remove();
|
||||
});
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
parentDiv.replaceChildren();
|
||||
|
||||
const scale = preset.scale;
|
||||
|
||||
const legendList: PresetLegend = [];
|
||||
|
||||
const priceSeriesType = createRWS<"Candlestick" | "Line">("Candlestick");
|
||||
|
||||
const valuesSkipped = createRWS(0);
|
||||
|
||||
const charts = [top || [], bottom]
|
||||
.flatMap((list) => (list ? [list] : []))
|
||||
.flatMap((seriesConfigList, index, array) => {
|
||||
if (index !== 0 && seriesConfigList.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isAnyArea = seriesConfigList.find(
|
||||
(config) => config.seriesType === SeriesType.Area,
|
||||
);
|
||||
|
||||
const div = document.createElement("div");
|
||||
|
||||
div.className = "w-full cursor-crosshair min-h-0 border-orange-200/10";
|
||||
|
||||
parentDiv.appendChild(div);
|
||||
|
||||
const chart = createChart(scale, div, {
|
||||
...priceScaleOptions,
|
||||
...(isAnyArea
|
||||
? {
|
||||
scaleMargins: {
|
||||
bottom: 0,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
chartState.chart = chart;
|
||||
|
||||
if (!chart) {
|
||||
console.log("chart: undefined");
|
||||
return [];
|
||||
}
|
||||
|
||||
setWhitespace(chart, scale);
|
||||
|
||||
const seriesList: ISeriesApi<any>[] = [];
|
||||
|
||||
const _legendList: PresetLegend = [];
|
||||
|
||||
if (index === 0) {
|
||||
const price = applyPriceSeries({
|
||||
chart,
|
||||
preset,
|
||||
seriesType: priceSeriesType,
|
||||
valuesSkipped,
|
||||
dataset:
|
||||
priceDataset ||
|
||||
(datasets[preset.scale as Scale].price as unknown as NonNullable<
|
||||
typeof priceDataset
|
||||
>),
|
||||
activeResources,
|
||||
options: priceOptions,
|
||||
});
|
||||
|
||||
_legendList.push(price.lineLegend, price.ohlcLegend);
|
||||
|
||||
seriesList.push(price.lineLegend.series, price.ohlcLegend.series);
|
||||
}
|
||||
|
||||
seriesList.push(
|
||||
...seriesConfigList
|
||||
.reverse()
|
||||
.map(
|
||||
({
|
||||
dataset,
|
||||
color,
|
||||
colors,
|
||||
seriesType: type,
|
||||
title,
|
||||
options,
|
||||
defaultVisible,
|
||||
}) => {
|
||||
let series: ISeriesApi<
|
||||
"Baseline" | "Line" | "Area" | "Histogram"
|
||||
>;
|
||||
|
||||
if (type === SeriesType.Based) {
|
||||
series = createBaseLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Area) {
|
||||
series = createAreaSeries(chart, {
|
||||
color,
|
||||
autoscaleInfoProvider: (
|
||||
getInfo: () => AutoscaleInfo | null,
|
||||
) => {
|
||||
const info = getInfo();
|
||||
if (info) {
|
||||
info.priceRange.minValue = 0;
|
||||
}
|
||||
return info;
|
||||
},
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Histogram) {
|
||||
series = createHistogramSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else {
|
||||
series = createLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
_legendList.push(
|
||||
createSeriesLegend({
|
||||
id: stringToId(title),
|
||||
presetId: preset.id,
|
||||
title,
|
||||
series,
|
||||
color: () => colors || color || DEFAULT_BASELINE_COLORS,
|
||||
defaultVisible,
|
||||
url: dataset.url,
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
series.setData(
|
||||
dataset?.values() || [],
|
||||
// computeDrawnSeriesValues(dataset?.values(), valuesSkipped()),
|
||||
);
|
||||
});
|
||||
|
||||
return series;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
_legendList.forEach((legend) => {
|
||||
legendList.splice(0, 0, legend);
|
||||
});
|
||||
|
||||
return [{ div, chart, seriesList, legendList: _legendList }];
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
const visibleCharts: typeof charts = [];
|
||||
|
||||
charts.forEach((chart) => {
|
||||
if (chart.legendList.some((legend) => legend.drawn())) {
|
||||
chart.div.style.border = "";
|
||||
visibleCharts.push(chart);
|
||||
} else {
|
||||
chart.div.style.height = "0px";
|
||||
chart.div.style.border = "none";
|
||||
}
|
||||
});
|
||||
|
||||
visibleCharts.forEach(({ div, chart }, index) => {
|
||||
const last = index === visibleCharts.length - 1;
|
||||
|
||||
div.style.height = last ? "100%" : "calc(100% - 62px)";
|
||||
div.style.borderBottomWidth = last ? "none" : "1px";
|
||||
|
||||
chart.timeScale().applyOptions({
|
||||
visible: last,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// const seriesType = createRWS(
|
||||
// checkIfUpClose(chart, chartState.range) || "Candlestick",
|
||||
// );
|
||||
|
||||
function updateVisibleRangeRatio(
|
||||
chart: IChartApi,
|
||||
range: LogicalRange | null,
|
||||
) {
|
||||
if (!range) return;
|
||||
|
||||
try {
|
||||
const width = chart.timeScale().width();
|
||||
|
||||
const ratio = (range.to - range.from) / width;
|
||||
|
||||
if (ratio <= 0.5) {
|
||||
priceSeriesType.set("Candlestick");
|
||||
} else {
|
||||
priceSeriesType.set("Line");
|
||||
|
||||
valuesSkipped.set(Math.floor(ratio / 5));
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const debouncedUpdateVisibleRangeRatio = debounce(
|
||||
updateVisibleRangeRatio,
|
||||
50,
|
||||
);
|
||||
|
||||
charts.forEach(({ chart }, index) => {
|
||||
chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => {
|
||||
// Last chart otherwise length of timescale is Infinity
|
||||
if (index === charts.length - 1) {
|
||||
debouncedUpdateVisibleRangeRatio(chart, timeRange);
|
||||
}
|
||||
|
||||
charts.forEach(({ chart: _chart }, _index) => {
|
||||
if (timeRange && index !== _index) {
|
||||
_chart.timeScale().setVisibleLogicalRange(timeRange);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
chart.subscribeCrosshairMove(({ time, sourceEvent }) => {
|
||||
// Don't override crosshair position from scroll event
|
||||
if (time && !sourceEvent) return;
|
||||
|
||||
charts.forEach(({ chart: _chart, seriesList }, _index) => {
|
||||
const first = seriesList.at(0);
|
||||
|
||||
if (first && index !== _index) {
|
||||
if (time) {
|
||||
_chart.setCrosshairPosition(NaN, time, first);
|
||||
} else {
|
||||
// No time when mouse goes outside the chart
|
||||
_chart.clearCrosshairPosition();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
legendSetter(legendList);
|
||||
|
||||
reactiveChartList.set(() => charts.map(({ chart }) => chart));
|
||||
}
|
||||
|
||||
export function computeDrawnSeriesValues<T>(
|
||||
values: DatasetValue<T>[] | undefined,
|
||||
valuesSkipped: number,
|
||||
) {
|
||||
values = values || [];
|
||||
|
||||
if (valuesSkipped === 0) {
|
||||
return values;
|
||||
} else {
|
||||
const valuesSkippedPlus1 = valuesSkipped + 1;
|
||||
|
||||
// console.log(_valuesSkippedPlus1);
|
||||
|
||||
let length = Math.floor(values.length / valuesSkippedPlus1);
|
||||
|
||||
// console.log(length);
|
||||
|
||||
const filteredValues = new Array(length);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
filteredValues[i] = values[i * valuesSkippedPlus1];
|
||||
}
|
||||
|
||||
// console.log(filteredValues.length);
|
||||
|
||||
return filteredValues;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets() {
|
||||
const scale: ResourceScale = "date";
|
||||
@@ -14,12 +14,9 @@ export function createPresets() {
|
||||
title: "Block Height",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Height",
|
||||
color: colors.bitcoin,
|
||||
@@ -40,19 +37,15 @@ export function createPresets() {
|
||||
title: "Daily Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1d_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -82,19 +75,15 @@ export function createPresets() {
|
||||
title: "Weekly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1w_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -113,18 +102,14 @@ export function createPresets() {
|
||||
title: "Monthly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1m_target,
|
||||
options: {
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
lineStyle: 3,
|
||||
},
|
||||
},
|
||||
@@ -144,19 +129,15 @@ export function createPresets() {
|
||||
title: "Yearly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1y_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -175,12 +156,9 @@ export function createPresets() {
|
||||
title: "Total Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Mined",
|
||||
color: colors.bitcoin,
|
||||
@@ -200,12 +178,9 @@ export function createPresets() {
|
||||
title: "Cumulative Block Size",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Size (MB)",
|
||||
color: colors.darkWhite,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets<Scale extends ResourceScale>({
|
||||
scale,
|
||||
@@ -19,9 +19,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Cointime Prices",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Vaulted Price",
|
||||
color: colors.vaultedness,
|
||||
@@ -61,9 +61,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Active Price",
|
||||
color: colors.liveliness,
|
||||
@@ -85,9 +85,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Vaulted Price",
|
||||
color: colors.vaultedness,
|
||||
@@ -109,9 +109,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "True Market Mean",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "True Market Mean",
|
||||
color: colors.trueMarketMeanPrice,
|
||||
@@ -133,9 +133,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Cointime",
|
||||
color: colors.cointimePrice,
|
||||
@@ -159,16 +159,14 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Capitalizations",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Market Cap",
|
||||
|
||||
color: colors.white,
|
||||
dataset: params.datasets[scale].market_cap,
|
||||
},
|
||||
@@ -198,13 +196,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Thermo Cap",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Thermo Cap",
|
||||
color: colors.thermoCap,
|
||||
@@ -221,13 +218,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Investor Cap",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Investor Cap",
|
||||
color: colors.investorCap,
|
||||
@@ -244,12 +240,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Thermo Cap To Investor Cap Ratio (%)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Ratio",
|
||||
color: colors.bitcoin,
|
||||
@@ -272,12 +265,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Coinblocks",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -304,12 +294,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Created",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -326,12 +313,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Destroyed",
|
||||
color: colors.coinblocksDestroyed,
|
||||
@@ -348,12 +332,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Stored",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Stored",
|
||||
color: colors.coinblocksStored,
|
||||
@@ -375,12 +356,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Cumulative Coinblocks",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -410,12 +388,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Created",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -433,12 +408,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Destroyed",
|
||||
color: colors.coinblocksDestroyed,
|
||||
@@ -456,12 +428,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Stored",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Stored",
|
||||
color: colors.coinblocksStored,
|
||||
@@ -484,12 +453,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness (Activity)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness",
|
||||
color: colors.liveliness,
|
||||
@@ -506,12 +472,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaultedness",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaultedness",
|
||||
color: colors.vaultedness,
|
||||
@@ -528,12 +491,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness V. Vaultedness",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness",
|
||||
color: colors.liveliness,
|
||||
@@ -555,12 +515,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Activity To Vaultedness Ratio",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Activity To Vaultedness Ratio",
|
||||
color: colors.activityToVaultednessRatio,
|
||||
@@ -578,12 +535,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Concurrent Liveliness - Supply Adjusted Coindays Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Concurrent Liveliness 14d Median",
|
||||
color: `${colors.liveliness}66`,
|
||||
@@ -606,12 +560,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness Incremental Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness Incremental Change",
|
||||
color: colors.darkLiveliness,
|
||||
@@ -641,12 +592,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Supply",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaulted Supply",
|
||||
color: colors.vaultedness,
|
||||
@@ -663,12 +611,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Supply",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply",
|
||||
color: colors.liveliness,
|
||||
@@ -685,12 +630,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted V. Active",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -747,12 +689,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaulted Supply Net Change",
|
||||
color: colors.vaultedness,
|
||||
@@ -769,12 +708,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply Net Change",
|
||||
color: colors.liveliness,
|
||||
@@ -791,12 +727,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active VS. Vaulted 90 Day Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply Net Change",
|
||||
color: `${colors.liveliness}80`,
|
||||
@@ -919,12 +852,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Supply In Profit",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -951,12 +881,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Supply In Loss",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -985,13 +912,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime-Adjusted Yearly Inflation Rate (%)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cointime Adjusted",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -1015,13 +941,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime-Adjusted Transactions Velocity",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cointime Adjusted",
|
||||
color: colors.coinblocksCreated,
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
yearCohorts,
|
||||
} from "../../datasets/consts/age";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applySeriesList } from "../apply";
|
||||
import { createCohortPresetFolder } from "../templates/cohort";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
|
||||
export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
return {
|
||||
@@ -20,12 +20,9 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
description: "",
|
||||
icon: IconTablerRipple,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `24h`,
|
||||
color: colors.up_to_1d,
|
||||
|
||||
@@ -48,22 +48,21 @@ export function createPresets(): Presets {
|
||||
],
|
||||
} satisfies PartialPresetFolder,
|
||||
{
|
||||
name: "By Height (Coming soon)",
|
||||
name: "By Height",
|
||||
tree: [
|
||||
// createMarketPresets({ scale: "height", datasets }),
|
||||
// createMinersPresets("height"),
|
||||
// createTransactionsPresets("height"),
|
||||
// ...createCohortPresetList({
|
||||
// datasets,
|
||||
// scale: "height",
|
||||
// color: colors.bitcoin,
|
||||
// name: "",
|
||||
// datasetKey: "",
|
||||
// title: "",
|
||||
// }),
|
||||
// createHodlersPresets({ scale: "height", datasets }),
|
||||
// createAddressesPresets({ scale: "height", datasets }),
|
||||
// createCoinblocksPresets({ scale: "height", datasets }),
|
||||
createMarketPresets({ scale: "height" }),
|
||||
createMinersPresets("height"),
|
||||
createTransactionsPresets("height"),
|
||||
...createCohortPresetList({
|
||||
scale: "height",
|
||||
color: colors.bitcoin,
|
||||
name: "",
|
||||
datasetKey: "",
|
||||
title: "",
|
||||
}),
|
||||
createHodlersPresets({ scale: "height" }),
|
||||
createAddressesPresets({ scale: "height" }),
|
||||
createCoinblocksPresets({ scale: "height" }),
|
||||
],
|
||||
} satisfies PartialPresetFolder,
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { averages } from "/src/scripts/datasets/date";
|
||||
import { colors } from "/src/scripts/utils/colors";
|
||||
|
||||
import { applyMultipleSeries } from "../../templates/multiple";
|
||||
import { applySeriesList } from "../../apply";
|
||||
|
||||
export function createPresets(): PartialPresetFolder {
|
||||
const scale: ResourceScale = "date";
|
||||
@@ -15,9 +15,9 @@ export function createPresets(): PartialPresetFolder {
|
||||
name: "All",
|
||||
title: "All Averages",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: averages.map((average) => ({
|
||||
top: averages.map((average) => ({
|
||||
title: average.key.toUpperCase(),
|
||||
color: colors[`_${average.key}`],
|
||||
dataset: params.datasets.date[`price_${average.key}_sma`],
|
||||
@@ -60,9 +60,9 @@ function createPresetFolder({
|
||||
icon: IconTablerMathAvg,
|
||||
title: `${name} Moving Average`,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: `SMA`,
|
||||
color,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
import { applySeriesList } from "../apply";
|
||||
import { createPresets as createAveragesPresets } from "./averages";
|
||||
import { createPresets as createIndicatorsPresets } from "./indicators";
|
||||
import { createPresets as createReturnsPresets } from "./returns";
|
||||
@@ -14,7 +14,7 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Price",
|
||||
title: "Market Price",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({ ...params });
|
||||
return applySeriesList(params);
|
||||
},
|
||||
description: "",
|
||||
},
|
||||
@@ -24,7 +24,7 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Performance",
|
||||
title: "Market Performance",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceOptions: {
|
||||
id: "performance",
|
||||
@@ -43,12 +43,9 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Capitalization",
|
||||
title: "Market Capitalization",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Market Cap.",
|
||||
dataset: params.datasets[scale].market_cap,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
totalReturns,
|
||||
} from "/src/scripts/datasets/consts/returns";
|
||||
|
||||
import { applyMultipleSeries, SeriesType } from "../../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../../apply";
|
||||
|
||||
export function createPresets() {
|
||||
return {
|
||||
@@ -57,12 +57,9 @@ function createPreset({
|
||||
icon: IconTablerReceiptTax,
|
||||
title: `${title} Return`,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Return (%)`,
|
||||
seriesType: SeriesType.Based,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets(scale: ResourceScale) {
|
||||
return {
|
||||
@@ -20,12 +20,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Coinbase (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -42,12 +39,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Coinbase (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -71,12 +65,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -93,12 +84,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -122,12 +110,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -144,12 +129,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -174,12 +156,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -197,12 +176,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -236,12 +212,10 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Subsidy (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -258,12 +232,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Subsidy (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -287,12 +258,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -309,12 +277,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -338,12 +303,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -360,12 +322,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -390,12 +349,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -413,12 +369,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -452,12 +405,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Fees (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -474,12 +424,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Fees (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -503,12 +450,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -525,12 +469,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -553,12 +494,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -575,12 +513,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -604,12 +539,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -626,12 +558,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -657,12 +586,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Subsidy V. Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidy (%)",
|
||||
color: colors.bitcoin,
|
||||
@@ -687,13 +613,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Puell Multiple",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Multiple",
|
||||
color: colors.bitcoin,
|
||||
@@ -711,13 +636,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Rate (EH/s)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -745,13 +669,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Ribbon (EH/s)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.profit,
|
||||
@@ -774,12 +697,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Price ($/PH/s)",
|
||||
color: colors.dollars,
|
||||
@@ -799,13 +719,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Difficulty",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Difficulty",
|
||||
color: colors.bitcoin,
|
||||
@@ -825,15 +744,11 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Difficulty Adjustment",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Adjustment (%)",
|
||||
// color: colors.bitcoin,
|
||||
seriesType: SeriesType.Based,
|
||||
dataset: params.datasets[scale].difficulty_adjustment,
|
||||
},
|
||||
@@ -851,13 +766,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Issuance",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Issuance",
|
||||
color: colors.bitcoin,
|
||||
@@ -875,13 +789,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Inflation Rate",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Rate (%)",
|
||||
color: colors.bitcoin,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { percentiles } from "../../datasets/consts/percentiles";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "./multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createCohortPresetFolder<Scale extends ResourceScale>({
|
||||
scale,
|
||||
@@ -54,12 +54,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unspent Transaction Outputs Count`,
|
||||
icon: () => IconTablerTicket,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Count",
|
||||
color,
|
||||
@@ -83,9 +80,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
description: "",
|
||||
icon: () => IconTablerTag,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Realized Price",
|
||||
color,
|
||||
@@ -102,12 +99,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Capitalization`,
|
||||
icon: () => IconTablerPigMoney,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `${name} Realized Cap.`,
|
||||
color,
|
||||
@@ -136,12 +130,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Capitalization 1 Month Net Change`,
|
||||
icon: () => IconTablerStatusChange,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Net Change`,
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -161,12 +152,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Profit`,
|
||||
icon: () => IconTablerCash,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Realized Profit",
|
||||
dataset:
|
||||
@@ -185,12 +173,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Loss`,
|
||||
icon: () => IconTablerCoffin,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Realized Loss",
|
||||
dataset:
|
||||
@@ -209,12 +194,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Profit And Loss`,
|
||||
icon: () => IconTablerArrowsVertical,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
color: colors.profit,
|
||||
@@ -242,12 +224,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Realized Profit And Loss`,
|
||||
icon: () => IconTablerScale,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net PNL",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -267,12 +246,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`,
|
||||
icon: () => IconTablerDivide,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -292,12 +268,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Realized Profit`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Realized Profit",
|
||||
color: colors.profit,
|
||||
@@ -318,12 +291,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Realized Loss`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Realized Loss",
|
||||
color: colors.loss,
|
||||
@@ -344,12 +314,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Net Realized Profit And Loss`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Net Realized PNL",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -369,12 +336,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`,
|
||||
icon: () => IconTablerTimeDuration30,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Net Realized PNL 30d Change",
|
||||
dataset:
|
||||
@@ -399,12 +363,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Profit`,
|
||||
icon: () => IconTablerMoodDollar,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
dataset:
|
||||
@@ -424,12 +385,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Loss`,
|
||||
icon: () => IconTablerMoodSadDizzy,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Loss",
|
||||
dataset:
|
||||
@@ -448,12 +406,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Profit And Loss`,
|
||||
icon: () => IconTablerArrowsVertical,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
color: colors.profit,
|
||||
@@ -481,12 +436,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Unrealized Profit And Loss`,
|
||||
icon: () => IconTablerScale,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net Unrealized PNL",
|
||||
dataset:
|
||||
@@ -506,12 +458,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`,
|
||||
icon: () => IconTablerDivide,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Relative Net Unrealized PNL",
|
||||
dataset:
|
||||
@@ -540,12 +489,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerArrowsCross,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In Profit",
|
||||
color: colors.profit,
|
||||
@@ -587,12 +533,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerSum,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color,
|
||||
@@ -609,12 +552,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -635,12 +575,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.loss,
|
||||
@@ -667,12 +604,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerArrowsCross,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In Profit",
|
||||
color: colors.profit,
|
||||
@@ -718,12 +652,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Total supply Relative To Circulating Supply`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color,
|
||||
@@ -744,12 +675,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit Relative To Circulating Supply`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -770,12 +698,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss Relative To Circulating Supply`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
seriesType: SeriesType.Area,
|
||||
@@ -801,14 +726,11 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit And Loss Relative To Own Supply`,
|
||||
icon: () => IconTablerArrowsCross,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In profit",
|
||||
title: "In Profit",
|
||||
dataset:
|
||||
params.datasets[scale][
|
||||
`${datasetPrefix}supply_in_profit_to_own_supply_ratio`
|
||||
@@ -816,7 +738,7 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
color: colors.profit,
|
||||
},
|
||||
{
|
||||
title: "In loss",
|
||||
title: "In Loss",
|
||||
color: colors.loss,
|
||||
dataset:
|
||||
params.datasets[scale][
|
||||
@@ -851,12 +773,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit Relative To Own Supply`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -877,12 +796,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss Relative To Own Supply`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
seriesType: SeriesType.Area,
|
||||
@@ -917,9 +833,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Average Price Paid - Realized Price`,
|
||||
icon: () => IconTablerMathAvg,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Average",
|
||||
color,
|
||||
@@ -937,9 +853,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} deciles`,
|
||||
icon: () => IconTablerSquareHalf,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: percentiles
|
||||
top: percentiles
|
||||
.filter(({ value }) => Number(value) % 10 === 0)
|
||||
.map(({ name, key }) => ({
|
||||
dataset: params.datasets[scale][`${datasetPrefix}${key}`],
|
||||
@@ -957,9 +873,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} ${percentile.title}`,
|
||||
icon: () => IconTablerSquareHalf,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: percentile.name,
|
||||
color,
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
import { applyPriceSeries } from "../../lightweightCharts/chart/price";
|
||||
import { chartState } from "../../lightweightCharts/chart/state";
|
||||
import { setTimeScale } from "../../lightweightCharts/chart/time";
|
||||
import { createAreaSeries } from "../../lightweightCharts/series/creators/area";
|
||||
import {
|
||||
createBaseLineSeries,
|
||||
DEFAULT_BASELINE_COLORS,
|
||||
} from "../../lightweightCharts/series/creators/baseLine";
|
||||
import { createHistogramSeries } from "../../lightweightCharts/series/creators/histogram";
|
||||
import { createSeriesLegend } from "../../lightweightCharts/series/creators/legend";
|
||||
import { createLineSeries } from "../../lightweightCharts/series/creators/line";
|
||||
import { resetRightPriceScale } from "../../lightweightCharts/series/options/priceScale";
|
||||
import { stringToId } from "../../utils/id";
|
||||
|
||||
export enum SeriesType {
|
||||
Normal,
|
||||
Based,
|
||||
Area,
|
||||
Histogram,
|
||||
}
|
||||
|
||||
export function applyMultipleSeries<
|
||||
Scale extends ResourceScale,
|
||||
DS extends Dataset<Scale> & Partial<ResourceDataset<Scale>>,
|
||||
>({
|
||||
chart,
|
||||
list = [],
|
||||
preset,
|
||||
priceScaleOptions,
|
||||
datasets,
|
||||
priceDataset,
|
||||
priceOptions,
|
||||
activeResources,
|
||||
}: {
|
||||
chart: IChartApi;
|
||||
preset: Preset;
|
||||
priceDataset?: DS;
|
||||
priceOptions?: PriceSeriesOptions;
|
||||
priceScaleOptions?: FullPriceScaleOptions;
|
||||
list?: (
|
||||
| {
|
||||
dataset: DS;
|
||||
color?: string;
|
||||
colors?: undefined;
|
||||
seriesType: SeriesType.Based;
|
||||
title: string;
|
||||
options?: BaselineSeriesOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: DS;
|
||||
color?: string;
|
||||
colors?: string[];
|
||||
seriesType: SeriesType.Histogram;
|
||||
title: string;
|
||||
options?: DeepPartialHistogramOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: DS;
|
||||
color: string;
|
||||
colors?: undefined;
|
||||
seriesType?: SeriesType.Normal | SeriesType.Area;
|
||||
title: string;
|
||||
options?: DeepPartialLineOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
)[];
|
||||
datasets: Datasets;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}): PresetLegend {
|
||||
const { halved } = priceScaleOptions || {};
|
||||
|
||||
const price = applyPriceSeries({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
dataset: priceDataset,
|
||||
activeResources,
|
||||
options: {
|
||||
...priceOptions,
|
||||
halved,
|
||||
},
|
||||
});
|
||||
|
||||
const legendList: PresetLegend = [price.lineLegend, price.ohlcLegend];
|
||||
|
||||
const isAnyArea = list.find(
|
||||
(config) => config.seriesType === SeriesType.Area,
|
||||
);
|
||||
|
||||
const rightPriceScaleOptions = resetRightPriceScale(chart, {
|
||||
...priceScaleOptions,
|
||||
...(isAnyArea
|
||||
? {
|
||||
scaleMargins: {
|
||||
bottom: 0,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
[...list]
|
||||
.reverse()
|
||||
.forEach(
|
||||
({
|
||||
dataset,
|
||||
color,
|
||||
colors,
|
||||
seriesType: type,
|
||||
title,
|
||||
options,
|
||||
defaultVisible,
|
||||
}) => {
|
||||
let series: ISeriesApi<"Baseline" | "Line" | "Area" | "Histogram">;
|
||||
|
||||
if (type === SeriesType.Based) {
|
||||
series = createBaseLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Area) {
|
||||
series = createAreaSeries(chart, {
|
||||
color,
|
||||
autoscaleInfoProvider: (getInfo: () => AutoscaleInfo | null) => {
|
||||
const info = getInfo();
|
||||
if (info) {
|
||||
info.priceRange.minValue = 0;
|
||||
}
|
||||
return info;
|
||||
},
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Histogram) {
|
||||
series = createHistogramSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else {
|
||||
series = createLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
legendList.splice(
|
||||
0,
|
||||
0,
|
||||
createSeriesLegend({
|
||||
id: stringToId(title),
|
||||
presetId: preset.id,
|
||||
title,
|
||||
series,
|
||||
color: () => colors || color || DEFAULT_BASELINE_COLORS,
|
||||
defaultVisible,
|
||||
url: dataset.url,
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
series.setData(dataset?.values() || []);
|
||||
|
||||
setTimeScale(chartState.range);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
const options = {
|
||||
scaleMargins: {
|
||||
top:
|
||||
price.lineLegend.visible() || price.ohlcLegend.visible()
|
||||
? rightPriceScaleOptions.scaleMargins.top
|
||||
: rightPriceScaleOptions.scaleMargins.bottom,
|
||||
bottom: rightPriceScaleOptions.scaleMargins.bottom,
|
||||
},
|
||||
};
|
||||
|
||||
chart.priceScale("right").applyOptions(options);
|
||||
});
|
||||
|
||||
return legendList;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
import { applySeriesList } from "../apply";
|
||||
|
||||
export function createPresets(scale: ResourceScale) {
|
||||
return {
|
||||
@@ -12,12 +12,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Count",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -48,12 +45,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Volume",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -80,13 +74,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Volume In Dollars",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.lightDollars,
|
||||
@@ -124,12 +117,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Transaction Volume",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Volume",
|
||||
color: colors.bitcoin,
|
||||
@@ -147,12 +137,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Transaction Volume In Dollars",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Volume",
|
||||
color: colors.dollars,
|
||||
@@ -173,12 +160,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transactions Velocity",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Transactions Velocity",
|
||||
color: colors.bitcoin,
|
||||
@@ -195,12 +179,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transactions Per Second",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.lightBitcoin,
|
||||
|
||||
8
app/src/scripts/presets/types.d.ts
vendored
8
app/src/scripts/presets/types.d.ts
vendored
@@ -20,13 +20,13 @@ type FilePath = {
|
||||
}[];
|
||||
|
||||
type ApplyPreset = (params: {
|
||||
chart: IChartApi;
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: HTMLDivElement;
|
||||
datasets: Datasets;
|
||||
preset: Preset;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) => ApplyPresetReturn;
|
||||
|
||||
type ApplyPresetReturn = PresetLegend;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
}) => void;
|
||||
|
||||
interface PartialPresetFolder {
|
||||
name: string;
|
||||
|
||||
@@ -1,31 +1,52 @@
|
||||
export const priceToUSLocale = (price: number, compact = true) => {
|
||||
const absolutePrice = Math.abs(price);
|
||||
const lessThan100 = absolutePrice < 100;
|
||||
const lessThan1000 = absolutePrice < 1_000;
|
||||
const biggerThanMillion = absolutePrice >= 1_000_000;
|
||||
const suffices = ["M", "B", "T", "Q"];
|
||||
|
||||
return numberToUSLocale(
|
||||
price,
|
||||
lessThan1000 ? (lessThan100 ? 2 : 1) : biggerThanMillion ? 3 : 0,
|
||||
biggerThanMillion && compact
|
||||
? {
|
||||
notation: "compact",
|
||||
compactDisplay: "short",
|
||||
}
|
||||
: undefined,
|
||||
);
|
||||
};
|
||||
export function valueToString(value: number) {
|
||||
const absoluteValue = Math.abs(value);
|
||||
|
||||
export const percentageToUSLocale = (percentage: number) =>
|
||||
numberToUSLocale(percentage, 1);
|
||||
// value = absoluteValue;
|
||||
|
||||
const numberToUSLocale = (
|
||||
if (isNaN(value)) {
|
||||
return "";
|
||||
// } else if (value === 0) {
|
||||
// return "0";
|
||||
} else if (absoluteValue < 10) {
|
||||
return numberToUSLocale(value, 3);
|
||||
} else if (absoluteValue < 100) {
|
||||
return numberToUSLocale(value, 2);
|
||||
} else if (absoluteValue < 1_000) {
|
||||
return numberToUSLocale(value, 1);
|
||||
} else if (absoluteValue < 100_000) {
|
||||
return numberToUSLocale(value, 0);
|
||||
} else if (absoluteValue < 1_000_000) {
|
||||
return `${numberToUSLocale(value / 1_000, 1)}K`;
|
||||
} else if (absoluteValue >= 1_000_000_000_000_000_000) {
|
||||
return "Inf.";
|
||||
}
|
||||
|
||||
const log = Math.floor(Math.log10(absoluteValue) - 6);
|
||||
|
||||
const letterIndex = Math.floor(log / 3);
|
||||
const letter = suffices[letterIndex];
|
||||
|
||||
const modulused = log % 3;
|
||||
|
||||
if (modulused === 0) {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 3)}${letter}`;
|
||||
} else if (modulused === 1) {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 2)}${letter}`;
|
||||
} else {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 1)}${letter}`;
|
||||
}
|
||||
}
|
||||
|
||||
function numberToUSLocale(
|
||||
value: number,
|
||||
digits: number,
|
||||
digits?: number,
|
||||
options?: Intl.NumberFormatOptions | undefined,
|
||||
) =>
|
||||
value.toLocaleString("en-us", {
|
||||
) {
|
||||
return value.toLocaleString("en-us", {
|
||||
...options,
|
||||
minimumFractionDigits: digits,
|
||||
maximumFractionDigits: digits,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
list: L,
|
||||
export const createDynamicList = <T, L extends T[] = T[]>(
|
||||
l: L,
|
||||
parameters?: {
|
||||
selected?: L[number];
|
||||
selectedIndex?: number | null;
|
||||
@@ -10,10 +10,10 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
const selected = createRWS<L[number] | null>(null);
|
||||
const selectedIndex = createRWS<number | null>(null);
|
||||
|
||||
const selectableList: SelectableList<L[number], L> = {
|
||||
const list: DynamicList<L[number], L> = {
|
||||
selected,
|
||||
selectedIndex,
|
||||
list: createRWS(list, {
|
||||
list: createRWS(l, {
|
||||
equals: false,
|
||||
}),
|
||||
select(s) {
|
||||
@@ -83,10 +83,10 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
toJSON<TJSON, LJSON extends TJSON[] = TJSON[]>(
|
||||
transform: (value: T) => TJSON,
|
||||
filter?: (value: T) => boolean,
|
||||
): JSONSelectableList<TJSON, LJSON> {
|
||||
): JSONDynamicList<TJSON, LJSON> {
|
||||
return {
|
||||
version: 1,
|
||||
selectedIndex: getIndexOfSelectedInSelectableList(this),
|
||||
selectedIndex: getIndexOfSelectedInDynamicList(this),
|
||||
list: (filter ? this.list().filter(filter) : this.list()).map((value) =>
|
||||
transform(value),
|
||||
) as LJSON,
|
||||
@@ -95,18 +95,18 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
};
|
||||
|
||||
if (parameters?.selected !== undefined) {
|
||||
selectableList.select(parameters.selected);
|
||||
list.select(parameters.selected);
|
||||
} else if (parameters?.selectedIndex !== undefined) {
|
||||
selectableList.selectIndex(parameters.selectedIndex);
|
||||
list.selectIndex(parameters.selectedIndex);
|
||||
}
|
||||
|
||||
return selectableList;
|
||||
return list;
|
||||
};
|
||||
|
||||
export const createSL = createSelectableList;
|
||||
export const createDSL = createDynamicList;
|
||||
|
||||
export const getIndexOfSelectedInSelectableList = <T, L extends T[] = T[]>(
|
||||
sl: SelectableList<L[number], L>,
|
||||
export const getIndexOfSelectedInDynamicList = <T, L extends T[] = T[]>(
|
||||
sl: DynamicList<L[number], L>,
|
||||
) => {
|
||||
const selected = sl.selected();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// JSON
|
||||
// ---
|
||||
|
||||
interface JSONSelectableList<T, L extends T[] = T[]> {
|
||||
interface JSONDynamicList<T, L extends T[] = T[]> {
|
||||
readonly version: 1;
|
||||
selectedIndex: number | null;
|
||||
readonly list: L;
|
||||
@@ -12,7 +12,7 @@ interface JSONSelectableList<T, L extends T[] = T[]> {
|
||||
// Object
|
||||
// ---
|
||||
|
||||
interface SelectableList<T, L extends T[] = T[]> {
|
||||
interface DynamicList<T, L extends T[] = T[]> {
|
||||
readonly selected: Accessor<T | null>;
|
||||
readonly selectedIndex: Accessor<number | null>;
|
||||
readonly list: RWS<L>;
|
||||
@@ -29,5 +29,5 @@ interface SelectableList<T, L extends T[] = T[]> {
|
||||
readonly toJSON: <TJSON, LJSON extends TJSON[] = TJSON[]>(
|
||||
transform: (value: T) => LJSON[number],
|
||||
filter?: (value: T) => boolean,
|
||||
) => JSONSelectableList<TJSON, LJSON>;
|
||||
) => JSONDynamicList<TJSON, LJSON>;
|
||||
}
|
||||
140
app/src/scripts/utils/selectableList/static/index.ts
Normal file
140
app/src/scripts/utils/selectableList/static/index.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { run } from "../../run";
|
||||
|
||||
export const createStaticList = <T, L extends T[] = T[]>(
|
||||
l: L,
|
||||
parameters: {
|
||||
selected?: L[number];
|
||||
selectedIndex?: number;
|
||||
saveable?: {
|
||||
mode: "localStorage" | "URLParams" | "both";
|
||||
key: string;
|
||||
};
|
||||
defaultValue?: L[number];
|
||||
defaultIndex?: number;
|
||||
},
|
||||
) => {
|
||||
if (
|
||||
!l.length ||
|
||||
(parameters.saveable === undefined &&
|
||||
parameters.selected === undefined &&
|
||||
parameters.selectedIndex === undefined)
|
||||
) {
|
||||
throw Error("not possible");
|
||||
}
|
||||
|
||||
const selected = createRWS<L[number]>(
|
||||
run(() => {
|
||||
let savedIndex: number | undefined;
|
||||
|
||||
if (parameters.saveable) {
|
||||
if (parameters.saveable.mode !== "localStorage") {
|
||||
throw Error("unsupported");
|
||||
}
|
||||
|
||||
const savedRaw = localStorage.getItem(parameters.saveable.key);
|
||||
|
||||
if (savedRaw) {
|
||||
savedIndex = Number(savedRaw);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.selected) {
|
||||
const found = l.find((v) => v === parameters.selected);
|
||||
|
||||
if (!found) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
return found;
|
||||
} else {
|
||||
return (
|
||||
l.at(savedIndex ?? parameters.selectedIndex!) ??
|
||||
parameters.defaultValue ??
|
||||
l[parameters.defaultIndex || 0]
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const selectedIndex = createRWS<number>(
|
||||
run(() => {
|
||||
if (
|
||||
parameters.selectedIndex !== null &&
|
||||
parameters.selectedIndex !== undefined
|
||||
) {
|
||||
const found = l.at(parameters.selectedIndex);
|
||||
|
||||
if (!found) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
return parameters.selectedIndex;
|
||||
} else {
|
||||
return l.indexOf(selected());
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
if (parameters.saveable) {
|
||||
localStorage.setItem(parameters.saveable.key, String(selectedIndex()));
|
||||
}
|
||||
});
|
||||
|
||||
const list: StaticList<L[number], L> = {
|
||||
selected,
|
||||
selectedIndex,
|
||||
list: createRWS(l, {
|
||||
equals: false,
|
||||
}),
|
||||
select(s) {
|
||||
if (this.selected() !== s) {
|
||||
batch(() => {
|
||||
selected.set(() => s);
|
||||
this.selectIndex(this.list().indexOf(s));
|
||||
});
|
||||
}
|
||||
},
|
||||
selectIndex(i) {
|
||||
if (i && (i < 0 || i >= this.list().length)) {
|
||||
throw new Error(
|
||||
`SelectableList: selectIndex: ${i} is incorrect ! (has ${
|
||||
this.list().length
|
||||
} elements)`,
|
||||
);
|
||||
}
|
||||
|
||||
if (i !== this.selectedIndex()) {
|
||||
selectedIndex.set(i);
|
||||
|
||||
const value = this.list().at(i);
|
||||
|
||||
if (value === undefined) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
this.select(value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (parameters?.selected !== undefined) {
|
||||
list.select(parameters.selected);
|
||||
} else if (parameters?.selectedIndex !== undefined) {
|
||||
list.selectIndex(parameters.selectedIndex);
|
||||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
export const createSL = createStaticList;
|
||||
|
||||
export const getIndexOfSelectedInStaticList = <T, L extends T[] = T[]>(
|
||||
sl: StaticList<L[number], L>,
|
||||
) => {
|
||||
const selected = sl.selected();
|
||||
|
||||
return selected ? sl.list().indexOf(selected) : null;
|
||||
};
|
||||
9
app/src/scripts/utils/selectableList/static/types.d.ts
vendored
Normal file
9
app/src/scripts/utils/selectableList/static/types.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
interface StaticList<T, L extends T[] = T[]> {
|
||||
readonly selected: Accessor<T>;
|
||||
readonly selectedIndex: Accessor<number>;
|
||||
readonly list: RWS<L>;
|
||||
readonly select: <S extends L[number] = L[number]>(s: S) => void;
|
||||
readonly selectIndex: (index: number) => void;
|
||||
}
|
||||
|
||||
type SL<T, L extends T[] = T[]> = StaticList<T, L>;
|
||||
Reference in New Issue
Block a user