pagamio-frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
147 lines (146 loc) • 5.93 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, getHeatmapData } from '../utils';
const HeatmapChart = ({ title, url = DashboardPaths.QUERY, query, xAxisKey, yAxisKey, valueKey, colorRange = ['#d73027', '#1a9850'], tooltipTitle = 'Value', tooltipUnit = '', visualMapLabels = ['Low', 'High'], visualMapRange = [0, 100], visualMapConfig, grid = { top: 60, bottom: 120, left: 120, right: 60 }, showSplitArea = false, splitAreaConfig, xAxisLabelFormatter, yAxisLabelFormatter, transformData, metricDetailData, showDetailsModal = true, }) => {
const { data: metricData = [], error, isEmpty, loading, refresh } = useChartData(url, query);
const chartData = useMemo(() => {
if (!metricData.length)
return { xAxis: [], yAxis: [], data: [] };
// Use custom transformData function if provided, otherwise use generic getHeatmapData
const transformFunction = transformData || getHeatmapData;
const { xAxis, yAxis, data } = transformFunction(metricData, xAxisKey, yAxisKey, valueKey);
// Apply formatters to axis categories if provided
const formattedXAxis = xAxis.map((category) => {
if (xAxisLabelFormatter) {
return xAxisLabelFormatter(category);
}
return category;
});
const formattedYAxis = yAxis.map((category) => {
if (yAxisLabelFormatter) {
return yAxisLabelFormatter(category);
}
return category;
});
return {
xAxis: formattedXAxis,
yAxis: formattedYAxis,
data,
};
}, [metricData, xAxisKey, yAxisKey, valueKey, transformData, xAxisLabelFormatter, yAxisLabelFormatter]);
const dataRange = useMemo(() => {
if (chartData.data.length === 0)
return visualMapRange;
// Extract values from the heatmap data (third element in each array)
const values = chartData.data
.map((item) => item[2])
.filter((val) => typeof val === 'number');
if (values.length === 0)
return visualMapRange;
const min = Math.min(...values);
const max = Math.max(...values);
// Ensure we have a proper range for the visual map
return min === max ? [0, Math.max(max, 1)] : [min, max];
}, [chartData.data, visualMapRange]);
const chartOptions = useMemo(() => ({
tooltip: {
position: 'top',
formatter: ({ value }) => {
if (!value || value.length < 3)
return '';
const xLabel = chartData.xAxis[value[0]];
const yLabel = chartData.yAxis[value[1]];
const dataValue = value[2];
return `
<div>
<strong>${tooltipTitle}</strong><br/>
${yAxisKey}: ${yLabel}<br/>
${xAxisKey}: ${xLabel}<br/>
${valueKey}: ${dataValue.toLocaleString()} ${tooltipUnit}
</div>
`;
},
},
grid: { ...grid, containLabel: true },
xAxis: {
type: 'category',
data: chartData.xAxis,
splitArea: {
show: showSplitArea,
...splitAreaConfig,
},
axisLabel: {
rotate: 0,
fontSize: 11,
interval: 0,
margin: 10,
overflow: 'none',
width: 80,
textStyle: {
fontSize: 11,
},
},
axisTick: { alignWithLabel: true },
},
yAxis: {
type: 'category',
data: chartData.yAxis,
splitArea: {
show: showSplitArea,
...splitAreaConfig,
},
axisLabel: {
fontSize: 11,
margin: 8,
},
},
visualMap: {
min: visualMapConfig?.min ?? dataRange[0],
max: visualMapConfig?.max ?? dataRange[1],
calculable: visualMapConfig?.calculable ?? true,
orient: visualMapConfig?.orient ?? 'horizontal',
left: visualMapConfig?.left ?? 'center',
right: visualMapConfig?.right,
top: visualMapConfig?.top,
bottom: visualMapConfig?.bottom ?? '5%',
show: visualMapConfig?.show ?? true,
precision: visualMapConfig?.precision ?? 0,
text: visualMapConfig?.text ?? [visualMapLabels[1], visualMapLabels[0]],
textStyle: visualMapConfig?.textStyle,
inRange: {
color: visualMapConfig?.inRange?.color ?? colorRange,
...visualMapConfig?.inRange,
},
},
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,
visualMapConfig,
visualMapLabels,
showSplitArea,
splitAreaConfig,
]);
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%', minWidth: '600px' } }) }) }));
};
export default HeatmapChart;