feat(ui): 卡片迷你图改用 Chart.js,历史弹窗改为纯表格 - 新增 app/static/vendor/chart.umd.min.js(Chart.js 4.4.3 离线内嵌) - 卡片折线图:Chart.js line(无坐标轴、线色随状态、阈值虚线、动画关闭避免刷新闪烁) - renderAccounts 重绘前销毁旧 Chart 实例防泄漏 - 历史弹窗:移除图表,仅表格(时间/余额,sticky 表头,hover 高亮)
This commit is contained in:
1 parent
cf9e2f5b59
commit
15832772c5
4 files changed
+134
-36
No files matched your search
+72
-36
@@ -14,6 +14,7 @@
|
||||
const checkingIds = new Set();
|
||||
let historyCache = {};
|
||||
let hasRendered = false; // 首次渲染保留进入动画,自动刷新静默更新
|
||||
const cardCharts = {}; // {accountId: Chart} 卡片迷你图实例
|
||||
const accountWindows = {}; // {accountId: 'all'|'1h'|'1d'|'1w'|'1mo'|'1yr'}
|
||||
const windowCache = {}; // {'aid:win': [...]}
|
||||
|
||||
@@ -208,7 +209,6 @@
|
||||
} else {
|
||||
hist = windowCache[a.id + ":" + win] || historyCache[a.id] || [];
|
||||
}
|
||||
const spark = sparkline(hist, a.threshold, st.cls);
|
||||
const winBtns = WINDOW_KEYS.map((k) =>
|
||||
`<button class="win-btn ${win === k ? "active" : ""}" data-act="win" data-win="${k}" title="${WINDOW_LABELS[k]}">${k === "all" ? "ALL" : k.toUpperCase()}</button>`
|
||||
).join("");
|
||||
@@ -231,10 +231,10 @@
|
||||
: `<span class="balance-empty">—</span>`}
|
||||
${th !== null ? `<span class="balance-vs">/ 阈值 ${th}</span>` : ""}
|
||||
</div>
|
||||
${spark
|
||||
${hist.length > 0
|
||||
? `<div class="spark-wrap">
|
||||
<div class="spark-title">余额历史 · ${WINDOW_LABELS[win]}(${hist.length} 条${th !== null ? `,虚线阈值 ${th}` : ""})</div>
|
||||
${spark}
|
||||
<canvas class="card-chart" data-aid="${a.id}"></canvas>
|
||||
<div class="window-switch" data-aid="${a.id}">${winBtns}</div>
|
||||
</div>`
|
||||
: ""}
|
||||
@@ -274,37 +274,55 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* 余额历史迷你折线图(SVG)。含阈值虚线;线色跟随状态。 */
|
||||
function sparkline(hist, threshold, statusCls) {
|
||||
const vals = (hist || []).map((h) => Number(h.balance)).filter(Number.isFinite);
|
||||
if (vals.length === 0) return "";
|
||||
const W = 100, H = 30, PAD = 3;
|
||||
const max = Math.max(...vals, threshold > 0 ? threshold : 0);
|
||||
const min = Math.min(...vals, threshold > 0 ? threshold : 0);
|
||||
const range = max - min || 1;
|
||||
const yOf = (v) => (H - PAD - ((v - min) / range) * (H - PAD * 2)).toFixed(1);
|
||||
const lineColor = statusCls === "warn" ? "var(--warn)"
|
||||
: statusCls === "err" ? "var(--text-3)"
|
||||
: statusCls === "disabled" ? "var(--text-3)"
|
||||
: "var(--ok)";
|
||||
let thLine = "";
|
||||
/* 销毁所有卡片迷你图实例(重绘前调用,避免 canvas 替换后泄漏) */
|
||||
function destroyCardCharts() {
|
||||
Object.values(cardCharts).forEach((c) => { try { c.destroy(); } catch (_) { /* 忽略 */ } });
|
||||
for (const k in cardCharts) delete cardCharts[k];
|
||||
}
|
||||
|
||||
/* 卡片迷你折线图(Chart.js):线色跟随状态,阈值画虚线,无坐标轴 */
|
||||
function createCardChart(canvas, hist, threshold, statusCls) {
|
||||
const css = getComputedStyle(document.documentElement);
|
||||
const lineColor = statusCls === "warn" ? (css.getPropertyValue("--warn").trim() || "#d97706")
|
||||
: statusCls === "err" || statusCls === "disabled" ? (css.getPropertyValue("--text-3").trim() || "#9aa1ad")
|
||||
: (css.getPropertyValue("--accent").trim() || "#3b6ef6");
|
||||
const thColor = css.getPropertyValue("--text-3").trim() || "#9aa1ad";
|
||||
const datasets = [{
|
||||
label: "余额",
|
||||
data: hist.map((h) => h.balance),
|
||||
borderColor: lineColor,
|
||||
backgroundColor: lineColor + "1f",
|
||||
fill: true,
|
||||
tension: 0.35,
|
||||
pointRadius: 0,
|
||||
borderWidth: 1.5,
|
||||
}];
|
||||
if (threshold > 0) {
|
||||
const y = yOf(threshold);
|
||||
thLine = `<line x1="0" y1="${y}" x2="${W}" y2="${y}" stroke="var(--text-3)" stroke-width="1" stroke-dasharray="3 3" opacity="0.75"/>`;
|
||||
datasets.push({
|
||||
label: "阈值",
|
||||
data: [threshold, threshold],
|
||||
borderColor: thColor,
|
||||
borderDash: [4, 4],
|
||||
pointRadius: 0,
|
||||
borderWidth: 1,
|
||||
});
|
||||
}
|
||||
if (vals.length === 1) {
|
||||
const x = W / 2, y = yOf(vals[0]);
|
||||
return `<svg class="sparkline" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">${thLine}<circle cx="${x}" cy="${y}" r="2.2" fill="${lineColor}" vector-effect="non-scaling-stroke"/></svg>`;
|
||||
}
|
||||
const pts = vals.map((v, i) => {
|
||||
const x = (i / (vals.length - 1)) * W;
|
||||
return `${x.toFixed(1)},${yOf(v)}`;
|
||||
return new Chart(canvas, {
|
||||
type: "line",
|
||||
data: { labels: hist.map((h) => h.checked_at), datasets },
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: false, // 自动刷新时不重播动画,避免闪烁
|
||||
plugins: { legend: { display: false }, tooltip: { enabled: false } },
|
||||
scales: { x: { display: false }, y: { display: false } },
|
||||
},
|
||||
});
|
||||
return `<svg class="sparkline" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">${thLine}<polyline points="${pts.join(" ")}" fill="none" stroke="${lineColor}" stroke-width="1.5" stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke"/></svg>`;
|
||||
}
|
||||
|
||||
function renderAccounts(animate = true) {
|
||||
const grid = document.getElementById("account-grid");
|
||||
destroyCardCharts();
|
||||
const stats = { total: accounts.length, ok: 0, below: 0, error: 0, disabled: 0, pending: 0 };
|
||||
accounts.forEach((a) => {
|
||||
const st = statusInfo(a);
|
||||
@@ -340,6 +358,18 @@
|
||||
list = [...list].sort((x, y) => STATUS_ORDER[statusInfo(x).cls] - STATUS_ORDER[statusInfo(y).cls]);
|
||||
|
||||
grid.innerHTML = list.map((a, i) => accountCard(a, i, animate)).join("");
|
||||
// 为每张卡片的 canvas 创建 Chart.js 迷你图
|
||||
grid.querySelectorAll("canvas.card-chart").forEach((canvas) => {
|
||||
const aid = Number(canvas.dataset.aid);
|
||||
const acc = accounts.find((a) => a.id === aid);
|
||||
if (!acc) return;
|
||||
const win = accountWindows[aid] || "all";
|
||||
const hist = win === "all"
|
||||
? (historyCache[aid] || [])
|
||||
: (windowCache[aid + ":" + win] || historyCache[aid] || []);
|
||||
if (hist.length === 0) return;
|
||||
cardCharts[aid] = createCardChart(canvas, hist, acc.threshold, statusInfo(acc).cls);
|
||||
});
|
||||
const hint = document.getElementById("empty-hint");
|
||||
if (accounts.length > 0) {
|
||||
hint.classList.add("hidden");
|
||||
@@ -392,11 +422,12 @@
|
||||
|
||||
/* ---------- 模态框 ---------- */
|
||||
|
||||
function openModal(html, onMount) {
|
||||
function openModal(html, onMount, onClose) {
|
||||
const root = document.getElementById("modal-root");
|
||||
const mask = document.createElement("div");
|
||||
mask.className = "modal-mask";
|
||||
mask.innerHTML = html;
|
||||
if (onClose) mask._onClose = onClose;
|
||||
mask.addEventListener("click", (e) => { if (e.target === mask) closeModal(mask); });
|
||||
document.addEventListener("keydown", (e) => { if (e.key === "Escape") closeModal(mask); }, { once: true });
|
||||
root.appendChild(mask);
|
||||
@@ -405,7 +436,9 @@
|
||||
}
|
||||
|
||||
function closeModal(mask) {
|
||||
if (mask) mask.remove();
|
||||
if (!mask) return;
|
||||
if (mask._onClose) mask._onClose();
|
||||
mask.remove();
|
||||
}
|
||||
|
||||
function confirmDialog(text, onOk) {
|
||||
@@ -513,7 +546,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* 历史弹窗 */
|
||||
/* 历史弹窗:纯表格(时间 + 余额),无图表 */
|
||||
async function showHistory(accountId) {
|
||||
const acc = accounts.find((a) => a.id === accountId);
|
||||
if (!acc) return;
|
||||
@@ -530,12 +563,15 @@
|
||||
body.innerHTML = `<div style="padding:20px 0;text-align:center">暂无记录(检查成功后自动记录)</div>`;
|
||||
return;
|
||||
}
|
||||
const max = Math.max(...hist.map((h) => h.balance), 1e-9);
|
||||
const bars = hist.map((h) =>
|
||||
`<i title="${fmtBalance(h.balance)} ${escapeHtml(plat.currency || "")} @ ${escapeHtml(h.checked_at)}" style="height:${Math.max(6, (h.balance / max) * 100)}%"></i>`).join("");
|
||||
const items = [...hist].reverse().map((h) =>
|
||||
`<div class="history-item"><span>${escapeHtml(h.checked_at)}</span><span class="h-bal">${fmtBalance(h.balance)} ${escapeHtml(plat.currency || "")}</span></div>`).join("");
|
||||
body.innerHTML = `<div class="spark">${bars}</div>${items}`;
|
||||
const rows = [...hist].reverse().map((h) =>
|
||||
`<tr><td>${escapeHtml(h.checked_at)}</td><td class="h-bal">${fmtBalance(h.balance)} ${escapeHtml(plat.currency || "")}</td></tr>`).join("");
|
||||
body.innerHTML = `
|
||||
<div class="hist-list-wrap">
|
||||
<table class="hist-table">
|
||||
<thead><tr><th>时间</th><th>余额</th></tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
</div>`;
|
||||
} catch (e) {
|
||||
mask.querySelector("#hist-body").textContent = "加载失败:" + e.message;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
<div id="toast-root"></div>
|
||||
|
||||
<script src="/static/icons.js"></script>
|
||||
<script src="/static/vendor/chart.umd.min.js"></script>
|
||||
<script src="/static/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -358,6 +358,41 @@ label { font-size: 12px; font-weight: 500; color: var(--text-2); margin-bottom:
|
||||
}
|
||||
.spark i:hover { opacity: 1; }
|
||||
|
||||
/* 历史弹窗表格 */
|
||||
.hist-list-wrap {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.hist-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
.hist-table th, .hist-table td {
|
||||
padding: 7px 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.hist-table th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: var(--bg-elev);
|
||||
color: var(--text-3);
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
}
|
||||
.hist-table tbody tr:last-child td { border-bottom: none; }
|
||||
.hist-table td.h-bal {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.hist-table tbody tr { transition: background 120ms ease; }
|
||||
.hist-table tbody tr:hover { background: var(--bg-elev-2); }
|
||||
|
||||
/* 确认弹窗 */
|
||||
.confirm-modal .modal { width: 340px; }
|
||||
.confirm-text { color: var(--text-2); font-size: 13px; margin-bottom: 18px; line-height: 1.6; }
|
||||
@@ -562,6 +597,12 @@ label { font-size: 12px; font-weight: 500; color: var(--text-2); margin-bottom:
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
/* 卡片迷你图(Chart.js canvas) */
|
||||
.card-chart {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
}
|
||||
.spark-title {
|
||||
font-size: 10px;
|
||||
color: var(--text-3);
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Skipped minification because the original files appears to be already minified.
|
||||
* Original file: /npm/chart.js@4.4.3/dist/chart.umd.js
|
||||
*
|
||||
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
|
||||
*/
|
||||
/*!
|
||||
* Chart.js v4.4.3
|
||||
* https://www.chartjs.org
|
||||
* (c) 2024 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";var t=Object.freeze({__proto__:null,get Colors(){return Go},get Decimation(){return Qo},get Filler(){return ma},get Legend(){return ya},get SubTitle(){return ka},get Title(){return Ma},get Tooltip(){return Ba}});function e(){}const i=(()=>{let t=0;return()=>t++})();function s(t){return null==t}function n(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function o(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)}function r(t,e){return a(t)?t:e}function l(t,e){return void 0===t?e:t}const h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:+t/e,c=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function d(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function u(t,e,i,s){let a,r,l;if(n(t))if(r=t.length,s)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;a<r;a++)e.call(i,t[a],a);else if(o(t))for(l=Object.keys(t),r=l.length,a=0;a<r;a++)e.call(i,t[l[a]],l[a])}function f(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function g(t){if(n(t))return t.map(g);if(o(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=g(t[i[n]]);return e}return t}function p(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function m(t,e,i,s){if(!p(t))return;const n=e[t],a=i[t];o(n)&&o(a)?x(n,a,s):e[t]=g(a)}function x(t,e,i){const s=n(e)?e:[e],a=s.length;if(!o(t))return t;const r=(i=i||{}).merger||m;let l;for(let e=0;e<a;++e){if(l=s[e],!o(l))continue;const n=Object.keys(l);for(let e=0,s=n.length;e<s;++e)r(n[e],t,l,i)}return t}function b(t,e){return x(t,e,{merger:_})}function _(t,e,i){if(!p(t))return;const s=e[t],n=i[t];o(s)&&o(n)?b(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=g(n))}const y={"":t=>t,x:t=>t.x,y:t=>t.y};function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function M(t,e){const i=y[e]||(y[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const k=t=>void 0!==t,S=t=>"function"==typeof t,P=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function D(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const C=Math.PI,O=2*C,A=O+C,T=Number.POSITIVE_INFINITY,L=C/180,E=C/2,R=C/4,I=2*C/3,z=Math.log10,F=Math.sign;function V(t,e,i){return Math.abs(t-e)<i}function B(t){const e=Math.round(t);t=V(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(z(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function W(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function N(t){return!isNaN(parseFloat(t))&&isFinite(t)}function H(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function $(t){return t*(C/180)}function Y(t){return t*(180/C)}function U(t){if(!a(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function X(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*C&&(o+=O),{angle:o,distance:n}}function q(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function K(t,e){return(t-e+A)%O-C}function G(t){return(t%O+O)%O}function Z(t,e,i,s){const n=G(t),o=G(e),a=G(i),r=G(o-n),l=G(a-n),h=G(n-o),c=G(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function J(t,e,i){return Math.max(e,Math.min(i,t))}function Q(t){return J(t,-32768,32767)}function tt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function et(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const it=(t,e,i,s)=>et(t,i,s?s=>{const n=t[s][e];return n<i||n===i&&t[s+1][e]===i}:s=>t[s][e]<i),st=(t,e,i)=>et(t,i,(s=>t[s][e]>=i));function nt(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ot=["push","pop","shift","splice","unshift"];function at(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ot.forEach((e=>{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function rt(t,e){Line truncated
|
||||
/*!
|
||||
* @kurkle/color v0.3.2
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2023 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function zt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(Mt)}function Ft(t,e,i){return zt(Lt,t,e,i)}function Vt(t){return(t%360+360)%360}function Bt(t){const e=Tt.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?vt(+e[5]):Mt(+e[5]));const n=Vt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return zt(Rt,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return zt(Et,t,e,i)}(n,o,a):Ft(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Wt={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},Nt={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let Ht;function jt(t){Ht||(Ht=function(){const t={},e=Object.keys(Nt),i=Object.keys(Wt);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,Wt[o]);o=parseInt(Nt[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),Ht.transparent=[0,0,0,0]);const e=Ht[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const $t=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Yt=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,Ut=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Xt(t,e,i){if(t){let s=It(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),Line truncated
|
||||
//# sourceMappingURL=chart.umd.js.map
|
||||
Reference in new issue
Block a user