wip: minor changes

This commit is contained in:
Loewy 2024-02-13 11:50:06 -08:00
parent db9475cf3b
commit 8c3b745d4d
4 changed files with 129 additions and 92 deletions

View File

@ -0,0 +1,91 @@
import React from "react";
import { View } from "react-native";
import { YAxis } from "react-native-svg-charts";
import { graphStyles } from "../chart-styles";
import ChartView from "../chart-view";
import { ChartContainerProps } from "../graph-types";
import { useGraphData } from "../use-graph-data";
// TODO: separate PR will update useGraphData to take into account useCommonScale
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const ChartContainer: React.FC<ChartContainerProps> = ({
ChartComponent,
data,
useCommonScale = false,
testID,
...props
}) => {
if (!data || typeof data !== "object") {
return null;
} // TODO:#38
const {
xValues,
yData,
yAxisLeftLabels,
yAxisRightLabels,
defaultProps: {
height,
contentInset,
min,
numberOfTicks,
lineStrokeWidth,
yAxisProps: {
maxLeftYAxisValue,
maxRightYAxisValue,
formatLeftYAxisLabel,
formatRightYAxisLabel,
},
},
// Proper error/loading handling from useQueryHandler can work with this rule #38
// eslint-disable-next-line react-hooks/rules-of-hooks
} = useGraphData(data, props);
// TODO: This could be done by the hook since it already handles spreading props.
// Depending on if we want a context provider for Charts, that could be another way to handle it
const chartComponentProps = {
yData,
xValues,
lineStrokeWidth,
min,
contentInset,
numberOfTicks,
};
return (
<ChartView>
<View
style={[graphStyles.rowContainer, { height: height }]}
testID={`line-graph-${testID}`}
>
<YAxis
data={yAxisLeftLabels.values}
contentInset={contentInset}
svg={graphStyles.yAxisFontStyle}
style={graphStyles.yAxisLeftPadding}
min={min}
max={maxLeftYAxisValue}
numberOfTicks={numberOfTicks}
formatLabel={formatLeftYAxisLabel}
/>
<View style={graphStyles.flex}>
<ChartComponent {...chartComponentProps} />
</View>
<YAxis
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
contentInset={contentInset}
svg={graphStyles.yAxisFontStyle}
style={[
graphStyles.yAxisRightPadding,
{ height: useCommonScale ? 0 : "auto" },
]}
min={min}
max={maxRightYAxisValue}
numberOfTicks={numberOfTicks}
formatLabel={formatRightYAxisLabel}
/>
</View>
</ChartView>
);
};
export default ChartContainer;

View File

@ -76,3 +76,12 @@ export interface CommonProps {
yAxisProps?: YAxisProps; yAxisProps?: YAxisProps;
testID?: string; testID?: string;
} }
/**
* Common properties for graph render components.
*
* @interface ChartContainerProps
* @property {React.FC} ChartComponent - The graph component to render
*/
export interface ChartContainerProps extends CommonProps {
ChartComponent?: React.FC;
}

View File

@ -1,72 +1,23 @@
import * as shape from "d3-shape"; import * as shape from "d3-shape";
import React from "react"; import React from "react";
import { View } from "react-native"; import { LineChart, XAxis } from "react-native-svg-charts";
import { LineChart, XAxis, YAxis } from "react-native-svg-charts";
import { graphStyles } from "../chart-styles"; import { graphStyles } from "../chart-styles";
import ChartView from "../chart-view";
import { CustomGrid } from "../custom-grid"; import { CustomGrid } from "../custom-grid";
import { CommonProps } from "../graph-types"; import { CommonProps } from "../graph-types";
import { useGraphData } from "../use-graph-data";
// TODO: separate PR will update useGraphData to take into account useCommonScale // TODO: separate PR will update useGraphData to take into account useCommonScale
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
const LineGraph: React.FC<CommonProps> = ({ const LineGraph: React.FC<CommonProps> = ({ ...chartComponentProps }) => {
data, const { yData, xValues, lineStrokeWidth, min, contentInset, numberOfTicks } =
useCommonScale = false, chartComponentProps;
testID,
...props
}) => {
if (!data || typeof data !== "object") {
return null;
} // TODO:#38
const {
xValues,
yData,
yAxisLeftLabels,
yAxisRightLabels,
defaultProps: {
height,
contentInset,
min,
numberOfTicks,
lineStrokeWidth,
yAxisProps: {
maxLeftYAxisValue,
maxRightYAxisValue,
formatLeftYAxisLabel,
formatRightYAxisLabel,
},
},
// Proper error/loading handling from useQueryHandler can work with this rule #38
// eslint-disable-next-line react-hooks/rules-of-hooks
} = useGraphData(data, props);
return ( return (
<ChartView> <>
<View
style={[graphStyles.rowContainer, { height: height }]}
testID={`line-graph-${testID}`}
>
<YAxis
data={yAxisLeftLabels.values}
contentInset={contentInset}
svg={graphStyles.yAxisFontStyle}
style={graphStyles.yAxisLeftPadding}
min={min}
max={maxLeftYAxisValue}
numberOfTicks={numberOfTicks}
formatLabel={formatLeftYAxisLabel}
/>
<View style={graphStyles.flex}>
<LineChart <LineChart
style={graphStyles.flex} style={graphStyles.flex}
data={yData} data={yData}
curve={shape.curveNatural} curve={shape.curveNatural}
svg={{ strokeWidth: lineStrokeWidth }} svg={{ strokeWidth: lineStrokeWidth }}
yAccessor={({ item }) => yAccessor={({ item }) => (item as unknown as { value: number }).value}
(item as unknown as { value: number }).value
}
xAccessor={({ index }) => xValues[index] as number} xAccessor={({ index }) => xValues[index] as number}
gridMin={min} gridMin={min}
contentInset={contentInset} contentInset={contentInset}
@ -81,22 +32,7 @@ const LineGraph: React.FC<CommonProps> = ({
numberOfTicks={numberOfTicks} numberOfTicks={numberOfTicks}
contentInset={graphStyles.horizontalInset} contentInset={graphStyles.horizontalInset}
/> />
</View> </>
<YAxis
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
contentInset={contentInset}
svg={graphStyles.yAxisFontStyle}
style={[
graphStyles.yAxisRightPadding,
{ height: useCommonScale ? 0 : "auto" },
]}
min={min}
max={maxRightYAxisValue}
numberOfTicks={numberOfTicks}
formatLabel={formatRightYAxisLabel} // formatRightYAxisLabel formatting could come from yAxisRightLabels object
/>
</View>
</ChartView>
); );
}; };

View File

@ -1,14 +1,15 @@
import React from "react"; import React from "react";
import { StyleSheet, View } from "react-native"; import { StyleSheet, View } from "react-native";
import { graph_data_two_measures } from "../../test/mock/charts/mock-data"; import { line_chart_two_y_data } from "../../test/mock/charts/mock-data";
import BarGraph from "../component/charts/bar-graph/bar-graph"; import ChartContainer from "../component/charts/container/chart-container";
import LineGraph from "../component/charts/line-graph/line-graph";
// Session Mock - can be used for session summary screen using a query handler component // Session Mock - can be used for session summary screen using a query handler component
// BarGraph component using mocked data currently // BarGraph component using mocked data currently
export default function SessionScreen() { export default function SessionScreen() {
return ( return (
<View style={StyleSheet.absoluteFill}> <View style={StyleSheet.absoluteFill}>
<BarGraph data={graph_data_two_measures} /> <ChartContainer data={line_chart_two_y_data} ChartComponent={LineGraph} />
</View> </View>
); );
} }