@@ -60,6 +60,61 @@ PieChart component renders a pie chart with the provided data, utilizing accent
60
60
and a vertical legend positioned to the right.
61
61
*/
62
62
63
+ const CustomLegend = ( props : unknown ) => {
64
+ const { payload } = props ;
65
+
66
+ return (
67
+ < ul
68
+ className = "recharts-default-legend"
69
+ style = { {
70
+ padding : 0 ,
71
+ margin : 0 ,
72
+ textAlign : "left" ,
73
+ display : "flex" ,
74
+ flexDirection : "column" ,
75
+ marginLeft : "12px" ,
76
+ gap : "2px" , // Tighter spacing between items
77
+ } }
78
+ >
79
+ { payload . map ( ( entry : unknown , index : number ) => {
80
+ const dataPoint = entry . payload as unknown as PieChartDataPoint ;
81
+ const formattedValue = Number . isInteger ( dataPoint . value )
82
+ ? dataPoint . value
83
+ : dataPoint . value . toFixed ( 2 ) ;
84
+
85
+ return (
86
+ < li
87
+ key = { `item-${ index } ` }
88
+ className = "recharts-legend-item"
89
+ style = { { marginBottom : "2px" } }
90
+ >
91
+ < span className = "recharts-surface" style = { { marginRight : "4px" } } >
92
+ < svg
93
+ width = "14"
94
+ height = "14"
95
+ style = { {
96
+ display : "inline-block" ,
97
+ verticalAlign : "middle" ,
98
+ marginRight : "4px" ,
99
+ } }
100
+ >
101
+ < path
102
+ fill = { entry . color }
103
+ d = "M0,0h14v14h-14z"
104
+ className = "recharts-legend-icon"
105
+ />
106
+ </ svg >
107
+ </ span >
108
+ < span style = { { fontSize : "0.85rem" , color : "#666" } } >
109
+ { entry . value } ({ formattedValue } %)
110
+ </ span >
111
+ </ li >
112
+ ) ;
113
+ } ) }
114
+ </ ul >
115
+ ) ;
116
+ } ;
117
+
63
118
export function PieChart ( {
64
119
data,
65
120
title,
@@ -69,48 +124,40 @@ export function PieChart({
69
124
} : PieChartProps ) {
70
125
return (
71
126
< Card className = "w-full" >
72
- < CardHeader >
73
- { title && < CardTitle className = "text-center" > { title } </ CardTitle > }
127
+ < CardHeader className = "pb-2" >
128
+ { title && (
129
+ < CardTitle className = "text-center text-2xl" > { title } </ CardTitle >
130
+ ) }
74
131
{ description && < CardDescription > { description } </ CardDescription > }
75
132
</ CardHeader >
76
133
< CardContent >
77
134
< ChartContainer config = { defaultChartConfig } >
78
- < div className = "w-full min-h-[350px]" >
79
- < ResponsiveContainer width = "100%" height = { 350 } >
80
- < RechartsPieChart
81
- margin = { { top : 10 , right : 10 , bottom : 10 , left : 10 } }
82
- >
135
+ < div className = "w-full md:h-[300px] h-[260px] flex" >
136
+ < ResponsiveContainer width = "100%" height = "100%" >
137
+ < RechartsPieChart >
83
138
< ChartTooltip
84
139
cursor = { false }
85
140
content = { < ChartTooltipContent /> }
86
141
/>
142
+ { /* Using custom legend component instead of the built-in Legend */ }
87
143
< Legend
144
+ content = { < CustomLegend /> }
88
145
layout = "vertical"
89
146
verticalAlign = "middle"
90
147
align = "right"
91
148
wrapperStyle = { {
92
- fontSize : "0.85rem" ,
93
- paddingLeft : "10px" ,
94
- lineHeight : "1.8em" ,
95
- maxWidth : "40%" , // Control legend width
96
- } }
97
- formatter = { ( value , entry ) => {
98
- const payload =
99
- entry . payload as unknown as PieChartDataPoint ;
100
- // Format to 2 decimal places if needed
101
- const formattedValue = Number . isInteger ( payload . value )
102
- ? payload . value
103
- : payload . value . toFixed ( 2 ) ;
104
- return `${ value } (${ formattedValue } %)` ;
149
+ paddingLeft : "0px" ,
150
+ paddingTop : "0px" ,
151
+ width : "40%" ,
105
152
} }
106
153
/>
107
154
< Pie
108
155
data = { data }
109
156
dataKey = "value"
110
157
nameKey = "name"
111
- cx = "35 %"
158
+ cx = "30 %"
112
159
cy = "50%"
113
- outerRadius = { 75 }
160
+ outerRadius = { 80 }
114
161
innerRadius = { 0 }
115
162
paddingAngle = { 1 }
116
163
label = { false }
0 commit comments