Files
n8n-enterprise-unlocked/packages/frontend/editor-ui/src/features/insights/chartjs.utils.ts
2025-04-07 10:55:56 +02:00

206 lines
4.6 KiB
TypeScript

import { merge } from 'lodash-es';
import { type ChartOptions, type ScriptableContext } from 'chart.js';
import { useCssVar } from '@vueuse/core';
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
/**
*
* Chart js configuration
*/
export const generateLinearGradient = (ctx: CanvasRenderingContext2D, height: number) => {
const gradient = ctx.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0, 'rgba(255, 111,92, 1)');
gradient.addColorStop(0.8, 'rgba(255, 111, 92, 0.25)');
gradient.addColorStop(1, 'rgba(255, 111, 92, 0)');
return gradient;
};
export const generateLineChartOptions = (
overrides: ChartOptions<'line'> = {},
): ChartOptions<'line'> => {
const colorTextDark = useCssVar('--color-text-dark', document.body);
const colorBackgroundLight = useCssVar('--color-background-xlight', document.body);
const colorForeGroundBase = useCssVar('--color-foreground-base', document.body);
const colorTextLight = useCssVar('--color-text-light', document.body);
return merge(
{
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
tooltip: {
caretSize: 0,
xAlign: 'center',
yAlign: 'bottom',
padding: 16,
titleFont: {
size: 14,
},
bodyFont: {
size: 14,
},
backgroundColor: colorBackgroundLight.value,
titleColor: colorTextDark.value,
bodyColor: colorTextDark.value,
borderWidth: 1,
borderColor: colorForeGroundBase.value,
callbacks: {
label(context: ScriptableContext<'line'>) {
const label = context.dataset.label ?? '';
return `${label} ${smartDecimal(context.parsed.y).toLocaleString('en-US')}`;
},
labelColor(context: ScriptableContext<'line'>) {
return {
borderColor: 'rgba(0, 0, 0, 0)',
backgroundColor: context.dataset.backgroundColor as string,
borderWidth: 0,
borderRadius: 2,
};
},
},
},
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false,
},
scales: {
x: {
grid: {
display: false,
},
stacked: true,
beginAtZero: true,
border: {
display: false,
},
ticks: {
color: colorTextLight.value,
},
},
y: {
grid: {
color: colorForeGroundBase.value,
},
stacked: true,
border: {
display: false,
},
ticks: {
maxTicksLimit: 3,
color: colorTextLight.value,
},
},
},
},
overrides,
);
};
export const generateBarChartOptions = (
overrides: ChartOptions<'bar'> = {},
): ChartOptions<'bar'> => {
const colorTextLight = useCssVar('--color-text-light', document.body);
const colorTextDark = useCssVar('--color-text-dark', document.body);
const colorBackgroundLight = useCssVar('--color-background-xlight', document.body);
const colorForeGroundBase = useCssVar('--color-foreground-base', document.body);
return merge(
{
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
align: 'end',
reverse: true,
position: 'top',
labels: {
boxWidth: 8,
boxHeight: 8,
borderRadius: 2,
useBorderRadius: true,
},
},
tooltip: {
caretSize: 0,
xAlign: 'center',
yAlign: 'bottom',
padding: 16,
titleFont: {
size: 14,
},
bodyFont: {
size: 14,
},
backgroundColor: colorBackgroundLight.value,
titleColor: colorTextDark.value,
bodyColor: colorTextDark.value,
borderWidth: 1,
borderColor: colorForeGroundBase.value,
callbacks: {
label(context: ScriptableContext<'bar'>) {
const label = context.dataset.label ?? '';
return `${label} ${context.parsed.y}`;
},
labelColor(context: ScriptableContext<'bar'>) {
return {
borderColor: 'rgba(0, 0, 0, 0)',
backgroundColor: context.dataset.backgroundColor as string,
borderWidth: 0,
borderRadius: 2,
};
},
},
},
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false,
},
datasets: {
bar: {
maxBarThickness: 32,
borderRadius: 4,
},
},
scales: {
x: {
grid: {
display: false,
},
stacked: true,
beginAtZero: true,
border: {
display: false,
},
ticks: {
color: colorTextLight.value,
},
},
y: {
grid: {
color: colorForeGroundBase.value,
},
stacked: true,
border: {
display: false,
},
ticks: {
maxTicksLimit: 3,
color: colorTextLight.value,
},
},
},
},
overrides,
);
};