td-plots 1.8.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/LineWithHistogram.d.ts +32 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.esm.js +177 -74
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +177 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/LinePlot.d.ts +0 -24
- package/dist/components/TestPlot.d.ts +0 -6
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { PlotParams } from "react-plotly.js";
|
|
3
|
+
import "./plotStyles.scss";
|
|
4
|
+
export interface LineDataTrace {
|
|
5
|
+
x: number[] | Date[];
|
|
6
|
+
y: number[];
|
|
7
|
+
name?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
hovertemplate?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface HistogramDataTrace {
|
|
12
|
+
x: number[] | Date[];
|
|
13
|
+
name?: string;
|
|
14
|
+
color?: string;
|
|
15
|
+
hovertemplate?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface LineWithHistogramProps {
|
|
18
|
+
lineData: LineDataTrace;
|
|
19
|
+
histogramData: HistogramDataTrace;
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
title?: string;
|
|
23
|
+
plotId?: string;
|
|
24
|
+
xAxisTitle?: string;
|
|
25
|
+
yAxisTitle?: string;
|
|
26
|
+
y2AxisTitle?: string;
|
|
27
|
+
containerStyleOverrides?: React.CSSProperties;
|
|
28
|
+
extraLayoutConfig?: Partial<PlotParams["layout"]>;
|
|
29
|
+
revision?: number;
|
|
30
|
+
}
|
|
31
|
+
declare const LineWithHistogram: (props: LineWithHistogramProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export default LineWithHistogram;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,8 +12,7 @@ export type { BoxPlotProps } from "./components/BoxPlot";
|
|
|
12
12
|
export { default as SummaryComparisonPlot } from "./components/SummaryComparisonPlot";
|
|
13
13
|
export type { SummaryComparisonPlotProps } from "./components/SummaryComparisonPlot";
|
|
14
14
|
export { SummaryComparisonPlotLegend } from "./components/SummaryComparisonPlot";
|
|
15
|
-
export { default as
|
|
16
|
-
export type {
|
|
17
|
-
export { default as TestPlot } from "./components/TestPlot";
|
|
15
|
+
export { default as LineWithHistogram } from "./components/LineWithHistogram";
|
|
16
|
+
export type { LineWithHistogramProps } from "./components/LineWithHistogram";
|
|
18
17
|
export { isDateArray, isNumberArray } from "./components/Utils";
|
|
19
18
|
export type { PlotParams } from "react-plotly.js";
|
package/dist/index.esm.js
CHANGED
|
@@ -36,7 +36,7 @@ function styleInject(css, ref) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
var css_248z = ".plot-container{height:100%;max-width:100%;min-height:300px;overflow:hidden!important;position:relative;width:100%}.plot-container>div{flex:1;width:100%!important}.plot-container .main-svg{max-height:100%!important;max-width:100%!important}.plot-container .main-svg,.plot-container .plotly-graph-div,.plot-container svg.main-svg[height],.plot-container svg.main-svg[width]{height:100%!important;width:100%!important}.plot-container .point{border-radius:5px!important;overflow:hidden!important}.plot-container .cursor-ns-resize{height:0;width:0}.plot-container .cursor-ew-resize{fill:var(--selection-color,blue)!important;stroke:var(--selection-color,blue)!important}.plot-container .selectionlayer>path{stroke:var(--selection-color,blue)!important;stroke-dasharray:0!important;stroke-width:1px!important;opacity:.5!important}.plot-container .zoomlayer>path{stroke-dasharray:0!important;stroke:var(--selection-color,blue)!important;fill:var(--selection-color,blue)!important}.radial-histogram-container{aspect-ratio:1}.loading-overlay{align-items:center;background-color:hsla(0,0%,100%,.8);display:flex;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%;z-index:300}.histogram-controls{pointer-events:auto}.histogram-controls.show-always{opacity:1;visibility:visible}.histogram-controls.show-on-hover{opacity:0;transition:opacity .2s ease-in-out,visibility .2s ease-in-out;visibility:hidden}.
|
|
39
|
+
var css_248z = ".plot-container{height:100%;max-width:100%;min-height:300px;overflow:hidden!important;position:relative;width:100%}.plot-container>div{flex:1;width:100%!important}.plot-container .main-svg{max-height:100%!important;max-width:100%!important}.plot-container .main-svg,.plot-container .plotly-graph-div,.plot-container svg.main-svg[height],.plot-container svg.main-svg[width]{height:100%!important;width:100%!important}.plot-container .point{border-radius:5px!important;overflow:hidden!important}.plot-container .cursor-ns-resize{height:0;width:0}.plot-container .cursor-ew-resize{fill:var(--selection-color,blue)!important;stroke:var(--selection-color,blue)!important}.plot-container .selectionlayer>path{stroke:var(--selection-color,blue)!important;stroke-dasharray:0!important;stroke-width:1px!important;opacity:.5!important}.plot-container .zoomlayer>path{stroke-dasharray:0!important;stroke:var(--selection-color,blue)!important;fill:var(--selection-color,blue)!important}.radial-histogram-container{aspect-ratio:1}.loading-overlay{align-items:center;background-color:hsla(0,0%,100%,.8);display:flex;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%;z-index:300}.histogram-controls{pointer-events:auto}.histogram-controls.show-always{opacity:1;visibility:visible}.histogram-controls.show-on-hover{opacity:0;transition:opacity .2s ease-in-out,visibility .2s ease-in-out;visibility:hidden}.plot-container.histogram:hover .histogram-controls.show-on-hover{opacity:1;visibility:visible}";
|
|
40
40
|
styleInject(css_248z);
|
|
41
41
|
|
|
42
42
|
function formatDecimal(x) {
|
|
@@ -539,7 +539,7 @@ var SettingsIcon = createSvgIcon(/*#__PURE__*/jsx("path", {
|
|
|
539
539
|
d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6"
|
|
540
540
|
}), 'Settings');
|
|
541
541
|
|
|
542
|
-
const Plot$
|
|
542
|
+
const Plot$5 = lazy(() => import('react-plotly.js'));
|
|
543
543
|
const HistogramPlot = (props) => {
|
|
544
544
|
var _a, _b, _c, _d;
|
|
545
545
|
const { data, title, xAxisTitle, barColor = "rgb(72, 72, 74)", unselectedBarColor = "rgba(203, 195, 195, 0.88)", selectorsColor = "black", containerStyleOverrides, unselectedData = [], handleClickOrSelection = () => { }, onDeselect = () => { }, plotId, selectByBin = false, dateTickFormat, binSizeOverride, statsAnnotations = ["mean"], emptySelectedRange = false, d3FormatValueString = ".1f", showBinSizeControls = "always", onBinSizeCalculated, onBinSizeChange, showBinSizeControlValue = true, isMobile = false, settingsTitleStylingOverrides = {}, } = props;
|
|
@@ -1291,7 +1291,7 @@ const HistogramPlot = (props) => {
|
|
|
1291
1291
|
const newBinSize = newValue;
|
|
1292
1292
|
setBinSize(newBinSize);
|
|
1293
1293
|
onBinSizeChange === null || onBinSizeChange === void 0 ? void 0 : onBinSizeChange(newBinSize);
|
|
1294
|
-
}, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides, disabledTooltipText: "Requires 10 or more data points" }) }) })] })), jsx(Plot$
|
|
1294
|
+
}, colorOverride: barColor, valueLabelFormat: valueLabelFormat, titleStylingOverrides: settingsTitleStylingOverrides, disabledTooltipText: "Requires 10 or more data points" }) }) })] })), jsx(Plot$5, { data: plotlyData, layout: layout, config: config, onSelected: handleSelection, onClick: handleClick, onDeselect: () => {
|
|
1295
1295
|
onDeselect();
|
|
1296
1296
|
setSelectedRange(null); // Remove selected box
|
|
1297
1297
|
}, onUpdate: handlePlotUpdate, useResizeHandler: true, style: {
|
|
@@ -1302,7 +1302,7 @@ const HistogramPlot = (props) => {
|
|
|
1302
1302
|
} }, `histogram-${plotId || "default"}`)] }) }) }));
|
|
1303
1303
|
};
|
|
1304
1304
|
|
|
1305
|
-
const Plot$
|
|
1305
|
+
const Plot$4 = lazy(() => import('react-plotly.js'));
|
|
1306
1306
|
const RadialHistogramPlot = (props) => {
|
|
1307
1307
|
const { data, barColor = 'rgb(72, 72, 74)', unselectedBarColor = 'rgba(203, 195, 195, 0.88)', selectorsColor = 'black', onSelected, onClick, containerStyleOverrides, barWidth = 20, // Default bar width in degrees
|
|
1308
1308
|
} = props;
|
|
@@ -1402,14 +1402,14 @@ const RadialHistogramPlot = (props) => {
|
|
|
1402
1402
|
staticPlot: false,
|
|
1403
1403
|
};
|
|
1404
1404
|
const containerStyles = Object.assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
|
|
1405
|
-
return (jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: Object.assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$
|
|
1405
|
+
return (jsx("div", { ref: containerRef, className: "plot-container radial-histogram-container", style: Object.assign({ '--selection-color': selectorsColor }, containerStyles), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$4, { data: plotlyData, layout: layout, config: config, onSelected: onSelected, onClick: onClick, useResizeHandler: true, style: {
|
|
1406
1406
|
width: "100%",
|
|
1407
1407
|
height: "100%",
|
|
1408
1408
|
display: "block"
|
|
1409
1409
|
} }) }) }));
|
|
1410
1410
|
};
|
|
1411
1411
|
|
|
1412
|
-
const Plot$
|
|
1412
|
+
const Plot$3 = lazy(() => import('react-plotly.js'));
|
|
1413
1413
|
const StatsDonut = (props) => {
|
|
1414
1414
|
const { withCenterLabel = false, centerLabel, centerValue, showLegend = true, legendPosition = "right", containerStyle = {}, } = props;
|
|
1415
1415
|
// Configure legend position based on prop
|
|
@@ -1457,7 +1457,7 @@ const StatsDonut = (props) => {
|
|
|
1457
1457
|
},
|
|
1458
1458
|
]
|
|
1459
1459
|
: [];
|
|
1460
|
-
return (jsx("div", { style: Object.assign({ width: "100%", height: "100%", minHeight: "300px", display: "flex", justifyContent: "center", alignItems: "center" }, containerStyle), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$
|
|
1460
|
+
return (jsx("div", { style: Object.assign({ width: "100%", height: "100%", minHeight: "300px", display: "flex", justifyContent: "center", alignItems: "center" }, containerStyle), children: jsx(Suspense, { fallback: jsx(Loading, {}), children: jsx(Plot$3, { data: [
|
|
1461
1461
|
{
|
|
1462
1462
|
type: "pie",
|
|
1463
1463
|
values: props.values,
|
|
@@ -1490,7 +1490,7 @@ const StatsDonut = (props) => {
|
|
|
1490
1490
|
}, useResizeHandler: true }) }) }));
|
|
1491
1491
|
};
|
|
1492
1492
|
|
|
1493
|
-
const Plot$
|
|
1493
|
+
const Plot$2 = lazy(() => import('react-plotly.js'));
|
|
1494
1494
|
const BoxPlot = (props) => {
|
|
1495
1495
|
const { data, width = 600, height = 400, title = "Box Plot", xAxisTitle, yAxisTitle, containerStyleOverrides, plotId = "boxplot", extraLayoutConfig = {}, } = props;
|
|
1496
1496
|
// Ref for plot container
|
|
@@ -1556,7 +1556,7 @@ const BoxPlot = (props) => {
|
|
|
1556
1556
|
position: "relative",
|
|
1557
1557
|
width: "100%",
|
|
1558
1558
|
height: "100%",
|
|
1559
|
-
}, children: [jsx(Plot$
|
|
1559
|
+
}, children: [jsx(Plot$2, { data: plotlyData, layout: layout, config: config, useResizeHandler: true,
|
|
1560
1560
|
// onHover={handleHover}
|
|
1561
1561
|
// onUnhover={handleUnhover}
|
|
1562
1562
|
style: {
|
|
@@ -1842,7 +1842,7 @@ const PairedComparisonsBoxPlot = (props) => {
|
|
|
1842
1842
|
return (jsxs("div", { style: Object.assign({}, containerStyles), children: [showLegend && legendNode, jsx(BoxPlot, { data: boxPlotData, width: width, height: height, title: title, xAxisTitle: xAxisTitle, yAxisTitle: yAxisTitle, extraLayoutConfig: extraLayoutConfig, containerStyleOverrides: containerStyleOverrides, plotId: `${plotId}-boxplot` })] }));
|
|
1843
1843
|
};
|
|
1844
1844
|
|
|
1845
|
-
const Plot$
|
|
1845
|
+
const Plot$1 = lazy(() => import('react-plotly.js'));
|
|
1846
1846
|
const SummaryComparisonPlot = (props) => {
|
|
1847
1847
|
const { groups, height = 250, title = "", xAxisTitle, yAxisTitle, containerStyleOverrides, plotId = "summary-comparison-plot", tooltipPosition = "right", startXAxisAtZero = true, } = props;
|
|
1848
1848
|
// Ref for plot container
|
|
@@ -1886,11 +1886,11 @@ const SummaryComparisonPlot = (props) => {
|
|
|
1886
1886
|
content += `
|
|
1887
1887
|
<table style="width: 100%; margin-top: 4px;">
|
|
1888
1888
|
<tr>
|
|
1889
|
-
<td style="text-align: left; padding: 2px 18px 2px 0;">Population
|
|
1889
|
+
<td style="text-align: left; padding: 2px 18px 2px 0;">Population avg-\u03C3:</td>
|
|
1890
1890
|
<td style="text-align: right; padding: 2px 0;">${summarizedMinText}</td>
|
|
1891
1891
|
</tr>
|
|
1892
1892
|
<tr>
|
|
1893
|
-
<td style="text-align: left; padding: 2px 18px 2px 0;">Population
|
|
1893
|
+
<td style="text-align: left; padding: 2px 18px 2px 0;">Population avg+\u03C3:</td>
|
|
1894
1894
|
<td style="text-align: right; padding: 2px 0;">${summarizedMaxText}</td>
|
|
1895
1895
|
</tr>
|
|
1896
1896
|
<tr>
|
|
@@ -2056,7 +2056,7 @@ const SummaryComparisonPlot = (props) => {
|
|
|
2056
2056
|
position: "relative",
|
|
2057
2057
|
width: "100%",
|
|
2058
2058
|
height: "100%",
|
|
2059
|
-
}, children: [jsx(Plot$
|
|
2059
|
+
}, children: [jsx(Plot$1, { data: plotlyData, layout: layout, config: config, useResizeHandler: true, onHover: handleHover, onUnhover: handleUnhover, style: {
|
|
2060
2060
|
width: "100%",
|
|
2061
2061
|
height: `${height}px`,
|
|
2062
2062
|
display: "block",
|
|
@@ -2095,42 +2095,150 @@ const SummaryComparisonPlotLegend = ({ comparedDataLabel, summarizedDataLabel, c
|
|
|
2095
2095
|
} }), jsx("span", { children: comparedDataLabel })] }), jsxs("div", { style: { display: "flex", gap: "5px", alignItems: "center" }, children: [jsx(Box, { width: 30, height: 3, sx: { backgroundColor: color } }), jsx("span", { children: summarizedDataLabel })] })] }));
|
|
2096
2096
|
};
|
|
2097
2097
|
|
|
2098
|
-
const Plot
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2098
|
+
const Plot = lazy(() => import('react-plotly.js'));
|
|
2099
|
+
// This component plots a line chart in the foreground with a histogram in the backgroun. The histogram
|
|
2100
|
+
// is used only for context, while the line is intended to have the focus. To that end, the line plot has hover interactions
|
|
2101
|
+
// while the histogram does not.
|
|
2102
|
+
// Additionally, because of plotly restrictions in the web (overlaying y issues) we cannot draw both plots
|
|
2103
|
+
// as normal. Instead, we first render a histogram, extract the calculated bin positions and heights from the rendered plot, and
|
|
2104
|
+
// then render a second plot with just the line and use the extracted histogram bin information to draw the histogram as shapes in
|
|
2105
|
+
// the background of the line plot. This allows us to have a shared x-axis and aligned y-axes for both plots, while only having hover
|
|
2106
|
+
// interactions on the line plot.
|
|
2107
|
+
const LineWithHistogram = (props) => {
|
|
2108
|
+
const { lineData, histogramData, width = 600, height = 400, title, xAxisTitle, yAxisTitle, containerStyleOverrides, plotId = "lineplot", extraLayoutConfig = {}, y2AxisTitle, revision = 0, } = props;
|
|
2102
2109
|
// Ref for plot container
|
|
2103
2110
|
const containerRef = useRef(null);
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2111
|
+
// State to store extracted histogram bin information
|
|
2112
|
+
const [histogramBins, setHistogramBins] = useState([]);
|
|
2113
|
+
// State to trigger re-render of hidden histogram plot when data changes
|
|
2114
|
+
const [hiddenPlotKey, setHiddenPlotKey] = useState(0);
|
|
2115
|
+
// When histogram data changes, reset bins and remount the hidden plot so onInitialized re-fires
|
|
2116
|
+
useEffect(() => {
|
|
2117
|
+
setHistogramBins([]);
|
|
2118
|
+
setHiddenPlotKey((k) => k + 1);
|
|
2119
|
+
}, [histogramData.x]);
|
|
2120
|
+
// Callback to extract histogram bin data from Plotly after it's rendered
|
|
2121
|
+
const handlePlotInitialized = (figure, graphDiv) => {
|
|
2122
|
+
try {
|
|
2123
|
+
// Only extract once - prevent infinite loop
|
|
2124
|
+
if (histogramBins.length > 0) {
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
// Access the calculated histogram data from Plotly's internal data
|
|
2128
|
+
const histogramTrace = graphDiv.data[0]; // First trace is the histogram
|
|
2129
|
+
if (histogramTrace && histogramTrace.type === "histogram") {
|
|
2130
|
+
// Plotly computes x (bin edges) and y (bin heights) after rendering
|
|
2131
|
+
// We need to access the computed bins from the graph div
|
|
2132
|
+
const fullData = graphDiv.calcdata;
|
|
2133
|
+
if (fullData && fullData[0]) {
|
|
2134
|
+
const histCalcData = fullData[0]; // Contains bin information
|
|
2135
|
+
const bins = [];
|
|
2136
|
+
// Extract bin information from Plotly's calculated data
|
|
2137
|
+
for (let i = 0; i < histCalcData.length; i++) {
|
|
2138
|
+
const point = histCalcData[i];
|
|
2139
|
+
if (point.p0 !== undefined &&
|
|
2140
|
+
point.p1 !== undefined &&
|
|
2141
|
+
point.s !== undefined) {
|
|
2142
|
+
bins.push({
|
|
2143
|
+
x0: point.p0,
|
|
2144
|
+
x1: point.p1,
|
|
2145
|
+
y: point.s, // bin height
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
if (bins.length > 0) {
|
|
2150
|
+
setHistogramBins(bins);
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
catch (error) {
|
|
2156
|
+
console.error("Error extracting histogram bins:", error);
|
|
2157
|
+
}
|
|
2158
|
+
};
|
|
2159
|
+
// Data for the hidden histogram plot used to extract bin information.
|
|
2160
|
+
// This plot is not visible and is only used for bin calculation.
|
|
2161
|
+
const histogramPlotlyData = [
|
|
2162
|
+
{
|
|
2163
|
+
type: "histogram",
|
|
2164
|
+
x: histogramData.x,
|
|
2165
|
+
name: histogramData.name || "histogram",
|
|
2114
2166
|
marker: {
|
|
2115
|
-
color:
|
|
2167
|
+
color: histogramData.color || "rgb(211, 211, 212)",
|
|
2168
|
+
line: {
|
|
2169
|
+
color: "white",
|
|
2170
|
+
width: 0.5,
|
|
2171
|
+
},
|
|
2172
|
+
},
|
|
2173
|
+
},
|
|
2174
|
+
];
|
|
2175
|
+
const plotlyData = [
|
|
2176
|
+
// Only the line trace - no histogram trace in main plot
|
|
2177
|
+
// Line trace on primary y-axis for hover interactions
|
|
2178
|
+
Object.assign({ type: "scatter", mode: "lines+markers", x: lineData.x, y: lineData.y, name: lineData.name, line: {
|
|
2179
|
+
color: lineData.color || "#1f77b4",
|
|
2180
|
+
shape: "hv", // Step-wise line.
|
|
2181
|
+
}, marker: {
|
|
2182
|
+
color: lineData.color || "#1f77b4",
|
|
2116
2183
|
size: 6,
|
|
2184
|
+
}, hoverinfo: lineData.hovertemplate ? "text" : "x+y+name" }, (lineData.hovertemplate && { hovertemplate: lineData.hovertemplate })),
|
|
2185
|
+
// Dummy invisible point on yaxis2 to force the axis to render
|
|
2186
|
+
// Position it at the top of the histogram range to ensure the
|
|
2187
|
+
// y2 axis scales appropriately even if the line data doesn't reach that high.
|
|
2188
|
+
// This is a hack to work around Plotly's behavior of not rendering an axis if no data
|
|
2189
|
+
// is plotted on it.
|
|
2190
|
+
...(histogramBins.length > 0
|
|
2191
|
+
? [
|
|
2192
|
+
{
|
|
2193
|
+
type: "scatter",
|
|
2194
|
+
mode: "markers",
|
|
2195
|
+
yaxis: "y2",
|
|
2196
|
+
x: [lineData.x[0]], // First x point
|
|
2197
|
+
y: [Math.max(...histogramBins.map((bin) => bin.y))], // Top of histogram range
|
|
2198
|
+
marker: {
|
|
2199
|
+
size: 0.1,
|
|
2200
|
+
opacity: 0,
|
|
2201
|
+
color: "rgba(0,0,0,0)",
|
|
2202
|
+
},
|
|
2203
|
+
hoverinfo: "skip",
|
|
2204
|
+
showlegend: false,
|
|
2205
|
+
},
|
|
2206
|
+
]
|
|
2207
|
+
: []),
|
|
2208
|
+
];
|
|
2209
|
+
// Convert histogram bins to Plotly shapes (rectangles drawn in the background)
|
|
2210
|
+
// Use yaxis2 coordinates so bins align with the right y-axis
|
|
2211
|
+
const histogramShapes = histogramBins.length > 0
|
|
2212
|
+
? histogramBins.map((bin) => ({
|
|
2213
|
+
type: "rect",
|
|
2214
|
+
xref: "x",
|
|
2215
|
+
yref: "y2", // Use secondary y-axis to match the histogram scale
|
|
2216
|
+
x0: bin.x0,
|
|
2217
|
+
x1: bin.x1,
|
|
2218
|
+
y0: 0, // Start at y2 = 0
|
|
2219
|
+
y1: bin.y, // Height matches bin count on y2 axis
|
|
2220
|
+
fillcolor: histogramData.color || "rgb(211, 211, 212)",
|
|
2221
|
+
line: {
|
|
2222
|
+
color: histogramData.color || "rgb(211, 211, 212)", // Match fill color
|
|
2223
|
+
width: 0, // No border
|
|
2117
2224
|
},
|
|
2118
|
-
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
const layout = Object.assign(Object.assign(
|
|
2225
|
+
layer: "below", // Ensure shapes are drawn below traces
|
|
2226
|
+
}))
|
|
2227
|
+
: [];
|
|
2228
|
+
const layout = Object.assign(Object.assign({}, extraLayoutConfig), { title: {
|
|
2122
2229
|
text: title,
|
|
2123
2230
|
}, showlegend: false, autosize: true, width: undefined, height: undefined, hovermode: "closest", margin: {
|
|
2124
2231
|
l: 50,
|
|
2125
|
-
r:
|
|
2232
|
+
r: 80, // Balance between ensuring the mean annotation doesn't get cut off and having too much margin.
|
|
2126
2233
|
t: title ? 50 : 20, // Adjust top margin based on whether a title is provided
|
|
2127
2234
|
b: 50,
|
|
2128
2235
|
pad: 4,
|
|
2129
|
-
},
|
|
2236
|
+
},
|
|
2237
|
+
// Add histogram shapes as background rectangles
|
|
2238
|
+
shapes: histogramShapes, xaxis: {
|
|
2130
2239
|
title: {
|
|
2131
2240
|
text: xAxisTitle,
|
|
2132
2241
|
},
|
|
2133
|
-
// range: displayXAxis, // Fixed range prevents axis shifting during interaction or data updates
|
|
2134
2242
|
showgrid: true,
|
|
2135
2243
|
zeroline: false,
|
|
2136
2244
|
showline: true,
|
|
@@ -2148,7 +2256,7 @@ const LinePlot = (props) => {
|
|
|
2148
2256
|
text: yAxisTitle || "", // Set default to empty string to prevent Plotly from adding its own default title
|
|
2149
2257
|
standoff: 12, // Add space between title and axis
|
|
2150
2258
|
font: {
|
|
2151
|
-
color:
|
|
2259
|
+
color: lineData.color || "#1f77b4", // Match y-axis title color to line color
|
|
2152
2260
|
},
|
|
2153
2261
|
},
|
|
2154
2262
|
automargin: true, // Required for standoff to work properly
|
|
@@ -2164,14 +2272,33 @@ const LinePlot = (props) => {
|
|
|
2164
2272
|
linewidth: 1,
|
|
2165
2273
|
fixedrange: true, // Disable zooming
|
|
2166
2274
|
tickfont: {
|
|
2167
|
-
color:
|
|
2275
|
+
color: lineData.color || "#1f77b4", // Match y-axis tick color to line color
|
|
2168
2276
|
},
|
|
2169
2277
|
tickcolor: "white", // Hide default ticks since we're using them for group labels in the paired comparisons plot
|
|
2170
2278
|
ticklen: 10, // Give ticks a length to push labels away from y axis.
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2279
|
+
},
|
|
2280
|
+
// Second y-axis for histogram bin counts (right side)
|
|
2281
|
+
yaxis2: {
|
|
2282
|
+
side: "right",
|
|
2283
|
+
overlaying: "y",
|
|
2284
|
+
showgrid: false, // Hide grid for histogram axis
|
|
2285
|
+
zeroline: false, // Hide zero line
|
|
2286
|
+
showline: true,
|
|
2287
|
+
linecolor: "#bababa",
|
|
2288
|
+
linewidth: 1,
|
|
2289
|
+
tickfont: {
|
|
2290
|
+
color: histogramData.color || "rgb(150, 150, 150)",
|
|
2291
|
+
},
|
|
2292
|
+
title: {
|
|
2293
|
+
text: y2AxisTitle || "Count",
|
|
2294
|
+
font: {
|
|
2295
|
+
color: histogramData.color || "rgb(150, 150, 150)",
|
|
2296
|
+
},
|
|
2297
|
+
standoff: 22,
|
|
2298
|
+
},
|
|
2299
|
+
tickprefix: " ", // Add space between the ticks and axis
|
|
2300
|
+
fixedrange: true,
|
|
2301
|
+
} });
|
|
2175
2302
|
const config = {
|
|
2176
2303
|
responsive: true, // Make the plot responsive
|
|
2177
2304
|
displayModeBar: false, // Hide the mode bar
|
|
@@ -2180,41 +2307,17 @@ const LinePlot = (props) => {
|
|
|
2180
2307
|
staticPlot: false, // Enable interactivity
|
|
2181
2308
|
};
|
|
2182
2309
|
const containerStyles = Object.assign({ width: "100%", height: "100%", position: "relative" }, containerStyleOverrides);
|
|
2183
|
-
return (jsx("div", { ref: containerRef, style: Object.assign({}, containerStyles), children:
|
|
2184
|
-
|
|
2185
|
-
width: "100%",
|
|
2186
|
-
height: "100%",
|
|
2187
|
-
}, children: jsx(Plot$1, { data: [
|
|
2188
|
-
...(additionalContextTrace ? [additionalContextTrace] : []),
|
|
2189
|
-
...plotlyData,
|
|
2190
|
-
], layout: layout, config: config, useResizeHandler: true, style: {
|
|
2310
|
+
return (jsx("div", { ref: containerRef, style: Object.assign({}, containerStyles), children: jsxs(Suspense, { fallback: jsx(Loading, {}), children: [jsx("div", { style: {
|
|
2311
|
+
position: "relative",
|
|
2191
2312
|
width: "100%",
|
|
2192
2313
|
height: "100%",
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
};
|
|
2199
|
-
|
|
2200
|
-
const Plot = lazy(() => import('react-plotly.js'));
|
|
2201
|
-
const TestPlot = (props) => {
|
|
2202
|
-
var _a, _b;
|
|
2203
|
-
const data = [
|
|
2204
|
-
{
|
|
2205
|
-
x: [1, 2, 3, 4],
|
|
2206
|
-
y: [10, 15, 13, 17],
|
|
2207
|
-
type: 'bar',
|
|
2208
|
-
marker: { color: 'blue' },
|
|
2209
|
-
},
|
|
2210
|
-
];
|
|
2211
|
-
const layout = {
|
|
2212
|
-
title: { text: 'Test Bar Plot' },
|
|
2213
|
-
xaxis: { title: { text: (_a = props.xaxisTitle) !== null && _a !== void 0 ? _a : 'X Axis' } },
|
|
2214
|
-
yaxis: { title: { text: (_b = props.yaxisTitle) !== null && _b !== void 0 ? _b : 'Y Axis' } },
|
|
2215
|
-
};
|
|
2216
|
-
return jsx(Plot, { data: data, layout: layout });
|
|
2314
|
+
}, children: jsx(Plot, { data: plotlyData, layout: layout, config: config, useResizeHandler: true, style: {
|
|
2315
|
+
width: "100%",
|
|
2316
|
+
height: "100%",
|
|
2317
|
+
display: "block",
|
|
2318
|
+
transition: "opacity 0.15s ease-in-out",
|
|
2319
|
+
}, revision: revision }, `lineplot-${plotId || "default"}`) }), jsx("div", { style: { display: "none" }, children: jsx(Plot, { data: histogramPlotlyData, layout: { width: 400, height: 300 }, onInitialized: handlePlotInitialized }, `hidden-histogram-${plotId || "default"}-${hiddenPlotKey}`) })] }) }));
|
|
2217
2320
|
};
|
|
2218
2321
|
|
|
2219
|
-
export { BoxPlot, HistogramPlot,
|
|
2322
|
+
export { BoxPlot, HistogramPlot, LineWithHistogram, PairedComparisonsBoxPlot, RadialHistogramPlot, StatsDonut, SummaryComparisonPlot, SummaryComparisonPlotLegend, isDateArray, isNumberArray };
|
|
2220
2323
|
//# sourceMappingURL=index.esm.js.map
|