feat: scaffold gold_monitor web hub, API, PM2 deploy and docs
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/** 轻量蜡烛图(无外部依赖),用于复盘四周期预览 */
|
||||
(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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user