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
JavaScript
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,
},
},
],
};
};