food sale chart

This commit is contained in:
hamid zarghami
2025-12-20 11:12:39 +03:30
parent 0b9d8e3421
commit 98be18f09f
@@ -1,5 +1,5 @@
import { type FC } from 'react'
import { Cell, Pie, PieChart, ResponsiveContainer } from 'recharts'
import { Cell, LabelList, Pie, PieChart, ResponsiveContainer } from 'recharts'
interface FoodSalesChartProps {
data?: Array<{ name: string; value: number; color: string }>
@@ -8,8 +8,8 @@ interface FoodSalesChartProps {
const FoodSalesChart: FC<FoodSalesChartProps> = ({ data }) => {
const defaultData = [
{ name: 'پیتزا', value: 50, color: '#6B7FED' },
{ name: 'پاستا', value: 25, color: '#A78BFA' },
{ name: 'رامن', value: 15, color: '#FF6B9D' },
{ name: 'برگر', value: 25, color: '#A78BFA' },
{ name: 'پاستا', value: 15, color: '#FF6B9D' },
{ name: 'نوشیدنی ها', value: 10, color: '#FF9A62' }
]
@@ -17,18 +17,23 @@ const FoodSalesChart: FC<FoodSalesChartProps> = ({ data }) => {
const total = chartData.reduce((sum, item) => sum + item.value, 0)
const dataWithPercent = chartData.map((item) => ({
...item,
percent: Math.round((item.value / total) * 100)
}))
return (
<div className='bg-white rounded-3xl p-6 shadow-sm h-full'>
<div className='bg-white h-fit rounded-3xl p-6 shadow-sm'>
<h3 className='text-base font-medium mb-6'>میزان فروش غذاها</h3>
<div className='flex items-center justify-center gap-6'>
<div className='flex items-center justify-center mb-6'>
<ResponsiveContainer
width='60%'
width='100%'
height={280}
>
<PieChart>
<Pie
data={chartData}
data={dataWithPercent}
cx='50%'
cy='50%'
innerRadius={70}
@@ -36,38 +41,74 @@ const FoodSalesChart: FC<FoodSalesChartProps> = ({ data }) => {
paddingAngle={3}
dataKey='value'
>
{chartData.map((entry, index) => (
{dataWithPercent.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={entry.color}
/>
))}
<LabelList
dataKey='percent'
position='outside'
content={(props: unknown) => {
const labelProps = props as {
x?: number | string
y?: number | string
value?: number | string
}
if (
labelProps.x === undefined ||
labelProps.y === undefined ||
labelProps.value === undefined
) {
return null
}
const x =
typeof labelProps.x === 'number'
? labelProps.x
: parseFloat(
String(labelProps.x)
) || 0
const y =
typeof labelProps.y === 'number'
? labelProps.y
: parseFloat(
String(labelProps.y)
) || 0
return (
<text
x={x}
y={y}
textAnchor='middle'
fontSize='14'
fontWeight={500}
fill='#1F2937'
>
{labelProps.value}%
</text>
)
}}
/>
</Pie>
</PieChart>
</ResponsiveContainer>
</div>
<div className='flex flex-col gap-4'>
{chartData.map((item, index) => {
const percent = Math.round((item.value / total) * 100)
return (
<div
key={index}
className='flex items-center gap-3'
>
<div
className='w-3 h-3 rounded-full flex-shrink-0'
style={{ backgroundColor: item.color }}
/>
<span className='text-sm text-gray-700 min-w-[80px]'>
{item.name}
</span>
<span className='text-sm font-medium text-gray-900'>
{percent}%
</span>
</div>
)
})}
</div>
<div className='flex items-center justify-center gap-6 flex-wrap'>
{dataWithPercent.map((item, index) => (
<div
key={index}
className='flex items-center gap-2'
>
<div
className='w-3 h-3 rounded-full flex-shrink-0'
style={{ backgroundColor: item.color }}
/>
<span className='text-sm text-gray-700'>
{item.name}
</span>
</div>
))}
</div>
</div>
)