td-plots 1.6.1 → 1.7.0
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/components/Histogram.d.ts +1 -1
- package/dist/components/PlusMinusControl.d.ts +1 -0
- package/dist/components/StatsDonut.d.ts +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +136 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +136 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -16,7 +16,7 @@ export type HistogramPlotProps = {
|
|
|
16
16
|
plotId?: string;
|
|
17
17
|
selectByBin?: boolean;
|
|
18
18
|
dateTickFormat?: string;
|
|
19
|
-
binSizeOverride?: number;
|
|
19
|
+
binSizeOverride?: number | string;
|
|
20
20
|
statsAnnotations?: HistogramStatsAnnotation[];
|
|
21
21
|
emptySelectedRange?: boolean;
|
|
22
22
|
d3FormatValueString?: string;
|
|
@@ -11,6 +11,7 @@ export type PlusMinusControlProps = {
|
|
|
11
11
|
colorOverride?: string;
|
|
12
12
|
valueLabelFormat?: (value: number) => string;
|
|
13
13
|
titleStylingOverrides?: React.CSSProperties;
|
|
14
|
+
disabledTooltipText?: string;
|
|
14
15
|
};
|
|
15
16
|
declare const PlusMinusControl: React.FC<PlusMinusControlProps>;
|
|
16
17
|
export default PlusMinusControl;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type StatsDonutProps = {
|
|
2
|
+
values: number[];
|
|
3
|
+
labels: string[];
|
|
4
|
+
hole: number;
|
|
5
|
+
withCenterLabel?: boolean;
|
|
6
|
+
centerLabel?: string;
|
|
7
|
+
centerValue?: string;
|
|
8
|
+
colors?: string[];
|
|
9
|
+
showLegend?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const StatsDonut: (props: StatsDonutProps) => import("react/jsx-runtime").JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { HistogramPlot } from "./components/Histogram";
|
|
|
3
3
|
export type { HistogramPlotProps } from "./components/Histogram";
|
|
4
4
|
export { RadialHistogramPlot } from "./components/RadialHistogram";
|
|
5
5
|
export type { RadialHistogramPlotProps } from "./components/RadialHistogram";
|
|
6
|
+
export { StatsDonut } from "./components/StatsDonut";
|
|
7
|
+
export type { StatsDonutProps } from "./components/StatsDonut";
|
|
6
8
|
export { default as TestPlot } from "./components/TestPlot";
|
|
7
9
|
export { isDateArray, isNumberArray } from "./components/Utils";
|
|
8
10
|
export type { PlotParams } from "react-plotly.js";
|
package/dist/index.esm.js
CHANGED
|
@@ -3,6 +3,7 @@ import React, { useEffect, lazy, useRef, useState, useMemo, Suspense } from 'rea
|
|
|
3
3
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
4
4
|
import ButtonGroup from '@mui/material/ButtonGroup';
|
|
5
5
|
import Button from '@mui/material/Button';
|
|
6
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
6
7
|
import { createSvgIcon } from '@mui/material/utils';
|
|
7
8
|
import IconButton from '@mui/material/IconButton';
|
|
8
9
|
|
|
@@ -435,7 +436,7 @@ var RemoveIcon = createSvgIcon(/*#__PURE__*/jsx("path", {
|
|
|
435
436
|
d: "M19 13H5v-2h14z"
|
|
436
437
|
}), 'Remove');
|
|
437
438
|
|
|
438
|
-
const PlusMinusControl = ({ value, onChange, steps = [1], ariaLabel = "Plus Minus Control", disabled = false, showValue = true, title = "", themeRole = "primary", colorOverride = undefined, valueLabelFormat, titleStylingOverrides = {}, }) => {
|
|
439
|
+
const PlusMinusControl = ({ value, onChange, steps = [1], ariaLabel = "Plus Minus Control", disabled = false, showValue = true, title = "", themeRole = "primary", colorOverride = undefined, valueLabelFormat, titleStylingOverrides = {}, disabledTooltipText = "Insufficient data", }) => {
|
|
439
440
|
const color = colorOverride || "#111fbcff";
|
|
440
441
|
const [disablePlus, setDisablePlus] = React.useState(false);
|
|
441
442
|
const [disableMinus, setDisableMinus] = React.useState(false);
|
|
@@ -462,39 +463,40 @@ const PlusMinusControl = ({ value, onChange, steps = [1], ariaLabel = "Plus Minu
|
|
|
462
463
|
const newValue = stepIndex === -1 ? steps[0] : steps[Math.max(stepIndex - 1, 0)];
|
|
463
464
|
onChange(newValue);
|
|
464
465
|
};
|
|
466
|
+
const buttonGroupContent = (jsxs(ButtonGroup, { size: "small", "aria-label": ariaLabel, variant: "text", disabled: disabled, orientation: "horizontal", color: themeRole, sx: {
|
|
467
|
+
backgroundColor: "background.paper",
|
|
468
|
+
"& .MuiButton-root:not(.Mui-disabled)": {
|
|
469
|
+
color: color,
|
|
470
|
+
},
|
|
471
|
+
"& .MuiButton-root:not(.Mui-disabled) .MuiSvgIcon-root": {
|
|
472
|
+
color: color,
|
|
473
|
+
},
|
|
474
|
+
}, children: [jsx(Button, { disabled: true, "aria-label": `${title}`, sx: Object.assign({ paddingRight: "10px", "&.Mui-disabled": disabled
|
|
475
|
+
? {}
|
|
476
|
+
: {
|
|
477
|
+
color: `${color} !important`,
|
|
478
|
+
}, "& .MuiSvgIcon-root": {
|
|
479
|
+
color: color,
|
|
480
|
+
backgroundColor: color,
|
|
481
|
+
} }, titleStylingOverrides), children: title }), showValue && (jsx(Button, { "aria-label": "current value", sx: {
|
|
482
|
+
pointerEvents: "none",
|
|
483
|
+
fontWeight: "600",
|
|
484
|
+
minHeight: "32px",
|
|
485
|
+
maxHeight: "32px",
|
|
486
|
+
height: "32px",
|
|
487
|
+
}, children: valueLabelFormat ? valueLabelFormat(value) : value })), jsx(Button, { onClick: handleIncrement, "aria-label": "increment", disabled: disablePlus, children: jsx(AddIcon, {}) }), jsx(Button, { onClick: handleDecrement, "aria-label": "decrement", disabled: disableMinus, children: jsx(RemoveIcon, {}) })] }));
|
|
465
488
|
return (jsx("div", { style: {
|
|
466
489
|
display: "flex",
|
|
467
490
|
flexDirection: "row",
|
|
468
491
|
alignItems: "center",
|
|
469
|
-
}, children:
|
|
470
|
-
backgroundColor: "background.paper",
|
|
471
|
-
"& .MuiButton-root:not(.Mui-disabled)": {
|
|
472
|
-
color: color,
|
|
473
|
-
},
|
|
474
|
-
"& .MuiButton-root:not(.Mui-disabled) .MuiSvgIcon-root": {
|
|
475
|
-
color: color,
|
|
476
|
-
},
|
|
477
|
-
}, children: [jsx(Button, { disabled: true, "aria-label": `${title}`, sx: Object.assign({ paddingRight: "10px", "&.Mui-disabled": disabled
|
|
478
|
-
? {}
|
|
479
|
-
: {
|
|
480
|
-
color: `${color} !important`,
|
|
481
|
-
}, "& .MuiSvgIcon-root": {
|
|
482
|
-
color: color,
|
|
483
|
-
backgroundColor: color,
|
|
484
|
-
} }, titleStylingOverrides), children: title }), showValue && (jsx(Button, { "aria-label": "current value", sx: {
|
|
485
|
-
pointerEvents: "none",
|
|
486
|
-
fontWeight: "600",
|
|
487
|
-
minHeight: "32px",
|
|
488
|
-
maxHeight: "32px",
|
|
489
|
-
height: "32px",
|
|
490
|
-
}, children: valueLabelFormat ? valueLabelFormat(value) : value })), jsx(Button, { onClick: handleIncrement, "aria-label": "increment", disabled: disablePlus, children: jsx(AddIcon, {}) }), jsx(Button, { onClick: handleDecrement, "aria-label": "decrement", disabled: disableMinus, children: jsx(RemoveIcon, {}) })] }) }));
|
|
492
|
+
}, children: disabled ? (jsx(Tooltip, { title: disabledTooltipText, arrow: true, children: jsx("span", { children: buttonGroupContent }) })) : (buttonGroupContent) }));
|
|
491
493
|
};
|
|
492
494
|
|
|
493
495
|
var SettingsIcon = createSvgIcon(/*#__PURE__*/jsx("path", {
|
|
494
496
|
d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6"
|
|
495
497
|
}), 'Settings');
|
|
496
498
|
|
|
497
|
-
const Plot$
|
|
499
|
+
const Plot$3 = lazy(() => import('react-plotly.js'));
|
|
498
500
|
const HistogramPlot = (props) => {
|
|
499
501
|
var _a, _b, _c, _d;
|
|
500
502
|
const { data, title, xAxisTitle, barColor = "rgb(72, 72, 74)", unselectedBarColor = "rgba(203, 195, 195, 0.88)", selectorsColor = "black", containerStyleOverrides, unselectedData = [], handleClickOrSelection = () => { }, onDeselect = () => { }, plotId, selectByBin = false, dateTickFormat, binSizeOverride, statsAnnotations = ["mean"], emptySelectedRange = false, d3FormatValueString = ".1f", showBinSizeControls = "always", onBinSizeCalculated, onBinSizeChange, showBinSizeControlValue = true, isMobile = false, settingsTitleStylingOverrides = {}, } = props;
|
|
@@ -1003,10 +1005,14 @@ const HistogramPlot = (props) => {
|
|
|
1003
1005
|
const isDivisibleByBinSize = isDateArray(data)
|
|
1004
1006
|
? (new Date(fixedXAxisRange[1]).getTime() -
|
|
1005
1007
|
new Date(fixedXAxisRange[0]).getTime()) %
|
|
1006
|
-
activeBinSize ===
|
|
1008
|
+
(typeof activeBinSize === "number"
|
|
1009
|
+
? activeBinSize
|
|
1010
|
+
: plotlyMToMilliseconds(activeBinSize)) ===
|
|
1007
1011
|
0
|
|
1008
1012
|
: (fixedXAxisRange[1] - fixedXAxisRange[0]) %
|
|
1009
|
-
activeBinSize ===
|
|
1013
|
+
(typeof activeBinSize === "number"
|
|
1014
|
+
? activeBinSize
|
|
1015
|
+
: plotlyMToMilliseconds(activeBinSize)) ===
|
|
1010
1016
|
0;
|
|
1011
1017
|
if (!isDivisibleByBinSize) {
|
|
1012
1018
|
// Need to extend the axis range to the next bin edge.
|
|
@@ -1169,11 +1175,29 @@ const HistogramPlot = (props) => {
|
|
|
1169
1175
|
};
|
|
1170
1176
|
}
|
|
1171
1177
|
}
|
|
1178
|
+
else if (defaultBinSize && typeof defaultBinSize === "string") {
|
|
1179
|
+
// Then we have a non-numeric bin size. It's a plotly M string
|
|
1180
|
+
// So we know we're dealing with months.
|
|
1181
|
+
const binSliderMarkValues = [1, 2, 3, 6, 12]
|
|
1182
|
+
.map((n) => n * ONEAVGMONTH)
|
|
1183
|
+
.concat([plotlyMToMilliseconds(defaultBinSize)]);
|
|
1184
|
+
const uniqueMarks = [...new Set(binSliderMarkValues)];
|
|
1185
|
+
binSliderMarks = uniqueMarks
|
|
1186
|
+
.sort((a, b) => a - b)
|
|
1187
|
+
.map((val) => ({
|
|
1188
|
+
value: val,
|
|
1189
|
+
label: `${Math.round(val / ONEAVGMONTH)} month${Math.round(val / ONEAVGMONTH) > 1 ? "s" : ""}`,
|
|
1190
|
+
}));
|
|
1191
|
+
valueLabelFormat = (value) => {
|
|
1192
|
+
const valueLabel = `${Math.round(value / ONEAVGMONTH)} month${Math.round(value / ONEAVGMONTH) > 1 ? "s" : ""}`;
|
|
1193
|
+
return valueLabel;
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1172
1196
|
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
1197
|
position: "relative",
|
|
1174
1198
|
width: "100%",
|
|
1175
1199
|
height: "100%",
|
|
1176
|
-
}, children: [showBinSizeControls !== "never" &&
|
|
1200
|
+
}, children: [showBinSizeControls !== "never" && (jsxs("div", { className: `histogram-controls ${showBinSizeControls === "onHover"
|
|
1177
1201
|
? "show-on-hover"
|
|
1178
1202
|
: "show-always"}`, style: {
|
|
1179
1203
|
position: "absolute",
|
|
@@ -1212,13 +1236,17 @@ const HistogramPlot = (props) => {
|
|
|
1212
1236
|
transition: isMobile
|
|
1213
1237
|
? ""
|
|
1214
1238
|
: "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:
|
|
1239
|
+
}, children: jsx("div", { children: jsx(PlusMinusControl, { "aria-label": "Bin Size Control", disabled: allData.length < 10, value: activeBinSize
|
|
1240
|
+
? typeof activeBinSize === "number"
|
|
1241
|
+
? activeBinSize
|
|
1242
|
+
: plotlyMToMilliseconds(activeBinSize)
|
|
1243
|
+
: 0, steps: binSliderMarks
|
|
1216
1244
|
? binSliderMarks.map((mark) => mark.value)
|
|
1217
1245
|
: [1], title: isMobile ? "Res" : "Resolution", showValue: showBinSizeControlValue, onChange: (newValue) => {
|
|
1218
1246
|
const newBinSize = newValue;
|
|
1219
1247
|
setBinSize(newBinSize);
|
|
1220
1248
|
onBinSizeChange === null || onBinSizeChange === void 0 ? void 0 : onBinSizeChange(newBinSize);
|
|
1221
|
-
}, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides }) }) })] })), jsx(Plot$
|
|
1249
|
+
}, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides, disabledTooltipText: "Requires 10 or more data points" }) }) })] })), jsx(Plot$3, { data: plotlyData, layout: layout, config: config, onSelected: handleSelection, onClick: handleClick, onDeselect: () => {
|
|
1222
1250
|
onDeselect();
|
|
1223
1251
|
setSelectedRange(null); // Remove selected box
|
|
1224
1252
|
}, onUpdate: handlePlotUpdate, useResizeHandler: true, style: {
|
|
@@ -1229,7 +1257,7 @@ const HistogramPlot = (props) => {
|
|
|
1229
1257
|
} }, `histogram-${plotId || "default"}`)] }) }) }));
|
|
1230
1258
|
};
|
|
1231
1259
|
|
|
1232
|
-
const Plot$
|
|
1260
|
+
const Plot$2 = lazy(() => import('react-plotly.js'));
|
|
1233
1261
|
const RadialHistogramPlot = (props) => {
|
|
1234
1262
|
const { data, barColor = 'rgb(72, 72, 74)', unselectedBarColor = 'rgba(203, 195, 195, 0.88)', selectorsColor = 'black', onSelected, onClick, containerStyleOverrides, barWidth = 20, // Default bar width in degrees
|
|
1235
1263
|
} = props;
|
|
@@ -1329,13 +1357,89 @@ const RadialHistogramPlot = (props) => {
|
|
|
1329
1357
|
staticPlot: false,
|
|
1330
1358
|
};
|
|
1331
1359
|
const containerStyles = Object.assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
|
|
1332
|
-
return (jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: Object.assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$
|
|
1360
|
+
return (jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: Object.assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
|
|
1333
1361
|
width: "100%",
|
|
1334
1362
|
height: "100%",
|
|
1335
1363
|
display: "block"
|
|
1336
1364
|
} }) }) }));
|
|
1337
1365
|
};
|
|
1338
1366
|
|
|
1367
|
+
const Plot$1 = lazy(() => import('react-plotly.js'));
|
|
1368
|
+
const StatsDonut = (props) => {
|
|
1369
|
+
const { withCenterLabel = false, centerLabel, centerValue, showLegend = true, } = props;
|
|
1370
|
+
const annotations = withCenterLabel
|
|
1371
|
+
? [
|
|
1372
|
+
{
|
|
1373
|
+
text: centerLabel || "",
|
|
1374
|
+
x: 0.5,
|
|
1375
|
+
y: 0.55,
|
|
1376
|
+
xref: "paper",
|
|
1377
|
+
yref: "paper",
|
|
1378
|
+
showarrow: false,
|
|
1379
|
+
font: {
|
|
1380
|
+
size: 16,
|
|
1381
|
+
color: "#666",
|
|
1382
|
+
},
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
text: centerValue || "",
|
|
1386
|
+
x: 0.5,
|
|
1387
|
+
y: 0.45,
|
|
1388
|
+
xref: "paper",
|
|
1389
|
+
yref: "paper",
|
|
1390
|
+
showarrow: false,
|
|
1391
|
+
font: {
|
|
1392
|
+
size: 24,
|
|
1393
|
+
weight: "bold",
|
|
1394
|
+
color: "#000",
|
|
1395
|
+
},
|
|
1396
|
+
},
|
|
1397
|
+
]
|
|
1398
|
+
: [];
|
|
1399
|
+
return (jsx("div", { style: {
|
|
1400
|
+
height: "400px",
|
|
1401
|
+
width: "600px",
|
|
1402
|
+
display: "flex",
|
|
1403
|
+
justifyContent: "center",
|
|
1404
|
+
alignItems: "center",
|
|
1405
|
+
}, children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$1, { data: [
|
|
1406
|
+
{
|
|
1407
|
+
type: "pie",
|
|
1408
|
+
values: props.values,
|
|
1409
|
+
labels: props.labels,
|
|
1410
|
+
hole: props.hole,
|
|
1411
|
+
marker: props.colors
|
|
1412
|
+
? {
|
|
1413
|
+
colors: props.colors,
|
|
1414
|
+
}
|
|
1415
|
+
: undefined,
|
|
1416
|
+
},
|
|
1417
|
+
], layout: {
|
|
1418
|
+
showlegend: true,
|
|
1419
|
+
annotations,
|
|
1420
|
+
height: 400,
|
|
1421
|
+
width: 600,
|
|
1422
|
+
legend: {
|
|
1423
|
+
x: 1.3,
|
|
1424
|
+
y: 0.5,
|
|
1425
|
+
font: {
|
|
1426
|
+
size: 16,
|
|
1427
|
+
},
|
|
1428
|
+
},
|
|
1429
|
+
margin: {
|
|
1430
|
+
l: 25,
|
|
1431
|
+
r: 15,
|
|
1432
|
+
t: 0,
|
|
1433
|
+
b: 0,
|
|
1434
|
+
},
|
|
1435
|
+
}, style: {
|
|
1436
|
+
width: "100%",
|
|
1437
|
+
height: "100%",
|
|
1438
|
+
}, config: {
|
|
1439
|
+
displayModeBar: false,
|
|
1440
|
+
} }) }) }));
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1339
1443
|
const Plot = lazy(() => import('react-plotly.js'));
|
|
1340
1444
|
const TestPlot = (props) => {
|
|
1341
1445
|
var _a, _b;
|
|
@@ -1355,5 +1459,5 @@ const TestPlot = (props) => {
|
|
|
1355
1459
|
return jsx(Plot, { data: data, layout: layout });
|
|
1356
1460
|
};
|
|
1357
1461
|
|
|
1358
|
-
export { HistogramPlot, RadialHistogramPlot, TestPlot, isDateArray, isNumberArray };
|
|
1462
|
+
export { HistogramPlot, RadialHistogramPlot, StatsDonut, TestPlot, isDateArray, isNumberArray };
|
|
1359
1463
|
//# sourceMappingURL=index.esm.js.map
|