mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-14 12:38:13 -07:00
general: snapshot
This commit is contained in:
@@ -1,19 +1,22 @@
|
||||
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 { initTimeScale } from "../lightweightCharts/chart/time";
|
||||
import { setWhitespace } from "../lightweightCharts/chart/whitespace";
|
||||
import { createAreaSeries } from "../lightweightCharts/series/creators/area";
|
||||
import {
|
||||
createBaseLineSeries,
|
||||
DEFAULT_BASELINE_COLORS,
|
||||
} from "../lightweightCharts/series/creators/baseLine";
|
||||
import { createCandlesticksSeries } from "../lightweightCharts/series/creators/candlesticks";
|
||||
import { createHistogramSeries } from "../lightweightCharts/series/creators/histogram";
|
||||
import { createSeriesLegend } from "../lightweightCharts/series/creators/legend";
|
||||
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,
|
||||
@@ -24,7 +27,7 @@ export enum SeriesType {
|
||||
|
||||
type SeriesConfig<Scale extends ResourceScale> =
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
dataset: ResourceDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: undefined;
|
||||
seriesType: SeriesType.Based;
|
||||
@@ -33,7 +36,7 @@ type SeriesConfig<Scale extends ResourceScale> =
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
dataset: ResourceDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: string[];
|
||||
seriesType: SeriesType.Histogram;
|
||||
@@ -42,7 +45,7 @@ type SeriesConfig<Scale extends ResourceScale> =
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
dataset: ResourceDataset<Scale>;
|
||||
color: string;
|
||||
colors?: undefined;
|
||||
seriesType?: SeriesType.Normal | SeriesType.Area;
|
||||
@@ -61,20 +64,18 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
datasets,
|
||||
priceDataset,
|
||||
priceOptions,
|
||||
activeResources,
|
||||
legendSetter,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: HTMLDivElement;
|
||||
preset: Preset;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
priceDataset?: AnyDataset<Scale>;
|
||||
priceDataset?: ResourceDataset<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) => {
|
||||
@@ -92,7 +93,9 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
|
||||
const priceSeriesType = createRWS<"Candlestick" | "Line">("Candlestick");
|
||||
|
||||
const valuesSkipped = createRWS(0);
|
||||
// const valuesSkipped = createRWS(0);
|
||||
|
||||
const activeDatasets: Set<ResourceDataset<any, any>> = new Set();
|
||||
|
||||
const charts = [top || [], bottom]
|
||||
.flatMap((list) => (list ? [list] : []))
|
||||
@@ -136,17 +139,20 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
const _legendList: PresetLegend = [];
|
||||
|
||||
if (index === 0) {
|
||||
const dataset =
|
||||
priceDataset ||
|
||||
(datasets[preset.scale as Scale].price as unknown as NonNullable<
|
||||
typeof priceDataset
|
||||
>);
|
||||
|
||||
activeDatasets.add(dataset);
|
||||
|
||||
const price = applyPriceSeries({
|
||||
chart,
|
||||
preset,
|
||||
seriesType: priceSeriesType,
|
||||
valuesSkipped,
|
||||
dataset:
|
||||
priceDataset ||
|
||||
(datasets[preset.scale as Scale].price as unknown as NonNullable<
|
||||
typeof priceDataset
|
||||
>),
|
||||
activeResources,
|
||||
// valuesSkipped,
|
||||
dataset,
|
||||
options: priceOptions,
|
||||
});
|
||||
|
||||
@@ -168,6 +174,8 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
options,
|
||||
defaultVisible,
|
||||
}) => {
|
||||
activeDatasets.add(dataset);
|
||||
|
||||
let series: ISeriesApi<
|
||||
"Baseline" | "Line" | "Area" | "Histogram"
|
||||
>;
|
||||
@@ -216,10 +224,10 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
series.setData(
|
||||
dataset?.values() || [],
|
||||
// computeDrawnSeriesValues(dataset?.values(), valuesSkipped()),
|
||||
);
|
||||
const values = dataset.values();
|
||||
console.log(values.length);
|
||||
|
||||
series.setData(values);
|
||||
});
|
||||
|
||||
return series;
|
||||
@@ -275,11 +283,13 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
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 / 5));
|
||||
// valuesSkipped.set(Math.floor(ratio / 1.25));
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
@@ -289,6 +299,10 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
50,
|
||||
);
|
||||
|
||||
initTimeScale({
|
||||
activeDatasets,
|
||||
});
|
||||
|
||||
charts.forEach(({ chart }, index) => {
|
||||
chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => {
|
||||
// Last chart otherwise length of timescale is Infinity
|
||||
@@ -327,31 +341,270 @@ export function applySeriesList<Scale extends ResourceScale>({
|
||||
reactiveChartList.set(() => charts.map(({ chart }) => chart));
|
||||
}
|
||||
|
||||
export function computeDrawnSeriesValues<T>(
|
||||
values: DatasetValue<T>[] | undefined,
|
||||
valuesSkipped: number,
|
||||
) {
|
||||
values = values || [];
|
||||
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");
|
||||
|
||||
if (valuesSkipped === 0) {
|
||||
return values;
|
||||
} else {
|
||||
const valuesSkippedPlus1 = valuesSkipped + 1;
|
||||
const id = options?.id || "price";
|
||||
const title = options?.title || "Price";
|
||||
|
||||
// console.log(_valuesSkippedPlus1);
|
||||
const url = "url" in dataset ? (dataset as any).url : undefined;
|
||||
|
||||
let length = Math.floor(values.length / valuesSkippedPlus1);
|
||||
const priceScaleOptions: DeepPartialPriceScaleOptions = {
|
||||
mode: 1,
|
||||
...options?.priceScaleOptions,
|
||||
};
|
||||
|
||||
// console.log(length);
|
||||
let [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, options);
|
||||
|
||||
const filteredValues = new Array(length);
|
||||
const ohlcLegend = createSeriesLegend({
|
||||
id,
|
||||
presetId: preset.id,
|
||||
title,
|
||||
color: () => ohlcColors,
|
||||
series: ohlcSeries,
|
||||
disabled: () => seriesType() !== "Candlestick",
|
||||
url,
|
||||
});
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
filteredValues[i] = values[i * valuesSkippedPlus1];
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// console.log(filteredValues.length);
|
||||
|
||||
return filteredValues;
|
||||
}
|
||||
return { ohlcLegend, lineLegend };
|
||||
}
|
||||
|
||||
// // const computeDrawnSeriesValues = debounce(_computeDrawnSeriesValues, 100);
|
||||
|
||||
// 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 { fetchedJSONs, activeRange: _activeRange } = dataset;
|
||||
|
||||
// const activeRange = _activeRange();
|
||||
|
||||
// const valuesSkippedPlus1 = valuesSkipped + 1;
|
||||
|
||||
// if (valuesSkippedPlus1 === 1) {
|
||||
// console.log("todo valuesSkippedPlus1===1, skip for now");
|
||||
// }
|
||||
|
||||
// // for (let i = 0; i < seriesList.length; i++) {
|
||||
// // seriesList[i].
|
||||
// // }
|
||||
|
||||
// const chunks = new Array(activeRange.length);
|
||||
// let length = 0;
|
||||
|
||||
// for (let i = 0; i < chunks.length; i++) {
|
||||
// const chunk =
|
||||
// fetchedJSONs[chunkIdToIndex(dataset.scale, activeRange[i])]?.vec?.() ||
|
||||
// [];
|
||||
|
||||
// chunks[i] = chunk;
|
||||
|
||||
// length += Math.ceil(chunk.length / valuesSkippedPlus1);
|
||||
// }
|
||||
|
||||
// callback(chunks, valuesSkippedPlus1, length);
|
||||
|
||||
// // setValues(chunks, valuesSkippedPlus1, length, callback);
|
||||
// // }
|
||||
|
||||
// // // const debouncedSetValues = debounce(setValues, 50);
|
||||
// // function setValues(
|
||||
// // chunks: any[],
|
||||
// // valuesSkippedPlus1: number,
|
||||
// // length: number,
|
||||
// // callback: (values: any[]) => void,
|
||||
// // ) {
|
||||
// // const values = new Array(length);
|
||||
|
||||
// // let i = 0;
|
||||
// // for (let k = 0; k < activeRange.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]);
|
||||
// // }
|
||||
|
||||
// // // i++;
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // console.log(i);
|
||||
|
||||
// // if (i !== values.length) {
|
||||
// // console.log({ n: i, values });
|
||||
// // throw Error("error");
|
||||
// // }
|
||||
|
||||
// // console.timeEnd(dataset.url);
|
||||
// }
|
||||
|
||||
Vendored
-1
@@ -24,7 +24,6 @@ type ApplyPreset = (params: {
|
||||
parentDiv: HTMLDivElement;
|
||||
datasets: Datasets;
|
||||
preset: Preset;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
}) => void;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user