Use new chart library in ViewGraph
This commit is contained in:
parent
f28406b4c4
commit
1c10e0f632
102
Chart.tsx
102
Chart.tsx
|
@ -1,69 +1,55 @@
|
|||
import { useTheme } from "@react-navigation/native";
|
||||
import * as shape from "d3-shape";
|
||||
import { View } from "react-native";
|
||||
import { Grid, LineChart, XAxis, YAxis } from "react-native-svg-charts";
|
||||
import { CombinedDarkTheme, CombinedDefaultTheme } from "./App";
|
||||
import { MARGIN, PADDING } from "./constants";
|
||||
import { useMemo } from "react";
|
||||
import { useWindowDimensions } from "react-native";
|
||||
import { LineChart } from "react-native-chart-kit";
|
||||
import { AbstractChartConfig } from "react-native-chart-kit/dist/AbstractChart";
|
||||
import { PADDING } from "./constants";
|
||||
import useDark from "./use-dark";
|
||||
import { useTheme } from "react-native-paper";
|
||||
|
||||
export default function Chart({
|
||||
yData,
|
||||
xFormat,
|
||||
xData,
|
||||
yFormat,
|
||||
}: {
|
||||
yData: number[];
|
||||
xData: unknown[];
|
||||
xFormat: (value: any, index: number) => string;
|
||||
yFormat: (value: any) => string;
|
||||
}) {
|
||||
interface ChartProps {
|
||||
labels: string[];
|
||||
data: number[];
|
||||
preserve?: number;
|
||||
}
|
||||
|
||||
export default function Chart({ labels, data, preserve = 3 }: ChartProps) {
|
||||
const { width } = useWindowDimensions();
|
||||
const { colors } = useTheme();
|
||||
const dark = useDark();
|
||||
const axesSvg = {
|
||||
fontSize: 10,
|
||||
fill: dark
|
||||
? CombinedDarkTheme.colors.text
|
||||
: CombinedDefaultTheme.colors.text,
|
||||
|
||||
const config: AbstractChartConfig = {
|
||||
backgroundGradientFrom: colors.background,
|
||||
backgroundGradientTo: colors.elevation.level1,
|
||||
color: () => colors.primary,
|
||||
};
|
||||
const verticalContentInset = { top: 10, bottom: 10 };
|
||||
const xAxisHeight = 30;
|
||||
|
||||
const pruned = useMemo(() => {
|
||||
const newPruned = [...labels];
|
||||
if (labels.length <= preserve + 2) return labels;
|
||||
|
||||
let interval = Math.floor((labels.length - 2) / (preserve + 1));
|
||||
for (let i = 1; i < labels.length - 1; i++) {
|
||||
if ((i - 1) % interval !== 0 || i === 1) {
|
||||
newPruned[i] = "";
|
||||
}
|
||||
}
|
||||
return newPruned;
|
||||
}, [labels, preserve]);
|
||||
|
||||
console.log({ labels, data, pruned, preserve });
|
||||
|
||||
return (
|
||||
<>
|
||||
<View
|
||||
style={{
|
||||
height: 300,
|
||||
padding: PADDING,
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<YAxis
|
||||
data={yData}
|
||||
style={{ marginBottom: xAxisHeight }}
|
||||
contentInset={verticalContentInset}
|
||||
svg={axesSvg}
|
||||
formatLabel={yFormat}
|
||||
/>
|
||||
<View style={{ flex: 1, marginLeft: MARGIN }}>
|
||||
<LineChart
|
||||
style={{ flex: 1 }}
|
||||
data={yData}
|
||||
contentInset={verticalContentInset}
|
||||
curve={shape.curveBasis}
|
||||
svg={{
|
||||
stroke: colors.primary,
|
||||
height={400}
|
||||
width={width - 20}
|
||||
data={{
|
||||
labels: pruned,
|
||||
datasets: [
|
||||
{
|
||||
data,
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
<Grid />
|
||||
</LineChart>
|
||||
<XAxis
|
||||
data={xData}
|
||||
formatLabel={xFormat}
|
||||
contentInset={{ left: 15, right: 16 }}
|
||||
svg={axesSvg}
|
||||
chartConfig={config}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { RouteProp, useRoute } from "@react-navigation/native";
|
||||
import { format } from "date-fns";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { FileSystem } from "react-native-file-access";
|
||||
|
@ -16,6 +15,7 @@ import GymSet from "./gym-set";
|
|||
import { Metrics } from "./metrics";
|
||||
import { Periods } from "./periods";
|
||||
import Volume from "./volume";
|
||||
import { format } from "date-fns";
|
||||
|
||||
export default function ViewGraph() {
|
||||
const { params } = useRoute<RouteProp<GraphsPageParams, "ViewGraph">>();
|
||||
|
@ -70,41 +70,38 @@ export default function ViewGraph() {
|
|||
}, [params.name, metric, period]);
|
||||
|
||||
const charts = useMemo(() => {
|
||||
if (
|
||||
(metric === Metrics.Volume && volumes?.length === 0) ||
|
||||
(metric === Metrics.Best && weights?.length === 0) ||
|
||||
(metric === Metrics.OneRepMax && weights?.length === 0)
|
||||
) {
|
||||
return <List.Item title="No data yet." />;
|
||||
}
|
||||
if (metric === Metrics.Volume && volumes?.length && weights?.length) {
|
||||
return (
|
||||
<Chart
|
||||
yData={volumes.map((v) => v.value)}
|
||||
yFormat={(value: number) =>
|
||||
`${value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}${
|
||||
volumes[0].unit || "kg"
|
||||
}`
|
||||
}
|
||||
xData={weights}
|
||||
xFormat={(_value, index) =>
|
||||
format(new Date(weights[index].created), "d/M")
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
let periodFormat = "do";
|
||||
if (period === Periods.Weekly) periodFormat = "iii";
|
||||
else if (period === Periods.Yearly) periodFormat = "P";
|
||||
let preserve = 3;
|
||||
if (period === Periods.Yearly) preserve = 1;
|
||||
|
||||
if (metric === Metrics.Volume && Number(volumes?.length) > 0)
|
||||
return (
|
||||
<Chart
|
||||
yData={weights?.map((set) => set.weight) || []}
|
||||
yFormat={(value) => `${value}${weights?.[0].unit}`}
|
||||
xData={weights || []}
|
||||
xFormat={(_value, index) =>
|
||||
format(new Date(weights?.[index].created), "d/M")
|
||||
}
|
||||
data={volumes.map((volume) => volume.value)}
|
||||
labels={volumes.map((volume) =>
|
||||
format(new Date(volume.created), periodFormat)
|
||||
)}
|
||||
preserve={preserve}
|
||||
/>
|
||||
);
|
||||
}, [volumes, weights, metric]);
|
||||
if (
|
||||
(metric === Metrics.Best || metric === Metrics.OneRepMax) &&
|
||||
Number(weights?.length) > 0
|
||||
)
|
||||
return (
|
||||
<Chart
|
||||
data={weights.map((set) => set.weight)}
|
||||
labels={weights.map((set) =>
|
||||
format(new Date(set.created), periodFormat)
|
||||
)}
|
||||
preserve={preserve}
|
||||
/>
|
||||
);
|
||||
|
||||
return <List.Item title="No data yet." />;
|
||||
}, [volumes, weights, metric, period]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -144,7 +141,9 @@ export default function ViewGraph() {
|
|||
onChange={(value) => setPeriod(value as Periods)}
|
||||
value={period}
|
||||
/>
|
||||
{charts}
|
||||
<View style={{ paddingTop: PADDING }}>
|
||||
{(weights || volumes) && charts}
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue
Block a user