diff --git a/website/index.html b/website/index.html
index 2e50731db..4c4878329 100644
--- a/website/index.html
+++ b/website/index.html
@@ -968,76 +968,135 @@
pointer-events: none;
}
- .chart > .panes {
- position: relative;
+ .chart {
display: flex;
flex-direction: column;
- flex: 1;
min-height: 0;
- > .pane {
- z-index: 20;
- position: relative;
- min-height: 0px;
- width: 100%;
- cursor: crosshair;
- height: 100%;
+ > legend {
+ display: flex;
+ align-items: center;
+ gap: 1.5rem;
+ margin-left: var(--negative-main-padding);
+ margin-right: var(--negative-main-padding);
+ padding-left: var(--main-padding);
+ padding-right: var(--main-padding);
+ padding-bottom: 1.25rem;
+ overflow-x: auto;
+ min-width: 0;
- &:has(+ .chart-wrapper:not([hidden])) {
- height: calc(100% - 62px);
- }
-
- > fieldset {
- pointer-events: none;
- position: absolute;
- left: 0px;
- top: 0px;
- z-index: 10;
+ > div {
+ flex: 0;
display: flex;
align-items: center;
- font-size: var(--font-size-xs);
- line-height: var(--line-height-xs);
- gap: 0.5rem;
- > div.field {
+ > label {
+ margin: -0.375rem 0;
+ color: var(--color);
+
+ > span {
+ display: flex !important;
+ }
+
+ &:has(input:not(:checked)) {
+ color: var(--off-color);
+
+ > span.main > span.name {
+ text-decoration-thickness: 1.5px;
+ text-decoration-color: var(--color);
+ text-decoration-line: line-through;
+ }
+
+ &:hover {
+ * {
+ color: var(--off-color) !important;
+ }
+
+ > span.main > span.name {
+ text-decoration-color: var(--orange) !important;
+ }
+ }
+ }
+ }
+
+ > a {
+ padding: 0.375rem;
+ margin: -0.375rem;
+ }
+ }
+ }
+
+ > .panes {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+
+ > .pane {
+ z-index: 20;
+ position: relative;
+ min-height: 0px;
+ width: 100%;
+ cursor: crosshair;
+ height: 100%;
+
+ &:has(+ .chart-wrapper:not([hidden])) {
+ height: calc(100% - 62px);
+ }
+
+ > fieldset {
+ pointer-events: none;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ z-index: 10;
display: flex;
align-items: center;
font-size: var(--font-size-xs);
line-height: var(--line-height-xs);
gap: 0.5rem;
- > legend,
- > div {
- flex-shrink: 0;
- }
-
- > hr {
- min-width: 1rem;
- }
-
- label {
- padding: 0.5rem;
- margin: -0.5rem;
- }
-
- > div {
+ > div.field {
display: flex;
+ align-items: center;
+ font-size: var(--font-size-xs);
+ line-height: var(--line-height-xs);
gap: 0.5rem;
+
+ > legend,
+ > div {
+ flex-shrink: 0;
+ }
+
+ > hr {
+ min-width: 1rem;
+ }
+
+ label {
+ padding: 0.5rem;
+ margin: -0.5rem;
+ }
+
+ > div {
+ display: flex;
+ gap: 0.5rem;
+ }
}
}
+
+ > .lightweight-chart {
+ height: 100%;
+ margin-right: var(--negative-main-padding);
+ }
}
- > .lightweight-chart {
- height: 100%;
- margin-right: var(--negative-main-padding);
+ > .shadow-bottom {
+ bottom: 1.75rem;
+ width: 80px;
+ left: auto;
}
}
-
- > .shadow-bottom {
- bottom: 1.75rem;
- width: 80px;
- left: auto;
- }
}
diff --git a/website/packages/lightweight-charts/types.d.ts b/website/packages/lightweight-charts/types.d.ts
new file mode 100644
index 000000000..a15bd5132
--- /dev/null
+++ b/website/packages/lightweight-charts/types.d.ts
@@ -0,0 +1,122 @@
+import { Signal } from "../solid-signals/types";
+import { Accessor } from "../solid-signals/2024-11-02/types/signals";
+import { Owner } from "../solid-signals/2024-11-02/types/core/owner";
+import {
+ DeepPartial,
+ BaselineStyleOptions,
+ CandlestickStyleOptions,
+ LineStyleOptions,
+ SeriesOptionsCommon,
+ Time,
+ CandlestickData,
+ ISeriesApi,
+ BaselineData,
+} from "./v4.2.0/types";
+import { Color } from "../../scripts/types/self";
+
+interface BaseSeriesBlueprint {
+ title: string;
+ defaultActive?: boolean;
+}
+interface BaselineSeriesBlueprint extends BaseSeriesBlueprint {
+ type: "Baseline";
+ color?: Color;
+ options?: DeepPartial;
+ data?: Accessor[]>;
+}
+interface CandlestickSeriesBlueprint extends BaseSeriesBlueprint {
+ type: "Candlestick";
+ color?: Color;
+ options?: DeepPartial;
+ data?: Accessor[]>;
+}
+interface LineSeriesBlueprint extends BaseSeriesBlueprint {
+ type?: "Line";
+ color: Color;
+ options?: DeepPartial;
+ data?: Accessor[]>;
+}
+type AnySpecificSeriesBlueprint =
+ | BaselineSeriesBlueprint
+ | CandlestickSeriesBlueprint
+ | LineSeriesBlueprint;
+
+type SeriesType = NonNullable;
+type PriceSeriesType = "Candlestick" | "Line";
+
+type RemoveSeriesBlueprintFluff =
+ Omit;
+
+type SplitSeriesBlueprint = {
+ datasetPath: AnyDatasetPath;
+ main?: boolean;
+} & AnySpecificSeriesBlueprint;
+
+type SingleSeriesBlueprint = AnySpecificSeriesBlueprint;
+
+interface CreateBaseSeriesParameters extends BaseSeriesBlueprint {
+ id: string;
+ disabled?: Accessor;
+ color?: Color;
+}
+interface BaseSeries {
+ id: string;
+ title: string;
+ color: Color | Color[];
+ active: Signal;
+ visible: Accessor;
+ disabled: Accessor;
+}
+interface SingleSeries extends BaseSeries {
+ iseries: ISeriesApi;
+}
+interface SplitSeries extends BaseSeries {
+ chunks: Array | undefined>>;
+ dataset: ResourceDataset;
+}
+
+interface CreateSingleSeriesParameters {
+ blueprint: SingleSeriesBlueprint;
+ id: string;
+}
+
+interface CreateSplitSeriesParameters {
+ dataset: ResourceDataset;
+ blueprint: SplitSeriesBlueprint;
+ id: string;
+ index: number;
+ setMinMaxMarkersWhenIdle: VoidFunction;
+ disabled?: Accessor;
+}
+
+type ChartPane = IChartApi & {
+ whitespace: ISeriesApi<"Line">;
+ hidden: () => boolean;
+ setHidden: (b: boolean) => void;
+ setInitialVisibleTimeRange: VoidFunction;
+ createSingleSeries: (a: CreateSingleSeriesParameters) => SingleSeries;
+ createSplitSeries: (
+ a: CreateSplitSeriesParameters,
+ ) => SplitSeries;
+ splitSeries: SplitSeries[];
+};
+
+interface CreatePaneParameters {
+ unit: Unit;
+ paneIndex?: number;
+ whitespace?: true;
+ options?: DeepPartial;
+ config?: SingleSeriesBlueprint[];
+}
+
+interface Marker {
+ weight: number;
+ time: Time;
+ value: number;
+ seriesChunk: ISeriesApi;
+}
+
+interface HoveredLegend {
+ label: HTMLLabelElement;
+ series: SingleSeries | SplitSeries;
+}
diff --git a/website/packages/lightweight-charts/wrapper.js b/website/packages/lightweight-charts/wrapper.js
index 957906815..1a6722496 100644
--- a/website/packages/lightweight-charts/wrapper.js
+++ b/website/packages/lightweight-charts/wrapper.js
@@ -357,6 +357,7 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
* @param {TimeScale} param0.scale
* @param {"static" | "moveable"} param0.kind
* @param {Utilities} param0.utils
+ * @param {Owner | null} [param0.owner]
* @param {CreatePaneParameters[]} [param0.config]
*/
function createChart({
@@ -368,7 +369,13 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
scale,
config,
utils,
+ owner: _owner,
}) {
+ /** @type {SplitSeries[]} */
+ const chartSplitSeries = [];
+
+ let owner = _owner || signals.getOwner();
+
const div = window.document.createElement("div");
div.classList.add("chart");
parent.append(div);
@@ -541,14 +548,14 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
inputName: utils.stringToId(`selected-${series.title}-${extraName}`),
inputValue: "value",
labelTitle: "Click to toggle",
- onClick: (event) => {
- event.preventDefault();
- event.stopPropagation();
- input.checked = !input.checked;
+ onClick: () => {
series.active.set(input.checked);
},
+ type: "solo",
});
+ input.checked = series.active();
+
const spanMain = window.document.createElement("span");
spanMain.classList.add("main");
label.append(spanMain);
@@ -568,10 +575,6 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
hoveredLegend.set(undefined);
});
- signals.createEffect(series.active, (checked) => {
- input.checked = checked;
- });
-
function shouldHighlight() {
const hovered = hoveredLegend();
return (
@@ -680,7 +683,7 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
}
} else {
applySeriesOption({
- series: series.series,
+ series: series.iseries,
hovered,
});
}
@@ -727,6 +730,9 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
chartDiv.classList.add("lightweight-chart");
chartWrapper.append(chartDiv);
+ /** @type {SplitSeries[]} */
+ const paneSplitSeries = [];
+
options = { ...options };
if (kind === "static") {
options.handleScale = false;
@@ -748,9 +754,9 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
});
/**
- * @param {CreateBaselineSeriesParams} args
+ * @param {RemoveSeriesBlueprintFluff} args
*/
- function createBaseLineSeries({ color, options, owner, data }) {
+ function createBaseLineSeries({ color, options, data }) {
const topLineColor = color || colors.profit;
const bottomLineColor = color || colors.loss;
@@ -784,16 +790,20 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
});
if (data) {
- series.setData(data);
+ signals.runWithOwner(owner, () => {
+ signals.createEffect(data, (data) => {
+ series.setData(data);
+ });
+ });
}
return series;
}
/**
- * @param {CreateCandlestickSeriesParams} args
+ * @param {RemoveSeriesBlueprintFluff} args
*/
- function createCandlestickSeries({ options, owner, data }) {
+ function createCandlestickSeries({ options, data }) {
function computeColors() {
const upColor = colors.profit();
const downColor = colors.loss();
@@ -825,16 +835,20 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
});
if (data) {
- series.setData(data);
+ signals.runWithOwner(owner, () => {
+ signals.createEffect(data, (data) => {
+ series.setData(data);
+ });
+ });
}
return series;
}
/**
- * @param {CreateLineSeriesParams} args
+ * @param {RemoveSeriesBlueprintFluff} args
*/
- function createLineSeries({ color, options, owner, data }) {
+ function createLineSeries({ color, options, data }) {
function computeColors() {
return {
color: color(),
@@ -847,49 +861,41 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
...computeColors(),
});
- if (data) {
- series.setData(data);
- }
-
signals.runWithOwner(owner, () => {
signals.createEffect(computeColors, (computeColors) => {
series.applyOptions(computeColors);
});
});
+ if (data) {
+ signals.runWithOwner(owner, () => {
+ signals.createEffect(data, (data) => {
+ series.setData(data);
+ });
+ });
+ }
+
return series;
}
/**
* @template {TimeScale} S
- * @param {CreateSplitSeriesParameters} args
+ * @param {CreateBaseSeriesParameters} args
*/
- function createSplitSeries({
- option,
- index: seriesIndex,
+ function createBaseSeries({
+ id,
disabled: _disabled,
- setMinMaxMarkersWhenIdle,
- dataset,
- seriesBlueprint,
- splitSeries,
+ title,
+ color,
+ defaultActive,
}) {
- const {
- title,
- color,
- defaultActive,
- type,
- options: seriesOptions,
- } = seriesBlueprint;
-
- /** @type {Signal | undefined>[]} */
- const chunks = new Array(dataset.fetchedJSONs.length);
-
- const id = utils.stringToId(title);
- const storageId = utils.stringToId(`${option.id}-${title}`);
+ const keyPrefix = id;
+ const paramKey = utils.stringToId(title);
+ const storageKey = `${keyPrefix}-${paramKey}`;
const active = signals.createSignal(
- utils.url.readBoolParam(id) ??
- utils.storage.readBool(storageId) ??
+ utils.url.readBoolParam(paramKey) ??
+ utils.storage.readBool(storageKey) ??
defaultActive ??
true,
);
@@ -898,12 +904,10 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
const visible = signals.createMemo(() => active() && !disabled());
- /** @satisfies {SplitSeries} */
+ /** @satisfies {BaseSeries} */
const series = {
active,
- chunks,
color: color || [colors.profit, colors.loss],
- dataset,
disabled,
id,
title,
@@ -918,32 +922,97 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
}
if (active !== (defaultActive || true)) {
- utils.url.writeParam(id, active);
- utils.storage.write(storageId, active);
+ utils.url.writeParam(paramKey, active);
+ utils.storage.write(storageKey, active);
} else {
- utils.url.removeParam(id);
- utils.storage.remove(storageId);
+ utils.url.removeParam(paramKey);
+ utils.storage.remove(storageKey);
}
},
);
- splitSeries.push(series);
+ return series;
+ }
- const owner = signals.getOwner();
+ const chartPane = /** @type {ChartPane} */ (_chart);
+
+ chartPane.createSingleSeries = function ({ blueprint, id }) {
+ /** @type {ISeriesApi} */
+ let s;
+
+ switch (blueprint.type) {
+ case "Baseline": {
+ s = createBaseLineSeries(blueprint);
+ break;
+ }
+ case "Candlestick": {
+ s = createCandlestickSeries(blueprint);
+ break;
+ }
+ default:
+ case "Line": {
+ s = createLineSeries(blueprint);
+ break;
+ }
+ }
+
+ /** @satisfies {SingleSeries} */
+ const series = {
+ ...createBaseSeries({
+ id,
+ title: blueprint.title,
+ color: blueprint.color,
+ defaultActive: blueprint.defaultActive,
+ }),
+ iseries: s,
+ };
+
+ signals.createEffect(series.visible, (visible) => {
+ series.iseries.applyOptions({
+ visible,
+ });
+ });
+
+ createLegend({ series });
+
+ return series;
+ };
+ chartPane.createSplitSeries = function ({
+ id,
+ index: seriesIndex,
+ disabled,
+ setMinMaxMarkersWhenIdle,
+ dataset,
+ blueprint,
+ }) {
+ /** @satisfies {SplitSeries} */
+ const series = {
+ ...createBaseSeries({
+ id,
+ title: blueprint.title,
+ color: blueprint.color,
+ defaultActive: blueprint.defaultActive,
+ disabled,
+ }),
+ dataset,
+ chunks: new Array(dataset.fetchedJSONs.length),
+ };
+
+ paneSplitSeries.push(series);
+ chartSplitSeries.unshift(series);
dataset.fetchedJSONs.forEach((json, index) => {
const chunk = signals.createSignal(
/** @type {ISeriesApi | undefined} */ (undefined),
);
- chunks[index] = chunk;
+ series.chunks[index] = chunk;
const isMyTurn = signals.createMemo(() => {
if (seriesIndex <= 0) return true;
- const previousSeriesChunk = splitSeries.at(seriesIndex - 1)?.chunks[
- index
- ];
+ const previousSeriesChunk = paneSplitSeries.at(seriesIndex - 1)
+ ?.chunks[index];
const isPreviousSeriesOnChart = previousSeriesChunk?.();
return !!isPreviousSeriesOnChart;
@@ -957,28 +1026,25 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
let s = chunk();
if (!s) {
- switch (type) {
+ switch (blueprint.type) {
case "Baseline": {
s = createBaseLineSeries({
- color,
- options: seriesOptions,
- owner,
+ color: blueprint.color,
+ options: blueprint.options,
});
break;
}
case "Candlestick": {
s = createCandlestickSeries({
- options: seriesOptions,
- owner,
+ options: blueprint.options,
});
break;
}
default:
case "Line": {
s = createLineSeries({
- color,
- options: seriesOptions,
- owner,
+ color: blueprint.color,
+ options: blueprint.options,
});
break;
}
@@ -1069,23 +1135,17 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
});
});
- createLegend({ series, extraName: type });
+ createLegend({ series, extraName: blueprint.type });
return series;
- }
-
- const chartPane = /** @type {ChartPane} */ (_chart);
-
- chartPane.createSplitSeries = createSplitSeries;
- chartPane.createBaseLineSeries = createBaseLineSeries;
- chartPane.createCandlesticksSeries = createCandlestickSeries;
- chartPane.createLineSeries = createLineSeries;
+ };
chartPane.hidden = () => {
return chartWrapper.hidden;
};
chartPane.setHidden = (b) => {
chartWrapper.hidden = b;
};
+ chartPane.splitSeries = paneSplitSeries;
chartPane.setInitialVisibleTimeRange = () => {
const range = visibleTimeRange();
@@ -1143,26 +1203,15 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
}
createUnitAndModeElements();
- config?.forEach((params) => {
- // createLegend(params);
- switch (params.kind) {
- case "line": {
- chartPane.createLineSeries(params);
- break;
- }
- case "candle": {
- chartPane.createCandlesticksSeries(params);
- break;
- }
- case "baseline": {
- chartPane.createBaseLineSeries(params);
- break;
- }
- }
- });
-
switch (kind) {
case "static": {
+ config?.forEach((params) => {
+ chartPane.createSingleSeries({
+ id: utils.stringToId(params.title),
+ blueprint: params,
+ });
+ });
+
chartPane.timeScale().fitContent();
break;
@@ -1199,9 +1248,11 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
*
* @param {Object} param0
* @param {TimeScale} param0.scale
+ * @param {Owner | null} param0.owner
*/
- function reset({ scale: _scale }) {
+ function reset({ scale: _scale, owner: _owner }) {
scale = _scale;
+ owner = _owner;
panes.forEach((pane) => pane.remove());
panes.length = 0;
legendElement.innerHTML = "";
@@ -1265,6 +1316,7 @@ export default import("./v4.2.0/script.js").then((lightweightCharts) => {
saveVisibleRange,
getTicksToWidthRatio,
debouncedSaveVisibleRange,
+ splitSeries: chartSplitSeries,
};
}
diff --git a/website/packages/solid-signals/wrapper.js b/website/packages/solid-signals/wrapper.js
index 462d16e11..c7153a4a9 100644
--- a/website/packages/solid-signals/wrapper.js
+++ b/website/packages/solid-signals/wrapper.js
@@ -33,7 +33,7 @@ const importSignals = import("./2024-11-02/script.js").then((_signals) => {
/**
* @template T
* @param {T} initialValue
- * @param {SignalOptions & {save?: {id?: string; param?: string; serialize: (v: NonNullable) => string; deserialize: (v: string) => NonNullable}}} [options]
+ * @param {SignalOptions & {save?: {keyPrefix: string; key: string; serialize: (v: NonNullable) => string; deserialize: (v: string) => NonNullable}}} [options]
* @returns {Signal}
*/
createSignal(initialValue, options) {
@@ -51,14 +51,14 @@ const importSignals = import("./2024-11-02/script.js").then((_signals) => {
if (options?.save) {
const save = options.save;
+ const paramKey = save.key;
+ const storageKey = `${save.keyPrefix}-${paramKey}`;
+
let serialized = /** @type {string | null} */ (null);
- if (save.param) {
- serialized = new URLSearchParams(window.location.search).get(
- save.param,
- );
- }
- if (serialized === null && save.id) {
- serialized = localStorage.getItem(save.id);
+ serialized = new URLSearchParams(window.location.search).get(paramKey);
+
+ if (serialized === null) {
+ serialized = localStorage.getItem(storageKey);
}
if (serialized) {
set(save.deserialize(serialized));
@@ -68,7 +68,7 @@ const importSignals = import("./2024-11-02/script.js").then((_signals) => {
this.createEffect(get, (value) => {
if (!save) return;
- if (!firstEffect && save.id) {
+ if (!firstEffect) {
if (
value !== undefined &&
value !== null &&
@@ -76,24 +76,22 @@ const importSignals = import("./2024-11-02/script.js").then((_signals) => {
initialValue === null ||
save.serialize(value) !== save.serialize(initialValue))
) {
- localStorage.setItem(save.id, save.serialize(value));
+ localStorage.setItem(storageKey, save.serialize(value));
} else {
- localStorage.removeItem(save.id);
+ localStorage.removeItem(storageKey);
}
}
- if (save.param) {
- if (
- value !== undefined &&
- value !== null &&
- (initialValue === undefined ||
- initialValue === null ||
- save.serialize(value) !== save.serialize(initialValue))
- ) {
- writeParam(save.param, save.serialize(value));
- } else {
- removeParam(save.param);
- }
+ if (
+ value !== undefined &&
+ value !== null &&
+ (initialValue === undefined ||
+ initialValue === null ||
+ save.serialize(value) !== save.serialize(initialValue))
+ ) {
+ writeParam(paramKey, save.serialize(value));
+ } else {
+ removeParam(paramKey);
}
firstEffect = false;
diff --git a/website/scripts/chart.js b/website/scripts/chart.js
index bc29719d0..8e19dc2ba 100644
--- a/website/scripts/chart.js
+++ b/website/scripts/chart.js
@@ -1,8 +1,7 @@
// @ts-check
/**
- * @import { ChartPane, HoveredLegend, PriceSeriesType, SplitSeries } from "./types/self"
- * @import { Options } from './options';
+ * @import { PriceSeriesType } from '../packages/lightweight-charts/types';
*/
/**
@@ -110,14 +109,12 @@ export function init({
* @param {VoidFunction} args.setMinMaxMarkersWhenIdle
* @param {Option} args.option
* @param {ChartPane} args.chartPane
- * @param {SplitSeries[]} args.chartSeries
*/
function createPriceSeries({
type,
setMinMaxMarkersWhenIdle,
option,
chartPane,
- chartSeries: splitSeries,
}) {
const s = scale();
@@ -131,17 +128,17 @@ export function init({
const title = "BTC Price";
- /** @type {SeriesBlueprint} */
- let seriesBlueprint;
+ /** @type {SplitSeriesBlueprint} */
+ let blueprint;
if (type === "Candlestick") {
- seriesBlueprint = {
+ blueprint = {
datasetPath,
title,
type: "Candlestick",
};
} else {
- seriesBlueprint = {
+ blueprint = {
datasetPath,
title,
color: colors.default,
@@ -151,11 +148,10 @@ export function init({
const disabled = signals.createMemo(() => priceSeriesType() !== type);
const priceSeries = chartPane.createSplitSeries({
- seriesBlueprint,
+ blueprint,
dataset,
- option,
+ id: option.id,
index: -1,
- splitSeries,
disabled,
setMinMaxMarkersWhenIdle,
});
@@ -199,9 +195,6 @@ export function init({
(list) => (list ? [list] : []),
);
- /** @type {SplitSeries[]} */
- const allSeries = [];
-
chartsBlueprints.map((seriesBlueprints, paneIndex) => {
const chartPane = chart.createPane({
paneIndex,
@@ -209,9 +202,6 @@ export function init({
whitespace: true,
});
- /** @type {SplitSeries[]} */
- const splitSeries = [];
-
function setMinMaxMarkers() {
try {
const { from, to } = chart.visibleTimeRange();
@@ -226,8 +216,8 @@ export function init({
const ids = chart.visibleDatasetIds();
- for (let i = 0; i < splitSeries.length; i++) {
- const { chunks, dataset } = splitSeries[i];
+ for (let i = 0; i < chartPane.splitSeries.length; i++) {
+ const { chunks, dataset } = chartPane.splitSeries[i];
for (let j = 0; j < ids.length; j++) {
const id = ids[j];
@@ -370,7 +360,6 @@ export function init({
function _createPriceSeries(type) {
return createPriceSeries({
chartPane,
- chartSeries: splitSeries,
option,
setMinMaxMarkersWhenIdle,
type,
@@ -392,21 +381,17 @@ export function init({
createLinkPriceSeriesEffect();
}
- [...seriesBlueprints].reverse().forEach((seriesBlueprint, index) => {
- const dataset = datasets.getOrCreate(
- scale,
- seriesBlueprint.datasetPath,
- );
+ [...seriesBlueprints].reverse().forEach((blueprint, index) => {
+ const dataset = datasets.getOrCreate(scale, blueprint.datasetPath);
// Don't trigger reactivity by design
activeDatasets().add(dataset);
chartPane.createSplitSeries({
index,
- seriesBlueprint,
- option,
+ blueprint,
+ id: option.id,
setMinMaxMarkersWhenIdle,
- splitSeries,
dataset,
});
});
@@ -415,16 +400,14 @@ export function init({
activeDatasets.set((s) => s);
- splitSeries.forEach((series) => {
- allSeries.unshift(series);
-
+ chartPane.splitSeries.forEach((series) => {
signals.createEffect(series.active, () => {
setMinMaxMarkersWhenIdle();
});
});
const chartVisible = signals.createMemo(() =>
- splitSeries.some((series) => series.visible()),
+ chartPane.splitSeries.some((series) => series.visible()),
);
function createChartVisibilityEffect() {
@@ -504,7 +487,7 @@ export function init({
function createApplyChartOptionEffect() {
signals.createEffect(selected, (option) => {
- chart.reset({ scale: option.scale });
+ chart.reset({ scale: option.scale, owner: signals.getOwner() });
applyChartOption(option);
});
}
diff --git a/website/scripts/main.js b/website/scripts/main.js
index 8d3fc22ec..ec5765f04 100644
--- a/website/scripts/main.js
+++ b/website/scripts/main.js
@@ -1,8 +1,9 @@
// @ts-check
/**
- * @import { Option, ResourceDataset, TimeScale, TimeRange, Unit, Marker, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, SeriesBlueprint, BaselineSpecificSeriesBlueprint, CandlestickSpecificSeriesBlueprint, LineSpecificSeriesBlueprint, SpecificSeriesBlueprintWithChart, Color, DatasetCandlestickData, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath, SimulationOption, Frequency, CreatePaneParameters, CreateBaselineSeriesParams, CreateCandlestickSeriesParams, CreateLineSeriesParams, LastValues, HoveredLegend, ChartPane, SplitSeries, SingleSeries, CreateSplitSeriesParameters } from "./types/self"
- * @import {createChart as CreateClassicChart, createChartEx as CreateCustomChart, LineStyleOptions} from "../packages/lightweight-charts/v4.2.0/types";
+ * @import { Option, ResourceDataset, TimeScale, TimeRange, Unit, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, Color, DatasetCandlestickData, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath, SimulationOption, Frequency, LastValues } from "./types/self"
+ * @import {createChart as CreateClassicChart, createChartEx as CreateCustomChart, LineStyleOptions } from "../packages/lightweight-charts/v4.2.0/types";
+ * @import { Marker, CreatePaneParameters, HoveredLegend, ChartPane, SplitSeries, SingleSeries, CreateSplitSeriesParameters, LineSeriesBlueprint, CandlestickSeriesBlueprint, BaselineSeriesBlueprint, CreateBaseSeriesParameters, BaseSeries, RemoveSeriesBlueprintFluff, SplitSeriesBlueprint } from "../packages/lightweight-charts/types";
* @import * as _ from "../packages/ufuzzy/v1.0.14/types"
* @import { DeepPartial, ChartOptions, IChartApi, IHorzScaleBehavior, WhitespaceData, SingleValueData, ISeriesApi, Time, LineData, LogicalRange, SeriesMarker, CandlestickData, SeriesType, BaselineStyleOptions, SeriesOptionsCommon } from "../packages/lightweight-charts/v4.2.0/types"
* @import { DatePath, HeightPath, LastPath } from "./types/paths";
@@ -232,6 +233,7 @@ const utils = {
* @param {string} args.inputValue
* @param {boolean} [args.inputChecked=false]
* @param {string} args.labelTitle
+ * @param {'solo' | 'multi'} args.type
* @param {(event: MouseEvent) => void} [args.onClick]
*/
createLabeledInput({
@@ -241,23 +243,27 @@ const utils = {
inputChecked = false,
labelTitle,
onClick,
+ type,
}) {
const label = window.document.createElement("label");
inputId = inputId.toLowerCase();
const input = window.document.createElement("input");
- input.type = "radio";
- input.name = inputName;
+ if (type === "multi") {
+ input.type = "radio";
+ input.name = inputName;
+ } else {
+ input.type = "checkbox";
+ }
input.id = inputId;
input.value = inputValue;
input.checked = inputChecked;
label.append(input);
label.id = `${inputId}-label`;
- // @ts-ignore
- label.for = inputId;
label.title = labelTitle;
+ label.htmlFor = inputId;
if (onClick) {
label.addEventListener("click", onClick);
@@ -362,6 +368,7 @@ const utils = {
inputValue,
inputChecked: inputValue === selected,
labelTitle: choice,
+ type: "multi",
});
const text = window.document.createTextNode(choice);
@@ -835,6 +842,26 @@ const utils = {
return new Date(v);
},
},
+ boolean: {
+ /**
+ * @param {boolean} v
+ */
+ serialize(v) {
+ return String(v);
+ },
+ /**
+ * @param {string} v
+ */
+ deserialize(v) {
+ if (v === "true") {
+ return true;
+ } else if (v === "false") {
+ return false;
+ } else {
+ throw "deser bool err";
+ }
+ },
+ },
},
formatters: {
dollars: new Intl.NumberFormat("en-US", {
diff --git a/website/scripts/options.js b/website/scripts/options.js
index ca9d591eb..983f05e97 100644
--- a/website/scripts/options.js
+++ b/website/scripts/options.js
@@ -1,7 +1,8 @@
// @ts-check
/**
- * @import { AnySpecificSeriesBlueprint, CohortOption, CohortOptions, Color, DefaultCohortOption, DefaultCohortOptions, OptionPath, OptionsGroup, PartialChartOption, PartialOptionsGroup, PartialOptionsTree, RatioOption, RatioOptions, SplitSeries, SeriesBlueprint, SeriesBlueprintParam, SeriesBluePrintType, TimeScale } from "./types/self"
+ * @import { CohortOption, CohortOptions, Color, DefaultCohortOption, DefaultCohortOptions, OptionPath, OptionsGroup, PartialChartOption, PartialOptionsGroup, PartialOptionsTree, RatioOption, RatioOptions, TimeScale } from "./types/self"
+ * @import {AnySpecificSeriesBlueprint, SplitSeriesBlueprint} from '../packages/lightweight-charts/types';
*/
const DATE_TO_PREFIX = "date-to-";
@@ -2819,12 +2820,12 @@ function createPartialOptions(colors) {
/**
* @template {AnyPossibleCohortId} T
* @param {CohortOption | CohortOptions} arg
- * @param {SeriesBlueprintParam & Omit} blueprint
+ * @param {{ title: string; singleColor?: Color; genPath: (id: T, scale: TimeScale) => AnyDatasetPath} & Omit} blueprint
*/
- toSeriesBlueprints(arg, blueprint) {
+ generateSeriesBlueprints(arg, blueprint) {
return this.toList(arg).map(
({ scale, datasetId, color, name }) =>
- /** @satisfies {SeriesBlueprint} */ ({
+ /** @satisfies {SplitSeriesBlueprint} */ ({
title: cohortOptionOrOptions.toLegendName(
arg,
name,
@@ -2886,7 +2887,7 @@ function createPartialOptions(colors) {
title: `Number Of ${title} Unspent Transaction Outputs`,
description: "",
unit: "Count",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Count",
genPath: (id, scale) =>
/** @type {const} */ (
@@ -2932,7 +2933,7 @@ function createPartialOptions(colors) {
title: `${title} Realized Price`,
description: "",
unit: "US Dollars",
- top: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ top: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Realized Price",
genPath: (id, scale) =>
/** @type {const} */ (
@@ -2955,7 +2956,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(
+ ...cohortOptionOrOptions.generateSeriesBlueprints(
arg,
{
@@ -2985,7 +2986,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(
+ ...cohortOptionOrOptions.generateSeriesBlueprints(
arg,
{
@@ -3006,7 +3007,7 @@ function createPartialOptions(colors) {
title: `${title} Realized Profit`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Realized Profit",
singleColor: colors.profit,
genPath: (id, scale) => {
@@ -3023,7 +3024,7 @@ function createPartialOptions(colors) {
title: `${title} Realized Loss`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Realized Loss",
singleColor: colors.loss,
genPath: (id, scale) => {
@@ -3071,7 +3072,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Net PNL",
type: "Baseline",
genPath: (id, scale) => {
@@ -3092,7 +3093,7 @@ function createPartialOptions(colors) {
description: "",
unit: "Percentage",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Net",
type: "Baseline",
genPath: (id) =>
@@ -3113,7 +3114,7 @@ function createPartialOptions(colors) {
title: `${title} Cumulative Realized Profit`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Cumulative Realized Profit",
singleColor: colors.profit,
genPath: (id, scale) =>
@@ -3128,7 +3129,7 @@ function createPartialOptions(colors) {
title: `${title} Cumulative Realized Loss`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Cumulative Realized Loss",
singleColor: colors.loss,
genPath: (id, scale) =>
@@ -3144,7 +3145,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Cumulative Net Realized PNL",
type: "Baseline",
genPath: (id, scale) =>
@@ -3162,7 +3163,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Cumulative Net Realized PNL 30d Change",
type: "Baseline",
genPath: (id, scale) =>
@@ -3182,7 +3183,7 @@ function createPartialOptions(colors) {
description: "",
unit: "Ratio",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Ratio",
type: "Baseline",
options: {
@@ -3210,7 +3211,7 @@ function createPartialOptions(colors) {
description: "",
unit: "Percentage",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "SOPR",
type: "Baseline",
options: {
@@ -3233,7 +3234,7 @@ function createPartialOptions(colors) {
description: "",
unit: "Percentage",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "aSOPR",
type: "Baseline",
options: {
@@ -3263,7 +3264,7 @@ function createPartialOptions(colors) {
title: `${title} Value Created`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Value",
singleColor: colors.profit,
genPath: (id, scale) => {
@@ -3280,7 +3281,7 @@ function createPartialOptions(colors) {
title: `${title} Adjusted Value Created`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Adjusted Value",
singleColor: colors.profit,
genPath: (id, scale) => {
@@ -3302,7 +3303,7 @@ function createPartialOptions(colors) {
title: `${title} Value Destroyed`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Value",
singleColor: colors.loss,
genPath: (id, scale) => {
@@ -3319,7 +3320,7 @@ function createPartialOptions(colors) {
title: `${title} Adjusted Value Destroyed`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Adjusted Value",
singleColor: colors.loss,
genPath: (id, scale) => {
@@ -3341,7 +3342,7 @@ function createPartialOptions(colors) {
title: `${title} Sell Side Risk Ratio`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Ratio",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(id)}sell-side-risk-ratio`,
@@ -3368,7 +3369,7 @@ function createPartialOptions(colors) {
title: `${title} Unrealized Profit`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Profit",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(id)}unrealized-profit`,
@@ -3381,7 +3382,7 @@ function createPartialOptions(colors) {
title: `${title} Unrealized Loss`,
description: "",
unit: "US Dollars",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Loss",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(id)}unrealized-loss`,
@@ -3419,7 +3420,7 @@ function createPartialOptions(colors) {
description: "",
unit: "US Dollars",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Net Unrealized PNL",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(
@@ -3437,7 +3438,7 @@ function createPartialOptions(colors) {
description: "",
unit: "Percentage",
bottom: [
- ...cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ ...cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Relative Net Unrealized PNL",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(
@@ -3505,7 +3506,7 @@ function createPartialOptions(colors) {
title: `${title} Total supply`,
description: "",
unit: "Bitcoin",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
genPath: (id) => `${scale}-to-${datasetIdToPrefix(id)}supply`,
}),
@@ -3516,7 +3517,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Profit`,
description: "",
unit: "Bitcoin",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.profit,
genPath: (id) =>
@@ -3529,7 +3530,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Loss`,
description: "",
unit: "Bitcoin",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.loss,
genPath: (id) =>
@@ -3581,7 +3582,7 @@ function createPartialOptions(colors) {
title: `${title} Total supply Relative To Circulating Supply`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(
@@ -3595,7 +3596,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Profit Relative To Circulating Supply`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.profit,
genPath: (id) =>
@@ -3610,7 +3611,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Loss Relative To Circulating Supply`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.loss,
genPath: (id) =>
@@ -3668,7 +3669,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Profit Relative To Own Supply`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.profit,
genPath: (id) =>
@@ -3683,7 +3684,7 @@ function createPartialOptions(colors) {
title: `${title} Supply In Loss Relative To Own Supply`,
description: "",
unit: "Percentage",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Supply",
singleColor: colors.loss,
genPath: (id) =>
@@ -3732,7 +3733,7 @@ function createPartialOptions(colors) {
title: `${title} Average Price Paid - Realized Price`,
description: "",
unit: "US Dollars",
- top: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ top: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Average",
genPath: (id) =>
`${scale}-to-${datasetIdToPrefix(id)}realized-price`,
@@ -3768,7 +3769,7 @@ function createPartialOptions(colors) {
title: `${title} ${percentile.title}`,
description: "",
unit: /** @type {const} */ ("US Dollars"),
- top: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ top: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Relative Net Unrealized PNL",
genPath: (id) =>
generatePath({
@@ -3923,7 +3924,7 @@ function createPartialOptions(colors) {
title: `${title} Address Count`,
description: "",
unit: "Count",
- bottom: cohortOptionOrOptions.toSeriesBlueprints(arg, {
+ bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, {
title: "Address Count",
genPath: (id) => `${scale}-to-${id}-address-count`,
}),
@@ -5199,7 +5200,7 @@ export function initOptions({
const optionsIds = env.localhost ? [] : undefined;
/**
- * @param {SeriesBlueprint[]} array
+ * @param {SplitSeriesBlueprint[]} array
*/
function getMainIdFromBlueprints(array) {
const searchArray = array.filter(
@@ -5316,6 +5317,7 @@ export function initOptions({
onClick: () => {
selected.set(option);
},
+ type: "multi",
});
const anchor = utils.dom.createAnchorElement({
diff --git a/website/scripts/simulation.js b/website/scripts/simulation.js
index 311b130da..189820a39 100644
--- a/website/scripts/simulation.js
+++ b/website/scripts/simulation.js
@@ -33,15 +33,15 @@ export function init({
const frequencies = computeFrequencies();
- const storagePrefix = "save-in-bitcoin";
+ const keyPrefix = "save-in-bitcoin";
const settings = {
dollars: {
initial: {
amount: signals.createSignal(/** @type {number | null} */ (1000), {
save: {
...utils.serde.number,
- id: `${storagePrefix}-initial-amount`,
- param: "initial-amount",
+ keyPrefix,
+ key: "initial-amount",
},
}),
},
@@ -49,8 +49,8 @@ export function init({
amount: signals.createSignal(/** @type {number | null} */ (150), {
save: {
...utils.serde.number,
- id: `${storagePrefix}-top-up-amount`,
- param: "top-up-amount",
+ keyPrefix,
+ key: "top-up-amount",
},
}),
frenquency: signals.createSignal(
@@ -58,8 +58,8 @@ export function init({
{
save: {
...frequencies.serde,
- id: `${storagePrefix}-top-up-freq`,
- param: "top-up-freq",
+ keyPrefix,
+ key: "top-up-freq",
},
},
),
@@ -70,15 +70,15 @@ export function init({
initial: signals.createSignal(/** @type {number | null} */ (1000), {
save: {
...utils.serde.number,
- id: `${storagePrefix}-initial-swap`,
- param: "initial-swap",
+ keyPrefix,
+ key: "initial-swap",
},
}),
recurrent: signals.createSignal(/** @type {number | null} */ (5), {
save: {
...utils.serde.number,
- id: `${storagePrefix}-recurrent-swap`,
- param: "recurrent-swap",
+ keyPrefix,
+ key: "recurrent-swap",
},
}),
frequency: signals.createSignal(
@@ -86,8 +86,8 @@ export function init({
{
save: {
...frequencies.serde,
- id: `${storagePrefix}-swap-freq`,
- param: "swap-freq",
+ keyPrefix,
+ key: "swap-freq",
},
},
),
@@ -99,16 +99,16 @@ export function init({
{
save: {
...utils.serde.date,
- id: `${storagePrefix}-interval-start`,
- param: "interval-start",
+ keyPrefix,
+ key: "interval-start",
},
},
),
end: signals.createSignal(/** @type {Date | null} */ (new Date()), {
save: {
...utils.serde.date,
- id: `${storagePrefix}-interval-end`,
- param: "interval-end",
+ keyPrefix,
+ key: "interval-end",
},
}),
},
@@ -116,8 +116,8 @@ export function init({
percentage: signals.createSignal(/** @type {number | null} */ (0.25), {
save: {
...utils.serde.number,
- id: `${storagePrefix}-percentage`,
- param: "percentage",
+ keyPrefix,
+ key: "percentage",
},
}),
},
@@ -652,32 +652,28 @@ export function init({
unit: "US Dollars",
config: [
{
- title: "Bitcoin Value",
- kind: "line",
- color: colors.amber,
- owner,
- data: bitcoinValueData,
+ title: "Fees Paid",
+ type: "Line",
+ color: colors.rose,
+ data: () => totalFeesPaidData,
},
{
title: "Dollars Left",
- kind: "line",
+ type: "Line",
color: colors.offDollars,
- owner,
- data: dollarsLeftData,
+ data: () => dollarsLeftData,
},
{
title: "Dollars Converted",
- kind: "line",
+ type: "Line",
color: colors.dollars,
- owner,
- data: totalInvestedAmountData,
+ data: () => totalInvestedAmountData,
},
{
- title: "Fees Paid",
- kind: "line",
- color: colors.rose,
- owner,
- data: totalFeesPaidData,
+ title: "Bitcoin Value",
+ type: "Line",
+ color: colors.amber,
+ data: () => bitcoinValueData,
},
],
},
@@ -698,10 +694,9 @@ export function init({
config: [
{
title: "Bitcoin Stack",
- kind: "line",
+ type: "Line",
color: colors.bitcoin,
- owner,
- data: bitcoinData,
+ data: () => bitcoinData,
},
],
},
@@ -722,17 +717,15 @@ export function init({
config: [
{
title: "Bitcoin Price",
- kind: "line",
- owner,
+ type: "Line",
color: colors.default,
- data: bitcoinPriceData,
+ data: () => bitcoinPriceData,
},
{
title: "Average Price Paid",
- kind: "line",
- owner,
+ type: "Line",
color: colors.lightDollars,
- data: averagePricePaidData,
+ data: () => averagePricePaidData,
},
],
},
@@ -753,9 +746,8 @@ export function init({
config: [
{
title: "Return Of Investment",
- kind: "baseline",
- owner,
- data: resultData,
+ type: "Baseline",
+ data: () => resultData,
// TODO: Doesn't work for some reason
// options: {
// baseLineColor: "#888",
@@ -780,23 +772,22 @@ export function init({
kind: "static",
scale: "date",
utils,
+ owner,
config: [
{
unit: "Percentage",
config: [
{
title: "Unprofitable Days Ratio",
- kind: "line",
- owner,
+ type: "Line",
color: colors.red,
- data: unprofitableDaysRatioData,
+ data: () => unprofitableDaysRatioData,
},
{
title: "Profitable Days Ratio",
- kind: "line",
- owner,
+ type: "Line",
color: colors.green,
- data: profitableDaysRatioData,
+ data: () => profitableDaysRatioData,
},
],
},
@@ -818,8 +809,7 @@ function createInputField({ name, input }) {
const label = window.document.createElement("label");
div.append(label);
- // @ts-ignore
- label.for = input.id;
+ label.htmlFor = input.id;
label.innerHTML = name;
div.append(input);
@@ -856,8 +846,7 @@ function createFieldElement({ title, description, input }) {
throw `Input should've an ID`;
}
- // @ts-ignore
- label.for = forId;
+ label.htmlFor = forId;
return div;
}
diff --git a/website/scripts/types/self.d.ts b/website/scripts/types/self.d.ts
index 8443c7f24..2c33d27a6 100644
--- a/website/scripts/types/self.d.ts
+++ b/website/scripts/types/self.d.ts
@@ -17,7 +17,6 @@ import {
BaselineData,
} from "../../packages/lightweight-charts/v4.2.0/types";
import { DatePath, HeightPath, LastPath } from "./paths";
-import { Owner } from "../../packages/solid-signals/2024-11-02/types/core/owner";
import { AnyPossibleCohortId } from "../options";
import { Signal } from "../../packages/solid-signals/types";
@@ -42,53 +41,6 @@ type AnyPath = AnyDatasetPath | LastPath;
type Color = () => string;
type ColorName = keyof Colors;
-interface BaselineSpecificSeriesBlueprint {
- type: "Baseline";
- color?: Color;
- options?: DeepPartial;
- data?: BaselineData