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}`,
+ },
+ },
+ }}
+ />
+
+
+
+ );
+}