freshness-indicator / frontend /src /components /FreshnessChart.jsx
Kishore200630's picture
Upload 23 files
17ac01f verified
Raw
History Blame Contribute Delete
5.61 kB
import React from 'react';
import { motion } from 'framer-motion';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
ArcElement,
} from 'chart.js';
import { Bar, Doughnut } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
ArcElement
);
const FreshnessChart = ({ data }) => {
const barData = {
labels: data.labels,
datasets: [
{
label: 'Freshness %',
data: data.freshness,
backgroundColor: [
'rgba(59, 130, 246, 0.8)',
'rgba(245, 158, 11, 0.8)',
'rgba(239, 68, 68, 0.8)',
],
borderColor: [
'rgba(59, 130, 246, 1)',
'rgba(245, 158, 11, 1)',
'rgba(239, 68, 68, 1)',
],
borderWidth: 2,
borderRadius: 8,
},
],
};
const doughnutData = {
labels: data.labels,
datasets: [
{
data: data.days_left,
backgroundColor: [
'rgba(59, 130, 246, 0.8)',
'rgba(245, 158, 11, 0.8)',
'rgba(239, 68, 68, 0.8)',
],
borderColor: [
'rgba(59, 130, 246, 1)',
'rgba(245, 158, 11, 1)',
'rgba(239, 68, 68, 1)',
],
borderWidth: 2,
},
],
};
const barOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
tooltip: {
backgroundColor: 'rgba(15, 23, 42, 0.9)',
titleColor: '#fff',
bodyColor: '#94a3b8',
borderColor: 'rgba(255, 255, 255, 0.1)',
borderWidth: 1,
padding: 12,
cornerRadius: 8,
callbacks: {
label: (context) => `Freshness: ${context.raw}%`
}
},
},
scales: {
x: {
grid: {
display: false,
},
ticks: {
color: '#94a3b8',
font: {
size: 11,
},
},
},
y: {
beginAtZero: true,
max: 100,
grid: {
color: 'rgba(148, 163, 184, 0.1)',
},
ticks: {
color: '#94a3b8',
font: {
size: 11,
},
callback: (value) => `${value}%`,
},
},
},
};
const doughnutOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
color: '#94a3b8',
padding: 15,
font: {
size: 11,
},
usePointStyle: true,
},
},
tooltip: {
backgroundColor: 'rgba(15, 23, 42, 0.9)',
titleColor: '#fff',
bodyColor: '#94a3b8',
borderColor: 'rgba(255, 255, 255, 0.1)',
borderWidth: 1,
padding: 12,
cornerRadius: 8,
callbacks: {
label: (context) => `${context.label}: ${context.raw} days left`
}
},
},
cutout: '60%',
};
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="glass rounded-3xl p-6 lg:p-8"
>
<div className="flex items-center gap-3 mb-6">
<div className="w-10 h-10 rounded-xl bg-primary-500/20 flex items-center justify-center">
<svg className="w-5 h-5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
</svg>
</div>
<div>
<h2 className="text-lg lg:text-xl font-semibold text-white">Storage Comparison</h2>
<p className="text-dark-400 text-sm">Freshness by storage condition</p>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Bar Chart */}
<div className="glass-light rounded-xl p-4">
<h3 className="text-sm font-medium text-dark-300 mb-4">Freshness Level (%)</h3>
<div className="h-48 lg:h-56">
<Bar data={barData} options={barOptions} />
</div>
</div>
{/* Doughnut Chart */}
<div className="glass-light rounded-xl p-4">
<h3 className="text-sm font-medium text-dark-300 mb-4">Days Remaining</h3>
<div className="h-48 lg:h-56">
<Doughnut data={doughnutData} options={doughnutOptions} />
</div>
</div>
</div>
{/* Legend */}
<div className="mt-6 grid grid-cols-3 gap-3">
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-blue-500" />
<span className="text-xs text-dark-400">Ideal (Refrigerated)</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-amber-500" />
<span className="text-xs text-dark-400">Room Temperature</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-red-500" />
<span className="text-xs text-dark-400">High Humidity</span>
</div>
</div>
</motion.div>
);
};
export default FreshnessChart;