kat/refactor-use-graph-data (#121)
Reviewed-on: railbird/railbird-mobile#121 Reviewed-by: Ivan Malison <ivanmalison@gmail.com>
This commit is contained in:
parent
762351f76e
commit
b05e354459
@ -4,8 +4,10 @@ import { View } from "react-native";
|
|||||||
import { XAxis, YAxis } from "react-native-svg-charts";
|
import { XAxis, YAxis } from "react-native-svg-charts";
|
||||||
import { graphStyles } from "../chart-styles";
|
import { graphStyles } from "../chart-styles";
|
||||||
import ChartView from "../chart-view";
|
import ChartView from "../chart-view";
|
||||||
|
import { chartDefaults } from "../graph-config";
|
||||||
import { ChartContainerProps } from "../graph-types";
|
import { ChartContainerProps } from "../graph-types";
|
||||||
import { useGraphData } from "../use-graph-data";
|
import { computeYAxisConfig, useGraphData } from "../use-graph-data";
|
||||||
|
computeYAxisConfig;
|
||||||
|
|
||||||
// TODO: #43 #31 separate PR will update useGraphData to take into account useCommonScale
|
// TODO: #43 #31 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
|
||||||
@ -19,62 +21,49 @@ const ChartContainer: React.FC<ChartContainerProps> = ({
|
|||||||
if (!data || typeof data !== "object") {
|
if (!data || typeof data !== "object") {
|
||||||
return null;
|
return null;
|
||||||
} // TODO:#38
|
} // TODO:#38
|
||||||
|
const yAxisProps = computeYAxisConfig(data, props.yAxisProps || {});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
xValues,
|
xValues,
|
||||||
yData,
|
yData,
|
||||||
yAxisLeftLabels,
|
yAxisLeftLabels,
|
||||||
yAxisRightLabels,
|
yAxisRightLabels,
|
||||||
defaultProps: {
|
|
||||||
height,
|
|
||||||
contentInset,
|
|
||||||
min,
|
|
||||||
numberOfTicks,
|
|
||||||
lineStrokeWidth,
|
|
||||||
spacingInner,
|
|
||||||
spacingOuter,
|
|
||||||
barColors,
|
|
||||||
yAxisProps: {
|
|
||||||
maxLeftYAxisValue,
|
|
||||||
maxRightYAxisValue,
|
|
||||||
formatLeftYAxisLabel,
|
|
||||||
formatRightYAxisLabel,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Proper error/loading handling from useQueryHandler can work with this rule #38
|
// Proper error/loading handling from useQueryHandler can work with this rule #38
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
} = useGraphData(data, {
|
} = useGraphData(data, yAxisProps, {
|
||||||
includeColors: ChartComponent.chartType === "bar" ? false : true,
|
includeColors: ChartComponent.chartType === "bar" ? false : true,
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: #31 This could be done by the hook since it already handles spreading props.
|
// TODO: #31 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
|
// Depiending on if we want a context pr}}ovider for Charts, that could be another way to handle it
|
||||||
const chartComponentProps = {
|
const chartComponentProps = {
|
||||||
yData,
|
yData,
|
||||||
xValues,
|
xValues,
|
||||||
lineStrokeWidth,
|
lineStrokeWidth: chartDefaults.lineStrokeWidth,
|
||||||
min,
|
min: chartDefaults.min,
|
||||||
contentInset,
|
contentInset: chartDefaults.contentInset,
|
||||||
numberOfTicks,
|
numberOfTicks: chartDefaults.numberOfTicks,
|
||||||
spacingInner,
|
spacingInner: chartDefaults.spacingInner,
|
||||||
spacingOuter,
|
spacingOuter: chartDefaults.spacingOuter,
|
||||||
barColors,
|
barColors: chartDefaults.barColors,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChartView>
|
<ChartView>
|
||||||
<View
|
<View
|
||||||
style={[graphStyles.rowContainer, { height: height }]}
|
style={[graphStyles.rowContainer, { height: chartDefaults.height }]}
|
||||||
testID={`chart-container-${testID}`}
|
testID={`chart-container-${testID}`}
|
||||||
>
|
>
|
||||||
<YAxis
|
<YAxis
|
||||||
data={yAxisLeftLabels.values}
|
data={yAxisLeftLabels.values}
|
||||||
contentInset={contentInset}
|
contentInset={chartDefaults.contentInset}
|
||||||
svg={graphStyles.yAxisFontStyle}
|
svg={graphStyles.yAxisFontStyle}
|
||||||
style={graphStyles.yAxisLeftPadding}
|
style={graphStyles.yAxisLeftPadding}
|
||||||
min={min}
|
min={chartDefaults.min}
|
||||||
max={maxLeftYAxisValue}
|
max={yAxisProps.maxLeftYAxisValue}
|
||||||
numberOfTicks={numberOfTicks}
|
numberOfTicks={chartDefaults.numberOfTicks}
|
||||||
formatLabel={formatLeftYAxisLabel}
|
formatLabel={yAxisProps.formatLeftYAxisLabel}
|
||||||
/>
|
/>
|
||||||
<View style={graphStyles.flex}>
|
<View style={graphStyles.flex}>
|
||||||
<ChartComponent {...chartComponentProps} />
|
<ChartComponent {...chartComponentProps} />
|
||||||
@ -87,23 +76,23 @@ const ChartContainer: React.FC<ChartContainerProps> = ({
|
|||||||
scale: scale.scaleBand,
|
scale: scale.scaleBand,
|
||||||
})}
|
})}
|
||||||
{...(ChartComponent.chartType === "line" && {
|
{...(ChartComponent.chartType === "line" && {
|
||||||
numberOfTicks: numberOfTicks,
|
numberOfTicks: chartDefaults.numberOfTicks,
|
||||||
contentInset: graphStyles.horizontalInset,
|
contentInset: graphStyles.horizontalInset,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<YAxis
|
<YAxis
|
||||||
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
|
data={yAxisRightLabels?.values ?? yAxisLeftLabels.values}
|
||||||
contentInset={contentInset}
|
contentInset={chartDefaults.contentInset}
|
||||||
svg={graphStyles.yAxisFontStyle}
|
svg={graphStyles.yAxisFontStyle}
|
||||||
style={[
|
style={[
|
||||||
graphStyles.yAxisRightPadding,
|
graphStyles.yAxisRightPadding,
|
||||||
{ height: useCommonScale ? 0 : "auto" },
|
{ height: useCommonScale ? 0 : "auto" },
|
||||||
]}
|
]}
|
||||||
min={min}
|
min={chartDefaults.min}
|
||||||
max={maxRightYAxisValue}
|
max={yAxisProps.maxRightYAxisValue}
|
||||||
numberOfTicks={numberOfTicks}
|
numberOfTicks={chartDefaults.numberOfTicks}
|
||||||
formatLabel={formatRightYAxisLabel}
|
formatLabel={yAxisProps.formatRightYAxisLabel}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</ChartView>
|
</ChartView>
|
||||||
|
@ -15,7 +15,7 @@ export interface YAxisData {
|
|||||||
|
|
||||||
export type XValue = string | number;
|
export type XValue = string | number;
|
||||||
|
|
||||||
export interface GraphData {
|
export interface XYValues {
|
||||||
xValues: Array<XValue>;
|
xValues: Array<XValue>;
|
||||||
yValues: Array<YAxisData>;
|
yValues: Array<YAxisData>;
|
||||||
}
|
}
|
||||||
@ -32,8 +32,15 @@ export interface YAxisProps {
|
|||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
formatLeftYAxisLabel?: (value: string) => string;
|
formatLeftYAxisLabel?: (value: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ScaledAndStyledYDataItem {
|
||||||
|
data: { value: number }[];
|
||||||
|
svg: { fill: string; stroke: string };
|
||||||
|
}
|
||||||
|
export type ScaledAndStyledYData = ScaledAndStyledYDataItem[];
|
||||||
|
|
||||||
export interface GraphProps {
|
export interface GraphProps {
|
||||||
data: GraphData;
|
data: XYValues;
|
||||||
includeColors?: boolean;
|
includeColors?: boolean;
|
||||||
height?: number;
|
height?: number;
|
||||||
spacingInner?: number;
|
spacingInner?: number;
|
||||||
@ -90,7 +97,7 @@ type ChartComponentWithStatic = React.ComponentType<CommonProps> & {
|
|||||||
*/
|
*/
|
||||||
export interface ChartContainerProps extends CommonProps {
|
export interface ChartContainerProps extends CommonProps {
|
||||||
ChartComponent: ChartComponentWithStatic;
|
ChartComponent: ChartComponentWithStatic;
|
||||||
data: GraphData;
|
data: XYValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,52 +1,115 @@
|
|||||||
import { GraphData } from "./graph-types";
|
import {
|
||||||
|
ScaledAndStyledYData,
|
||||||
|
XValue,
|
||||||
|
XYValues,
|
||||||
|
YAxisData,
|
||||||
|
YAxisProps,
|
||||||
|
} from "./graph-types";
|
||||||
|
|
||||||
export const convertToGraphData = (
|
interface PrepareGraphDataReturn {
|
||||||
graphData: GraphData,
|
yData: ScaledAndStyledYData;
|
||||||
options: {
|
yAxisLeftLabels: YAxisData;
|
||||||
selectedLeftYAxisLabel?: string;
|
yAxisRightLabels: YAxisData;
|
||||||
selectedRightYAxisLabel?: string;
|
xValues: XValue[];
|
||||||
maxRightYAxisValue: number;
|
}
|
||||||
maxLeftYAxisValue: number;
|
|
||||||
includeColors: boolean;
|
export const prepareGraphData = (
|
||||||
barColors: Array<string>;
|
xyData: XYValues,
|
||||||
},
|
yAxisProps: YAxisProps,
|
||||||
|
includeColors: boolean,
|
||||||
|
barColors: string[],
|
||||||
|
): PrepareGraphDataReturn => {
|
||||||
|
const { leftAxisIndex, rightAxisIndex } = findAxisIndices(
|
||||||
|
xyData.yValues,
|
||||||
|
yAxisProps.selectedLeftYAxisLabel,
|
||||||
|
yAxisProps.selectedRightYAxisLabel,
|
||||||
|
);
|
||||||
|
|
||||||
|
const yData = createYData(
|
||||||
|
xyData.yValues,
|
||||||
|
rightAxisIndex,
|
||||||
|
yAxisProps.maxRightYAxisValue,
|
||||||
|
yAxisProps.maxLeftYAxisValue,
|
||||||
|
includeColors,
|
||||||
|
barColors,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure yAxisLeftLabels and yAxisRightLabels are correctly defined
|
||||||
|
const yAxisLeftLabels =
|
||||||
|
leftAxisIndex >= 0
|
||||||
|
? xyData.yValues[leftAxisIndex]
|
||||||
|
: { key: "", values: [] };
|
||||||
|
const yAxisRightLabels =
|
||||||
|
rightAxisIndex >= 0
|
||||||
|
? xyData.yValues[rightAxisIndex]
|
||||||
|
: { key: "", values: [] };
|
||||||
|
|
||||||
|
return {
|
||||||
|
yData,
|
||||||
|
yAxisLeftLabels,
|
||||||
|
yAxisRightLabels,
|
||||||
|
xValues: xyData.xValues,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const scaleValues = (
|
||||||
|
yAxis,
|
||||||
|
index,
|
||||||
|
rightAxisIndex,
|
||||||
|
maxRightYAxisValue,
|
||||||
|
maxLeftYAxisValue,
|
||||||
) => {
|
) => {
|
||||||
const xValues = graphData.xValues;
|
const maxValue =
|
||||||
const leftAxisIndex = graphData.yValues.findIndex(
|
index === rightAxisIndex ? maxRightYAxisValue : maxLeftYAxisValue;
|
||||||
(y) => y.key === options.selectedLeftYAxisLabel,
|
return yAxis.values.map((value) => (value / maxValue) * 100);
|
||||||
);
|
};
|
||||||
const rightAxisIndex = graphData.yValues.findIndex(
|
|
||||||
(y) => y.key === options.selectedRightYAxisLabel,
|
|
||||||
);
|
|
||||||
|
|
||||||
// scale data points according to max value
|
const getStrokeColor = (index, includeColors, barColors) =>
|
||||||
const yData = graphData.yValues.map((yAxis, index) => {
|
includeColors ? barColors[index % barColors.length] : "transparent";
|
||||||
const maxValue =
|
|
||||||
index === rightAxisIndex
|
|
||||||
? options.maxRightYAxisValue
|
|
||||||
: options.maxLeftYAxisValue;
|
|
||||||
|
|
||||||
// scale values as a percentage of the max value
|
/**
|
||||||
const scaledValues = yAxis.values.map((value) => (value / maxValue) * 100);
|
* Finds the indices of the datasets in `yValues` that match the specified left and right Y-axis labels.
|
||||||
|
*
|
||||||
const strokeColor =
|
* Iterates through the `yValues` , searching for objects whose `key` matches
|
||||||
options.includeColors && options.barColors
|
* `selectedLeftYAxisLabel` and `selectedRightYAxisLabel`. It's used to identify which datasets
|
||||||
? options.barColors[index % options.barColors.length]
|
* should be plotted against the left and right Y-axes in a graph. If a match is not found for a label,
|
||||||
: "transparent";
|
* the corresponding axis index is set to `-1`.
|
||||||
|
*/
|
||||||
const mappedData = scaledValues.map((scaledValue) => ({
|
const findAxisIndices = (
|
||||||
value: scaledValue,
|
yValues: Array<{ key: string; values: Array<number> }>,
|
||||||
}));
|
selectedLeftYAxisLabel?: string,
|
||||||
|
selectedRightYAxisLabel?: string,
|
||||||
|
): { leftAxisIndex: number; rightAxisIndex: number } => ({
|
||||||
|
leftAxisIndex: yValues.findIndex((y) => y.key === selectedLeftYAxisLabel),
|
||||||
|
rightAxisIndex: yValues.findIndex((y) => y.key === selectedRightYAxisLabel),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms Y-axis data by scaling values and applying stroke colors for visualization.
|
||||||
|
*
|
||||||
|
* This function takes an array of Y-axis data objects, each with a key and an array of numeric values.
|
||||||
|
* It scales these values relative to specified maximum values for the left and right Y-axes and
|
||||||
|
* applies coloring based on the includeColors flag and the provided barColors array.
|
||||||
|
*/
|
||||||
|
const createYData = (
|
||||||
|
yValues: YAxisData[],
|
||||||
|
rightAxisIndex: number,
|
||||||
|
maxRightYAxisValue: number,
|
||||||
|
maxLeftYAxisValue: number,
|
||||||
|
includeColors: boolean,
|
||||||
|
barColors: string[],
|
||||||
|
): ScaledAndStyledYData =>
|
||||||
|
yValues.map((yAxis, index) => {
|
||||||
|
const scaledValues = scaleValues(
|
||||||
|
yAxis,
|
||||||
|
index,
|
||||||
|
rightAxisIndex,
|
||||||
|
maxRightYAxisValue,
|
||||||
|
maxLeftYAxisValue,
|
||||||
|
);
|
||||||
|
const strokeColor = getStrokeColor(index, includeColors, barColors);
|
||||||
return {
|
return {
|
||||||
data: mappedData,
|
data: scaledValues.map((value) => ({ value })),
|
||||||
svg: { fill: "transparent", stroke: strokeColor }, // Apply the stroke color here
|
svg: { fill: "transparent", stroke: strokeColor },
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const yAxisLeftLabels =
|
|
||||||
leftAxisIndex !== -1 ? graphData.yValues[leftAxisIndex] : null;
|
|
||||||
const yAxisRightLabels =
|
|
||||||
rightAxisIndex !== -1 ? graphData.yValues[rightAxisIndex] : undefined;
|
|
||||||
|
|
||||||
return { yData, yAxisLeftLabels, yAxisRightLabels, xValues };
|
|
||||||
};
|
|
||||||
|
@ -1,70 +1,89 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
|
||||||
import { chartDefaults } from "./graph-config";
|
import { chartDefaults } from "./graph-config";
|
||||||
import { GraphData, GraphProps, XValue, YAxisData } from "./graph-types";
|
import {
|
||||||
import { convertToGraphData } from "./graph-utils";
|
GraphProps,
|
||||||
|
ScaledAndStyledYData,
|
||||||
|
XValue,
|
||||||
|
XYValues,
|
||||||
|
YAxisData,
|
||||||
|
YAxisProps,
|
||||||
|
} from "./graph-types";
|
||||||
|
import { prepareGraphData } from "./graph-utils";
|
||||||
|
|
||||||
interface useGraphDataInterface {
|
export interface UseGraphDataReturn {
|
||||||
xValues: Array<XValue>;
|
xValues: Array<XValue>;
|
||||||
yData: {
|
yData: ScaledAndStyledYData;
|
||||||
data: {
|
|
||||||
value: number;
|
|
||||||
}[];
|
|
||||||
svg: {
|
|
||||||
fill: string;
|
|
||||||
};
|
|
||||||
}[];
|
|
||||||
yAxisLeftLabels: YAxisData;
|
yAxisLeftLabels: YAxisData;
|
||||||
yAxisRightLabels: YAxisData;
|
yAxisRightLabels: YAxisData;
|
||||||
defaultProps: Partial<GraphProps>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this version assumes string values for X, this isn't necessarily the case
|
|
||||||
// convertToGraphData is specifically tailored to bar/group bar graphs
|
|
||||||
// ultimately this component could be used by any x & y axis graph types (line/bar/scatter)
|
|
||||||
export const useGraphData = (
|
export const useGraphData = (
|
||||||
graphData: GraphData,
|
xyData: XYValues,
|
||||||
|
yAxisProps: YAxisProps,
|
||||||
props: Partial<GraphProps>,
|
props: Partial<GraphProps>,
|
||||||
): useGraphDataInterface => {
|
): UseGraphDataReturn => {
|
||||||
const { yAxisProps = {}, ...otherProps } = props;
|
const { yData, yAxisLeftLabels, yAxisRightLabels, xValues } = useMemo(() => {
|
||||||
const defaultProps = {
|
return prepareGraphData(
|
||||||
...chartDefaults,
|
xyData,
|
||||||
...otherProps,
|
yAxisProps,
|
||||||
// assign default values for yAxisProps + spread to override with values coming from props
|
chartDefaults.includeColors,
|
||||||
yAxisProps: {
|
chartDefaults.barColors,
|
||||||
maxLeftYAxisValue: Math.max(...(graphData.yValues[0]?.values ?? [0])),
|
);
|
||||||
maxRightYAxisValue:
|
}, [xyData]);
|
||||||
graphData.yValues.length > 1
|
|
||||||
? Math.max(...graphData.yValues[1]?.values)
|
|
||||||
: undefined,
|
|
||||||
formatRightYAxisLabel: yAxisProps.formatRightYAxisLabel,
|
|
||||||
formatLeftYAxisLabel: yAxisProps.formatLeftYAxisLabel,
|
|
||||||
selectedLeftYAxisLabel: graphData.yValues[0]?.key,
|
|
||||||
selectedRightYAxisLabel: graphData.yValues[1]?.key,
|
|
||||||
...yAxisProps,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const { yData, yAxisLeftLabels, yAxisRightLabels, xValues } = useMemo(
|
|
||||||
() =>
|
|
||||||
convertToGraphData(graphData, {
|
|
||||||
...defaultProps.yAxisProps,
|
|
||||||
includeColors: defaultProps.includeColors,
|
|
||||||
barColors: defaultProps.barColors,
|
|
||||||
}),
|
|
||||||
[
|
|
||||||
graphData,
|
|
||||||
defaultProps.yAxisProps,
|
|
||||||
defaultProps.includeColors,
|
|
||||||
defaultProps.barColors,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
xValues,
|
xValues,
|
||||||
yData,
|
yData,
|
||||||
yAxisLeftLabels,
|
yAxisLeftLabels,
|
||||||
yAxisRightLabels,
|
yAxisRightLabels,
|
||||||
defaultProps,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function computeAxisMaxValues(xyData: XYValues): {
|
||||||
|
maxLeft: number;
|
||||||
|
maxRight: number | undefined;
|
||||||
|
} {
|
||||||
|
const maxLeft = Math.max(...(xyData.yValues[0]?.values ?? [0]));
|
||||||
|
const maxRight =
|
||||||
|
xyData.yValues.length > 1
|
||||||
|
? Math.max(...(xyData.yValues[1]?.values ?? []))
|
||||||
|
: undefined;
|
||||||
|
return { maxLeft, maxRight };
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAxisLabels(xyData: XYValues): {
|
||||||
|
leftLabel: string;
|
||||||
|
rightLabel: string | undefined;
|
||||||
|
} {
|
||||||
|
const leftLabel = xyData.yValues[0]?.key;
|
||||||
|
const rightLabel =
|
||||||
|
xyData.yValues.length > 1 ? xyData.yValues[1]?.key : undefined;
|
||||||
|
return { leftLabel, rightLabel };
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyDefaultYAxisProps(
|
||||||
|
defaultProps: Partial<GraphProps["yAxisProps"]>,
|
||||||
|
): Partial<YAxisProps> {
|
||||||
|
return {
|
||||||
|
formatRightYAxisLabel: defaultProps.formatRightYAxisLabel,
|
||||||
|
formatLeftYAxisLabel: defaultProps.formatLeftYAxisLabel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function computeYAxisConfig(
|
||||||
|
xyData: XYValues,
|
||||||
|
yAxisPropsDefault: Partial<GraphProps["yAxisProps"]>,
|
||||||
|
): YAxisProps {
|
||||||
|
const { maxLeft, maxRight } = computeAxisMaxValues(xyData);
|
||||||
|
const { leftLabel, rightLabel } = selectAxisLabels(xyData);
|
||||||
|
const defaultYAxisProps = applyDefaultYAxisProps(yAxisPropsDefault);
|
||||||
|
|
||||||
|
return {
|
||||||
|
maxLeftYAxisValue: maxLeft,
|
||||||
|
maxRightYAxisValue: maxRight,
|
||||||
|
selectedLeftYAxisLabel: leftLabel,
|
||||||
|
selectedRightYAxisLabel: rightLabel,
|
||||||
|
...defaultYAxisProps,
|
||||||
|
...yAxisPropsDefault,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { StyleSheet, View } from "react-native";
|
import { StyleSheet, View } from "react-native";
|
||||||
import { line_chart_two_y_data } from "../../test/mock/charts/mock-data";
|
import {
|
||||||
|
graph_data_two_measures,
|
||||||
|
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 ChartContainer from "../component/charts/container/chart-container";
|
||||||
import LineGraph from "../component/charts/line-graph/line-graph";
|
import LineGraph from "../component/charts/line-graph/line-graph";
|
||||||
|
|
||||||
// Session Mock - can be used for session summary screen using a query handler component
|
|
||||||
// BarGraph component using mocked data currently
|
|
||||||
export default function SessionScreen() {
|
export default function SessionScreen() {
|
||||||
return (
|
return (
|
||||||
<View style={StyleSheet.absoluteFill}>
|
<View style={StyleSheet.absoluteFill}>
|
||||||
<ChartContainer data={line_chart_two_y_data} ChartComponent={LineGraph} />
|
<ChartContainer data={line_chart_two_y_data} ChartComponent={LineGraph} />
|
||||||
|
<ChartContainer
|
||||||
|
data={graph_data_two_measures}
|
||||||
|
ChartComponent={BarGraph}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import { renderHook } from "@testing-library/react-native";
|
import { renderHook } from "@testing-library/react-native";
|
||||||
import { GraphData, GraphProps } from "../../src/component/charts/graph-types";
|
import { GraphProps, XYValues } from "../../src/component/charts/graph-types";
|
||||||
import { useGraphData } from "../../src/component/charts/use-graph-data";
|
import {
|
||||||
|
computeYAxisConfig,
|
||||||
|
useGraphData,
|
||||||
|
} from "../../src/component/charts/use-graph-data";
|
||||||
|
|
||||||
describe("useGraphData", () => {
|
describe("useGraphData", () => {
|
||||||
it("should return correctly processed data from convertToGraphData", () => {
|
it("should return correctly processed data from convertToGraphData", () => {
|
||||||
// mock values
|
// mock values
|
||||||
const mockGraphData: GraphData = {
|
const mockGraphData: XYValues = {
|
||||||
xValues: ["full hit", "3/4 ball ball", "1/2 ball"],
|
xValues: ["full hit", "3/4 ball ball", "1/2 ball"],
|
||||||
yValues: [
|
yValues: [
|
||||||
{ key: "left", values: [10, 20, 30] },
|
{ key: "left", values: [10, 20, 30] },
|
||||||
@ -23,8 +26,14 @@ describe("useGraphData", () => {
|
|||||||
formatLeftYAxisLabel: (value) => `${value}%`,
|
formatLeftYAxisLabel: (value) => `${value}%`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const yAxisProps = computeYAxisConfig(
|
||||||
|
mockGraphData,
|
||||||
|
mockProps.yAxisProps || {},
|
||||||
|
);
|
||||||
|
|
||||||
const { result } = renderHook(() => useGraphData(mockGraphData, mockProps));
|
const { result } = renderHook(() =>
|
||||||
|
useGraphData(mockGraphData, yAxisProps, mockProps),
|
||||||
|
);
|
||||||
// values expected
|
// values expected
|
||||||
const expectedYData = [
|
const expectedYData = [
|
||||||
{
|
{
|
||||||
@ -55,12 +64,5 @@ describe("useGraphData", () => {
|
|||||||
});
|
});
|
||||||
expect(result.current.yAxisLeftLabels).toEqual(expectedLeftLabels);
|
expect(result.current.yAxisLeftLabels).toEqual(expectedLeftLabels);
|
||||||
expect(result.current.yAxisRightLabels).toEqual(expectedRightLabels);
|
expect(result.current.yAxisRightLabels).toEqual(expectedRightLabels);
|
||||||
expect(
|
|
||||||
result.current.defaultProps.yAxisProps.selectedLeftYAxisLabel,
|
|
||||||
).toEqual("left");
|
|
||||||
expect(
|
|
||||||
result.current.defaultProps.yAxisProps.selectedRightYAxisLabel,
|
|
||||||
).toEqual("right");
|
|
||||||
expect(result.current.defaultProps).toBeDefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user