mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-10 06:53:33 -07:00
general: snapshot
This commit is contained in:
+3
-2
@@ -9,10 +9,11 @@
|
||||
- General
|
||||
- Added a light theme !
|
||||
- Performance
|
||||
- Added height datasets and many optimizations to make them usable
|
||||
- Added split panes in order to always have the vertical axis visible
|
||||
- Improved app's reactivity
|
||||
- Added some chunk splitting for a faster initial load
|
||||
- Global improvements that increased the Lighthouse's performance score from the low 30s to the high 70s
|
||||
- Chart
|
||||
- Global improvements that increased the Lighthouse's performance score
|
||||
- Fixed legend hovering on mobile not resetting on touch end
|
||||
- Updated legend padding so that the scrollbar, if visible, is less in the way
|
||||
- Added "3 months" and yearly time scale setters (from year 2009 to today)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
Satonomics is a Bitcoin only on-chain data generator and visualizer that is fully free, open source, verifiable, local-first and self-hostable.
|
||||
Satonomics is a better, FOSS, Bitcoin-only, self-hostable Glassnode.
|
||||
|
||||
While [mempool.space](https://mempool.space) gives a very micro view of the network where you can follow the journey of any address, this tool on the other hand, is the exact opposite and very complimentary by giving you a much more global/macro view of the flow and various dynamics of the network.
|
||||
|
||||
@@ -19,9 +19,11 @@ This project is in a very early stage. The web app will have bugs, the API might
|
||||
## Instances
|
||||
|
||||
Web App:
|
||||
|
||||
- [app.satonomics.xyz](https://app.satonomics.xyz)
|
||||
|
||||
API:
|
||||
|
||||
- [api.satonomics.xyz](https://api.satonomics.xyz)
|
||||
|
||||
## Structure
|
||||
|
||||
+1
-2
@@ -19,7 +19,6 @@
|
||||
"@leeoniya/ufuzzy": "^1.0.14",
|
||||
"@solid-primitives/event-listener": "^2.3.3",
|
||||
"@solid-primitives/intersection-observer": "^2.1.6",
|
||||
"@solid-primitives/memo": "^1.3.8",
|
||||
"@solid-primitives/resize-observer": "^2.0.25",
|
||||
"lean-qr": "^2.3.4",
|
||||
"lightweight-charts": "^4.1.6",
|
||||
@@ -36,7 +35,7 @@
|
||||
"pwa-asset-generator": "^6.3.1",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"typescript": "^5.5.2",
|
||||
"typescript": "^5.5.3",
|
||||
"unplugin-auto-import": "^0.17.6",
|
||||
"unplugin-icons": "^0.19.0",
|
||||
"vite": "^5.3.2",
|
||||
|
||||
Generated
+21
-42
@@ -14,9 +14,6 @@ dependencies:
|
||||
'@solid-primitives/intersection-observer':
|
||||
specifier: ^2.1.6
|
||||
version: 2.1.6(solid-js@1.8.18)
|
||||
'@solid-primitives/memo':
|
||||
specifier: ^1.3.8
|
||||
version: 1.3.8(solid-js@1.8.18)
|
||||
'@solid-primitives/resize-observer':
|
||||
specifier: ^2.0.25
|
||||
version: 2.0.25(solid-js@1.8.18)
|
||||
@@ -62,8 +59,8 @@ devDependencies:
|
||||
specifier: ^3.4.4
|
||||
version: 3.4.4
|
||||
typescript:
|
||||
specifier: ^5.5.2
|
||||
version: 5.5.2
|
||||
specifier: ^5.5.3
|
||||
version: 5.5.3
|
||||
unplugin-auto-import:
|
||||
specifier: ^0.17.6
|
||||
version: 0.17.6(rollup@2.79.1)
|
||||
@@ -2251,16 +2248,6 @@ packages:
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/memo@1.3.8(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-U75pfLFSxFmM2xbx1+2XPPyWbaXrnUFF10spbFuOUgJ7azrC+4y+FnrVi4RKqHw9gftd8aKQuTiyMQq468YLQw==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/scheduled': 1.4.3(solid-js@1.8.18)
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/resize-observer@2.0.25(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-jVDXkt2MiriYRaz4DYs62185d+6jQ+1DCsR+v7f6XMsIJJuf963qdBRFjtZtKXBaxdPNMyuPeDgf5XQe3EoDJg==}
|
||||
peerDependencies:
|
||||
@@ -2282,14 +2269,6 @@ packages:
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/scheduled@1.4.3(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-HfWN5w7b7FEc6VPLBKnnE302h90jsLMuR28Fcf7neRGGf8jBj6wm6/UFQ00VlKexHFMR6KQ2u4VBh5a1ZcqM8g==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/static-store@0.0.8(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-ZecE4BqY0oBk0YG00nzaAWO5Mjcny8Fc06CdbXadH9T9lzq/9GefqcSe/5AtdXqjvY/DtJ5C6CkcjPZO0o/eqg==}
|
||||
peerDependencies:
|
||||
@@ -2528,7 +2507,7 @@ packages:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.23.1
|
||||
caniuse-lite: 1.0.30001638
|
||||
caniuse-lite: 1.0.30001639
|
||||
fraction.js: 4.3.7
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.1
|
||||
@@ -2655,8 +2634,8 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001638
|
||||
electron-to-chromium: 1.4.815
|
||||
caniuse-lite: 1.0.30001639
|
||||
electron-to-chromium: 1.4.816
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.16(browserslist@4.23.1)
|
||||
dev: true
|
||||
@@ -2715,8 +2694,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/caniuse-lite@1.0.30001638:
|
||||
resolution: {integrity: sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==}
|
||||
/caniuse-lite@1.0.30001639:
|
||||
resolution: {integrity: sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==}
|
||||
dev: true
|
||||
|
||||
/capnp-ts@0.7.0:
|
||||
@@ -3122,8 +3101,8 @@ packages:
|
||||
jake: 10.9.1
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium@1.4.815:
|
||||
resolution: {integrity: sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==}
|
||||
/electron-to-chromium@1.4.816:
|
||||
resolution: {integrity: sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
@@ -4125,7 +4104,7 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
dependencies:
|
||||
mlly: 1.7.1
|
||||
pkg-types: 1.1.1
|
||||
pkg-types: 1.1.2
|
||||
dev: true
|
||||
|
||||
/locate-path@5.0.0:
|
||||
@@ -4349,7 +4328,7 @@ packages:
|
||||
dependencies:
|
||||
acorn: 8.12.0
|
||||
pathe: 1.1.2
|
||||
pkg-types: 1.1.1
|
||||
pkg-types: 1.1.2
|
||||
ufo: 1.5.3
|
||||
dev: true
|
||||
|
||||
@@ -4632,8 +4611,8 @@ packages:
|
||||
find-up: 4.1.0
|
||||
dev: true
|
||||
|
||||
/pkg-types@1.1.1:
|
||||
resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
|
||||
/pkg-types@1.1.2:
|
||||
resolution: {integrity: sha512-VEGf1he2DR5yowYRl0XJhWJq5ktm9gYIsH+y8sNJpHlxch7JPDaufgrsl4vYjd9hMUY8QVjoNncKbow9I7exyA==}
|
||||
dependencies:
|
||||
confbox: 0.1.7
|
||||
mlly: 1.7.1
|
||||
@@ -5671,8 +5650,8 @@ packages:
|
||||
possible-typed-array-names: 1.0.0
|
||||
dev: true
|
||||
|
||||
/typescript@5.5.2:
|
||||
resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==}
|
||||
/typescript@5.5.3:
|
||||
resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
@@ -5754,10 +5733,10 @@ packages:
|
||||
magic-string: 0.30.10
|
||||
mlly: 1.7.1
|
||||
pathe: 1.1.2
|
||||
pkg-types: 1.1.1
|
||||
pkg-types: 1.1.2
|
||||
scule: 1.3.0
|
||||
strip-literal: 2.1.0
|
||||
unplugin: 1.10.2
|
||||
unplugin: 1.11.0
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
@@ -5793,7 +5772,7 @@ packages:
|
||||
magic-string: 0.30.10
|
||||
minimatch: 9.0.5
|
||||
unimport: 3.7.2(rollup@2.79.1)
|
||||
unplugin: 1.10.2
|
||||
unplugin: 1.11.0
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
@@ -5824,13 +5803,13 @@ packages:
|
||||
debug: 4.3.5
|
||||
kolorist: 1.8.0
|
||||
local-pkg: 0.5.0
|
||||
unplugin: 1.10.2
|
||||
unplugin: 1.11.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/unplugin@1.10.2:
|
||||
resolution: {integrity: sha512-KuPqnjU4HBcrSwmQatfdc5hU4xzaQrhoKqCKylwmLnbBvqj5udXL8cHrkOuYDoI4ESCwJIiAIKMujroIUKLgow==}
|
||||
/unplugin@1.11.0:
|
||||
resolution: {integrity: sha512-3r7VWZ/webh0SGgJScpWl2/MRCZK5d3ZYFcNaeci/GQ7Teop7zf0Nl2pUuz7G21BwPd9pcUPOC5KmJ2L3WgC5g==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
dependencies:
|
||||
acorn: 8.12.0
|
||||
|
||||
@@ -4,14 +4,12 @@ export function Chart({
|
||||
presets,
|
||||
datasets,
|
||||
legendSetter,
|
||||
activeResources,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: RWS<HTMLDivElement | undefined>;
|
||||
presets: Presets;
|
||||
datasets: Datasets;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
onMount(() => {
|
||||
createEffect(() => {
|
||||
@@ -28,7 +26,6 @@ export function Chart({
|
||||
parentDiv: div,
|
||||
datasets,
|
||||
preset,
|
||||
activeResources,
|
||||
legendSetter,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import { Title } from "./components/title";
|
||||
export function ChartFrame({
|
||||
presets,
|
||||
datasets,
|
||||
activeResources,
|
||||
hide,
|
||||
qrcode,
|
||||
standalone,
|
||||
@@ -20,7 +19,6 @@ export function ChartFrame({
|
||||
presets: Presets;
|
||||
hide?: Accessor<boolean>;
|
||||
qrcode: RWS<string>;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
datasets: Datasets;
|
||||
fullscreen?: RWS<boolean>;
|
||||
standalone: boolean;
|
||||
@@ -64,7 +62,6 @@ export function ChartFrame({
|
||||
<Chart
|
||||
parentDiv={div}
|
||||
charts={charts}
|
||||
activeResources={activeResources}
|
||||
datasets={datasets}
|
||||
legendSetter={legend.set}
|
||||
presets={presets}
|
||||
|
||||
@@ -136,13 +136,7 @@ export function App() {
|
||||
},
|
||||
);
|
||||
|
||||
const activeResources = createRWS<Set<ResourceDataset<any, any>>>(new Set(), {
|
||||
equals: false,
|
||||
});
|
||||
|
||||
const datasets = createDatasets({
|
||||
setActiveResources: activeResources.set,
|
||||
});
|
||||
const datasets = createDatasets();
|
||||
|
||||
onMount(() => {
|
||||
webSockets.openAll();
|
||||
@@ -273,7 +267,6 @@ export function App() {
|
||||
qrcode={qrcode}
|
||||
standalone={false}
|
||||
datasets={datasets}
|
||||
activeResources={activeResources}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
@@ -340,7 +333,6 @@ export function App() {
|
||||
presets={presets}
|
||||
qrcode={qrcode}
|
||||
fullscreen={fullscreen}
|
||||
activeResources={activeResources}
|
||||
datasets={datasets}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -4,11 +4,9 @@ export { averages } from "./consts/averages";
|
||||
|
||||
export function createScaleDatasets<Scale extends ResourceScale>({
|
||||
scale,
|
||||
setActiveResources,
|
||||
groupedKeysToURLPath,
|
||||
}: {
|
||||
scale: Scale;
|
||||
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
|
||||
groupedKeysToURLPath: GroupedKeysToURLPath[Scale];
|
||||
}) {
|
||||
type Key = keyof typeof groupedKeysToURLPath;
|
||||
@@ -23,7 +21,6 @@ export function createScaleDatasets<Scale extends ResourceScale>({
|
||||
datasets[key as unknown as Exclude<Key, "ohlc">] = createResourceDataset({
|
||||
scale,
|
||||
path: groupedKeysToURLPath[key as Key] as any,
|
||||
setActiveResources,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -31,7 +28,6 @@ export function createScaleDatasets<Scale extends ResourceScale>({
|
||||
const price = createResourceDataset<Scale, OHLC>({
|
||||
scale,
|
||||
path: `/${scale}-to-ohlc`,
|
||||
setActiveResources,
|
||||
});
|
||||
|
||||
Object.assign(datasets, { price });
|
||||
|
||||
@@ -3,10 +3,8 @@ import { createResourceDataset } from "./resource";
|
||||
export { averages } from "./consts/averages";
|
||||
|
||||
export function createDateDatasets({
|
||||
setActiveResources,
|
||||
groupedKeysToURLPath,
|
||||
}: {
|
||||
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
|
||||
groupedKeysToURLPath: GroupedKeysToURLPath["date"];
|
||||
}) {
|
||||
type Key = keyof typeof groupedKeysToURLPath;
|
||||
@@ -21,7 +19,6 @@ export function createDateDatasets({
|
||||
datasets[key as Exclude<Key, "ohlc">] = createResourceDataset<"date">({
|
||||
scale: "date",
|
||||
path: groupedKeysToURLPath[key as Key],
|
||||
setActiveResources,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -29,7 +26,6 @@ export function createDateDatasets({
|
||||
const price = createResourceDataset<"date", OHLC>({
|
||||
scale: "date",
|
||||
path: "/date-to-ohlc",
|
||||
setActiveResources,
|
||||
});
|
||||
|
||||
Object.assign(datasets, { price });
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { createResourceDataset } from "./resource";
|
||||
|
||||
export function createHeightDatasets({
|
||||
setActiveResources,
|
||||
groupedKeysToURLPath,
|
||||
}: {
|
||||
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
|
||||
groupedKeysToURLPath: GroupedKeysToURLPath["height"];
|
||||
}) {
|
||||
type Key = keyof typeof groupedKeysToURLPath;
|
||||
@@ -19,7 +17,6 @@ export function createHeightDatasets({
|
||||
datasets[key as Exclude<Key, "ohlc">] = createResourceDataset<"height">({
|
||||
scale: "height",
|
||||
path: groupedKeysToURLPath[key as Key],
|
||||
setActiveResources,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -27,7 +24,6 @@ export function createHeightDatasets({
|
||||
const price = createResourceDataset<"height", OHLC>({
|
||||
scale: "height",
|
||||
path: "/height-to-ohlc",
|
||||
setActiveResources,
|
||||
});
|
||||
|
||||
Object.assign(datasets, { price });
|
||||
|
||||
@@ -7,18 +7,12 @@ export const scales = ["date" as const, "height" as const];
|
||||
|
||||
export const HEIGHT_CHUNK_SIZE = 10_000;
|
||||
|
||||
export function createDatasets({
|
||||
setActiveResources,
|
||||
}: {
|
||||
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
export function createDatasets() {
|
||||
const date = createDateDatasets({
|
||||
setActiveResources,
|
||||
groupedKeysToURLPath: groupedKeysToURLPath.date,
|
||||
});
|
||||
|
||||
const height = createHeightDatasets({
|
||||
setActiveResources,
|
||||
groupedKeysToURLPath: groupedKeysToURLPath.height,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { createLazyMemo } from "@solid-primitives/memo";
|
||||
|
||||
import {
|
||||
ONE_DAY_IN_MS,
|
||||
ONE_HOUR_IN_MS,
|
||||
@@ -8,19 +6,12 @@ import {
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { HEIGHT_CHUNK_SIZE } from ".";
|
||||
import { debounce } from "../utils/debounce";
|
||||
|
||||
export function createResourceDataset<
|
||||
Scale extends ResourceScale,
|
||||
Type extends OHLC | number = number,
|
||||
>({
|
||||
scale,
|
||||
path,
|
||||
setActiveResources,
|
||||
}: {
|
||||
scale: Scale;
|
||||
path: string;
|
||||
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
>({ scale, path }: { scale: Scale; path: string }) {
|
||||
type Dataset = Scale extends "date"
|
||||
? FetchedDateDataset<Type>
|
||||
: FetchedHeightDataset<Type>;
|
||||
@@ -85,8 +76,7 @@ export function createResourceDataset<
|
||||
}) as FetchedResult<Scale, Type>[];
|
||||
|
||||
const _fetch = async (id: number) => {
|
||||
const index =
|
||||
scale === "date" ? id - 2009 : Math.floor(id / HEIGHT_CHUNK_SIZE);
|
||||
const index = chunkIdToIndex(scale, id);
|
||||
|
||||
if (
|
||||
index < 0 ||
|
||||
@@ -205,25 +195,43 @@ export function createResourceDataset<
|
||||
fetched.loading = false;
|
||||
};
|
||||
|
||||
const valuesCallback = (vecs: Value[][]) => {
|
||||
let length = 0;
|
||||
for (let i = 0; i < vecs.length; i++) {
|
||||
length += vecs[i].length;
|
||||
}
|
||||
|
||||
if (!length) return;
|
||||
|
||||
const array = new Array(length);
|
||||
let k = 0;
|
||||
for (let i = 0; i < vecs.length; i++) {
|
||||
let vec = vecs[i];
|
||||
for (let j = 0; j < vec.length; j++) {
|
||||
array[k++] = vec[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (k !== length) throw Error("e");
|
||||
|
||||
values.set(array);
|
||||
};
|
||||
|
||||
const debouncedValuesCallback = debounce(valuesCallback, 100);
|
||||
|
||||
const values = createRWS<Value[]>([]);
|
||||
|
||||
createEffect(() => {
|
||||
const vecs = fetchedJSONs.map((fetched) => fetched.vec() || []);
|
||||
debouncedValuesCallback(vecs);
|
||||
});
|
||||
|
||||
const resource: ResourceDataset<Scale, Type> = {
|
||||
scale,
|
||||
url: baseURL,
|
||||
fetch: _fetch,
|
||||
fetchedJSONs,
|
||||
values: createLazyMemo(() => {
|
||||
setActiveResources((resources) => resources.add(resource));
|
||||
|
||||
onCleanup(() =>
|
||||
setActiveResources((resources) => {
|
||||
resources.delete(resource);
|
||||
return resources;
|
||||
}),
|
||||
);
|
||||
|
||||
const flat = fetchedJSONs.flatMap((fetched) => fetched.vec() || []);
|
||||
|
||||
return flat;
|
||||
}),
|
||||
values,
|
||||
drop() {
|
||||
fetchedJSONs.forEach((fetched) => {
|
||||
fetched.at = null;
|
||||
@@ -245,3 +253,7 @@ async function convertResponseToJSON<
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function chunkIdToIndex(scale: ResourceScale, id: number) {
|
||||
return scale === "date" ? id - 2009 : Math.floor(id / HEIGHT_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
Vendored
+3
-12
@@ -8,14 +8,6 @@ type ResourceScale = (typeof import("./index").scales)[index];
|
||||
|
||||
type DatasetValue<T> = T & Numbered & Valued;
|
||||
|
||||
interface Dataset<
|
||||
Scale extends ResourceScale,
|
||||
Value extends SingleValueData | CandlestickData = SingleValueData,
|
||||
> {
|
||||
scale: Scale;
|
||||
values: Accessor<DatasetValue<Value>[]>;
|
||||
}
|
||||
|
||||
interface ResourceDataset<
|
||||
Scale extends ResourceScale,
|
||||
Type extends OHLC | number = number,
|
||||
@@ -27,16 +19,15 @@ interface ResourceDataset<
|
||||
Value extends SingleValueData | CandlestickData = Type extends number
|
||||
? SingleValueData
|
||||
: CandlestickData,
|
||||
> extends Dataset<Scale, Value> {
|
||||
> {
|
||||
scale: Scale;
|
||||
url: string;
|
||||
fetch: (id: number) => void;
|
||||
fetchedJSONs: FetchedResult<Scale, Type>[];
|
||||
values: Accessor<DatasetValue<Value>[]>;
|
||||
drop: VoidFunction;
|
||||
}
|
||||
|
||||
type AnyDataset<Scale extends ResourceScale> = Dataset<Scale> &
|
||||
Partial<ResourceDataset<Scale>>;
|
||||
|
||||
interface FetchedResult<
|
||||
Scale extends ResourceScale,
|
||||
Type extends number | OHLC,
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { webSockets } from "../../ws";
|
||||
import { createCandlesticksSeries } from "../series/creators/candlesticks";
|
||||
import { createSeriesLegend } from "../series/creators/legend";
|
||||
import { createLineSeries } from "../series/creators/line";
|
||||
import { initTimeScale } from "./time";
|
||||
|
||||
export const PRICE_SCALE_MOMENTUM_ID = "momentum";
|
||||
|
||||
export const applyPriceSeries = <
|
||||
Scale extends ResourceScale,
|
||||
T extends SingleValueData,
|
||||
>({
|
||||
chart,
|
||||
preset,
|
||||
dataset,
|
||||
seriesType,
|
||||
valuesSkipped,
|
||||
options,
|
||||
activeResources,
|
||||
}: {
|
||||
chart: IChartApi;
|
||||
preset: Preset;
|
||||
valuesSkipped: Accessor<number>;
|
||||
seriesType: Accessor<"Candlestick" | "Line">;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
dataset: Dataset<Scale, T>;
|
||||
options?: PriceSeriesOptions;
|
||||
}) => {
|
||||
const id = options?.id || "price";
|
||||
const title = options?.title || "Price";
|
||||
|
||||
const url = "url" in dataset ? (dataset as any).url : undefined;
|
||||
|
||||
const priceScaleOptions: DeepPartialPriceScaleOptions = {
|
||||
mode: 1,
|
||||
...options?.priceScaleOptions,
|
||||
};
|
||||
|
||||
const [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;
|
||||
|
||||
const 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);
|
||||
|
||||
// ---
|
||||
|
||||
// setMinMaxMarkers({
|
||||
// scale: preset.scale,
|
||||
// candlesticks:
|
||||
// dataset?.values() || datasets[preset.scale].price.values() || ([] as any),
|
||||
// range: chartState.range,
|
||||
// lowerOpacity,
|
||||
// });
|
||||
|
||||
initTimeScale({
|
||||
activeResources,
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
const values = dataset.values();
|
||||
// const values = computeDrawnSeriesValues(dataset.values(), valuesSkipped());
|
||||
|
||||
lineSeries.setData(values);
|
||||
ohlcSeries.setData(values);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (preset.scale === "date") {
|
||||
const latest = webSockets.liveKrakenCandle.latest();
|
||||
|
||||
if (latest) {
|
||||
ohlcSeries.update(latest);
|
||||
lineSeries.update(latest);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { ohlcLegend, lineLegend };
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
import { HEIGHT_CHUNK_SIZE } from "../../datasets";
|
||||
import { debounce } from "../../utils/debounce";
|
||||
import { writeURLParam } from "../../utils/urlParams";
|
||||
import { setMinMaxMarkers } from "./markers";
|
||||
import {
|
||||
chartState,
|
||||
LOCAL_STORAGE_RANGE_KEY,
|
||||
@@ -20,9 +19,9 @@ const debouncedUpdateURLParams = debounce((range: TimeRange | null) => {
|
||||
}, 500);
|
||||
|
||||
export function initTimeScale({
|
||||
activeResources,
|
||||
activeDatasets,
|
||||
}: {
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
activeDatasets: Set<ResourceDataset<any, any>>;
|
||||
}) {
|
||||
setTimeScale(chartState.range);
|
||||
|
||||
@@ -46,7 +45,7 @@ export function initTimeScale({
|
||||
}
|
||||
|
||||
ids.forEach((id) => {
|
||||
activeResources().forEach((resource) => resource.fetch(id));
|
||||
activeDatasets.forEach((dataset) => dataset.fetch(id));
|
||||
});
|
||||
}, 100);
|
||||
|
||||
@@ -63,6 +62,7 @@ export function initTimeScale({
|
||||
chartState.range = range;
|
||||
});
|
||||
}, 50);
|
||||
|
||||
onCleanup(() => clearTimeout(timeout));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,17 +27,16 @@ const whitespaceDateDataset: (SingleValueData & Numbered)[] = new Array(
|
||||
};
|
||||
});
|
||||
|
||||
const whitespaceHeightDataset: (WhitespaceData & Numbered)[] = new Array(
|
||||
840_000,
|
||||
const heightStart = -100_000;
|
||||
const whitespaceHeightDataset: (SingleValueData & Numbered)[] = new Array(
|
||||
1_200_000,
|
||||
)
|
||||
.fill(0)
|
||||
.map(
|
||||
(_, index) =>
|
||||
({
|
||||
time: index,
|
||||
number: index,
|
||||
}) as any,
|
||||
);
|
||||
.map((_, index) => ({
|
||||
time: (heightStart + index) as any,
|
||||
number: heightStart + index,
|
||||
value: NaN,
|
||||
}));
|
||||
|
||||
export function setWhitespace(chart: IChartApi, scale: ResourceScale) {
|
||||
const whitespaceSeries = createLineSeries(chart);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { PRICE_SCALE_MOMENTUM_ID } from "../../chart/price";
|
||||
import { defaultSeriesOptions } from "./options";
|
||||
|
||||
type HistogramOptions = DeepPartial<
|
||||
HistogramStyleOptions & SeriesOptionsCommon
|
||||
>;
|
||||
|
||||
export const PRICE_SCALE_MOMENTUM_ID = "momentum";
|
||||
|
||||
export const createHistogramSeries = (
|
||||
chart: IChartApi,
|
||||
options?: HistogramOptions,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ export const convertCandleToVolumeColor = (
|
||||
|
||||
export const colors = {
|
||||
white,
|
||||
black,
|
||||
darkWhite,
|
||||
gray,
|
||||
lightBitcoin: yellow,
|
||||
|
||||
Generated
+7
-7
@@ -1061,12 +1061,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memory-stats"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34f79cf9964c5c9545493acda1263f1912f8d2c56c8a2ffee2606cb960acaacc"
|
||||
checksum = "c73f5c649995a115e1a0220b35e4df0a1294500477f97a91d0660fb5abeb574a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1209,9 +1209,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "4.2.0"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e"
|
||||
checksum = "19ff2cf528c6c03d9ed653d6c4ce1dc0582dc4af309790ad92f07c1cd551b0be"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
@@ -1648,9 +1648,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.117"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
||||
+3
-3
@@ -20,12 +20,12 @@ fastrand = "2.1.0"
|
||||
inferno = "0.11.19"
|
||||
itertools = "0.13.0"
|
||||
leveldb = "0.8.6"
|
||||
memory-stats = "1.1.0"
|
||||
memory-stats = "1.2.0"
|
||||
nohash = "0.2.0"
|
||||
ordered-float = "4.2.0"
|
||||
ordered-float = "4.2.1"
|
||||
par-iter-sync = "0.1.11"
|
||||
rayon = "1.10.0"
|
||||
reqwest = { version = "0.12.5", features = ["blocking", "json"] }
|
||||
sanakirja = "1.4.2"
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
serde_json = "1.0.117"
|
||||
serde_json = "1.0.120"
|
||||
|
||||
Generated
+13
-13
@@ -1242,12 +1242,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "memory-stats"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34f79cf9964c5c9545493acda1263f1912f8d2c56c8a2ffee2606cb960acaacc"
|
||||
checksum = "c73f5c649995a115e1a0220b35e4df0a1294500477f97a91d0660fb5abeb574a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1390,9 +1390,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "4.2.0"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e"
|
||||
checksum = "19ff2cf528c6c03d9ed653d6c4ce1dc0582dc4af309790ad92f07c1cd551b0be"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
@@ -1601,9 +1601,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -1874,9 +1874,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.117"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -2114,9 +2114,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -2133,9 +2133,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
+5
-5
@@ -7,12 +7,12 @@ edition = "2021"
|
||||
axum = "0.7.5"
|
||||
color-eyre = "0.6.3"
|
||||
itertools = "0.12.1"
|
||||
regex = "1.10.4"
|
||||
regex = "1.10.5"
|
||||
bincode = { git = "https://github.com/bincode-org/bincode.git" }
|
||||
reqwest = { version = "0.12.4", features = ["json"] }
|
||||
serde = { version = "1.0.199", features = ["derive"] }
|
||||
serde_json = { version = "1.0.116" }
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
reqwest = { version = "0.12.5", features = ["json"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
serde_json = { version = "1.0.120" }
|
||||
tokio = { version = "1.38.0", features = ["full"] }
|
||||
tower-http = { version = "0.5.2", features = ["compression-full"] }
|
||||
parser = { path = "../parser" }
|
||||
derive_deref = "1.1.1"
|
||||
|
||||
Reference in New Issue
Block a user