td-plots 1.2.2 → 1.3.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.
- package/dist/components/Histogram.d.ts +2 -2
- package/dist/index.esm.js +81 -21
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +81 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,8 +3,7 @@ import './plotStyles.scss';
|
|
|
3
3
|
export type HistogramPlotProps = {
|
|
4
4
|
data: number[] | Date[];
|
|
5
5
|
unselectedData?: number[] | Date[];
|
|
6
|
-
|
|
7
|
-
showAllDataMeanLine?: boolean;
|
|
6
|
+
showMeanLines?: boolean;
|
|
8
7
|
title?: string;
|
|
9
8
|
xAxisTitle?: string;
|
|
10
9
|
barColor?: string;
|
|
@@ -14,6 +13,7 @@ export type HistogramPlotProps = {
|
|
|
14
13
|
containerStyleOverrides?: React.CSSProperties;
|
|
15
14
|
onDeselect?: () => void;
|
|
16
15
|
plotId?: string;
|
|
16
|
+
selectByBin?: boolean;
|
|
17
17
|
};
|
|
18
18
|
export declare const HistogramPlot: (props: HistogramPlotProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
19
|
export default HistogramPlot;
|
package/dist/index.esm.js
CHANGED
|
@@ -5840,7 +5840,7 @@ var Loading = function () {
|
|
|
5840
5840
|
var Plot$2 = lazy(function () { return import('react-plotly.js'); });
|
|
5841
5841
|
var HistogramPlot = function (props) {
|
|
5842
5842
|
var _a, _b;
|
|
5843
|
-
var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _c = props.barColor, barColor = _c === void 0 ? 'rgb(72, 72, 74)' : _c, _d = props.unselectedBarColor, unselectedBarColor = _d === void 0 ? 'rgba(203, 195, 195, 0.88)' : _d, _e = props.selectorsColor, selectorsColor = _e === void 0 ? 'black' : _e, _f = props.
|
|
5843
|
+
var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _c = props.barColor, barColor = _c === void 0 ? 'rgb(72, 72, 74)' : _c, _d = props.unselectedBarColor, unselectedBarColor = _d === void 0 ? 'rgba(203, 195, 195, 0.88)' : _d, _e = props.selectorsColor, selectorsColor = _e === void 0 ? 'black' : _e, _f = props.showMeanLines, showMeanLines = _f === void 0 ? true : _f, containerStyleOverrides = props.containerStyleOverrides, _g = props.unselectedData, unselectedData = _g === void 0 ? [] : _g, _h = props.handleClickOrSelection, handleClickOrSelection = _h === void 0 ? function () { } : _h, _j = props.onDeselect, onDeselect = _j === void 0 ? function () { } : _j, plotId = props.plotId, _k = props.selectByBin, selectByBin = _k === void 0 ? false : _k;
|
|
5844
5844
|
// Ref for plot container
|
|
5845
5845
|
var containerRef = useRef(null);
|
|
5846
5846
|
// Track any selections made in this plot so we can style the selection box.
|
|
@@ -5851,14 +5851,23 @@ var HistogramPlot = function (props) {
|
|
|
5851
5851
|
// to access that information once the plot has been initialized so that we can prevent the
|
|
5852
5852
|
// axis range from changing during interaction. Dates use strings.
|
|
5853
5853
|
var _m = useState(undefined), fixedXAxisRange = _m[0], setFixedXAxisRange = _m[1];
|
|
5854
|
+
// Once the plot is drawn, record the initial axis range so we can keep it fixed.
|
|
5854
5855
|
// figure should be Readonly<Plotly.Figure> but react-plotly.js doesn't expose that type, so we use any.
|
|
5855
|
-
var
|
|
5856
|
-
var _a
|
|
5857
|
-
if (
|
|
5858
|
-
var
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5856
|
+
var handlePlotUpdate = function (figure, graphDiv) {
|
|
5857
|
+
var _a;
|
|
5858
|
+
if (!fixedXAxisRange) {
|
|
5859
|
+
var currentLayout = graphDiv._fullLayout;
|
|
5860
|
+
if ((_a = currentLayout === null || currentLayout === void 0 ? void 0 : currentLayout.xaxis) === null || _a === void 0 ? void 0 : _a.range) {
|
|
5861
|
+
var range = currentLayout.xaxis.range;
|
|
5862
|
+
// Skip temporary [-1, 1] range
|
|
5863
|
+
if (range[0] === -1 && range[1] === 1) {
|
|
5864
|
+
return;
|
|
5865
|
+
}
|
|
5866
|
+
var computedRange = typeof (range[0]) === 'string'
|
|
5867
|
+
? [new Date(range[0]), new Date(range[1])]
|
|
5868
|
+
: [range[0], range[1]];
|
|
5869
|
+
setFixedXAxisRange(computedRange);
|
|
5870
|
+
}
|
|
5862
5871
|
}
|
|
5863
5872
|
};
|
|
5864
5873
|
// Create handler for click event that can use event data to update the plot if desired.
|
|
@@ -5927,22 +5936,73 @@ var HistogramPlot = function (props) {
|
|
|
5927
5936
|
var minValue;
|
|
5928
5937
|
var maxValue;
|
|
5929
5938
|
if (typeof event.range.x[0] === 'string' && typeof event.range.x[1] === 'string') {
|
|
5930
|
-
// Then we must be dealing with dates
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5939
|
+
// Then we are must be dealing with dates
|
|
5940
|
+
if (selectByBin) {
|
|
5941
|
+
// Set selected range to include the whole bin if at least half the bin is within the explicit range
|
|
5942
|
+
// Plotly already tells us which bins were selected based on this logic. These are the points in the event.
|
|
5943
|
+
if (event.points && event.points.length > 0) {
|
|
5944
|
+
// Means at least one bin has been selected
|
|
5945
|
+
var firstBinMidPoint = new Date(event.points[0].x).getTime();
|
|
5946
|
+
var lastBinMidPoint = new Date(event.points[event.points.length - 1].x).getTime();
|
|
5947
|
+
var binSize = event.points[0].data.xbins.size;
|
|
5948
|
+
minValue = new Date(firstBinMidPoint - binSize / 2);
|
|
5949
|
+
maxValue = new Date(lastBinMidPoint + binSize / 2);
|
|
5950
|
+
}
|
|
5951
|
+
else {
|
|
5952
|
+
// No bins selected, so the range should be empty.
|
|
5953
|
+
minValue = new Date(event.range.x[0]);
|
|
5954
|
+
maxValue = minValue;
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
else {
|
|
5958
|
+
// Set the range based on the explicit selection boundaries
|
|
5959
|
+
minValue = new Date(event.range.x[0]);
|
|
5960
|
+
maxValue = new Date(event.range.x[1]);
|
|
5961
|
+
}
|
|
5934
5962
|
}
|
|
5935
5963
|
else {
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5964
|
+
// Handle selection for numbers
|
|
5965
|
+
if (selectByBin) {
|
|
5966
|
+
// Set the range based on the bins selected. Plotly will include a bin in event.points if
|
|
5967
|
+
// at least half of it is selected.
|
|
5968
|
+
if (event.points && event.points.length > 0) {
|
|
5969
|
+
var firstBinMidPoint = event.points[0].x;
|
|
5970
|
+
var lastBinMidPoint = event.points[event.points.length - 1].x;
|
|
5971
|
+
var binSize = event.points[0].data.xbins.size;
|
|
5972
|
+
var roundedMinValue = firstBinMidPoint - binSize / 2;
|
|
5973
|
+
var roundedMaxValue = lastBinMidPoint + binSize / 2;
|
|
5974
|
+
minValue = roundedMinValue;
|
|
5975
|
+
maxValue = roundedMaxValue;
|
|
5976
|
+
}
|
|
5977
|
+
else {
|
|
5978
|
+
// No bins selected, so set the range to be empty.
|
|
5979
|
+
minValue = event.range.x[0];
|
|
5980
|
+
maxValue = minValue;
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
else {
|
|
5984
|
+
// Set the range based on the explicit selection boundaries
|
|
5985
|
+
minValue = event.range.x[0];
|
|
5986
|
+
maxValue = event.range.x[1];
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
if (minValue !== undefined && maxValue !== undefined) {
|
|
5990
|
+
// Update selected range. Have to be strict about types.
|
|
5991
|
+
if (typeof minValue === 'number' && typeof maxValue === 'number') {
|
|
5992
|
+
setSelectedRange([minValue, maxValue]);
|
|
5993
|
+
}
|
|
5994
|
+
else if (minValue instanceof Date && maxValue instanceof Date) {
|
|
5995
|
+
setSelectedRange([minValue, maxValue]);
|
|
5996
|
+
}
|
|
5997
|
+
handleClickOrSelection(minValue, maxValue);
|
|
5939
5998
|
}
|
|
5940
|
-
handleClickOrSelection(minValue, maxValue);
|
|
5941
5999
|
};
|
|
5942
6000
|
// Create the selected range box
|
|
5943
6001
|
var selectedRangeBox = useMemo(function () {
|
|
5944
6002
|
if (!selectedRange)
|
|
5945
6003
|
return [];
|
|
6004
|
+
if (unselectedData.length === 0)
|
|
6005
|
+
return []; // Don't show the box if the entire dataset is selected.
|
|
5946
6006
|
// Create a multiply-like effect by using a semi-transparent dark overlay
|
|
5947
6007
|
var multiplyColor = 'rgba(29, 104, 185, 0.1)';
|
|
5948
6008
|
return [{
|
|
@@ -5959,7 +6019,7 @@ var HistogramPlot = function (props) {
|
|
|
5959
6019
|
},
|
|
5960
6020
|
layer: 'above' // Ensure the selection box is above the bars
|
|
5961
6021
|
}];
|
|
5962
|
-
}, [selectedRange]);
|
|
6022
|
+
}, [selectedRange, unselectedData]);
|
|
5963
6023
|
var unselectedTrace = {
|
|
5964
6024
|
x: unselectedData,
|
|
5965
6025
|
type: 'histogram',
|
|
@@ -5998,7 +6058,7 @@ var HistogramPlot = function (props) {
|
|
|
5998
6058
|
// Calculate the mean of the selected data using normalized data
|
|
5999
6059
|
var meanValue = (_a = calculateMean(data)) !== null && _a !== void 0 ? _a : 0; // Default to 0 if no data
|
|
6000
6060
|
var meanLineRadius = 0.01; // distance from the top of the y axis to the top/bottom end of the mean line
|
|
6001
|
-
var meanLine =
|
|
6061
|
+
var meanLine = (showMeanLines && data.length > 0) ? [{
|
|
6002
6062
|
type: 'line',
|
|
6003
6063
|
x0: meanValue,
|
|
6004
6064
|
y0: 1 - meanLineRadius,
|
|
@@ -6013,7 +6073,7 @@ var HistogramPlot = function (props) {
|
|
|
6013
6073
|
// Draw mean line for all data
|
|
6014
6074
|
var allData = __spreadArray(__spreadArray([], data, true), unselectedData, true);
|
|
6015
6075
|
var allDataMeanValue = (_b = calculateMean(allData)) !== null && _b !== void 0 ? _b : 0;
|
|
6016
|
-
var allDataMeanLine = (
|
|
6076
|
+
var allDataMeanLine = (showMeanLines && unselectedData.length > 0 && data.length > 0) ? [{
|
|
6017
6077
|
type: 'line',
|
|
6018
6078
|
x0: allDataMeanValue,
|
|
6019
6079
|
y0: 1 - meanLineRadius,
|
|
@@ -6082,7 +6142,7 @@ var HistogramPlot = function (props) {
|
|
|
6082
6142
|
dragmode: 'select', // Enable drag to select
|
|
6083
6143
|
selectdirection: 'h', // User can select in horizontal direction only
|
|
6084
6144
|
shapes: __spreadArray(__spreadArray(__spreadArray([], allDataMeanLine, true), meanLine, true), selectedRangeBox, true), // Add the mean line and selection box
|
|
6085
|
-
annotations: (
|
|
6145
|
+
annotations: (showMeanLines && meanLine && data.length > 0) ? [{
|
|
6086
6146
|
x: meanValue,
|
|
6087
6147
|
y: 1 + meanLineRadius + 0.04, // Position above the mean line. Value set with respect to the paper coordinates.
|
|
6088
6148
|
yref: 'paper',
|
|
@@ -6111,7 +6171,7 @@ var HistogramPlot = function (props) {
|
|
|
6111
6171
|
return (jsx("div", { ref: containerRef, className: "plot-container ".concat(plotId), style: __assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Fragment, { children: jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: handleSelection, onClick: handleClick, onDeselect: function () {
|
|
6112
6172
|
onDeselect();
|
|
6113
6173
|
setSelectedRange(null); // Remove selected box
|
|
6114
|
-
},
|
|
6174
|
+
}, onUpdate: handlePlotUpdate, useResizeHandler: true, style: {
|
|
6115
6175
|
width: "100%",
|
|
6116
6176
|
height: "100%",
|
|
6117
6177
|
display: "block"
|