fix(HEL-494): 日K默认45根并修复问天行业0/205覆盖

悬浮窗和详情页只画最近45个交易日,中枢仍保留250日历史。盘后缺sw_daily时保留成分日线内核,外显走免费申万;成分行情改为全市场快照+分页,不再截成前60只。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
总工
2026-09-08 17:00:01 +08:00
co-authored by Cursor multica-agent
parent 3e828b346c
commit b5d65ecb41
17 changed files with 343 additions and 127 deletions
+3 -3
View File
@@ -3402,9 +3402,9 @@
const payload = detail && detail.payload ? detail.payload : {};
const meta = payload.meta || {};
if (tab === "daily") {
const bars = (payload.prices || []).slice(-48);
const bars = (payload.prices || []).slice(-45);
const last = bars.length ? bars[bars.length - 1].trade_date : "";
return "日线 · 近48根 · 至 " + (displayCompactDate(last) || "--");
return "日线 · 近45根 · 至 " + (displayCompactDate(last) || "--");
}
const d = displayCompactDate(meta.intraday_trade_date) || displayCompactDate(meta.trade_date);
return "分时 · " + (d || "--");
@@ -3702,7 +3702,7 @@
const W = 360, H = 240, padL = 8, padR = 52, padT = 10, padB = 22;
const pw = W - padL - padR;
const ph = H - padT - padB;
const prices = (payload.prices || []).slice(-48);
const prices = (payload.prices || []).slice(-45);
if (prices.length < 2) return emptyChart("日线数据暂不可用");
+4 -4
View File
@@ -68,10 +68,10 @@
"/pages/sentiment/page.js?v=20260729-1",
"/pages/pools/page.js?v=20260820-1",
"/pages/market/breadth.js?v=20260803-1",
"/pages/market/charts.js?v=20260803-1",
"/pages/market/entity-detail.js?v=20260803-1",
"/pages/market/stock-detail.js?v=20260803-1",
"/pages/market/preview.js?v=20260806-1",
"/pages/market/charts.js?v=20260908-1",
"/pages/market/entity-detail.js?v=20260908-1",
"/pages/market/stock-detail.js?v=20260908-1",
"/pages/market/preview.js?v=20260908-1",
"/pages/market/search.js?v=20260803-1",
"/pages/market/bindings.js?v=20260803-1",
"/pages/ladder/page.js?v=20260820-1",
+23 -9
View File
@@ -1,3 +1,16 @@
const DAILY_CHART_BARS = 45;
function visibleDailyPrices(prices) {
return (prices || []).slice(-DAILY_CHART_BARS);
}
function dailyChartSourceLabel(prices, notice) {
const count = visibleDailyPrices(prices).length;
const base = `日 K 行情 · ${count} 个交易日`;
const text = String(notice || "").trim();
return text ? `${base} · ${text}` : base;
}
function currentChartPalette() {
const style = getComputedStyle(document.documentElement);
const color = (token, fallback) => style.getPropertyValue(token).trim() || fallback;
@@ -56,7 +69,8 @@ function drawCandlestick(context, x, item, priceY, candleWidth, palette = curren
function drawPriceChart(prices) {
const canvas = elements.priceChart;
if (!prices?.length) {
const visible = visibleDailyPrices(prices);
if (!visible.length) {
clearPriceChart("暂无日 K 数据");
return;
}
@@ -81,15 +95,15 @@ function drawPriceChart(prices) {
const gap = 12;
const priceBottom = height - bottom - volumeHeight - gap;
const plotWidth = width - left - right;
const highs = prices.map((item) => number(item.high));
const lows = prices.map((item) => number(item.low));
const highs = visible.map((item) => number(item.high));
const lows = visible.map((item) => number(item.low));
const maximum = Math.max(...highs);
const minimum = Math.min(...lows);
const range = Math.max(maximum - minimum, maximum * 0.01, 0.01);
const volumes = prices.map((item) => number(item.volume));
const volumes = visible.map((item) => number(item.volume));
const maxVolume = Math.max(...volumes, 1);
const priceY = (value) => top + (maximum - value) / range * (priceBottom - top);
const step = plotWidth / prices.length;
const step = plotWidth / visible.length;
const candleWidth = clamp(step * 0.62, 2, 8);
context.strokeStyle = palette.grid;
@@ -105,7 +119,7 @@ function drawPriceChart(prices) {
context.fillText((maximum - range * line / 4).toFixed(2), left - 5, y + 4);
}
prices.forEach((item, index) => {
visible.forEach((item, index) => {
const x = left + step * index + step / 2;
const color = drawCandlestick(context, x, item, priceY, candleWidth, palette);
const volumeBarHeight = number(item.volume) / maxVolume * volumeHeight;
@@ -117,10 +131,10 @@ function drawPriceChart(prices) {
context.textAlign = "center";
context.fillStyle = palette.axis;
const labelIndexes = [0, Math.floor((prices.length - 1) / 2), prices.length - 1];
const labelIndexes = [0, Math.floor((visible.length - 1) / 2), visible.length - 1];
labelIndexes.forEach((index) => {
const x = left + step * index + step / 2;
context.fillText(String(prices[index].trade_date).slice(5), x, height - 5);
context.fillText(String(visible[index].trade_date).slice(5), x, height - 5);
});
}
@@ -301,7 +315,7 @@ function drawIntradayPreviewChart(points, dailyPrices, referenceClose = 0) {
function drawDailyPreviewChart(prices) {
const { context, width, height, palette } = prepareStockPreviewCanvas();
const visible = prices.slice(-45);
const visible = visibleDailyPrices(prices);
const visibleStart = prices.length - visible.length;
const left = 45;
const right = 10;
+2 -2
View File
@@ -113,13 +113,13 @@ function renderEntityDetailMetrics(metrics) {
}
function drawEntityDetailChart(series, canvas = elements.entityDetailChart) {
const candles = (series || []).filter((item) => number(item.close) > 0).map((item) => {
const candles = visibleDailyPrices((series || []).filter((item) => number(item.close) > 0).map((item) => {
const close = number(item.close);
const open = number(item.open) || close;
const high = Math.max(number(item.high) || close, open, close);
const low = Math.min(number(item.low) || close, open, close);
return { ...item, open, high, low, close };
});
}));
if (!candles.length) {
clearEntityDetailChart("暂无日 K 数据", canvas);
return;
+1 -4
View File
@@ -368,10 +368,7 @@ function selectStockPreviewChart(chart) {
} else if ((payload.prices || []).length) {
setText("stockPreviewDate", payload.meta?.trade_date || "最新行情");
const notice = String(payload.meta?.notice || "").trim();
setText(
"stockPreviewSource",
notice ? `日 K 行情 · ${payload.prices.length} 个交易日 · ${notice}` : `日 K 行情 · ${payload.prices.length} 个交易日`,
);
setText("stockPreviewSource", dailyChartSourceLabel(payload.prices, notice));
drawDailyPreviewChart(payload.prices);
} else {
setText("stockPreviewDate", payload.meta?.trade_date || "最新行情");
+2 -7
View File
@@ -46,10 +46,7 @@ async function openStock(code, fallback = null) {
updateWatchButton();
if (state.stockDetailChartMode === "daily") {
const notice = String(payload.meta?.notice || "").trim();
setText(
"chartSource",
notice ? `日 K 行情 · ${payload.prices.length} 个交易日 · ${notice}` : `日 K 行情 · ${payload.prices.length} 个交易日`,
);
setText("chartSource", dailyChartSourceLabel(payload.prices, notice));
requestAnimationFrame(() => drawPriceChart(payload.prices || []));
}
} catch (error) {
@@ -69,9 +66,7 @@ async function selectStockDetailChart(mode) {
const notice = String(state.stockDetail?.meta?.notice || "").trim();
setText(
"chartSource",
prices.length
? (notice ? `日 K 行情 · ${prices.length} 个交易日 · ${notice}` : `日 K 行情 · ${prices.length} 个交易日`)
: "正在加载行情",
prices.length ? dailyChartSourceLabel(prices, notice) : "正在加载行情",
);
if (prices.length) requestAnimationFrame(() => drawPriceChart(prices));
else clearPriceChart("正在加载日 K 数据");