增加K线
This commit is contained in:
+46
-2
@@ -42,6 +42,10 @@ let lwcVolumeSeries = null;
|
|||||||
let lwcResizeObserver = null;
|
let lwcResizeObserver = null;
|
||||||
let lwcPriceLines = [];
|
let lwcPriceLines = [];
|
||||||
const symbolPriceMeta = new Map();
|
const symbolPriceMeta = new Map();
|
||||||
|
let lwcModalCandles = [];
|
||||||
|
let lwcModalInterval = "1d";
|
||||||
|
let lwcModalPriceMeta = { tick_size: "0.01", price_precision: 2 };
|
||||||
|
let lwcOnVisibleRangeChange = null;
|
||||||
|
|
||||||
function cacheKey(symbol, interval) {
|
function cacheKey(symbol, interval) {
|
||||||
return `${symbol}:${interval}`;
|
return `${symbol}:${interval}`;
|
||||||
@@ -144,6 +148,38 @@ function findCandleExtremes(candles, interval) {
|
|||||||
return { maxHigh, minLow, highTime, lowTime };
|
return { maxHigh, minLow, highTime, lowTime };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function candlesInLogicalRange(candles, range) {
|
||||||
|
if (!range || !candles.length) return candles;
|
||||||
|
const from = Math.max(0, Math.floor(range.from));
|
||||||
|
const to = Math.min(candles.length - 1, Math.ceil(range.to));
|
||||||
|
if (from > to) return [];
|
||||||
|
return candles.slice(from, to + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHighLowForVisibleWindow() {
|
||||||
|
if (!lwcChart || !lwcCandleSeries || !lwcModalCandles.length) return;
|
||||||
|
const range = lwcChart.timeScale().getVisibleLogicalRange();
|
||||||
|
const visible = candlesInLogicalRange(lwcModalCandles, range);
|
||||||
|
const subset = visible.length ? visible : lwcModalCandles;
|
||||||
|
applyHighLowAnnotations(subset, lwcModalInterval, lwcModalPriceMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindVisibleRangeHighLow() {
|
||||||
|
if (!lwcChart) return;
|
||||||
|
unbindVisibleRangeHighLow();
|
||||||
|
lwcOnVisibleRangeChange = () => {
|
||||||
|
updateHighLowForVisibleWindow();
|
||||||
|
};
|
||||||
|
lwcChart.timeScale().subscribeVisibleLogicalRangeChange(lwcOnVisibleRangeChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unbindVisibleRangeHighLow() {
|
||||||
|
if (lwcChart && lwcOnVisibleRangeChange) {
|
||||||
|
lwcChart.timeScale().unsubscribeVisibleLogicalRangeChange(lwcOnVisibleRangeChange);
|
||||||
|
}
|
||||||
|
lwcOnVisibleRangeChange = null;
|
||||||
|
}
|
||||||
|
|
||||||
function toLwcTime(ms, interval) {
|
function toLwcTime(ms, interval) {
|
||||||
if (interval === "1d" || interval === "1w") {
|
if (interval === "1d" || interval === "1w") {
|
||||||
const d = new Date(ms);
|
const d = new Date(ms);
|
||||||
@@ -374,7 +410,9 @@ async function loadMiniChart(box) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function destroyLwcChart() {
|
function destroyLwcChart() {
|
||||||
|
unbindVisibleRangeHighLow();
|
||||||
clearHighLowAnnotations();
|
clearHighLowAnnotations();
|
||||||
|
lwcModalCandles = [];
|
||||||
if (lwcResizeObserver) {
|
if (lwcResizeObserver) {
|
||||||
lwcResizeObserver.disconnect();
|
lwcResizeObserver.disconnect();
|
||||||
lwcResizeObserver = null;
|
lwcResizeObserver = null;
|
||||||
@@ -523,6 +561,8 @@ function ensureLwcChart(container) {
|
|||||||
});
|
});
|
||||||
lwcResizeObserver.observe(container);
|
lwcResizeObserver.observe(container);
|
||||||
|
|
||||||
|
bindVisibleRangeHighLow();
|
||||||
|
|
||||||
return lwcChart;
|
return lwcChart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,11 +576,15 @@ function renderLwcChart(candles, interval, priceMeta) {
|
|||||||
const meta = getPriceMeta(chartModalSymbol, priceMeta);
|
const meta = getPriceMeta(chartModalSymbol, priceMeta);
|
||||||
applySeriesPriceFormat(meta);
|
applySeriesPriceFormat(meta);
|
||||||
|
|
||||||
|
lwcModalCandles = candles;
|
||||||
|
lwcModalInterval = interval;
|
||||||
|
lwcModalPriceMeta = meta;
|
||||||
|
|
||||||
const { ohlc, vol } = candlesToLwc(candles, interval);
|
const { ohlc, vol } = candlesToLwc(candles, interval);
|
||||||
lwcCandleSeries.setData(ohlc);
|
lwcCandleSeries.setData(ohlc);
|
||||||
lwcVolumeSeries.setData(vol);
|
lwcVolumeSeries.setData(vol);
|
||||||
applyHighLowAnnotations(candles, interval, meta);
|
|
||||||
lwcChart.timeScale().fitContent();
|
lwcChart.timeScale().fitContent();
|
||||||
|
requestAnimationFrame(() => updateHighLowForVisibleWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateIntervalTabs() {
|
function updateIntervalTabs() {
|
||||||
@@ -556,7 +600,7 @@ function updateModalMeta(candles, source, interval) {
|
|||||||
title.textContent = `${chartModalSymbol} · ${interval.toUpperCase()} K线`;
|
title.textContent = `${chartModalSymbol} · ${interval.toUpperCase()} K线`;
|
||||||
}
|
}
|
||||||
if (hint) {
|
if (hint) {
|
||||||
hint.textContent = `${candles.length} 根 · ${sourceLabel(source)} · 滚轮缩放 · 拖拽平移 · 十字线 · Esc 或点击遮罩关闭`;
|
hint.textContent = `${candles.length} 根 · ${sourceLabel(source)} · 最高/最低随可见窗口 · 滚轮缩放 · Esc 关闭`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user