td-plots 1.5.4 → 1.5.5

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/dist/index.js CHANGED
@@ -56,6 +56,319 @@ function styleInject(css, ref) {
56
56
  var css_248z = ".plot-container{height:100%;max-width:100%;min-height:300px;overflow:hidden!important;position:relative;width:100%}.plot-container>div{flex:1;height:100%!important;width:100%!important}.plot-container .main-svg{max-height:100%!important;max-width:100%!important}.plot-container .main-svg,.plot-container .plotly-graph-div,.plot-container svg.main-svg[height],.plot-container svg.main-svg[width]{height:100%!important;width:100%!important}.plot-container .point{border-radius:5px!important;overflow:hidden!important}.plot-container .cursor-ns-resize{height:0;width:0}.plot-container .cursor-ew-resize{fill:var(--selection-color,blue)!important;stroke:var(--selection-color,blue)!important}.plot-container .selectionlayer>path{stroke:var(--selection-color,blue)!important;stroke-dasharray:0!important;stroke-width:1px!important;opacity:.5!important}.plot-container .zoomlayer>path{stroke-dasharray:0!important;stroke:var(--selection-color,blue)!important;fill:var(--selection-color,blue)!important}.radial-histogram-container{aspect-ratio:1}.loading-overlay{align-items:center;background-color:hsla(0,0%,100%,.8);display:flex;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%;z-index:300}";
57
57
  styleInject(css_248z);
58
58
 
59
+ function formatDecimal(x) {
60
+ return Math.abs(x = Math.round(x)) >= 1e21
61
+ ? x.toLocaleString("en").replace(/,/g, "")
62
+ : x.toString(10);
63
+ }
64
+
65
+ // Computes the decimal coefficient and exponent of the specified number x with
66
+ // significant digits p, where x is positive and p is in [1, 21] or undefined.
67
+ // For example, formatDecimalParts(1.23) returns ["123", 0].
68
+ function formatDecimalParts(x, p) {
69
+ if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
70
+ var i, coefficient = x.slice(0, i);
71
+
72
+ // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
73
+ // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
74
+ return [
75
+ coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
76
+ +x.slice(i + 1)
77
+ ];
78
+ }
79
+
80
+ function exponent(x) {
81
+ return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;
82
+ }
83
+
84
+ function formatGroup(grouping, thousands) {
85
+ return function(value, width) {
86
+ var i = value.length,
87
+ t = [],
88
+ j = 0,
89
+ g = grouping[0],
90
+ length = 0;
91
+
92
+ while (i > 0 && g > 0) {
93
+ if (length + g + 1 > width) g = Math.max(1, width - length);
94
+ t.push(value.substring(i -= g, i + g));
95
+ if ((length += g + 1) > width) break;
96
+ g = grouping[j = (j + 1) % grouping.length];
97
+ }
98
+
99
+ return t.reverse().join(thousands);
100
+ };
101
+ }
102
+
103
+ function formatNumerals(numerals) {
104
+ return function(value) {
105
+ return value.replace(/[0-9]/g, function(i) {
106
+ return numerals[+i];
107
+ });
108
+ };
109
+ }
110
+
111
+ // [[fill]align][sign][symbol][0][width][,][.precision][~][type]
112
+ var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
113
+
114
+ function formatSpecifier(specifier) {
115
+ if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
116
+ var match;
117
+ return new FormatSpecifier({
118
+ fill: match[1],
119
+ align: match[2],
120
+ sign: match[3],
121
+ symbol: match[4],
122
+ zero: match[5],
123
+ width: match[6],
124
+ comma: match[7],
125
+ precision: match[8] && match[8].slice(1),
126
+ trim: match[9],
127
+ type: match[10]
128
+ });
129
+ }
130
+
131
+ formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
132
+
133
+ function FormatSpecifier(specifier) {
134
+ this.fill = specifier.fill === undefined ? " " : specifier.fill + "";
135
+ this.align = specifier.align === undefined ? ">" : specifier.align + "";
136
+ this.sign = specifier.sign === undefined ? "-" : specifier.sign + "";
137
+ this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + "";
138
+ this.zero = !!specifier.zero;
139
+ this.width = specifier.width === undefined ? undefined : +specifier.width;
140
+ this.comma = !!specifier.comma;
141
+ this.precision = specifier.precision === undefined ? undefined : +specifier.precision;
142
+ this.trim = !!specifier.trim;
143
+ this.type = specifier.type === undefined ? "" : specifier.type + "";
144
+ }
145
+
146
+ FormatSpecifier.prototype.toString = function() {
147
+ return this.fill
148
+ + this.align
149
+ + this.sign
150
+ + this.symbol
151
+ + (this.zero ? "0" : "")
152
+ + (this.width === undefined ? "" : Math.max(1, this.width | 0))
153
+ + (this.comma ? "," : "")
154
+ + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0))
155
+ + (this.trim ? "~" : "")
156
+ + this.type;
157
+ };
158
+
159
+ // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.
160
+ function formatTrim(s) {
161
+ out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {
162
+ switch (s[i]) {
163
+ case ".": i0 = i1 = i; break;
164
+ case "0": if (i0 === 0) i0 = i; i1 = i; break;
165
+ default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;
166
+ }
167
+ }
168
+ return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
169
+ }
170
+
171
+ var prefixExponent;
172
+
173
+ function formatPrefixAuto(x, p) {
174
+ var d = formatDecimalParts(x, p);
175
+ if (!d) return x + "";
176
+ var coefficient = d[0],
177
+ exponent = d[1],
178
+ i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
179
+ n = coefficient.length;
180
+ return i === n ? coefficient
181
+ : i > n ? coefficient + new Array(i - n + 1).join("0")
182
+ : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
183
+ : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!
184
+ }
185
+
186
+ function formatRounded(x, p) {
187
+ var d = formatDecimalParts(x, p);
188
+ if (!d) return x + "";
189
+ var coefficient = d[0],
190
+ exponent = d[1];
191
+ return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
192
+ : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
193
+ : coefficient + new Array(exponent - coefficient.length + 2).join("0");
194
+ }
195
+
196
+ var formatTypes = {
197
+ "%": (x, p) => (x * 100).toFixed(p),
198
+ "b": (x) => Math.round(x).toString(2),
199
+ "c": (x) => x + "",
200
+ "d": formatDecimal,
201
+ "e": (x, p) => x.toExponential(p),
202
+ "f": (x, p) => x.toFixed(p),
203
+ "g": (x, p) => x.toPrecision(p),
204
+ "o": (x) => Math.round(x).toString(8),
205
+ "p": (x, p) => formatRounded(x * 100, p),
206
+ "r": formatRounded,
207
+ "s": formatPrefixAuto,
208
+ "X": (x) => Math.round(x).toString(16).toUpperCase(),
209
+ "x": (x) => Math.round(x).toString(16)
210
+ };
211
+
212
+ function identity(x) {
213
+ return x;
214
+ }
215
+
216
+ var map = Array.prototype.map,
217
+ prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
218
+
219
+ function formatLocale(locale) {
220
+ var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""),
221
+ currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "",
222
+ currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "",
223
+ decimal = locale.decimal === undefined ? "." : locale.decimal + "",
224
+ numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),
225
+ percent = locale.percent === undefined ? "%" : locale.percent + "",
226
+ minus = locale.minus === undefined ? "−" : locale.minus + "",
227
+ nan = locale.nan === undefined ? "NaN" : locale.nan + "";
228
+
229
+ function newFormat(specifier) {
230
+ specifier = formatSpecifier(specifier);
231
+
232
+ var fill = specifier.fill,
233
+ align = specifier.align,
234
+ sign = specifier.sign,
235
+ symbol = specifier.symbol,
236
+ zero = specifier.zero,
237
+ width = specifier.width,
238
+ comma = specifier.comma,
239
+ precision = specifier.precision,
240
+ trim = specifier.trim,
241
+ type = specifier.type;
242
+
243
+ // The "n" type is an alias for ",g".
244
+ if (type === "n") comma = true, type = "g";
245
+
246
+ // The "" type, and any invalid type, is an alias for ".12~g".
247
+ else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g";
248
+
249
+ // If zero fill is specified, padding goes after sign and before digits.
250
+ if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
251
+
252
+ // Compute the prefix and suffix.
253
+ // For SI-prefix, the suffix is lazily computed.
254
+ var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
255
+ suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "";
256
+
257
+ // What format function should we use?
258
+ // Is this an integer type?
259
+ // Can this type generate exponential notation?
260
+ var formatType = formatTypes[type],
261
+ maybeSuffix = /[defgprs%]/.test(type);
262
+
263
+ // Set the default precision if not specified,
264
+ // or clamp the specified precision to the supported range.
265
+ // For significant precision, it must be in [1, 21].
266
+ // For fixed precision, it must be in [0, 20].
267
+ precision = precision === undefined ? 6
268
+ : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
269
+ : Math.max(0, Math.min(20, precision));
270
+
271
+ function format(value) {
272
+ var valuePrefix = prefix,
273
+ valueSuffix = suffix,
274
+ i, n, c;
275
+
276
+ if (type === "c") {
277
+ valueSuffix = formatType(value) + valueSuffix;
278
+ value = "";
279
+ } else {
280
+ value = +value;
281
+
282
+ // Determine the sign. -0 is not less than 0, but 1 / -0 is!
283
+ var valueNegative = value < 0 || 1 / value < 0;
284
+
285
+ // Perform the initial formatting.
286
+ value = isNaN(value) ? nan : formatType(Math.abs(value), precision);
287
+
288
+ // Trim insignificant zeros.
289
+ if (trim) value = formatTrim(value);
290
+
291
+ // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.
292
+ if (valueNegative && +value === 0 && sign !== "+") valueNegative = false;
293
+
294
+ // Compute the prefix and suffix.
295
+ valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
296
+ valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
297
+
298
+ // Break the formatted value into the integer “value” part that can be
299
+ // grouped, and fractional or exponential “suffix” part that is not.
300
+ if (maybeSuffix) {
301
+ i = -1, n = value.length;
302
+ while (++i < n) {
303
+ if (c = value.charCodeAt(i), 48 > c || c > 57) {
304
+ valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
305
+ value = value.slice(0, i);
306
+ break;
307
+ }
308
+ }
309
+ }
310
+ }
311
+
312
+ // If the fill character is not "0", grouping is applied before padding.
313
+ if (comma && !zero) value = group(value, Infinity);
314
+
315
+ // Compute the padding.
316
+ var length = valuePrefix.length + value.length + valueSuffix.length,
317
+ padding = length < width ? new Array(width - length + 1).join(fill) : "";
318
+
319
+ // If the fill character is "0", grouping is applied after padding.
320
+ if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
321
+
322
+ // Reconstruct the final output based on the desired alignment.
323
+ switch (align) {
324
+ case "<": value = valuePrefix + value + valueSuffix + padding; break;
325
+ case "=": value = valuePrefix + padding + value + valueSuffix; break;
326
+ case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
327
+ default: value = padding + valuePrefix + value + valueSuffix; break;
328
+ }
329
+
330
+ return numerals(value);
331
+ }
332
+
333
+ format.toString = function() {
334
+ return specifier + "";
335
+ };
336
+
337
+ return format;
338
+ }
339
+
340
+ function formatPrefix(specifier, value) {
341
+ var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
342
+ e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
343
+ k = Math.pow(10, -e),
344
+ prefix = prefixes[8 + e / 3];
345
+ return function(value) {
346
+ return f(k * value) + prefix;
347
+ };
348
+ }
349
+
350
+ return {
351
+ format: newFormat,
352
+ formatPrefix: formatPrefix
353
+ };
354
+ }
355
+
356
+ var locale;
357
+ var format;
358
+
359
+ defaultLocale({
360
+ thousands: ",",
361
+ grouping: [3],
362
+ currency: ["$", ""]
363
+ });
364
+
365
+ function defaultLocale(definition) {
366
+ locale = formatLocale(definition);
367
+ format = locale.format;
368
+ locale.formatPrefix;
369
+ return locale;
370
+ }
371
+
59
372
  // Utility functions for our components
60
373
  var ONEAVGMONTH = 2629800000; // Average month length in ms, copied from plotly constants in plotly.js/src/constants/numerical.js
61
374
  // Type guard to check if array contains only numbers
@@ -6072,11 +6385,11 @@ var Loading = function () {
6072
6385
  var Plot$2 = React.lazy(function () { return import('react-plotly.js'); });
6073
6386
  var HistogramPlot = function (props) {
6074
6387
  var _a, _b, _c, _d;
6075
- var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _e = props.barColor, barColor = _e === void 0 ? "rgb(72, 72, 74)" : _e, _f = props.unselectedBarColor, unselectedBarColor = _f === void 0 ? "rgba(203, 195, 195, 0.88)" : _f, _g = props.selectorsColor, selectorsColor = _g === void 0 ? "black" : _g, containerStyleOverrides = props.containerStyleOverrides, _h = props.unselectedData, unselectedData = _h === void 0 ? [] : _h, _j = props.handleClickOrSelection, handleClickOrSelection = _j === void 0 ? function () { } : _j, _k = props.onDeselect, onDeselect = _k === void 0 ? function () { } : _k, plotId = props.plotId, _l = props.selectByBin, selectByBin = _l === void 0 ? false : _l, dateTickFormat = props.dateTickFormat, binSizeOverride = props.binSizeOverride, _m = props.statsAnnotations, statsAnnotations = _m === void 0 ? ["mean"] : _m, _o = props.emptySelectedRange, emptySelectedRange = _o === void 0 ? false : _o;
6388
+ var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _e = props.barColor, barColor = _e === void 0 ? "rgb(72, 72, 74)" : _e, _f = props.unselectedBarColor, unselectedBarColor = _f === void 0 ? "rgba(203, 195, 195, 0.88)" : _f, _g = props.selectorsColor, selectorsColor = _g === void 0 ? "black" : _g, containerStyleOverrides = props.containerStyleOverrides, _h = props.unselectedData, unselectedData = _h === void 0 ? [] : _h, _j = props.handleClickOrSelection, handleClickOrSelection = _j === void 0 ? function () { } : _j, _k = props.onDeselect, onDeselect = _k === void 0 ? function () { } : _k, plotId = props.plotId, _l = props.selectByBin, selectByBin = _l === void 0 ? false : _l, dateTickFormat = props.dateTickFormat, binSizeOverride = props.binSizeOverride, _m = props.statsAnnotations, statsAnnotations = _m === void 0 ? ["mean"] : _m, _o = props.emptySelectedRange, emptySelectedRange = _o === void 0 ? false : _o, _p = props.d3FormatValueString, d3FormatValueString = _p === void 0 ? ".1f" : _p;
6076
6389
  // Ref for plot container
6077
6390
  var containerRef = React.useRef(null);
6078
6391
  // Track any selections made in this plot so we can style the selection box.
6079
- var _p = React.useState(null), selectedRange = _p[0], setSelectedRange = _p[1];
6392
+ var _q = React.useState(null), selectedRange = _q[0], setSelectedRange = _q[1];
6080
6393
  // If the parent component wants to clear the selection, reset selectedRange to null.
6081
6394
  React.useEffect(function () {
6082
6395
  if (emptySelectedRange) {
@@ -6098,9 +6411,9 @@ var HistogramPlot = function (props) {
6098
6411
  // Plotly determines "nice" bins which consequently means it internally decides the axis range. We need
6099
6412
  // to access that information once the plot has been initialized so that we can prevent the
6100
6413
  // axis range from changing during interaction. Dates use strings.
6101
- var _q = React.useState(undefined), fixedXAxisRange = _q[0], setFixedXAxisRange = _q[1];
6414
+ var _r = React.useState(undefined), fixedXAxisRange = _r[0], setFixedXAxisRange = _r[1];
6102
6415
  // track xbins too
6103
- var _r = React.useState(undefined), binSize = _r[0], setBinSize = _r[1];
6416
+ var _s = React.useState(undefined), binSize = _s[0], setBinSize = _s[1];
6104
6417
  // Once the plot is drawn, record the initial axis range so we can keep it fixed.
6105
6418
  // figure should be Readonly<Plotly.Figure> but react-plotly.js doesn't expose that type, so we use any.
6106
6419
  var handlePlotUpdate = function (figure, graphDiv) {
@@ -6486,7 +6799,7 @@ var HistogramPlot = function (props) {
6486
6799
  day: "2-digit",
6487
6800
  year: "2-digit",
6488
6801
  })
6489
- : meanValue.toFixed(2), "</span>"),
6802
+ : format(d3FormatValueString)(meanValue), "</span>"),
6490
6803
  xanchor: "center",
6491
6804
  yanchor: "bottom",
6492
6805
  showarrow: false,
@@ -6511,7 +6824,7 @@ var HistogramPlot = function (props) {
6511
6824
  day: "2-digit",
6512
6825
  year: "2-digit",
6513
6826
  })
6514
- : stdevValue.toFixed(2), "</span>"),
6827
+ : format(d3FormatValueString)(stdevValue), "</span>"),
6515
6828
  xanchor: "center",
6516
6829
  yanchor: "bottom",
6517
6830
  showarrow: false,
@@ -6575,12 +6888,9 @@ var HistogramPlot = function (props) {
6575
6888
  linewidth: 1,
6576
6889
  fixedrange: true, // Disable zooming
6577
6890
  ticklabelposition: "outside",
6578
- tickformat: isDateArray(data) ? dateTickFormat : undefined, // Format ticks for dates
6891
+ tickformat: isDateArray(data) ? dateTickFormat : d3FormatValueString, // Format ticks for dates
6579
6892
  automargin: true, // Adjust margin if tick labels rotate
6580
- hoverformat: isNumberArray(allData) &&
6581
- Math.max.apply(Math, allData) - Math.min.apply(Math, allData) > 3
6582
- ? ".1~f"
6583
- : undefined,
6893
+ hoverformat: isNumberArray(allData) ? d3FormatValueString : undefined,
6584
6894
  },
6585
6895
  yaxis: {
6586
6896
  title: {