@splunk/visualizations 28.3.0 → 28.4.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.
Files changed (225) hide show
  1. package/Area/Area.d.ts.map +1 -1
  2. package/Area.config.js +0 -1
  3. package/Area.config.js.map +2 -2
  4. package/Area.js +495 -99
  5. package/Area.js.map +3 -3
  6. package/Bar/Bar.d.ts.map +1 -1
  7. package/Bar.config.js +0 -1
  8. package/Bar.config.js.map +2 -2
  9. package/Bar.js +505 -99
  10. package/Bar.js.map +3 -3
  11. package/Bubble.config.js +0 -1
  12. package/Bubble.config.js.map +2 -2
  13. package/Bubble.js +494 -86
  14. package/Bubble.js.map +3 -3
  15. package/CHANGELOG.external.md +76 -0
  16. package/ChoroplethSvg/ChoroplethSvg.d.ts +4 -3
  17. package/ChoroplethSvg/ChoroplethSvg.d.ts.map +1 -1
  18. package/ChoroplethSvg.config.js +1 -3
  19. package/ChoroplethSvg.config.js.map +2 -2
  20. package/ChoroplethSvg.js +539 -103
  21. package/ChoroplethSvg.js.map +4 -4
  22. package/Column/Column.d.ts.map +1 -1
  23. package/Column.config.js +0 -1
  24. package/Column.config.js.map +2 -2
  25. package/Column.js +495 -99
  26. package/Column.js.map +3 -3
  27. package/Ellipse.js +528 -104
  28. package/Ellipse.js.map +4 -4
  29. package/Events/PureEvents/PureEvents.d.ts.map +1 -1
  30. package/Events.js +612 -149
  31. package/Events.js.map +4 -4
  32. package/FillerGauge/FillerGauge.d.ts.map +1 -1
  33. package/FillerGauge/PureFillerGauge/FillerGauge.d.ts.map +1 -1
  34. package/FillerGauge.js +535 -140
  35. package/FillerGauge.js.map +4 -4
  36. package/Image/Image.d.ts.map +1 -1
  37. package/Image.js +564 -108
  38. package/Image.js.map +4 -4
  39. package/Line/Line.d.ts.map +1 -1
  40. package/Line/lineUtils.d.ts.map +1 -1
  41. package/Line/mockdata/LineData.d.ts +59 -0
  42. package/Line/mockdata/LineData.d.ts.map +1 -1
  43. package/Line.config.js +0 -1
  44. package/Line.config.js.map +2 -2
  45. package/Line.js +601 -100
  46. package/Line.js.map +3 -3
  47. package/LinkGraph/PureLinkGraph/PureLinkGraph.d.ts +5 -0
  48. package/LinkGraph/PureLinkGraph/PureLinkGraph.d.ts.map +1 -1
  49. package/LinkGraph/PureLinkGraph/PureLinkGraphUtils.d.ts.map +1 -1
  50. package/LinkGraph/PureLinkGraph/components/Graph.d.ts +9 -1
  51. package/LinkGraph/PureLinkGraph/components/Graph.d.ts.map +1 -1
  52. package/LinkGraph/PureLinkGraph/components/GraphStyles.d.ts.map +1 -1
  53. package/LinkGraph/PureLinkGraph/components/Node.d.ts +1 -0
  54. package/LinkGraph/PureLinkGraph/components/Node.d.ts.map +1 -1
  55. package/LinkGraph/PureLinkGraph/components/Nodes.d.ts +1 -0
  56. package/LinkGraph/PureLinkGraph/components/Nodes.d.ts.map +1 -1
  57. package/LinkGraph/PureLinkGraph/measurementUtils.d.ts +16 -0
  58. package/LinkGraph/PureLinkGraph/measurementUtils.d.ts.map +1 -0
  59. package/LinkGraph/PureLinkGraph/utils/iconLoader.d.ts.map +1 -1
  60. package/LinkGraph/config.d.ts.map +1 -1
  61. package/LinkGraph.config.js +15 -1
  62. package/LinkGraph.config.js.map +2 -2
  63. package/LinkGraph.js +1355 -654
  64. package/LinkGraph.js.map +4 -4
  65. package/Map/Map.d.ts +2 -2
  66. package/Map/Map.d.ts.map +1 -1
  67. package/Map/PureMap/BubbleLayer.d.ts +5 -0
  68. package/Map/PureMap/BubbleLayer.d.ts.map +1 -1
  69. package/Map/PureMap/LocalChoroplethLayer.d.ts.map +1 -1
  70. package/Map/PureMap/PureMap.d.ts.map +1 -1
  71. package/Map/PureMap/PureMapContainer.d.ts.map +1 -1
  72. package/Map/PureMap/Tooltip.d.ts.map +1 -1
  73. package/Map/config.d.ts.map +1 -1
  74. package/Map.config.js +0 -1
  75. package/Map.config.js.map +2 -2
  76. package/Map.js +738 -228
  77. package/Map.js.map +4 -4
  78. package/Markdown/Markdown.d.ts.map +1 -1
  79. package/Markdown.js +548 -95
  80. package/Markdown.js.map +4 -4
  81. package/MarkerGauge/MarkerGauge.d.ts +5 -1
  82. package/MarkerGauge/MarkerGauge.d.ts.map +1 -1
  83. package/MarkerGauge/PureMarkerGauge/MarkerGauge.d.ts +4 -0
  84. package/MarkerGauge/PureMarkerGauge/MarkerGauge.d.ts.map +1 -1
  85. package/MarkerGauge/config.d.ts.map +1 -1
  86. package/MarkerGauge.config.js +121 -3
  87. package/MarkerGauge.config.js.map +3 -3
  88. package/MarkerGauge.js +1318 -142
  89. package/MarkerGauge.js.map +4 -4
  90. package/NetworkGraph/NetworkGraph.d.ts +22 -0
  91. package/NetworkGraph/NetworkGraph.d.ts.map +1 -0
  92. package/NetworkGraph/PureNetworkGraph/PureNetworkGraph.d.ts +60 -0
  93. package/NetworkGraph/PureNetworkGraph/PureNetworkGraph.d.ts.map +1 -0
  94. package/NetworkGraph/PureNetworkGraph/components/Link.d.ts +19 -0
  95. package/NetworkGraph/PureNetworkGraph/components/Link.d.ts.map +1 -0
  96. package/NetworkGraph/PureNetworkGraph/components/NetworkGraphSvg.d.ts +29 -0
  97. package/NetworkGraph/PureNetworkGraph/components/NetworkGraphSvg.d.ts.map +1 -0
  98. package/NetworkGraph/PureNetworkGraph/components/Node.d.ts +27 -0
  99. package/NetworkGraph/PureNetworkGraph/components/Node.d.ts.map +1 -0
  100. package/NetworkGraph/PureNetworkGraph/components/Tooltip.d.ts +12 -0
  101. package/NetworkGraph/PureNetworkGraph/components/Tooltip.d.ts.map +1 -0
  102. package/NetworkGraph/PureNetworkGraph/components/ZoomControls.d.ts +13 -0
  103. package/NetworkGraph/PureNetworkGraph/components/ZoomControls.d.ts.map +1 -0
  104. package/NetworkGraph/PureNetworkGraph/mockdata/data.d.ts +140 -0
  105. package/NetworkGraph/PureNetworkGraph/mockdata/data.d.ts.map +1 -0
  106. package/NetworkGraph/PureNetworkGraph/mockdata/datasource.d.ts +89 -0
  107. package/NetworkGraph/PureNetworkGraph/mockdata/datasource.d.ts.map +1 -0
  108. package/NetworkGraph/PureNetworkGraph/utils/forceLayout.d.ts +47 -0
  109. package/NetworkGraph/PureNetworkGraph/utils/forceLayout.d.ts.map +1 -0
  110. package/NetworkGraph/PureNetworkGraph/utils/iconLoader.d.ts +78 -0
  111. package/NetworkGraph/PureNetworkGraph/utils/iconLoader.d.ts.map +1 -0
  112. package/NetworkGraph/PureNetworkGraph/utils/networkGraphShared.d.ts +111 -0
  113. package/NetworkGraph/PureNetworkGraph/utils/networkGraphShared.d.ts.map +1 -0
  114. package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts +123 -0
  115. package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts.map +1 -0
  116. package/NetworkGraph/config.d.ts +4 -0
  117. package/NetworkGraph/config.d.ts.map +1 -0
  118. package/NetworkGraph/index.d.ts +3 -0
  119. package/NetworkGraph/index.d.ts.map +1 -0
  120. package/NetworkGraph.config.js +938 -0
  121. package/NetworkGraph.config.js.map +7 -0
  122. package/NetworkGraph.js +6793 -0
  123. package/NetworkGraph.js.map +7 -0
  124. package/ParallelCoordinates.js +532 -93
  125. package/ParallelCoordinates.js.map +4 -4
  126. package/Pie/Pie.d.ts.map +1 -1
  127. package/Pie/pieUtils.d.ts.map +1 -1
  128. package/Pie.js +510 -101
  129. package/Pie.js.map +3 -3
  130. package/Punchcard.js +523 -84
  131. package/Punchcard.js.map +4 -4
  132. package/Rectangle.js +537 -113
  133. package/Rectangle.js.map +4 -4
  134. package/Sankey/PureSankey/SankeyTooltip.d.ts.map +1 -1
  135. package/Sankey.js +562 -111
  136. package/Sankey.js.map +4 -4
  137. package/Scatter/Scatter.d.ts.map +1 -1
  138. package/Scatter.config.js +0 -1
  139. package/Scatter.config.js.map +2 -2
  140. package/Scatter.js +505 -99
  141. package/Scatter.js.map +3 -3
  142. package/SingleValue/SingleValue.d.ts.map +1 -1
  143. package/SingleValue/config.d.ts.map +1 -1
  144. package/SingleValue.config.js +15 -2
  145. package/SingleValue.config.js.map +2 -2
  146. package/SingleValue.js +656 -173
  147. package/SingleValue.js.map +3 -3
  148. package/SingleValueBasic.js.map +1 -1
  149. package/SingleValueIcon/SingleValueIcon.d.ts.map +1 -1
  150. package/SingleValueIcon/config.d.ts.map +1 -1
  151. package/SingleValueIcon.config.js +0 -1
  152. package/SingleValueIcon.config.js.map +2 -2
  153. package/SingleValueIcon.js +512 -124
  154. package/SingleValueIcon.js.map +3 -3
  155. package/SingleValueRadial/PureSingleValueRadial/utils/gaugeUtils.d.ts +0 -8
  156. package/SingleValueRadial/PureSingleValueRadial/utils/gaugeUtils.d.ts.map +1 -1
  157. package/SingleValueRadial/SingleValueRadial.d.ts.map +1 -1
  158. package/SingleValueRadial.config.js +0 -1
  159. package/SingleValueRadial.config.js.map +2 -2
  160. package/SingleValueRadial.js +517 -124
  161. package/SingleValueRadial.js.map +4 -4
  162. package/SparkLine.js +46 -8
  163. package/SparkLine.js.map +2 -2
  164. package/Table/PureTable.d.ts +10 -0
  165. package/Table/PureTable.d.ts.map +1 -1
  166. package/Table/cells/SparklineCell.d.ts.map +1 -1
  167. package/Table/config.d.ts.map +1 -1
  168. package/Table/hooks.d.ts +4 -0
  169. package/Table/hooks.d.ts.map +1 -1
  170. package/Table.config.js +1 -1
  171. package/Table.config.js.map +2 -2
  172. package/Table.js +760 -223
  173. package/Table.js.map +4 -4
  174. package/Timeline/PureTimeline/src/CursorPlugin.d.ts.map +1 -1
  175. package/Timeline/PureTimeline/src/TimelineLegend.d.ts.map +1 -1
  176. package/Timeline/config.d.ts.map +1 -1
  177. package/Timeline.config.js +31 -12
  178. package/Timeline.config.js.map +4 -4
  179. package/Timeline.js +649 -211
  180. package/Timeline.js.map +4 -4
  181. package/common/Charting.d.ts +5 -0
  182. package/common/Charting.d.ts.map +1 -1
  183. package/common/Charting.js +12 -0
  184. package/common/Charting.js.map +2 -2
  185. package/common/OptionsDoc.js.map +1 -1
  186. package/common/ThemesDoc.js +0 -1
  187. package/common/ThemesDoc.js.map +2 -2
  188. package/common/TimeSeriesChartWrapper.d.ts +24 -11
  189. package/common/TimeSeriesChartWrapper.d.ts.map +1 -1
  190. package/common/TimeSeriesChartWrapper.js +561 -83
  191. package/common/TimeSeriesChartWrapper.js.map +4 -4
  192. package/common/chartingUtils.d.ts +45 -5
  193. package/common/chartingUtils.d.ts.map +1 -1
  194. package/common/chartingUtils.js +102 -8
  195. package/common/chartingUtils.js.map +3 -3
  196. package/common/editorConfig/AxesChartDataConfig.d.ts.map +1 -1
  197. package/common/hocs/withTrellis.d.ts.map +1 -1
  198. package/common/interfaces/DashboardVizProps.d.ts +0 -3
  199. package/common/interfaces/DashboardVizProps.d.ts.map +1 -1
  200. package/common/interfaces/DataSource.d.ts +1 -1
  201. package/common/interfaces/DataSource.d.ts.map +1 -1
  202. package/common/shapeUtils.js +5 -20
  203. package/common/shapeUtils.js.map +2 -2
  204. package/common/utils/dataUtils.d.ts.map +1 -1
  205. package/common/utils/dataUtils.js +5 -4
  206. package/common/utils/dataUtils.js.map +2 -2
  207. package/common/utils/mapUtils.js +16 -9
  208. package/common/utils/mapUtils.js.map +2 -2
  209. package/common/utils/singleValueUtils.js +17 -18
  210. package/common/utils/singleValueUtils.js.map +2 -2
  211. package/common/utils/textUtils.d.ts +20 -0
  212. package/common/utils/textUtils.d.ts.map +1 -0
  213. package/common/utils/textUtils.js +76 -0
  214. package/common/utils/textUtils.js.map +7 -0
  215. package/common/utils/trellisUtils.d.ts.map +1 -1
  216. package/common/utils/trellisUtils.js +12 -14
  217. package/common/utils/trellisUtils.js.map +2 -2
  218. package/common/withDashboardViz.d.ts.map +1 -1
  219. package/common/withDashboardViz.js +544 -84
  220. package/common/withDashboardViz.js.map +4 -4
  221. package/package.json +33 -26
  222. package/common/utils/styleUtils.d.ts +0 -2
  223. package/common/utils/styleUtils.d.ts.map +0 -1
  224. package/common/utils/styleUtils.js +0 -30
  225. package/common/utils/styleUtils.js.map +0 -7
package/Table.js CHANGED
@@ -723,8 +723,8 @@ var editorConfig = [
723
723
  }
724
724
  ]
725
725
  ],
726
- // TODO(fkurniawan): fill in with proper editor components
727
726
  sparkline: [],
727
+ // Configure via columnFormat.sparklineNullValueDisplay
728
728
  string: [
729
729
  [
730
730
  __spreadValues({}, unitPositionConfig),
@@ -1201,7 +1201,7 @@ var Cover = styled_components_default.div`
1201
1201
  bottom: 0;
1202
1202
  `;
1203
1203
  var Blocker = styled_components_default.div.attrs({
1204
- "data-splunk-visualization-version": "28.3.0 - 843e0f60b"
1204
+ "data-splunk-visualization-version": "28.4.0 - 002bd482f"
1205
1205
  })`
1206
1206
  position: relative;
1207
1207
  width: 100%;
@@ -1282,7 +1282,7 @@ var withFixedSizeContainer = (Viz) => {
1282
1282
  FixSizeItem,
1283
1283
  {
1284
1284
  "data-test": "fix-size-item",
1285
- "data-splunk-visualization-version": "28.3.0 - 843e0f60b",
1285
+ "data-splunk-visualization-version": "28.4.0 - 002bd482f",
1286
1286
  width,
1287
1287
  height,
1288
1288
  backgroundColor
@@ -1378,6 +1378,7 @@ __reExport(numberUtils_exports, require("@splunk/visualizations-shared/numberUti
1378
1378
  var numberUtils_default = "default" in defaultImport31 ? defaultImport31.default : defaultImport31;
1379
1379
 
1380
1380
  // src/common/utils/dataUtils.ts
1381
+ var getFieldName = (field) => typeof field === "string" ? field : field.name;
1381
1382
  var largestTriangleThreeBuckets = (data, threshold, preferredDownsampleIndices) => {
1382
1383
  const dataLength = data.length;
1383
1384
  const downsampledIndices = [];
@@ -1494,9 +1495,9 @@ var tryToCoerceAllDisplayedFields = (ds, xField, yFields, fieldTypes, options) =
1494
1495
  let xColumn = [];
1495
1496
  const yColumns = [];
1496
1497
  const canDownsample = !ds.data.fields.some((field, index) => {
1497
- var _a, _b;
1498
- const fieldName = (_a = field.name) != null ? _a : field;
1499
- const fieldType = (_b = fieldTypes[index]) != null ? _b : "unknown";
1498
+ var _a;
1499
+ const fieldName = getFieldName(field);
1500
+ const fieldType = (_a = fieldTypes[index]) != null ? _a : "unknown";
1500
1501
  const column = ds.data.columns[index];
1501
1502
  let hasDisplayedColumnThatCantBeDownsampled = false;
1502
1503
  if (fieldName === xField) {
@@ -1849,6 +1850,16 @@ var triangleEventAnnotationRenderer = ({
1849
1850
  eventColor: eventWithColor.color
1850
1851
  });
1851
1852
  };
1853
+ var shouldEnableSearchZoom = (eventHandlers = [], xField = "") => {
1854
+ const rangeSelectEventHandler = eventHandlers.find(
1855
+ (eventHandler) => {
1856
+ var _a;
1857
+ return (_a = eventHandler.options.events) == null ? void 0 : _a.includes("range.select");
1858
+ }
1859
+ );
1860
+ const xAxisIsTime = xField === "_time";
1861
+ return !!rangeSelectEventHandler && xAxisIsTime;
1862
+ };
1852
1863
  var canvasSupportedTimeSeriesCharts = ["splunk.line"];
1853
1864
  var isTimeSeriesCanvasRenderSupported = (vizConfigKey) => {
1854
1865
  return canvasSupportedTimeSeriesCharts.indexOf(vizConfigKey) > -1;
@@ -1869,16 +1880,31 @@ var filterChartDataFromInternalFields = (chartData) => {
1869
1880
  var convert2DArrayToNumbers = (arr) => {
1870
1881
  return arr.map((subArray) => subArray.map((element) => parseFloat(element)));
1871
1882
  };
1883
+ var parseAxisValue = (val) => {
1884
+ if (val === void 0 || val === null || val === "auto" || val === "") {
1885
+ return void 0;
1886
+ }
1887
+ const num = typeof val === "number" ? val : Number.parseFloat(val);
1888
+ return Number.isNaN(num) ? void 0 : num;
1889
+ };
1872
1890
  var SideLegendWidth = 75;
1873
- var commonLegendProps = { center: true, fontSize: 12, largerTiles: true, hideSeriesValue: true };
1891
+ var SeriesCompareLegendWidth = 200;
1874
1892
  var getLegend = (props) => {
1875
1893
  const legendPlacement = props == null ? void 0 : props.legendDisplay;
1894
+ const { isSeriesCompare } = props;
1895
+ const commonLegendProps = {
1896
+ center: true,
1897
+ fontSize: 12,
1898
+ largerTiles: true,
1899
+ hideSeriesValue: !isSeriesCompare
1900
+ // Show values if in seriesCompare mode
1901
+ };
1876
1902
  switch (legendPlacement) {
1877
1903
  case "off":
1878
1904
  return false;
1879
1905
  case "left":
1880
1906
  return (0, visualization_canvas_exports.LeftLegendFactory)(__spreadValues({
1881
- width: SideLegendWidth
1907
+ width: isSeriesCompare ? SeriesCompareLegendWidth : SideLegendWidth
1882
1908
  }, commonLegendProps));
1883
1909
  case "bottom":
1884
1910
  return (0, visualization_canvas_exports.BottomLegendFactory)(__spreadValues({
@@ -1890,7 +1916,7 @@ var getLegend = (props) => {
1890
1916
  }, commonLegendProps));
1891
1917
  default:
1892
1918
  return (0, visualization_canvas_exports.SideLegendFactory)(__spreadValues({
1893
- width: SideLegendWidth
1919
+ width: isSeriesCompare ? SeriesCompareLegendWidth : SideLegendWidth
1894
1920
  }, commonLegendProps));
1895
1921
  }
1896
1922
  };
@@ -1926,22 +1952,25 @@ var ellipsisAxisTitle = (axisTitle, containerSpacing, fontSize = 12) => {
1926
1952
  const end = axisTitle.slice(-halfChars);
1927
1953
  return `${start}...${end}`;
1928
1954
  };
1929
- var getFieldName = (field) => {
1955
+ var getFieldName2 = (field) => {
1930
1956
  const fieldName = typeof field === "object" ? field == null ? void 0 : field.name : field;
1931
1957
  return fieldName;
1932
1958
  };
1933
1959
  var getFieldNames = (fields) => {
1934
- return fields.map((field) => getFieldName(field));
1960
+ return fields.map((field) => getFieldName2(field));
1935
1961
  };
1936
- var getXScaleConfig = (label, xAxisLabelVisibility) => {
1962
+ var getXScaleConfig = (label, xAxisLabelVisibility, xAxisLabelRotation) => {
1937
1963
  const xConfig = { x: {} };
1938
1964
  xConfig.x.label = label;
1939
1965
  if (xAxisLabelVisibility === "hide") {
1940
1966
  xConfig.x.hideLabels = true;
1941
1967
  }
1968
+ if (xAxisLabelRotation !== void 0) {
1969
+ xConfig.x.labelRotation = xAxisLabelRotation;
1970
+ }
1942
1971
  return xConfig;
1943
1972
  };
1944
- var getYScaleConfig = (label, yAxisAbbreviation, yAxisScale, yAxisLabelVisibility) => {
1973
+ var getYScaleConfig = (label, yAxisAbbreviation, yAxisScale, yAxisLabelVisibility, yAxisMin, yAxisMax) => {
1945
1974
  const scaleType = yAxisScale != null ? yAxisScale : "linear";
1946
1975
  const yConfig = { y: {} };
1947
1976
  yConfig.y.label = label;
@@ -1957,14 +1986,20 @@ var getYScaleConfig = (label, yAxisAbbreviation, yAxisScale, yAxisLabelVisibilit
1957
1986
  if (yAxisLabelVisibility === "hide") {
1958
1987
  yConfig.y.hideLabels = true;
1959
1988
  }
1989
+ if (yAxisMin !== void 0 || yAxisMax !== void 0) {
1990
+ yConfig.y.range = (u, dataMin, dataMax) => {
1991
+ const min2 = yAxisMin != null ? yAxisMin : dataMin;
1992
+ const max2 = yAxisMax != null ? yAxisMax : dataMax;
1993
+ return [min2, max2];
1994
+ };
1995
+ }
1960
1996
  return yConfig;
1961
1997
  };
1962
- var getY2ScaleConfig = (label, axisAbbreviation, axisScale, roundAxisLabelsToInteger, y2AxisLabelVisibility) => {
1998
+ var getY2ScaleConfig = (label, axisAbbreviation, axisScale, roundAxisLabelsToInteger, y2AxisLabelVisibility, y2AxisMin, y2AxisMax) => {
1963
1999
  const y2Config = { y2: {} };
1964
2000
  const scaleType = axisScale != null ? axisScale : "linear";
1965
2001
  y2Config.y2.label = label;
1966
2002
  y2Config.y2.side = "right";
1967
- y2Config.y2.showGrid = false;
1968
2003
  y2Config.y2.type = scaleType;
1969
2004
  if (axisAbbreviation !== "none") {
1970
2005
  y2Config.y2.tickFmt = (v) => (0, visualization_canvas_exports.shortenNumber)(v, 1, roundAxisLabelsToInteger);
@@ -1974,9 +2009,16 @@ var getY2ScaleConfig = (label, axisAbbreviation, axisScale, roundAxisLabelsToInt
1974
2009
  if (y2AxisLabelVisibility === "hide") {
1975
2010
  y2Config.y2.hideLabels = true;
1976
2011
  }
2012
+ if (y2AxisMin !== void 0 || y2AxisMax !== void 0) {
2013
+ y2Config.y2.range = (u, dataMin, dataMax) => {
2014
+ const min2 = y2AxisMin != null ? y2AxisMin : dataMin;
2015
+ const max2 = y2AxisMax != null ? y2AxisMax : dataMax;
2016
+ return [min2, max2];
2017
+ };
2018
+ }
1977
2019
  return y2Config;
1978
2020
  };
1979
- var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled, nullValueMode, markerDisplay) => {
2021
+ var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled, nullValueMode, markerDisplay, lineDashStyle, lineDashStylesByField) => {
1980
2022
  const seriesConfig = {};
1981
2023
  let spanGaps;
1982
2024
  let replaceNullsWithZero;
@@ -2011,12 +2053,87 @@ var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled
2011
2053
  if (markerDisplay !== void 0) {
2012
2054
  seriesConfig[field].markerDisplay = markerDisplay;
2013
2055
  }
2056
+ const fieldDashStyle = (lineDashStylesByField == null ? void 0 : lineDashStylesByField[field]) || lineDashStyle;
2057
+ if (fieldDashStyle) {
2058
+ seriesConfig[field].lineDashStyle = fieldDashStyle;
2059
+ }
2014
2060
  if (replaceNullsWithZero !== void 0) {
2015
2061
  seriesConfig[field].replaceNullsWithZero = replaceNullsWithZero;
2016
2062
  }
2017
2063
  });
2018
2064
  return seriesConfig;
2019
2065
  };
2066
+ var findRangeIndices = (xData, startValue, endValue) => {
2067
+ let startXIndex = -1;
2068
+ let endXIndex = -1;
2069
+ const xDataEpoch = xData.map((val) => {
2070
+ if (typeof val === "string") {
2071
+ return new Date(val).getTime() / 1e3;
2072
+ }
2073
+ return val;
2074
+ });
2075
+ for (let i = 0; i < xDataEpoch.length; i += 1) {
2076
+ if (xDataEpoch[i] >= startValue) {
2077
+ startXIndex = i;
2078
+ break;
2079
+ }
2080
+ }
2081
+ if (startXIndex === -1 && xDataEpoch.length > 0) {
2082
+ startXIndex = xDataEpoch.length - 1;
2083
+ }
2084
+ for (let i = xDataEpoch.length - 1; i >= 0; i -= 1) {
2085
+ if (xDataEpoch[i] <= endValue) {
2086
+ endXIndex = i;
2087
+ break;
2088
+ }
2089
+ }
2090
+ if (endXIndex === -1 && xDataEpoch.length > 0) {
2091
+ endXIndex = 0;
2092
+ }
2093
+ return { startXIndex, endXIndex };
2094
+ };
2095
+
2096
+ // src/common/hooks/useTrellisEnabled.ts
2097
+ var useTrellisFeatureFlagOn = () => {
2098
+ const context = (0, react_exports.useContext)(FeatureFlagContext_default);
2099
+ return Boolean(context == null ? void 0 : context.visualizations_enableTrellis);
2100
+ };
2101
+ var useTrellisEnabled = (layoutType = visualization_schemas_exports.LAYOUT_TYPE.Off) => {
2102
+ const trellisFeatureEnabled = useTrellisFeatureFlagOn();
2103
+ return trellisFeatureEnabled && layoutType === visualization_schemas_exports.LAYOUT_TYPE.Trellis;
2104
+ };
2105
+
2106
+ // src/common/components/TrellisTitle.tsx
2107
+ var TRELLIS_TITLE_HEIGHT = 28;
2108
+ var TrellisTitleText = styled_components_default.div`
2109
+ margin-left: 10px;
2110
+ margin-right: 10px;
2111
+ padding-top: 8px;
2112
+ text-overflow: ellipsis;
2113
+ white-space: nowrap;
2114
+ overflow: hidden;
2115
+ `;
2116
+ var TrellisTitleDiv = styled_components_default.div`
2117
+ height: ${TRELLIS_TITLE_HEIGHT}px;
2118
+ font-size: 14px;
2119
+ font-weight: 700;
2120
+ color: ${(props) => props.fontColor};
2121
+ background-color: ${(props) => props.backgroundColor};
2122
+ box-shadow: 0 1px ${(props) => props.backgroundColor}; // this is added to avoid a 1px gap between title and viz divs that showed up intermittently because of pixel rounding error in chrome.
2123
+ `;
2124
+ var TrellisTitle = (props) => {
2125
+ const titleText = String(props.trellisKey).toString();
2126
+ return /* @__PURE__ */ react_exports.createElement(
2127
+ TrellisTitleDiv,
2128
+ {
2129
+ fontColor: props.fontColor,
2130
+ backgroundColor: props.backgroundColor,
2131
+ "data-test": "trellis-title",
2132
+ title: titleText
2133
+ },
2134
+ /* @__PURE__ */ react_exports.createElement(TrellisTitleText, null, titleText)
2135
+ );
2136
+ };
2020
2137
 
2021
2138
  // src/common/TimeSeriesChartWrapper.tsx
2022
2139
  var TimeSeriesChartContainer = styled_components_default.div`
@@ -2027,38 +2144,123 @@ var TimeSeriesChartContainer = styled_components_default.div`
2027
2144
  position: absolute !important; // This is needed for canvas element export pdf/png to work correctly
2028
2145
  }
2029
2146
  `;
2030
- var handleClick = (chartEvent, onClick) => {
2147
+ var appendTrellisToPayload = (payload, trellisKey, trellisSplitBy) => {
2148
+ const result = __spreadValues({}, payload);
2149
+ if (trellisSplitBy) {
2150
+ result["trellis.name"] = trellisSplitBy;
2151
+ }
2152
+ if (trellisKey) {
2153
+ result["trellis.value"] = trellisKey;
2154
+ }
2155
+ return result;
2156
+ };
2157
+ var hasMouseoverPayloadChanged = (currentPayload, previousPayload) => {
2158
+ if (!previousPayload) {
2159
+ return true;
2160
+ }
2161
+ if (currentPayload.index !== previousPayload.index) {
2162
+ return true;
2163
+ }
2164
+ if (currentPayload.seriesIndex !== previousPayload.seriesIndex) {
2165
+ return true;
2166
+ }
2167
+ if (currentPayload["trellis.name"] !== previousPayload["trellis.name"]) {
2168
+ return true;
2169
+ }
2170
+ if (currentPayload["trellis.value"] !== previousPayload["trellis.value"]) {
2171
+ return true;
2172
+ }
2173
+ return false;
2174
+ };
2175
+ var handleClick = (chartEvent, onClick, trellisKey, trellisSplitBy) => {
2031
2176
  const payload = __spreadProps(__spreadValues({}, (0, lodash_exports.pick)(chartEvent, "value", "seriesKey")), {
2032
2177
  name: chartEvent.seriesKey
2033
2178
  });
2034
2179
  delete payload.seriesKey;
2035
2180
  if (chartEvent.rowContext) {
2036
- Object.keys(chartEvent.rowContext).forEach((fieldName) => {
2037
- payload[`row.${fieldName}.value`] = chartEvent.rowContext[fieldName];
2038
- });
2181
+ Object.assign(
2182
+ payload,
2183
+ Object.keys(chartEvent.rowContext).reduce((acc, fieldName) => {
2184
+ acc[`row.${fieldName}.value`] = chartEvent.rowContext[fieldName];
2185
+ return acc;
2186
+ }, {})
2187
+ );
2039
2188
  }
2189
+ const updatedPayload = appendTrellisToPayload(payload, trellisKey, trellisSplitBy);
2040
2190
  if (onClick) {
2041
2191
  onClick({
2042
2192
  type: "point.click",
2043
2193
  originalEvent: chartEvent,
2044
- payload
2194
+ payload: updatedPayload
2045
2195
  });
2046
2196
  }
2047
2197
  };
2048
- var handleLegendClick = (chartEvent, onClick) => {
2198
+ var handleLegendClick = (chartEvent, onClick, trellisKey, trellisSplitBy) => {
2049
2199
  const payload = {
2050
2200
  name: chartEvent
2051
2201
  };
2202
+ const updatedPayload = appendTrellisToPayload(payload, trellisKey, trellisSplitBy);
2052
2203
  if (onClick) {
2053
2204
  onClick({
2054
2205
  type: "legend.click",
2055
2206
  originalEvent: chartEvent,
2056
- payload
2207
+ payload: updatedPayload
2208
+ });
2209
+ }
2210
+ };
2211
+ var handleRangeSelection = (rangeEvent, onSelect, chartData, trellisKey, trellisSplitBy) => {
2212
+ var _a;
2213
+ if (!rangeEvent) {
2214
+ return;
2215
+ }
2216
+ const xData = ((_a = chartData == null ? void 0 : chartData.columns) == null ? void 0 : _a[0]) || [];
2217
+ const { startXIndex, endXIndex } = findRangeIndices(xData, rangeEvent.start, rangeEvent.end);
2218
+ const payload = {
2219
+ startXIndex,
2220
+ startXValue: rangeEvent.start,
2221
+ endXIndex,
2222
+ endXValue: rangeEvent.end
2223
+ };
2224
+ const updatedPayload = appendTrellisToPayload(payload, trellisKey, trellisSplitBy);
2225
+ if (onSelect) {
2226
+ onSelect({
2227
+ type: "range.selectBeforeZoom",
2228
+ originalEvent: rangeEvent,
2229
+ payload: updatedPayload
2057
2230
  });
2058
2231
  }
2059
2232
  };
2233
+ var handleRangeZoom = (rangeEvent, onSelect, chartData, trellisKey, trellisSplitBy) => {
2234
+ var _a;
2235
+ const xData = ((_a = chartData == null ? void 0 : chartData.columns) == null ? void 0 : _a[0]) || [];
2236
+ const { startXIndex, endXIndex } = findRangeIndices(xData, rangeEvent.start, rangeEvent.end);
2237
+ const payload = {
2238
+ startXIndex,
2239
+ startXValue: rangeEvent.start,
2240
+ endXIndex,
2241
+ endXValue: rangeEvent.end
2242
+ };
2243
+ const updatedPayload = appendTrellisToPayload(payload, trellisKey, trellisSplitBy);
2244
+ if (onSelect) {
2245
+ onSelect({
2246
+ type: "range.select",
2247
+ originalEvent: rangeEvent,
2248
+ payload: updatedPayload
2249
+ });
2250
+ }
2251
+ };
2252
+ var parseArrayOption = (value) => {
2253
+ if (Array.isArray(value)) {
2254
+ return value;
2255
+ }
2256
+ if (value) {
2257
+ return JSON.parse(value);
2258
+ }
2259
+ return void 0;
2260
+ };
2060
2261
  var TimeSeriesChartWrapper = (props) => {
2061
- const {
2262
+ var _b, _c, _d;
2263
+ const _a = props, {
2062
2264
  width,
2063
2265
  height,
2064
2266
  chartData,
@@ -2071,12 +2273,49 @@ var TimeSeriesChartWrapper = (props) => {
2071
2273
  markerDisplay,
2072
2274
  onClick,
2073
2275
  onPointMouseOver,
2074
- onPointMouseOut
2075
- } = props;
2076
- const {
2276
+ onPointMouseOut,
2277
+ onSelect,
2278
+ splitByLayout,
2279
+ trellisKey,
2280
+ trellisSplitBy,
2077
2281
  backgroundColor,
2282
+ defaultFontColor,
2283
+ additionalTooltipValues,
2284
+ showYAxisWithZero: showYAxisWithZeroFromProps,
2285
+ showY2AxisWithZero: showY2AxisWithZeroFromProps
2286
+ } = _a, otherOptions = __objRest(_a, [
2287
+ "width",
2288
+ "height",
2289
+ "chartData",
2290
+ "options",
2291
+ "userLocale",
2292
+ "annotationX",
2293
+ "annotationLabel",
2294
+ "annotationColor",
2295
+ "legendDisplay",
2296
+ "markerDisplay",
2297
+ "onClick",
2298
+ "onPointMouseOver",
2299
+ "onPointMouseOut",
2300
+ "onSelect",
2301
+ "splitByLayout",
2302
+ "trellisKey",
2303
+ "trellisSplitBy",
2304
+ "backgroundColor",
2305
+ "defaultFontColor",
2306
+ "additionalTooltipValues",
2307
+ // Extract showYAxisWithZero directly from props for accelerated render mode
2308
+ "showYAxisWithZero",
2309
+ "showY2AxisWithZero"
2310
+ ]);
2311
+ const { eventHandlers, xField: xFieldFromProps } = otherOptions;
2312
+ const trellisEnabled = useTrellisEnabled(splitByLayout);
2313
+ const {
2314
+ backgroundColor: bgColorFromOptions,
2078
2315
  seriesColors: seriesColorsStr,
2079
2316
  fieldColors,
2317
+ legendLabels: legendLabelsStr,
2318
+ legendMode,
2080
2319
  "axisTitleX.text": xAxisTitleText,
2081
2320
  "axisTitleY.text": yAxisTitleText,
2082
2321
  "axisTitleY2.text": y2AxisTitleText,
@@ -2084,8 +2323,11 @@ var TimeSeriesChartWrapper = (props) => {
2084
2323
  "axisTitleY.visibility": yAxisTitleVisibility,
2085
2324
  "axisTitleY2.visibility": y2AxisTitleVisibility,
2086
2325
  "axisLabelsX.majorLabelVisibility": xAxisLabelVisibility,
2326
+ "axisLabelsX.majorLabelStyle.rotation": xAxisLabelRotation,
2087
2327
  "axisLabelsY.majorLabelVisibility": yAxisLabelVisibility,
2328
+ "axisLabelsY.majorUnit": yAxisMajorUnitFromSimpleXML,
2088
2329
  "axisLabelsY2.majorLabelVisibility": y2AxisLabelVisibility,
2330
+ "axisLabelsY2.majorUnit": y2AxisMajorUnitFromSimpleXML,
2089
2331
  "axisY.abbreviation": yAxisAbbreviation,
2090
2332
  "axisY.scale": yAxisScale,
2091
2333
  "axisY2.abbreviation": y2AxisAbbreviation,
@@ -2095,10 +2337,63 @@ var TimeSeriesChartWrapper = (props) => {
2095
2337
  "axisLabelsY2.integerUnits": y2IntegerUnits,
2096
2338
  "chart.overlayFields": overlayFieldsStr,
2097
2339
  "chart.nullValueMode": nullValueMode,
2098
- lineWidth
2340
+ "chart.showDataLabels": showDataLabels,
2341
+ lineWidth,
2342
+ lineDashStyle,
2343
+ fieldDashStyles: lineDashStylesByFieldStr,
2344
+ yAxisMin: yAxisMinRaw,
2345
+ yAxisMax: yAxisMaxRaw,
2346
+ y2AxisMin: y2AxisMinRaw,
2347
+ y2AxisMax: y2AxisMaxRaw,
2348
+ showXMajorGridLines,
2349
+ showYMajorGridLines,
2350
+ showY2MajorGridLines,
2351
+ showYMinorGridLines,
2352
+ showY2MinorGridLines,
2353
+ showLineSmoothing,
2354
+ yAxisMajorTickVisibility,
2355
+ y2AxisMajorTickVisibility,
2356
+ yAxisMajorTickSize,
2357
+ y2AxisMajorTickSize,
2358
+ yAxisMajorTickInterval,
2359
+ y2AxisMajorTickInterval,
2360
+ yAxisMinorTickVisibility,
2361
+ y2AxisMinorTickVisibility,
2362
+ yAxisMinorTickSize,
2363
+ y2AxisMinorTickSize,
2364
+ showYAxisWithZero: showYAxisWithZeroFromOptions,
2365
+ showY2AxisWithZero: showY2AxisWithZeroFromOptions
2099
2366
  } = options;
2367
+ const dataValuesDisplay = showDataLabels === "none" ? "off" : showDataLabels;
2368
+ const showYAxisWithZero = showYAxisWithZeroFromProps != null ? showYAxisWithZeroFromProps : showYAxisWithZeroFromOptions;
2369
+ const showY2AxisWithZero = showY2AxisWithZeroFromProps != null ? showY2AxisWithZeroFromProps : showY2AxisWithZeroFromOptions;
2370
+ const showYMajorTicks = yAxisMajorTickVisibility === "show";
2371
+ const showY2MajorTicks = y2AxisMajorTickVisibility === "show";
2372
+ const showYMinorTicks = yAxisMinorTickVisibility === "show";
2373
+ const showY2MinorTicks = y2AxisMinorTickVisibility === "show";
2374
+ const yAxisMin = parseAxisValue(yAxisMinRaw);
2375
+ const yAxisMax = parseAxisValue(yAxisMaxRaw);
2376
+ const y2AxisMin = parseAxisValue(y2AxisMinRaw);
2377
+ const y2AxisMax = parseAxisValue(y2AxisMaxRaw);
2378
+ const parseTickInterval = (simpleXMLValue, canvasValue) => {
2379
+ if (simpleXMLValue) return Number(simpleXMLValue);
2380
+ if (canvasValue) return Number(canvasValue);
2381
+ return void 0;
2382
+ };
2383
+ const yAxisMajorTickIntervalNum = parseTickInterval(yAxisMajorUnitFromSimpleXML, yAxisMajorTickInterval);
2384
+ const y2AxisMajorTickIntervalNum = parseTickInterval(
2385
+ y2AxisMajorUnitFromSimpleXML,
2386
+ y2AxisMajorTickInterval
2387
+ );
2388
+ const yAxisMajorTickSizeNum = yAxisMajorTickSize ? Number(yAxisMajorTickSize) : void 0;
2389
+ const y2AxisMajorTickSizeNum = y2AxisMajorTickSize ? Number(y2AxisMajorTickSize) : void 0;
2390
+ const yAxisMinorTickSizeNum = yAxisMinorTickSize ? Number(yAxisMinorTickSize) : void 0;
2391
+ const y2AxisMinorTickSizeNum = y2AxisMinorTickSize ? Number(y2AxisMinorTickSize) : void 0;
2100
2392
  const seriesColors = seriesColorsStr ? JSON.parse(seriesColorsStr) : void 0;
2101
2393
  const seriesColorsByField = fieldColors ? JSON.parse(fieldColors) : void 0;
2394
+ const lineDashStylesByField = lineDashStylesByFieldStr ? JSON.parse(lineDashStylesByFieldStr) : void 0;
2395
+ const legendLabels = parseArrayOption(legendLabelsStr);
2396
+ const bgColor = backgroundColor || bgColorFromOptions;
2102
2397
  const [containerWidth, setContainerWidth] = react_exports.useState(Number(props.width));
2103
2398
  const [containerHeight, setContainerHeight] = react_exports.useState(Number(props.height));
2104
2399
  const cachedHandleResize = react_exports.useCallback((w, h) => {
@@ -2109,31 +2404,64 @@ var TimeSeriesChartWrapper = (props) => {
2109
2404
  fields: chartData.fields,
2110
2405
  columns: chartData.seriesList
2111
2406
  });
2112
- const xField = getFieldName(filteredChartData.fields[0]);
2407
+ const xField = getFieldName2(filteredChartData.fields[0]);
2113
2408
  const yFields = getFieldNames(
2114
2409
  filteredChartData.fields.length > 1 ? filteredChartData.fields.slice(1) : []
2115
2410
  );
2116
- const y2Fields = y2FieldsStr ? y2FieldsStr.split(",").map((f) => f.trim()) : [];
2117
- const overlayFields = overlayFieldsStr ? overlayFieldsStr.split(",").map((f) => f.trim()) : [];
2411
+ const y2Fields = (0, react_exports.useMemo)(
2412
+ () => y2FieldsStr ? y2FieldsStr.split(",").map((f) => f.trim()) : [],
2413
+ [y2FieldsStr]
2414
+ );
2415
+ const overlayFields = (0, react_exports.useMemo)(
2416
+ () => overlayFieldsStr ? overlayFieldsStr.split(",").map((f) => f.trim()) : [],
2417
+ [overlayFieldsStr]
2418
+ );
2118
2419
  let xAxisTitle = getComputedAxisTitles(xAxisTitleText, [xField], xAxisTitleVisibility);
2119
2420
  xAxisTitle = ellipsisAxisTitle(xAxisTitle, containerWidth);
2120
- let yAxisTitle = getComputedAxisTitles(yAxisTitleText, yFields, yAxisTitleVisibility);
2421
+ const yFieldsForTitle = y2Enabled ? yFields.filter((field) => !y2Fields.includes(field)) : yFields;
2422
+ let yAxisTitle = getComputedAxisTitles(yAxisTitleText, yFieldsForTitle, yAxisTitleVisibility);
2121
2423
  yAxisTitle = ellipsisAxisTitle(yAxisTitle, containerHeight);
2122
2424
  const fieldsForY2Axis = y2Fields.length > 0 ? y2Fields : overlayFields;
2123
2425
  let y2AxisTitle = getComputedAxisTitles(y2AxisTitleText, fieldsForY2Axis, y2AxisTitleVisibility);
2124
2426
  y2AxisTitle = ellipsisAxisTitle(y2AxisTitle, containerHeight);
2125
- const xScaleConfig = getXScaleConfig(xAxisTitle, xAxisLabelVisibility);
2126
- const yScaleConfig = getYScaleConfig(yAxisTitle, yAxisAbbreviation, yAxisScale, yAxisLabelVisibility);
2127
- let y2ScaleConfig = {};
2128
- if (y2Enabled) {
2129
- y2ScaleConfig = getY2ScaleConfig(
2130
- y2AxisTitle,
2131
- y2AxisAbbreviation,
2132
- y2AxisScale,
2133
- y2IntegerUnits,
2134
- y2AxisLabelVisibility
2135
- );
2136
- }
2427
+ const xScaleConfig = (0, react_exports.useMemo)(
2428
+ () => getXScaleConfig(xAxisTitle, xAxisLabelVisibility, xAxisLabelRotation),
2429
+ [xAxisTitle, xAxisLabelVisibility, xAxisLabelRotation]
2430
+ );
2431
+ const yScaleConfig = (0, react_exports.useMemo)(
2432
+ () => getYScaleConfig(
2433
+ yAxisTitle,
2434
+ yAxisAbbreviation,
2435
+ yAxisScale,
2436
+ yAxisLabelVisibility,
2437
+ yAxisMin,
2438
+ yAxisMax
2439
+ ),
2440
+ [yAxisTitle, yAxisAbbreviation, yAxisScale, yAxisLabelVisibility, yAxisMin, yAxisMax]
2441
+ );
2442
+ const y2ScaleConfig = (0, react_exports.useMemo)(() => {
2443
+ if (y2Enabled) {
2444
+ return getY2ScaleConfig(
2445
+ y2AxisTitle,
2446
+ y2AxisAbbreviation,
2447
+ y2AxisScale,
2448
+ y2IntegerUnits,
2449
+ y2AxisLabelVisibility,
2450
+ y2AxisMin,
2451
+ y2AxisMax
2452
+ );
2453
+ }
2454
+ return {};
2455
+ }, [
2456
+ y2Enabled,
2457
+ y2AxisTitle,
2458
+ y2AxisAbbreviation,
2459
+ y2AxisScale,
2460
+ y2IntegerUnits,
2461
+ y2AxisLabelVisibility,
2462
+ y2AxisMin,
2463
+ y2AxisMax
2464
+ ]);
2137
2465
  const uplotContainerElement = (0, react_exports.useRef)(null);
2138
2466
  const seriesDataFormatted = [
2139
2467
  filteredChartData.columns[0],
@@ -2149,9 +2477,21 @@ var TimeSeriesChartWrapper = (props) => {
2149
2477
  overlayFields,
2150
2478
  y2Enabled,
2151
2479
  nullValueMode,
2152
- markerDisplay
2480
+ markerDisplay,
2481
+ lineDashStyle,
2482
+ lineDashStylesByField
2153
2483
  ),
2154
- [yFields, y2Fields, lineWidth, overlayFields, y2Enabled, nullValueMode, markerDisplay]
2484
+ [
2485
+ yFields,
2486
+ y2Fields,
2487
+ lineWidth,
2488
+ overlayFields,
2489
+ y2Enabled,
2490
+ nullValueMode,
2491
+ markerDisplay,
2492
+ lineDashStyle,
2493
+ lineDashStylesByField
2494
+ ]
2155
2495
  );
2156
2496
  const chartingEventAnnotations = (0, react_exports.useMemo)(
2157
2497
  () => getAnnotationsForCanvas({
@@ -2165,25 +2505,54 @@ var TimeSeriesChartWrapper = (props) => {
2165
2505
  () => __spreadValues(__spreadValues(__spreadValues({}, xScaleConfig), yScaleConfig), y2ScaleConfig),
2166
2506
  [xScaleConfig, yScaleConfig, y2ScaleConfig]
2167
2507
  );
2168
- const legend = (0, react_exports.useMemo)(() => getLegend({ legendDisplay }), [legendDisplay]);
2508
+ const legend = (0, react_exports.useMemo)(
2509
+ () => getLegend({ legendDisplay, isSeriesCompare: legendMode === "seriesCompare" }),
2510
+ [legendDisplay, legendMode]
2511
+ );
2169
2512
  const handleChartClick = react_exports.useCallback(
2170
2513
  (event) => {
2171
2514
  if (onClick) {
2172
- handleClick(event, onClick);
2515
+ handleClick(event, onClick, trellisKey, trellisSplitBy);
2173
2516
  }
2174
2517
  },
2175
- [onClick]
2518
+ [onClick, trellisKey, trellisSplitBy]
2176
2519
  );
2177
2520
  const handleChartLegendClick = react_exports.useCallback(
2178
2521
  (event) => {
2179
2522
  if (onClick) {
2180
- handleLegendClick(event, onClick);
2523
+ handleLegendClick(event, onClick, trellisKey, trellisSplitBy);
2524
+ }
2525
+ },
2526
+ [onClick, trellisKey, trellisSplitBy]
2527
+ );
2528
+ const handleChartRangeSelection = react_exports.useCallback(
2529
+ (range2) => {
2530
+ if (onSelect) {
2531
+ handleRangeSelection(range2, onSelect, chartData, trellisKey, trellisSplitBy);
2532
+ }
2533
+ },
2534
+ [onSelect, chartData, trellisKey, trellisSplitBy]
2535
+ );
2536
+ const handleChartRangeZoom = react_exports.useCallback(
2537
+ (range2) => {
2538
+ if (onSelect) {
2539
+ handleRangeZoom(range2, onSelect, chartData, trellisKey, trellisSplitBy);
2181
2540
  }
2182
2541
  },
2183
- [onClick]
2542
+ [onSelect, chartData, trellisKey, trellisSplitBy]
2543
+ );
2544
+ const xFieldToUse = xFieldFromProps || xField;
2545
+ const enableSearchZoom = react_exports.useMemo(
2546
+ () => shouldEnableSearchZoom(eventHandlers, xFieldToUse),
2547
+ [eventHandlers, xFieldToUse]
2184
2548
  );
2185
2549
  const lastPayloadRef = react_exports.useRef(null);
2186
2550
  const lastOriginalEventRef = react_exports.useRef(null);
2551
+ const previousMouseoverPayloadRef = react_exports.useRef(null);
2552
+ const additionalTooltipValuesRef = react_exports.useRef(additionalTooltipValues);
2553
+ react_exports.useEffect(() => {
2554
+ additionalTooltipValuesRef.current = additionalTooltipValues;
2555
+ }, [additionalTooltipValues]);
2187
2556
  const handleChartCrosshairChange = react_exports.useCallback(
2188
2557
  (event) => {
2189
2558
  if (onPointMouseOver || onPointMouseOut) {
@@ -2195,6 +2564,7 @@ var TimeSeriesChartWrapper = (props) => {
2195
2564
  payload: lastPayloadRef.current
2196
2565
  });
2197
2566
  }
2567
+ previousMouseoverPayloadRef.current = null;
2198
2568
  return;
2199
2569
  }
2200
2570
  const payload = __spreadProps(__spreadValues({}, (0, lodash_exports.pick)(event, "value", "seriesKey", "time", "index", "seriesIndex")), {
@@ -2202,25 +2572,36 @@ var TimeSeriesChartWrapper = (props) => {
2202
2572
  });
2203
2573
  delete payload.seriesKey;
2204
2574
  if (event.rowContext) {
2205
- Object.keys(event.rowContext).forEach((fieldName) => {
2206
- payload[`row.${fieldName}.value`] = event.rowContext[fieldName];
2207
- });
2575
+ Object.assign(
2576
+ payload,
2577
+ Object.keys(event.rowContext).reduce((acc, fieldName) => {
2578
+ acc[`row.${fieldName}.value`] = event.rowContext[fieldName];
2579
+ return acc;
2580
+ }, {})
2581
+ );
2208
2582
  }
2209
- lastPayloadRef.current = payload;
2583
+ const updatedPayload = appendTrellisToPayload(payload, trellisKey, trellisSplitBy);
2584
+ if (!hasMouseoverPayloadChanged(updatedPayload, previousMouseoverPayloadRef.current)) {
2585
+ return;
2586
+ }
2587
+ lastPayloadRef.current = updatedPayload;
2210
2588
  lastOriginalEventRef.current = event;
2589
+ previousMouseoverPayloadRef.current = __spreadValues({}, updatedPayload);
2211
2590
  if (onPointMouseOver) {
2212
2591
  onPointMouseOver({
2213
2592
  type: "point.mouseover",
2214
2593
  originalEvent: event,
2215
- payload
2594
+ payload: updatedPayload
2216
2595
  });
2217
2596
  }
2218
2597
  }
2219
2598
  },
2220
- [onPointMouseOver, onPointMouseOut]
2599
+ [onPointMouseOver, onPointMouseOut, trellisKey, trellisSplitBy]
2221
2600
  );
2222
- const memoizedChart = (0, react_exports.useMemo)(
2223
- () => /* @__PURE__ */ react_exports.createElement(
2601
+ const dataKey = `${(_b = chartData.columns[0]) == null ? void 0 : _b[0]}-${(_c = chartData.columns[0]) == null ? void 0 : _c[chartData.columns[0].length - 1]}-${(_d = chartData.columns[0]) == null ? void 0 : _d.length}`;
2602
+ const memoizedChart = (0, react_exports.useMemo)(() => {
2603
+ const computedOnRangeZoom = onSelect ? handleChartRangeZoom : void 0;
2604
+ return /* @__PURE__ */ react_exports.createElement(visualization_canvas_exports.RangeSelectionProvider, { key: dataKey }, /* @__PURE__ */ react_exports.createElement(
2224
2605
  visualization_canvas_exports.TimeSeriesChart,
2225
2606
  {
2226
2607
  data: chartData,
@@ -2230,49 +2611,107 @@ var TimeSeriesChartWrapper = (props) => {
2230
2611
  seriesColorsByField,
2231
2612
  seriesConfig: seriesOverrides,
2232
2613
  legend,
2614
+ legendLabels,
2615
+ isSeriesCompare: legendMode === "seriesCompare",
2616
+ maxSeriesFocus: legendMode === "seriesCompare" ? 0 : void 0,
2233
2617
  scaleConfig,
2234
2618
  timestampFormat: "expanded",
2235
2619
  onCrosshairClick: onClick ? handleChartClick : void 0,
2236
2620
  onCrosshairChange: onPointMouseOver || onPointMouseOut ? handleChartCrosshairChange : void 0,
2237
2621
  onSeriesClick: onClick ? handleChartLegendClick : void 0,
2622
+ onRangeSelection: handleChartRangeSelection,
2623
+ onRangeZoom: computedOnRangeZoom,
2624
+ serverSideZoom: enableSearchZoom,
2238
2625
  userLocale,
2239
2626
  events: chartingEventAnnotations,
2240
- eventsConfig: { renderer: triangleEventAnnotationRenderer }
2627
+ eventsConfig: { renderer: triangleEventAnnotationRenderer },
2628
+ additionalTooltipValuesRef,
2629
+ showXMajorGridLines,
2630
+ showYMajorGridLines,
2631
+ showY2MajorGridLines,
2632
+ showYMinorGridLines,
2633
+ showY2MinorGridLines,
2634
+ showLineSmoothing,
2635
+ dataValuesDisplay,
2636
+ showYMajorTicks,
2637
+ showY2MajorTicks,
2638
+ yAxisMajorTickSize: yAxisMajorTickSizeNum,
2639
+ y2AxisMajorTickSize: y2AxisMajorTickSizeNum,
2640
+ yAxisMajorTickInterval: yAxisMajorTickIntervalNum,
2641
+ y2AxisMajorTickInterval: y2AxisMajorTickIntervalNum,
2642
+ showYMinorTicks,
2643
+ showY2MinorTicks,
2644
+ yAxisMinorTickSize: yAxisMinorTickSizeNum,
2645
+ y2AxisMinorTickSize: y2AxisMinorTickSizeNum,
2646
+ showYAxisWithZero,
2647
+ showY2AxisWithZero
2241
2648
  }
2242
- ),
2243
- [
2244
- chartData,
2245
- containerWidth,
2246
- containerHeight,
2247
- seriesColors,
2248
- seriesColorsByField,
2249
- seriesOverrides,
2250
- legend,
2251
- scaleConfig,
2252
- userLocale,
2253
- chartingEventAnnotations,
2254
- onClick,
2255
- handleChartClick,
2256
- onPointMouseOver,
2257
- onPointMouseOut,
2258
- handleChartCrosshairChange,
2259
- handleChartLegendClick
2260
- ]
2261
- );
2649
+ ));
2650
+ }, [
2651
+ onSelect,
2652
+ handleChartRangeZoom,
2653
+ dataKey,
2654
+ chartData,
2655
+ containerWidth,
2656
+ containerHeight,
2657
+ seriesColors,
2658
+ seriesColorsByField,
2659
+ seriesOverrides,
2660
+ legend,
2661
+ legendLabels,
2662
+ scaleConfig,
2663
+ onClick,
2664
+ handleChartClick,
2665
+ onPointMouseOver,
2666
+ onPointMouseOut,
2667
+ handleChartCrosshairChange,
2668
+ handleChartLegendClick,
2669
+ handleChartRangeSelection,
2670
+ enableSearchZoom,
2671
+ userLocale,
2672
+ chartingEventAnnotations,
2673
+ showXMajorGridLines,
2674
+ showYMajorGridLines,
2675
+ showY2MajorGridLines,
2676
+ showYMinorGridLines,
2677
+ showY2MinorGridLines,
2678
+ showLineSmoothing,
2679
+ dataValuesDisplay,
2680
+ showYMajorTicks,
2681
+ showY2MajorTicks,
2682
+ yAxisMajorTickSizeNum,
2683
+ y2AxisMajorTickSizeNum,
2684
+ yAxisMajorTickIntervalNum,
2685
+ y2AxisMajorTickIntervalNum,
2686
+ showYMinorTicks,
2687
+ showY2MinorTicks,
2688
+ yAxisMinorTickSizeNum,
2689
+ y2AxisMinorTickSizeNum,
2690
+ showYAxisWithZero,
2691
+ showY2AxisWithZero,
2692
+ legendMode
2693
+ ]);
2262
2694
  const memoizedVisualization = (0, react_exports.useMemo)(() => {
2263
- return /* @__PURE__ */ react_exports.createElement(VizStyleWrapper_default, { backgroundColor }, memoizedChart);
2264
- }, [backgroundColor, memoizedChart]);
2265
- return /* @__PURE__ */ react_exports.createElement(
2695
+ return /* @__PURE__ */ react_exports.createElement(VizStyleWrapper_default, { backgroundColor: bgColor }, memoizedChart);
2696
+ }, [bgColor, memoizedChart]);
2697
+ return /* @__PURE__ */ react_exports.createElement(react_exports.Fragment, null, trellisEnabled && /* @__PURE__ */ react_exports.createElement(
2698
+ TrellisTitle,
2699
+ {
2700
+ trellisKey,
2701
+ backgroundColor: bgColor,
2702
+ fontColor: defaultFontColor
2703
+ }
2704
+ ), /* @__PURE__ */ react_exports.createElement(
2266
2705
  TimeSeriesChartContainer,
2267
2706
  {
2268
- height,
2707
+ height: trellisEnabled ? Number(height) - TRELLIS_TITLE_HEIGHT : height,
2269
2708
  width,
2270
2709
  ref: uplotContainerElement,
2271
2710
  "data-test": "timeseries-chart-wrapper"
2272
2711
  },
2273
2712
  /* @__PURE__ */ react_exports.createElement(SizeAwareWrapper_default, { width, height, onResize: cachedHandleResize }),
2274
2713
  memoizedVisualization
2275
- );
2714
+ ));
2276
2715
  };
2277
2716
  var TimeSeriesChartWrapper_default = TimeSeriesChartWrapper;
2278
2717
 
@@ -2773,6 +3212,19 @@ var getColumnFormatSparklineColor = (columnFormat, currentColumn, currentRow) =>
2773
3212
  var getColumnFormatSparklineAreaColor = (columnFormat, currentColumn, currentRow) => {
2774
3213
  return getColumnFormatColor(columnFormat, currentColumn, currentRow, "sparklineAreaColors");
2775
3214
  };
3215
+ var validSparklineNullValueDisplayOptions = ["gaps", "zero", "connect"];
3216
+ var getColumnFormatSparklineNullValueDisplay = (columnFormat, currentColumn) => {
3217
+ const nullValueDisplay = getAttributeFromColumnFormat(
3218
+ "sparklineNullValueDisplay",
3219
+ columnFormat,
3220
+ currentColumn.columnId,
3221
+ currentColumn.value
3222
+ );
3223
+ if (typeof nullValueDisplay === "string" && validSparklineNullValueDisplayOptions.includes(nullValueDisplay)) {
3224
+ return nullValueDisplay;
3225
+ }
3226
+ return void 0;
3227
+ };
2776
3228
  var getColumnFormatHeaderAlign = (columnFormat, columnId, columnValue) => {
2777
3229
  let headerAlign;
2778
3230
  const alignOption = getAttributeFromColumnFormat("headerAlign", columnFormat, columnId, columnValue);
@@ -2862,6 +3314,13 @@ var getTableFormatSparklineColor = (tableFormat, currentCol, currentRow) => {
2862
3314
  var getTableFormatSparklineAreaColor = (tableFormat, currentCol, currentRow) => {
2863
3315
  return getTableFormatColor(tableFormat, currentCol, currentRow, "sparklineAreaColors");
2864
3316
  };
3317
+ var getTableFormatSparklineNullValueDisplay = (tableFormat) => {
3318
+ const nullValueDisplay = (0, lodash_exports.get)(tableFormat, "sparklineNullValueDisplay");
3319
+ if (typeof nullValueDisplay === "string" && validSparklineNullValueDisplayOptions.includes(nullValueDisplay)) {
3320
+ return nullValueDisplay;
3321
+ }
3322
+ return void 0;
3323
+ };
2865
3324
  var getTableFormatData = (tableFormat, currentCol, currentRow) => {
2866
3325
  const data = (0, lodash_exports.get)(tableFormat, "data");
2867
3326
  let datum;
@@ -2911,7 +3370,9 @@ var useTable = (tableArgs = {}) => {
2911
3370
  tableFormat = {},
2912
3371
  columnFormat = {},
2913
3372
  paginationOffset = 0,
2914
- count = 0
3373
+ count = 0,
3374
+ showFooterTotals = false,
3375
+ showFooterPercentages = false
2915
3376
  } = tableArgs;
2916
3377
  const longestColumnLength = Math.max(...table.map((column) => column.length));
2917
3378
  if (showRowNumbers) {
@@ -3025,13 +3486,9 @@ var useTable = (tableArgs = {}) => {
3025
3486
  const sparklineColor = getColumnFormatSparklineColor(cfmt, currentHeader, r) || getTableFormatSparklineColor(tfmt, i, r) || void 0;
3026
3487
  const sparklineAreaColor = getColumnFormatSparklineAreaColor(cfmt, currentHeader, r) || getTableFormatSparklineAreaColor(tfmt, i, r) || void 0;
3027
3488
  const sparklineType = getColumnFormatSparklineType(cfmt, currentHeader, r) || getTableFormatSparklineType(tfmt, i, r) || "area";
3489
+ const sparklineNullValueDisplay = getColumnFormatSparklineNullValueDisplay(cfmt, currentHeader) || getTableFormatSparklineNullValueDisplay(tfmt) || "gaps";
3028
3490
  const key = generateKey(value, `${r}-${i}`);
3029
- const textOverflowType = getTextOverflowType(
3030
- cfmt,
3031
- cids[i],
3032
- tfmt,
3033
- currentHeader.value
3034
- );
3491
+ const textOverflowType = getTextOverflowType(cfmt, cids[i], tfmt, currentHeader.value);
3035
3492
  const textOverflowStyle = getOverflowStyles({
3036
3493
  textOverflow: textOverflowType
3037
3494
  });
@@ -3047,6 +3504,7 @@ var useTable = (tableArgs = {}) => {
3047
3504
  sparklineColor,
3048
3505
  sparklineAreaColor,
3049
3506
  sparklineType,
3507
+ sparklineNullValueDisplay,
3050
3508
  header: currentHeader.value,
3051
3509
  style: __spreadValues({
3052
3510
  backgroundColor: rowBackgroundColor,
@@ -3068,22 +3526,17 @@ var useTable = (tableArgs = {}) => {
3068
3526
  showInternalFields,
3069
3527
  longestColumnLength
3070
3528
  });
3071
- const { showFooterTotals = false, showFooterPercentages = false } = tableArgs;
3072
3529
  const resolveByField = (fieldId, displayName, map) => {
3073
3530
  if (!map) return void 0;
3074
- if (Object.prototype.hasOwnProperty.call(map, fieldId)) return map[fieldId];
3075
- if (Object.prototype.hasOwnProperty.call(map, displayName)) return map[displayName];
3531
+ if (Object.hasOwn(map, fieldId)) return map[fieldId];
3532
+ if (Object.hasOwn(map, displayName)) return map[displayName];
3076
3533
  return void 0;
3077
3534
  };
3078
3535
  const computeDerivedAlign = (colMeta, colIdx, alignOverrides) => {
3079
3536
  const fieldId = colMeta.columnId;
3080
3537
  const label = colMeta.value;
3081
3538
  const alignOverride = resolveByField(fieldId, label, alignOverrides);
3082
- return alignOverride || getColumnFormatAlign(
3083
- columnFormat,
3084
- colMeta,
3085
- Math.max(0, longestColumnLength - 1)
3086
- ) || getTableFormatAlign(tableFormat, colIdx, Math.max(0, longestColumnLength - 1)) || "right";
3539
+ return alignOverride || getColumnFormatAlign(columnFormat, colMeta, Math.max(0, longestColumnLength - 1)) || getTableFormatAlign(tableFormat, colIdx, Math.max(0, longestColumnLength - 1)) || "right";
3087
3540
  };
3088
3541
  const buildFooterRow = (key, styleExtras, rowIndexBase) => {
3089
3542
  const idx = rowIndexBase + tableFooter.rows.length;
@@ -3222,6 +3675,8 @@ var StyledSvg = styled_components_default.svg`
3222
3675
  var StyledTooltip = styled_components_default.div`
3223
3676
  padding: 3px 8px;
3224
3677
  font-size: 12px;
3678
+ text-align: center;
3679
+ min-width: 20px;
3225
3680
  `;
3226
3681
  var preventDefault = (e) => e.preventDefault();
3227
3682
  var _SparkLine = class _SparkLine extends react_exports.Component {
@@ -3358,16 +3813,19 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3358
3813
  * @method getSegmentSets
3359
3814
  * @param {Array} data
3360
3815
  * @param {Array} points
3361
- * @returns {Array} List of datapoint sets used for drawing lines
3816
+ * @returns {Object} Object containing lines (arrays of points for polylines) and isolatedPoints (single points surrounded by nulls)
3362
3817
  */
3363
3818
  getSegmentSets(data, points) {
3364
3819
  const { acceptNull } = this.props;
3365
3820
  const lines = [];
3821
+ const isolatedPoints = [];
3366
3822
  let currentLine = [];
3367
3823
  for (const [idx, p] of data.entries()) {
3368
3824
  if (!acceptNull && (0, lodash_exports.isNull)(p)) {
3369
3825
  if (currentLine.length > 1) {
3370
3826
  lines.push(currentLine);
3827
+ } else if (currentLine.length === 1) {
3828
+ isolatedPoints.push(currentLine[0]);
3371
3829
  }
3372
3830
  currentLine = [];
3373
3831
  } else {
@@ -3376,8 +3834,10 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3376
3834
  }
3377
3835
  if (currentLine.length > 1) {
3378
3836
  lines.push(currentLine);
3837
+ } else if (currentLine.length === 1) {
3838
+ isolatedPoints.push(currentLine[0]);
3379
3839
  }
3380
- return lines;
3840
+ return { lines, isolatedPoints };
3381
3841
  }
3382
3842
  /**
3383
3843
  * Utility for fill null value with number 0.
@@ -3445,8 +3905,8 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3445
3905
  if (!isArea || points.length === 0) {
3446
3906
  return null;
3447
3907
  }
3448
- let segments = this.getSegmentSets(data, points);
3449
- segments = segments.map(
3908
+ const { lines } = this.getSegmentSets(data, points);
3909
+ const segments = lines.map(
3450
3910
  (s) => s.concat([
3451
3911
  [s.at(-1)[0], height],
3452
3912
  // down to bottom of graph
@@ -3492,6 +3952,7 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3492
3952
  }
3493
3953
  renderTooltip(tooltipValue, isOpen) {
3494
3954
  const { anchor } = this.state;
3955
+ const displayValue = tooltipValue === null ? "-" : tooltipValue;
3495
3956
  return /* @__PURE__ */ react_default.createElement(
3496
3957
  Popover_default,
3497
3958
  {
@@ -3503,7 +3964,7 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3503
3964
  defaultPlacement: "above",
3504
3965
  animation: false
3505
3966
  },
3506
- /* @__PURE__ */ react_default.createElement(StyledTooltip, null, tooltipValue)
3967
+ /* @__PURE__ */ react_default.createElement(StyledTooltip, null, displayValue)
3507
3968
  );
3508
3969
  }
3509
3970
  /**
@@ -3533,16 +3994,46 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3533
3994
  }
3534
3995
  )));
3535
3996
  }
3997
+ /**
3998
+ * Renders circles for isolated points (single data points surrounded by nulls)
3999
+ * These would otherwise be invisible since a line requires at least 2 points
4000
+ * @method renderIsolatedPoints
4001
+ * @param {Array} isolatedPoints - Array of [x, y] coordinates for isolated points
4002
+ * @returns {Object} SVG Group of circles
4003
+ */
4004
+ renderIsolatedPoints(isolatedPoints) {
4005
+ const { lineColor, lineStrokeWidth } = this.props;
4006
+ if (!isolatedPoints || isolatedPoints.length === 0) {
4007
+ return null;
4008
+ }
4009
+ const radius = lineStrokeWidth + 0.5;
4010
+ return /* @__PURE__ */ react_default.createElement("g", { "data-test": "isolated-points" }, isolatedPoints.map((point) => /* @__PURE__ */ react_default.createElement(
4011
+ "circle",
4012
+ {
4013
+ key: `isolated-${point[0]}-${point[1]}`,
4014
+ "data-test": "isolated-point",
4015
+ cx: point[0],
4016
+ cy: point[1],
4017
+ r: radius,
4018
+ style: {
4019
+ fill: lineColor
4020
+ }
4021
+ }
4022
+ )));
4023
+ }
3536
4024
  /**
3537
4025
  * Renders the line(s) above the area graph
3538
4026
  * @method renderPolyline
3539
4027
  * @param {Array} points
3540
- * @returns {Object} SVG Group of polylines
4028
+ * @returns {Object} SVG Group of polylines and isolated points
3541
4029
  */
3542
4030
  renderPolyline(points) {
3543
4031
  const { data, lineColor, lineLength, lineStrokeWidth } = this.props;
3544
4032
  const linePoints = (0, lodash_exports.isFinite)(lineLength) && lineLength > 0 ? lineLength : points.length;
3545
- const lines = this.getSegmentSets(data.slice(-linePoints), points.slice(-linePoints));
4033
+ const { lines, isolatedPoints } = this.getSegmentSets(
4034
+ data.slice(-linePoints),
4035
+ points.slice(-linePoints)
4036
+ );
3546
4037
  return /* @__PURE__ */ react_default.createElement("g", { "data-test": "sparkline" }, lines.map((lineData) => /* @__PURE__ */ react_default.createElement(
3547
4038
  "polyline",
3548
4039
  {
@@ -3557,7 +4048,7 @@ var _SparkLine = class _SparkLine extends react_exports.Component {
3557
4048
  },
3558
4049
  points: lineData.join(" ")
3559
4050
  }
3560
- )));
4051
+ )), this.renderIsolatedPoints(isolatedPoints));
3561
4052
  }
3562
4053
  getInteractionState({ data, points, showTooltip, activeIndex, hoveredIndex, componentIsFocused }) {
3563
4054
  if (!showTooltip) {
@@ -3767,7 +4258,24 @@ var SparkLine_default = SparkLine;
3767
4258
  // src/Table/cells/SparklineCell.tsx
3768
4259
  var paddingLeftRight = 5;
3769
4260
  var paddingTopBottom = 3;
3770
- var parseSparklineData = (data) => (Array.isArray(data) ? data : [data]).map((d) => Number(d.toString())).map((d) => isNaN(d) ? null : d);
4261
+ var parseSparklineData = (data) => (Array.isArray(data) ? data : [data]).map((d) => {
4262
+ var _a;
4263
+ const str = (_a = d == null ? void 0 : d.toString()) != null ? _a : "";
4264
+ if (str.trim() === "") {
4265
+ return null;
4266
+ }
4267
+ const num = Number(str);
4268
+ return Number.isNaN(num) ? null : num;
4269
+ });
4270
+ var processDataForNullDisplay = (data, nullValueDisplay) => {
4271
+ if (nullValueDisplay === "connect") {
4272
+ return data.filter((d) => d !== null);
4273
+ }
4274
+ return data;
4275
+ };
4276
+ var getAcceptNull = (nullValueDisplay) => {
4277
+ return nullValueDisplay === "zero";
4278
+ };
3771
4279
  var noop6 = () => void 0;
3772
4280
  var svgStyle = { height: 0 };
3773
4281
  var dummySVG = /* @__PURE__ */ react_exports.createElement("svg", { style: svgStyle });
@@ -3778,10 +4286,15 @@ var SparklineCell = ({
3778
4286
  }) => {
3779
4287
  const [cellEl, setEl] = react_exports.useState();
3780
4288
  const [height, setHeight] = react_exports.useState();
3781
- let data = react_exports.useMemo(() => parseSparklineData(cell.value), [cell.value]);
4289
+ const nullValueDisplay = cell.sparklineNullValueDisplay || "gaps";
4290
+ let data = react_exports.useMemo(() => {
4291
+ const parsed = parseSparklineData(cell.value);
4292
+ return processDataForNullDisplay(parsed, nullValueDisplay);
4293
+ }, [cell.value, nullValueDisplay]);
3782
4294
  if (cell.value[0] === "##__SPARKLINE__##") {
3783
4295
  data = data.slice(1);
3784
4296
  }
4297
+ const acceptNull = getAcceptNull(nullValueDisplay);
3785
4298
  react_exports.useLayoutEffect(() => {
3786
4299
  setHeight((cellEl == null ? void 0 : cellEl.offsetHeight) || 20);
3787
4300
  }, [cellEl]);
@@ -3824,7 +4337,7 @@ var SparklineCell = ({
3824
4337
  width: (cellEl == null ? void 0 : cellEl.offsetWidth) - paddingLeftRight * 2,
3825
4338
  height: height - paddingTopBottom * 2,
3826
4339
  isArea: cell.sparklineType === "area",
3827
- acceptNull: true,
4340
+ acceptNull,
3828
4341
  lineColor: cell.sparklineColor,
3829
4342
  fillColor: cell.sparklineAreaColor
3830
4343
  }
@@ -3833,9 +4346,13 @@ var SparklineCell = ({
3833
4346
  };
3834
4347
  SparklineCell.displayName = "SparklineCell";
3835
4348
 
4349
+ // src/common/utils/textUtils.ts
4350
+ var VIZ_FONT_FAMILY = "'Splunk Platform Sans', 'Splunk Data Sans', Roboto, Droid, 'Helvetica Neue', Helvetica, Arial, sans-serif";
4351
+
3836
4352
  // src/Table/PureTable.tsx
3837
4353
  var MINIMUM_COLUMN_SIZE = 60;
3838
4354
  var INITIAL_UNSET_COLUMN_WIDTH = 90;
4355
+ var COMPACT_PAGINATOR_WIDTH_THRESHOLD = 350;
3839
4356
  var NonVisibleTableHead = styled_components_default(Table_default.Head)`
3840
4357
  pointer-events: none;
3841
4358
  & [data-test='head-cell'] > div {
@@ -3881,11 +4398,6 @@ var VizTableContainer = styled_components_default.div`
3881
4398
  overflow: hidden !important;
3882
4399
  height: 100%;
3883
4400
 
3884
- td,
3885
- * > td:hover {
3886
- color: ${({ isCellClickable }) => isCellClickable ? variables_default.linkColor : variables_default.textColor};
3887
- }
3888
-
3889
4401
  /* footer totals row styling */
3890
4402
  tr[data-test='footer-row-totals'] td[data-test='cell'] {
3891
4403
  color: ${variables_default.contentColorActive} !important;
@@ -3927,7 +4439,6 @@ var SUITableContainer = styled_components_default.div`
3927
4439
  margin-bottom: ${PAGINATOR_SPACING}px;
3928
4440
  `};
3929
4441
 
3930
- /* TODO: Replace unsupported hacky style overrides */
3931
4442
  ${({ headerStyle }) => headerStyle && headerStyle.backgroundColor && styled_components_exports.css`
3932
4443
  & [data-test='head-cell'] {
3933
4444
  background-color: ${headerStyle.backgroundColor};
@@ -4029,7 +4540,7 @@ var HeadCell = (_a) => {
4029
4540
  return /* @__PURE__ */ react_exports.createElement(TableHeadCell, __spreadValues({ elementRef: cellRef, textOverflowType }, props), value);
4030
4541
  };
4031
4542
  var fontMap = {
4032
- proportional: "Splunk Platform Sans",
4543
+ proportional: VIZ_FONT_FAMILY,
4033
4544
  monospace: "Splunk Platform Mono"
4034
4545
  };
4035
4546
  var fontSizeMap = {
@@ -4044,7 +4555,23 @@ var rowHeightMap = {
4044
4555
  default: "20px",
4045
4556
  large: "24px"
4046
4557
  };
4047
- var tableInnerStyle = { height: "100%" };
4558
+ var getUseMouseOverEffect = (props, header) => {
4559
+ if (!props.hasEventHandlers || props.mode === "edit") {
4560
+ return false;
4561
+ }
4562
+ const eventHandlers = props.eventHandlers || [];
4563
+ if (eventHandlers.length === 0) {
4564
+ return true;
4565
+ }
4566
+ return eventHandlers.some((handler) => {
4567
+ var _a;
4568
+ const handlerFields = (_a = handler.options) == null ? void 0 : _a.fields;
4569
+ if (!(handlerFields == null ? void 0 : handlerFields.length)) {
4570
+ return true;
4571
+ }
4572
+ return handlerFields.includes(header);
4573
+ });
4574
+ };
4048
4575
  var PureTable = (props) => {
4049
4576
  const _a = props, {
4050
4577
  count,
@@ -4189,10 +4716,8 @@ var PureTable = (props) => {
4189
4716
  const fontMapped = fontMap[font] || fontMap.proportional;
4190
4717
  const fontSizeMapped = fontSizeMap[fontSize] || fontSizeMap.default;
4191
4718
  const rowHeightMapped = rowHeightMap[fontSize] || rowHeightMap.default;
4192
- const tableOuterStyle = react_exports.useMemo(
4193
- () => ({ height: "100%", cursor: onCellClick ? "pointer" : "unset" }),
4194
- [onCellClick]
4195
- );
4719
+ const tableInnerStyle = { height: "100%" };
4720
+ const tableOuterStyle = { height: "100%" };
4196
4721
  const visibleHeaderCells = tableHeader.cells.filter((c) => c.showCell);
4197
4722
  const numberOfFixedHeaders = visibleHeaderCells.filter(({ value }) => {
4198
4723
  var _a2, _b2;
@@ -4228,113 +4753,125 @@ var PureTable = (props) => {
4228
4753
  })
4229
4754
  ));
4230
4755
  };
4231
- return /* @__PURE__ */ react_exports.createElement(
4232
- VizTableContainer,
4756
+ return /* @__PURE__ */ react_exports.createElement(VizTableContainer, { backgroundColor, ref: containerRef, "data-test": "table-container" }, /* @__PURE__ */ react_exports.createElement(
4757
+ SUITableContainer,
4233
4758
  {
4234
- isCellClickable: Boolean(onCellClick),
4235
- backgroundColor,
4236
- ref: containerRef,
4237
- "data-test": "table-container"
4759
+ ref: containerRefInner,
4760
+ width,
4761
+ height,
4762
+ isPaging,
4763
+ headerStyle: tableHeader.style,
4764
+ font: fontMapped,
4765
+ fontSize: fontSizeMapped,
4766
+ lineHeight: rowHeightMapped,
4767
+ isFullyFixed
4238
4768
  },
4239
4769
  /* @__PURE__ */ react_exports.createElement(
4240
- SUITableContainer,
4770
+ Table_default,
4241
4771
  {
4242
- ref: containerRefInner,
4243
- width,
4244
- height,
4245
- isPaging,
4246
- headerStyle: tableHeader.style,
4247
- font: fontMapped,
4248
- fontSize: fontSizeMapped,
4249
- lineHeight: rowHeightMapped,
4250
- isFullyFixed
4772
+ resizableFillLayout: true,
4773
+ headType: isHeaderHidden ? void 0 : "inline",
4774
+ innerStyle: tableInnerStyle,
4775
+ outerStyle: tableOuterStyle,
4776
+ onClick: tableCellClickHandler,
4777
+ onKeyDown: onCellClick ? handleKeyDown : lodash_exports.noop,
4778
+ onKeyUp: handleKeyUp,
4779
+ onRequestResizeColumn: handleResizeColumn
4251
4780
  },
4252
- /* @__PURE__ */ react_exports.createElement(
4253
- Table_default,
4254
- {
4255
- resizableFillLayout: true,
4256
- headType: isHeaderHidden ? void 0 : "inline",
4257
- innerStyle: tableInnerStyle,
4258
- outerStyle: tableOuterStyle,
4259
- onClick: tableCellClickHandler,
4260
- onKeyDown: onCellClick ? handleKeyDown : lodash_exports.noop,
4261
- onKeyUp: handleKeyUp,
4262
- onRequestResizeColumn: handleResizeColumn
4263
- },
4264
- /* @__PURE__ */ react_exports.createElement(TableHead, null, visibleHeaderCells.map(
4265
- (_d) => {
4266
- var _e = _d, {
4781
+ /* @__PURE__ */ react_exports.createElement(TableHead, null, visibleHeaderCells.map(
4782
+ (_d) => {
4783
+ var _e = _d, {
4784
+ key,
4785
+ value,
4786
+ sortKey,
4787
+ style,
4788
+ align,
4789
+ textOverflowType
4790
+ } = _e, rest = __objRest(_e, [
4791
+ "key",
4792
+ "value",
4793
+ "sortKey",
4794
+ "style",
4795
+ "align",
4796
+ "textOverflowType"
4797
+ ]);
4798
+ var _a2, _b2;
4799
+ return /* @__PURE__ */ react_exports.createElement(
4800
+ HeadCell,
4801
+ __spreadProps(__spreadValues({}, __spreadValues({ sortKey }, rest)), {
4802
+ align,
4803
+ "data-test-align-value": align,
4804
+ "data-test-text-overflow-value": textOverflowType,
4267
4805
  key,
4806
+ columnId: value,
4807
+ sortDir: sortKey === currentSortKey ? currentSortDir : "none",
4808
+ width: (_b2 = (_a2 = columns[value]) == null ? void 0 : _a2.width) != null ? _b2 : INITIAL_UNSET_COLUMN_WIDTH,
4809
+ onMouseDown: handleEventHeadCellMouseDown,
4268
4810
  value,
4269
- sortKey,
4270
- style,
4271
- align,
4272
- textOverflowType
4273
- } = _e, rest = __objRest(_e, [
4274
- "key",
4275
- "value",
4276
- "sortKey",
4277
- "style",
4278
- "align",
4279
- "textOverflowType"
4280
- ]);
4281
- var _a2, _b2;
4282
- return /* @__PURE__ */ react_exports.createElement(
4283
- HeadCell,
4284
- __spreadProps(__spreadValues({}, __spreadValues({ sortKey }, rest)), {
4285
- align,
4286
- "data-test-align-value": align,
4287
- "data-test-text-overflow-value": textOverflowType,
4288
- key,
4289
- columnId: value,
4290
- sortDir: sortKey === currentSortKey ? currentSortDir : "none",
4291
- width: (_b2 = (_a2 = columns[value]) == null ? void 0 : _a2.width) != null ? _b2 : INITIAL_UNSET_COLUMN_WIDTH,
4292
- onMouseDown: handleEventHeadCellMouseDown,
4293
- value,
4294
- onSort: showRowNumbers && value === "#" || isHeaderHidden ? null : onSortToUse,
4295
- resizable: !isHeaderHidden,
4296
- style: showRowNumbers && value === "#" ? __spreadProps(__spreadValues({}, style), { cursor: "auto" }) : style,
4297
- textOverflowType,
4298
- headerVisibility
4299
- })
4300
- );
4301
- }
4302
- )),
4303
- /* @__PURE__ */ react_exports.createElement(Table_default.Body, null, tableBody.rows.map(
4304
- (row) => /* @__PURE__ */ react_exports.createElement(Table_default.Row, { key: row.key }, row.cells.filter((c) => c.showCell).map((cell) => {
4305
- var _a2, _b2;
4306
- return /* @__PURE__ */ react_exports.createElement(SwitchTableCell, { key: cell.key, type: cell.cellType }, /* @__PURE__ */ react_exports.createElement(
4307
- TextCell,
4308
- {
4309
- cell,
4310
- useMouseOverEffect: !!onCellClick
4311
- }
4312
- ), /* @__PURE__ */ react_exports.createElement(
4313
- SparklineCell,
4314
- {
4315
- cell,
4316
- useMouseOverEffect: !!onCellClick,
4317
- width: (_b2 = (_a2 = columns[cell.header]) == null ? void 0 : _a2.width) != null ? _b2 : "auto"
4318
- }
4319
- ), /* @__PURE__ */ react_exports.createElement(
4320
- ArrayCell,
4321
- {
4322
- cell,
4323
- useMouseOverEffect: !!onCellClick
4324
- }
4325
- ));
4326
- }))
4327
- ), tableFooter && showFooterTotals && renderFooterRow("footer-totals", "footer-row-totals"), tableFooter && showFooterPercentages && renderFooterRow("footer-percentages", "footer-row-percentages"))
4328
- )
4329
- ),
4330
- isPaging ? /* @__PURE__ */ react_exports.createElement(PaginatorContainer, null, /* @__PURE__ */ react_exports.createElement(
4331
- Paginator_default,
4332
- __spreadValues({
4333
- totalPages: paginatorProps.totalPages,
4334
- onChange: paginatorOnChange
4335
- }, paginatorProps)
4336
- )) : null
4337
- );
4811
+ onSort: showRowNumbers && value === "#" || isHeaderHidden ? null : onSortToUse,
4812
+ resizable: !isHeaderHidden,
4813
+ style: showRowNumbers && value === "#" ? __spreadProps(__spreadValues({}, style), { cursor: "auto" }) : style,
4814
+ textOverflowType,
4815
+ headerVisibility
4816
+ })
4817
+ );
4818
+ }
4819
+ )),
4820
+ /* @__PURE__ */ react_exports.createElement(Table_default.Body, null, tableBody.rows.map(
4821
+ (row) => /* @__PURE__ */ react_exports.createElement(Table_default.Row, { key: row.key }, row.cells.filter((c) => c.showCell).map((cell) => {
4822
+ var _a2, _b2;
4823
+ return /* @__PURE__ */ react_exports.createElement(SwitchTableCell, { key: cell.key, type: cell.cellType }, /* @__PURE__ */ react_exports.createElement(
4824
+ TextCell,
4825
+ {
4826
+ cell,
4827
+ useMouseOverEffect: getUseMouseOverEffect(
4828
+ props,
4829
+ cell.header
4830
+ )
4831
+ }
4832
+ ), /* @__PURE__ */ react_exports.createElement(
4833
+ SparklineCell,
4834
+ {
4835
+ cell,
4836
+ useMouseOverEffect: getUseMouseOverEffect(
4837
+ props,
4838
+ cell.header
4839
+ ),
4840
+ width: (_b2 = (_a2 = columns[cell.header]) == null ? void 0 : _a2.width) != null ? _b2 : "auto"
4841
+ }
4842
+ ), /* @__PURE__ */ react_exports.createElement(
4843
+ ArrayCell,
4844
+ {
4845
+ cell,
4846
+ useMouseOverEffect: getUseMouseOverEffect(
4847
+ props,
4848
+ cell.header
4849
+ )
4850
+ }
4851
+ ));
4852
+ }))
4853
+ ), tableFooter && showFooterTotals && renderFooterRow("footer-totals", "footer-row-totals"), tableFooter && showFooterPercentages && renderFooterRow("footer-percentages", "footer-row-percentages"))
4854
+ )
4855
+ ), isPaging ? /* @__PURE__ */ react_exports.createElement(PaginatorContainer, null, width < COMPACT_PAGINATOR_WIDTH_THRESHOLD ? /* @__PURE__ */ react_exports.createElement(
4856
+ Paginator_default.Compact,
4857
+ {
4858
+ current: paginatorProps.current,
4859
+ totalPages: paginatorProps.totalPages,
4860
+ renderLabel: false,
4861
+ onChange: (e, { direction }) => {
4862
+ const newPage = direction === "next" ? paginatorProps.current + 1 : paginatorProps.current - 1;
4863
+ paginatorOnChange(e, {
4864
+ page: newPage
4865
+ });
4866
+ }
4867
+ }
4868
+ ) : /* @__PURE__ */ react_exports.createElement(
4869
+ Paginator_default,
4870
+ __spreadValues({
4871
+ totalPages: paginatorProps.totalPages,
4872
+ onChange: paginatorOnChange
4873
+ }, paginatorProps)
4874
+ )) : null);
4338
4875
  };
4339
4876
  var cellDataType = prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number, prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]))]);
4340
4877
  PureTable.propTypes = {