mirror of
https://github.com/fankes/komari-theme-purcarte.git
synced 2025-10-18 11:29:22 +08:00
feat: 优化延迟图表,添加连接断点控制
This commit is contained in:
@@ -147,6 +147,13 @@
|
||||
"default": true,
|
||||
"help": "启用后默认显示延迟图表"
|
||||
},
|
||||
{
|
||||
"key": "enableConnectBreaks",
|
||||
"name": "启用连接断点",
|
||||
"type": "switch",
|
||||
"default": false,
|
||||
"help": "启用后图表中的曲线将会跨过断点形成连续的线条,并使用半透明的垂直参考线来标记断点位置"
|
||||
},
|
||||
{
|
||||
"key": "pingChatrtMaxPoints",
|
||||
"name": "延迟图表最大渲染点数",
|
||||
|
@@ -97,6 +97,8 @@ export function ConfigProvider({
|
||||
enableInstanceDetail:
|
||||
theme.enableInstanceDetail ?? DEFAULT_CONFIG.enableInstanceDetail,
|
||||
enablePingChart: theme.enablePingChart ?? DEFAULT_CONFIG.enablePingChart,
|
||||
enableConnectBreaks:
|
||||
theme.enableConnectBreaks ?? DEFAULT_CONFIG.enableConnectBreaks,
|
||||
pingChartMaxPoints:
|
||||
theme.pingChartMaxPoints || DEFAULT_CONFIG.pingChartMaxPoints,
|
||||
backgroundImage,
|
||||
|
@@ -16,6 +16,7 @@ export interface ConfigOptions {
|
||||
enableGroupedBar?: boolean; // 是否启用分组栏
|
||||
enableInstanceDetail?: boolean; // 是否启用实例详情
|
||||
enablePingChart?: boolean; // 是否启用延迟图表
|
||||
enableConnectBreaks?: boolean; // 是否启用连接断点
|
||||
pingChartMaxPoints?: number; // 延迟图表最大点数
|
||||
enableSwap?: boolean; // 是否启用SWAP显示
|
||||
}
|
||||
@@ -39,6 +40,7 @@ export const DEFAULT_CONFIG: ConfigOptions = {
|
||||
enableGroupedBar: true,
|
||||
enableInstanceDetail: true,
|
||||
enablePingChart: true,
|
||||
enableConnectBreaks: false,
|
||||
pingChartMaxPoints: 0,
|
||||
enableSwap: true,
|
||||
};
|
||||
|
@@ -117,11 +117,13 @@ const Instance = memo(({ node }: InstanceProps) => {
|
||||
<div>
|
||||
<p className="text-muted-foreground text-sm">总流量</p>
|
||||
<div className="flex items-center gap-2">
|
||||
{node.traffic_limit && isOnline && (
|
||||
{node.traffic_limit !== 0 && isOnline && stats && (
|
||||
<CircleProgress
|
||||
value={trafficPercentage}
|
||||
maxValue={100}
|
||||
size={36}
|
||||
size={32}
|
||||
strokeWidth={4}
|
||||
showPercentage={true}
|
||||
/>
|
||||
)}
|
||||
<div>
|
||||
|
@@ -31,7 +31,9 @@ const PingChart = memo(({ node, hours }: PingChartProps) => {
|
||||
const [visiblePingTasks, setVisiblePingTasks] = useState<number[]>([]);
|
||||
const [timeRange, setTimeRange] = useState<[number, number] | null>(null);
|
||||
const [cutPeak, setCutPeak] = useState(false);
|
||||
const [connectBreaks, setConnectBreaks] = useState(false);
|
||||
const [connectBreaks, setConnectBreaks] = useState(
|
||||
useConfigItem("enableConnectBreaks")
|
||||
);
|
||||
const maxPointsToRender = useConfigItem("pingChartMaxPoints") || 0; // 0表示不限制
|
||||
|
||||
useEffect(() => {
|
||||
@@ -147,12 +149,27 @@ const PingChart = memo(({ node, hours }: PingChartProps) => {
|
||||
}, [pingHistory?.tasks]);
|
||||
|
||||
const generateColor = useCallback(
|
||||
(taskName: string, total: number, isBreakPoints?: boolean) => {
|
||||
(taskName: string, total: number) => {
|
||||
const index = sortedTasks.findIndex((t) => t.name === taskName);
|
||||
if (index === -1) return "#000000"; // Fallback color
|
||||
|
||||
const hue = (index * (360 / total)) % 360;
|
||||
return `hsla(${hue}, 50%, 60%, ${isBreakPoints ? 0.7 : 1})`;
|
||||
|
||||
// 使用OKLCH色彩空间,优化折线图的颜色区分度
|
||||
// L=0.7 (较高亮度,便于在图表背景上清晰显示)
|
||||
// C=0.2 (较高饱和度,增强颜色区分度)
|
||||
const oklchColor = `oklch(0.6 0.2 ${hue} / .8)`;
|
||||
|
||||
// 为不支持OKLCH的浏览器提供HSL备用色
|
||||
// 使用更高的饱和度和适中的亮度来匹配OKLCH的视觉效果
|
||||
const hslFallback = `hsl(${hue}, 50%, 60%)`;
|
||||
|
||||
// 检查浏览器是否支持OKLCH
|
||||
if (CSS.supports("color", oklchColor)) {
|
||||
return oklchColor;
|
||||
} else {
|
||||
return hslFallback;
|
||||
}
|
||||
},
|
||||
[sortedTasks]
|
||||
);
|
||||
@@ -180,7 +197,7 @@ const PingChart = memo(({ node, hours }: PingChartProps) => {
|
||||
if (isBreak) {
|
||||
points.push({
|
||||
x: currentPoint.time,
|
||||
color: generateColor(task.name, sortedTasks.length, true),
|
||||
color: generateColor(task.name, sortedTasks.length),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -271,7 +288,7 @@ const PingChart = memo(({ node, hours }: PingChartProps) => {
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
'<h2 class="text-lg font-bold">关于连接断点的提示</h2><p>当您开启"连接断点"功能后,图表中的曲线将会跨过那些由于网络问题或其他原因导致的丢包点,形成一条连续的线条。同时,系统会在丢包位置显示<strong>半透明的垂直参考线</strong>来标记断点位置。</p>',
|
||||
'<h2 class="text-lg font-bold">关于连接断点的提示</h2><p><strong>默认关闭,可在后台配置</strong></p><p>当您开启"连接断点"功能后,图表中的曲线将会跨过那些由于网络问题或其他原因导致的丢包点,形成一条连续的线条。同时,系统会在丢包位置显示<strong>半透明的垂直参考线</strong>来标记断点位置。</p>',
|
||||
}}
|
||||
/>
|
||||
</Tips>
|
||||
@@ -322,14 +339,14 @@ const PingChart = memo(({ node, hours }: PingChartProps) => {
|
||||
key={`break-${index}`}
|
||||
x={point.x}
|
||||
stroke={point.color}
|
||||
strokeWidth={1}
|
||||
strokeWidth={1.5}
|
||||
strokeOpacity={0.5}
|
||||
/>
|
||||
))}
|
||||
{sortedTasks.map((task) => (
|
||||
<Line
|
||||
key={task.id}
|
||||
type={"basis"}
|
||||
type={"monotone"}
|
||||
dataKey={String(task.id)}
|
||||
name={task.name}
|
||||
stroke={generateColor(task.name, sortedTasks.length)}
|
||||
|
Reference in New Issue
Block a user