bitview: reorg part 2

This commit is contained in:
nym21
2025-09-23 19:58:34 +02:00
parent 5b6ce5d8ee
commit d45686128e
21 changed files with 1803 additions and 1810 deletions

View File

@@ -1,7 +1,13 @@
// @ts-check
/** @import { IChartApi, ISeriesApi as _ISeriesApi, SeriesDefinition, SingleValueData as _SingleValueData, CandlestickData as _CandlestickData, BaselineData as _BaselineData, HistogramData as _HistogramData, SeriesType, IPaneApi, LineSeriesPartialOptions as _LineSeriesPartialOptions, HistogramSeriesPartialOptions as _HistogramSeriesPartialOptions, BaselineSeriesPartialOptions as _BaselineSeriesPartialOptions, CandlestickSeriesPartialOptions as _CandlestickSeriesPartialOptions, WhitespaceData, DeepPartial, ChartOptions, Time, LineData as _LineData } from '../packages/lightweight-charts/5.0.8/dist/typings' */
import {
createHorizontalChoiceField,
createLabeledInput,
createSpanName,
} from "./dom";
import { createOklchToRGBA } from "./colors";
import { throttle } from "./scheduling";
/**
* @typedef {[number, number, number, number]} OHLCTuple
*
@@ -209,7 +215,7 @@ function createChartElement({
const activeResources = /** @type {Set<VecResource>} */ (new Set());
ichart.subscribeCrosshairMove(
utils.throttle(() => {
throttle(() => {
activeResources.forEach((v) => {
v.fetch();
});
@@ -285,7 +291,7 @@ function createChartElement({
paneIndex,
position: "sw",
createChild(pane) {
const { field, selected } = utils.dom.createHorizontalChoiceField({
const { field, selected } = createHorizontalChoiceField({
choices: /** @type {const} */ (["lin", "log"]),
id: utils.stringToId(`${id} ${paneIndex} ${unit}`),
defaultValue:
@@ -341,7 +347,7 @@ function createChartElement({
save: {
keyPrefix: "",
key: id,
...utils.serde.boolean,
...serde.boolean,
},
});
@@ -868,7 +874,7 @@ function createLegend({ signals, utils }) {
}
legends[order] = div;
const { input, label } = utils.dom.createLabeledInput({
const { input, label } = createLabeledInput({
inputId: utils.stringToId(`legend-${series.id}`),
inputName: utils.stringToId(`selected-${series.id}`),
inputValue: "value",
@@ -884,7 +890,7 @@ function createLegend({ signals, utils }) {
spanMain.classList.add("main");
label.append(spanMain);
const spanName = utils.dom.createSpanName(name);
const spanName = createSpanName(name);
spanMain.append(spanName);
div.append(label);
@@ -1044,107 +1050,6 @@ function numberToUSFormat(value, digits, options) {
});
}
function createOklchToRGBA() {
{
/**
*
* @param {readonly [number, number, number, number, number, number, number, number, number]} A
* @param {readonly [number, number, number]} B
* @returns
*/
function multiplyMatrices(A, B) {
return /** @type {const} */ ([
A[0] * B[0] + A[1] * B[1] + A[2] * B[2],
A[3] * B[0] + A[4] * B[1] + A[5] * B[2],
A[6] * B[0] + A[7] * B[1] + A[8] * B[2],
]);
}
/**
* @param {readonly [number, number, number]} param0
*/
function oklch2oklab([l, c, h]) {
return /** @type {const} */ ([
l,
isNaN(h) ? 0 : c * Math.cos((h * Math.PI) / 180),
isNaN(h) ? 0 : c * Math.sin((h * Math.PI) / 180),
]);
}
/**
* @param {readonly [number, number, number]} rgb
*/
function srgbLinear2rgb(rgb) {
return rgb.map((c) =>
Math.abs(c) > 0.0031308
? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055)
: 12.92 * c,
);
}
/**
* @param {readonly [number, number, number]} lab
*/
function oklab2xyz(lab) {
const LMSg = multiplyMatrices(
/** @type {const} */ ([
1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586,
-0.0638541728258133, 1, -0.0894841775298119, -1.2914855480194092,
]),
lab,
);
const LMS = /** @type {[number, number, number]} */ (
LMSg.map((val) => val ** 3)
);
return multiplyMatrices(
/** @type {const} */ ([
1.2268798758459243, -0.5578149944602171, 0.2813910456659647,
-0.0405757452148008, 1.112286803280317, -0.0717110580655164,
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816,
]),
LMS,
);
}
/**
* @param {readonly [number, number, number]} xyz
*/
function xyz2rgbLinear(xyz) {
return multiplyMatrices(
[
3.2409699419045226, -1.537383177570094, -0.4986107602930034,
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
0.05563007969699366, -0.20397695888897652, 1.0569715142428786,
],
xyz,
);
}
/** @param {string} oklch */
return function (oklch) {
oklch = oklch.replace("oklch(", "");
oklch = oklch.replace(")", "");
let splitOklch = oklch.split(" / ");
let alpha = 1;
if (splitOklch.length === 2) {
alpha = Number(splitOklch.pop()?.replace("%", "")) / 100;
}
splitOklch = oklch.split(" ");
const lch = splitOklch.map((v, i) => {
if (!i && v.includes("%")) {
return Number(v.replace("%", "")) / 100;
} else {
return Number(v);
}
});
const rgb = srgbLinear2rgb(
xyz2rgbLinear(
oklab2xyz(oklch2oklab(/** @type {[number, number, number]} */ (lch))),
),
).map((v) => {
return Math.max(Math.min(Math.round(v * 255), 255), 0);
});
return [...rgb, alpha];
};
}
}
/**
* @typedef {typeof createChartElement} CreateChartElement
* @typedef {ReturnType<createChartElement>} Chart