From 6e077a57363b67b8fe74270d44baa772cd50e6af Mon Sep 17 00:00:00 2001 From: Petr Knetl Date: Fri, 14 Jul 2023 15:20:52 +0200 Subject: [PATCH 1/2] feat: graph events Support for graph events added. --- README.md | 27 +++++ example/src/data/GraphData.ts | 26 ++++- example/src/screens/GraphPage.tsx | 20 +++- img/events.png | Bin 0 -> 72853 bytes src/AnimatedLineGraph.tsx | 62 ++++++++++- src/DefaultGraphEvent.tsx | 48 +++++++++ src/LineGraph.tsx | 11 +- src/LineGraphProps.ts | 165 ++++++++++++++++++++---------- src/hooks/useEventTooltipProps.ts | 42 ++++++++ 9 files changed, 333 insertions(+), 68 deletions(-) create mode 100644 img/events.png create mode 100644 src/DefaultGraphEvent.tsx create mode 100644 src/hooks/useEventTooltipProps.ts diff --git a/README.md b/README.md index 0f702f7..fec9b30 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,34 @@ Example: ``` See this [example `` component](./example/src/components/CustomSelectionDot.tsx). +### `events` + An array of events to be marked in the graph. The position is calculated based on the `date` property of each event relatively to `points` of the graph. +### `EventComponent` + A component that is used to render an event. + +### `EventTooltipComponent` + An additional event component that is rendered if the `SelectionDot` overlaps an `Event`. + +### `onEventHover` + Callback called when an `Event` is hovered on. + +> Events related props require `animated` and `enablePanGesture` to be `true`. + +Example: + + + +```jsx + +``` ## Sponsor diff --git a/example/src/data/GraphData.ts b/example/src/data/GraphData.ts index f0c3fd8..7ac11c1 100644 --- a/example/src/data/GraphData.ts +++ b/example/src/data/GraphData.ts @@ -1,4 +1,4 @@ -import type { GraphPoint } from '../../../src/LineGraphProps' +import type { GraphEvent, GraphPoint } from '../../../src/LineGraphProps' import gaussian from 'gaussian' function weightedRandom(mean: number, variance: number): number { @@ -7,7 +7,7 @@ function weightedRandom(mean: number, variance: number): number { return distribution.ppf(Math.random()) } -export function generateRandomGraphData(length: number): GraphPoint[] { +export function generateRandomGraphPoints(length: number): GraphPoint[] { return Array(length) .fill(0) .map((_, index) => ({ @@ -18,6 +18,28 @@ export function generateRandomGraphData(length: number): GraphPoint[] { })) } +export function generateRandomGraphEvents( + length: number, + points: GraphPoint[] +): GraphEvent[] { + const firstPointTimestamp = points[0]?.date.getTime() + const lastPointTimestamp = points[points.length - 1]?.date.getTime() + + if (!firstPointTimestamp || !lastPointTimestamp) { + return [] + } + return Array(length) + .fill(0) + .map((_) => ({ + date: new Date( // Get a random date between the two defined timestamps. + Math.floor( + Math.random() * (lastPointTimestamp - firstPointTimestamp + 1) + ) + firstPointTimestamp + ), + payload: {}, + })) +} + export function generateSinusGraphData(length: number): GraphPoint[] { return Array(length) .fill(0) diff --git a/example/src/screens/GraphPage.tsx b/example/src/screens/GraphPage.tsx index 8dbfd9b..09bd69f 100644 --- a/example/src/screens/GraphPage.tsx +++ b/example/src/screens/GraphPage.tsx @@ -6,14 +6,17 @@ import type { GraphRange } from '../../../src/LineGraphProps' import { SelectionDot } from '../components/CustomSelectionDot' import { Toggle } from '../components/Toggle' import { - generateRandomGraphData, + generateRandomGraphEvents, + generateRandomGraphPoints, generateSinusGraphData, } from '../data/GraphData' import { useColors } from '../hooks/useColors' import { hapticFeedback } from '../utils/HapticFeedback' const POINT_COUNT = 70 -const POINTS = generateRandomGraphData(POINT_COUNT) +const POINTS = generateRandomGraphPoints(POINT_COUNT) +const EVENT_COUNT = 10 +const EVENTS = generateRandomGraphEvents(EVENT_COUNT, POINTS) const COLOR = '#6a7ee7' const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00'] const SMALL_POINTS = generateSinusGraphData(9) @@ -30,11 +33,16 @@ export function GraphPage() { const [enableRange, setEnableRange] = useState(false) const [enableIndicator, setEnableIndicator] = useState(false) const [indicatorPulsating, setIndicatorPulsating] = useState(false) + const [enableEvents, setEnableEvents] = useState(false) const [points, setPoints] = useState(POINTS) + const [events, setEvents] = useState(EVENTS) const refreshData = useCallback(() => { - setPoints(generateRandomGraphData(POINT_COUNT)) + const freshPoints = generateRandomGraphPoints(POINT_COUNT) + const freshEvents = generateRandomGraphEvents(EVENT_COUNT, freshPoints) + setPoints(freshPoints) + setEvents(freshEvents) hapticFeedback('impactLight') }, []) @@ -100,6 +108,7 @@ export function GraphPage() { enableIndicator={enableIndicator} horizontalPadding={enableIndicator ? 15 : 0} indicatorPulsating={indicatorPulsating} + events={enableEvents ? events : []} />