UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

394 lines (393 loc) 12.2 kB
import { formatDonutChartData } from '.'; import { createTooltipFormatter } from './tooltipUtils'; export const createDistributionMetricOptions = ({ distributionChartTooltip, distributionData, processedTooltipFields, xAxisDataValueKey, seriesDataValueKey, displaySymbol, }) => { const { tooltipValueFormat, tooltipTitle, tooltipUnit, treeMapSegmentLabel } = distributionChartTooltip; const currency = distributionData?.[0]?.currency; const formattedData = formatDonutChartData(distributionData || [], xAxisDataValueKey, seriesDataValueKey); const labelFormatter = (params) => { const formattedValue = params.value.toLocaleString(); return `${params.name}\n${treeMapSegmentLabel}: ${formattedValue}`; }; const tooltipFormatter = createTooltipFormatter(tooltipValueFormat, tooltipTitle, tooltipUnit, processedTooltipFields, distributionData || [], currency, displaySymbol); return getLargeDatasetChartOptions({ data: { legendData: [], seriesData: formattedData.seriesData, }, labelFormatter, tooltipFormatter, }); }; export const getGroupedChartOptions = ({ xAxisLabel, xAxisValueKey, rightYAxisValueKey, leftYAxisValueKey, chartToolTip, data, yAxisLabelFormatter, }) => ({ tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, ...chartToolTip, }, legend: { data: ['Total Amount', 'Quantity Sold'], top: 0, textStyle: { fontSize: 12 }, }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true, }, xAxis: { type: 'category', name: xAxisLabel, data: data.map((item) => item[xAxisValueKey]), axisLabel: { interval: 0, rotate: 30, }, }, yAxis: [ { type: 'value', name: 'Total Amount', position: 'left', axisLine: { show: true, lineStyle: { color: '#c789b8' }, }, axisLabel: { formatter: yAxisLabelFormatter || ((value) => `${(value / 1000).toFixed(0)}k`), }, }, { type: 'value', name: 'Quantity Sold', position: 'right', axisLine: { show: true, lineStyle: { color: '#5470c6' }, }, }, ], series: [ { name: 'Total Amount', type: 'bar', data: data.map((item) => item[leftYAxisValueKey]), itemStyle: { color: '#c789b8' }, }, { name: 'Quantity Sold', type: 'bar', yAxisIndex: 1, data: data.map((item) => item[rightYAxisValueKey]), itemStyle: { color: '#5470c6' }, }, ], dataZoom: [ { type: 'inside', start: 0, end: 100, }, ], responsive: true, maintainAspectRatio: false, }); export const getLineGraphOptions = ({ title, yAxisLabel, chartToolTip, data, yAxisLabelFormatter, }) => { if (!data?.length) return {}; return { tooltip: { trigger: 'axis', ...chartToolTip, }, legend: { data: data.map((s) => s.name), bottom: 0, }, grid: { left: '5%', right: '5%', bottom: '20%', top: title ? '60' : '30', containLabel: true, }, xAxis: { type: 'time', axisLabel: { formatter: (value) => { // value is a timestamp (ms since epoch) const dateObj = new Date(value); const day = dateObj.getDate(); const month = dateObj.getMonth() + 1; // getMonth() is zero-based const hour = dateObj.getHours().toString().padStart(2, '0'); const minute = dateObj.getMinutes().toString().padStart(2, '0'); return `${day}/${month}-${hour}:${minute}`; }, name: 'Date', hideOverlap: true, }, splitLine: { show: false, }, }, yAxis: { type: 'value', name: yAxisLabel, axisLabel: { formatter: yAxisLabelFormatter || ((value) => `${value}`), }, }, series: data.map((series) => ({ type: 'line', name: series.name, data: series.data.map((point) => ({ value: [point.date instanceof Date ? point.date : new Date(point.date), point.value], })), showSymbol: true, })), }; }; export const getChartBarOptions = ({ title, colorScheme = ['#60A5FA', '#93C5FD'], yAxisDataNameKey, xAxisNameKey, xAxisLabel = '', yAxisLabel = '', chartToolTip, data, }) => ({ tooltip: { trigger: 'axis', axisPointer: { type: 'shadow', }, ...chartToolTip, }, grid: { left: '3%', right: '4%', bottom: '3%', top: title ? '60' : '3%', containLabel: true, }, xAxis: { type: 'value', name: xAxisLabel, axisLine: { show: true, }, axisTick: { show: true, }, splitLine: { show: true, lineStyle: { color: '#E5E7EB', }, }, }, yAxis: { type: 'category', name: yAxisLabel, data: data.map((item) => item[yAxisDataNameKey]).reverse(), // Reverse the categories to maintain original order axisLabel: { formatter: (value) => { return value.length > 20 ? `${value.substring(0, 17)}...` : value; }, }, }, series: [ { name: 'Value', type: 'bar', data: data.map((item) => item[xAxisNameKey]).reverse(), // Reverse the data to match categories itemStyle: { color: { type: 'linear', x: 0, y: 0, x2: 1, y2: 0, colorStops: [ { offset: 0, color: colorScheme[0], }, { offset: 1, color: colorScheme[1], }, ], }, }, barWidth: '60%', emphasis: { itemStyle: { opacity: 0.8, }, }, }, ], aria: { enabled: true, }, animation: true, animationDuration: 1000, animationEasing: 'cubicInOut', }); export const getDonutChartOptions = ({ data }) => { const chartOptions = { tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)', }, legend: { orient: 'horizontal', bottom: 0, left: 'center', }, series: [ { name: 'Distribution', type: 'pie', radius: ['40%', '70%'], avoidLabelOverlap: false, itemStyle: { borderRadius: 10, borderColor: '#fff', borderWidth: 2, }, label: { show: true, position: 'outside', formatter: '{b}', fontSize: 12, lineHeight: 15, rich: { b: { fontSize: 12, lineHeight: 15, }, }, }, labelLine: { show: true, length: 15, length2: 10, }, emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold', }, itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)', }, }, data: data, }, ], }; return chartOptions; }; export const formatChartLabel = (params) => { console.log('formatChartLabel params', params); const formattedValue = params.value.toLocaleString(); const percentage = params.treeMapPercent ? ` (${params.treeMapPercent.toFixed(1)}%)` : ''; return `${params.name}\n${params.valueLabel}: ${formattedValue}\n${percentage}`; }; export const getLargeDatasetChartOptions = ({ data, labelFormatter, tooltipFormatter }) => { return { tooltip: { trigger: 'item', formatter: tooltipFormatter, }, toolbox: { show: true, feature: { dataView: { show: true, title: 'View as Text', readOnly: true, lang: ['Data View', 'Close', 'Refresh'], }, saveAsImage: { show: true, title: 'Save Image', }, }, right: '3%', top: 5, }, grid: { left: '5%', right: '5%', bottom: '15%', containLabel: true, }, series: [ { type: 'treemap', data: data.seriesData, label: { show: true, formatter: labelFormatter, position: 'inside', }, breadcrumb: { show: false, }, roam: 'scale', nodeClick: false, animation: true, height: '85%', itemStyle: { borderColor: '#fff', borderWidth: 1, gapWidth: 1, }, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)', }, }, levels: [ { itemStyle: { borderColor: '#fff', borderWidth: 1, gapWidth: 1, }, upperLabel: { show: false, }, }, ], }, ], dataZoom: [ { type: 'slider', show: true, start: 0, end: 100, height: 20, bottom: 10, left: '5%', right: '5%', zoomLock: false, showDetail: true, borderColor: '#ccc', borderRadius: 3, backgroundColor: '#f5f5f5', fillerColor: 'rgba(167, 183, 204, 0.4)', handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z', handleSize: '80%', handleStyle: { color: '#fff', shadowBlur: 3, shadowColor: 'rgba(0, 0, 0, 0.6)', shadowOffsetX: 2, shadowOffsetY: 2, }, }, ], }; };