feat: StockChartModal.tsx 替换 KLine 实现
This commit is contained in:
@@ -290,9 +290,193 @@ export const darkTheme: DeepPartial<Styles> = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 分时图专用主题配置
|
||||
* 特点:面积图样式、均价线、百分比Y轴
|
||||
*/
|
||||
export const timelineTheme: DeepPartial<Styles> = {
|
||||
...lightTheme,
|
||||
candle: {
|
||||
type: 'area', // ✅ 面积图模式(分时线)
|
||||
area: {
|
||||
lineSize: 2,
|
||||
lineColor: CHART_COLORS.up, // 默认红色,实际会根据涨跌动态调整
|
||||
value: 'close',
|
||||
backgroundColor: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(239, 83, 80, 0.2)', // 红色半透明渐变(顶部)
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(239, 83, 80, 0.01)', // 红色几乎透明(底部)
|
||||
},
|
||||
],
|
||||
},
|
||||
priceMark: {
|
||||
show: true,
|
||||
high: {
|
||||
show: false, // 分时图不显示最高最低价标记
|
||||
},
|
||||
low: {
|
||||
show: false,
|
||||
},
|
||||
last: {
|
||||
show: true,
|
||||
upColor: CHART_COLORS.up,
|
||||
downColor: CHART_COLORS.down,
|
||||
noChangeColor: CHART_COLORS.neutral,
|
||||
line: {
|
||||
show: true,
|
||||
style: 'dashed',
|
||||
dashValue: [4, 2],
|
||||
size: 1,
|
||||
},
|
||||
text: {
|
||||
show: true,
|
||||
size: 12,
|
||||
paddingLeft: 4,
|
||||
paddingTop: 2,
|
||||
paddingRight: 4,
|
||||
paddingBottom: 2,
|
||||
borderRadius: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
showRule: 'always',
|
||||
showType: 'standard',
|
||||
// ✅ 自定义 Tooltip 标签和格式化
|
||||
labels: ['时间: ', '现价: ', '涨跌: ', '均价: ', '昨收: ', '成交量: '],
|
||||
// 自定义格式化函数(如果 KLineChart 支持)
|
||||
formatter: (data: any, indicator: any) => {
|
||||
if (!data) return [];
|
||||
|
||||
const { timestamp, close, volume, prev_close } = data;
|
||||
const time = new Date(timestamp);
|
||||
const timeStr = `${String(time.getHours()).padStart(2, '0')}:${String(time.getMinutes()).padStart(2, '0')}`;
|
||||
|
||||
// 计算涨跌幅
|
||||
const changePercent = prev_close ? ((close - prev_close) / prev_close * 100).toFixed(2) : '0.00';
|
||||
const changeValue = prev_close ? (close - prev_close).toFixed(2) : '0.00';
|
||||
|
||||
// 成交量转换为手(1手 = 100股)
|
||||
const volumeHands = Math.floor(volume / 100);
|
||||
|
||||
return [
|
||||
{ title: '时间', value: timeStr },
|
||||
{ title: '现价', value: `¥${close?.toFixed(2) || '--'}` },
|
||||
{ title: '涨跌', value: `${changeValue} (${changePercent}%)` },
|
||||
{ title: '昨收', value: `¥${prev_close?.toFixed(2) || '--'}` },
|
||||
{ title: '成交量', value: `${volumeHands.toLocaleString()}手` },
|
||||
];
|
||||
},
|
||||
text: {
|
||||
size: 12,
|
||||
family: 'Helvetica, Arial, sans-serif',
|
||||
weight: 'normal',
|
||||
color: CHART_COLORS.text,
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
...lightTheme.yAxis,
|
||||
type: 'percentage', // ✅ 百分比模式
|
||||
position: 'left', // Y轴在左侧
|
||||
inside: false,
|
||||
reverse: false,
|
||||
tickText: {
|
||||
...lightTheme.yAxis?.tickText,
|
||||
// ✅ 自定义 Y 轴格式化:显示百分比(如 "+2.50%", "-1.20%", "0.00%")
|
||||
formatter: (value: any) => {
|
||||
const percent = (value * 100).toFixed(2);
|
||||
// 处理 0 值:显示 "0.00%" 而非 "-0.00%" 或 "+0.00%"
|
||||
if (Math.abs(value) < 0.0001) {
|
||||
return '0.00%';
|
||||
}
|
||||
return value > 0 ? `+${percent}%` : `${percent}%`;
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
show: true,
|
||||
horizontal: {
|
||||
show: true,
|
||||
size: 1,
|
||||
color: CHART_COLORS.grid,
|
||||
style: 'solid', // 分时图使用实线网格
|
||||
},
|
||||
vertical: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 分时图深色主题
|
||||
*/
|
||||
export const timelineThemeDark: DeepPartial<Styles> = {
|
||||
...timelineTheme,
|
||||
...darkTheme,
|
||||
candle: {
|
||||
...timelineTheme.candle,
|
||||
tooltip: {
|
||||
...timelineTheme.candle?.tooltip,
|
||||
text: {
|
||||
...timelineTheme.candle?.tooltip?.text,
|
||||
color: CHART_COLORS.textDark,
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
...timelineTheme.grid,
|
||||
horizontal: {
|
||||
...timelineTheme.grid?.horizontal,
|
||||
color: CHART_COLORS.gridDark,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取主题配置(根据 Chakra UI colorMode)
|
||||
*/
|
||||
export const getTheme = (colorMode: 'light' | 'dark' = 'light'): DeepPartial<Styles> => {
|
||||
return colorMode === 'dark' ? darkTheme : lightTheme;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取分时图主题配置
|
||||
*/
|
||||
export const getTimelineTheme = (colorMode: 'light' | 'dark' = 'light'): DeepPartial<Styles> => {
|
||||
const baseTheme = colorMode === 'dark' ? timelineThemeDark : timelineTheme;
|
||||
|
||||
// ✅ 添加成交量指标样式(蓝色渐变柱状图)+ 成交量单位格式化
|
||||
return {
|
||||
...baseTheme,
|
||||
indicator: {
|
||||
...baseTheme.indicator,
|
||||
bars: [
|
||||
{
|
||||
upColor: 'rgba(59, 130, 246, 0.6)', // 蓝色(涨)
|
||||
downColor: 'rgba(59, 130, 246, 0.6)', // 蓝色(跌)- 分时图成交量统一蓝色
|
||||
noChangeColor: 'rgba(59, 130, 246, 0.6)',
|
||||
}
|
||||
],
|
||||
// ✅ 自定义 Tooltip 格式化(显示完整信息)
|
||||
tooltip: {
|
||||
...baseTheme.indicator?.tooltip,
|
||||
// 格式化成交量数值:显示为"手"(1手 = 100股)
|
||||
formatter: (params: any) => {
|
||||
if (params.name === 'VOL' && params.calcParamsText) {
|
||||
const volume = params.calcParamsText.match(/\d+/)?.[0];
|
||||
if (volume) {
|
||||
const hands = Math.floor(Number(volume) / 100);
|
||||
return `成交量: ${hands.toLocaleString()}手`;
|
||||
}
|
||||
}
|
||||
return params.calcParamsText || '';
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user