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