chore: initial commit
This commit is contained in:
156
src/components/Page06ExportTax.tsx
Normal file
156
src/components/Page06ExportTax.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
import { useRef, useEffect } from 'react';
|
||||
import * as echarts from 'echarts';
|
||||
import { ContentPage } from './ContentPage';
|
||||
import type { BarChartCompareItem } from '../types/data';
|
||||
|
||||
interface ExportTaxBarProps {
|
||||
title: string;
|
||||
data: BarChartCompareItem[];
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const ExportTaxBar = ({ title, data = [], description }: ExportTaxBarProps) => {
|
||||
const chartRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartRef.current) return;
|
||||
const myChart = echarts.init(chartRef.current);
|
||||
|
||||
const option: echarts.EChartsOption = {
|
||||
animation: false,
|
||||
silent: true,
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
legend: {
|
||||
data: ['本机构', '全量客户'],
|
||||
right: 10,
|
||||
top: 0,
|
||||
textStyle: { fontSize: 9, color: '#666' },
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
itemGap: 12
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
bottom: 75,
|
||||
left: 35,
|
||||
right: 15,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: data.map(d => d.label),
|
||||
axisLabel: {
|
||||
fontSize: 8,
|
||||
color: '#666',
|
||||
interval: 0,
|
||||
rotate: 0,
|
||||
margin: 8,
|
||||
formatter: (value: string) => {
|
||||
if (value.includes('出口免抵退税额')) {
|
||||
return value.replace('额', '额\n');
|
||||
}
|
||||
if (value.includes('出口退税额')) {
|
||||
return value.replace('额', '额\n');
|
||||
}
|
||||
if (value.includes('关联企业数量')) {
|
||||
return value.replace('数量', '数量\n');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#F0F0F0' } },
|
||||
axisTick: { show: false }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
interval: 20,
|
||||
axisLabel: { fontSize: 9, color: '#666', formatter: '{value}%' },
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
splitLine: { show: true, lineStyle: { type: 'dashed', color: '#F0F0F0' } }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '本机构',
|
||||
type: 'bar',
|
||||
data: data.map(d => d.customerValue),
|
||||
barGap: '10%',
|
||||
barWidth: 22,
|
||||
itemStyle: { color: '#45dad1', borderRadius: [2, 2, 0, 0] },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
fontSize: 8,
|
||||
color: '#666',
|
||||
formatter: '{c}%'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '全量客户',
|
||||
type: 'bar',
|
||||
data: data.map(d => d.marketValue),
|
||||
barGap: '10%',
|
||||
barWidth: 22,
|
||||
itemStyle: { color: '#40a9ff', borderRadius: [2, 2, 0, 0] },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
fontSize: 8,
|
||||
color: '#666',
|
||||
formatter: '{c}%'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
|
||||
const handleResize = () => myChart.resize();
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
myChart.dispose();
|
||||
};
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full break-inside-avoid">
|
||||
<div className="subtitle-container mb-1">
|
||||
<span className="blue-bar-subtitle h-[12px]"></span>
|
||||
<h4 className="text-[16px] font-semibold text-[#333]">{title}</h4>
|
||||
</div>
|
||||
{description && (
|
||||
<div className="bg-gray-50 border border-gray-200 rounded-md px-3 py-2 mb-2">
|
||||
<p className="text-[10px] text-gray-600 leading-relaxed">{description}</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="relative w-full bg-white border-[0.5px] border-gray-100 rounded-lg p-2">
|
||||
<div className="echarts-canvas-container relative w-full" style={{ height: '320px' }}>
|
||||
<div ref={chartRef} className="echarts-inner w-full h-full" />
|
||||
<img className="echarts-export-image absolute inset-0 w-full h-full object-contain hidden" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface Page06ExportTaxProps {
|
||||
exportFreeTaxRebate: BarChartCompareItem[];
|
||||
exportTaxRebate: BarChartCompareItem[];
|
||||
chartDescriptions?: { exportFreeTaxRebate?: string; exportTaxRebate?: string };
|
||||
}
|
||||
|
||||
export const Page06ExportTax = ({ exportFreeTaxRebate = [], exportTaxRebate = [], chartDescriptions }: Page06ExportTaxProps) => {
|
||||
return (
|
||||
<ContentPage pageNumber={6} hidePageNumber={true}>
|
||||
<div className="flex flex-col space-y-8 -mx-[20px] px-[20px]">
|
||||
<ExportTaxBar title="不同出口免抵退税金额企业分布" data={exportFreeTaxRebate} description={chartDescriptions?.exportFreeTaxRebate} />
|
||||
<ExportTaxBar title="不同出口退税金额企业分布" data={exportTaxRebate} description={chartDescriptions?.exportTaxRebate} />
|
||||
</div>
|
||||
</ContentPage>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user