/** * DeepAnalysisTab 图表配置工具 * * 生成雷达图和桑基图的 ECharts 配置 */ import type { ComprehensiveData, ValueChainData, RadarChartOption, SankeyChartOption, } from '../types'; /** * 生成竞争力雷达图配置 * @param comprehensiveData - 综合分析数据 * @returns ECharts 雷达图配置,或 null(数据不足时) */ export const getRadarChartOption = ( comprehensiveData?: ComprehensiveData ): RadarChartOption | null => { if (!comprehensiveData?.competitive_position?.scores) return null; const scores = comprehensiveData.competitive_position.scores; const indicators = [ { name: '市场地位', max: 100 }, { name: '技术实力', max: 100 }, { name: '品牌价值', max: 100 }, { name: '运营效率', max: 100 }, { name: '财务健康', max: 100 }, { name: '创新能力', max: 100 }, { name: '风险控制', max: 100 }, { name: '成长潜力', max: 100 }, ]; const data = [ scores.market_position || 0, scores.technology || 0, scores.brand || 0, scores.operation || 0, scores.finance || 0, scores.innovation || 0, scores.risk || 0, scores.growth || 0, ]; return { tooltip: { trigger: 'item' }, radar: { indicator: indicators, shape: 'polygon', splitNumber: 4, name: { textStyle: { color: '#666', fontSize: 12 } }, splitLine: { lineStyle: { color: ['#e8e8e8', '#e0e0e0', '#d0d0d0', '#c0c0c0'] }, }, splitArea: { show: true, areaStyle: { color: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'], }, }, axisLine: { lineStyle: { color: '#ddd' } }, }, series: [ { name: '竞争力评分', type: 'radar', data: [ { value: data, name: '当前评分', symbol: 'circle', symbolSize: 5, lineStyle: { width: 2, color: '#3182ce' }, areaStyle: { color: 'rgba(49, 130, 206, 0.3)' }, label: { show: true, formatter: (params: { value: number }) => params.value, color: '#3182ce', fontSize: 10, }, }, ], }, ], }; }; /** * 生成产业链桑基图配置 * @param valueChainData - 产业链数据 * @returns ECharts 桑基图配置,或 null(数据不足时) */ export const getSankeyChartOption = ( valueChainData?: ValueChainData ): SankeyChartOption | null => { if ( !valueChainData?.value_chain_flows || valueChainData.value_chain_flows.length === 0 ) { return null; } const nodes = new Set(); const links: Array<{ source: string; target: string; value: number; lineStyle: { color: string; opacity: number }; }> = []; valueChainData.value_chain_flows.forEach((flow) => { if (!flow?.source?.node_name || !flow?.target?.node_name) return; nodes.add(flow.source.node_name); nodes.add(flow.target.node_name); links.push({ source: flow.source.node_name, target: flow.target.node_name, value: parseFloat(flow.flow_metrics?.flow_ratio || '1') || 1, lineStyle: { color: 'source', opacity: 0.6 }, }); }); return { tooltip: { trigger: 'item', triggerOn: 'mousemove' }, series: [ { type: 'sankey', layout: 'none', emphasis: { focus: 'adjacency' }, data: Array.from(nodes).map((name) => ({ name })), links: links, lineStyle: { color: 'gradient', curveness: 0.5 }, label: { color: '#333', fontSize: 10 }, }, ], }; };