From e5f675c6ca8b41dd93732c85ea2666c8a1c4518f Mon Sep 17 00:00:00 2001 From: dekun Date: Fri, 26 Jun 2026 01:11:21 +0800 Subject: [PATCH] Sync equity curve with card theme and keep trade actions on one row. Use CSS variables for chart colors with dark/light auto-switch; prevent trade action buttons from wrapping. Co-authored-by: Cursor --- static/js/equity_curve.js | 144 +++++++++++++++++++++++++++----------- templates/base.html | 4 +- 2 files changed, 105 insertions(+), 43 deletions(-) diff --git a/static/js/equity_curve.js b/static/js/equity_curve.js index 09c4e77..436390c 100644 --- a/static/js/equity_curve.js +++ b/static/js/equity_curve.js @@ -3,6 +3,25 @@ var raw = window.__EQUITY_CURVE__; if (!el || !raw || !raw.length || !window.LightweightCharts) return; + var chart = null; + var series = null; + var chartData = []; + + function cssVar(name, fallback) { + var v = getComputedStyle(document.documentElement).getPropertyValue(name).trim(); + return v || fallback; + } + + function themeColors() { + return { + bg: cssVar('--card-inner', '#101424'), + text: cssVar('--text-muted', '#7a82a0'), + grid: cssVar('--table-border', 'rgba(76,194,255,.1)'), + border: cssVar('--card-border', 'rgba(76,194,255,.22)'), + line: cssVar('--accent', '#4cc2ff'), + }; + } + function parseTime(s) { if (!s) return null; var t = String(s).trim().replace(' ', 'T'); @@ -12,50 +31,93 @@ return Math.floor(d.getTime() / 1000); } - var data = []; - var lastTs = 0; - raw.forEach(function (p) { - var ts = parseTime(p.time); - if (ts == null) return; - if (ts <= lastTs) ts = lastTs + 1; - lastTs = ts; - data.push({ time: ts, value: Number(p.value) }); - }); - if (!data.length) { - el.innerHTML = '

暂无资金曲线数据

'; - return; + function buildData() { + var data = []; + var lastTs = 0; + raw.forEach(function (p) { + var ts = parseTime(p.time); + if (ts == null) return; + if (ts <= lastTs) ts = lastTs + 1; + lastTs = ts; + data.push({ time: ts, value: Number(p.value) }); + }); + return data; } - var c = { - bg: '#1a1d24', - text: '#9ca3af', - grid: '#2d3139', - line: '#6366f1', - }; - var chart = LightweightCharts.createChart(el, { - width: el.clientWidth || 800, - height: 220, - layout: { - background: { type: 'solid', color: c.bg }, - textColor: c.text, - fontSize: 11, - }, - grid: { - vertLines: { color: c.grid }, - horzLines: { color: c.grid }, - }, - rightPriceScale: { borderColor: c.grid }, - timeScale: { borderColor: c.grid, timeVisible: true, secondsVisible: false }, - }); - var series = chart.addLineSeries({ - color: c.line, - lineWidth: 2, - priceFormat: { type: 'price', precision: 2, minMove: 0.01 }, - }); - series.setData(data); - chart.timeScale().fitContent(); + function applyChartTheme() { + if (!chart || !series) return; + var c = themeColors(); + chart.applyOptions({ + layout: { + background: { type: 'solid', color: c.bg }, + textColor: c.text, + }, + grid: { + vertLines: { color: c.grid }, + horzLines: { color: c.grid }, + }, + rightPriceScale: { borderColor: c.border }, + timeScale: { borderColor: c.border }, + }); + series.applyOptions({ color: c.line }); + } + + function renderChart() { + chartData = buildData(); + if (!chartData.length) { + el.innerHTML = '

暂无资金曲线数据

'; + return; + } + + var c = themeColors(); + if (chart) { + chart.remove(); + chart = null; + series = null; + } + + chart = LightweightCharts.createChart(el, { + width: el.clientWidth || 800, + height: 220, + layout: { + background: { type: 'solid', color: c.bg }, + textColor: c.text, + fontSize: 11, + }, + grid: { + vertLines: { color: c.grid }, + horzLines: { color: c.grid }, + }, + rightPriceScale: { borderColor: c.border }, + timeScale: { borderColor: c.border, timeVisible: true, secondsVisible: false }, + }); + series = chart.addLineSeries({ + color: c.line, + lineWidth: 2, + priceFormat: { type: 'price', precision: 2, minMove: 0.01 }, + }); + series.setData(chartData); + chart.timeScale().fitContent(); + } + + renderChart(); window.addEventListener('resize', function () { - chart.applyOptions({ width: el.clientWidth || 800 }); + if (chart) chart.applyOptions({ width: el.clientWidth || 800 }); }); + + document.addEventListener('click', function (e) { + if (e.target.closest('[data-theme-pick]')) { + setTimeout(applyChartTheme, 50); + } + }); + + if (typeof MutationObserver !== 'undefined') { + var obs = new MutationObserver(function (mutations) { + mutations.forEach(function (m) { + if (m.attributeName === 'data-theme') applyChartTheme(); + }); + }); + obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); + } })(); diff --git a/templates/base.html b/templates/base.html index 8a1f38f..fbafc14 100644 --- a/templates/base.html +++ b/templates/base.html @@ -432,8 +432,8 @@ .trade-table .cell-readonly{color:var(--text-primary)} .records-trade-card{overflow:visible} .records-trade-card .card-body{overflow:visible} - .trade-actions{display:flex;gap:.35rem;flex-wrap:wrap;align-items:center;min-width:148px} - .trade-actions a,.trade-actions button{font-size:.72rem;padding:.3rem .55rem;border-radius:6px;text-decoration:none;border:none;cursor:pointer} + .trade-actions{display:flex;gap:.35rem;flex-wrap:nowrap;align-items:center;min-width:230px;white-space:nowrap} + .trade-actions a,.trade-actions button{flex-shrink:0;white-space:nowrap;font-size:.72rem;padding:.3rem .55rem;border-radius:6px;text-decoration:none;border:none;cursor:pointer} .btn-fill{background:var(--dir-bg);color:var(--accent)} .btn-verify{background:var(--nav-active);color:#fff} .btn-verify:disabled{opacity:.45;cursor:not-allowed}