95 lines
2.8 KiB
JavaScript
95 lines
2.8 KiB
JavaScript
// src/views/Community/components/DynamicNewsDetail/MiniLineChart.js
|
||
// Mini 折线图组件(用于股票卡片)
|
||
|
||
import React from 'react';
|
||
import { Box } from '@chakra-ui/react';
|
||
|
||
/**
|
||
* Mini 折线图组件
|
||
* @param {Object} props
|
||
* @param {Array<number>} props.data - 价格走势数据数组(15个数据点:前5+中5+后5)
|
||
* @param {number} props.width - 图表宽度(默认180)
|
||
* @param {number} props.height - 图表高度(默认60)
|
||
*/
|
||
const MiniLineChart = ({ data = [], width = 180, height = 60 }) => {
|
||
if (!data || data.length === 0) {
|
||
return null;
|
||
}
|
||
|
||
// 计算最大值和最小值,用于归一化
|
||
const max = Math.max(...data);
|
||
const min = Math.min(...data);
|
||
const range = max - min || 1; // 防止除以0
|
||
|
||
// 将数据点转换为 SVG 路径坐标
|
||
const points = data.map((value, index) => {
|
||
const x = (index / (data.length - 1)) * width;
|
||
const y = height - ((value - min) / range) * height;
|
||
return `${x.toFixed(2)},${y.toFixed(2)}`;
|
||
});
|
||
|
||
// 构建 SVG 路径字符串
|
||
const pathD = `M ${points.join(' L ')}`;
|
||
|
||
// 判断整体趋势(比较第一个和最后一个值)
|
||
const isPositive = data[data.length - 1] >= data[0];
|
||
const strokeColor = isPositive ? '#48BB78' : '#F56565'; // 绿色上涨,红色下跌
|
||
|
||
// 创建渐变填充区域路径
|
||
const fillPathD = `${pathD} L ${width},${height} L 0,${height} Z`;
|
||
|
||
return (
|
||
<Box width={`${width}px`} height={`${height}px`}>
|
||
<svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
|
||
<defs>
|
||
<linearGradient id={`gradient-${isPositive ? 'up' : 'down'}`} x1="0%" y1="0%" x2="0%" y2="100%">
|
||
<stop offset="0%" stopColor={strokeColor} stopOpacity="0.3" />
|
||
<stop offset="100%" stopColor={strokeColor} stopOpacity="0.05" />
|
||
</linearGradient>
|
||
</defs>
|
||
|
||
{/* 填充区域 */}
|
||
<path
|
||
d={fillPathD}
|
||
fill={`url(#gradient-${isPositive ? 'up' : 'down'})`}
|
||
/>
|
||
|
||
{/* 折线 */}
|
||
<path
|
||
d={pathD}
|
||
fill="none"
|
||
stroke={strokeColor}
|
||
strokeWidth="1.5"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
/>
|
||
|
||
{/* 垂直分隔线(标记三个时间段) */}
|
||
{/* 前一天和当天之间 */}
|
||
<line
|
||
x1={width / 3}
|
||
y1={0}
|
||
x2={width / 3}
|
||
y2={height}
|
||
stroke="#E2E8F0"
|
||
strokeWidth="1"
|
||
strokeDasharray="2,2"
|
||
/>
|
||
|
||
{/* 当天和后一天之间 */}
|
||
<line
|
||
x1={(width * 2) / 3}
|
||
y1={0}
|
||
x2={(width * 2) / 3}
|
||
y2={height}
|
||
stroke="#E2E8F0"
|
||
strokeWidth="1"
|
||
strokeDasharray="2,2"
|
||
/>
|
||
</svg>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
export default MiniLineChart;
|