td-plots 1.0.1 → 1.1.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/README.md CHANGED
@@ -1,41 +1,153 @@
1
1
  # td-plots
2
2
 
3
- A React + TypeScript component library for interactive Plotly.js charts, with Storybook documentation and Vite-powered builds.
3
+ A React + TypeScript component library for interactive Plotly.js charts, with Storybook documentation and comprehensive testing.
4
4
 
5
+ [![CI](https://github.com/asizemore/td-plots/actions/workflows/ci.yml/badge.svg)](https://github.com/asizemore/td-plots/actions/workflows/ci.yml)
6
+ [![npm version](https://badge.fury.io/js/td-plots.svg)](https://badge.fury.io/js/td-plots)
5
7
 
6
- ## Getting Started
7
8
 
8
- ### Install dependencies
9
- ```sh
10
- pnpm install
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install td-plots
13
+ # or
14
+ yarn add td-plots
15
+ # or
16
+ pnpm add td-plots
11
17
  ```
12
18
 
13
- ### Run Storybook
14
- ```sh
19
+ ## Development
20
+ ### Prerequisites
21
+
22
+ - Node.js 18+
23
+ - pnpm 8+
24
+
25
+ ### Setup
26
+
27
+ 1. **Clone the repository**
28
+ ```bash
29
+ git clone https://github.com/asizemore/td-plots.git
30
+ cd td-plots
31
+ ```
32
+
33
+ 2. **Install dependencies**
34
+ ```bash
35
+ pnpm install
36
+ ```
37
+
38
+ 3. **Set up environment variables**
39
+ Copy `.env.sample` to `.env` and configure:
40
+ ```bash
41
+ CHROMATIC_PROJECT_TOKEN=your_chromatic_token_here
42
+ ```
43
+
44
+ ### Development Commands
45
+
46
+ ```bash
47
+ # Start Storybook development server
15
48
  pnpm storybook
16
- ```
17
49
 
18
- ### Build the library
19
- ```sh
50
+ # Build the library
20
51
  pnpm run build
52
+
53
+ # Run tests
54
+ pnpm test
55
+
56
+ # Run tests in watch mode
57
+ pnpm test --watch
58
+
59
+ # Build Storybook for production
60
+ pnpm build-storybook
61
+
62
+ # Publish to Chromatic (visual testing)
63
+ pnpm chromatic
21
64
  ```
22
65
 
23
- ## Usage Example
66
+ ### Local Development Linking
67
+
68
+ To use this package in another local project during development:
69
+
70
+ 1. **In this package directory:**
71
+ ```bash
72
+ pnpm link --global
73
+ ```
24
74
 
25
- Import and use the `TestPlot` component in your React app:
75
+ 2. **In your target project:**
76
+ ```bash
77
+ pnpm link td-plots
78
+ ```
79
+
80
+ Alternatively, you can link directly (I have best results with this):
81
+ ```bash
82
+ pnpm add file:../td-plots
83
+ ```
84
+
85
+ Build `td-plots` and watch for new changes with
86
+ ```bash
87
+ pnpm dev:full
88
+ ```
89
+
90
+ If the target project doesn't see the new updates, try unlinking and relinking, or clearing cache
91
+ ```bash
92
+ # Clear Parcel cache
93
+ rm -rf .parcel-cache
94
+ rm -rf dist
95
+ ```
96
+ and then restarting the target project.
97
+
98
+
99
+ To unlink, run
100
+ ```bash
101
+ pnpm unlink td-plots
102
+ ```
103
+
104
+
105
+
106
+ ## Components
107
+
108
+ ### HistogramPlot
109
+
110
+ Interactive histogram component with click and selection event handling.
26
111
 
27
112
  ```tsx
28
- import { TestPlot } from './src/components/TestPlot';
113
+ import { HistogramPlot } from 'td-plots';
29
114
 
30
- export default function App() {
31
- return <TestPlot xaxisTitle="X Label" yaxisTitle="Y Label" />;
115
+ function MyComponent() {
116
+ const data = [1, 2, 3, 4, 5, 2, 3, 4, 1, 2];
117
+
118
+ return (
119
+ <HistogramPlot
120
+ data={data}
121
+ title="My Histogram"
122
+ xAxisTitle="Values"
123
+ barColor="rgb(72, 72, 74)"
124
+ onClick={(event) => console.log('Clicked:', event)}
125
+ onSelected={(event) => console.log('Selected:', event)}
126
+ />
127
+ );
32
128
  }
33
129
  ```
34
130
 
35
- ## Project Structure
36
- - `src/components/` – Plot components (e.g., `TestPlot.tsx`)
37
- - `stories/` – Storybook stories for components
38
131
 
39
132
 
133
+
134
+ ## Testing
135
+
136
+ This package uses vitest for testing.
137
+
138
+ Run tests locally:
139
+ ```bash
140
+ pnpm test # Run all tests
141
+ pnpm test --ui # Run with Vitest UI
142
+ pnpm test --coverage # Run with coverage report
143
+ ```
144
+
40
145
  ## License
41
- MIT
146
+
147
+ MIT
148
+
149
+ ## Support
150
+
151
+ - 📖 [Storybook Documentation](https://main--6871481055cbf1b95be162e1.chromatic.com)
152
+ - 🐛 [Issue Tracker](https://github.com/asizemore/td-plots/issues)
153
+ - 💬 [Discussions](https://github.com/asizemore/td-plots/discussions)
@@ -1,11 +1,17 @@
1
+ import React from 'react';
1
2
  import './plotStyles.scss';
2
3
  export type HistogramPlotProps = {
3
- data: number[];
4
+ data: number[] | Date[];
5
+ showMeanLine?: boolean;
6
+ meanLineColor?: string;
4
7
  title?: string;
5
8
  xAxisTitle?: string;
6
9
  barColor?: string;
7
10
  unselectedBarColor?: string;
8
11
  selectorsColor?: string;
12
+ onSelected?: (event: Plotly.PlotSelectionEvent) => void;
13
+ onClick?: (event: Plotly.PlotMouseEvent) => void;
14
+ containerStyleOverrides?: React.CSSProperties;
9
15
  };
10
16
  export declare const HistogramPlot: (props: HistogramPlotProps) => import("react/jsx-runtime").JSX.Element;
11
17
  export default HistogramPlot;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import './plotStyles.scss';
3
+ export type RadialHistogramPlotProps = {
4
+ data: number[];
5
+ barColor?: string;
6
+ unselectedBarColor?: string;
7
+ selectorsColor?: string;
8
+ onSelected?: (event: Plotly.PlotSelectionEvent) => void;
9
+ onClick?: (event: Plotly.PlotMouseEvent) => void;
10
+ containerStyleOverrides?: React.CSSProperties;
11
+ barWidth?: number;
12
+ };
13
+ export declare const RadialHistogramPlot: (props: RadialHistogramPlotProps) => import("react/jsx-runtime").JSX.Element | null;
14
+ export default RadialHistogramPlot;
@@ -0,0 +1,4 @@
1
+ export declare const isNumberArray: (arr: unknown[]) => arr is number[];
2
+ export declare const isDateArray: (arr: unknown[]) => arr is Date[];
3
+ export declare function calculateMean(arr: number[] | Date[]): number | undefined;
4
+ export declare const formatDateMDY: (timestamp: number) => string;
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- .plot-container{height:100%;overflow:hidden!important;width:100%}.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}
1
+ .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}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ import './components/plotStyles.scss';
1
2
  export { HistogramPlot } from './components/Histogram';
2
3
  export type { HistogramPlotProps } from './components/Histogram';
4
+ export { RadialHistogramPlot } from './components/RadialHistogram';
5
+ export type { RadialHistogramPlotProps } from './components/RadialHistogram';
3
6
  export { default as TestPlot } from './components/TestPlot';
4
7
  export type { PlotParams } from 'react-plotly.js';
@@ -1 +1 @@
1
- .plot-container{height:100%;overflow:hidden!important;width:100%}.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}
1
+ .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}
package/dist/index.esm.js CHANGED
@@ -1,9 +1,67 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { lazy } from 'react';
2
+ import { lazy, useRef, Suspense } from 'react';
3
3
 
4
- var Plot$1 = lazy(function () { return import('react-plotly.js'); });
4
+ /******************************************************************************
5
+ Copyright (c) Microsoft Corporation.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16
+ PERFORMANCE OF THIS SOFTWARE.
17
+ ***************************************************************************** */
18
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
19
+
20
+
21
+ var __assign = function() {
22
+ __assign = Object.assign || function __assign(t) {
23
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
24
+ s = arguments[i];
25
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
26
+ }
27
+ return t;
28
+ };
29
+ return __assign.apply(this, arguments);
30
+ };
31
+
32
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
33
+ var e = new Error(message);
34
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
35
+ };
36
+
37
+ // Utility functions for our components
38
+ // Type guard to check if array contains only numbers
39
+ var isNumberArray = function (arr) {
40
+ return arr.every(function (item) { return typeof item === 'number' && !isNaN(item); });
41
+ };
42
+ // Type guard to check if array contains only dates
43
+ var isDateArray = function (arr) {
44
+ return arr.every(function (item) { return item instanceof Date; });
45
+ };
46
+ // Calculate the mean of an array of numbers or dates
47
+ function calculateMean(arr) {
48
+ if (arr.length === 0)
49
+ return undefined;
50
+ if (isNumberArray(arr)) {
51
+ return arr.reduce(function (acc, num) { return acc + num; }, 0) / arr.length;
52
+ }
53
+ else if (isDateArray(arr)) {
54
+ var sum = arr.reduce(function (acc, date) { return acc + date.getTime(); }, 0);
55
+ return sum / arr.length;
56
+ }
57
+ }
58
+
59
+ var Plot$2 = lazy(function () { return import('react-plotly.js'); });
5
60
  var HistogramPlot = function (props) {
6
- var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _a = props.barColor, barColor = _a === void 0 ? 'rgb(72, 72, 74)' : _a, _b = props.unselectedBarColor, unselectedBarColor = _b === void 0 ? 'rgba(203, 195, 195, 0.88)' : _b, _c = props.selectorsColor, selectorsColor = _c === void 0 ? 'black' : _c;
61
+ var _a;
62
+ var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _b = props.barColor, barColor = _b === void 0 ? 'rgb(72, 72, 74)' : _b, _c = props.unselectedBarColor, unselectedBarColor = _c === void 0 ? 'rgba(203, 195, 195, 0.88)' : _c, _d = props.selectorsColor, selectorsColor = _d === void 0 ? 'black' : _d, onSelected = props.onSelected, onClick = props.onClick, _e = props.showMeanLine, showMeanLine = _e === void 0 ? true : _e, _f = props.meanLineColor, meanLineColor = _f === void 0 ? 'grey' : _f, containerStyleOverrides = props.containerStyleOverrides;
63
+ // Simple ref for container - no ResizeObserver needed
64
+ var containerRef = useRef(null);
7
65
  var plotlyData = [
8
66
  {
9
67
  x: data,
@@ -26,8 +84,34 @@ var HistogramPlot = function (props) {
26
84
  hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text
27
85
  }
28
86
  ];
87
+ // Calculate the mean
88
+ var meanValue = (_a = calculateMean(data)) !== null && _a !== void 0 ? _a : 0; // Default to 0 if no data
89
+ var meanLine = showMeanLine ? {
90
+ type: 'line',
91
+ x0: meanValue,
92
+ y0: 0,
93
+ x1: meanValue,
94
+ yref: 'paper',
95
+ y1: 1.04, // Extend slightly above so we can annotate better
96
+ line: {
97
+ color: meanLineColor,
98
+ width: 1.5,
99
+ }
100
+ } : {};
29
101
  var layout = {
30
- title: { text: title },
102
+ title: {
103
+ text: title,
104
+ },
105
+ autosize: true,
106
+ width: undefined, // Let autosize handle width
107
+ height: undefined, // Let autosize handle height
108
+ margin: {
109
+ l: 50,
110
+ r: 20,
111
+ t: title ? 80 : 30,
112
+ b: 50,
113
+ pad: 4
114
+ },
31
115
  xaxis: {
32
116
  title: {
33
117
  text: xAxisTitle
@@ -64,8 +148,24 @@ var HistogramPlot = function (props) {
64
148
  ticksuffix: ' ', // Add space between y axis and ticks
65
149
  },
66
150
  bargap: 0.03, // Gap between bars
67
- dragmode: 'select',
151
+ dragmode: 'select', // Enable selection for both click and drag
68
152
  selectdirection: 'h', // Allow selection in horizontal direction
153
+ shapes: meanLine ? [meanLine] : [], // Add the mean line if it exists
154
+ annotations: showMeanLine ? [{
155
+ x: meanValue,
156
+ y: 1.12, // Position above the top of the plot
157
+ yref: 'paper',
158
+ text: "Mean: ".concat(isDateArray(data) ? new Date(meanValue).toLocaleDateString('en-US', {
159
+ month: 'short',
160
+ day: '2-digit',
161
+ year: 'numeric'
162
+ }) : meanValue.toFixed(2)),
163
+ showarrow: false, // No arrow for the annotation
164
+ font: {
165
+ color: meanLineColor,
166
+ size: 12,
167
+ },
168
+ }] : [],
69
169
  };
70
170
  var config = {
71
171
  responsive: true, // Make the plot responsive
@@ -74,9 +174,133 @@ var HistogramPlot = function (props) {
74
174
  scrollZoom: false, // Disable zooming with scroll
75
175
  staticPlot: false, // Enable interactivity
76
176
  };
77
- return (jsx("div", { className: "plot-container", style: {
78
- '--selection-color': selectorsColor,
79
- }, children: jsx(Plot$1, { data: plotlyData, layout: layout, config: config }) }));
177
+ var containerStyles = __assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
178
+ return (jsx("div", { ref: containerRef, className: "plot-container", style: __assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx("div", { style: {
179
+ width: "100%",
180
+ height: "100%",
181
+ minHeight: "300px",
182
+ display: "flex",
183
+ alignItems: "center",
184
+ justifyContent: "center",
185
+ color: "#666"
186
+ }, children: "Loading plot..." }), children: jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
187
+ width: "100%",
188
+ height: "100%",
189
+ display: "block"
190
+ } }) }) }));
191
+ };
192
+
193
+ var Plot$1 = lazy(function () { return import('react-plotly.js'); });
194
+ var RadialHistogramPlot = function (props) {
195
+ var data = props.data, _a = props.barColor, barColor = _a === void 0 ? 'rgb(72, 72, 74)' : _a, _b = props.unselectedBarColor, unselectedBarColor = _b === void 0 ? 'rgba(203, 195, 195, 0.88)' : _b, _c = props.selectorsColor, selectorsColor = _c === void 0 ? 'black' : _c, onSelected = props.onSelected, onClick = props.onClick, containerStyleOverrides = props.containerStyleOverrides, _d = props.barWidth, barWidth = _d === void 0 ? 20 : _d;
196
+ // Simple ref for container
197
+ var containerRef = useRef(null);
198
+ // TEMPORARY Calculate histogram bins manually to get proper polar coordinates
199
+ // This function should be extracted and used for both the regular and radial histograms.
200
+ if (data.length === 0) {
201
+ return null;
202
+ }
203
+ var min = Math.min.apply(Math, data);
204
+ var max = Math.max.apply(Math, data);
205
+ var numBins = Math.ceil(Math.sqrt(data.length)); // Default bin count
206
+ var binWidth = (max - min) / numBins;
207
+ // Create bins
208
+ var binCounts = new Array(numBins).fill(0);
209
+ var binCenters = [];
210
+ for (var i = 0; i < numBins; i++) {
211
+ binCenters.push(min + (i + 0.5) * binWidth);
212
+ }
213
+ // Count values in each bin
214
+ data.forEach(function (value) {
215
+ var binIndex = Math.min(Math.floor((value - min) / binWidth), numBins - 1);
216
+ binCounts[binIndex]++;
217
+ });
218
+ var plotlyData = [
219
+ {
220
+ type: 'barpolar',
221
+ theta: binCenters,
222
+ r: binCounts,
223
+ width: barWidth, // Width of each bar in degrees
224
+ marker: {
225
+ color: barColor,
226
+ line: {
227
+ color: "white",
228
+ width: 0.5,
229
+ },
230
+ },
231
+ // @ts-ignore - Not in the type but a valid property. See api https://plotly.com/javascript/reference/barpolar/#barpolar
232
+ unselected: {
233
+ marker: {
234
+ color: unselectedBarColor,
235
+ }
236
+ },
237
+ hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text,
238
+ }
239
+ ];
240
+ var layout = {
241
+ autosize: true,
242
+ width: undefined,
243
+ height: undefined,
244
+ margin: {
245
+ l: 50,
246
+ r: 50,
247
+ t: 30,
248
+ b: 50,
249
+ pad: 4
250
+ },
251
+ polar: {
252
+ bgcolor: 'rgba(0,0,0,0)',
253
+ sector: [90, -90],
254
+ angularaxis: {
255
+ tickmode: 'linear',
256
+ tick0: 0,
257
+ dtick: 45, // Show ticks every 45 degrees
258
+ direction: "counterclockwise",
259
+ rotation: 0,
260
+ showgrid: true,
261
+ gridcolor: '#efefef',
262
+ gridwidth: 0.5,
263
+ tickfont: {
264
+ size: 10
265
+ }
266
+ },
267
+ radialaxis: {
268
+ title: {
269
+ text: 'Count'
270
+ },
271
+ showgrid: true,
272
+ gridcolor: '#efefef',
273
+ gridwidth: 0.5,
274
+ tickfont: {
275
+ size: 10
276
+ },
277
+ angle: 90, // Position radial axis labels at top
278
+ side: 'counterclockwise',
279
+ }
280
+ },
281
+ dragmode: 'select',
282
+ selectdirection: 'any',
283
+ };
284
+ var config = {
285
+ responsive: true,
286
+ displayModeBar: false,
287
+ displaylogo: false,
288
+ scrollZoom: false,
289
+ staticPlot: false,
290
+ };
291
+ var containerStyles = __assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
292
+ return (jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: __assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx("div", { style: {
293
+ width: "100%",
294
+ height: "100%",
295
+ minHeight: "300px",
296
+ display: "flex",
297
+ alignItems: "center",
298
+ justifyContent: "center",
299
+ }, children: "Loading radial plot..." }), children: jsx(Plot$1, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
300
+ width: "100%",
301
+ height: "100%",
302
+ display: "block"
303
+ } }) }) }));
80
304
  };
81
305
 
82
306
  var Plot = lazy(function () { return import('react-plotly.js'); });
@@ -98,5 +322,5 @@ var TestPlot = function (props) {
98
322
  return jsx(Plot, { data: data, layout: layout });
99
323
  };
100
324
 
101
- export { HistogramPlot, TestPlot };
325
+ export { HistogramPlot, RadialHistogramPlot, TestPlot };
102
326
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/components/Histogram.tsx","../src/components/TestPlot.tsx"],"sourcesContent":["import React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss'; // Importing styles for the plot\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type HistogramPlotProps = {\n data: number[];\n title?: string;\n xAxisTitle?: string;\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n}\nexport const HistogramPlot = (props: HistogramPlotProps) => {\n\n const {\n data,\n title,\n xAxisTitle,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n } = props;\n\n const plotlyData: PlotParams['data'] = [\n {\n x: data,\n type: 'histogram',\n marker: { \n color: barColor ?? 'blue',\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // The following property is listed in the api. Not sure why typescript doesn't know about it.\n // Styles the unselected bars in the histogram\n //@ts-ignore\n unselected: {\n marker: { \n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text\n }\n ];\n\n const layout: PlotParams['layout'] = {\n title: {text: title},\n xaxis: {\n title: {\n text: xAxisTitle\n },\n // range: [Math.min(...data, 0), Math.max(...data)], // Range needs to get padding on both sides based on bin size. Consider calculating bins here.\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticklabelposition: 'outside',\n },\n yaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticksuffix: ' ', // Add space between y axis and ticks\n },\n bargap: 0.03, // Gap between bars\n dragmode: 'select',\n selectdirection: 'h', // Allow selection in horizontal direction\n };\n\n const config: PlotParams['config'] = {\n responsive: true, // Make the plot responsive\n displayModeBar: false, // Hide the mode bar\n displaylogo: false, // Hide the Plotly logo\n scrollZoom: false, // Disable zooming with scroll\n staticPlot: false, // Enable interactivity\n };\n\n return (\n <div \n className=\"plot-container\"\n style={{\n '--selection-color': selectorsColor,\n } as React.CSSProperties}\n >\n <Plot data={plotlyData} layout={layout} config={config} />\n </div>\n );\n}\n\nexport default HistogramPlot;\n","// A test bar plotly plot\nimport React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type TestPlotProps = {\n yaxisTitle?: string;\n xaxisTitle?: string;\n}\nexport const TestPlot = (props: TestPlotProps) => {\n const data: PlotParams['data'] = [\n {\n x: [1, 2, 3, 4],\n y: [10, 15, 13, 17],\n type: 'bar' as const,\n marker: { color: 'blue' },\n },\n ];\n\n const layout = {\n title: {text: 'Test Bar Plot'},\n xaxis: { title: {text: props.xaxisTitle ?? 'X Axis'} },\n yaxis: { title: {text: props.yaxisTitle ?? 'Y Axis'} },\n };\n\n return <Plot data={data} layout={layout} />;\n};\n\nexport default TestPlot;\n"],"names":["Plot","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../node_modules/.pnpm/@rollup+plugin-typescript@12.1.4_rollup@4.44.1_tslib@2.8.1_typescript@5.8.3/node_modules/tslib/tslib.es6.js","../src/components/Utils.ts","../src/components/Histogram.tsx","../src/components/RadialHistogram.tsx","../src/components/TestPlot.tsx"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","// Utility functions for our components\n\n// Type guard to check if array contains only numbers\nexport const isNumberArray = (arr: unknown[]): arr is number[] => {\n return arr.every(item => typeof item === 'number' && !isNaN(item));\n};\n\n// Type guard to check if array contains only dates\nexport const isDateArray = (arr: unknown[]): arr is Date[] => {\n return arr.every(item => item instanceof Date);\n};\n\n// Calculate the mean of an array of numbers or dates\nexport function calculateMean(arr: number[] | Date[]): number | undefined {\n \n if (arr.length === 0) return undefined;\n\n if (isNumberArray(arr)) {\n return arr.reduce((acc, num) => acc + num, 0) / arr.length;\n } else if (isDateArray(arr)) {\n const sum = arr.reduce((acc, date) => acc + date.getTime(), 0);\n return sum / arr.length;\n }\n}\n\n// Utility function to format date as mm/dd/yy\nexport const formatDateMDY = (timestamp: number): string => {\n const date = new Date(timestamp);\n const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};","import React, { lazy, Suspense, useRef } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss';\nimport { calculateMean, isDateArray, isNumberArray } from './Utils'; \n\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type HistogramPlotProps = {\n data: number[] | Date[];\n showMeanLine?: boolean; // Optional prop to show a vertical line at the mean\n meanLineColor?: string; // Optional prop to set the color of the mean line\n title?: string;\n xAxisTitle?: string;\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n onSelected?: (event: Plotly.PlotSelectionEvent) => void; // Optional handler for when a user clicks and drags to select an area of the plot\n onClick?: (event: Plotly.PlotMouseEvent) => void; // Optional handler for click events on the plot\n containerStyleOverrides?: React.CSSProperties; // Optional style override for the container\n}\nexport const HistogramPlot = (props: HistogramPlotProps) => {\n\n const {\n data,\n title,\n xAxisTitle,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n onSelected,\n onClick,\n showMeanLine = true,\n meanLineColor = 'grey',\n containerStyleOverrides,\n } = props;\n\n // Simple ref for container - no ResizeObserver needed\n const containerRef = useRef<HTMLDivElement>(null);\n\n const plotlyData: PlotParams['data'] = [\n {\n x: data,\n type: 'histogram',\n marker: { \n color: barColor ?? 'blue',\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // The following property is listed in the api. Not sure why typescript doesn't know about it.\n // Styles the unselected bars in the histogram\n //@ts-ignore\n unselected: {\n marker: { \n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text\n }\n ];\n\n\n // Calculate the mean\n const meanValue = calculateMean(data) ?? 0; // Default to 0 if no data\n\n const meanLine: Partial<Plotly.Shape> = showMeanLine ? {\n type: 'line',\n x0: meanValue,\n y0: 0,\n x1: meanValue,\n yref: 'paper',\n y1: 1.04, // Extend slightly above so we can annotate better\n line: {\n color: meanLineColor,\n width: 1.5,\n }\n } : {};\n\n const layout: PlotParams['layout'] = {\n title: {\n text: title,\n },\n autosize: true,\n width: undefined, // Let autosize handle width\n height: undefined, // Let autosize handle height\n margin: {\n l: 50,\n r: 20, \n t: title ? 80 : 30,\n b: 50,\n pad: 4\n },\n xaxis: {\n title: {\n text: xAxisTitle\n },\n // range: [Math.min(...data, 0), Math.max(...data)], // Range needs to get padding on both sides based on bin size. Consider calculating bins here.\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticklabelposition: 'outside',\n },\n yaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticksuffix: ' ', // Add space between y axis and ticks\n },\n bargap: 0.03, // Gap between bars\n dragmode: 'select', // Enable selection for both click and drag\n selectdirection: 'h', // Allow selection in horizontal direction\n shapes: meanLine ? [meanLine] : [], // Add the mean line if it exists\n annotations: showMeanLine ? [{\n x: meanValue,\n y: 1.12, // Position above the top of the plot\n yref: 'paper',\n text: `Mean: ${isDateArray(data) ? new Date(meanValue).toLocaleDateString('en-US', { \n month: 'short', \n day: '2-digit', \n year: 'numeric' \n }) : meanValue.toFixed(2)}`,\n showarrow: false, // No arrow for the annotation\n font: {\n color: meanLineColor,\n size: 12,\n },\n }] : [],\n };\n\n const config: PlotParams['config'] = {\n responsive: true, // Make the plot responsive\n displayModeBar: false, // Hide the mode bar\n displaylogo: false, // Hide the Plotly logo\n scrollZoom: false, // Disable zooming with scroll\n staticPlot: false, // Enable interactivity\n };\n\n const containerStyles: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n position: \"relative\",\n ...containerStyleOverrides,\n };\n\n return (\n <div \n ref={containerRef}\n className=\"plot-container\"\n style={{\n '--selection-color': selectorsColor,\n ...containerStyles\n } as React.CSSProperties}\n >\n <Suspense fallback={\n <div style={{ \n width: \"100%\", \n height: \"100%\", \n minHeight: \"300px\",\n display: \"flex\", \n alignItems: \"center\", \n justifyContent: \"center\",\n color: \"#666\"\n }}>\n Loading plot...\n </div>\n }>\n <Plot \n data={plotlyData} \n layout={layout} \n config={config}\n onSelected={onSelected}\n onClick={onClick}\n useResizeHandler={true}\n style={{ \n width: \"100%\", \n height: \"100%\",\n display: \"block\"\n }}\n />\n </Suspense>\n </div>\n );\n}\n\nexport default HistogramPlot;\n","import React, { lazy, Suspense, useRef } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss';\nimport { calculateMean } from './Utils';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type RadialHistogramPlotProps = {\n data: number[];\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n onSelected?: (event: Plotly.PlotSelectionEvent) => void; // Optional handler for when a user clicks and drags to select an area\n onClick?: (event: Plotly.PlotMouseEvent) => void; // Optional handler for click events on the plot\n containerStyleOverrides?: React.CSSProperties; // Optional style override for the container\n barWidth?: number; // Optional bar width for radial histogram\n}\n\nexport const RadialHistogramPlot = (props: RadialHistogramPlotProps) => {\n const {\n data,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n onSelected,\n onClick,\n containerStyleOverrides,\n barWidth = 20, // Default bar width in degrees\n } = props;\n\n // Simple ref for container\n const containerRef = useRef<HTMLDivElement>(null);\n\n // TEMPORARY Calculate histogram bins manually to get proper polar coordinates\n // This function should be extracted and used for both the regular and radial histograms.\n\n if (data.length === 0) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const numBins = Math.ceil(Math.sqrt(data.length)); // Default bin count\n const binWidth = (max - min) / numBins;\n \n // Create bins\n const binCounts = new Array(numBins).fill(0);\n const binCenters = [];\n \n for (let i = 0; i < numBins; i++) {\n binCenters.push(min + (i + 0.5) * binWidth);\n }\n \n // Count values in each bin\n data.forEach(value => {\n const binIndex = Math.min(Math.floor((value - min) / binWidth), numBins - 1);\n binCounts[binIndex]++;\n });\n\n\n const plotlyData: PlotParams['data'] = [\n {\n type: 'barpolar',\n theta: binCenters,\n r: binCounts,\n width: barWidth, // Width of each bar in degrees\n marker: {\n color: barColor,\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // @ts-ignore - Not in the type but a valid property. See api https://plotly.com/javascript/reference/barpolar/#barpolar\n unselected: {\n marker: {\n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text,\n }\n ];\n\n\n const layout: PlotParams['layout'] = {\n autosize: true,\n width: undefined,\n height: undefined,\n margin: {\n l: 50,\n r: 50,\n t: 30,\n b: 50,\n pad: 4\n },\n polar: {\n bgcolor: 'rgba(0,0,0,0)',\n sector: [90, -90],\n angularaxis: {\n tickmode: 'linear',\n tick0: 0,\n dtick: 45, // Show ticks every 45 degrees\n direction: \"counterclockwise\",\n rotation: 0,\n showgrid: true,\n gridcolor: '#efefef',\n gridwidth: 0.5,\n tickfont: {\n size: 10\n }\n },\n radialaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n gridcolor: '#efefef',\n gridwidth: 0.5,\n tickfont: {\n size: 10\n },\n angle: 90, // Position radial axis labels at top\n side: 'counterclockwise',\n }\n },\n dragmode: 'select',\n selectdirection: 'any',\n };\n\n const config: PlotParams['config'] = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n scrollZoom: false,\n staticPlot: false,\n };\n\n const containerStyles: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n position: \"relative\",\n ...containerStyleOverrides,\n };\n\n return (\n <div \n ref={containerRef}\n className=\"plot-container radial-histogram-container\"\n style={{\n '--selection-color': selectorsColor,\n ...containerStyles\n } as React.CSSProperties}\n >\n <Suspense fallback={\n <div style={{ \n width: \"100%\", \n height: \"100%\", \n minHeight: \"300px\",\n display: \"flex\", \n alignItems: \"center\", \n justifyContent: \"center\",\n }}>\n Loading radial plot...\n </div>\n }>\n <Plot \n data={plotlyData} \n layout={layout} \n config={config}\n onSelected={onSelected}\n onClick={onClick}\n useResizeHandler={true}\n style={{ \n width: \"100%\", \n height: \"100%\",\n display: \"block\"\n }}\n />\n </Suspense>\n </div>\n );\n};\n\nexport default RadialHistogramPlot;\n","// A test bar plotly plot\nimport React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type TestPlotProps = {\n yaxisTitle?: string;\n xaxisTitle?: string;\n}\nexport const TestPlot = (props: TestPlotProps) => {\n const data: PlotParams['data'] = [\n {\n x: [1, 2, 3, 4],\n y: [10, 15, 13, 17],\n type: 'bar' as const,\n marker: { color: 'blue' },\n },\n ];\n\n const layout = {\n title: {text: 'Test Bar Plot'},\n xaxis: { title: {text: props.xaxisTitle ?? 'X Axis'} },\n yaxis: { title: {text: props.yaxisTitle ?? 'Y Axis'} },\n };\n\n return <Plot data={data} layout={layout} />;\n};\n\nexport default TestPlot;\n"],"names":["Plot","_jsx"],"mappings":"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","x_google_ignoreList":[0]}
package/dist/index.js CHANGED
@@ -3,9 +3,67 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var react = require('react');
5
5
 
6
- var Plot$1 = react.lazy(function () { return import('react-plotly.js'); });
6
+ /******************************************************************************
7
+ Copyright (c) Microsoft Corporation.
8
+
9
+ Permission to use, copy, modify, and/or distribute this software for any
10
+ purpose with or without fee is hereby granted.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
14
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
+ PERFORMANCE OF THIS SOFTWARE.
19
+ ***************************************************************************** */
20
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
21
+
22
+
23
+ var __assign = function() {
24
+ __assign = Object.assign || function __assign(t) {
25
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
26
+ s = arguments[i];
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
28
+ }
29
+ return t;
30
+ };
31
+ return __assign.apply(this, arguments);
32
+ };
33
+
34
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
35
+ var e = new Error(message);
36
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
37
+ };
38
+
39
+ // Utility functions for our components
40
+ // Type guard to check if array contains only numbers
41
+ var isNumberArray = function (arr) {
42
+ return arr.every(function (item) { return typeof item === 'number' && !isNaN(item); });
43
+ };
44
+ // Type guard to check if array contains only dates
45
+ var isDateArray = function (arr) {
46
+ return arr.every(function (item) { return item instanceof Date; });
47
+ };
48
+ // Calculate the mean of an array of numbers or dates
49
+ function calculateMean(arr) {
50
+ if (arr.length === 0)
51
+ return undefined;
52
+ if (isNumberArray(arr)) {
53
+ return arr.reduce(function (acc, num) { return acc + num; }, 0) / arr.length;
54
+ }
55
+ else if (isDateArray(arr)) {
56
+ var sum = arr.reduce(function (acc, date) { return acc + date.getTime(); }, 0);
57
+ return sum / arr.length;
58
+ }
59
+ }
60
+
61
+ var Plot$2 = react.lazy(function () { return import('react-plotly.js'); });
7
62
  var HistogramPlot = function (props) {
8
- var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _a = props.barColor, barColor = _a === void 0 ? 'rgb(72, 72, 74)' : _a, _b = props.unselectedBarColor, unselectedBarColor = _b === void 0 ? 'rgba(203, 195, 195, 0.88)' : _b, _c = props.selectorsColor, selectorsColor = _c === void 0 ? 'black' : _c;
63
+ var _a;
64
+ var data = props.data, title = props.title, xAxisTitle = props.xAxisTitle, _b = props.barColor, barColor = _b === void 0 ? 'rgb(72, 72, 74)' : _b, _c = props.unselectedBarColor, unselectedBarColor = _c === void 0 ? 'rgba(203, 195, 195, 0.88)' : _c, _d = props.selectorsColor, selectorsColor = _d === void 0 ? 'black' : _d, onSelected = props.onSelected, onClick = props.onClick, _e = props.showMeanLine, showMeanLine = _e === void 0 ? true : _e, _f = props.meanLineColor, meanLineColor = _f === void 0 ? 'grey' : _f, containerStyleOverrides = props.containerStyleOverrides;
65
+ // Simple ref for container - no ResizeObserver needed
66
+ var containerRef = react.useRef(null);
9
67
  var plotlyData = [
10
68
  {
11
69
  x: data,
@@ -28,8 +86,34 @@ var HistogramPlot = function (props) {
28
86
  hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text
29
87
  }
30
88
  ];
89
+ // Calculate the mean
90
+ var meanValue = (_a = calculateMean(data)) !== null && _a !== void 0 ? _a : 0; // Default to 0 if no data
91
+ var meanLine = showMeanLine ? {
92
+ type: 'line',
93
+ x0: meanValue,
94
+ y0: 0,
95
+ x1: meanValue,
96
+ yref: 'paper',
97
+ y1: 1.04, // Extend slightly above so we can annotate better
98
+ line: {
99
+ color: meanLineColor,
100
+ width: 1.5,
101
+ }
102
+ } : {};
31
103
  var layout = {
32
- title: { text: title },
104
+ title: {
105
+ text: title,
106
+ },
107
+ autosize: true,
108
+ width: undefined, // Let autosize handle width
109
+ height: undefined, // Let autosize handle height
110
+ margin: {
111
+ l: 50,
112
+ r: 20,
113
+ t: title ? 80 : 30,
114
+ b: 50,
115
+ pad: 4
116
+ },
33
117
  xaxis: {
34
118
  title: {
35
119
  text: xAxisTitle
@@ -66,8 +150,24 @@ var HistogramPlot = function (props) {
66
150
  ticksuffix: ' ', // Add space between y axis and ticks
67
151
  },
68
152
  bargap: 0.03, // Gap between bars
69
- dragmode: 'select',
153
+ dragmode: 'select', // Enable selection for both click and drag
70
154
  selectdirection: 'h', // Allow selection in horizontal direction
155
+ shapes: meanLine ? [meanLine] : [], // Add the mean line if it exists
156
+ annotations: showMeanLine ? [{
157
+ x: meanValue,
158
+ y: 1.12, // Position above the top of the plot
159
+ yref: 'paper',
160
+ text: "Mean: ".concat(isDateArray(data) ? new Date(meanValue).toLocaleDateString('en-US', {
161
+ month: 'short',
162
+ day: '2-digit',
163
+ year: 'numeric'
164
+ }) : meanValue.toFixed(2)),
165
+ showarrow: false, // No arrow for the annotation
166
+ font: {
167
+ color: meanLineColor,
168
+ size: 12,
169
+ },
170
+ }] : [],
71
171
  };
72
172
  var config = {
73
173
  responsive: true, // Make the plot responsive
@@ -76,9 +176,133 @@ var HistogramPlot = function (props) {
76
176
  scrollZoom: false, // Disable zooming with scroll
77
177
  staticPlot: false, // Enable interactivity
78
178
  };
79
- return (jsxRuntime.jsx("div", { className: "plot-container", style: {
80
- '--selection-color': selectorsColor,
81
- }, children: jsxRuntime.jsx(Plot$1, { data: plotlyData, layout: layout, config: config }) }));
179
+ var containerStyles = __assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
180
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: "plot-container", style: __assign({ '--selection-color': selectorsColor }, containerStyles), children: jsxRuntime.jsx(react.Suspense, { fallback: jsxRuntime.jsx("div", { style: {
181
+ width: "100%",
182
+ height: "100%",
183
+ minHeight: "300px",
184
+ display: "flex",
185
+ alignItems: "center",
186
+ justifyContent: "center",
187
+ color: "#666"
188
+ }, children: "Loading plot..." }), children: jsxRuntime.jsx(Plot$2, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
189
+ width: "100%",
190
+ height: "100%",
191
+ display: "block"
192
+ } }) }) }));
193
+ };
194
+
195
+ var Plot$1 = react.lazy(function () { return import('react-plotly.js'); });
196
+ var RadialHistogramPlot = function (props) {
197
+ var data = props.data, _a = props.barColor, barColor = _a === void 0 ? 'rgb(72, 72, 74)' : _a, _b = props.unselectedBarColor, unselectedBarColor = _b === void 0 ? 'rgba(203, 195, 195, 0.88)' : _b, _c = props.selectorsColor, selectorsColor = _c === void 0 ? 'black' : _c, onSelected = props.onSelected, onClick = props.onClick, containerStyleOverrides = props.containerStyleOverrides, _d = props.barWidth, barWidth = _d === void 0 ? 20 : _d;
198
+ // Simple ref for container
199
+ var containerRef = react.useRef(null);
200
+ // TEMPORARY Calculate histogram bins manually to get proper polar coordinates
201
+ // This function should be extracted and used for both the regular and radial histograms.
202
+ if (data.length === 0) {
203
+ return null;
204
+ }
205
+ var min = Math.min.apply(Math, data);
206
+ var max = Math.max.apply(Math, data);
207
+ var numBins = Math.ceil(Math.sqrt(data.length)); // Default bin count
208
+ var binWidth = (max - min) / numBins;
209
+ // Create bins
210
+ var binCounts = new Array(numBins).fill(0);
211
+ var binCenters = [];
212
+ for (var i = 0; i < numBins; i++) {
213
+ binCenters.push(min + (i + 0.5) * binWidth);
214
+ }
215
+ // Count values in each bin
216
+ data.forEach(function (value) {
217
+ var binIndex = Math.min(Math.floor((value - min) / binWidth), numBins - 1);
218
+ binCounts[binIndex]++;
219
+ });
220
+ var plotlyData = [
221
+ {
222
+ type: 'barpolar',
223
+ theta: binCenters,
224
+ r: binCounts,
225
+ width: barWidth, // Width of each bar in degrees
226
+ marker: {
227
+ color: barColor,
228
+ line: {
229
+ color: "white",
230
+ width: 0.5,
231
+ },
232
+ },
233
+ // @ts-ignore - Not in the type but a valid property. See api https://plotly.com/javascript/reference/barpolar/#barpolar
234
+ unselected: {
235
+ marker: {
236
+ color: unselectedBarColor,
237
+ }
238
+ },
239
+ hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text,
240
+ }
241
+ ];
242
+ var layout = {
243
+ autosize: true,
244
+ width: undefined,
245
+ height: undefined,
246
+ margin: {
247
+ l: 50,
248
+ r: 50,
249
+ t: 30,
250
+ b: 50,
251
+ pad: 4
252
+ },
253
+ polar: {
254
+ bgcolor: 'rgba(0,0,0,0)',
255
+ sector: [90, -90],
256
+ angularaxis: {
257
+ tickmode: 'linear',
258
+ tick0: 0,
259
+ dtick: 45, // Show ticks every 45 degrees
260
+ direction: "counterclockwise",
261
+ rotation: 0,
262
+ showgrid: true,
263
+ gridcolor: '#efefef',
264
+ gridwidth: 0.5,
265
+ tickfont: {
266
+ size: 10
267
+ }
268
+ },
269
+ radialaxis: {
270
+ title: {
271
+ text: 'Count'
272
+ },
273
+ showgrid: true,
274
+ gridcolor: '#efefef',
275
+ gridwidth: 0.5,
276
+ tickfont: {
277
+ size: 10
278
+ },
279
+ angle: 90, // Position radial axis labels at top
280
+ side: 'counterclockwise',
281
+ }
282
+ },
283
+ dragmode: 'select',
284
+ selectdirection: 'any',
285
+ };
286
+ var config = {
287
+ responsive: true,
288
+ displayModeBar: false,
289
+ displaylogo: false,
290
+ scrollZoom: false,
291
+ staticPlot: false,
292
+ };
293
+ var containerStyles = __assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
294
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: __assign({ '--selection-color': selectorsColor }, containerStyles), children: jsxRuntime.jsx(react.Suspense, { fallback: jsxRuntime.jsx("div", { style: {
295
+ width: "100%",
296
+ height: "100%",
297
+ minHeight: "300px",
298
+ display: "flex",
299
+ alignItems: "center",
300
+ justifyContent: "center",
301
+ }, children: "Loading radial plot..." }), children: jsxRuntime.jsx(Plot$1, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
302
+ width: "100%",
303
+ height: "100%",
304
+ display: "block"
305
+ } }) }) }));
82
306
  };
83
307
 
84
308
  var Plot = react.lazy(function () { return import('react-plotly.js'); });
@@ -101,5 +325,6 @@ var TestPlot = function (props) {
101
325
  };
102
326
 
103
327
  exports.HistogramPlot = HistogramPlot;
328
+ exports.RadialHistogramPlot = RadialHistogramPlot;
104
329
  exports.TestPlot = TestPlot;
105
330
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/components/Histogram.tsx","../src/components/TestPlot.tsx"],"sourcesContent":["import React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss'; // Importing styles for the plot\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type HistogramPlotProps = {\n data: number[];\n title?: string;\n xAxisTitle?: string;\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n}\nexport const HistogramPlot = (props: HistogramPlotProps) => {\n\n const {\n data,\n title,\n xAxisTitle,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n } = props;\n\n const plotlyData: PlotParams['data'] = [\n {\n x: data,\n type: 'histogram',\n marker: { \n color: barColor ?? 'blue',\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // The following property is listed in the api. Not sure why typescript doesn't know about it.\n // Styles the unselected bars in the histogram\n //@ts-ignore\n unselected: {\n marker: { \n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text\n }\n ];\n\n const layout: PlotParams['layout'] = {\n title: {text: title},\n xaxis: {\n title: {\n text: xAxisTitle\n },\n // range: [Math.min(...data, 0), Math.max(...data)], // Range needs to get padding on both sides based on bin size. Consider calculating bins here.\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticklabelposition: 'outside',\n },\n yaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticksuffix: ' ', // Add space between y axis and ticks\n },\n bargap: 0.03, // Gap between bars\n dragmode: 'select',\n selectdirection: 'h', // Allow selection in horizontal direction\n };\n\n const config: PlotParams['config'] = {\n responsive: true, // Make the plot responsive\n displayModeBar: false, // Hide the mode bar\n displaylogo: false, // Hide the Plotly logo\n scrollZoom: false, // Disable zooming with scroll\n staticPlot: false, // Enable interactivity\n };\n\n return (\n <div \n className=\"plot-container\"\n style={{\n '--selection-color': selectorsColor,\n } as React.CSSProperties}\n >\n <Plot data={plotlyData} layout={layout} config={config} />\n </div>\n );\n}\n\nexport default HistogramPlot;\n","// A test bar plotly plot\nimport React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type TestPlotProps = {\n yaxisTitle?: string;\n xaxisTitle?: string;\n}\nexport const TestPlot = (props: TestPlotProps) => {\n const data: PlotParams['data'] = [\n {\n x: [1, 2, 3, 4],\n y: [10, 15, 13, 17],\n type: 'bar' as const,\n marker: { color: 'blue' },\n },\n ];\n\n const layout = {\n title: {text: 'Test Bar Plot'},\n xaxis: { title: {text: props.xaxisTitle ?? 'X Axis'} },\n yaxis: { title: {text: props.yaxisTitle ?? 'Y Axis'} },\n };\n\n return <Plot data={data} layout={layout} />;\n};\n\nexport default TestPlot;\n"],"names":["Plot","lazy","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../node_modules/.pnpm/@rollup+plugin-typescript@12.1.4_rollup@4.44.1_tslib@2.8.1_typescript@5.8.3/node_modules/tslib/tslib.es6.js","../src/components/Utils.ts","../src/components/Histogram.tsx","../src/components/RadialHistogram.tsx","../src/components/TestPlot.tsx"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","// Utility functions for our components\n\n// Type guard to check if array contains only numbers\nexport const isNumberArray = (arr: unknown[]): arr is number[] => {\n return arr.every(item => typeof item === 'number' && !isNaN(item));\n};\n\n// Type guard to check if array contains only dates\nexport const isDateArray = (arr: unknown[]): arr is Date[] => {\n return arr.every(item => item instanceof Date);\n};\n\n// Calculate the mean of an array of numbers or dates\nexport function calculateMean(arr: number[] | Date[]): number | undefined {\n \n if (arr.length === 0) return undefined;\n\n if (isNumberArray(arr)) {\n return arr.reduce((acc, num) => acc + num, 0) / arr.length;\n } else if (isDateArray(arr)) {\n const sum = arr.reduce((acc, date) => acc + date.getTime(), 0);\n return sum / arr.length;\n }\n}\n\n// Utility function to format date as mm/dd/yy\nexport const formatDateMDY = (timestamp: number): string => {\n const date = new Date(timestamp);\n const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const year = date.getFullYear().toString().slice(-2);\n return `${month}/${day}/${year}`;\n};","import React, { lazy, Suspense, useRef } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss';\nimport { calculateMean, isDateArray, isNumberArray } from './Utils'; \n\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type HistogramPlotProps = {\n data: number[] | Date[];\n showMeanLine?: boolean; // Optional prop to show a vertical line at the mean\n meanLineColor?: string; // Optional prop to set the color of the mean line\n title?: string;\n xAxisTitle?: string;\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n onSelected?: (event: Plotly.PlotSelectionEvent) => void; // Optional handler for when a user clicks and drags to select an area of the plot\n onClick?: (event: Plotly.PlotMouseEvent) => void; // Optional handler for click events on the plot\n containerStyleOverrides?: React.CSSProperties; // Optional style override for the container\n}\nexport const HistogramPlot = (props: HistogramPlotProps) => {\n\n const {\n data,\n title,\n xAxisTitle,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n onSelected,\n onClick,\n showMeanLine = true,\n meanLineColor = 'grey',\n containerStyleOverrides,\n } = props;\n\n // Simple ref for container - no ResizeObserver needed\n const containerRef = useRef<HTMLDivElement>(null);\n\n const plotlyData: PlotParams['data'] = [\n {\n x: data,\n type: 'histogram',\n marker: { \n color: barColor ?? 'blue',\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // The following property is listed in the api. Not sure why typescript doesn't know about it.\n // Styles the unselected bars in the histogram\n //@ts-ignore\n unselected: {\n marker: { \n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text\n }\n ];\n\n\n // Calculate the mean\n const meanValue = calculateMean(data) ?? 0; // Default to 0 if no data\n\n const meanLine: Partial<Plotly.Shape> = showMeanLine ? {\n type: 'line',\n x0: meanValue,\n y0: 0,\n x1: meanValue,\n yref: 'paper',\n y1: 1.04, // Extend slightly above so we can annotate better\n line: {\n color: meanLineColor,\n width: 1.5,\n }\n } : {};\n\n const layout: PlotParams['layout'] = {\n title: {\n text: title,\n },\n autosize: true,\n width: undefined, // Let autosize handle width\n height: undefined, // Let autosize handle height\n margin: {\n l: 50,\n r: 20, \n t: title ? 80 : 30,\n b: 50,\n pad: 4\n },\n xaxis: {\n title: {\n text: xAxisTitle\n },\n // range: [Math.min(...data, 0), Math.max(...data)], // Range needs to get padding on both sides based on bin size. Consider calculating bins here.\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticklabelposition: 'outside',\n },\n yaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n zeroline: true,\n showline: true,\n mirror: 'ticks',\n gridcolor: '#efefef',\n gridwidth: 0.2,\n zerolinecolor: '#969696',\n zerolinewidth: 1,\n linecolor: '#bababa',\n linewidth: 1,\n fixedrange: true, // Disable zooming\n ticksuffix: ' ', // Add space between y axis and ticks\n },\n bargap: 0.03, // Gap between bars\n dragmode: 'select', // Enable selection for both click and drag\n selectdirection: 'h', // Allow selection in horizontal direction\n shapes: meanLine ? [meanLine] : [], // Add the mean line if it exists\n annotations: showMeanLine ? [{\n x: meanValue,\n y: 1.12, // Position above the top of the plot\n yref: 'paper',\n text: `Mean: ${isDateArray(data) ? new Date(meanValue).toLocaleDateString('en-US', { \n month: 'short', \n day: '2-digit', \n year: 'numeric' \n }) : meanValue.toFixed(2)}`,\n showarrow: false, // No arrow for the annotation\n font: {\n color: meanLineColor,\n size: 12,\n },\n }] : [],\n };\n\n const config: PlotParams['config'] = {\n responsive: true, // Make the plot responsive\n displayModeBar: false, // Hide the mode bar\n displaylogo: false, // Hide the Plotly logo\n scrollZoom: false, // Disable zooming with scroll\n staticPlot: false, // Enable interactivity\n };\n\n const containerStyles: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n position: \"relative\",\n ...containerStyleOverrides,\n };\n\n return (\n <div \n ref={containerRef}\n className=\"plot-container\"\n style={{\n '--selection-color': selectorsColor,\n ...containerStyles\n } as React.CSSProperties}\n >\n <Suspense fallback={\n <div style={{ \n width: \"100%\", \n height: \"100%\", \n minHeight: \"300px\",\n display: \"flex\", \n alignItems: \"center\", \n justifyContent: \"center\",\n color: \"#666\"\n }}>\n Loading plot...\n </div>\n }>\n <Plot \n data={plotlyData} \n layout={layout} \n config={config}\n onSelected={onSelected}\n onClick={onClick}\n useResizeHandler={true}\n style={{ \n width: \"100%\", \n height: \"100%\",\n display: \"block\"\n }}\n />\n </Suspense>\n </div>\n );\n}\n\nexport default HistogramPlot;\n","import React, { lazy, Suspense, useRef } from 'react';\nimport { PlotParams } from 'react-plotly.js';\nimport './plotStyles.scss';\nimport { calculateMean } from './Utils';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type RadialHistogramPlotProps = {\n data: number[];\n barColor?: string; // Optional prop to set the color of the bars\n unselectedBarColor?: string; // Optional prop to set the color of unselected bars\n selectorsColor?: string; // Optional prop to set the color of elements in the selection box\n onSelected?: (event: Plotly.PlotSelectionEvent) => void; // Optional handler for when a user clicks and drags to select an area\n onClick?: (event: Plotly.PlotMouseEvent) => void; // Optional handler for click events on the plot\n containerStyleOverrides?: React.CSSProperties; // Optional style override for the container\n barWidth?: number; // Optional bar width for radial histogram\n}\n\nexport const RadialHistogramPlot = (props: RadialHistogramPlotProps) => {\n const {\n data,\n barColor = 'rgb(72, 72, 74)',\n unselectedBarColor = 'rgba(203, 195, 195, 0.88)',\n selectorsColor = 'black',\n onSelected,\n onClick,\n containerStyleOverrides,\n barWidth = 20, // Default bar width in degrees\n } = props;\n\n // Simple ref for container\n const containerRef = useRef<HTMLDivElement>(null);\n\n // TEMPORARY Calculate histogram bins manually to get proper polar coordinates\n // This function should be extracted and used for both the regular and radial histograms.\n\n if (data.length === 0) {\n return null;\n }\n\n const min = Math.min(...data);\n const max = Math.max(...data);\n const numBins = Math.ceil(Math.sqrt(data.length)); // Default bin count\n const binWidth = (max - min) / numBins;\n \n // Create bins\n const binCounts = new Array(numBins).fill(0);\n const binCenters = [];\n \n for (let i = 0; i < numBins; i++) {\n binCenters.push(min + (i + 0.5) * binWidth);\n }\n \n // Count values in each bin\n data.forEach(value => {\n const binIndex = Math.min(Math.floor((value - min) / binWidth), numBins - 1);\n binCounts[binIndex]++;\n });\n\n\n const plotlyData: PlotParams['data'] = [\n {\n type: 'barpolar',\n theta: binCenters,\n r: binCounts,\n width: barWidth, // Width of each bar in degrees\n marker: {\n color: barColor,\n line: {\n color: \"white\",\n width: 0.5,\n },\n },\n // @ts-ignore - Not in the type but a valid property. See api https://plotly.com/javascript/reference/barpolar/#barpolar\n unselected: {\n marker: {\n color: unselectedBarColor,\n }\n },\n hovertemplate: '[%{x})<br>Count: %{y}<extra></extra>', // Custom hover text,\n }\n ];\n\n\n const layout: PlotParams['layout'] = {\n autosize: true,\n width: undefined,\n height: undefined,\n margin: {\n l: 50,\n r: 50,\n t: 30,\n b: 50,\n pad: 4\n },\n polar: {\n bgcolor: 'rgba(0,0,0,0)',\n sector: [90, -90],\n angularaxis: {\n tickmode: 'linear',\n tick0: 0,\n dtick: 45, // Show ticks every 45 degrees\n direction: \"counterclockwise\",\n rotation: 0,\n showgrid: true,\n gridcolor: '#efefef',\n gridwidth: 0.5,\n tickfont: {\n size: 10\n }\n },\n radialaxis: {\n title: {\n text: 'Count'\n },\n showgrid: true,\n gridcolor: '#efefef',\n gridwidth: 0.5,\n tickfont: {\n size: 10\n },\n angle: 90, // Position radial axis labels at top\n side: 'counterclockwise',\n }\n },\n dragmode: 'select',\n selectdirection: 'any',\n };\n\n const config: PlotParams['config'] = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n scrollZoom: false,\n staticPlot: false,\n };\n\n const containerStyles: React.CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n position: \"relative\",\n ...containerStyleOverrides,\n };\n\n return (\n <div \n ref={containerRef}\n className=\"plot-container radial-histogram-container\"\n style={{\n '--selection-color': selectorsColor,\n ...containerStyles\n } as React.CSSProperties}\n >\n <Suspense fallback={\n <div style={{ \n width: \"100%\", \n height: \"100%\", \n minHeight: \"300px\",\n display: \"flex\", \n alignItems: \"center\", \n justifyContent: \"center\",\n }}>\n Loading radial plot...\n </div>\n }>\n <Plot \n data={plotlyData} \n layout={layout} \n config={config}\n onSelected={onSelected}\n onClick={onClick}\n useResizeHandler={true}\n style={{ \n width: \"100%\", \n height: \"100%\",\n display: \"block\"\n }}\n />\n </Suspense>\n </div>\n );\n};\n\nexport default RadialHistogramPlot;\n","// A test bar plotly plot\nimport React, { lazy } from 'react';\nimport { PlotParams } from 'react-plotly.js';\n\nconst Plot = lazy(() => import('react-plotly.js'));\n\nexport type TestPlotProps = {\n yaxisTitle?: string;\n xaxisTitle?: string;\n}\nexport const TestPlot = (props: TestPlotProps) => {\n const data: PlotParams['data'] = [\n {\n x: [1, 2, 3, 4],\n y: [10, 15, 13, 17],\n type: 'bar' as const,\n marker: { color: 'blue' },\n },\n ];\n\n const layout = {\n title: {text: 'Test Bar Plot'},\n xaxis: { title: {text: props.xaxisTitle ?? 'X Axis'} },\n yaxis: { title: {text: props.yaxisTitle ?? 'Y Axis'} },\n };\n\n return <Plot data={data} layout={layout} />;\n};\n\nexport default TestPlot;\n"],"names":["Plot","lazy","useRef","_jsx","Suspense"],"mappings":"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","x_google_ignoreList":[0]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "td-plots",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Custom React plotting components built with Plotly.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,19 +47,22 @@
47
47
  "@types/react": "^19.1.8",
48
48
  "@types/react-dom": "^19.1.6",
49
49
  "@types/react-plotly.js": "^2.6.3",
50
+ "@types/seedrandom": "^3.0.8",
50
51
  "@vitejs/plugin-react": "^4.6.0",
51
52
  "@vitest/browser": "^3.2.4",
52
53
  "@vitest/coverage-v8": "^3.2.4",
53
54
  "@vitest/ui": "^3.2.4",
55
+ "chromatic": "^13.1.2",
54
56
  "dotenv": "^16.5.0",
55
57
  "jsdom": "^26.1.0",
56
58
  "playwright": "^1.53.1",
57
- "react": "^19.1.0",
58
- "react-dom": "^19.1.0",
59
+ "react": "^18.3.1",
60
+ "react-dom": "^18.3.1",
59
61
  "rollup": "^4.9.0",
60
62
  "rollup-plugin-peer-deps-external": "^2.2.4",
61
63
  "rollup-plugin-postcss": "^4.0.2",
62
64
  "sass": "^1.69.0",
65
+ "seedrandom": "^3.0.5",
63
66
  "storybook": "^9.0.13",
64
67
  "ts-node": "^10.9.2",
65
68
  "typescript": "^5.8.3",
@@ -72,9 +75,14 @@
72
75
  "build": "npm run clean && npm run build:rollup && npm run build:types",
73
76
  "build:rollup": "rollup -c",
74
77
  "build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly",
78
+ "build:watch": "rollup -c --watch",
79
+ "build:types:watch": "tsc --project tsconfig.build.json --emitDeclarationOnly --watch",
80
+ "dev": "npm run build:watch",
81
+ "dev:full": "npm run build:types:watch & npm run build:watch",
75
82
  "clean": "rm -rf dist",
76
83
  "test": "vitest run",
77
84
  "storybook": "storybook dev -p 6006",
78
- "build-storybook": "storybook build"
85
+ "build-storybook": "storybook build",
86
+ "chromatic": "npx chromatic"
79
87
  }
80
88
  }