2024-01-15 13:33:08 -07:00
|
|
|
import React from 'react';
|
|
|
|
import * as scale from 'd3-scale';
|
|
|
|
import { View } from 'react-native';
|
|
|
|
import { BarChart, XAxis, YAxis } from 'react-native-svg-charts';
|
|
|
|
|
2024-01-15 18:40:24 -07:00
|
|
|
import { useGraphData } from '../use-graph-data';
|
2024-01-15 13:33:08 -07:00
|
|
|
import { GraphData, YAxisProps } from '../graph-types';
|
|
|
|
|
|
|
|
import { CustomBars } from '../custom-bars';
|
|
|
|
import { CustomGrid } from '../custom-grid';
|
2024-01-15 18:52:10 -07:00
|
|
|
import { graphStyles } from '../chart-styles';
|
|
|
|
import ChartView from '../chart-view';
|
2024-01-15 13:33:08 -07:00
|
|
|
|
|
|
|
interface Props {
|
|
|
|
data: GraphData;
|
|
|
|
height?: number;
|
|
|
|
spacingInner?: number;
|
|
|
|
spacingOuter?: number;
|
|
|
|
contentInset?: { top: number; bottom: number };
|
|
|
|
min?: number;
|
|
|
|
numberOfTicks?: number;
|
|
|
|
barColors?: Array<string>;
|
|
|
|
useCommonScale?: boolean;
|
|
|
|
yAxisProps?: YAxisProps;
|
2024-01-15 18:40:24 -07:00
|
|
|
testID?: string;
|
2024-01-15 13:33:08 -07:00
|
|
|
}
|
|
|
|
|
2024-01-15 18:40:24 -07:00
|
|
|
// TODO: separate PR will update useGraphData to take into account useCommonScale
|
|
|
|
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
|
|
|
export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, testID, ...props }) => {
|
|
|
|
if (!data) {
|
|
|
|
return null
|
|
|
|
}
|
2024-01-15 13:33:08 -07:00
|
|
|
const {
|
|
|
|
xValues,
|
|
|
|
yData,
|
|
|
|
yAxisRightLabels,
|
|
|
|
yAxisLeftLabels,
|
|
|
|
defaultProps: {
|
|
|
|
height,
|
|
|
|
spacingInner,
|
|
|
|
spacingOuter,
|
|
|
|
contentInset,
|
|
|
|
min,
|
|
|
|
numberOfTicks,
|
|
|
|
barColors,
|
|
|
|
yAxisProps: {
|
|
|
|
maxLeftYAxisValue,
|
|
|
|
maxRightYAxisValue,
|
|
|
|
formatRightYAxisLabel,
|
|
|
|
formatLeftYAxisLabel
|
|
|
|
}
|
|
|
|
}
|
2024-01-15 18:40:24 -07:00
|
|
|
// Proper error/loading handling from useQueryHandler can work with this rule
|
|
|
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
|
|
} = useGraphData(data, props);
|
|
|
|
|
|
|
|
|
2024-01-15 13:33:08 -07:00
|
|
|
|
|
|
|
return (
|
2024-01-15 18:52:10 -07:00
|
|
|
<ChartView>
|
2024-01-15 18:40:24 -07:00
|
|
|
<View style={[graphStyles.rowContainer, { height: height }]} testID={`bar-graph-${testID}`}>
|
2024-01-15 13:33:08 -07:00
|
|
|
<YAxis
|
|
|
|
data={yAxisLeftLabels.values}
|
|
|
|
contentInset={contentInset}
|
|
|
|
svg={graphStyles.yAxisFontStyle}
|
|
|
|
style={graphStyles.yAxisLeftPadding}
|
|
|
|
min={min}
|
|
|
|
max={maxLeftYAxisValue}
|
|
|
|
numberOfTicks={numberOfTicks}
|
|
|
|
formatLabel={formatLeftYAxisLabel}
|
|
|
|
/>
|
2024-01-15 18:40:24 -07:00
|
|
|
|
2024-01-15 13:33:08 -07:00
|
|
|
<View style={graphStyles.flex}>
|
|
|
|
<BarChart
|
|
|
|
style={graphStyles.flex}
|
|
|
|
data={yData}
|
|
|
|
gridMin={min}
|
2024-01-15 18:40:24 -07:00
|
|
|
svg={{ stroke: 'transparent' }} // might want to do the transparent from here - if so may be best built as coming from defaultConfig
|
|
|
|
numberOfTicks={numberOfTicks} // rethink numberOfTicks, it should be determined automatically if we do our y axis scaling properly
|
2024-01-15 13:33:08 -07:00
|
|
|
yAccessor={({ item }) => (item as unknown as { value: number }).value}
|
|
|
|
contentInset={contentInset}
|
|
|
|
spacingInner={spacingInner}
|
|
|
|
spacingOuter={spacingOuter}
|
|
|
|
>
|
|
|
|
<CustomGrid />
|
|
|
|
<CustomBars barData={yData} xValues={xValues} barColors={barColors} />
|
|
|
|
</BarChart>
|
|
|
|
<XAxis
|
|
|
|
data={xValues.map((_, index) => index)}
|
|
|
|
formatLabel={(_, index) => xValues[index]}
|
|
|
|
style={graphStyles.xAxisMarginTop}
|
|
|
|
svg={graphStyles.xAxisFontStyle}
|
|
|
|
scale={scale.scaleBand}
|
|
|
|
/>
|
|
|
|
</View>
|
2024-01-15 18:40:24 -07:00
|
|
|
|
2024-01-15 13:33:08 -07:00
|
|
|
<YAxis
|
|
|
|
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
|
|
|
|
contentInset={contentInset}
|
|
|
|
svg={graphStyles.yAxisFontStyle}
|
|
|
|
style={graphStyles.yAxisRightPadding}
|
|
|
|
min={min}
|
|
|
|
max={maxRightYAxisValue}
|
|
|
|
numberOfTicks={numberOfTicks}
|
2024-01-15 18:40:24 -07:00
|
|
|
formatLabel={formatRightYAxisLabel}
|
2024-01-15 13:33:08 -07:00
|
|
|
/>
|
|
|
|
</View>
|
2024-01-15 18:55:19 -07:00
|
|
|
</ChartView>
|
2024-01-15 13:33:08 -07:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default BarGraph;
|