general: snapshot

This commit is contained in:
k
2024-07-05 18:03:53 +02:00
parent 069311dcf3
commit a931ad7a1e
43 changed files with 1210 additions and 1037 deletions
+36 -18
View File
@@ -28,7 +28,6 @@ export function createPresets({
{
title: `Total Non Empty Address`,
color: colors.bitcoin,
seriesType: SeriesType.Area,
dataset: params.datasets[scale].address_count,
},
],
@@ -67,7 +66,6 @@ export function createPresets({
{
title: `Total Addresses Created`,
color: colors.bitcoin,
seriesType: SeriesType.Area,
dataset: params.datasets[scale].created_addresses,
},
],
@@ -87,7 +85,6 @@ export function createPresets({
{
title: `Total Empty Addresses`,
color: colors.darkWhite,
seriesType: SeriesType.Area,
dataset: params.datasets[scale].empty_addresses,
},
],
@@ -143,25 +140,46 @@ function createAddressPresetFolder<Scale extends ResourceScale>({
color,
datasetKey,
}),
{
name: `Split By Liquidity`,
tree: liquidities.map(
(liquidity): PartialPresetFolder => ({
name: liquidity.name,
tree: createCohortPresetList({
title: `${liquidity.name} ${name}`,
name: `${liquidity.name} ${name}`,
scale,
color,
datasetKey: `${liquidity.key}_${datasetKey}`,
}),
}),
),
},
createLiquidityFolder({
scale,
name,
datasetKey,
color,
}),
],
};
}
export function createLiquidityFolder<Scale extends ResourceScale>({
scale,
color,
name,
datasetKey,
}: {
scale: Scale;
name: string;
datasetKey: AddressCohortKey | "";
color: string;
}): PartialPresetFolder {
return {
name: `Split By Liquidity`,
tree: liquidities.map(
(liquidity): PartialPresetFolder => ({
name: liquidity.name,
tree: createCohortPresetList({
title: `${liquidity.name} ${name}`,
name: `${liquidity.name} ${name}`,
scale,
color,
datasetKey: !datasetKey
? liquidity.key
: `${liquidity.key}_${datasetKey}`,
}),
}),
),
};
}
export function createAddressCountPreset<Scale extends ResourceScale>({
scale,
color,
+362 -406
View File
@@ -1,10 +1,10 @@
import { createRWS } from "/src/solid/rws";
import { chunkIdToIndex } from "../datasets/resource";
import { createChart } from "../lightweightCharts/chart/create";
import { chartState } from "../lightweightCharts/chart/state";
import { setMinMaxMarkers } from "../lightweightCharts/chart/markers";
import { initTimeScale } from "../lightweightCharts/chart/time";
import { setWhitespace } from "../lightweightCharts/chart/whitespace";
import { createAreaSeries } from "../lightweightCharts/series/creators/area";
import {
createBaseLineSeries,
DEFAULT_BASELINE_COLORS,
@@ -16,13 +16,12 @@ import { createLineSeries } from "../lightweightCharts/series/creators/line";
import { colors } from "../utils/colors";
import { debounce } from "../utils/debounce";
import { stringToId } from "../utils/id";
import { webSockets } from "../ws";
export enum SeriesType {
Normal,
Line,
Based,
Area,
Histogram,
Candlestick,
}
type SeriesConfig<Scale extends ResourceScale> =
@@ -33,6 +32,7 @@ type SeriesConfig<Scale extends ResourceScale> =
seriesType: SeriesType.Based;
title: string;
options?: BaselineSeriesOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
@@ -42,15 +42,27 @@ type SeriesConfig<Scale extends ResourceScale> =
seriesType: SeriesType.Histogram;
title: string;
options?: DeepPartialHistogramOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
dataset: ResourceDataset<Scale>;
seriesType: SeriesType.Candlestick;
priceScaleOptions?: DeepPartialPriceScaleOptions;
colors?: undefined;
color?: undefined;
options?: DeepPartialLineOptions;
defaultVisible?: boolean;
title: string;
}
| {
dataset: ResourceDataset<Scale>;
color: string;
colors?: undefined;
seriesType?: SeriesType.Normal | SeriesType.Area;
seriesType?: SeriesType.Line;
title: string;
options?: DeepPartialLineOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
};
@@ -65,18 +77,28 @@ export function applySeriesList<Scale extends ResourceScale>({
priceDataset,
priceOptions,
legendSetter,
dark,
activeRange,
}: {
charts: RWS<IChartApi[]>;
parentDiv: HTMLDivElement;
preset: Preset;
legendSetter: Setter<PresetLegend>;
legendSetter: Setter<SeriesLegend[]>;
priceDataset?: ResourceDataset<Scale>;
priceOptions?: PriceSeriesOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
top?: SeriesConfig<Scale>[];
bottom?: SeriesConfig<Scale>[];
datasets: Datasets;
dark: boolean;
activeRange: RWS<number[]>;
}) {
// ---
// Reset states
// ---
legendSetter([]);
reactiveChartList.set((charts) => {
charts.forEach((chart) => {
chart.remove();
@@ -85,29 +107,36 @@ export function applySeriesList<Scale extends ResourceScale>({
return [];
});
activeRange.set([]);
parentDiv.replaceChildren();
// ---
// Done
// ---
const scale = preset.scale;
const legendList: PresetLegend = [];
const presetLegend: SeriesLegend[] = [];
const priceSeriesType = createRWS<"Candlestick" | "Line">("Candlestick");
const priceSeriesType = createRWS<PriceSeriesType>("Candlestick");
// const valuesSkipped = createRWS(0);
const activeDatasets: ResourceDataset<any, any>[] = [];
const activeDatasets: Set<ResourceDataset<any, any>> = new Set();
const lastActiveIndex = createMemo(() => {
const last = activeRange().at(-1);
return last !== undefined ? chunkIdToIndex(scale, last) : undefined;
});
const exactRange = createRWS(undefined as TimeRange | undefined);
const charts = [top || [], bottom]
.flatMap((list) => (list ? [list] : []))
.flatMap((seriesConfigList, index, array) => {
.flatMap((seriesConfigList, index) => {
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";
@@ -115,28 +144,40 @@ export function applySeriesList<Scale extends ResourceScale>({
parentDiv.appendChild(div);
const chart = createChart(scale, div, {
...priceScaleOptions,
...(isAnyArea
? {
scaleMargins: {
bottom: 0,
},
}
: {}),
dark,
priceScaleOptions: {
...priceScaleOptions,
},
});
chartState.chart = chart;
if (!chart) {
console.log("chart: undefined");
return [];
}
setWhitespace(chart, scale);
const whitespace = setWhitespace(chart, scale);
const seriesList: ISeriesApi<any>[] = [];
// return [
// {
// scale,
// div,
// chart,
// whitespace,
// legendList: [],
// debouncedSetMinMaxMarkers: () => {},
// },
// ];
const _legendList: PresetLegend = [];
const chartLegend: SeriesLegend[] = [];
const debouncedSetMinMaxMarkers = debounce(() => {
setMinMaxMarkers({
scale,
visibleRange: exactRange(),
legendList: chartLegend,
activeRange,
});
}, 20);
if (index === 0) {
const dataset =
@@ -145,102 +186,93 @@ export function applySeriesList<Scale extends ResourceScale>({
typeof priceDataset
>);
activeDatasets.add(dataset);
activeDatasets.push(dataset);
const price = applyPriceSeries({
chart,
preset,
seriesType: priceSeriesType,
// valuesSkipped,
dataset,
options: priceOptions,
const title = priceOptions?.title || "Price";
const priceScaleOptions: DeepPartialPriceScaleOptions = {
mode: 1,
...priceOptions?.priceScaleOptions,
};
function createPriceSeries(seriesType: PriceSeriesType) {
let seriesConfig: SeriesConfig<Scale>;
if (seriesType === "Candlestick") {
seriesConfig = {
dataset,
title,
seriesType: SeriesType.Candlestick,
options: priceOptions,
priceScaleOptions,
};
} else {
seriesConfig = {
dataset,
title,
color: colors.white,
options: priceOptions?.seriesOptions,
priceScaleOptions,
};
}
return createSeriesGroup({
activeRange,
seriesConfig,
chart,
chartLegend,
lastActiveIndex,
preset,
disabled: () => priceSeriesType() !== seriesType,
debouncedSetMinMaxMarkers,
});
}
const priceCandlestickLegend = createPriceSeries("Candlestick");
const priceLineLegend = createPriceSeries("Line");
createEffect(() => {
priceCandlestickLegend.visible.set(priceLineLegend.visible());
});
_legendList.push(price.lineLegend, price.ohlcLegend);
seriesList.push(price.lineLegend.series, price.ohlcLegend.series);
createEffect(() => {
priceLineLegend.visible.set(priceCandlestickLegend.visible());
});
}
seriesList.push(
...seriesConfigList
.reverse()
.map(
({
dataset,
color,
colors,
seriesType: type,
title,
options,
defaultVisible,
}) => {
activeDatasets.add(dataset);
seriesConfigList.reverse().forEach((seriesConfig) => {
activeDatasets.push(seriesConfig.dataset);
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(() => {
const values = dataset.values();
console.log(values.length);
series.setData(values);
});
return series;
},
),
);
_legendList.forEach((legend) => {
legendList.splice(0, 0, legend);
createSeriesGroup({
activeRange,
seriesConfig,
chartLegend,
chart,
preset,
lastActiveIndex,
debouncedSetMinMaxMarkers,
});
});
return [{ div, chart, seriesList, legendList: _legendList }];
});
chartLegend.forEach((legend) => {
presetLegend.splice(0, 0, legend);
createEffect(on(legend.visible, debouncedSetMinMaxMarkers));
});
createEffect(on(exactRange, debouncedSetMinMaxMarkers));
return [
{
scale,
div,
chart,
whitespace,
legendList: chartLegend,
debouncedSetMinMaxMarkers,
},
];
}) satisfies ChartObject[];
createEffect(() => {
const visibleCharts: typeof charts = [];
@@ -267,344 +299,268 @@ export function applySeriesList<Scale extends ResourceScale>({
});
});
// 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) {
// valuesSkipped.set(0);
priceSeriesType.set("Candlestick");
} else {
priceSeriesType.set("Line");
// valuesSkipped.set(Math.floor(ratio / 1.25));
}
} catch {}
}
const debouncedUpdateVisibleRangeRatio = debounce(
updateVisibleRangeRatio,
const debouncedUpdateVisiblePriceSeriesType = debounce(
updateVisiblePriceSeriesType,
50,
);
initTimeScale({
activeDatasets,
scale,
charts,
activeRange,
exactRange,
});
charts.forEach(({ chart }, index) => {
const activeDatasetsLength = activeDatasets.length;
createEffect(() => {
const range = activeRange();
untrack(() => {
for (let i = 0; i < range.length; i++) {
const id = range[i];
for (let j = 0; j < activeDatasetsLength; j++) {
activeDatasets[j].fetch(id);
}
}
});
});
const lastChartIndex = charts.length - 1;
for (let i = 0; i < charts.length; i++) {
const chart = charts[i].chart;
chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => {
// Last chart otherwise length of timescale is Infinity
if (index === charts.length - 1) {
debouncedUpdateVisibleRangeRatio(chart, timeRange);
if (!timeRange) return;
// Must be the chart with the visible timeScale
if (i === lastChartIndex) {
debouncedUpdateVisiblePriceSeriesType(
chart,
timeRange,
priceSeriesType,
);
}
charts.forEach(({ chart: _chart }, _index) => {
if (timeRange && index !== _index) {
_chart.timeScale().setVisibleLogicalRange(timeRange);
for (let j = 0; j <= lastChartIndex; j++) {
if (i !== j) {
charts[j].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);
for (let j = 0; j <= lastChartIndex; j++) {
const whitespace = charts[j].whitespace;
const otherChart = charts[j].chart;
if (first && index !== _index) {
if (whitespace && i !== j) {
if (time) {
_chart.setCrosshairPosition(NaN, time, first);
otherChart.setCrosshairPosition(NaN, time, whitespace);
} else {
// No time when mouse goes outside the chart
_chart.clearCrosshairPosition();
otherChart.clearCrosshairPosition();
}
}
});
}
});
});
}
legendSetter(legendList);
legendSetter(presetLegend);
reactiveChartList.set(() => charts.map(({ chart }) => chart));
}
function applyPriceSeries<
Scale extends ResourceScale,
T extends OHLC | number,
>({
chart,
preset,
dataset,
seriesType,
// valuesSkipped,
options,
}: {
chart: IChartApi;
preset: Preset;
// valuesSkipped: Accessor<number>;
seriesType: Accessor<"Candlestick" | "Line">;
dataset: ResourceDataset<Scale, T>;
options?: PriceSeriesOptions;
}) {
// console.time("series add");
function updateVisiblePriceSeriesType(
chart: IChartApi,
range: LogicalRange,
priceSeriesType: RWS<PriceSeriesType>,
) {
try {
const width = chart.timeScale().width();
const id = options?.id || "price";
const title = options?.title || "Price";
const ratio = (range.to - range.from) / width;
const url = "url" in dataset ? (dataset as any).url : undefined;
const priceScaleOptions: DeepPartialPriceScaleOptions = {
mode: 1,
...options?.priceScaleOptions,
};
let [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, options);
const ohlcLegend = createSeriesLegend({
id,
presetId: preset.id,
title,
color: () => ohlcColors,
series: ohlcSeries,
disabled: () => seriesType() !== "Candlestick",
url,
});
ohlcSeries.priceScale().applyOptions(priceScaleOptions);
// ---
const lineColor = colors.white;
let lineSeries = createLineSeries(chart, {
color: lineColor,
...options?.seriesOptions,
});
const lineLegend = createSeriesLegend({
id,
presetId: preset.id,
title,
color: () => lineColor,
series: lineSeries,
disabled: () => seriesType() !== "Line",
visible: ohlcLegend.visible,
url,
});
lineSeries.priceScale().applyOptions(priceScaleOptions);
// console.timeEnd("series add");
// lineSeries.setData(whitespaceHeightDataset);
// ohlcSeries.setData({ time: 0, value: NaN });
// ---
// setMinMaxMarkers({
// scale: preset.scale,
// candlesticks:
// dataset?.values() || datasets[preset.scale].price.values() || ([] as any),
// range: chartState.range,
// lowerOpacity,
// });
// const startingValue = {
// number: -1,
// time: -1,
// open: NaN,
// high: NaN,
// low: NaN,
// close: NaN,
// value: NaN,
// };
// lineSeries.update(startingValue);
// ohlcSeries.update(startingValue);
// const callback = (
// chunks: any[],
// valuesSkippedPlus1: number,
// length: number,
// ) => {
// console.time("t");
// console.time("a");
// // chart.removeSeries(ohlcSeries);
// // chart.removeSeries(lineSeries);
// // ohlcSeries = createCandlesticksSeries(chart, options)[0];
// // ohlcSeries.priceScale().applyOptions(priceScaleOptions);
// // lineSeries = createLineSeries(chart, {
// // color: lineColor,
// // ...options?.seriesOptions,
// // });
// // lineSeries.priceScale().applyOptions(priceScaleOptions);
// const values = new Array(length);
// let i = 0;
// for (let k = 0; k < chunks.length; k++) {
// const chunk = chunks[k];
// // const chunk =
// // fetchedJSONs[chunkIdToIndex(dataset.scale, activeRange[k])]?.vec?.() ||
// // [];
// for (let j = 0; j < chunk.length; j += valuesSkippedPlus1) {
// values[i++] = chunk[j];
// // console.log(chunk[j]);
// // callback(chunk[j]);
// // for (let i = 0; i < seriesList.length; i++) {
// // seriesList[i].update(chunk[j]);
// // }
// // const value = chunk[j];
// // console.log(value.time);
// // lineSeries.update(value);
// // ohlcSeries.update(value);
// // i++;
// }
// }
// console.log(values.length);
// console.timeEnd("t");
// lineSeries.setData(values);
// console.timeEnd("a");
// };
// const debouncedCallback = debounce(callback, 200);
createEffect(() => {
const values = dataset.values();
console.log(values.length);
lineSeries.setData(values);
ohlcSeries.setData(values);
});
// createEffect(() =>
// computeDrawnSeriesValues(
// dataset,
// valuesSkipped(),
// debouncedCallback,
// // [lineSeries, ohlcSeries],
// // (value) => {
// // try {
// // console.log(value);
// // lineSeries.update(value);
// // ohlcSeries.update(value);
// // } catch {}
// // }),
// ),
// );
createEffect(() => {
if (preset.scale === "date") {
const latest = webSockets.liveKrakenCandle.latest();
if (latest) {
ohlcSeries.update(latest);
lineSeries.update(latest);
}
if (ratio <= 0.5) {
priceSeriesType.set("Candlestick");
} else {
priceSeriesType.set("Line");
}
});
return { ohlcLegend, lineLegend };
} catch {}
}
// // const computeDrawnSeriesValues = debounce(_computeDrawnSeriesValues, 100);
function createSeriesGroup<Scale extends ResourceScale>({
activeRange,
seriesConfig,
preset,
chartLegend,
chart,
disabled,
lastActiveIndex,
debouncedSetMinMaxMarkers,
}: {
activeRange: Accessor<number[]>;
seriesConfig: SeriesConfig<Scale>;
preset: Preset;
chart: IChartApi;
chartLegend: SeriesLegend[];
lastActiveIndex: Accessor<number | undefined>;
disabled?: Accessor<boolean>;
debouncedSetMinMaxMarkers: VoidFunction;
}) {
const {
dataset,
title,
colors,
color,
defaultVisible,
seriesType: type,
options,
priceScaleOptions,
} = seriesConfig;
// function computeDrawnSeriesValues<
// S extends ResourceScale,
// T extends OHLC | number,
// >(
// dataset: ResourceDataset<S, T>,
// valuesSkipped: number,
// callback: (chunks: any, v: number, l: number) => void,
// // seriesList: ISeriesApi<any>[],
// ) {
// // console.time(dataset.url);
const scale = preset.scale;
// const { fetchedJSONs, activeRange: _activeRange } = dataset;
const seriesList: RWS<
ISeriesApi<"Baseline" | "Line" | "Histogram" | "Candlestick"> | undefined
>[] = new Array(dataset.fetchedJSONs.length);
// const activeRange = _activeRange();
let defaultSeriesColor: string | string[] | undefined = undefined;
// const valuesSkippedPlus1 = valuesSkipped + 1;
const legend = createSeriesLegend({
id: stringToId(title),
presetId: preset.id,
title,
seriesList,
color: () =>
colors || color || defaultSeriesColor || DEFAULT_BASELINE_COLORS,
defaultVisible,
disabled,
dataset,
});
// if (valuesSkippedPlus1 === 1) {
// console.log("todo valuesSkippedPlus1===1, skip for now");
// }
chartLegend.push(legend);
// // for (let i = 0; i < seriesList.length; i++) {
// // seriesList[i].
// // }
dataset.fetchedJSONs.forEach((json, index) => {
const series: (typeof seriesList)[number] = createRWS(undefined);
// const chunks = new Array(activeRange.length);
// let length = 0;
seriesList[index] = series;
// for (let i = 0; i < chunks.length; i++) {
// const chunk =
// fetchedJSONs[chunkIdToIndex(dataset.scale, activeRange[i])]?.vec?.() ||
// [];
createEffect(() => {
const values = json.vec();
if (!values) return;
// chunks[i] = chunk;
untrack(() => {
let s = series();
// length += Math.ceil(chunk.length / valuesSkippedPlus1);
// }
if (!s) {
switch (type) {
case SeriesType.Based: {
s = createBaseLineSeries(chart, {
color,
...options,
});
// callback(chunks, valuesSkippedPlus1, length);
break;
}
case SeriesType.Candlestick: {
const candlestickSeries = createCandlesticksSeries(
chart,
options,
);
// // setValues(chunks, valuesSkippedPlus1, length, callback);
// // }
s = candlestickSeries[0];
defaultSeriesColor = candlestickSeries[1];
// // // const debouncedSetValues = debounce(setValues, 50);
// // function setValues(
// // chunks: any[],
// // valuesSkippedPlus1: number,
// // length: number,
// // callback: (values: any[]) => void,
// // ) {
// // const values = new Array(length);
break;
}
case SeriesType.Histogram: {
s = createHistogramSeries(chart, {
color,
...options,
});
// // let i = 0;
// // for (let k = 0; k < activeRange.length; k++) {
// // const chunk = chunks[k];
// // // const chunk =
// // // fetchedJSONs[chunkIdToIndex(dataset.scale, activeRange[k])]?.vec?.() ||
// // // [];
break;
}
default:
case SeriesType.Line: {
s = createLineSeries(chart, {
color,
...options,
});
// // for (let j = 0; j < chunk.length; j += valuesSkippedPlus1) {
// // // values[i++] = chunk[j];
// // // console.log(chunk[j]);
// // // callback(chunk[j]);
// // for (let i = 0; i < seriesList.length; i++) {
// // seriesList[i].update(chunk[j]);
// // }
break;
}
}
// // // i++;
// // }
// // }
if (priceScaleOptions) {
s.priceScale().applyOptions(priceScaleOptions);
}
// // console.log(i);
series.set(s);
}
// // if (i !== values.length) {
// // console.log({ n: i, values });
// // throw Error("error");
// // }
s.setData(values);
// // console.timeEnd(dataset.url);
// }
untrack(() => {
debouncedSetMinMaxMarkers();
});
});
});
createEffect(() => {
const s = series();
const currentVec = dataset.fetchedJSONs.at(index)?.vec();
const nextVec = dataset.fetchedJSONs.at(index + 1)?.vec();
if (s && currentVec?.length && nextVec?.length) {
s.update(nextVec[0]);
}
});
const isLast = createMemo(() => {
const last = lastActiveIndex();
return last !== undefined && last === index;
});
createEffect(() => {
series()?.applyOptions({
lastValueVisible: legend.drawn() && isLast(),
});
});
const inRange = createMemo(() => {
const range = activeRange();
if (range.length) {
const start = chunkIdToIndex(scale, range.at(0)!);
const end = chunkIdToIndex(scale, range.at(-1)!);
if (index >= start && index <= end) {
return true;
}
}
return false;
});
const visible = createMemo((previous: boolean) => {
if (legend.disabled()) {
return false;
}
return previous || inRange();
}, false);
createEffect(() => {
series()?.applyOptions({
visible: legend.drawn() && visible(),
});
});
});
return legend;
}
-2
View File
@@ -162,7 +162,6 @@ export function createPresets() {
{
title: "Mined",
color: colors.bitcoin,
seriesType: SeriesType.Area,
dataset: params.datasets.date.total_blocks_mined,
},
],
@@ -184,7 +183,6 @@ export function createPresets() {
{
title: "Size (MB)",
color: colors.darkWhite,
seriesType: SeriesType.Area,
dataset: params.datasets.date.cumulative_block_size,
},
],
+19 -4
View File
@@ -4,7 +4,10 @@ import { colors } from "../utils/colors";
import { replaceHistory } from "../utils/history";
import { stringToId } from "../utils/id";
import { resetURLParams } from "../utils/urlParams";
import { createPresets as createAddressesPresets } from "./addresses";
import {
createPresets as createAddressesPresets,
createLiquidityFolder,
} from "./addresses";
import { createPresets as createBlocksPresets } from "./blocks";
import { createPresets as createCoinblocksPresets } from "./coinblocks";
import { createPresets as createHodlersPresets } from "./hodlers";
@@ -31,7 +34,7 @@ export function createPresets(): Presets {
{
name: "By Date",
tree: [
createMarketPresets({ scale: "date" }),
createMarketPresets("date"),
createBlocksPresets(),
createMinersPresets("date"),
createTransactionsPresets("date"),
@@ -42,6 +45,12 @@ export function createPresets(): Presets {
name: "",
title: "",
}),
createLiquidityFolder({
scale: "date",
color: colors.bitcoin,
datasetKey: "",
name: "",
}),
createHodlersPresets({ scale: "date" }),
createAddressesPresets({ scale: "date" }),
createCoinblocksPresets({ scale: "date" }),
@@ -50,7 +59,7 @@ export function createPresets(): Presets {
{
name: "By Height",
tree: [
createMarketPresets({ scale: "height" }),
createMarketPresets("height"),
createMinersPresets("height"),
createTransactionsPresets("height"),
...createCohortPresetList({
@@ -60,6 +69,12 @@ export function createPresets(): Presets {
datasetKey: "",
title: "",
}),
createLiquidityFolder({
scale: "height",
color: colors.bitcoin,
datasetKey: "",
name: "",
}),
createHodlersPresets({ scale: "height" }),
createAddressesPresets({ scale: "height" }),
createCoinblocksPresets({ scale: "height" }),
@@ -101,7 +116,7 @@ export function createPresets(): Presets {
const serializedHistory: SerializedPresetsHistory = history().map(
({ preset, date }) => ({
p: preset.id,
d: date.valueOf(),
d: date.getTime(),
}),
);
+1 -20
View File
@@ -4,7 +4,7 @@ import { createPresets as createAveragesPresets } from "./averages";
import { createPresets as createIndicatorsPresets } from "./indicators";
import { createPresets as createReturnsPresets } from "./returns";
export function createPresets({ scale }: { scale: ResourceScale }) {
export function createPresets(scale: ResourceScale) {
return {
name: "Market",
tree: [
@@ -18,25 +18,6 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
},
description: "",
},
{
scale,
icon: IconTablerPercentage,
name: "Performance",
title: "Market Performance",
applyPreset(params) {
return applySeriesList({
...params,
priceOptions: {
id: "performance",
title: "Performance",
priceScaleOptions: {
mode: 2,
},
},
});
},
description: "",
},
{
scale,
icon: IconTablerInfinity,
@@ -60,7 +60,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Count",
color,
seriesType: SeriesType.Area,
dataset: params.datasets[scale][`${datasetPrefix}utxo_count`],
},
],
@@ -105,7 +104,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: `${name} Realized Cap.`,
color,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][`${datasetPrefix}realized_cap`],
},
@@ -160,7 +158,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
dataset:
params.datasets[scale][`${datasetPrefix}realized_profit`],
color: colors.profit,
seriesType: SeriesType.Area,
},
],
});
@@ -181,7 +178,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
dataset:
params.datasets[scale][`${datasetPrefix}realized_loss`],
color: colors.loss,
seriesType: SeriesType.Area,
},
],
});
@@ -274,7 +270,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Cumulative Realized Profit",
color: colors.profit,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_realized_profit`
@@ -297,7 +292,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Cumulative Realized Loss",
color: colors.loss,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_realized_loss`
@@ -371,7 +365,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
dataset:
params.datasets[scale][`${datasetPrefix}unrealized_profit`],
color: colors.profit,
seriesType: SeriesType.Area,
},
],
});
@@ -393,7 +386,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
dataset:
params.datasets[scale][`${datasetPrefix}unrealized_loss`],
color: colors.loss,
seriesType: SeriesType.Area,
},
],
});
@@ -539,7 +531,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color,
seriesType: SeriesType.Area,
dataset: params.datasets[scale][`${datasetPrefix}supply`],
},
],
@@ -558,7 +549,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color: colors.profit,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit`
@@ -581,7 +571,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color: colors.loss,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss`
@@ -658,7 +647,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_to_circulating_supply_ratio`
@@ -681,7 +669,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color: colors.profit,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_circulating_supply_ratio`
@@ -703,7 +690,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
bottom: [
{
title: "Supply",
seriesType: SeriesType.Area,
color: colors.loss,
dataset:
params.datasets[scale][
@@ -779,7 +765,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
{
title: "Supply",
color: colors.profit,
seriesType: SeriesType.Area,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_own_supply_ratio`
@@ -801,7 +786,6 @@ export function createCohortPresetList<Scale extends ResourceScale>({
bottom: [
{
title: "Supply",
seriesType: SeriesType.Area,
color: colors.loss,
dataset:
params.datasets[scale][
+13 -2
View File
@@ -24,7 +24,9 @@ type ApplyPreset = (params: {
parentDiv: HTMLDivElement;
datasets: Datasets;
preset: Preset;
legendSetter: Setter<PresetLegend>;
legendSetter: Setter<SeriesLegend[]>;
dark: boolean;
activeRange: RWS<number[]>;
}) => void;
interface PartialPresetFolder {
@@ -58,4 +60,13 @@ interface Presets {
select(preset: Preset): void;
}
type PresetLegend = SeriesLegend[];
type PriceSeriesType = "Candlestick" | "Line";
interface ChartObject {
scale: ResourceScale;
div: HTMLDivElement;
chart: IChartApi;
whitespace: ISeriesApi<"Line">;
legendList: SeriesLegend[];
debouncedSetMinMaxMarkers: VoidFunction;
}