td-plots 1.5.0 → 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
@@ -1,5 +1,5 @@
1
1
  import { __spreadArray, __assign } from 'tslib';
2
- import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
4
  import { lazy, useRef, useState, useEffect, useMemo, Suspense } from 'react';
5
5
  import emStyled from '@emotion/styled';
@@ -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;
@@ -1392,8 +1431,8 @@ function requireReactIs_production () {
1392
1431
  REACT_PORTAL_TYPE = Symbol.for("react.portal"),
1393
1432
  REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
1394
1433
  REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
1395
- REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1396
- var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
1434
+ REACT_PROFILER_TYPE = Symbol.for("react.profiler"),
1435
+ REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
1397
1436
  REACT_CONTEXT_TYPE = Symbol.for("react.context"),
1398
1437
  REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
1399
1438
  REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
@@ -1563,8 +1602,8 @@ function requireReactIs_development () {
1563
1602
  REACT_PORTAL_TYPE = Symbol.for("react.portal"),
1564
1603
  REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
1565
1604
  REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
1566
- REACT_PROFILER_TYPE = Symbol.for("react.profiler");
1567
- var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
1605
+ REACT_PROFILER_TYPE = Symbol.for("react.profiler"),
1606
+ REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
1568
1607
  REACT_CONTEXT_TYPE = Symbol.for("react.context"),
1569
1608
  REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
1570
1609
  REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
@@ -2760,7 +2799,7 @@ const styleFunctionSx = unstable_createStyleFunctionSx();
2760
2799
  styleFunctionSx.filterProps = ['sx'];
2761
2800
 
2762
2801
  /**
2763
- * @mui/styled-engine v7.3.2
2802
+ * @mui/styled-engine v7.3.3
2764
2803
  *
2765
2804
  * @license MIT
2766
2805
  * This source code is licensed under the MIT license found in the
@@ -5059,7 +5098,7 @@ function createColorScheme(options) {
5059
5098
  opacity,
5060
5099
  overlays,
5061
5100
  colorSpace,
5062
- ...rest
5101
+ ...other
5063
5102
  } = options;
5064
5103
  // need to cast because `colorSpace` is considered internal at the moment.
5065
5104
  const palette = createPalette({
@@ -5073,7 +5112,7 @@ function createColorScheme(options) {
5073
5112
  ...opacity
5074
5113
  },
5075
5114
  overlays: overlays || getOverlays(palette.mode),
5076
- ...rest
5115
+ ...other
5077
5116
  };
5078
5117
  }
5079
5118
 
@@ -5583,7 +5622,7 @@ function createTheme(options = {},
5583
5622
  light: true
5584
5623
  } : undefined,
5585
5624
  defaultColorScheme: initialDefaultColorScheme = palette?.mode,
5586
- ...rest
5625
+ ...other
5587
5626
  } = options;
5588
5627
  const defaultColorSchemeInput = initialDefaultColorScheme || 'light';
5589
5628
  const defaultScheme = initialColorSchemes?.[defaultColorSchemeInput];
@@ -5640,7 +5679,7 @@ function createTheme(options = {},
5640
5679
  colorSchemesInput.light = true;
5641
5680
  }
5642
5681
  return createThemeWithVars({
5643
- ...rest,
5682
+ ...other,
5644
5683
  colorSchemes: colorSchemesInput,
5645
5684
  defaultColorScheme: defaultColorSchemeInput,
5646
5685
  ...(typeof cssVariables !== 'boolean' && cssVariables)
@@ -5729,7 +5768,7 @@ function createSimplePaletteValueFilter(additionalPropertiesToCheck = []) {
5729
5768
  function getCircularProgressUtilityClass(slot) {
5730
5769
  return generateUtilityClass('MuiCircularProgress', slot);
5731
5770
  }
5732
- generateUtilityClasses('MuiCircularProgress', ['root', 'determinate', 'indeterminate', 'colorPrimary', 'colorSecondary', 'svg', 'circle', 'circleDeterminate', 'circleIndeterminate', 'circleDisableShrink']);
5771
+ generateUtilityClasses('MuiCircularProgress', ['root', 'determinate', 'indeterminate', 'colorPrimary', 'colorSecondary', 'svg', 'track', 'circle', 'circleDeterminate', 'circleIndeterminate', 'circleDisableShrink']);
5733
5772
 
5734
5773
  const SIZE = 44;
5735
5774
  const circularRotateKeyframe = keyframes`
@@ -5777,6 +5816,7 @@ const useUtilityClasses = ownerState => {
5777
5816
  const slots = {
5778
5817
  root: ['root', variant, `color${capitalize(color)}`],
5779
5818
  svg: ['svg'],
5819
+ track: ['track'],
5780
5820
  circle: ['circle', `circle${capitalize(variant)}`, disableShrink && 'circleDisableShrink']
5781
5821
  };
5782
5822
  return composeClasses(slots, getCircularProgressUtilityClass, classes);
@@ -5862,6 +5902,15 @@ const CircularProgressCircle = styled('circle', {
5862
5902
  }
5863
5903
  }]
5864
5904
  })));
5905
+ const CircularProgressTrack = styled('circle', {
5906
+ name: 'MuiCircularProgress',
5907
+ slot: 'Track'
5908
+ })(memoTheme(({
5909
+ theme
5910
+ }) => ({
5911
+ stroke: 'currentColor',
5912
+ opacity: (theme.vars || theme).palette.action.activatedOpacity
5913
+ })));
5865
5914
 
5866
5915
  /**
5867
5916
  * ## ARIA
@@ -5879,6 +5928,7 @@ const CircularProgress = /*#__PURE__*/React.forwardRef(function CircularProgress
5879
5928
  className,
5880
5929
  color = 'primary',
5881
5930
  disableShrink = false,
5931
+ enableTrackSlot = false,
5882
5932
  size = 40,
5883
5933
  style,
5884
5934
  thickness = 3.6,
@@ -5893,7 +5943,8 @@ const CircularProgress = /*#__PURE__*/React.forwardRef(function CircularProgress
5893
5943
  size,
5894
5944
  thickness,
5895
5945
  value,
5896
- variant
5946
+ variant,
5947
+ enableTrackSlot
5897
5948
  };
5898
5949
  const classes = useUtilityClasses(ownerState);
5899
5950
  const circleStyle = {};
@@ -5919,11 +5970,20 @@ const CircularProgress = /*#__PURE__*/React.forwardRef(function CircularProgress
5919
5970
  role: "progressbar",
5920
5971
  ...rootProps,
5921
5972
  ...other,
5922
- children: /*#__PURE__*/jsx(CircularProgressSVG, {
5973
+ children: /*#__PURE__*/jsxs(CircularProgressSVG, {
5923
5974
  className: classes.svg,
5924
5975
  ownerState: ownerState,
5925
5976
  viewBox: `${SIZE / 2} ${SIZE / 2} ${SIZE} ${SIZE}`,
5926
- children: /*#__PURE__*/jsx(CircularProgressCircle, {
5977
+ children: [enableTrackSlot ? /*#__PURE__*/jsx(CircularProgressTrack, {
5978
+ className: classes.track,
5979
+ ownerState: ownerState,
5980
+ cx: SIZE,
5981
+ cy: SIZE,
5982
+ r: (SIZE - thickness) / 2,
5983
+ fill: "none",
5984
+ strokeWidth: thickness,
5985
+ "aria-hidden": "true"
5986
+ }) : null, /*#__PURE__*/jsx(CircularProgressCircle, {
5927
5987
  className: classes.circle,
5928
5988
  style: circleStyle,
5929
5989
  ownerState: ownerState,
@@ -5932,7 +5992,7 @@ const CircularProgress = /*#__PURE__*/React.forwardRef(function CircularProgress
5932
5992
  r: (SIZE - thickness) / 2,
5933
5993
  fill: "none",
5934
5994
  strokeWidth: thickness
5935
- })
5995
+ })]
5936
5996
  })
5937
5997
  });
5938
5998
  });
@@ -5967,6 +6027,12 @@ process.env.NODE_ENV !== "production" ? CircularProgress.propTypes /* remove-pro
5967
6027
  }
5968
6028
  return null;
5969
6029
  }),
6030
+ /**
6031
+ * If `true`, a track circle slot is mounted to show a subtle background for the progress.
6032
+ * The `size` and `thickness` apply to the track slot to be consistent with the progress circle.
6033
+ * @default false
6034
+ */
6035
+ enableTrackSlot: PropTypes.bool,
5970
6036
  /**
5971
6037
  * The size of the component.
5972
6038
  * If using a number, the pixel unit is assumed.
@@ -6066,8 +6132,8 @@ var HistogramPlot = function (props) {
6066
6132
  // This is the start of the first bin out of all the traces. The global first bin.
6067
6133
  var globalFirstBinStart = void 0;
6068
6134
  if (isDateArray(data)) {
6069
- // Date bins are represented as strings. We'll need to convert them to timestamps.
6070
- 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);
6071
6137
  minTraceValue = Math.min.apply(Math, data.map(function (d) { return d.getTime(); }));
6072
6138
  }
6073
6139
  else {
@@ -6080,10 +6146,14 @@ var HistogramPlot = function (props) {
6080
6146
  minTraceValue = Math.min.apply(Math, data);
6081
6147
  globalFirstBinStart = event.points[0].data.xbins.start;
6082
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;
6083
6155
  // This minTraceValue is in the 0th bin of this trace. Find the index of this bin in the whole plot.
6084
- var clickedBinGlobalIndex = clickedBinIndex + Math.floor((minTraceValue - globalFirstBinStart) / event.points[0].data.xbins.size);
6085
- // Finally we can calculate the min and max values of the clicked bin.
6086
- var binSize = event.points[0].data.xbins.size;
6156
+ var clickedBinGlobalIndex = clickedBinIndex + Math.floor((minTraceValue - globalFirstBinStart) / binSize);
6087
6157
  var _a = [
6088
6158
  globalFirstBinStart + clickedBinGlobalIndex * binSize,
6089
6159
  globalFirstBinStart + (clickedBinGlobalIndex + 1) * binSize
@@ -6116,7 +6186,11 @@ var HistogramPlot = function (props) {
6116
6186
  // Means at least one bin has been selected
6117
6187
  var firstBinMidPoint = new Date(event.points[0].x).getTime();
6118
6188
  var lastBinMidPoint = new Date(event.points[event.points.length - 1].x).getTime();
6119
- 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;
6120
6194
  minValue = new Date(firstBinMidPoint - binSize / 2);
6121
6195
  maxValue = new Date(lastBinMidPoint + binSize / 2);
6122
6196
  }
@@ -6281,7 +6355,7 @@ var HistogramPlot = function (props) {
6281
6355
  // If binSizeOverride is provided, use it to set the bin size and range explicitly.
6282
6356
  // Plotly does a better job of setting bins and ending them at nice numbers, so only use
6283
6357
  // this prop when necessary.
6284
- var xBins = binSizeOverride
6358
+ var xBins = (binSizeOverride && allData.length > 0)
6285
6359
  ? (isDateArray(allData)
6286
6360
  ? {
6287
6361
  start: roundToPrevDay(Math.min.apply(Math, allData.map(function (d) { return d.getTime(); }))), // Find a nice round number as a starting point.
@@ -6311,7 +6385,7 @@ var HistogramPlot = function (props) {
6311
6385
  width: 0.5,
6312
6386
  },
6313
6387
  },
6314
- hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text
6388
+ hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>',
6315
6389
  };
6316
6390
  var meanAnnotation = (statsAnnotations.includes('mean') && meanLine && data.length > 0) ? [{
6317
6391
  x: meanValue,
@@ -6402,6 +6476,7 @@ var HistogramPlot = function (props) {
6402
6476
  ticklabelposition: 'outside',
6403
6477
  tickformat: isDateArray(data) ? dateTickFormat : undefined, // Format ticks for dates
6404
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,
6405
6480
  },
6406
6481
  yaxis: {
6407
6482
  title: {