@windborne/grapher 1.0.41 → 1.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windborne/grapher",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "Graphing library",
5
5
  "main": "src/index.js",
6
6
  "module": "dist/bundle.esm.js",
package/readme.md CHANGED
@@ -141,7 +141,7 @@ Grapher supports multiple data formats within a series:
141
141
  | width | `number` | ✗ | Line width. |
142
142
  | axis | `string \| object` | ✗ | Axis specification for the series. |
143
143
  | rangeSelectorWidth | `number` | ✗ | Width of the range selector for this series. |
144
- | expandYWith | `number[]` | ✗ | Values to include when calculating y-axis range. |
144
+ | expandYWith | `(number | null)[] | null` | ✗ | Values to include when calculating y-axis range. |
145
145
  | defaultAlwaysTooltipped | `boolean` | ✗ | Whether to always show tooltip for this series. |
146
146
  | square | `boolean` | ✗ | Whether to render the series with square points. |
147
147
  | shiftXBy | `number` | ✗ | Value to shift x-coordinates by. |
@@ -385,17 +385,9 @@ function placeDateOnlyGrid({ min, max, precision, expectedLabelSize, labelPaddin
385
385
  const spanMultipleYears = minYear !== maxYear;
386
386
 
387
387
  const customDateFormatter = (date, options) => {
388
- const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
389
- const d = new Date(date);
390
- const month = monthNames[d.getMonth()];
391
- const day = d.getDate();
392
- const year = d.getFullYear();
393
-
394
- if (spanMultipleYears) {
395
- return `${month} ${day} ${year}`;
396
- } else {
397
- return `${month} ${day}`;
398
- }
388
+ const timeZone = formatOptions.timeZone;
389
+ const result = formatter(date, { ...options, dates: true, justMonthAndDay: !spanMultipleYears, justDate: spanMultipleYears, timeZone });
390
+ return result;
399
391
  };
400
392
 
401
393
  const placementParams = { scale, min, max, inverted, totalSize, precision, formatter: customDateFormatter, formatOptions, dates: true };
package/src/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export interface SeriesData {
16
16
  width?: number;
17
17
  rangeSelectorWidth?: number;
18
18
  axis?: string | object;
19
- expandYWith?: number[];
19
+ expandYWith?: (number | null)[] | null;
20
20
  defaultAlwaysTooltipped?: boolean;
21
21
  square?: boolean;
22
22
  shiftXBy?: number;
@@ -13,7 +13,7 @@ function finalizeBounds(bounds, { dates }) {
13
13
  return bounds;
14
14
  }
15
15
 
16
- function percentileBounds(inDataSpace, bounds, {percentile=100, percentileAsymmetry=0}={}) {
16
+ function percentileBounds(inDataSpace, bounds, {percentile=100, percentileAsymmetry=0, rangeValues=[]}={}) {
17
17
  let dates = false;
18
18
 
19
19
  bounds.minX = inDataSpace[0][0];
@@ -32,6 +32,13 @@ function percentileBounds(inDataSpace, bounds, {percentile=100, percentileAsymme
32
32
  .filter(([_x, y]) => typeof y === 'number')
33
33
  .sort(([_x1, y1], [_x2, y2]) => y1 - y2);
34
34
 
35
+ for (let rangeValue of rangeValues) {
36
+ if (typeof rangeValue === 'number') {
37
+ sortedByY.push([null, rangeValue]);
38
+ }
39
+ }
40
+ sortedByY.sort(([_x1, y1], [_x2, y2]) => y1 - y2);
41
+
35
42
  if (!sortedByY.length) {
36
43
  return finalizeBounds(bounds, {dates});
37
44
  }
@@ -49,7 +56,7 @@ function percentileBounds(inDataSpace, bounds, {percentile=100, percentileAsymme
49
56
  return finalizeBounds(bounds, {dates});
50
57
  }
51
58
 
52
- export default function calculateDataBounds(inDataSpace, {percentile=100, percentileAsymmetry=0}={}) {
59
+ export default function calculateDataBounds(inDataSpace, {percentile=100, percentileAsymmetry=0, rangeValues=[]}={}) {
53
60
  let bounds = {
54
61
  minX: null,
55
62
  maxX: null,
@@ -100,5 +107,16 @@ export default function calculateDataBounds(inDataSpace, {percentile=100, percen
100
107
  }
101
108
  }
102
109
 
110
+ for (let rangeValue of rangeValues) {
111
+ if (typeof rangeValue === 'number') {
112
+ if (typeof bounds.minY !== 'number' || rangeValue < bounds.minY) {
113
+ bounds.minY = rangeValue;
114
+ }
115
+ if (typeof bounds.maxY !== 'number' || rangeValue > bounds.maxY) {
116
+ bounds.maxY = rangeValue;
117
+ }
118
+ }
119
+ }
120
+
103
121
  return finalizeBounds(bounds, {dates});
104
122
  }
@@ -166,6 +166,7 @@ function objectsToDataSpace(data, series, options) {
166
166
  }
167
167
 
168
168
  const inDataSpace = [];
169
+ const rangeValues = [];
169
170
 
170
171
  for (let point of data) {
171
172
  if (point.buffer instanceof ArrayBuffer) {
@@ -222,8 +223,24 @@ function objectsToDataSpace(data, series, options) {
222
223
  }
223
224
 
224
225
  inDataSpace.push([xValue, yValue]);
226
+
227
+ if (series.rangeKey && point[series.rangeKey]) {
228
+ const range = point[series.rangeKey];
229
+ if (typeof range === 'object' && range.min !== undefined && range.max !== undefined) {
230
+ if (typeof range.min === 'number') {
231
+ rangeValues.push(range.min);
232
+ }
233
+ if (typeof range.max === 'number') {
234
+ rangeValues.push(range.max);
235
+ }
236
+ }
237
+ }
225
238
  }
226
239
  }
227
240
 
241
+ if (rangeValues.length > 0) {
242
+ series._rangeValues = rangeValues;
243
+ }
244
+
228
245
  return inDataSpace;
229
246
  }
@@ -620,7 +620,9 @@ export default class StateController extends Eventable {
620
620
  stateController: this
621
621
  });
622
622
  singleSeries.simpleDataSliceStart = simpleData.length;
623
- singleSeries.dataBounds = calculateDataBounds(singleSeries.inDataSpace);
623
+ singleSeries.dataBounds = calculateDataBounds(singleSeries.inDataSpace, {
624
+ rangeValues: singleSeries._rangeValues || []
625
+ });
624
626
  if (singleSeries.rendering === 'bar') {
625
627
  singleSeries.dataBounds = expandBounds(singleSeries.dataBounds, { extendXForNBars: singleSeries.inDataSpace.length, expandYWith: singleSeries.expandYWith });
626
628
  }
@@ -795,6 +797,10 @@ export default class StateController extends Eventable {
795
797
  if (singleSeries.rendering === 'bar') {
796
798
  expandYWith.push(singleSeries.selectedBounds.minY, singleSeries.selectedBounds.maxY);
797
799
  }
800
+
801
+ if (singleSeries._rangeValues && singleSeries._rangeValues.length > 0) {
802
+ expandYWith.push(...singleSeries._rangeValues);
803
+ }
798
804
  }
799
805
 
800
806
  axis.selectedDataBounds = mergeBounds(selectedBoundsList);