Skip to content

Commit

Permalink
feat: integrate axis labels
Browse files Browse the repository at this point in the history
  • Loading branch information
e-younan committed Mar 4, 2024
1 parent a8fd0a9 commit 3ac649a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 19 deletions.
21 changes: 18 additions & 3 deletions example/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LineChart } from "@codeherence/react-native-graph";
import { type AxisLabelComponentProps, LineChart } from "@codeherence/react-native-graph";
import { useCallback, useState } from "react";
import { Button, StyleSheet, View } from "react-native";
import { Button, StyleSheet, Text, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";

import { Banner } from "../components/Banner";
Expand All @@ -9,6 +9,15 @@ const generateRandomData = (): [number, number][] => {
return Array.from({ length: 100 }, (_, i) => [i, Math.random() * 2000]);
};

const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
});

const AxisLabel: React.FC<AxisLabelComponentProps> = ({ value }) => (
<Text>{formatter.format(value)}</Text>
);

export default () => {
const { top, bottom } = useSafeAreaInsets();
const [data, setData] = useState<[number, number][]>(generateRandomData());
Expand All @@ -20,7 +29,13 @@ export default () => {
return (
<View style={[styles.container, { paddingTop: top, paddingBottom: bottom }]}>
<Button title="Randomize data" onPress={handlePress} />
<LineChart points={data} style={styles.chart} BannerComponent={Banner} />
<LineChart
points={data}
style={styles.chart}
BannerComponent={Banner}
TopAxisLabel={AxisLabel}
BottomAxisLabel={AxisLabel}
/>
</View>
);
};
Expand Down
31 changes: 15 additions & 16 deletions src/components/LineChart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Canvas, Path } from "@shopify/react-native-skia";
import { useCallback, useMemo, useState } from "react";
import { LayoutChangeEvent, Platform, StyleSheet, Text, View, ViewProps } from "react-native";
import { LayoutChangeEvent, Platform, StyleSheet, View, ViewProps } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import { useDerivedValue, useSharedValue } from "react-native-reanimated";

import { AxisLabelContainer } from "./AxisLabel";
import { AxisLabelComponentProps, AxisLabelContainer } from "./AxisLabel";
import type { BannerComponentProps } from "./Banner";
import { Cursor } from "./Cursor";
import { computePath, getYForX, type ComputePathProps, computeGraphData } from "./Math";
Expand All @@ -24,15 +24,10 @@ export type LineChartProps = ViewProps & {
/** A worklet function to format a given price. */
formatter?: (price: number) => string;
BannerComponent?: React.FC<BannerComponentProps>;
TopAxisLabel?: React.FC;
BottomAxisLabel?: React.FC;
TopAxisLabel?: React.FC<AxisLabelComponentProps>;
BottomAxisLabel?: React.FC<AxisLabelComponentProps>;
};

const currencyFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
});

const GestureMethod = Platform.OS === "web" ? Gesture.Hover : Gesture.Pan;

export const LineChart: React.FC<LineChartProps> = ({
Expand Down Expand Up @@ -77,9 +72,11 @@ export const LineChart: React.FC<LineChartProps> = ({

return (
<View style={[styles.root, viewProps.style]} {...viewProps}>
<AxisLabelContainer x={data.maxValueXProportion * width} containerWidth={width}>
<Text style={{ fontSize: 12 }}>{currencyFormatter.format(data.maxValue)}</Text>
</AxisLabelContainer>
{TopAxisLabel && (
<AxisLabelContainer x={data.maxValueXProportion * width} containerWidth={width}>
<TopAxisLabel value={data.maxValue} />
</AxisLabelContainer>
)}
<GestureDetector gesture={gesture}>
<View style={styles.container} onLayout={onLayout}>
<Canvas style={{ height, width }}>
Expand All @@ -88,15 +85,17 @@ export const LineChart: React.FC<LineChartProps> = ({
</Canvas>
</View>
</GestureDetector>
<AxisLabelContainer x={data.minValueXProportion * width} containerWidth={width}>
<Text style={{ fontSize: 12 }}>{currencyFormatter.format(data.minValue)}</Text>
</AxisLabelContainer>
{BottomAxisLabel && (
<AxisLabelContainer x={data.minValueXProportion * width} containerWidth={width}>
<BottomAxisLabel value={data.minValue} />
</AxisLabelContainer>
)}
</View>
);
};

const styles = StyleSheet.create({
root: { position: "relative" },
root: { position: "relative", overflow: "hidden" },
container: { flex: 1 },
canvas: { flex: 1 },
});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { LineChart } from "./components/SkiaComponents";
export { type BannerComponentProps } from "./components/LineChart/Banner";
export { type AxisLabelComponentProps } from "./components/LineChart/AxisLabel";

0 comments on commit 3ac649a

Please sign in to comment.