pagamio-frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
87 lines (86 loc) • 3.85 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import ReactECharts from 'echarts-for-react';
import { useMemo } from 'react';
import Card from '../components/CardWrapper';
import ChartWrapper from '../components/ChartWrapper';
import { useChartData } from '../hooks/useChartData';
import { DashboardPaths } from '../utils';
const HeatmapChart = ({ title, url = DashboardPaths.QUERY, query, xAxisKey, yAxisKey, valueKey, colorRange = ['#d73027', '#1a9850'], tooltipTitle = 'Value', tooltipUnit = '', visualMapLabels = ['Low Stock', 'Sufficient Stock'], visualMapRange = [0, 100], grid = { top: 50, bottom: 100, left: 100, right: 50 }, metricDetailData, showDetailsModal = true, }) => {
const { data: metricData = [], error, isEmpty, loading, refresh } = useChartData(url, query);
const chartData = useMemo(() => {
if (!metricData.length)
return { xAxis: [], yAxis: [], data: [] };
const xAxisCategories = Array.from(new Set(metricData.map((item) => item[xAxisKey])));
const yAxisCategories = Array.from(new Set(metricData.map((item) => item[yAxisKey])));
const heatmapData = metricData.map((item) => [
xAxisCategories.indexOf(item[xAxisKey]),
yAxisCategories.indexOf(item[yAxisKey]),
item[valueKey] || 0,
]);
return {
xAxis: xAxisCategories,
yAxis: yAxisCategories,
data: heatmapData,
};
}, [metricData, xAxisKey, yAxisKey, valueKey]);
const dataRange = useMemo(() => {
if (metricData.length === 0)
return visualMapRange;
const values = metricData.map((item) => item[valueKey] || 0);
return [Math.min(...values), Math.max(...values)];
}, [metricData, valueKey, visualMapRange]);
const chartOptions = useMemo(() => ({
tooltip: {
position: 'top',
formatter: ({ value }) => {
if (!value || value.length < 3)
return '';
return `
<div>
<strong>${tooltipTitle}</strong><br/>
${yAxisKey}: ${chartData.yAxis[value[1]]} <br/>
${xAxisKey}: ${chartData.xAxis[value[0]]} <br/>
${valueKey}: ${value[2].toLocaleString()} ${tooltipUnit}
</div>
`;
},
},
grid: { ...grid, containLabel: true },
xAxis: {
type: 'category',
data: chartData.xAxis,
axisLabel: {
rotate: 30, // Rotates labels for better visibility
fontSize: 10,
overflow: 'truncate',
},
axisTick: { alignWithLabel: true },
},
yAxis: {
type: 'category',
data: chartData.yAxis,
axisLabel: { fontSize: 10, overflow: 'truncate' },
},
visualMap: {
min: dataRange[0],
max: dataRange[1],
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '5%',
text: [visualMapLabels[1], visualMapLabels[0]],
inRange: { color: colorRange },
},
series: [
{
name: title,
type: 'heatmap',
data: chartData.data,
label: { show: true, fontSize: 10 },
emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0,0,0,0.5)' } },
},
],
}), [chartData, colorRange, title, tooltipTitle, tooltipUnit, xAxisKey, yAxisKey, valueKey, dataRange, grid]);
return (_jsx(Card, { title: title, children: _jsx(ChartWrapper, { loading: loading, error: error, isEmpty: isEmpty, onRetry: refresh, children: _jsx(ReactECharts, { option: chartOptions, style: { height: '400px', width: '100%' } }) }) }));
};
export default HeatmapChart;