mirror of https://github.com/buster-so/buster.git
animation handler
This commit is contained in:
parent
0f5648c2c8
commit
26db7bb1df
|
@ -24,7 +24,6 @@ import {
|
||||||
scales
|
scales
|
||||||
} from 'chart.js';
|
} from 'chart.js';
|
||||||
import { ChartMountedPlugin } from './core/plugins';
|
import { ChartMountedPlugin } from './core/plugins';
|
||||||
import CrosshairPlugin from './core/plugins/chartjs-plugin-crosshair';
|
|
||||||
import ChartDeferred from 'chartjs-plugin-deferred';
|
import ChartDeferred from 'chartjs-plugin-deferred';
|
||||||
import ChartJsAnnotationPlugin from 'chartjs-plugin-annotation';
|
import ChartJsAnnotationPlugin from 'chartjs-plugin-annotation';
|
||||||
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
||||||
|
@ -70,8 +69,7 @@ ChartJS.register(
|
||||||
LogarithmicScale,
|
LogarithmicScale,
|
||||||
TimeScale,
|
TimeScale,
|
||||||
TimeSeriesScale,
|
TimeSeriesScale,
|
||||||
ChartDataLabels,
|
ChartDataLabels
|
||||||
CrosshairPlugin
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ChartJS.defaults.responsive = true;
|
ChartJS.defaults.responsive = true;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { AnimationOptions, AnimationSpec } from 'chart.js';
|
||||||
|
|
||||||
|
export const barDelayAnimation = (props?: { dataDelay?: number; datasetDelay?: number }) => {
|
||||||
|
const { dataDelay = 200, datasetDelay = 100 } = props || {};
|
||||||
|
let delayed = false;
|
||||||
|
return {
|
||||||
|
onComplete: () => {
|
||||||
|
delayed = true;
|
||||||
|
},
|
||||||
|
delay: (context) => {
|
||||||
|
let delay = 0;
|
||||||
|
const numberOfDatasets = context.chart.data.datasets.length;
|
||||||
|
const numberOfDataPoints = context.chart.data.datasets[context.datasetIndex].data.length;
|
||||||
|
|
||||||
|
if (context.type === 'data' && context.mode === 'default' && !delayed) {
|
||||||
|
delay = context.dataIndex * dataDelay + context.datasetIndex * datasetDelay;
|
||||||
|
// Ensure the maximum delay is 1000ms
|
||||||
|
delay = Math.min(delay, 1000);
|
||||||
|
}
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
} satisfies AnimationOptions<'bar'>['animation'];
|
||||||
|
};
|
|
@ -1,10 +1,21 @@
|
||||||
import { ArcElement, Chart, ChartDataset, ChartMeta, ChartType, Plugin } from 'chart.js';
|
import {
|
||||||
|
AnimationSpec,
|
||||||
|
ArcElement,
|
||||||
|
Chart,
|
||||||
|
ChartDataset,
|
||||||
|
ChartMeta,
|
||||||
|
ChartType,
|
||||||
|
Plugin
|
||||||
|
} from 'chart.js';
|
||||||
import OutLabel from './OutLabel';
|
import OutLabel from './OutLabel';
|
||||||
import OutLabelsContext from './OutLabelsContext';
|
import OutLabelsContext from './OutLabelsContext';
|
||||||
import OutLabelsManager from './OutLabelsManager';
|
import OutLabelsManager from './OutLabelsManager';
|
||||||
import { OutLabelStyle } from './OutLabelsStyle';
|
import { OutLabelStyle } from './OutLabelsStyle';
|
||||||
import { OutLabelsOptions } from './OutLabelsOptions';
|
import { OutLabelsOptions } from './OutLabelsOptions';
|
||||||
import { CustomAnimationSpec } from '../common';
|
|
||||||
|
interface CustomAnimationSpec extends AnimationSpec<'doughnut' | 'pie'> {
|
||||||
|
onProgress?: (animation: { currentStep: number; numSteps: number }) => void;
|
||||||
|
}
|
||||||
|
|
||||||
const globalAnimationDuration = (Chart.defaults.animation as CustomAnimationSpec).duration;
|
const globalAnimationDuration = (Chart.defaults.animation as CustomAnimationSpec).duration;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
import { AnimationSpec } from 'chart.js';
|
|
||||||
|
|
||||||
export interface CustomAnimationSpec extends AnimationSpec<'doughnut' | 'pie'> {
|
|
||||||
onProgress?: (animation: { currentStep: number; numSteps: number }) => void;
|
|
||||||
}
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { barDelayAnimation } from '../../core/animations/barDelayAnimation';
|
||||||
|
import { ANIMATION_DURATION, ANIMATION_THRESHOLD } from '../../../config';
|
||||||
|
import { AnimationOptions, ChartType as ChartTypeJS } from 'chart.js';
|
||||||
|
import { ChartType } from '@/api/asset_interfaces/metric';
|
||||||
|
|
||||||
|
export const useAnimations = ({
|
||||||
|
animate,
|
||||||
|
numberOfSources,
|
||||||
|
chartType
|
||||||
|
}: {
|
||||||
|
animate: boolean;
|
||||||
|
numberOfSources: number;
|
||||||
|
chartType: ChartType;
|
||||||
|
}): AnimationOptions<ChartTypeJS>['animation'] => {
|
||||||
|
const isAnimationEnabled = useMemo(() => {
|
||||||
|
return animate && numberOfSources <= ANIMATION_THRESHOLD;
|
||||||
|
}, [animate, numberOfSources]);
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
return isAnimationEnabled
|
||||||
|
? {
|
||||||
|
duration: ANIMATION_DURATION,
|
||||||
|
...animationRecord[chartType]?.()
|
||||||
|
}
|
||||||
|
: false;
|
||||||
|
}, [isAnimationEnabled, chartType]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const animationRecord: Record<ChartType, () => AnimationOptions<ChartTypeJS>['animation']> = {
|
||||||
|
bar: barDelayAnimation,
|
||||||
|
line: () => ({}),
|
||||||
|
scatter: () => ({}),
|
||||||
|
pie: () => ({}),
|
||||||
|
metric: () => ({}),
|
||||||
|
table: () => ({}),
|
||||||
|
combo: () => ({})
|
||||||
|
};
|
|
@ -23,6 +23,8 @@ import {
|
||||||
LINE_DECIMATION_THRESHOLD,
|
LINE_DECIMATION_THRESHOLD,
|
||||||
TOOLTIP_THRESHOLD
|
TOOLTIP_THRESHOLD
|
||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
|
import { barDelayAnimation } from '../../core/animations/barDelayAnimation';
|
||||||
|
import { useAnimations } from './useAnimations';
|
||||||
|
|
||||||
interface UseOptionsProps {
|
interface UseOptionsProps {
|
||||||
colors: string[];
|
colors: string[];
|
||||||
|
@ -173,9 +175,7 @@ export const useOptions = ({
|
||||||
}, 0);
|
}, 0);
|
||||||
}, [datasetOptions]);
|
}, [datasetOptions]);
|
||||||
|
|
||||||
const isAnimationEnabled = useMemo(() => {
|
const animation = useAnimations({ animate, numberOfSources, chartType: selectedChartType });
|
||||||
return animate && numberOfSources <= ANIMATION_THRESHOLD;
|
|
||||||
}, [animate, numberOfSources]);
|
|
||||||
|
|
||||||
const disableTooltip = useMemo(() => {
|
const disableTooltip = useMemo(() => {
|
||||||
return disableTooltipProp || numberOfSources >= TOOLTIP_THRESHOLD;
|
return disableTooltipProp || numberOfSources >= TOOLTIP_THRESHOLD;
|
||||||
|
@ -202,7 +202,7 @@ export const useOptions = ({
|
||||||
|
|
||||||
return {
|
return {
|
||||||
indexAxis: isHorizontalBar ? 'y' : 'x',
|
indexAxis: isHorizontalBar ? 'y' : 'x',
|
||||||
animation: isAnimationEnabled ? { duration: ANIMATION_DURATION } : false,
|
animation,
|
||||||
backgroundColor: colors,
|
backgroundColor: colors,
|
||||||
borderColor: colors,
|
borderColor: colors,
|
||||||
scales,
|
scales,
|
||||||
|
@ -236,7 +236,7 @@ export const useOptions = ({
|
||||||
goalLinesAnnotations,
|
goalLinesAnnotations,
|
||||||
trendlineAnnotations,
|
trendlineAnnotations,
|
||||||
tooltipOptions,
|
tooltipOptions,
|
||||||
isAnimationEnabled
|
animate
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
|
Loading…
Reference in New Issue