mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-18 02:39:43 -07:00
general: fixes
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* @param {Ids} args.ids
|
||||
* @param {Accessor<boolean>} args.dark
|
||||
*/
|
||||
export function initChartsElement({
|
||||
export function init({
|
||||
colors,
|
||||
consts,
|
||||
dark,
|
||||
@@ -796,89 +796,6 @@ export function initChartsElement({
|
||||
}
|
||||
|
||||
function initTimeScaleElement() {
|
||||
function initScrollButtons() {
|
||||
const buttonBackward = utils.dom.getElementById("button-backward");
|
||||
const buttonBackwardIcon = utils.dom.getElementById(
|
||||
"button-backward-icon",
|
||||
);
|
||||
const buttonBackwardPauseIcon = utils.dom.getElementById(
|
||||
"button-backward-pause-icon",
|
||||
);
|
||||
const buttonForward = utils.dom.getElementById("button-forward");
|
||||
const buttonForwardIcon = utils.dom.getElementById("button-forward-icon");
|
||||
const buttonForwardPauseIcon = utils.dom.getElementById(
|
||||
"button-forward-pause-icon",
|
||||
);
|
||||
|
||||
let interval = /** @type {number | undefined} */ (undefined);
|
||||
let direction = /** @type {1 | -1 | 0} */ (0);
|
||||
|
||||
const DELAY = 5;
|
||||
const MULTIPLIER = DELAY / 10000;
|
||||
|
||||
function scrollChart() {
|
||||
if (direction <= 0) {
|
||||
buttonForwardIcon.removeAttribute("hidden");
|
||||
buttonForwardPauseIcon.setAttribute("hidden", "");
|
||||
}
|
||||
if (direction >= 0) {
|
||||
buttonBackwardIcon.removeAttribute("hidden");
|
||||
buttonBackwardPauseIcon.setAttribute("hidden", "");
|
||||
}
|
||||
if (direction === -1) {
|
||||
buttonBackwardIcon.setAttribute("hidden", "");
|
||||
buttonBackwardPauseIcon.removeAttribute("hidden");
|
||||
}
|
||||
if (direction === 1) {
|
||||
buttonForwardIcon.setAttribute("hidden", "");
|
||||
buttonForwardPauseIcon.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (!direction) {
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
|
||||
interval = setInterval(() => {
|
||||
const time = charts.at(-1)?.timeScale();
|
||||
|
||||
if (!time) return;
|
||||
|
||||
const range = time.getVisibleLogicalRange();
|
||||
|
||||
if (!range) return;
|
||||
|
||||
const speed = (range.to - range.from) * MULTIPLIER * direction;
|
||||
|
||||
// @ts-ignore
|
||||
range.from += speed;
|
||||
// @ts-ignore
|
||||
range.to += speed;
|
||||
|
||||
time.setVisibleLogicalRange(range);
|
||||
}, DELAY);
|
||||
}
|
||||
|
||||
buttonBackward.addEventListener("click", () => {
|
||||
if (direction !== -1) {
|
||||
direction = -1;
|
||||
} else {
|
||||
direction = 0;
|
||||
}
|
||||
scrollChart();
|
||||
});
|
||||
|
||||
buttonForward.addEventListener("click", () => {
|
||||
if (direction !== 1) {
|
||||
direction = 1;
|
||||
} else {
|
||||
direction = 0;
|
||||
}
|
||||
scrollChart();
|
||||
});
|
||||
}
|
||||
initScrollButtons();
|
||||
|
||||
const GENESIS_DAY = "2009-01-03";
|
||||
|
||||
/**
|
||||
|
||||
+74
-9
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @import { OptionPath, PartialOption, PartialOptionsGroup, PartialOptionsTree, Option, OptionsGroup, Series, PriceSeriesType, ResourceDataset, TimeScale, SerializedHistory, TimeRange, Unit, Marker, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, SeriesBlueprint, BaselineSpecificSeriesBlueprint, CandlestickSpecificSeriesBlueprint, LineSpecificSeriesBlueprint, SpecificSeriesBlueprintWithChart, Signal, Color, SettingsTheme, DatasetCandlestickData, FoldersFilter, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath } from "./types/self"
|
||||
* @import { OptionPath, PartialOption, PartialOptionsGroup, PartialOptionsTree, Option, OptionsGroup, Series, PriceSeriesType, ResourceDataset, TimeScale, SerializedHistory, TimeRange, Unit, Marker, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, SeriesBlueprint, BaselineSpecificSeriesBlueprint, CandlestickSpecificSeriesBlueprint, LineSpecificSeriesBlueprint, SpecificSeriesBlueprintWithChart, Signal, Color, SettingsTheme, DatasetCandlestickData, FoldersFilter, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath, SimulationOption } from "./types/self"
|
||||
* @import {createChart as CreateClassicChart, createChartEx as CreateCustomChart, LineStyleOptions} from "./packages/lightweight-charts/v4.2.0/types";
|
||||
* @import * as _ from "./packages/ufuzzy/v1.0.14/types"
|
||||
* @import { DeepPartial, ChartOptions, IChartApi, IHorzScaleBehavior, WhitespaceData, SingleValueData, ISeriesApi, Time, LogicalRange, SeriesMarker, CandlestickData, SeriesType, BaselineStyleOptions, SeriesOptionsCommon } from "./packages/lightweight-charts/v4.2.0/types"
|
||||
@@ -720,7 +720,9 @@ const utils = {
|
||||
label.for = inputId;
|
||||
label.title = labelTitle;
|
||||
|
||||
label.addEventListener("click", onClick || (() => {}));
|
||||
if (onClick) {
|
||||
label.addEventListener("click", onClick);
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
@@ -734,6 +736,7 @@ const utils = {
|
||||
* @param {string} args.inputId
|
||||
* @param {string} args.inputValue
|
||||
* @param {string} args.labelTitle
|
||||
* @param {string} [args.href]
|
||||
* @param {(event: MouseEvent) => void} args.onClick
|
||||
*/
|
||||
createComplexLabeledInput({
|
||||
@@ -743,6 +746,7 @@ const utils = {
|
||||
labelTitle,
|
||||
name,
|
||||
onClick,
|
||||
href,
|
||||
}) {
|
||||
const { label, input } = this.createLabeledInput({
|
||||
inputId,
|
||||
@@ -757,7 +761,30 @@ const utils = {
|
||||
label.append(spanMain);
|
||||
|
||||
const spanName = this.createSpanName(name);
|
||||
spanMain.append(spanName);
|
||||
|
||||
if (href) {
|
||||
const anchor = window.document.createElement("a");
|
||||
anchor.href = href;
|
||||
anchor.append(spanName);
|
||||
spanMain.append(anchor);
|
||||
|
||||
if (href.includes(".")) {
|
||||
anchor.target = "_target";
|
||||
anchor.rel = "noopener noreferrer";
|
||||
|
||||
anchor.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
// event.preventDefault();
|
||||
});
|
||||
} else {
|
||||
anchor.addEventListener("click", (event) => {
|
||||
// event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
spanMain.append(spanName);
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
@@ -1249,7 +1276,7 @@ const elements = {
|
||||
selectedHr: utils.dom.getElementById("selected-hr"),
|
||||
home: utils.dom.getElementById("home"),
|
||||
charts: utils.dom.getElementById("charts"),
|
||||
dashboard: utils.dom.getElementById("dashboard"),
|
||||
simulation: utils.dom.getElementById("simulation"),
|
||||
};
|
||||
/** @typedef {typeof elements} Elements */
|
||||
|
||||
@@ -2144,6 +2171,9 @@ packages.signals().then((signals) =>
|
||||
const lastChartOption = signals.createSignal(
|
||||
/** @type {ChartOption | null} */ (null),
|
||||
);
|
||||
const lastSimulationOption = signals.createSignal(
|
||||
/** @type {SimulationOption | null} */ (null),
|
||||
);
|
||||
|
||||
const owner = signals.getOwner();
|
||||
|
||||
@@ -2151,7 +2181,7 @@ packages.signals().then((signals) =>
|
||||
undefined
|
||||
);
|
||||
let firstChartOption = true;
|
||||
let firstDashboardOption = true;
|
||||
let firstSimulationOption = true;
|
||||
|
||||
signals.createEffect(() => {
|
||||
const option = options.selected();
|
||||
@@ -2187,9 +2217,9 @@ packages.signals().then((signals) =>
|
||||
|
||||
if (firstChartOption) {
|
||||
const lightweightCharts = packages.lightweightCharts();
|
||||
const chartsScript = import("./chart.js");
|
||||
const chartScript = import("./chart.js");
|
||||
utils.dom.importStyleAndThen("/styles/chart.css", () =>
|
||||
chartsScript.then(({ initChartsElement }) =>
|
||||
chartScript.then(({ init: initChartsElement }) =>
|
||||
lightweightCharts.then((lightweightCharts) =>
|
||||
signals.runWithOwner(owner, () =>
|
||||
initChartsElement({
|
||||
@@ -2215,8 +2245,43 @@ packages.signals().then((signals) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case "pdf": {
|
||||
utils.dom.open(`/assets/pdfs/${option.file}`, true);
|
||||
case "simulation": {
|
||||
element = elements.simulation;
|
||||
|
||||
lastSimulationOption.set(option);
|
||||
|
||||
if (firstSimulationOption) {
|
||||
const lightweightCharts = packages.lightweightCharts();
|
||||
const simulationScript = import("./simulation.js");
|
||||
|
||||
utils.dom.importStyleAndThen("/styles/simulation.css", () =>
|
||||
simulationScript.then(({ init }) =>
|
||||
lightweightCharts.then((lightweightCharts) =>
|
||||
signals.runWithOwner(owner, () =>
|
||||
init({
|
||||
colors,
|
||||
consts,
|
||||
dark,
|
||||
datasets,
|
||||
elements,
|
||||
ids,
|
||||
lightweightCharts,
|
||||
options,
|
||||
selected: /** @type {any} */ (lastChartOption),
|
||||
signals,
|
||||
utils,
|
||||
webSockets,
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
firstSimulationOption = false;
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4820,6 +4820,17 @@ function createPartialOptions(colors) {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Simulations",
|
||||
tree: [
|
||||
{
|
||||
icon: "🧪",
|
||||
kind: "simulation",
|
||||
title: "Dollar Cost Average Simulation",
|
||||
name: "Dollar Cost Average",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Library",
|
||||
tree: [
|
||||
@@ -5075,7 +5086,12 @@ export function initOptions({
|
||||
inputName: `option-${frame}${id || ""}`,
|
||||
labelTitle: option.title,
|
||||
name: name || option.name,
|
||||
onClick: () => selected.set(option),
|
||||
onClick: () => {
|
||||
// if (option.kind !== "pdf") {
|
||||
selected.set(option);
|
||||
// }
|
||||
},
|
||||
href: `/${option.kind === "pdf" ? option.file : option.id}`,
|
||||
});
|
||||
|
||||
if (top) {
|
||||
@@ -5343,6 +5359,7 @@ export function initOptions({
|
||||
kind = "pdf";
|
||||
id = `${ids.fromString(anyPartial.name)}-pdf`;
|
||||
title = anyPartial.name;
|
||||
anyPartial.file = `assets/pdfs/${anyPartial.file}`;
|
||||
} else if ("scale" in anyPartial) {
|
||||
kind = "chart";
|
||||
id = `chart-${anyPartial.scale}-to-${ids.fromString(
|
||||
@@ -5350,8 +5367,11 @@ export function initOptions({
|
||||
)}`;
|
||||
title = anyPartial.title;
|
||||
} else {
|
||||
console.log(anyPartial);
|
||||
throw "Unreachable";
|
||||
kind = anyPartial.kind;
|
||||
title = anyPartial.title;
|
||||
console.log("Unprocessed", anyPartial);
|
||||
id = `${kind}-${ids.fromString(anyPartial.title)}`;
|
||||
// return;
|
||||
}
|
||||
|
||||
/** @type {ProcessedOptionAddons} */
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @import {Options} from './options';
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} args
|
||||
* @param {Colors} args.colors
|
||||
* @param {Consts} args.consts
|
||||
* @param {LightweightCharts} args.lightweightCharts
|
||||
* @param {Accessor<ChartOption>} args.selected
|
||||
* @param {Signals} args.signals
|
||||
* @param {Utilities} args.utils
|
||||
* @param {Options} args.options
|
||||
* @param {Datasets} args.datasets
|
||||
* @param {WebSockets} args.webSockets
|
||||
* @param {Elements} args.elements
|
||||
* @param {Ids} args.ids
|
||||
* @param {Accessor<boolean>} args.dark
|
||||
*/
|
||||
export function init({
|
||||
colors,
|
||||
consts,
|
||||
dark,
|
||||
datasets,
|
||||
elements,
|
||||
ids,
|
||||
lightweightCharts,
|
||||
options,
|
||||
selected,
|
||||
signals,
|
||||
utils,
|
||||
webSockets,
|
||||
}) {
|
||||
const simulationElement = elements.simulation;
|
||||
}
|
||||
Vendored
-8
File diff suppressed because one or more lines are too long
Vendored
+11
-3
@@ -125,6 +125,12 @@ interface PartialChartOption extends PartialOption {
|
||||
};
|
||||
}
|
||||
|
||||
interface PartialSimulationOption extends PartialOption {
|
||||
kind: "simulation";
|
||||
title: "Dollar Cost Average Simulation";
|
||||
name: "Dollar Cost Average";
|
||||
}
|
||||
|
||||
interface PartialPdfOption extends PartialOption {
|
||||
file: string;
|
||||
}
|
||||
@@ -136,8 +142,9 @@ interface PartialOptionsGroup {
|
||||
|
||||
type AnyPartialOption =
|
||||
| PartialHomeOption
|
||||
| PartialPdfOption
|
||||
| PartialChartOption;
|
||||
| PartialChartOption
|
||||
| PartialSimulationOption
|
||||
| PartialPdfOption;
|
||||
|
||||
type PartialOptionsTree = (AnyPartialOption | PartialOptionsGroup)[];
|
||||
|
||||
@@ -155,6 +162,7 @@ type OptionPath = {
|
||||
}[];
|
||||
|
||||
type HomeOption = PartialHomeOption & ProcessedOptionAddons;
|
||||
type SimulationOption = PartialSimulationOption & ProcessedOptionAddons;
|
||||
|
||||
interface PdfOption extends PartialPdfOption, ProcessedOptionAddons {
|
||||
kind: "pdf";
|
||||
@@ -165,7 +173,7 @@ interface ChartOption extends PartialChartOption, ProcessedOptionAddons {
|
||||
kind: "chart";
|
||||
}
|
||||
|
||||
type Option = HomeOption | PdfOption | ChartOption;
|
||||
type Option = HomeOption | PdfOption | ChartOption | SimulationOption;
|
||||
|
||||
type OptionsTree = (Option | OptionsGroup)[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user