mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-08 14:11:56 -07:00
heatmaps: part 11
This commit is contained in:
@@ -116,6 +116,7 @@ function loadRange() {
|
||||
}
|
||||
|
||||
let cursor = 0;
|
||||
let needsRebuild = false;
|
||||
const workers = Array.from({
|
||||
length: Math.min(MAX_PARALLEL_FETCHES, missing.length),
|
||||
}).map(async () => {
|
||||
@@ -123,10 +124,17 @@ function loadRange() {
|
||||
while (index !== undefined) {
|
||||
const entry = missing[index];
|
||||
try {
|
||||
const points = await option.points.fetch(entry.date, controller.signal);
|
||||
const points = await option.points.fetch(
|
||||
entry.date,
|
||||
controller.signal,
|
||||
(points) => {
|
||||
if (isCurrentLoad(option, controller, generation)) {
|
||||
setPoints(entry, points);
|
||||
}
|
||||
},
|
||||
);
|
||||
if (isCurrentLoad(option, controller, generation)) {
|
||||
pointsByDate.set(entry.date, points);
|
||||
addDateToGrid(entry.dateIndex, points);
|
||||
setPoints(entry, points);
|
||||
}
|
||||
} catch (error) {
|
||||
if (controller.signal.aborted) return;
|
||||
@@ -147,7 +155,11 @@ function loadRange() {
|
||||
void Promise.all(workers).then(() => {
|
||||
if (isCurrentLoad(option, controller, generation)) {
|
||||
updateStatus(completed, currentDates.length, failed);
|
||||
paint();
|
||||
if (needsRebuild) {
|
||||
rebuildGrid();
|
||||
} else {
|
||||
paint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -157,6 +169,21 @@ function loadRange() {
|
||||
cursor += 1;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ date: string, dateIndex: number }} entry
|
||||
* @param {HeatmapPoints} points
|
||||
*/
|
||||
function setPoints(entry, points) {
|
||||
const previous = pointsByDate.get(entry.date);
|
||||
if (previous && samePoints(previous, points)) return;
|
||||
pointsByDate.set(entry.date, points);
|
||||
if (previous) {
|
||||
needsRebuild = true;
|
||||
} else {
|
||||
addDateToGrid(entry.dateIndex, points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,6 +236,20 @@ function addDateToGrid(dateIndex, points) {
|
||||
if (dirtyCol !== undefined) schedulePaint(dirtyCol);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HeatmapPoints} a
|
||||
* @param {HeatmapPoints} b
|
||||
*/
|
||||
function samePoints(a, b) {
|
||||
if (a === b) return true;
|
||||
if (a.kind !== b.kind || a.values !== b.values) return false;
|
||||
if (a.kind === "implicit" && b.kind === "implicit") {
|
||||
return a.yStart === b.yStart && a.yStep === b.yStep;
|
||||
}
|
||||
if (a.kind === "explicit" && b.kind === "explicit") return a.y === b.y;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @param {number} col */
|
||||
function schedulePaint(col) {
|
||||
dirtyCols.add(col);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { defaultTooltip } from "./tooltip.js";
|
||||
const BINS = 2400;
|
||||
const MIN_LOG = -8;
|
||||
const BINS_PER_DECADE = 200;
|
||||
const MAX_LOG = MIN_LOG + (BINS - 1) / BINS_PER_DECADE;
|
||||
|
||||
export const oracleRawHeatmapOption = createOracleHeatmapOption("raw", "Raw");
|
||||
export const oracleEmaHeatmapOption = createOracleHeatmapOption("ema", "EMA");
|
||||
@@ -24,7 +25,8 @@ function createOracleHeatmapOption(mode, name) {
|
||||
name,
|
||||
title: `Oracle ${name} Histogram`,
|
||||
points: {
|
||||
fetch: (date, signal) => fetchOraclePoints(mode, date, signal),
|
||||
fetch: (date, signal, onPoints) =>
|
||||
fetchOraclePoints(mode, date, signal, onPoints),
|
||||
},
|
||||
grid: createAverageGrid({
|
||||
yStart: MIN_LOG,
|
||||
@@ -40,40 +42,44 @@ function createOracleHeatmapOption(mode, name) {
|
||||
* @param {"raw" | "ema"} mode
|
||||
* @param {string} date
|
||||
* @param {AbortSignal} signal
|
||||
* @param {(points: HeatmapPoints) => void} [onPoints]
|
||||
* @returns {Promise<HeatmapPoints>}
|
||||
*/
|
||||
async function fetchOraclePoints(mode, date, signal) {
|
||||
const values = await firstAvailable((onValue) =>
|
||||
mode === "raw"
|
||||
? brk.getOracleHistogramRaw(date, { signal, onValue })
|
||||
: brk.getOracleHistogramEma(date, { signal, onValue }),
|
||||
async function fetchOraclePoints(mode, date, signal, onPoints) {
|
||||
const values = await fetchOracleValues(
|
||||
mode,
|
||||
date,
|
||||
signal,
|
||||
onPoints ? (values) => onPoints(toOraclePoints(values)) : undefined,
|
||||
);
|
||||
|
||||
return {
|
||||
kind: "implicit",
|
||||
yStart: MIN_LOG,
|
||||
yStep: 1 / BINS_PER_DECADE,
|
||||
values,
|
||||
};
|
||||
return toOraclePoints(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(onValue: (value: number[]) => void) => Promise<number[]>} fetch
|
||||
* @param {"raw" | "ema"} mode
|
||||
* @param {string} date
|
||||
* @param {AbortSignal} signal
|
||||
* @param {(values: number[]) => void} [onValue]
|
||||
* @returns {Promise<number[]>}
|
||||
*/
|
||||
function firstAvailable(fetch) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let settled = false;
|
||||
|
||||
/** @param {number[]} value */
|
||||
const resolveOnce = (value) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
resolve(value);
|
||||
};
|
||||
|
||||
fetch(resolveOnce).then(resolveOnce, (error) => {
|
||||
if (!settled) reject(error);
|
||||
});
|
||||
});
|
||||
function fetchOracleValues(mode, date, signal, onValue) {
|
||||
return (
|
||||
mode === "raw"
|
||||
? brk.getOracleHistogramRaw(date, { signal, onValue })
|
||||
: brk.getOracleHistogramEma(date, { signal, onValue })
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number[]} values
|
||||
* @returns {HeatmapPoints}
|
||||
*/
|
||||
function toOraclePoints(values) {
|
||||
return {
|
||||
kind: "implicit",
|
||||
yStart: MAX_LOG,
|
||||
yStep: -1 / BINS_PER_DECADE,
|
||||
values,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* @typedef {HeatmapImplicitPoints | HeatmapExplicitPoints} HeatmapPoints
|
||||
*
|
||||
* @typedef {Object} HeatmapPointSource
|
||||
* @property {(date: string, signal: AbortSignal) => Promise<HeatmapPoints>} fetch
|
||||
* @property {(date: string, signal: AbortSignal, onPoints?: (points: HeatmapPoints) => void) => Promise<HeatmapPoints>} fetch
|
||||
*
|
||||
* @typedef {Object} HeatmapRange
|
||||
* @property {number} start
|
||||
|
||||
Reference in New Issue
Block a user