hyapp-admin-platform/databi/src/charts/options/createMetricTrendOption.js
2026-06-08 00:53:55 +08:00

63 lines
2.7 KiB
JavaScript

import { compactMoneyAxis, formatCoin } from "../../utils/format.js";
export function createMetricTrendOption(item) {
const lines = Array.isArray(item?.trend) ? item.trend.filter((line) => Array.isArray(line.data) && line.data.length) : [];
const labels = lines[0]?.data.map((point) => point.label) || [];
const values = lines.flatMap((line) => line.data.map((point) => Number(point.value) || 0));
const axis = niceAxis(values);
return {
animationDuration: 650,
color: ["#27e4f5", "#24d79f", "#4f8cff"],
grid: { bottom: 32, left: 58, right: 24, top: 42 },
legend: { icon: "roundRect", itemGap: 18, itemHeight: 8, itemWidth: 14, textStyle: { color: "#a8bdd8", fontSize: 12 }, top: 0 },
tooltip: {
backgroundColor: "#08243a",
borderColor: "#1a5f82",
formatter: (params) => {
const rows = Array.isArray(params) ? params : [params];
return rows.map((row, index) => `${index === 0 ? `${row.axisValue}<br/>` : ""}${row.marker}${row.seriesName}: ${formatTrendValue(row.data, item.trendFormat)}`).join("<br/>");
},
textStyle: { color: "#e9f6ff" },
trigger: "axis"
},
xAxis: { axisLabel: { color: "#90a8c4", margin: 10 }, axisLine: { lineStyle: { color: "#1a3a56" } }, axisTick: { show: false }, boundaryGap: false, data: labels, type: "category" },
yAxis: { axisLabel: { color: "#90a8c4", formatter: (value) => formatTrendValue(value, item.trendFormat, true) }, axisTick: { show: false }, interval: axis.interval, max: axis.max, min: 0, splitLine: { lineStyle: { color: "rgba(111, 166, 212, 0.16)", type: "dashed" } }, type: "value" },
series: lines.map((line) => ({
areaStyle: { color: "rgba(39, 228, 245, 0.08)" },
data: line.data.map((point) => point.value),
lineStyle: { width: 3 },
name: line.name,
smooth: 0.38,
symbol: "circle",
symbolSize: 7,
type: "line"
}))
};
}
export function niceAxis(values) {
const maxValue = Math.max(...values, 0);
if (maxValue <= 0) {
return { interval: 1, max: 4 };
}
const rawStep = maxValue / 4;
const magnitude = 10 ** Math.floor(Math.log10(rawStep));
const normalized = rawStep / magnitude;
const step = (normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10) * magnitude;
return {
interval: step,
max: step * Math.ceil(maxValue / step)
};
}
function formatTrendValue(value, format, axis = false) {
const numeric = Number(value) || 0;
if (format === "money") {
return axis ? compactMoneyAxis(numeric) : `$${numeric.toLocaleString("en-US", { maximumFractionDigits: 2 })}`;
}
if (format === "coin") {
return axis ? compactMoneyAxis(numeric) : formatCoin(numeric);
}
return axis ? compactMoneyAxis(numeric) : numeric.toLocaleString("en-US");
}