td-plots 1.10.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,7 @@ export interface BoxPlotDataTrace {
15
15
  color?: string;
16
16
  fill?: "auto" | "none";
17
17
  y?: number;
18
+ width?: number;
18
19
  }
19
20
  export interface BoxPlotProps {
20
21
  data: BoxPlotDataTrace[];
@@ -17,6 +17,7 @@ export interface PairedComparisonsBoxPlotProps {
17
17
  containerStyleOverrides?: React.CSSProperties;
18
18
  showLegend?: boolean;
19
19
  plotId?: string;
20
+ unit?: string;
20
21
  }
21
22
  declare const PairedComparisonsBoxPlot: (props: PairedComparisonsBoxPlotProps) => import("react/jsx-runtime").JSX.Element;
22
23
  export default PairedComparisonsBoxPlot;
@@ -20,6 +20,7 @@ export type SummaryComparisonPlotProps = {
20
20
  plotId?: string;
21
21
  tooltipPosition?: "left" | "right";
22
22
  startXAxisAtZero?: boolean;
23
+ unit?: string;
23
24
  };
24
25
  declare const SummaryComparisonPlot: (props: SummaryComparisonPlotProps) => import("react/jsx-runtime").JSX.Element;
25
26
  export default SummaryComparisonPlot;
package/dist/index.esm.js CHANGED
@@ -1515,31 +1515,17 @@ const BoxPlot = (props) => {
1515
1515
  }; // Values map to x because the boxplot is horizontal
1516
1516
  return Object.assign({ type: "box", orientation: "h", name: trace.label, fillcolor: trace.fill === "none" ? "rgba(255, 255, 255, 0)" : undefined, line: {
1517
1517
  color: trace.color || "#1f77b4", // Default to Plotly's default blue if no color provided
1518
- }, boxpoints: false, hoverinfo: "none" }, boxDefinition);
1518
+ }, boxpoints: false,
1519
+ // hoverinfo: "none", // Disable default hover
1520
+ width: trace.width }, boxDefinition);
1519
1521
  });
1520
1522
  const layout = Object.assign(Object.assign({}, extraLayoutConfig), { title: {
1521
1523
  text: title,
1522
- }, showlegend: false, autosize: true, width: undefined, height: undefined, margin: Object.assign({ l: 50, r: 35, t: 50, b: 50, pad: 4 }, extraLayoutConfig.margin), xaxis: {
1523
- title: {
1524
+ }, showlegend: false, autosize: true, width: undefined, height: undefined, margin: Object.assign({ l: 50, r: 35, t: 50, b: 50, pad: 4 }, extraLayoutConfig.margin), xaxis: Object.assign({ title: {
1524
1525
  text: xAxisTitle,
1525
- },
1526
+ },
1526
1527
  // range: displayXAxis, // Fixed range prevents axis shifting during interaction or data updates
1527
- showgrid: true,
1528
- zeroline: false,
1529
- showline: true,
1530
- mirror: "ticks",
1531
- gridcolor: "#efefef",
1532
- gridwidth: 0.2,
1533
- zerolinecolor: "#969696",
1534
- zerolinewidth: 1,
1535
- linecolor: "#bababa",
1536
- linewidth: 1,
1537
- fixedrange: true, // Disable zooming
1538
- ticklabelposition: "outside",
1539
- // tickformat: isDateArray(data) ? dateTickFormat : d3FormatValueString, // Format ticks for dates
1540
- // automargin: true, // Adjust margin if tick labels rotate
1541
- // hoverformat: isNumberArray(allData) ? d3FormatValueString : undefined,
1542
- }, yaxis: Object.assign({ title: {
1528
+ showgrid: true, zeroline: false, showline: true, mirror: "ticks", gridcolor: "#efefef", gridwidth: 0.2, zerolinecolor: "#969696", zerolinewidth: 1, linecolor: "#bababa", linewidth: 1, fixedrange: true, ticklabelposition: "outside" }, extraLayoutConfig.xaxis), yaxis: Object.assign({ title: {
1543
1529
  text: yAxisTitle || "", // Set default to empty string to prevent Plotly from adding its own default title
1544
1530
  standoff: 12, // Add space between title and axis
1545
1531
  }, automargin: true, showgrid: true, zeroline: false, showline: true, mirror: "ticks", gridcolor: "#efefef", gridwidth: 0.2, zerolinecolor: "#969696", zerolinewidth: 1, linecolor: "#bababa", linewidth: 1, fixedrange: true, tickcolor: "white", ticklen: 10, ticksuffix: " " }, extraLayoutConfig.yaxis) });
@@ -1618,10 +1604,12 @@ const PairedComparisonsBoxPlot = (props) => {
1618
1604
  // Transform the grouped data into an array for BoxPlot
1619
1605
  const boxPlotData = groups.flatMap((group, groupIndex) => {
1620
1606
  const groupYPosition = groupIndex; // Position the group on the y-axis based on its index
1621
- group.color || "orange";
1622
- return group.boxes.map((box, boxIndex) => (Object.assign(Object.assign({}, box), {
1623
- // color: box.color || groupColor, // Use box color if provided, otherwise use group color
1624
- color: "#75757f", fill: boxIndex % 2 === 0 ? "none" : "auto", y: groupYPosition + 0.15 + (boxIndex - 1) * 0.3 })));
1607
+ const groupColor = group.color || "orange";
1608
+ return group.boxes.map((box, boxIndex) => (Object.assign(Object.assign({}, box), { color: box.color || groupColor, width: 0.28, fill: boxIndex % 2 === 0 ? "none" : "auto", y: boxIndex % 2 === 0 &&
1609
+ Array.isArray(group.boxes[1].values) &&
1610
+ group.boxes[1].values.length === 0
1611
+ ? groupYPosition
1612
+ : groupYPosition + 0.25 + (boxIndex - 1) * 0.5 })));
1625
1613
  });
1626
1614
  // We have to construct nice ticks. We can position them with the group indices.
1627
1615
  const tickvals = groups.map((_, index) => index);
@@ -1636,15 +1624,15 @@ const PairedComparisonsBoxPlot = (props) => {
1636
1624
  y0: groupIndex - 0.5,
1637
1625
  y1: groupIndex + 0.5,
1638
1626
  yref: "y",
1639
- fillcolor: groupIndex % 2 === 0 ? "#ffffff" : "#f8f8f8",
1640
- opacity: 0.05,
1627
+ fillcolor: groupIndex % 2 === 0 ? "#ffffff" : "#e7e5e5",
1628
+ opacity: 0.2,
1641
1629
  layer: "below",
1642
1630
  line: {
1643
1631
  width: 0,
1644
1632
  },
1645
1633
  };
1646
1634
  });
1647
- const groupAnnotations = groups.map((group, groupIndex) => ({
1635
+ groups.map((group, groupIndex) => ({
1648
1636
  type: "line",
1649
1637
  yref: "y",
1650
1638
  xref: "paper",
@@ -1659,8 +1647,23 @@ const PairedComparisonsBoxPlot = (props) => {
1659
1647
  }));
1660
1648
  const differenceAnnotations = [];
1661
1649
  const differenceBetweenMediansLines = [];
1650
+ // Find reasonable max and min for the x axis.
1651
+ let globalMin = Infinity;
1652
+ let globalMax = -Infinity;
1662
1653
  groups.forEach((group, groupIndex) => {
1663
- // console.log(group.boxes);
1654
+ // Update global min and max
1655
+ group.boxes.forEach((box) => {
1656
+ if (isBoxPlotDataSummary(box.values)) {
1657
+ globalMin = Math.min(globalMin, box.values.lowerWhisker);
1658
+ globalMax = Math.max(globalMax, box.values.upperWhisker);
1659
+ }
1660
+ else if (Array.isArray(box.values)) {
1661
+ const boxMin = Math.min(...box.values);
1662
+ const boxMax = Math.max(...box.values);
1663
+ globalMin = Math.min(globalMin, boxMin);
1664
+ globalMax = Math.max(globalMax, boxMax);
1665
+ }
1666
+ });
1664
1667
  if ((!isBoxPlotDataSummary(group.boxes[0].values) &&
1665
1668
  group.boxes[0].values.length == 0) ||
1666
1669
  (!isBoxPlotDataSummary(group.boxes[1].values) &&
@@ -1702,14 +1705,15 @@ const PairedComparisonsBoxPlot = (props) => {
1702
1705
  xref: "x",
1703
1706
  x: medianB > medianA ? medianB : medianA, // Position the annotation at the larger median
1704
1707
  y: groupIndex, // Align with the center of the group
1705
- text: ` ${differenceBetweenMedians.toFixed(1)}`,
1708
+ text: ` ${differenceBetweenMedians.toFixed(1)}${props.unit ? ` ${props.unit}` : ""} `, // Show the difference between the medians with optional unit
1706
1709
  showarrow: false,
1707
1710
  xanchor: "left",
1708
1711
  align: "left",
1709
1712
  font: {
1710
- size: 12,
1713
+ size: 16,
1711
1714
  color: annotationColor,
1712
1715
  style: "italic",
1716
+ weight: "bold",
1713
1717
  },
1714
1718
  });
1715
1719
  differenceBetweenMediansLines.push({
@@ -1761,6 +1765,20 @@ const PairedComparisonsBoxPlot = (props) => {
1761
1765
  range: [-0.5, groups.length - 0.5], // Add some padding to the y-axis range to accommodate the boxes
1762
1766
  tickcolor: "#ffffff",
1763
1767
  showgrid: false,
1768
+ ticklabelposition: "inside",
1769
+ //@ts-ignore
1770
+ ticklabelstandoff: 10,
1771
+ ticksuffix: " ", // Add space between ticks and data
1772
+ title: {
1773
+ text: yAxisTitle || "", // Set default to empty string to prevent Plotly from adding its own default title
1774
+ standoff: 45,
1775
+ },
1776
+ },
1777
+ xaxis: {
1778
+ insiderange: [
1779
+ globalMin - (globalMax - globalMin) * 0.1,
1780
+ globalMax + (globalMax - globalMin) * 0.1,
1781
+ ], // Set the x-axis range based on the global min and max values with some padding
1764
1782
  },
1765
1783
  margin: {
1766
1784
  t: 5,
@@ -1769,7 +1787,7 @@ const PairedComparisonsBoxPlot = (props) => {
1769
1787
  shapes: [
1770
1788
  ...separatorShapes,
1771
1789
  ...differenceBetweenMediansLines,
1772
- ...groupAnnotations,
1790
+ // ...groupAnnotations,
1773
1791
  ],
1774
1792
  annotations: differenceAnnotations,
1775
1793
  };
@@ -1780,7 +1798,7 @@ const PairedComparisonsBoxPlot = (props) => {
1780
1798
 
1781
1799
  const Plot$2 = lazy(() => Promise.resolve().then(function () { return reactPlotlyWrapper$1; }));
1782
1800
  const SummaryComparisonPlot = (props) => {
1783
- const { groups, height = 250, title = "", xAxisTitle, yAxisTitle, containerStyleOverrides, plotId = "summary-comparison-plot", tooltipPosition = "right", startXAxisAtZero = true, } = props;
1801
+ const { groups, height = 250, title = "", xAxisTitle, yAxisTitle, containerStyleOverrides, plotId = "summary-comparison-plot", tooltipPosition = "right", startXAxisAtZero = true, unit = "", } = props;
1784
1802
  // Ref for plot container
1785
1803
  const containerRef = useRef(null);
1786
1804
  // State for custom tooltip
@@ -1862,6 +1880,8 @@ const SummaryComparisonPlot = (props) => {
1862
1880
  const handleUnhover = () => {
1863
1881
  setTooltip((prev) => (Object.assign(Object.assign({}, prev), { visible: false })));
1864
1882
  };
1883
+ const comparedLines = [];
1884
+ const comparedAnnotations = [];
1865
1885
  // Transform the data into a format suitable for a plotly scatterplot
1866
1886
  const plotlyData = groups.flatMap((group, groupIndex) => {
1867
1887
  const traces = [];
@@ -1872,10 +1892,10 @@ const SummaryComparisonPlot = (props) => {
1872
1892
  mode: "lines",
1873
1893
  name: group.groupLabel,
1874
1894
  x: [group.data.summarizedMin, group.data.summarizedMax],
1875
- y: [0 + groupIndex * 0.1, 0 + groupIndex * 0.1],
1895
+ y: [groupIndex * 0.1, groupIndex * 0.1],
1876
1896
  line: {
1877
1897
  color: colorToRGBA(group.color || "orange", 1),
1878
- width: 2,
1898
+ width: 6,
1879
1899
  },
1880
1900
  showlegend: false,
1881
1901
  hoverinfo: "none",
@@ -1887,9 +1907,9 @@ const SummaryComparisonPlot = (props) => {
1887
1907
  mode: "markers",
1888
1908
  name: group.groupLabel,
1889
1909
  x: [group.data.comparedMedian],
1890
- y: [0 + groupIndex * 0.1],
1910
+ y: [groupIndex * 0.1],
1891
1911
  marker: {
1892
- color: group.color || "orange",
1912
+ color: colorToRGBA(group.color || "orange", 1),
1893
1913
  size: 10,
1894
1914
  symbol: "circle",
1895
1915
  line: {
@@ -1900,9 +1920,45 @@ const SummaryComparisonPlot = (props) => {
1900
1920
  showlegend: false,
1901
1921
  hoverinfo: "none",
1902
1922
  });
1923
+ comparedLines.push({
1924
+ type: "line",
1925
+ name: group.groupLabel,
1926
+ x0: group.data.comparedMedian,
1927
+ x1: group.data.comparedMedian,
1928
+ y0: 0,
1929
+ y1: 1.1,
1930
+ yref: "paper",
1931
+ line: {
1932
+ color: group.color || "orange",
1933
+ width: 2,
1934
+ },
1935
+ });
1936
+ comparedAnnotations.push({
1937
+ x: group.data.comparedMedian,
1938
+ y: 1.08,
1939
+ xref: "x",
1940
+ yref: "paper",
1941
+ text: `${group.data.comparedMedian.toFixed(2)} ${unit}`,
1942
+ showarrow: false,
1943
+ xanchor: "center",
1944
+ yanchor: "bottom",
1945
+ });
1903
1946
  }
1904
1947
  return traces;
1905
1948
  });
1949
+ // Add tick label for the compared annotation value
1950
+ if (comparedAnnotations.length > 0) {
1951
+ comparedAnnotations.push({
1952
+ x: -0.03, // Position to the left of the y-axis
1953
+ y: 1.03,
1954
+ xref: "paper",
1955
+ yref: "paper",
1956
+ text: "My AVG",
1957
+ showarrow: false,
1958
+ xanchor: "right",
1959
+ yanchor: "bottom",
1960
+ });
1961
+ }
1906
1962
  const xRangeMin = groups.reduce((min, group) => {
1907
1963
  var _a, _b;
1908
1964
  return Math.min(min, (_a = group.data.summarizedMin) !== null && _a !== void 0 ? _a : Infinity, (_b = group.data.comparedMedian) !== null && _b !== void 0 ? _b : Infinity);
@@ -1918,10 +1974,9 @@ const SummaryComparisonPlot = (props) => {
1918
1974
  margin: {
1919
1975
  l: 130,
1920
1976
  r: 35, // Balance between ensuring the mean annotation doesn't get cut off and having too much margin.
1921
- t: title ? 50 : 5,
1977
+ t: title ? 70 : 40,
1922
1978
  b: 50,
1923
1979
  pad: 4,
1924
- // ...extraLayoutConfig.margin, // Merge in any extra margin config provided via props
1925
1980
  },
1926
1981
  title: {
1927
1982
  text: title,
@@ -1929,8 +1984,12 @@ const SummaryComparisonPlot = (props) => {
1929
1984
  size: 16,
1930
1985
  },
1931
1986
  xref: "paper",
1932
- x: 0.5,
1933
- xanchor: "center",
1987
+ x: 0,
1988
+ xanchor: "left",
1989
+ yanchor: "bottom",
1990
+ pad: {
1991
+ b: 30,
1992
+ },
1934
1993
  },
1935
1994
  xaxis: {
1936
1995
  title: {
@@ -1975,8 +2034,12 @@ const SummaryComparisonPlot = (props) => {
1975
2034
  range: [-0.08, 0.08 + (groups.length - 1) * 0.1], // Add padding around the groups
1976
2035
  automargin: true,
1977
2036
  tickcolor: "white", // Hide default ticks since we're using them for group labels in the paired comparisons plot
2037
+ //@ts-ignore
2038
+ ticklabelstandoff: 5,
1978
2039
  },
1979
2040
  hovermode: "y",
2041
+ shapes: comparedLines,
2042
+ annotations: comparedAnnotations,
1980
2043
  };
1981
2044
  const containerStyles = Object.assign({ width: "100%", height: height, position: "relative", display: "flex", flexDirection: "column", gap: 0 }, containerStyleOverrides);
1982
2045
  const config = {