Skip to content

Commit 88da23b

Browse files
committed
chore: Cleanup example app by moving mock data
1 parent 2803c22 commit 88da23b

6 files changed

Lines changed: 204 additions & 144 deletions

File tree

example/src/App.tsx

Lines changed: 28 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { useMemo, useState } from 'react'
22
import { View, StyleSheet, TouchableOpacity, Text, Switch } from 'react-native'
33

4-
import Chart, { ChartProps, Dataset, Point } from 'react-native-d3-chart'
4+
import Chart, { ChartProps, Dataset } from 'react-native-d3-chart'
55

6-
import { generateRandomPulses } from './helpers/generateRandomPulses'
6+
import { buildSlices } from './helpers/buildSlices'
7+
import { generateTimeSeriesData } from './helpers/generateTimeSeriesData'
8+
import { temperatureData, visits } from './mockData'
79

810
type TimeDomainType = 'hour' | 'day' | 'week' | 'month'
911

@@ -18,62 +20,20 @@ const chartColors: ChartProps['colors'] = {
1820
highlightTime: '#444',
1921
}
2022

21-
// Generate data points every minute from a month ago to now
22-
const generateDataPoints = ({
23-
startingValue = 400,
24-
minimum = 0,
25-
maximum = 3000,
26-
radomFactor = 20,
27-
} = {}) => {
28-
const points = []
29-
const now = Date.now()
30-
const monthAgo = now - 30 * 24 * 60 * 60 * 1000 // 30 days ago
31-
let value = startingValue
32-
33-
for (let timestamp = monthAgo; timestamp <= now; timestamp += 60 * 1000) {
34-
const randomVariation = (Math.random() - 0.5) * radomFactor
35-
value += randomVariation
36-
37-
// either randomVariation was negative and value went below minimum
38-
// or randomVariation was positive and value went above maximum
39-
if (value < minimum || value > maximum) {
40-
// invert direction to keep within bounds
41-
value -= 2 * randomVariation
42-
}
43-
44-
points.push({ timestamp, value })
45-
}
46-
47-
return points
48-
}
49-
5023
enum Measurement {
5124
Temperature = 'Temperature',
5225
Blue = 'Blue',
5326
Green = 'Green',
5427
Pink = 'Pink',
55-
Pulses = 'Pulses',
56-
PulseRate = 'Pulse Rate',
28+
Visits = 'Visits',
29+
VisitRate = 'Visit Rate',
5730
}
5831

59-
const averagePulseRatePerHour = 120
60-
const pulsePoints = generateRandomPulses({
61-
maxAgeDays: 60,
62-
burstFactor: 10,
63-
burstProbability: 0.05,
64-
averageRatePerHour: averagePulseRatePerHour,
65-
})
66-
6732
const measurementKeys = Object.values(Measurement)
6833
const measurementsRecords: Record<Measurement, Dataset> = {
6934
[Measurement.Temperature]: {
7035
unit: '°C',
71-
points: generateDataPoints({
72-
maximum: 40,
73-
minimum: -10,
74-
radomFactor: 1,
75-
startingValue: -8,
76-
}),
36+
points: temperatureData,
7737
decimals: 0,
7838
areaColor: '#c4deff',
7939
color: {
@@ -92,7 +52,7 @@ const measurementsRecords: Record<Measurement, Dataset> = {
9252
},
9353
[Measurement.Blue]: {
9454
unit: 'l',
95-
points: generateDataPoints({
55+
points: generateTimeSeriesData({
9656
startingValue: 160,
9757
minimum: 50,
9858
radomFactor: 6,
@@ -103,14 +63,14 @@ const measurementsRecords: Record<Measurement, Dataset> = {
10363
},
10464
[Measurement.Green]: {
10565
unit: 'kg',
106-
points: generateDataPoints(),
66+
points: generateTimeSeriesData(),
10767
decimals: 0,
10868
color: '#6e6',
10969
measurementName: Measurement.Green,
11070
},
11171
[Measurement.Pink]: {
11272
unit: 'm/s',
113-
points: generateDataPoints({
73+
points: generateTimeSeriesData({
11474
startingValue: 20,
11575
minimum: 100,
11676
}),
@@ -119,108 +79,33 @@ const measurementsRecords: Record<Measurement, Dataset> = {
11979
measurementName: Measurement.Pink,
12080
},
12181

122-
[Measurement.PulseRate]: {
123-
unit: 'pulses/h',
124-
points: pulsePoints.map(({ timestamp }, index, array) => {
125-
const slice = [...array.slice(Math.max(0, index - 60 + 1), index + 1)] // this and previous 59 minutes
126-
const hourSum = slice.reduce((sum, point) => sum + (point.value || 0), 0)
127-
128-
return {
129-
timestamp,
130-
value: hourSum,
131-
}
82+
[Measurement.VisitRate]: {
83+
unit: 'visits/h',
84+
points: visits.movingAveregeData,
85+
slices: buildSlices('horizontal', {
86+
end: visits.latestTimestamp,
87+
start: visits.oldestTimestamp,
88+
yellowThreshold: visits.averageVisitRatePerHour,
89+
redThreshold: visits.averageVisitRatePerHour * 1.1,
13290
}),
133-
slices: {
134-
start: pulsePoints[0]?.timestamp ?? 0,
135-
end: pulsePoints[pulsePoints.length - 1]?.timestamp ?? 0,
136-
items: [
137-
{
138-
color: '#08985115',
139-
start: { bottom: 0, top: averagePulseRatePerHour },
140-
end: { bottom: 0, top: averagePulseRatePerHour },
141-
},
142-
{
143-
color: '#ffc40015',
144-
start: {
145-
bottom: averagePulseRatePerHour,
146-
top: averagePulseRatePerHour * 1.1,
147-
},
148-
end: {
149-
bottom: averagePulseRatePerHour,
150-
top: averagePulseRatePerHour * 1.1,
151-
},
152-
},
153-
{
154-
color: '#bb222215',
155-
start: {
156-
bottom: averagePulseRatePerHour * 1.1,
157-
top: averagePulseRatePerHour * 10,
158-
},
159-
end: {
160-
bottom: averagePulseRatePerHour * 1.1,
161-
top: averagePulseRatePerHour * 10,
162-
},
163-
},
164-
],
165-
},
16691
decimals: 0,
16792
color: '#000',
16893
areaColor: null,
169-
measurementName: Measurement.PulseRate,
94+
measurementName: Measurement.VisitRate,
17095
},
171-
[Measurement.Pulses]: {
96+
[Measurement.Visits]: {
17297
unit: 'pulses',
173-
points: pulsePoints.reduce(
174-
({ array, sum }, { timestamp, value }) => {
175-
const newSum = sum + (value || 0)
176-
array.push({ timestamp, value: newSum })
177-
return {
178-
array,
179-
sum: newSum,
180-
}
181-
},
182-
{ array: [] as Point[], sum: 0 }
183-
).array,
98+
points: visits.culmulativeData,
18499
decimals: 0,
185100
color: '#000',
186101
areaColor: null,
187-
measurementName: 'Pulses cumulative',
188-
slices: (() => {
189-
const start = pulsePoints[0]?.timestamp ?? 0
190-
const end = pulsePoints[pulsePoints.length - 1]?.timestamp ?? 0
191-
const dataDurationMs = end - start
192-
const dataDurationHours = dataDurationMs / (60 * 60 * 1000)
193-
194-
const warningRate = averagePulseRatePerHour
195-
const dangerRate = warningRate * 1.1
196-
197-
const warningEnd = dataDurationHours * warningRate
198-
const dangerEnd = dataDurationHours * dangerRate
199-
200-
const topEdge = dangerRate * 2 * dataDurationHours
201-
202-
return {
203-
end,
204-
start,
205-
items: [
206-
{
207-
color: '#08985115',
208-
start: { bottom: 0, top: 0 },
209-
end: { bottom: 0, top: warningEnd },
210-
},
211-
{
212-
color: '#ffc40015',
213-
start: { bottom: 0, top: 0 },
214-
end: { bottom: warningEnd, top: dangerEnd },
215-
},
216-
{
217-
color: '#bb222215',
218-
start: { bottom: 0, top: topEdge },
219-
end: { bottom: dangerEnd, top: topEdge },
220-
},
221-
],
222-
}
223-
})(),
102+
measurementName: 'Visits cumulative',
103+
slices: buildSlices('axial', {
104+
end: visits.latestTimestamp,
105+
start: visits.oldestTimestamp,
106+
yellowThreshold: visits.averageVisitRatePerHour,
107+
redThreshold: visits.averageVisitRatePerHour * 1.1,
108+
}),
224109
},
225110
}
226111

example/src/helpers/buildSlices.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import type { Slices } from '../../../src/types'
2+
3+
export function buildSlices(
4+
variant: 'horizontal' | 'axial',
5+
{
6+
end,
7+
start,
8+
redThreshold,
9+
yellowThreshold,
10+
}: {
11+
end: number
12+
start: number
13+
redThreshold: number
14+
yellowThreshold: number
15+
}
16+
): Slices {
17+
if (variant === 'horizontal') {
18+
return {
19+
end,
20+
start,
21+
items: [
22+
{
23+
color: '#08985115',
24+
start: { bottom: 0, top: yellowThreshold },
25+
end: { bottom: 0, top: yellowThreshold },
26+
},
27+
{
28+
color: '#ffc40015',
29+
start: {
30+
bottom: yellowThreshold,
31+
top: redThreshold,
32+
},
33+
end: {
34+
bottom: yellowThreshold,
35+
top: redThreshold,
36+
},
37+
},
38+
{
39+
color: '#bb222215',
40+
start: {
41+
bottom: redThreshold,
42+
top: redThreshold * 10,
43+
},
44+
end: {
45+
bottom: redThreshold,
46+
top: redThreshold * 10,
47+
},
48+
},
49+
],
50+
}
51+
}
52+
53+
const dataDurationMs = end - start
54+
const dataDurationHours = dataDurationMs / (60 * 60 * 1000)
55+
56+
const warningEnd = dataDurationHours * yellowThreshold
57+
const dangerEnd = dataDurationHours * redThreshold
58+
59+
const topEdge = redThreshold * 2 * dataDurationHours
60+
61+
return {
62+
end,
63+
start,
64+
items: [
65+
{
66+
color: '#08985115',
67+
start: { bottom: 0, top: 0 },
68+
end: { bottom: 0, top: warningEnd },
69+
},
70+
{
71+
color: '#ffc40015',
72+
start: { bottom: 0, top: 0 },
73+
end: { bottom: warningEnd, top: dangerEnd },
74+
},
75+
{
76+
color: '#bb222215',
77+
start: { bottom: 0, top: topEdge },
78+
end: { bottom: dangerEnd, top: topEdge },
79+
},
80+
],
81+
}
82+
}

example/src/helpers/generateRandomPulses.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/**
2+
* Generates random pulse data points over a specified time range.
3+
* @param maxAgeDays - The maximum age of the data points in days.
4+
* @param intervalMs - Time interval in milliseconds between consecutive data points. Default is 60,000 ms (1 minute).
5+
* @param averageRatePerHour - Average number of pulses per hour. Default is 120.
6+
* @param burstFactor - Factor by which the pulse rate increases during bursts. Default is 3.
7+
* @param burstProbability - Probability of a burst occurring at each interval. Default is 0.1.
8+
* @returns An array of random pulse data points.
9+
*/
110
export function generateRandomPulses({
211
maxAgeDays = 30,
312
intervalMs = 60 * 1000,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Generates time series data points, each point deviating slightly from the previous one.
3+
* @param startingValue Initial value for the first data point. Default is 400.
4+
* @param minimum Minimum value for the data points. Default is 0.
5+
* @param maximum Maximum value for the data points. Default is 3000.
6+
* @param maxAgeDays Number of days in the past to start generating data from. Default is 30 days.
7+
* @param intervalMs Time interval in milliseconds between consecutive data points. Default is 60,000 ms (1 minute).
8+
* @param radomFactor Maximum random variation applied to each point. Default is 20.
9+
* @returns Array of data points with timestamps and values.
10+
*/
11+
export function generateTimeSeriesData({
12+
startingValue = 400,
13+
minimum = 0,
14+
maximum = 3000,
15+
maxAgeDays = 30,
16+
intervalMs = 60 * 1000,
17+
radomFactor = 20,
18+
} = {}) {
19+
const points = []
20+
const now = Date.now()
21+
const monthAgo = now - maxAgeDays * 24 * 60 * 60 * 1000
22+
let value = startingValue
23+
24+
for (let timestamp = monthAgo; timestamp <= now; timestamp += intervalMs) {
25+
const randomVariation = (Math.random() - 0.5) * radomFactor
26+
value += randomVariation
27+
28+
// either randomVariation was negative and value went below minimum
29+
// or randomVariation was positive and value went above maximum
30+
if (value < minimum || value > maximum) {
31+
// invert direction to keep within bounds
32+
value -= 2 * randomVariation
33+
}
34+
35+
points.push({ timestamp, value })
36+
}
37+
38+
return points
39+
}

0 commit comments

Comments
 (0)