td-plots 1.6.0 → 1.6.1

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.
@@ -3,7 +3,6 @@ export type PlusMinusControlProps = {
3
3
  value: number;
4
4
  onChange: (newValue: number) => void;
5
5
  steps: number[];
6
- defaultValue: number;
7
6
  ariaLabel?: string;
8
7
  disabled?: boolean;
9
8
  showValue?: boolean;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import './components/plotStyles.scss';
2
- export { HistogramPlot } from './components/Histogram';
3
- export type { HistogramPlotProps } from './components/Histogram';
4
- export { RadialHistogramPlot } from './components/RadialHistogram';
5
- export type { RadialHistogramPlotProps } from './components/RadialHistogram';
6
- export { default as TestPlot } from './components/TestPlot';
7
- export { isDateArray, isNumberArray } from './components/Utils';
8
- export type { PlotParams } from 'react-plotly.js';
1
+ import "./components/plotStyles.scss";
2
+ export { HistogramPlot } from "./components/Histogram";
3
+ export type { HistogramPlotProps } from "./components/Histogram";
4
+ export { RadialHistogramPlot } from "./components/RadialHistogram";
5
+ export type { RadialHistogramPlotProps } from "./components/RadialHistogram";
6
+ export { default as TestPlot } from "./components/TestPlot";
7
+ export { isDateArray, isNumberArray } from "./components/Utils";
8
+ export type { PlotParams } from "react-plotly.js";
package/dist/index.esm.js CHANGED
@@ -33,7 +33,7 @@ function styleInject(css, ref) {
33
33
  }
34
34
  }
35
35
 
36
- 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}";
36
+ 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}.histogram-controls{pointer-events:auto}.histogram-controls.show-always{opacity:1;visibility:visible}.histogram-controls.show-on-hover{opacity:0;transition:opacity .2s ease-in-out,visibility .2s ease-in-out;visibility:hidden}.plot-container:hover .histogram-controls.show-on-hover{opacity:1;visibility:visible}";
37
37
  styleInject(css_248z);
38
38
 
39
39
  function formatDecimal(x) {
@@ -435,7 +435,7 @@ var RemoveIcon = createSvgIcon(/*#__PURE__*/jsx("path", {
435
435
  d: "M19 13H5v-2h14z"
436
436
  }), 'Remove');
437
437
 
438
- const PlusMinusControl = ({ value, onChange, steps = [1], ariaLabel = "Plus Minus Control", disabled = false, showValue = true, title = "", themeRole = "primary", colorOverride = undefined, defaultValue, valueLabelFormat, titleStylingOverrides = {}, }) => {
438
+ const PlusMinusControl = ({ value, onChange, steps = [1], ariaLabel = "Plus Minus Control", disabled = false, showValue = true, title = "", themeRole = "primary", colorOverride = undefined, valueLabelFormat, titleStylingOverrides = {}, }) => {
439
439
  const color = colorOverride || "#111fbcff";
440
440
  const [disablePlus, setDisablePlus] = React.useState(false);
441
441
  const [disableMinus, setDisableMinus] = React.useState(false);
@@ -527,7 +527,6 @@ const HistogramPlot = (props) => {
527
527
  // Set the default bin size (calculated by plotly), and the current bin size (may be adjusted by the user).
528
528
  const [defaultBinSize, setDefaultBinSize] = useState(undefined);
529
529
  const [binSize, setBinSize] = useState(undefined);
530
- const [isHoveringPlot, setIsHoveringPlot] = useState(false);
531
530
  const [isControlsExpanded, setIsControlsExpanded] = useState(false);
532
531
  // Set the top/left position on the axes relative to the plot container.
533
532
  const [plotAreaPosition, setPlotAreaPosition] = useState(null);
@@ -549,7 +548,9 @@ const HistogramPlot = (props) => {
549
548
  // _offset gives the top/left position of the plot area in pixels from container top
550
549
  const top = yaxis._offset || 0;
551
550
  const left = xaxis._offset || 0;
552
- if (!plotAreaPosition) {
551
+ if (!plotAreaPosition ||
552
+ top !== plotAreaPosition.top ||
553
+ left !== plotAreaPosition.left) {
553
554
  setPlotAreaPosition({ top, left });
554
555
  }
555
556
  }
@@ -570,9 +571,7 @@ const HistogramPlot = (props) => {
570
571
  figure.data.length > 0 &&
571
572
  figure.data[0].xbins &&
572
573
  figure.data[0].xbins.size) {
573
- const calculatedBinSize = typeof figure.data[0].xbins.size === "string"
574
- ? plotlyMToMilliseconds(figure.data[0].xbins.size)
575
- : figure.data[0].xbins.size;
574
+ const calculatedBinSize = figure.data[0].xbins.size;
576
575
  setDefaultBinSize(calculatedBinSize);
577
576
  setBinSize(calculatedBinSize);
578
577
  onBinSizeCalculated === null || onBinSizeCalculated === void 0 ? void 0 : onBinSizeCalculated(calculatedBinSize);
@@ -897,10 +896,10 @@ const HistogramPlot = (props) => {
897
896
  ? isDateArray(allData)
898
897
  ? {
899
898
  start: fixedXAxisRange && fixedXAxisRange[0]
900
- ? new Date(fixedXAxisRange[0]).getTime()
899
+ ? fixedXAxisRange[0] // May be a string like 2025-09-03, and that's okay for dates.
901
900
  : roundToPrevDay(Math.min(...allData.map((d) => d.getTime()))), // Find a nice round number as a starting point.
902
901
  end: roundToNextDay(Math.max(...allData.map((d) => d.getTime()))),
903
- size: activeBinSize, // bin size in milliseconds
902
+ size: activeBinSize, // bin size in milliseconds or plotly's M string for months.
904
903
  }
905
904
  : isNumberArray(allData)
906
905
  ? {
@@ -1135,7 +1134,9 @@ const HistogramPlot = (props) => {
1135
1134
  .map((n) => n * ONEMINUTE)
1136
1135
  .concat([defaultBinSize]);
1137
1136
  const uniqueMarks = [...new Set(binSliderMarkValues)];
1138
- binSliderMarks = uniqueMarks.map((val) => ({
1137
+ binSliderMarks = uniqueMarks
1138
+ .sort((a, b) => a - b)
1139
+ .map((val) => ({
1139
1140
  value: val,
1140
1141
  label: `${Math.round(val / conversionFactor)} ${unitOfTime}${Math.round(val / conversionFactor) > 1 ? "s" : ""}`,
1141
1142
  }));
@@ -1157,7 +1158,9 @@ const HistogramPlot = (props) => {
1157
1158
  ]
1158
1159
  : [0.1, 0.5, 1];
1159
1160
  const uniqueMarks = [...new Set(binSliderMarkValues)];
1160
- binSliderMarks = uniqueMarks.map((val) => ({
1161
+ binSliderMarks = uniqueMarks
1162
+ .sort((a, b) => a - b)
1163
+ .map((val) => ({
1161
1164
  value: val,
1162
1165
  label: `${val}`,
1163
1166
  }));
@@ -1166,66 +1169,64 @@ const HistogramPlot = (props) => {
1166
1169
  };
1167
1170
  }
1168
1171
  }
1169
- return (jsx("div", { ref: containerRef, className: `plot-container ${plotId}`, style: Object.assign({ "--selection-color": selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx("div", { style: {
1172
+ return (jsx("div", { ref: containerRef, className: `plot-container ${plotId}`, style: Object.assign({ "--selection-color": selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsxs("div", { style: {
1173
+ position: "relative",
1170
1174
  width: "100%",
1171
1175
  height: "100%",
1172
- display: "flex",
1173
- flexDirection: "column",
1174
- gap: "10px",
1175
- }, children: jsxs("div", { style: { position: "relative", width: "100%", height: "100%" }, onMouseEnter: () => setIsHoveringPlot(true), onMouseLeave: () => setIsHoveringPlot(false), children: [(showBinSizeControls === "always" ||
1176
- (showBinSizeControls === "onHover" && isHoveringPlot)) &&
1177
- typeof binSize === "number" && (jsxs("div", { style: {
1178
- position: "absolute",
1179
- top: plotAreaPosition
1180
- ? `${plotAreaPosition.top + 5}px`
1181
- : "44px",
1182
- left: plotAreaPosition
1183
- ? `${plotAreaPosition.left + 5}px`
1184
- : "65px",
1185
- zIndex: 1000,
1186
- display: "flex",
1187
- alignItems: isMobile ? "flex-start" : "center",
1188
- gap: "8px",
1189
- flexDirection: isMobile ? "column" : "row",
1190
- }, children: [jsx(IconButton, { onClick: () => setIsControlsExpanded(!isControlsExpanded), size: "small", sx: {
1191
- backgroundColor: "rgba(255, 255, 255, 0.95)",
1192
- color: barColor,
1193
- borderRadius: "4px",
1194
- boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
1195
- border: "1px solid rgba(0, 0, 0, 0.12)",
1196
- width: "32px",
1197
- height: "32px",
1198
- "&:hover": {
1199
- backgroundColor: "rgba(255, 255, 255, 1)",
1200
- boxShadow: "0 2px 10px rgba(0,0,0,0.2)",
1201
- },
1202
- }, children: jsx(SettingsIcon, { fontSize: "small" }) }), jsx("div", { style: {
1203
- backgroundColor: "rgba(255, 255, 255, 0.95)",
1204
- borderRadius: "4px",
1205
- boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
1206
- border: "1px solid rgba(0, 0, 0, 0.12)",
1207
- overflow: "hidden",
1208
- maxWidth: isControlsExpanded ? "fit-content" : "0",
1209
- opacity: isControlsExpanded ? 1 : 0,
1210
- paddingLeft: "6px",
1211
- transition: isMobile
1212
- ? ""
1213
- : "max-width 0.15s ease-in-out, opacity 0.15s ease-in-out",
1214
- }, children: jsx("div", { children: jsx(PlusMinusControl, { "aria-label": "Bin Size Control", disabled: data.length < 10, value: activeBinSize, steps: binSliderMarks
1215
- ? binSliderMarks.map((mark) => mark.value)
1216
- : [1], defaultValue: defaultBinSize !== null && defaultBinSize !== void 0 ? defaultBinSize : 1, title: isMobile ? "Res" : "Resolution", showValue: showBinSizeControlValue, onChange: (newValue) => {
1217
- const newBinSize = newValue;
1218
- setBinSize(newBinSize);
1219
- onBinSizeChange === null || onBinSizeChange === void 0 ? void 0 : onBinSizeChange(newBinSize);
1220
- }, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides }) }) })] })), jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: handleSelection, onClick: handleClick, onDeselect: () => {
1221
- onDeselect();
1222
- setSelectedRange(null); // Remove selected box
1223
- }, onUpdate: handlePlotUpdate, useResizeHandler: true, style: {
1224
- width: "100%",
1225
- height: "100%",
1226
- display: "block",
1227
- transition: "opacity 0.15s ease-in-out",
1228
- } }, `histogram-${plotId || "default"}`)] }) }) }) }));
1176
+ }, children: [showBinSizeControls !== "never" && typeof binSize === "number" && (jsxs("div", { className: `histogram-controls ${showBinSizeControls === "onHover"
1177
+ ? "show-on-hover"
1178
+ : "show-always"}`, style: {
1179
+ position: "absolute",
1180
+ top: plotAreaPosition
1181
+ ? `${plotAreaPosition.top + 5}px`
1182
+ : "44px",
1183
+ left: plotAreaPosition
1184
+ ? `${plotAreaPosition.left + 5}px`
1185
+ : "65px",
1186
+ zIndex: 1000,
1187
+ display: "flex",
1188
+ alignItems: isMobile ? "flex-start" : "center",
1189
+ gap: "8px",
1190
+ flexDirection: isMobile ? "column" : "row",
1191
+ }, children: [jsx(IconButton, { onClick: () => setIsControlsExpanded(!isControlsExpanded), size: "small", sx: {
1192
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
1193
+ color: barColor,
1194
+ borderRadius: "4px",
1195
+ boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
1196
+ border: "1px solid rgba(0, 0, 0, 0.12)",
1197
+ width: "32px",
1198
+ height: "32px",
1199
+ "&:hover": {
1200
+ backgroundColor: "rgba(255, 255, 255, 1)",
1201
+ boxShadow: "0 2px 10px rgba(0,0,0,0.2)",
1202
+ },
1203
+ }, children: jsx(SettingsIcon, { fontSize: "small" }) }), jsx("div", { style: {
1204
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
1205
+ borderRadius: "4px",
1206
+ boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
1207
+ border: "1px solid rgba(0, 0, 0, 0.12)",
1208
+ overflow: "hidden",
1209
+ maxWidth: isControlsExpanded ? "fit-content" : "0",
1210
+ opacity: isControlsExpanded ? 1 : 0,
1211
+ paddingLeft: "6px",
1212
+ transition: isMobile
1213
+ ? ""
1214
+ : "max-width 0.15s ease-in-out, opacity 0.15s ease-in-out",
1215
+ }, children: jsx("div", { children: jsx(PlusMinusControl, { "aria-label": "Bin Size Control", disabled: data.length < 10, value: activeBinSize, steps: binSliderMarks
1216
+ ? binSliderMarks.map((mark) => mark.value)
1217
+ : [1], title: isMobile ? "Res" : "Resolution", showValue: showBinSizeControlValue, onChange: (newValue) => {
1218
+ const newBinSize = newValue;
1219
+ setBinSize(newBinSize);
1220
+ onBinSizeChange === null || onBinSizeChange === void 0 ? void 0 : onBinSizeChange(newBinSize);
1221
+ }, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides }) }) })] })), jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: handleSelection, onClick: handleClick, onDeselect: () => {
1222
+ onDeselect();
1223
+ setSelectedRange(null); // Remove selected box
1224
+ }, onUpdate: handlePlotUpdate, useResizeHandler: true, style: {
1225
+ width: "100%",
1226
+ height: "100%",
1227
+ display: "block",
1228
+ transition: "opacity 0.15s ease-in-out",
1229
+ } }, `histogram-${plotId || "default"}`)] }) }) }));
1229
1230
  };
1230
1231
 
1231
1232
  const Plot$1 = lazy(() => import('react-plotly.js'));