add bar graph, make changes to customgrid and custombars to match new structure
This commit is contained in:
@@ -3,8 +3,7 @@ import * as scale from 'd3-scale';
|
||||
import { View } from 'react-native';
|
||||
import { BarChart, XAxis, YAxis } from 'react-native-svg-charts';
|
||||
|
||||
import { useGraphData } from '../../../hooks/charts/useGraphData';
|
||||
import ChartView from '../ChartView';
|
||||
import { useGraphData } from '../use-graph-data';
|
||||
import { GraphData, YAxisProps } from '../graph-types';
|
||||
|
||||
import { CustomBars } from '../custom-bars';
|
||||
@@ -22,10 +21,15 @@ interface Props {
|
||||
barColors?: Array<string>;
|
||||
useCommonScale?: boolean;
|
||||
yAxisProps?: YAxisProps;
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, ...props }) => {
|
||||
if (!data || typeof data !== 'object') return null; // TODO: replace when we have error/loading context from useQueryHandler
|
||||
// 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
|
||||
}
|
||||
const {
|
||||
xValues,
|
||||
yData,
|
||||
@@ -46,11 +50,14 @@ export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, ...pro
|
||||
formatLeftYAxisLabel
|
||||
}
|
||||
}
|
||||
} = useGraphData(data, props, useCommonScale);
|
||||
// Proper error/loading handling from useQueryHandler can work with this rule
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
} = useGraphData(data, props);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<ChartView>
|
||||
<View style={[graphStyles.rowContainer, { height: height }]}>
|
||||
<View style={[graphStyles.rowContainer, { height: height }]} testID={`bar-graph-${testID}`}>
|
||||
<YAxis
|
||||
data={yAxisLeftLabels.values}
|
||||
contentInset={contentInset}
|
||||
@@ -61,13 +68,14 @@ export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, ...pro
|
||||
numberOfTicks={numberOfTicks}
|
||||
formatLabel={formatLeftYAxisLabel}
|
||||
/>
|
||||
|
||||
<View style={graphStyles.flex}>
|
||||
<BarChart
|
||||
style={graphStyles.flex}
|
||||
data={yData}
|
||||
gridMin={min}
|
||||
svg={{ stroke: 'transparent' }} // might want to do the transparent from here?
|
||||
numberOfTicks={numberOfTicks} // rethink numberOfTicks, it should be determined automatically if we do our y axis scaling proper
|
||||
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
|
||||
yAccessor={({ item }) => (item as unknown as { value: number }).value}
|
||||
contentInset={contentInset}
|
||||
spacingInner={spacingInner}
|
||||
@@ -84,6 +92,7 @@ export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, ...pro
|
||||
scale={scale.scaleBand}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<YAxis
|
||||
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
|
||||
contentInset={contentInset}
|
||||
@@ -92,10 +101,9 @@ export const BarGraph: React.FC<Props> = ({ data, useCommonScale = false, ...pro
|
||||
min={min}
|
||||
max={maxRightYAxisValue}
|
||||
numberOfTicks={numberOfTicks}
|
||||
formatLabel={formatRightYAxisLabel} // formatRightYAxisLabel formatting could come from yAxisRightLabels object
|
||||
formatLabel={formatRightYAxisLabel}
|
||||
/>
|
||||
</View>
|
||||
</ChartView>
|
||||
);
|
||||
};
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { path as d3 } from 'd3-path';
|
||||
|
||||
import { ScaleFunction } from './graph-types';
|
||||
import { ScaleLinearType, ScaleBandType } from './graph-types';
|
||||
|
||||
type BarCalculationProps = {
|
||||
scaleX: ScaleFunction;
|
||||
scaleY: ScaleFunction;
|
||||
scaleX: ScaleBandType;
|
||||
scaleY: ScaleLinearType;
|
||||
data: { value: number };
|
||||
barNumber: number;
|
||||
index: number;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import { Svg } from 'react-native-svg';
|
||||
|
||||
import { Bar } from './bar';
|
||||
import { ScaleFunction } from './graph-types';
|
||||
import { ScaleBandType, ScaleLinearType } from './graph-types';
|
||||
import { calculateBarWidth } from './custom-bar-utils';
|
||||
|
||||
export interface CombinedData {
|
||||
@@ -11,38 +11,38 @@ export interface CombinedData {
|
||||
}
|
||||
|
||||
interface CustomBarsProps {
|
||||
x: ScaleFunction;
|
||||
y: ScaleFunction;
|
||||
x: ScaleBandType;
|
||||
y: ScaleLinearType;
|
||||
bandwidth: number;
|
||||
barColors: string[];
|
||||
rawData: unknown[]; // TODO: update this value when this data type is defined
|
||||
combinedData: CombinedData[];
|
||||
xValues: unknown[]; // TODO: update this value when this data type is defined
|
||||
barData: CombinedData[];
|
||||
gap: number;
|
||||
roundedRadius: number;
|
||||
}
|
||||
|
||||
export const CustomBars: React.FC<CustomBarsProps> = ({
|
||||
export const CustomBars: React.FC<Partial<CustomBarsProps>> = ({
|
||||
x: scaleX,
|
||||
y: scaleY,
|
||||
bandwidth,
|
||||
combinedData,
|
||||
rawData,
|
||||
barData,
|
||||
xValues,
|
||||
barColors,
|
||||
gap = 2,
|
||||
roundedRadius = 4
|
||||
}) => {
|
||||
const barWidth = calculateBarWidth(bandwidth, combinedData.length, gap);
|
||||
const barWidth = calculateBarWidth(bandwidth, barData.length, gap);
|
||||
|
||||
return rawData.map((_, index) => (
|
||||
return xValues.map((_, index) => (
|
||||
<Svg key={`group-${index}`} testID={`svg-${index}`}>
|
||||
{combinedData.map((item, i) => (
|
||||
{barData.map((item, i) => (
|
||||
<Bar
|
||||
key={`bar-${i}-${index}`}
|
||||
scaleX={scaleX}
|
||||
scaleY={scaleY}
|
||||
data={item.data[index]}
|
||||
barNumber={i} // index of bar
|
||||
index={index} // index of group
|
||||
barNumber={i}
|
||||
index={index}
|
||||
fill={barColors[i]}
|
||||
barWidth={barWidth}
|
||||
gap={gap}
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import { G, Line } from 'react-native-svg';
|
||||
import { colors } from '../../styles';
|
||||
import { ScaleFunction } from './graph-types';
|
||||
import { ScaleLinearType } from './graph-types';
|
||||
|
||||
interface CustomGridProps {
|
||||
y: ScaleFunction;
|
||||
y: ScaleLinearType;
|
||||
ticks: Array<number>;
|
||||
}
|
||||
|
||||
export const CustomGrid: React.FC<CustomGridProps> = ({ y, ticks }) => {
|
||||
export const CustomGrid: React.FC<Partial<CustomGridProps>> = ({ y, ticks }) => {
|
||||
const [firstTick, ...remainingTicks] = ticks;
|
||||
const dashArray = [1, 3];
|
||||
const strokeSolidWidth = 0.2;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { ScaleLinear } from 'd3-scale'
|
||||
import { ScaleBand, ScaleLinear } from 'd3-scale'
|
||||
|
||||
export type ScaleFunction = ScaleLinear<number, number>;
|
||||
export type ScaleLinearType = ScaleLinear<number, number>;
|
||||
export type ScaleBandType = ScaleBand<number | string>;
|
||||
|
||||
export interface YAxisData {
|
||||
key: string; // string value for ChartLabel and useGraphData
|
||||
@@ -40,5 +41,6 @@ export interface GraphProps {
|
||||
min?: number;
|
||||
numberOfTicks?: number;
|
||||
barColors?: Array<string>;
|
||||
useCommonScale?: boolean;
|
||||
yAxisProps?: YAxisProps;
|
||||
}
|
Reference in New Issue
Block a user