ok
This commit is contained in:
@@ -1,48 +1,17 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { BarChart, Bar, XAxis, Tooltip, Legend, CartesianGrid, ResponsiveContainer, LabelList } from 'recharts';
|
||||
import ReactApexChart from 'react-apexcharts';
|
||||
|
||||
// Colors palette
|
||||
const colors = [
|
||||
// **Analogous Colors** (near greens, yellows)
|
||||
"#D0E14F", // Light green-yellow
|
||||
"#B2B83D", // Olive yellow
|
||||
"#A9C96E", // Muted olive green (your bg color itself)
|
||||
"#A8B64E", // Olive green with yellow undertones
|
||||
|
||||
// **Complementary Colors** (contrast with green)
|
||||
"#FF6347", // Tomato red
|
||||
"#FF4500", // Orange red
|
||||
"#FF8C00", // Dark orange
|
||||
"#FF7F50", // Coral
|
||||
|
||||
// **Triadic Colors** (balanced vibrant combination)
|
||||
"#1E90FF", // Dodger blue
|
||||
"#FF00FF", // Magenta
|
||||
"#32CD32", // Lime green
|
||||
|
||||
// **Tetradic Colors** (4-color palette: 2 complementary pairs)
|
||||
"#00CED1", // Dark turquoise
|
||||
"#FFD700", // Gold
|
||||
"#FF1493", // Deep pink
|
||||
"#8A2BE2", // Blue violet
|
||||
|
||||
// **Neutral Tones** (earthy, muted tones to balance the palette)
|
||||
"#FFDAB9", // Peach
|
||||
"#F0E68C", // Khaki
|
||||
"#8B4513", // Saddle brown
|
||||
"#4B0082", // Indigo
|
||||
"#C71585", // Medium violet red
|
||||
|
||||
// **Pastels for softer contrast**
|
||||
"#FFB6C1", // Light pink
|
||||
"#E6E6FA", // Lavender
|
||||
"#98FB98", // Pale green
|
||||
"#F0FFF0", // Honeydew
|
||||
"#D3D3D3", // Light grey
|
||||
];
|
||||
|
||||
"#D0E14F", "#B2B83D", "#A9C96E", "#A8B64E",
|
||||
"#FF6347", "#FF4500", "#FF8C00", "#FF7F50",
|
||||
"#1E90FF", "#FF00FF", "#32CD32",
|
||||
"#00CED1", "#FFD700", "#FF1493", "#8A2BE2",
|
||||
"#FFDAB9", "#F0E68C", "#8B4513", "#4B0082", "#C71585",
|
||||
"#FFB6C1", "#E6E6FA", "#98FB98", "#F0FFF0", "#D3D3D3"
|
||||
];
|
||||
|
||||
const SimpleBarChart = ({ Data }) => {
|
||||
const SimpleLineChart = ({ Data }) => {
|
||||
const lastMonthRef = useRef('');
|
||||
const lastYearRef = useRef('');
|
||||
const usedColors = useRef([]); // Keep track of used colors
|
||||
@@ -54,23 +23,19 @@ const SimpleBarChart = ({ Data }) => {
|
||||
// Ensure Data is not null or undefined
|
||||
const transformedData = (Data?.length ? Data.reduce((acc, { date, materialId, priceAtp, stockDifference, name }) => {
|
||||
function isSameDay(date1, date2) {
|
||||
const d1 = new Date(date1);
|
||||
const d2 = new Date(date2);
|
||||
|
||||
return d1.getFullYear() === d2.getFullYear() &&
|
||||
d1.getMonth() === d2.getMonth() &&
|
||||
d1.getDate() === d2.getDate();
|
||||
const d1 = new Date(date1);
|
||||
const d2 = new Date(date2);
|
||||
|
||||
return d1.getFullYear() === d2.getFullYear() &&
|
||||
d1.getMonth() === d2.getMonth() &&
|
||||
d1.getDate() === d2.getDate();
|
||||
}
|
||||
|
||||
// Assuming `acc` is an array of entries and `date` is the input date you're checking
|
||||
const existingEntry = acc.find(d => isSameDay(d.date, date));
|
||||
|
||||
console.log(existingEntry)
|
||||
if (existingEntry) {
|
||||
// If it exists, sum the stockDifference (priceAtp * stockDifference)
|
||||
existingEntry[name] = (existingEntry[name] || 0) + (priceAtp * stockDifference);
|
||||
} else {
|
||||
// If it doesn't exist yet, add a new entry
|
||||
acc.push({
|
||||
date,
|
||||
materialId,
|
||||
@@ -78,123 +43,84 @@ const SimpleBarChart = ({ Data }) => {
|
||||
[name]: priceAtp * stockDifference
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []) : []);
|
||||
|
||||
// Sort the data by date (ascending) to easily find the oldest date
|
||||
const sortedData = [...transformedData].sort((a, b) => new Date(a.date) - new Date(b.date));
|
||||
|
||||
// The first date in the sorted array will be the oldest
|
||||
const oldestDate = sortedData[0]?.date;
|
||||
|
||||
// Get the unique materials (names) from the data
|
||||
|
||||
const uniqueMaterials = Array.from(new Set(Data?.map(item => item.name) || []));
|
||||
const uniqueDates = Array.from(new Set(transformedData.map(item => item.date)));
|
||||
|
||||
// Function to format date and handle month and year changes
|
||||
const formatDate = (date) => {
|
||||
const formattedDate = new Date(date);
|
||||
const day = formattedDate.getDate(); // Get the day of the month
|
||||
const month = formattedDate.toLocaleString('en-US', { month: 'short' }); // Get the abbreviated month (e.g., "Nov")
|
||||
const year = formattedDate.getFullYear().toString().slice(2); // Get the last two digits of the year (e.g., "24")
|
||||
|
||||
// Extract the year from the first data point
|
||||
const firstYear = new Date(sortedData[0]?.date).getFullYear();
|
||||
|
||||
// Check if all dates have the same year
|
||||
const allSameYear = sortedData.every((item) => new Date(item.date).getFullYear() === firstYear);
|
||||
|
||||
// If all dates are from the same year, show only "day month"
|
||||
if (allSameYear && formattedDate.toLocaleString('en-US', { month: 'short' }) !== lastMonthRef.current) {
|
||||
lastMonthRef.current = formattedDate.toLocaleString('en-US', { month: 'short' });
|
||||
// Show just the day and month if all dates have the same year
|
||||
return `${day} ${month}`;
|
||||
}
|
||||
// if (allSameYear) {
|
||||
// // Show just the day and month if all dates have the same year
|
||||
// return `${day} ${month}`;
|
||||
// }
|
||||
|
||||
// Check if it's the oldest date (first entry)
|
||||
if (date === oldestDate) {
|
||||
lastMonthRef.current = formattedDate.toLocaleDateString('en-US', { month: 'short' });
|
||||
lastYearRef.current = formattedDate.getFullYear();
|
||||
return `${day} ${month} ${year}`; // Format as "day month year" (e.g., "4 Nov 24")
|
||||
}
|
||||
|
||||
// If the year changes, show the full date with year
|
||||
if (formattedDate.getFullYear() !== lastYearRef.current) {
|
||||
lastYearRef.current = formattedDate.getFullYear();
|
||||
return `${day} ${month} ${year}`; // Show full date: day month year
|
||||
}
|
||||
|
||||
// If the month changes, show the full date with month and year
|
||||
if (formattedDate.toLocaleString('en-US', { month: 'short' }) !== lastMonthRef.current) {
|
||||
lastMonthRef.current = formattedDate.toLocaleString('en-US', { month: 'short' });
|
||||
return `${day} ${month} `; // Show full date: day month year
|
||||
}
|
||||
|
||||
// Only show the day if the month hasn't changed
|
||||
return `${day}`; // Show just the day if the month remains the same
|
||||
};
|
||||
|
||||
|
||||
// Function to get the next available color from the palette, starting from a random index
|
||||
const getNextColor = () => {
|
||||
// Randomly pick a starting index from the color palette
|
||||
const randomIndex = Math.floor(Math.random() * colors.length);
|
||||
|
||||
// Find the first unused color from the random starting point
|
||||
let color = null;
|
||||
for (let i = 0; i < colors.length; i++) {
|
||||
const index = (randomIndex + i) % colors.length;
|
||||
if (!usedColors.current.includes(colors[index])) {
|
||||
color = colors[index];
|
||||
usedColors.current.push(color); // Mark color as used
|
||||
usedColors.current.push(color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return color || '#000000'; // Fallback color if no colors are available
|
||||
return color || '#000000';
|
||||
};
|
||||
|
||||
// Extract unique dates for the XAxis
|
||||
const uniqueDates = Array.from(new Set(transformedData.map(item => item.date)));
|
||||
// Prepare data for ApexCharts
|
||||
const series = uniqueMaterials.map((material) => {
|
||||
return {
|
||||
name: material,
|
||||
data: transformedData.map(item => item[material] || 0)
|
||||
};
|
||||
});
|
||||
|
||||
const options = {
|
||||
chart: {
|
||||
type: 'line',
|
||||
height: '100%',
|
||||
zoom: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: uniqueDates,
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: uniqueMaterials.map(() => getNextColor()), // Assign unique colors for each material
|
||||
legend: {
|
||||
position: 'top',
|
||||
horizontalAlign: 'center',
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 0
|
||||
},
|
||||
labels: {
|
||||
colors: '#3498db', // Set legend text color
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
theme: 'light',
|
||||
style: {
|
||||
fontSize: '14px',
|
||||
color: '#3498db'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ width: '100%', height: '20vh' }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<BarChart data={transformedData}>
|
||||
{/* Format the XAxis ticks to show only the month when it changes */}
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
tickFormatter={formatDate} // Custom formatting function
|
||||
interval={0} // Set interval to 0 to display all dates in data
|
||||
ticks={uniqueDates} // Only use unique dates for the XAxis
|
||||
/>
|
||||
<Tooltip
|
||||
itemStyle={{
|
||||
color: '#3498db', // Set the tooltip text color to blue
|
||||
}}
|
||||
/>
|
||||
<CartesianGrid strokeDasharray="3 3" />
|
||||
|
||||
{/* Dynamically create bars and labels for each unique material */}
|
||||
{uniqueMaterials.map((material) => (
|
||||
<React.Fragment key={material}>
|
||||
<Bar dataKey={material} fill={getNextColor()}>
|
||||
</Bar>
|
||||
</React.Fragment>
|
||||
))}<Legend
|
||||
wrapperStyle={{
|
||||
color: '#3498db', // Set the legend text color to blue
|
||||
backgroundColor: 'white'
|
||||
}}
|
||||
/>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
<ReactApexChart
|
||||
options={options}
|
||||
series={series}
|
||||
type="line"
|
||||
height="100%"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SimpleBarChart;
|
||||
export default SimpleLineChart;
|
||||
|
||||
Reference in New Issue
Block a user