UNPKG

@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
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;