food sale chart
This commit is contained in:
@@ -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>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user