td-plots 1.5.1 → 1.5.2

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.
@@ -5,3 +5,5 @@ export declare function calculateStandardDeviation(arr: number[] | Date[]): numb
5
5
  export declare const formatDateMDY: (timestamp: number) => string;
6
6
  export declare const roundToNextDay: (timestamp: number) => string;
7
7
  export declare const roundToPrevDay: (timestamp: number) => string;
8
+ export declare const plotlyMToMilliseconds: (mString: string) => number;
9
+ export declare const convertDateDescriptionToTimestamp: (startValue: string | number) => number;
package/dist/index.esm.js CHANGED
@@ -37,6 +37,7 @@ var css_248z = ".plot-container{height:100%;max-width:100%;min-height:300px;over
37
37
  styleInject(css_248z);
38
38
 
39
39
  // Utility functions for our components
40
+ var ONEAVGMONTH = 2629800000; // Average month length in ms, copied from plotly constants in plotly.js/src/constants/numerical.js
40
41
  // Type guard to check if array contains only numbers
41
42
  var isNumberArray = function (arr) {
42
43
  return arr.every(function (item) { return typeof item === 'number' && !isNaN(item); });
@@ -89,6 +90,44 @@ var roundToPrevDay = function (timestamp) {
89
90
  date.setHours(0, 0, 0, 0); // Start of day
90
91
  return date.toISOString();
91
92
  };
93
+ // Convert plotly M# string to number of milliseconds
94
+ // According to the docs, plotly will use M# whenever the bin size is
95
+ // larger than one average month. Even if the bin size is 2 years, plotly
96
+ // will still use M24 instead of Y2 (plotly.js/src/plots/cartesian/axes.js).
97
+ var plotlyMToMilliseconds = function (mString) {
98
+ var match = mString.match(/^M(\d+)$/);
99
+ if (match) {
100
+ var months = parseInt(match[1], 10);
101
+ return months * ONEAVGMONTH;
102
+ }
103
+ else {
104
+ console.error("plotlyMToMilliseconds: Invalid M# string: ".concat(mString));
105
+ }
106
+ return 0;
107
+ };
108
+ // Convert a string specifying a day (with no time) to a timestamp
109
+ var convertDateDescriptionToTimestamp = function (startValue) {
110
+ if (typeof startValue === 'number') {
111
+ // Then we're assuming it's already a timestamp
112
+ return startValue;
113
+ }
114
+ if (typeof startValue === 'string') {
115
+ // Try to parse the date string.
116
+ var date = new Date(startValue);
117
+ // Sometimes the date will fail to be a proper Date if it does not
118
+ // have a time component. Add a time stamp if necessary.
119
+ if (isNaN(date.getTime())) {
120
+ // Then date did not have a time and is just a day. Try adding a time.
121
+ var dateWithTime = new Date(startValue + 'T00:00:00');
122
+ if (isNaN(dateWithTime.getTime())) {
123
+ throw new Error("Cannot parse date: ".concat(startValue));
124
+ }
125
+ return dateWithTime.getTime();
126
+ }
127
+ return date.getTime();
128
+ }
129
+ throw new Error("Unexpected type for start value: ".concat(typeof startValue));
130
+ };
92
131
 
93
132
  function getDefaultExportFromCjs (x) {
94
133
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -6093,8 +6132,8 @@ var HistogramPlot = function (props) {
6093
6132
  // This is the start of the first bin out of all the traces. The global first bin.
6094
6133
  var globalFirstBinStart = void 0;
6095
6134
  if (isDateArray(data)) {
6096
- // Date bins are represented as strings. We'll need to convert them to timestamps.
6097
- globalFirstBinStart = new Date(event.points[0].data.xbins.start).getTime();
6135
+ // Date bins are represented as strings (sometimes). We'll need to convert whatever plotly gives us to timestamps.
6136
+ globalFirstBinStart = convertDateDescriptionToTimestamp(event.points[0].data.xbins.start);
6098
6137
  minTraceValue = Math.min.apply(Math, data.map(function (d) { return d.getTime(); }));
6099
6138
  }
6100
6139
  else {
@@ -6107,10 +6146,14 @@ var HistogramPlot = function (props) {
6107
6146
  minTraceValue = Math.min.apply(Math, data);
6108
6147
  globalFirstBinStart = event.points[0].data.xbins.start;
6109
6148
  }
6149
+ // Finally, we need to calculate the min and max values of the clicked bin.
6150
+ // If the bin size is a month or more, plotly records it in their "mstring" format like "M3" for 3 months.
6151
+ // We then must convert it back to milliseconds. Otherwise, it's always ms.
6152
+ var binSize = typeof event.points[0].data.xbins.size === 'string'
6153
+ ? plotlyMToMilliseconds(event.points[0].data.xbins.size)
6154
+ : event.points[0].data.xbins.size;
6110
6155
  // This minTraceValue is in the 0th bin of this trace. Find the index of this bin in the whole plot.
6111
- var clickedBinGlobalIndex = clickedBinIndex + Math.floor((minTraceValue - globalFirstBinStart) / event.points[0].data.xbins.size);
6112
- // Finally we can calculate the min and max values of the clicked bin.
6113
- var binSize = event.points[0].data.xbins.size;
6156
+ var clickedBinGlobalIndex = clickedBinIndex + Math.floor((minTraceValue - globalFirstBinStart) / binSize);
6114
6157
  var _a = [
6115
6158
  globalFirstBinStart + clickedBinGlobalIndex * binSize,
6116
6159
  globalFirstBinStart + (clickedBinGlobalIndex + 1) * binSize
@@ -6143,7 +6186,11 @@ var HistogramPlot = function (props) {
6143
6186
  // Means at least one bin has been selected
6144
6187
  var firstBinMidPoint = new Date(event.points[0].x).getTime();
6145
6188
  var lastBinMidPoint = new Date(event.points[event.points.length - 1].x).getTime();
6146
- var binSize = event.points[0].data.xbins.size;
6189
+ // If the bin size is a month or more, plotly records it in their "mstring" format like "M3" for 3 months.
6190
+ // We then must convert it back to milliseconds. Otherwise, it's always ms.
6191
+ var binSize = typeof event.points[0].data.xbins.size === 'string'
6192
+ ? plotlyMToMilliseconds(event.points[0].data.xbins.size)
6193
+ : event.points[0].data.xbins.size;
6147
6194
  minValue = new Date(firstBinMidPoint - binSize / 2);
6148
6195
  maxValue = new Date(lastBinMidPoint + binSize / 2);
6149
6196
  }
@@ -6308,7 +6355,7 @@ var HistogramPlot = function (props) {
6308
6355
  // If binSizeOverride is provided, use it to set the bin size and range explicitly.
6309
6356
  // Plotly does a better job of setting bins and ending them at nice numbers, so only use
6310
6357
  // this prop when necessary.
6311
- var xBins = binSizeOverride
6358
+ var xBins = (binSizeOverride && allData.length > 0)
6312
6359
  ? (isDateArray(allData)
6313
6360
  ? {
6314
6361
  start: roundToPrevDay(Math.min.apply(Math, allData.map(function (d) { return d.getTime(); }))), // Find a nice round number as a starting point.
@@ -6338,7 +6385,7 @@ var HistogramPlot = function (props) {
6338
6385
  width: 0.5,
6339
6386
  },
6340
6387
  },
6341
- hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text
6388
+ hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>',
6342
6389
  };
6343
6390
  var meanAnnotation = (statsAnnotations.includes('mean') && meanLine && data.length > 0) ? [{
6344
6391
  x: meanValue,
@@ -6429,6 +6476,7 @@ var HistogramPlot = function (props) {
6429
6476
  ticklabelposition: 'outside',
6430
6477
  tickformat: isDateArray(data) ? dateTickFormat : undefined, // Format ticks for dates
6431
6478
  automargin: true, // Adjust margin if tick labels rotate
6479
+ hoverformat: (isNumberArray(allData) && Math.max.apply(Math, allData) - Math.min.apply(Math, allData) > 3) ? '.1~f' : undefined,
6432
6480
  },
6433
6481
  yaxis: {
6434
6482
  title: {