general: snapshot

This commit is contained in:
k
2024-07-03 20:40:35 +02:00
parent b7e8cbea20
commit 069311dcf3
24 changed files with 407 additions and 312 deletions
+292 -39
View File
@@ -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);
// }
-1
View File
@@ -24,7 +24,6 @@ type ApplyPreset = (params: {
parentDiv: HTMLDivElement;
datasets: Datasets;
preset: Preset;
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
legendSetter: Setter<PresetLegend>;
}) => void;