/** 轻量蜡烛图(无外部依赖),用于复盘四周期预览 */ (function () { function drawCandleChart(canvas, bars) { if (!canvas || !bars || !bars.length) return; const dpr = window.devicePixelRatio || 1; const cssW = canvas.clientWidth || 400; const cssH = canvas.clientHeight || 180; canvas.width = cssW * dpr; canvas.height = cssH * dpr; const ctx = canvas.getContext("2d"); ctx.scale(dpr, dpr); const pad = 8; let min = Infinity, max = -Infinity; bars.forEach((b) => { min = Math.min(min, b.low); max = Math.max(max, b.high); }); if (!(max > min)) { max = min + 1; } const w = cssW - pad * 2; const h = cssH - pad * 2; const n = bars.length; const slot = w / n; ctx.clearRect(0, 0, cssW, cssH); ctx.fillStyle = "#0e0e18"; ctx.fillRect(0, 0, cssW, cssH); const yOf = (p) => pad + ((max - p) / (max - min)) * h; bars.forEach((b, i) => { const x = pad + i * slot + slot * 0.5; const up = b.close >= b.open; ctx.strokeStyle = up ? "#0ecb81" : "#f6465d"; ctx.fillStyle = ctx.strokeStyle; ctx.beginPath(); ctx.moveTo(x, yOf(b.high)); ctx.lineTo(x, yOf(b.low)); ctx.stroke(); const y1 = yOf(b.open); const y2 = yOf(b.close); const top = Math.min(y1, y2); const bh = Math.max(1, Math.abs(y2 - y1)); ctx.fillRect(x - Math.max(1, slot * 0.3), top, Math.max(2, slot * 0.6), bh); }); } document.querySelectorAll("canvas.chart-canvas").forEach((el) => { try { const bars = JSON.parse(el.dataset.bars || "[]"); drawCandleChart(el, bars); } catch (e) { console.warn(e); } }); })();