Skip to content

Commit

Permalink
🎉 added a new hook for creating series range, and use it with useLine…
Browse files Browse the repository at this point in the history
…Series to create all ranges (wonder if this approach worked)
  • Loading branch information
kunkoala committed Sep 18, 2024
1 parent 8d0c165 commit 5b2fbd3
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 30 deletions.
72 changes: 42 additions & 30 deletions frontend/src/components/LineChartComponents/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ import useValueAxis from 'components/shared/LineChart/ValueAxis';
import {useDateSelectorFilter} from 'components/shared/LineChart/Filter';
import useDateAxisRange from 'components/shared/LineChart/AxisRange';
import useValueAxisRange from 'components/shared/LineChart/ValueAxisRange';
import {useLineSeriesList} from 'components/shared/LineChart/LineSeries';
import {LineSeries} from '@amcharts/amcharts5/.internal/charts/xy/series/LineSeries';
import {LineChartData} from 'types/lineChart';
import {useSeriesRange} from 'components/shared/LineChart/SeriesRange';

interface LineChartProps {
/** Optional unique identifier for the chart. Defaults to 'chartdiv'. */
Expand Down Expand Up @@ -86,7 +85,7 @@ export default function LineChart({
exportedFileName = 'Data',
yAxisLabel,
localization,
horizontalYAxisThreshold = 0,
horizontalYAxisThreshold = undefined,
}: LineChartProps): JSX.Element {
const {t: defaultT, i18n} = useTranslation();

Expand Down Expand Up @@ -364,28 +363,46 @@ export default function LineChart({
});
}, [lineChartData, root, xAxis, yAxis, chartId]);

useLineSeriesList(
root,
chart,
lineChartDataSettings,
useCallback(
(series: LineSeries) => {
if (!lineChartData) return;
const seriesSettings = lineChartData.find((line) => line.serieId === series.get('id')?.split('_')[1]);
series.strokes.template.setAll({
strokeWidth: seriesSettings?.stroke.strokeWidth ?? 2,
strokeDasharray: seriesSettings?.stroke.strokeDasharray ?? undefined,
});
if (seriesSettings?.fill) {
series.fills.template.setAll({
fillOpacity: seriesSettings.fillOpacity ?? 1,
visible: true,
});
}
},
[lineChartData]
)
);
// useLineSeriesList(
// root,
// chart,
// lineChartDataSettings,
// useCallback(
// (series: LineSeries) => {
// if (!lineChartData) return;

// const seriesSettings = lineChartData.find((line) => line.serieId === series.get('id')?.split('_')[1]);

// series.strokes.template.setAll({
// strokeWidth: seriesSettings?.stroke.strokeWidth ?? 2,
// strokeDasharray: seriesSettings?.stroke.strokeDasharray ?? undefined,
// });
// if (seriesSettings?.fill) {
// series.fills.template.setAll({
// fillOpacity: seriesSettings.fillOpacity ?? 1,
// visible: true,
// });
// }
// },
// [lineChartData]
// )
// );

// Effect to add series range above threshold to chart
useSeriesRange(root, chart, lineChartDataSettings, yAxis, {
threshold: horizontalYAxisThreshold ?? 0,
fills: {
fill: color(theme.palette.error.main),
fillOpacity: 0.3,
visible: true,
},
strokes: {
stroke: color(theme.palette.error.main),
strokeWidth: 2,
strokeOpacity: 1,
visible: true,
},
});

// a horizontal line to limit the y-axis
const targetLineSettings = useMemo(() => {
Expand All @@ -406,11 +423,6 @@ export default function LineChart({
visible: true,
location: 0,
},
axisFill: {
fill: color(theme.palette.error.main), // Use dynamic fill color based on the threshold
fillOpacity: 0.5,
visible: true,
},
label: {
fill: color(theme.palette.divider),
text: `Threshold: ${horizontalYAxisThreshold}`,
Expand Down
61 changes: 61 additions & 0 deletions frontend/src/components/shared/LineChart/SeriesRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {XYChart} from '@amcharts/amcharts5/.internal/charts/xy/XYChart';
import {Root} from '@amcharts/amcharts5/.internal/core/Root';
import {ILineSeriesSettings, LineSeries} from '@amcharts/amcharts5/.internal/charts/xy/series/LineSeries';
import {useLineSeriesList} from './LineSeries';
import {useLayoutEffect} from 'react';
import {AxisRenderer, ValueAxis} from '@amcharts/amcharts5/xy';
import {IGraphicsSettings} from '@amcharts/amcharts5';
import {ILineSeriesAxisRange} from '@amcharts/amcharts5/.internal/charts/xy/series/LineSeries';

export function useSeriesRange(
root: Root | null,
chart: XYChart | null,
settings: Array<ILineSeriesSettings>,
yAxis: ValueAxis<AxisRenderer> | null, // The yAxis for creating range
rangeSettings: {
threshold: number; // The threshold for the series range
fills: Partial<IGraphicsSettings>; // Fill color for the range
strokes: Partial<IGraphicsSettings>; // Stroke color for the range
},
initializer?: (series: LineSeries, i: number) => void
) {
// Use the existing `useLineSeriesList` hook to create the series
const seriesList = useLineSeriesList(root, chart, settings, initializer);

// Use `useLayoutEffect` to apply the series range logic after the series are created
useLayoutEffect(() => {
if (!seriesList || !yAxis || seriesList.length === 0) return;

// Iterate over each series to create and apply the series range
seriesList.forEach((series: LineSeries) => {
const seriesRangeDataItem = yAxis.makeDataItem({
value: rangeSettings.threshold, // Start of the range
endValue: 1e6, // End value of the range (adjust as needed)
});

const seriesRange = series.createAxisRange(seriesRangeDataItem);

// Set the fill and stroke properties for the range
if (rangeSettings.fills) {
seriesRange.fills?.template.setAll(rangeSettings.fills);
}

if (rangeSettings.strokes) {
seriesRange.strokes?.template.setAll(rangeSettings.strokes);
}
});

return () => {
// Dispose of the ranges when the component unmounts
seriesList.forEach((series: LineSeries) => {
series.axisRanges.each((range: ILineSeriesAxisRange) => {
if (series.axisRanges.contains(range)) {
series.axisRanges.removeValue(range);
}
});
});
};
}, [seriesList, rangeSettings, yAxis]);

return seriesList ?? null;
}

0 comments on commit 5b2fbd3

Please sign in to comment.