Skip to content

Commit 304bf37

Browse files
committed
Improve code - threshold gradients
1 parent cf8dd81 commit 304bf37

4 files changed

Lines changed: 40 additions & 35 deletions

File tree

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ type Dataset = {
145145
type ThresholdColor = {
146146
type: 'thresholds'
147147
baseColor: string // Default color for values below all thresholds
148-
gradientBlur: number // Gradient transition distance around thresholds
149148
thresholds: Array<{
150149
value: number // Threshold value
151150
color: string // Color to use above this value
152151
}> // Should be sorted by value descending
152+
gradientBlur?: number // Gradient transition distance around thresholds. Default 0 - no blur
153153
}
154154
```
155155
@@ -231,11 +231,11 @@ const datasetWithThresholds = {
231231
areaColor: '#e78e96', // Optional: custom area fill color
232232
color: {
233233
type: 'thresholds',
234-
baseColor: '#089851', // Green for values below all thresholds (low load)
235-
gradientBlur: 50, // Smooth transition distance around thresholds
234+
baseColor: '#00FF00', // Green for values below all thresholds (low load)
235+
gradientBlur: 5, // Smooth transition distance around thresholds
236236
thresholds: [
237-
{ value: 85, color: '#CF1E2E' }, // Red for values >= 85% (critical)
238-
{ value: 50, color: '#F29400' }, // Orange for values >= 50% (warning)
237+
{ value: 85, color: '#FF0000' }, // Red for values >= 85% (critical)
238+
{ value: 50, color: '#FF9400' }, // Orange for values >= 50% (warning)
239239
// Values < 50% will use baseColor (green)
240240
],
241241
},
@@ -246,9 +246,9 @@ const datasetWithThresholds = {
246246
**How it works:**
247247

248248
- **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
249+
- Values >= 85% will be colored red (`#FF0000`) - critical load
250+
- Values >= 50% but < 80% will be colored orange (`#FF9400`) - warning load
251+
- Values < 50% will use the `baseColor` green (`#00FF00`) - healthy load
252252
- The `gradientBlur` creates smooth color transitions around threshold boundaries
253253

254254
**Real-world examples:**

example/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const measurementsRecords: Record<Measurement, Dataset> = {
6262
startingValue: -8,
6363
}),
6464
decimals: 0,
65-
areaColor: '#ff00ff', // '#83cba8',
65+
areaColor: '#83cba8',
6666
color: {
6767
type: 'thresholds',
6868
baseColor: '#3d91ff',

src/drawFunction.js

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ window.draw = (props) => {
453453
.area()
454454
.defined(isDefined)
455455
.x((d) => x(d.date))
456-
.y0(y(y.domain()[0]) + 1) // Use min value, +1 to avoid blinking space
456+
.y0(y(y.domain()[0]) + 1) // NOTE: +1 prevents a weird hairline at the bottom (just above axis)
457457
.y1((d) => y(d.value))
458458
)
459459
@@ -464,20 +464,18 @@ window.draw = (props) => {
464464
.attr('stroke-width', 2)
465465
466466
if (dataset.color.type === 'thresholds') {
467-
const { baseColor, gradientBlur, thresholds } = dataset.color
468-
const stops = []
469-
thresholds.forEach(({ value, color }, index) => {
470-
stops.push(
471-
{
472-
value: value + gradientBlur,
473-
color: color,
474-
},
475-
{
476-
value: value - gradientBlur,
477-
color: thresholds[index + 1]?.color ?? baseColor,
478-
}
479-
)
480-
})
467+
const { baseColor, gradientBlur = 0, thresholds } = dataset.color
468+
const stops = thresholds.flatMap(({ value, color }, index) => [
469+
{
470+
value: value + gradientBlur,
471+
color: color,
472+
},
473+
{
474+
value: value - gradientBlur,
475+
// NOTE: All thresholds have color. index out of bounds - last threshold - use baseColor
476+
color: thresholds[index + 1]?.color ?? baseColor,
477+
},
478+
])
481479
482480
defs
483481
.append('linearGradient')
@@ -663,7 +661,7 @@ window.draw = (props) => {
663661
.area()
664662
.defined(isDefined)
665663
.x((d) => x(d.date))
666-
.y0(y(y.domain()[0]) + 1) // Use min value, +1 to avoid blinking space
664+
.y0(y(y.domain()[0]) + 1) // NOTE: +1 prevents a weird hairline at the bottom (just above axis)
667665
.y1((d) => y(d.value))
668666
)
669667
@@ -736,7 +734,7 @@ window.draw = (props) => {
736734
.area()
737735
.defined(isDefined)
738736
.x((d) => newX(d.date))
739-
.y0(y(y.domain()[0]) + 1) // Use min value, +1 to avoid blinking space
737+
.y0(y(y.domain()[0]) + 1) // NOTE: +1 prevents a weird hairline at the bottom (just above axis)
740738
.y1((d) => y(d.value))
741739
)
742740
})

src/types.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,24 @@ export type CalendarStrings = {
1616
shortMonths: string[]
1717
}
1818

19+
type ThresholdColor = {
20+
type: 'thresholds'
21+
baseColor: string
22+
/**
23+
* Must be sorted by value descending (highest value first)
24+
*/
25+
thresholds: { value: number; color: string }[]
26+
/**
27+
* Gradient transition distance around thresholds.
28+
* Must be non-negative. Should be less than half the distance between thresholds.
29+
* @default 0 - no blur
30+
*/
31+
gradientBlur?: number
32+
}
33+
1934
export type Dataset = {
2035
measurementName: string
21-
color:
22-
| string
23-
| {
24-
type: 'thresholds'
25-
baseColor: string
26-
gradientBlur: number
27-
/* should be sorted by value descending */
28-
thresholds: { value: number; color: string }[]
29-
}
36+
color: string | ThresholdColor
3037
points: Point[]
3138
unit: string
3239
decimals: number

0 commit comments

Comments
 (0)