diff --git a/web/components/chart/index.tsx b/web/components/chart/index.tsx index d377e1d25..f44242ac3 100644 --- a/web/components/chart/index.tsx +++ b/web/components/chart/index.tsx @@ -3,6 +3,7 @@ import { Card, CardContent, Typography } from '@mui/joy'; import { useMemo } from 'react'; import BarChart from './bar-chart'; import LineChart from './line-chart'; +import PieChart from './pie-chart'; import TableChart from './table-chart'; type Props = { @@ -68,6 +69,8 @@ function Chart({ chartsData }: Props) { return ; } else if (chart.chart_type === 'Table' || chart.type === 'TableChartData') { return ; + } else if (chart.chart_type === 'PieChart' || chart.type === 'PieChart') { + return ; } })} diff --git a/web/components/chart/pie-chart.tsx b/web/components/chart/pie-chart.tsx new file mode 100644 index 000000000..d8f735dac --- /dev/null +++ b/web/components/chart/pie-chart.tsx @@ -0,0 +1,104 @@ +import { ChatContext } from '@/app/chat-context'; +import { ChartData } from '@/types/chat'; +import { Chart } from '@berryv/g2-react'; +import { useContext, useMemo } from 'react'; + +export default function PieChart({ chart }: { key: string; chart: ChartData }) { + const { mode } = useContext(ChatContext); + + // Transform raw data into pie chart format + const pieData = useMemo(() => { + if (!chart.values || !Array.isArray(chart.values)) { + return []; + } + + return chart.values.map(item => ({ + name: item.name, + value: Number(item.value) || 0, + })); + }, [chart.values]); + + if (!pieData.length) { + return null; + } + + // Calculate total for percentage + const total = pieData.reduce((sum, item) => sum + item.value, 0); + + return ( +
+
+
{chart.chart_name}
+
{chart.chart_desc}
+
+ { + const percentage = ((value / total) * 100).toFixed(1); + return `${percentage}%`; + }, + }, + }, + }, + tooltip: { + format: { + value: (v: number) => `${v}`, + }, + }, + }} + /> +
+
+
+ ); +}