Skip to content

Commit 143e3ce

Browse files
committed
feat: Support threshold gradients
1 parent b3bdab1 commit 143e3ce

File tree

4 files changed

+204
-53
lines changed

4 files changed

+204
-53
lines changed

README.md

Lines changed: 91 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ yarn add react-native-webview
3737
## Quick Start
3838

3939
```tsx
40-
import React, { useState, useMemo } from 'react';
41-
import { View } from 'react-native';
42-
import Chart from 'react-native-d3-chart';
40+
import React, { useState, useMemo } from 'react'
41+
import { View } from 'react-native'
42+
import Chart from 'react-native-d3-chart'
4343

4444
export default function App() {
45-
const [width, setWidth] = useState(0);
46-
const height = width * 0.6; // 16:10 aspect ratio
45+
const [width, setWidth] = useState(0)
46+
const height = width * 0.6 // 16:10 aspect ratio
4747

4848
// Generate some sample data
4949
const datasets = useMemo(
@@ -61,7 +61,7 @@ export default function App() {
6161
},
6262
],
6363
[]
64-
);
64+
)
6565

6666
const timeDomain = useMemo(
6767
() => ({
@@ -70,7 +70,7 @@ export default function App() {
7070
end: Date.now(),
7171
}),
7272
[]
73-
);
73+
)
7474

7575
const colors = {
7676
background: '#fff',
@@ -79,7 +79,7 @@ export default function App() {
7979
cursorStroke: '#0ff',
8080
highlightLabel: '#000',
8181
highlightTime: '#444',
82-
};
82+
}
8383

8484
return (
8585
<View
@@ -95,7 +95,7 @@ export default function App() {
9595
noDataString="No data available"
9696
/>
9797
</View>
98-
);
98+
)
9999
}
100100
```
101101

@@ -126,62 +126,74 @@ export default function App() {
126126

127127
```typescript
128128
type Dataset = {
129-
measurementName: string; // Display name for this data series
130-
color: string; // Hex color for the line and labels
131-
points: Point[]; // Array of data points
132-
unit: string; // Unit symbol (e.g., '°C', 'kg', 'm/s')
133-
decimals: number; // Number of decimal places to show
134-
minDeltaY?: number; // Minimum Y-axis change to show, limit Y-zoom
135-
decimalSeparator?: '.' | ','; // Decimal separator
129+
measurementName: string // Display name for this data series
130+
color: string | ThresholdColor // Hex color for the line, or threshold-based coloring
131+
points: Point[] // Array of data points
132+
unit: string // Unit symbol (e.g., '°C', 'kg', 'm/s')
133+
decimals: number // Number of decimal places to show
134+
minDeltaY?: number // Minimum Y-axis change to show, limit Y-zoom
135+
areaColor?: string // Optional area fill color (defaults to base color)
136+
axisColor?: string // Optional Y-axis text color (defaults to base color)
137+
decimalSeparator?: '.' | ',' // Decimal separator
136138
domain?: {
137139
// Custom Y-axis range
138-
bottom: number;
139-
top: number;
140-
};
141-
};
140+
bottom: number
141+
top: number
142+
}
143+
}
144+
145+
type ThresholdColor = {
146+
type: 'thresholds'
147+
baseColor: string // Default color for values below all thresholds
148+
gradientBlur: number // Gradient transition distance around thresholds
149+
thresholds: Array<{
150+
value: number // Threshold value
151+
color: string // Color to use above this value
152+
}> // Should be sorted by value descending
153+
}
142154
```
143155
144156
#### Point
145157
146158
```typescript
147159
type Point = {
148-
timestamp: number; // Unix timestamp in milliseconds
149-
value: number | null; // Data value (null for gaps)
150-
};
160+
timestamp: number // Unix timestamp in milliseconds
161+
value: number | null // Data value (null for gaps)
162+
}
151163
```
152164
153165
#### TimeDomain
154166
155167
```typescript
156168
type TimeDomain = {
157-
type: string; // Domain type (e.g., 'hour', 'day', 'week')
158-
start: number; // Start timestamp (ms)
159-
end: number; // End timestamp (ms)
160-
};
169+
type: string // Domain type (e.g., 'hour', 'day', 'week')
170+
start: number // Start timestamp (ms)
171+
end: number // End timestamp (ms)
172+
}
161173
```
162174
163175
#### ChartColors
164176
165177
```typescript
166178
type ChartColors = {
167-
background: string; // Chart background color
168-
highlightLine: string; // Crosshair line color
169-
border: string; // Chart border color
170-
highlightLabel: string; // Value label text color
171-
highlightTime: string; // Time label text color
172-
cursorStroke: string; // Cursor/crosshair circle color
173-
};
179+
background: string // Chart background color
180+
highlightLine: string // Crosshair line color
181+
border: string // Chart border color
182+
highlightLabel: string // Value label text color
183+
highlightTime: string // Time label text color
184+
cursorStroke: string // Cursor/crosshair circle color
185+
}
174186
```
175187
176188
#### CalendarStrings
177189
178190
```typescript
179191
type CalendarStrings = {
180-
days: string[]; // Full day names (Sunday first)
181-
shortDays: string[]; // Short day names (Sun first)
182-
months: string[]; // Full month names (January first)
183-
shortMonths: string[]; // Short month names (Jan first)
184-
};
192+
days: string[] // Full day names (Sunday first)
193+
shortDays: string[] // Short day names (Sun first)
194+
months: string[] // Full month names (January first)
195+
shortMonths: string[] // Short month names (Jan first)
196+
}
185197
```
186198
187199
## Advanced Usage
@@ -204,9 +216,48 @@ const datasets = [
204216
decimals: 0,
205217
points: humidityData,
206218
},
207-
];
219+
]
208220
```
209221

222+
### Threshold-Based Colors
223+
224+
Create dynamic line colors that change based on data values using threshold configurations. This is perfect for showing status indicators, alerts, or different states in your data:
225+
226+
```tsx
227+
const datasetWithThresholds = {
228+
measurementName: 'Server Load',
229+
unit: '%',
230+
decimals: 0,
231+
areaColor: '#e78e96', // Optional: custom area fill color
232+
color: {
233+
type: 'thresholds',
234+
baseColor: '#089851', // Green for values below all thresholds (low load)
235+
gradientBlur: 50, // Smooth transition distance around thresholds
236+
thresholds: [
237+
{ value: 85, color: '#CF1E2E' }, // Red for values >= 85% (critical)
238+
{ value: 50, color: '#F29400' }, // Orange for values >= 50% (warning)
239+
// Values < 50% will use baseColor (green)
240+
],
241+
},
242+
points: serverLoadData,
243+
}
244+
```
245+
246+
**How it works:**
247+
248+
- **Thresholds should be sorted by value in descending order**
249+
- Values >= 85% will be colored red (`#CF1E2E`) - critical load
250+
- Values >= 50% but < 80% will be colored orange (`#F29400`) - warning load
251+
- Values < 50% will use the `baseColor` green (`#089851`) - healthy load
252+
- The `gradientBlur` creates smooth color transitions around threshold boundaries
253+
254+
**Real-world examples:**
255+
256+
- **Temperature monitoring**: Blue (cold) → Green (optimal) → Red (overheating)
257+
- **Performance metrics**: Red (poor) → Yellow (acceptable) → Green (excellent)
258+
- **Battery levels**: Red (critical) → Orange (low) → Green (healthy)
259+
- **Network latency**: Green (fast) → Yellow (moderate) → Red (slow)
260+
210261
### Zoom Callbacks
211262

212263
```tsx

example/src/App.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ const measurementsRecords: Record<Measurement, Dataset> = {
5555
unit: '°C',
5656
points: generateDataPoints(),
5757
decimals: 0,
58-
color: '#e66',
58+
areaColor: '#e78e96',
59+
color: {
60+
type: 'thresholds',
61+
baseColor: '#CF1E2E',
62+
gradientBlur: 50,
63+
thresholds: [
64+
{ value: 800, color: '#089851' },
65+
{ value: 400, color: '#F29400' },
66+
],
67+
},
5968
measurementName: Measurement.Red,
6069
},
6170
[Measurement.Blue]: {

0 commit comments

Comments
 (0)