@splunk/visualizations 28.4.0 → 28.5.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.
Files changed (165) hide show
  1. package/Area.config.js +28 -7
  2. package/Area.config.js.map +2 -2
  3. package/Area.js +109 -39
  4. package/Area.js.map +2 -2
  5. package/Bar.config.js +28 -7
  6. package/Bar.config.js.map +2 -2
  7. package/Bar.js +109 -39
  8. package/Bar.js.map +2 -2
  9. package/Bubble.config.js +4 -4
  10. package/Bubble.config.js.map +2 -2
  11. package/Bubble.js +81 -30
  12. package/Bubble.js.map +2 -2
  13. package/CHANGELOG.external.md +98 -0
  14. package/ChoroplethSvg.js +74 -26
  15. package/ChoroplethSvg.js.map +2 -2
  16. package/Column.config.js +28 -7
  17. package/Column.config.js.map +2 -2
  18. package/Column.js +109 -39
  19. package/Column.js.map +2 -2
  20. package/Ellipse/config.d.ts.map +1 -1
  21. package/Ellipse.config.js +14 -5
  22. package/Ellipse.config.js.map +4 -4
  23. package/Ellipse.js +130 -73
  24. package/Ellipse.js.map +4 -4
  25. package/Events.js +74 -26
  26. package/Events.js.map +2 -2
  27. package/FillerGauge.js +234 -47
  28. package/FillerGauge.js.map +2 -2
  29. package/Image.js +74 -26
  30. package/Image.js.map +2 -2
  31. package/Line/lineUtils.d.ts.map +1 -1
  32. package/Line/mockdata/LineData.d.ts +95 -0
  33. package/Line/mockdata/LineData.d.ts.map +1 -1
  34. package/Line.config.js +28 -7
  35. package/Line.config.js.map +2 -2
  36. package/Line.js +125 -41
  37. package/Line.js.map +2 -2
  38. package/LinkGraph.js +74 -26
  39. package/LinkGraph.js.map +2 -2
  40. package/Map/PureMap/BubbleLayer.d.ts.map +1 -1
  41. package/Map/PureMap/ClusterLayer.d.ts.map +1 -1
  42. package/Map/PureMap/MapUtils.d.ts +2 -2
  43. package/Map/PureMap/MapUtils.d.ts.map +1 -1
  44. package/Map/PureMap/PureMap.d.ts.map +1 -1
  45. package/Map.js +111 -37
  46. package/Map.js.map +2 -2
  47. package/Markdown/config.d.ts.map +1 -1
  48. package/Markdown.config.js +14 -5
  49. package/Markdown.config.js.map +4 -4
  50. package/Markdown.js +91 -34
  51. package/Markdown.js.map +4 -4
  52. package/MarkerGauge.js +243 -56
  53. package/MarkerGauge.js.map +4 -4
  54. package/NetworkGraph/PureNetworkGraph/PureNetworkGraph.d.ts.map +1 -1
  55. package/NetworkGraph/PureNetworkGraph/components/Node.d.ts.map +1 -1
  56. package/NetworkGraph/PureNetworkGraph/components/ZoomControls.d.ts.map +1 -1
  57. package/NetworkGraph/PureNetworkGraph/utils/dragUtils.d.ts +78 -0
  58. package/NetworkGraph/PureNetworkGraph/utils/dragUtils.d.ts.map +1 -0
  59. package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts +1 -2
  60. package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts.map +1 -1
  61. package/NetworkGraph/config.d.ts.map +1 -1
  62. package/NetworkGraph.config.js +1 -0
  63. package/NetworkGraph.config.js.map +2 -2
  64. package/NetworkGraph.js +366 -105
  65. package/NetworkGraph.js.map +4 -4
  66. package/PERFORMANCE.md +23 -0
  67. package/ParallelCoordinates/ParallelCoordinates.d.ts +1 -46
  68. package/ParallelCoordinates/ParallelCoordinates.d.ts.map +1 -1
  69. package/ParallelCoordinates/PureParallelCoordinates/PureParallelCoordinates.d.ts +12 -58
  70. package/ParallelCoordinates/PureParallelCoordinates/PureParallelCoordinates.d.ts.map +1 -1
  71. package/ParallelCoordinates/PureParallelCoordinates/src/ParallelCoordinatesChart.d.ts +1 -0
  72. package/ParallelCoordinates/PureParallelCoordinates/src/ParallelCoordinatesChart.d.ts.map +1 -1
  73. package/ParallelCoordinates.js +150 -153
  74. package/ParallelCoordinates.js.map +4 -4
  75. package/Pie/Pie.d.ts.map +1 -1
  76. package/Pie/config.d.ts.map +1 -1
  77. package/Pie/pieUtils.d.ts +4 -0
  78. package/Pie/pieUtils.d.ts.map +1 -1
  79. package/Pie.config.js +16 -0
  80. package/Pie.config.js.map +2 -2
  81. package/Pie.js +121 -35
  82. package/Pie.js.map +2 -2
  83. package/Punchcard.js +74 -26
  84. package/Punchcard.js.map +2 -2
  85. package/Rectangle/config.d.ts.map +1 -1
  86. package/Rectangle.config.js +14 -5
  87. package/Rectangle.config.js.map +4 -4
  88. package/Rectangle.js +92 -35
  89. package/Rectangle.js.map +4 -4
  90. package/Sankey/PureSankey/PureSankey.d.ts +26 -72
  91. package/Sankey/PureSankey/PureSankey.d.ts.map +1 -1
  92. package/Sankey/PureSankey/SankeyLink.d.ts +3 -19
  93. package/Sankey/PureSankey/SankeyLink.d.ts.map +1 -1
  94. package/Sankey/PureSankey/SankeyNode.d.ts +3 -20
  95. package/Sankey/PureSankey/SankeyNode.d.ts.map +1 -1
  96. package/Sankey/PureSankey/SankeyTooltip.d.ts +3 -24
  97. package/Sankey/PureSankey/SankeyTooltip.d.ts.map +1 -1
  98. package/Sankey.js +270 -336
  99. package/Sankey.js.map +2 -2
  100. package/Scatter.config.js +168 -147
  101. package/Scatter.config.js.map +4 -4
  102. package/Scatter.js +249 -179
  103. package/Scatter.js.map +4 -4
  104. package/SingleValue.js +96 -75
  105. package/SingleValue.js.map +2 -2
  106. package/SingleValueIcon/config.d.ts.map +1 -1
  107. package/SingleValueIcon.config.js +14 -5
  108. package/SingleValueIcon.config.js.map +4 -4
  109. package/SingleValueIcon.js +118 -76
  110. package/SingleValueIcon.js.map +4 -4
  111. package/SingleValueRadial/PureSingleValueRadial/GaugeGraph.d.ts.map +1 -1
  112. package/SingleValueRadial.js +95 -76
  113. package/SingleValueRadial.js.map +2 -2
  114. package/Table/Table.d.ts.map +1 -1
  115. package/Table/hooks.d.ts +2 -0
  116. package/Table/hooks.d.ts.map +1 -1
  117. package/Table.js +95 -49
  118. package/Table.js.map +2 -2
  119. package/Timeline/PureTimeline/PureTimeline.d.ts.map +1 -1
  120. package/Timeline/PureTimeline/src/TimelinePlugin.d.ts.map +1 -1
  121. package/Timeline/PureTimeline/src/TimelineYAxis.d.ts.map +1 -1
  122. package/Timeline/PureTimeline/src/utils/timelineUtils.d.ts +2 -1
  123. package/Timeline/PureTimeline/src/utils/timelineUtils.d.ts.map +1 -1
  124. package/Timeline.js +154 -54
  125. package/Timeline.js.map +2 -2
  126. package/common/Charting.d.ts.map +1 -1
  127. package/common/Charting.js +3 -0
  128. package/common/Charting.js.map +2 -2
  129. package/common/GaugeMajorTicks.js +150 -13
  130. package/common/GaugeMajorTicks.js.map +4 -4
  131. package/common/GaugeValueMarker.js +84 -17
  132. package/common/GaugeValueMarker.js.map +4 -4
  133. package/common/OptionsDoc.js.map +1 -1
  134. package/common/OverviewDoc.d.ts.map +1 -1
  135. package/common/OverviewDoc.js +2 -2
  136. package/common/OverviewDoc.js.map +2 -2
  137. package/common/TimeSeriesChartWrapper.d.ts.map +1 -1
  138. package/common/TimeSeriesChartWrapper.js +72 -24
  139. package/common/TimeSeriesChartWrapper.js.map +2 -2
  140. package/common/chartingUtils.d.ts +9 -3
  141. package/common/chartingUtils.d.ts.map +1 -1
  142. package/common/chartingUtils.js +21 -16
  143. package/common/chartingUtils.js.map +2 -2
  144. package/common/editorConfig/AxesChartDataConfig.d.ts +3 -3
  145. package/common/editorConfig/AxesChartDataConfig.d.ts.map +1 -1
  146. package/common/editorConfig/AxesChartDataDisplay.d.ts +4 -0
  147. package/common/editorConfig/AxesChartDataDisplay.d.ts.map +1 -1
  148. package/common/editorConfig/AxesChartLegend.d.ts.map +1 -1
  149. package/common/gaugeUtils.d.ts +37 -0
  150. package/common/gaugeUtils.d.ts.map +1 -1
  151. package/common/gaugeUtils.js +152 -2
  152. package/common/gaugeUtils.js.map +4 -4
  153. package/common/hocs/mockdata/trellisData.d.ts +119 -0
  154. package/common/hocs/mockdata/trellisData.d.ts.map +1 -1
  155. package/common/interfaces/Overview.d.ts +1 -0
  156. package/common/interfaces/Overview.d.ts.map +1 -1
  157. package/common/interfaces/VizConfig.d.ts +2 -1
  158. package/common/interfaces/VizConfig.d.ts.map +1 -1
  159. package/common/utils/mapUtils.js.map +1 -1
  160. package/common/utils/trellisUtils.d.ts.map +1 -1
  161. package/common/utils/trellisUtils.js +4 -6
  162. package/common/utils/trellisUtils.js.map +2 -2
  163. package/common/withDashboardViz.js +74 -26
  164. package/common/withDashboardViz.js.map +2 -2
  165. package/package.json +36 -36
package/NetworkGraph.js CHANGED
@@ -1673,7 +1673,7 @@ var Cover = styled_components_default.div`
1673
1673
  bottom: 0;
1674
1674
  `;
1675
1675
  var Blocker = styled_components_default.div.attrs({
1676
- "data-splunk-visualization-version": "28.4.0 - 002bd482f"
1676
+ "data-splunk-visualization-version": "28.5.1 - 617766eb3"
1677
1677
  })`
1678
1678
  position: relative;
1679
1679
  width: 100%;
@@ -1784,7 +1784,7 @@ var withFixedSizeContainer = (Viz) => {
1784
1784
  FixSizeItem,
1785
1785
  {
1786
1786
  "data-test": "fix-size-item",
1787
- "data-splunk-visualization-version": "28.4.0 - 002bd482f",
1787
+ "data-splunk-visualization-version": "28.5.1 - 617766eb3",
1788
1788
  width,
1789
1789
  height,
1790
1790
  backgroundColor
@@ -2480,25 +2480,27 @@ var parseAxisValue = (val) => {
2480
2480
  const num = typeof val === "number" ? val : Number.parseFloat(val);
2481
2481
  return Number.isNaN(num) ? void 0 : num;
2482
2482
  };
2483
- var SideLegendWidth = 75;
2484
- var SeriesCompareLegendWidth = 200;
2483
+ var parseXAxisLineVisibility = (visibility) => {
2484
+ if (visibility === "hide") return false;
2485
+ if (visibility === "show") return true;
2486
+ return void 0;
2487
+ };
2485
2488
  var getLegend = (props) => {
2486
2489
  const legendPlacement = props == null ? void 0 : props.legendDisplay;
2487
- const { isSeriesCompare } = props;
2490
+ const { isSeriesCompare, legendTruncation } = props;
2488
2491
  const commonLegendProps = {
2489
2492
  center: true,
2490
2493
  fontSize: 12,
2491
2494
  largerTiles: true,
2492
- hideSeriesValue: !isSeriesCompare
2495
+ hideSeriesValue: !isSeriesCompare,
2493
2496
  // Show values if in seriesCompare mode
2497
+ legendTruncation
2494
2498
  };
2495
2499
  switch (legendPlacement) {
2496
2500
  case "off":
2497
2501
  return false;
2498
2502
  case "left":
2499
- return (0, visualization_canvas_exports.LeftLegendFactory)(__spreadValues({
2500
- width: isSeriesCompare ? SeriesCompareLegendWidth : SideLegendWidth
2501
- }, commonLegendProps));
2503
+ return (0, visualization_canvas_exports.LeftLegendFactory)(__spreadValues({}, commonLegendProps));
2502
2504
  case "bottom":
2503
2505
  return (0, visualization_canvas_exports.BottomLegendFactory)(__spreadValues({
2504
2506
  wrap: true
@@ -2508,9 +2510,7 @@ var getLegend = (props) => {
2508
2510
  wrap: true
2509
2511
  }, commonLegendProps));
2510
2512
  default:
2511
- return (0, visualization_canvas_exports.SideLegendFactory)(__spreadValues({
2512
- width: isSeriesCompare ? SeriesCompareLegendWidth : SideLegendWidth
2513
- }, commonLegendProps));
2513
+ return (0, visualization_canvas_exports.SideLegendFactory)(__spreadValues({}, commonLegendProps));
2514
2514
  }
2515
2515
  };
2516
2516
  var getComputedAxisTitles = (inputAxisTitle, fields, axisTitleVisibility) => {
@@ -2571,9 +2571,7 @@ var getYScaleConfig = (label, yAxisAbbreviation, yAxisScale, yAxisLabelVisibilit
2571
2571
  if (yAxisAbbreviation !== "none") {
2572
2572
  yConfig.y.tickFmt = (v) => (0, visualization_canvas_exports.shortenNumber)(v, 1);
2573
2573
  }
2574
- if (yAxisAbbreviation === "none") {
2575
- yConfig.y.width = 55;
2576
- } else {
2574
+ if (yAxisAbbreviation !== "none") {
2577
2575
  yConfig.y.width = label && label.length > 0 ? 30 : 10;
2578
2576
  }
2579
2577
  if (yAxisLabelVisibility === "hide") {
@@ -2596,6 +2594,7 @@ var getY2ScaleConfig = (label, axisAbbreviation, axisScale, roundAxisLabelsToInt
2596
2594
  y2Config.y2.type = scaleType;
2597
2595
  if (axisAbbreviation !== "none") {
2598
2596
  y2Config.y2.tickFmt = (v) => (0, visualization_canvas_exports.shortenNumber)(v, 1, roundAxisLabelsToInteger);
2597
+ y2Config.y2.width = label && label.length > 0 ? 50 : 10;
2599
2598
  } else if (roundAxisLabelsToInteger) {
2600
2599
  y2Config.y2.tickFmt = (v) => roundAxisLabelsToInteger ? Math.round(v).toString() : v.toString();
2601
2600
  }
@@ -2611,7 +2610,7 @@ var getY2ScaleConfig = (label, axisAbbreviation, axisScale, roundAxisLabelsToInt
2611
2610
  }
2612
2611
  return y2Config;
2613
2612
  };
2614
- var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled, nullValueMode, markerDisplay, lineDashStyle, lineDashStylesByField) => {
2613
+ var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled, nullValueMode, markerDisplay, lineDashStyle, lineDashStylesByField, stepPosition, stepPositionsByField) => {
2615
2614
  const seriesConfig = {};
2616
2615
  let spanGaps;
2617
2616
  let replaceNullsWithZero;
@@ -2638,6 +2637,8 @@ var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled
2638
2637
  );
2639
2638
  if (shouldAssignToY2) {
2640
2639
  seriesConfig[field].overrides.scale = "y2";
2640
+ } else {
2641
+ seriesConfig[field].overrides.scale = "y";
2641
2642
  }
2642
2643
  }
2643
2644
  if (overlayFields == null ? void 0 : overlayFields.includes(field)) {
@@ -2650,6 +2651,11 @@ var getSeriesOverrides = (yfields, y2fields, lineWidth, overlayFields, y2Enabled
2650
2651
  if (fieldDashStyle) {
2651
2652
  seriesConfig[field].lineDashStyle = fieldDashStyle;
2652
2653
  }
2654
+ const hasFieldStepPosition = Object.hasOwn(stepPositionsByField || {}, field);
2655
+ const fieldStepPosition = hasFieldStepPosition ? stepPositionsByField == null ? void 0 : stepPositionsByField[field] : stepPosition;
2656
+ if (fieldStepPosition && fieldStepPosition !== "off") {
2657
+ seriesConfig[field].stepPosition = fieldStepPosition;
2658
+ }
2653
2659
  if (replaceNullsWithZero !== void 0) {
2654
2660
  seriesConfig[field].replaceNullsWithZero = replaceNullsWithZero;
2655
2661
  }
@@ -2888,6 +2894,9 @@ var TimeSeriesChartWrapper = (props) => {
2888
2894
  backgroundColor,
2889
2895
  defaultFontColor,
2890
2896
  additionalTooltipValues,
2897
+ xAxisLineVisibility: xAxisLineVisibility,
2898
+ yAxisLineVisibility,
2899
+ y2AxisLineVisibility,
2891
2900
  showYAxisWithZero: showYAxisWithZeroFromProps,
2892
2901
  showY2AxisWithZero: showY2AxisWithZeroFromProps
2893
2902
  } = _a, otherOptions = __objRest(_a, [
@@ -2911,6 +2920,10 @@ var TimeSeriesChartWrapper = (props) => {
2911
2920
  "backgroundColor",
2912
2921
  "defaultFontColor",
2913
2922
  "additionalTooltipValues",
2923
+ // Extract axis line visibility options from props
2924
+ "xAxisLineVisibility",
2925
+ "yAxisLineVisibility",
2926
+ "y2AxisLineVisibility",
2914
2927
  // Extract showYAxisWithZero directly from props for accelerated render mode
2915
2928
  "showYAxisWithZero",
2916
2929
  "showY2AxisWithZero"
@@ -2923,6 +2936,7 @@ var TimeSeriesChartWrapper = (props) => {
2923
2936
  fieldColors,
2924
2937
  legendLabels: legendLabelsStr,
2925
2938
  legendMode,
2939
+ legendTruncation,
2926
2940
  "axisTitleX.text": xAxisTitleText,
2927
2941
  "axisTitleY.text": yAxisTitleText,
2928
2942
  "axisTitleY2.text": y2AxisTitleText,
@@ -2931,6 +2945,7 @@ var TimeSeriesChartWrapper = (props) => {
2931
2945
  "axisTitleY2.visibility": y2AxisTitleVisibility,
2932
2946
  "axisLabelsX.majorLabelVisibility": xAxisLabelVisibility,
2933
2947
  "axisLabelsX.majorLabelStyle.rotation": xAxisLabelRotation,
2948
+ "axisLabelsX.maxLabelParts": xAxisMaxLabelParts,
2934
2949
  "axisLabelsY.majorLabelVisibility": yAxisLabelVisibility,
2935
2950
  "axisLabelsY.majorUnit": yAxisMajorUnitFromSimpleXML,
2936
2951
  "axisLabelsY2.majorLabelVisibility": y2AxisLabelVisibility,
@@ -2948,6 +2963,8 @@ var TimeSeriesChartWrapper = (props) => {
2948
2963
  lineWidth,
2949
2964
  lineDashStyle,
2950
2965
  fieldDashStyles: lineDashStylesByFieldStr,
2966
+ stepPosition,
2967
+ fieldStepPositions: stepPositionsByFieldStr,
2951
2968
  yAxisMin: yAxisMinRaw,
2952
2969
  yAxisMax: yAxisMaxRaw,
2953
2970
  y2AxisMin: y2AxisMinRaw,
@@ -2958,6 +2975,8 @@ var TimeSeriesChartWrapper = (props) => {
2958
2975
  showYMinorGridLines,
2959
2976
  showY2MinorGridLines,
2960
2977
  showLineSmoothing,
2978
+ xAxisMajorTickVisibility,
2979
+ xAxisMajorTickSize,
2961
2980
  yAxisMajorTickVisibility,
2962
2981
  y2AxisMajorTickVisibility,
2963
2982
  yAxisMajorTickSize,
@@ -2974,10 +2993,14 @@ var TimeSeriesChartWrapper = (props) => {
2974
2993
  const dataValuesDisplay = showDataLabels === "none" ? "off" : showDataLabels;
2975
2994
  const showYAxisWithZero = showYAxisWithZeroFromProps != null ? showYAxisWithZeroFromProps : showYAxisWithZeroFromOptions;
2976
2995
  const showY2AxisWithZero = showY2AxisWithZeroFromProps != null ? showY2AxisWithZeroFromProps : showY2AxisWithZeroFromOptions;
2996
+ const showXMajorTicks = xAxisMajorTickVisibility !== "hide";
2977
2997
  const showYMajorTicks = yAxisMajorTickVisibility === "show";
2978
2998
  const showY2MajorTicks = y2AxisMajorTickVisibility === "show";
2979
2999
  const showYMinorTicks = yAxisMinorTickVisibility === "show";
2980
3000
  const showY2MinorTicks = y2AxisMinorTickVisibility === "show";
3001
+ const showXAxisLine = parseXAxisLineVisibility(xAxisLineVisibility);
3002
+ const showYAxisLine = yAxisLineVisibility === "show";
3003
+ const showY2AxisLine = y2AxisLineVisibility === "show";
2981
3004
  const yAxisMin = parseAxisValue(yAxisMinRaw);
2982
3005
  const yAxisMax = parseAxisValue(yAxisMaxRaw);
2983
3006
  const y2AxisMin = parseAxisValue(y2AxisMinRaw);
@@ -2992,13 +3015,15 @@ var TimeSeriesChartWrapper = (props) => {
2992
3015
  y2AxisMajorUnitFromSimpleXML,
2993
3016
  y2AxisMajorTickInterval
2994
3017
  );
2995
- const yAxisMajorTickSizeNum = yAxisMajorTickSize ? Number(yAxisMajorTickSize) : void 0;
2996
- const y2AxisMajorTickSizeNum = y2AxisMajorTickSize ? Number(y2AxisMajorTickSize) : void 0;
2997
- const yAxisMinorTickSizeNum = yAxisMinorTickSize ? Number(yAxisMinorTickSize) : void 0;
2998
- const y2AxisMinorTickSizeNum = y2AxisMinorTickSize ? Number(y2AxisMinorTickSize) : void 0;
3018
+ const xAxisMajorTickSizeNum = xAxisMajorTickSize != null ? Number(xAxisMajorTickSize) : void 0;
3019
+ const yAxisMajorTickSizeNum = yAxisMajorTickSize != null ? Number(yAxisMajorTickSize) : void 0;
3020
+ const y2AxisMajorTickSizeNum = y2AxisMajorTickSize != null ? Number(y2AxisMajorTickSize) : void 0;
3021
+ const yAxisMinorTickSizeNum = yAxisMinorTickSize != null ? Number(yAxisMinorTickSize) : void 0;
3022
+ const y2AxisMinorTickSizeNum = y2AxisMinorTickSize != null ? Number(y2AxisMinorTickSize) : void 0;
2999
3023
  const seriesColors = seriesColorsStr ? JSON.parse(seriesColorsStr) : void 0;
3000
3024
  const seriesColorsByField = fieldColors ? JSON.parse(fieldColors) : void 0;
3001
3025
  const lineDashStylesByField = lineDashStylesByFieldStr ? JSON.parse(lineDashStylesByFieldStr) : void 0;
3026
+ const stepPositionsByField = stepPositionsByFieldStr ? JSON.parse(stepPositionsByFieldStr) : void 0;
3002
3027
  const legendLabels = parseArrayOption(legendLabelsStr);
3003
3028
  const bgColor = backgroundColor || bgColorFromOptions;
3004
3029
  const [containerWidth, setContainerWidth] = react_exports.useState(Number(props.width));
@@ -3086,7 +3111,9 @@ var TimeSeriesChartWrapper = (props) => {
3086
3111
  nullValueMode,
3087
3112
  markerDisplay,
3088
3113
  lineDashStyle,
3089
- lineDashStylesByField
3114
+ lineDashStylesByField,
3115
+ stepPosition,
3116
+ stepPositionsByField
3090
3117
  ),
3091
3118
  [
3092
3119
  yFields,
@@ -3097,7 +3124,9 @@ var TimeSeriesChartWrapper = (props) => {
3097
3124
  nullValueMode,
3098
3125
  markerDisplay,
3099
3126
  lineDashStyle,
3100
- lineDashStylesByField
3127
+ lineDashStylesByField,
3128
+ stepPosition,
3129
+ stepPositionsByField
3101
3130
  ]
3102
3131
  );
3103
3132
  const chartingEventAnnotations = (0, react_exports.useMemo)(
@@ -3112,9 +3141,14 @@ var TimeSeriesChartWrapper = (props) => {
3112
3141
  () => __spreadValues(__spreadValues(__spreadValues({}, xScaleConfig), yScaleConfig), y2ScaleConfig),
3113
3142
  [xScaleConfig, yScaleConfig, y2ScaleConfig]
3114
3143
  );
3144
+ const isSeriesCompare = legendMode === "seriesCompare";
3115
3145
  const legend = (0, react_exports.useMemo)(
3116
- () => getLegend({ legendDisplay, isSeriesCompare: legendMode === "seriesCompare" }),
3117
- [legendDisplay, legendMode]
3146
+ () => getLegend({
3147
+ legendDisplay: isSeriesCompare && legendDisplay !== "off" ? "right" : legendDisplay,
3148
+ isSeriesCompare,
3149
+ legendTruncation
3150
+ }),
3151
+ [legendDisplay, isSeriesCompare, legendTruncation]
3118
3152
  );
3119
3153
  const handleChartClick = react_exports.useCallback(
3120
3154
  (event) => {
@@ -3219,6 +3253,7 @@ var TimeSeriesChartWrapper = (props) => {
3219
3253
  seriesConfig: seriesOverrides,
3220
3254
  legend,
3221
3255
  legendLabels,
3256
+ legendTruncation,
3222
3257
  isSeriesCompare: legendMode === "seriesCompare",
3223
3258
  maxSeriesFocus: legendMode === "seriesCompare" ? 0 : void 0,
3224
3259
  scaleConfig,
@@ -3240,6 +3275,8 @@ var TimeSeriesChartWrapper = (props) => {
3240
3275
  showY2MinorGridLines,
3241
3276
  showLineSmoothing,
3242
3277
  dataValuesDisplay,
3278
+ showXMajorTicks,
3279
+ xAxisMajorTickSize: xAxisMajorTickSizeNum,
3243
3280
  showYMajorTicks,
3244
3281
  showY2MajorTicks,
3245
3282
  yAxisMajorTickSize: yAxisMajorTickSizeNum,
@@ -3251,7 +3288,11 @@ var TimeSeriesChartWrapper = (props) => {
3251
3288
  yAxisMinorTickSize: yAxisMinorTickSizeNum,
3252
3289
  y2AxisMinorTickSize: y2AxisMinorTickSizeNum,
3253
3290
  showYAxisWithZero,
3254
- showY2AxisWithZero
3291
+ showY2AxisWithZero,
3292
+ showXAxisLine,
3293
+ showYAxisLine,
3294
+ showY2AxisLine,
3295
+ xAxisMaxLabelParts
3255
3296
  }
3256
3297
  ));
3257
3298
  }, [
@@ -3266,6 +3307,7 @@ var TimeSeriesChartWrapper = (props) => {
3266
3307
  seriesOverrides,
3267
3308
  legend,
3268
3309
  legendLabels,
3310
+ legendTruncation,
3269
3311
  scaleConfig,
3270
3312
  onClick,
3271
3313
  handleChartClick,
@@ -3284,6 +3326,8 @@ var TimeSeriesChartWrapper = (props) => {
3284
3326
  showY2MinorGridLines,
3285
3327
  showLineSmoothing,
3286
3328
  dataValuesDisplay,
3329
+ showXMajorTicks,
3330
+ xAxisMajorTickSizeNum,
3287
3331
  showYMajorTicks,
3288
3332
  showY2MajorTicks,
3289
3333
  yAxisMajorTickSizeNum,
@@ -3296,7 +3340,11 @@ var TimeSeriesChartWrapper = (props) => {
3296
3340
  y2AxisMinorTickSizeNum,
3297
3341
  showYAxisWithZero,
3298
3342
  showY2AxisWithZero,
3299
- legendMode
3343
+ showXAxisLine,
3344
+ showYAxisLine,
3345
+ showY2AxisLine,
3346
+ legendMode,
3347
+ xAxisMaxLabelParts
3300
3348
  ]);
3301
3349
  const memoizedVisualization = (0, react_exports.useMemo)(() => {
3302
3350
  return /* @__PURE__ */ react_exports.createElement(VizStyleWrapper_default, { backgroundColor: bgColor }, memoizedChart);
@@ -4246,7 +4294,6 @@ var getNodeMapWithPositions = ({
4246
4294
  nodeSize,
4247
4295
  layout,
4248
4296
  layoutOptions,
4249
- nodeDragPositions,
4250
4297
  resultLimit
4251
4298
  }) => {
4252
4299
  const nodeMapStruct = getUniqueNodesStruct(
@@ -4281,9 +4328,7 @@ var getNodeMapWithPositions = ({
4281
4328
  updatedLayoutOptions = __spreadProps(__spreadValues({}, updatedLayoutOptions), { d3NodeList, d3LinkList });
4282
4329
  }
4283
4330
  const positionMap = getLayout(layout, nodeMapStruct, updatedLayoutOptions);
4284
- const nodeMapStructWithPositions = updatePositions(nodeMapStruct, positionMap);
4285
- const nodeMapStructWithDragPositions = updatePositions(nodeMapStructWithPositions, nodeDragPositions);
4286
- return nodeMapStructWithDragPositions;
4331
+ return updatePositions(nodeMapStruct, positionMap);
4287
4332
  };
4288
4333
  var fitCharacters = (context, maxWidth, prefix, word) => {
4289
4334
  const space = prefix ? " " : "";
@@ -4354,11 +4399,14 @@ var truncateTextToMaxLines = (text = "", font = `12px ${VIZ_FONT_FAMILY}`, maxWi
4354
4399
  return outputLines;
4355
4400
  };
4356
4401
  var getNodeBounds = (node) => {
4357
- var _a;
4402
+ var _a, _b;
4358
4403
  if (!node) return void 0;
4359
- const nodeLabelHeightWithMargin = RECT_TOP_MARGIN + RECT_VERTICAL_PADDING * 2 + LABEL_FONT_SIZE;
4360
- const nodeLabelWidth = computeTextWidth(node.label, `14px ${VIZ_FONT_FAMILY}`) + RECT_HORIZONTAL_PADDING * 2;
4361
- const nodeDiameter = (_a = node.size) != null ? _a : DEFAULT_NODE_RADIUS * 2;
4404
+ const truncatedText = truncateTextToMaxLines((_a = node.label) != null ? _a : "", FONT, MAX_TEXT_WIDTH, 2);
4405
+ const textWidth = truncatedText.length ? Math.max(...truncatedText.map((line) => computeTextWidth(line, FONT))) : 0;
4406
+ const labelHeight = truncatedText.length > 0 ? RECT_VERTICAL_PADDING * 2 + LINE_HEIGHT * truncatedText.length : 0;
4407
+ const nodeLabelHeightWithMargin = RECT_TOP_MARGIN + labelHeight;
4408
+ const nodeLabelWidth = textWidth + RECT_HORIZONTAL_PADDING * 2;
4409
+ const nodeDiameter = (_b = node.size) != null ? _b : DEFAULT_NODE_RADIUS * 2;
4362
4410
  const nodeRadius = nodeDiameter / 2;
4363
4411
  return {
4364
4412
  x: node.x - Math.max(nodeRadius, nodeLabelWidth / 2),
@@ -4368,10 +4416,10 @@ var getNodeBounds = (node) => {
4368
4416
  };
4369
4417
  };
4370
4418
  var getFullVizBoundsWithPadding = (nodeMap, padding) => {
4371
- let minXNode;
4372
- let minYNode;
4373
- let maxXNode;
4374
- let maxYNode;
4419
+ let minX = Infinity;
4420
+ let minY = Infinity;
4421
+ let maxX = -Infinity;
4422
+ let maxY = -Infinity;
4375
4423
  if (Object.keys(nodeMap).length === 0) {
4376
4424
  return {
4377
4425
  x: 0,
@@ -4381,18 +4429,20 @@ var getFullVizBoundsWithPadding = (nodeMap, padding) => {
4381
4429
  };
4382
4430
  }
4383
4431
  Object.values(nodeMap).forEach((node) => {
4384
- var _a, _b, _c, _d, _e, _f, _g, _h;
4385
- if (!getNodeBounds(node)) return;
4386
- if (getNodeBounds(node).x < ((_b = (_a = getNodeBounds(minXNode)) == null ? void 0 : _a.x) != null ? _b : Infinity)) minXNode = node;
4387
- if (getNodeBounds(node).y < ((_d = (_c = getNodeBounds(minYNode)) == null ? void 0 : _c.y) != null ? _d : Infinity)) minYNode = node;
4388
- if (getNodeBounds(node).x2 > ((_f = (_e = getNodeBounds(maxXNode)) == null ? void 0 : _e.x2) != null ? _f : -Infinity)) maxXNode = node;
4389
- if (getNodeBounds(node).y2 > ((_h = (_g = getNodeBounds(maxYNode)) == null ? void 0 : _g.y2) != null ? _h : -Infinity)) maxYNode = node;
4432
+ const bounds = getNodeBounds(node);
4433
+ if (!bounds) return;
4434
+ if (!Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) return;
4435
+ if (!Number.isFinite(bounds.x2) || !Number.isFinite(bounds.y2)) return;
4436
+ minX = Math.min(minX, bounds.x);
4437
+ minY = Math.min(minY, bounds.y);
4438
+ maxX = Math.max(maxX, bounds.x2);
4439
+ maxY = Math.max(maxY, bounds.y2);
4390
4440
  });
4391
4441
  return {
4392
- x: getNodeBounds(minXNode) ? getNodeBounds(minXNode).x - padding : 0,
4393
- y: getNodeBounds(minYNode) ? getNodeBounds(minYNode).y - padding : 0,
4394
- width: getNodeBounds(maxXNode) ? getNodeBounds(maxXNode).x2 - getNodeBounds(minXNode).x + padding * 2 : 0,
4395
- height: getNodeBounds(maxYNode) ? getNodeBounds(maxYNode).y2 - getNodeBounds(minYNode).y + padding * 2 : 0
4442
+ x: Number.isFinite(minX) ? minX - padding : 0,
4443
+ y: Number.isFinite(minY) ? minY - padding : 0,
4444
+ width: Number.isFinite(maxX) && Number.isFinite(minX) ? maxX - minX + padding * 2 : 0,
4445
+ height: Number.isFinite(maxY) && Number.isFinite(minY) ? maxY - minY + padding * 2 : 0
4396
4446
  };
4397
4447
  };
4398
4448
  var getAutoZoomAndPan = (nodeMap, containerWidth, containerHeight) => {
@@ -4695,6 +4745,131 @@ var getEdgePath = ({
4695
4745
  `;
4696
4746
  };
4697
4747
 
4748
+ // src/NetworkGraph/PureNetworkGraph/utils/dragUtils.ts
4749
+ init_define_global();
4750
+ var isValidZoomAndPanState = (zoomAndPanState) => Number.isFinite(zoomAndPanState.zoom) && zoomAndPanState.zoom > 0 && Number.isFinite(zoomAndPanState.x) && Number.isFinite(zoomAndPanState.y);
4751
+ var getAdjustedDragPosition = (pendingDragPosition, zoomAndPanState) => {
4752
+ if (!pendingDragPosition) {
4753
+ return null;
4754
+ }
4755
+ if (!isValidZoomAndPanState(zoomAndPanState)) {
4756
+ return pendingDragPosition;
4757
+ }
4758
+ return {
4759
+ x: (pendingDragPosition.x - zoomAndPanState.x) / zoomAndPanState.zoom,
4760
+ y: (pendingDragPosition.y - zoomAndPanState.y) / zoomAndPanState.zoom
4761
+ };
4762
+ };
4763
+ var getPointerInGraphSpaceFromMouseEvent = (event, svgElement, zoomAndPanState) => {
4764
+ var _a, _b, _c, _d, _e, _f;
4765
+ if (!svgElement || !Number.isFinite(event == null ? void 0 : event.clientX) || !Number.isFinite(event == null ? void 0 : event.clientY)) {
4766
+ return null;
4767
+ }
4768
+ const rect = svgElement.getBoundingClientRect();
4769
+ if (rect.width <= 0 || rect.height <= 0) {
4770
+ return null;
4771
+ }
4772
+ const svgWidth = (_c = (_b = (_a = svgElement.width) == null ? void 0 : _a.baseVal) == null ? void 0 : _b.value) != null ? _c : rect.width;
4773
+ const svgHeight = (_f = (_e = (_d = svgElement.height) == null ? void 0 : _d.baseVal) == null ? void 0 : _e.value) != null ? _f : rect.height;
4774
+ const scaleX = svgWidth / rect.width;
4775
+ const scaleY = svgHeight / rect.height;
4776
+ const pointerInSvgSpace = {
4777
+ x: (event.clientX - rect.left) * scaleX,
4778
+ y: (event.clientY - rect.top) * scaleY
4779
+ };
4780
+ return getAdjustedDragPosition(pointerInSvgSpace, zoomAndPanState);
4781
+ };
4782
+ var getInitialDragOffset = (pointerInGraphSpace, nodePosition) => {
4783
+ if (!pointerInGraphSpace || !nodePosition || !Number.isFinite(pointerInGraphSpace.x) || !Number.isFinite(pointerInGraphSpace.y) || !Number.isFinite(nodePosition.x) || !Number.isFinite(nodePosition.y)) {
4784
+ return null;
4785
+ }
4786
+ return {
4787
+ x: pointerInGraphSpace.x - nodePosition.x,
4788
+ y: pointerInGraphSpace.y - nodePosition.y
4789
+ };
4790
+ };
4791
+ var getDraggedNodePositionWithOffset = ({
4792
+ pendingDragPosition,
4793
+ zoomAndPanState,
4794
+ currentNodePosition,
4795
+ existingDragOffset
4796
+ }) => {
4797
+ var _a, _b;
4798
+ const adjustedPendingPosition = getAdjustedDragPosition(pendingDragPosition, zoomAndPanState);
4799
+ if (!adjustedPendingPosition) {
4800
+ return null;
4801
+ }
4802
+ const resolvedDragOffset = existingDragOffset != null ? existingDragOffset : getInitialDragOffset(adjustedPendingPosition, currentNodePosition);
4803
+ return {
4804
+ adjustedPositionWithOffset: {
4805
+ x: adjustedPendingPosition.x - ((_a = resolvedDragOffset == null ? void 0 : resolvedDragOffset.x) != null ? _a : 0),
4806
+ y: adjustedPendingPosition.y - ((_b = resolvedDragOffset == null ? void 0 : resolvedDragOffset.y) != null ? _b : 0)
4807
+ },
4808
+ resolvedDragOffset
4809
+ };
4810
+ };
4811
+ var updateDraggedNodePosition = (previousNodeMap, nodeId, nextPosition) => {
4812
+ if (!nodeId || !nextPosition) {
4813
+ return previousNodeMap;
4814
+ }
4815
+ const currentNode = previousNodeMap[nodeId];
4816
+ if (!currentNode) {
4817
+ return previousNodeMap;
4818
+ }
4819
+ if (currentNode.x === nextPosition.x && currentNode.y === nextPosition.y) {
4820
+ return previousNodeMap;
4821
+ }
4822
+ return __spreadProps(__spreadValues({}, previousNodeMap), {
4823
+ [nodeId]: __spreadProps(__spreadValues({}, currentNode), {
4824
+ x: nextPosition.x,
4825
+ y: nextPosition.y
4826
+ })
4827
+ });
4828
+ };
4829
+ var patchNodeMapWithDragPositionChanges = (previousNodeMap, baseNodeMap, previousDragPositions, nextDragPositions) => {
4830
+ const changedNodeIds = /* @__PURE__ */ new Set([
4831
+ ...Object.keys(previousDragPositions || {}),
4832
+ ...Object.keys(nextDragPositions || {})
4833
+ ]);
4834
+ let updatedNodeMap = previousNodeMap;
4835
+ changedNodeIds.forEach((nodeId) => {
4836
+ const currentNode = previousNodeMap[nodeId];
4837
+ const baseNode = baseNodeMap[nodeId];
4838
+ if (!currentNode || !baseNode) {
4839
+ return;
4840
+ }
4841
+ const nextPosition = nextDragPositions == null ? void 0 : nextDragPositions[nodeId];
4842
+ const resolvedPosition = nextPosition != null ? nextPosition : { x: baseNode.x, y: baseNode.y };
4843
+ if (currentNode.x === resolvedPosition.x && currentNode.y === resolvedPosition.y) {
4844
+ return;
4845
+ }
4846
+ if (updatedNodeMap === previousNodeMap) {
4847
+ updatedNodeMap = __spreadValues({}, previousNodeMap);
4848
+ }
4849
+ updatedNodeMap[nodeId] = __spreadProps(__spreadValues({}, currentNode), {
4850
+ x: resolvedPosition.x,
4851
+ y: resolvedPosition.y
4852
+ });
4853
+ });
4854
+ return updatedNodeMap;
4855
+ };
4856
+ var patchDragPositionsMap = (baseMap, previousDragPositions, nextDragPositions) => {
4857
+ const patchedMap = __spreadValues({}, baseMap);
4858
+ const changedNodeIds = /* @__PURE__ */ new Set([
4859
+ ...Object.keys(previousDragPositions || {}),
4860
+ ...Object.keys(nextDragPositions || {})
4861
+ ]);
4862
+ changedNodeIds.forEach((nodeId) => {
4863
+ const nextPosition = nextDragPositions == null ? void 0 : nextDragPositions[nodeId];
4864
+ if (nextPosition) {
4865
+ patchedMap[nodeId] = nextPosition;
4866
+ } else {
4867
+ delete patchedMap[nodeId];
4868
+ }
4869
+ });
4870
+ return patchedMap;
4871
+ };
4872
+
4698
4873
  // src/NetworkGraph/PureNetworkGraph/components/NetworkGraphSvg.tsx
4699
4874
  init_define_global();
4700
4875
 
@@ -4909,11 +5084,23 @@ var Node = (0, react_exports.memo)(function Node2(props) {
4909
5084
  isMounted = false;
4910
5085
  };
4911
5086
  }, [builtInIcon]);
4912
- const nodeClickHandler = () => {
5087
+ const nodeClickHandler = (0, react_exports.useCallback)(() => {
4913
5088
  if (handleNodeClick) {
4914
5089
  handleNodeClick({ id, value, index });
4915
5090
  }
4916
- };
5091
+ }, [handleNodeClick, id, value, index]);
5092
+ const onKeyDown = (0, react_exports.useCallback)(
5093
+ (event) => {
5094
+ if (event.repeat) {
5095
+ return;
5096
+ }
5097
+ if (event.key === "Enter" || event.key === " ") {
5098
+ event.preventDefault();
5099
+ nodeClickHandler();
5100
+ }
5101
+ },
5102
+ [nodeClickHandler]
5103
+ );
4917
5104
  const nodeWithPosition = (0, react_exports.useMemo)(
4918
5105
  () => ({ id, value, index, x, y, size: diameter }),
4919
5106
  [id, index, value, x, y, diameter]
@@ -4966,11 +5153,16 @@ var Node = (0, react_exports.memo)(function Node2(props) {
4966
5153
  id: sanitizedId,
4967
5154
  ref: circleRef,
4968
5155
  tabIndex: 0,
5156
+ role: "button",
5157
+ "aria-label": label || (0, i18n_exports._)("Node"),
4969
5158
  color,
4970
5159
  opacity,
4971
5160
  onClick: nodeClickHandler,
5161
+ onKeyDown,
4972
5162
  onMouseEnter,
4973
- onMouseLeave
5163
+ onMouseLeave,
5164
+ onFocus: onMouseEnter,
5165
+ onBlur: onMouseLeave
4974
5166
  }
4975
5167
  ), !!IconComponent && !shouldHideIcon && /* @__PURE__ */ react_exports.createElement(
4976
5168
  NodeIcon,
@@ -5217,7 +5409,7 @@ var NetworkGraphSvg = (0, react_exports.memo)(function NetworkGraphSvg2({
5217
5409
  handleNodeMouseOver,
5218
5410
  handleNodeMouseOut,
5219
5411
  highlightedNode,
5220
- setHighlightedNode,
5412
+ setHighlightedNode = () => void 0,
5221
5413
  isDragging = false
5222
5414
  }) {
5223
5415
  var _a, _b;
@@ -5407,6 +5599,16 @@ var defaultImport116 = __toESM(require("@splunk/react-ui/Button"));
5407
5599
  __reExport(Button_exports, require("@splunk/react-ui/Button"));
5408
5600
  var Button_default = "default" in defaultImport116 ? defaultImport116.default : defaultImport116;
5409
5601
 
5602
+ // esm-externals:@splunk/react-ui/Tooltip
5603
+ var Tooltip_exports = {};
5604
+ __export(Tooltip_exports, {
5605
+ default: () => Tooltip_default2
5606
+ });
5607
+ init_define_global();
5608
+ var defaultImport117 = __toESM(require("@splunk/react-ui/Tooltip"));
5609
+ __reExport(Tooltip_exports, require("@splunk/react-ui/Tooltip"));
5610
+ var Tooltip_default2 = "default" in defaultImport117 ? defaultImport117.default : defaultImport117;
5611
+
5410
5612
  // src/NetworkGraph/PureNetworkGraph/components/ZoomControls.tsx
5411
5613
  var StyledZoomControlsContainer = styled_components_default.div`
5412
5614
  position: absolute;
@@ -5452,33 +5654,33 @@ var ZoomControls = (0, react_exports.memo)(function ZoomControls2(props) {
5452
5654
  disableZoomIn = false,
5453
5655
  disableZoomOut = false
5454
5656
  } = props;
5455
- return /* @__PURE__ */ react_exports.createElement(StyledZoomControlsContainer, { "data-test": "zoom-controls-container" }, !hideZoomControls && /* @__PURE__ */ react_exports.createElement(StyledBaseContainer, { "data-test": "zoom-buttons-container" }, /* @__PURE__ */ react_exports.createElement(
5657
+ return /* @__PURE__ */ react_exports.createElement(StyledZoomControlsContainer, { "data-test": "zoom-controls-container" }, !hideZoomControls && /* @__PURE__ */ react_exports.createElement(StyledBaseContainer, { "data-test": "zoom-buttons-container" }, /* @__PURE__ */ react_exports.createElement(Tooltip_default2, { contentRelationship: "label", content: (0, i18n_exports._)("Zoom in") }, /* @__PURE__ */ react_exports.createElement(
5456
5658
  StyledZoomInButton,
5457
5659
  {
5458
5660
  icon: /* @__PURE__ */ react_exports.createElement(Plus_default, null),
5459
5661
  appearance: "subtle",
5460
5662
  onClick: handleZoomIn,
5461
- "aria-label": (0, i18n_exports._)("Zoom In"),
5462
- disabled: disableZoomIn
5663
+ disabled: disableZoomIn,
5664
+ "data-test": "zoom-in-button"
5463
5665
  }
5464
- ), /* @__PURE__ */ react_exports.createElement(
5666
+ )), /* @__PURE__ */ react_exports.createElement(Tooltip_default2, { contentRelationship: "label", content: (0, i18n_exports._)("Zoom out") }, /* @__PURE__ */ react_exports.createElement(
5465
5667
  StyledZoomOutButton,
5466
5668
  {
5467
5669
  icon: /* @__PURE__ */ react_exports.createElement(Minus_default, null),
5468
5670
  appearance: "subtle",
5469
5671
  onClick: handleZoomOut,
5470
- "aria-label": (0, i18n_exports._)("Zoom Out"),
5471
- disabled: disableZoomOut
5672
+ disabled: disableZoomOut,
5673
+ "data-test": "zoom-out-button"
5472
5674
  }
5473
- )), !hideReset && /* @__PURE__ */ react_exports.createElement(StyledResetContainer, { moveToTop: hideZoomControls, "data-test": "reset-button-container" }, /* @__PURE__ */ react_exports.createElement(
5675
+ ))), !hideReset && /* @__PURE__ */ react_exports.createElement(StyledResetContainer, { moveToTop: hideZoomControls, "data-test": "reset-button-container" }, /* @__PURE__ */ react_exports.createElement(Tooltip_default2, { contentRelationship: "label", content: (0, i18n_exports._)("Reset zoom") }, /* @__PURE__ */ react_exports.createElement(
5474
5676
  StyledButton,
5475
5677
  {
5476
5678
  icon: /* @__PURE__ */ react_exports.createElement(SquareAndCorners_default, null),
5477
5679
  appearance: "subtle",
5478
5680
  onClick: handleReset,
5479
- "aria-label": (0, i18n_exports._)("Reset Zoom")
5681
+ "data-test": "reset-button"
5480
5682
  }
5481
- )));
5683
+ ))));
5482
5684
  });
5483
5685
  var ZoomControls_default = ZoomControls;
5484
5686
 
@@ -5555,7 +5757,16 @@ var PureNetworkGraph = ({
5555
5757
  height: typeof height === "number" ? height : DEFAULT_CHART_HEIGHT
5556
5758
  });
5557
5759
  const [isDragging, setIsDragging] = (0, react_exports.useState)({ dragStarted: false, id: null });
5558
- const [parentZoomAndPanState, setParentZoomAndPanState] = (0, react_exports.useState)({ zoom: null, x: null, y: null });
5760
+ const [parentZoomAndPanState, setParentZoomAndPanState] = (0, react_exports.useState)({
5761
+ zoom: null,
5762
+ x: null,
5763
+ y: null
5764
+ });
5765
+ const frozenNodeMapForZoomRef = (0, react_exports.useRef)(null);
5766
+ const dragOffsetRef = (0, react_exports.useRef)(null);
5767
+ const baseNodeMapRef = (0, react_exports.useRef)(null);
5768
+ const previousNodeDragPositionsRef = (0, react_exports.useRef)(nodeDragPositions);
5769
+ const persistedDragPositionsRef = (0, react_exports.useRef)(__spreadValues({}, nodeDragPositions));
5559
5770
  const effectivePreferPorts = preferPorts != null ? preferPorts : getDefaultPreferPorts(layout, hierarchyDirection);
5560
5771
  (0, react_exports.useEffect)(() => {
5561
5772
  const updateSize = () => {
@@ -5624,7 +5835,6 @@ var PureNetworkGraph = ({
5624
5835
  nodeSize,
5625
5836
  layout,
5626
5837
  layoutOptions,
5627
- nodeDragPositions,
5628
5838
  resultLimit
5629
5839
  });
5630
5840
  }, [
@@ -5650,10 +5860,11 @@ var PureNetworkGraph = ({
5650
5860
  nodeSize,
5651
5861
  nodeTexts,
5652
5862
  nodeTypes,
5653
- nodeDragPositions,
5654
5863
  resultLimit
5655
5864
  ]);
5656
- const [nodeMapStruct, setNodeMapStruct] = (0, react_exports.useState)(nodeMapStructWithPositions);
5865
+ const [nodeMapStruct, setNodeMapStruct] = (0, react_exports.useState)(
5866
+ () => updatePositions(nodeMapStructWithPositions, nodeDragPositions)
5867
+ );
5657
5868
  const [hideReset, setHideReset] = (0, react_exports.useState)(true);
5658
5869
  const [isReadyToRender, setIsReadyToRender] = (0, react_exports.useState)(false);
5659
5870
  const [highlightedNode, setHighlightedNode] = (0, react_exports.useState)(null);
@@ -5661,9 +5872,10 @@ var PureNetworkGraph = ({
5661
5872
  const numberHeight = typeof height === "string" ? containerSize.height : height;
5662
5873
  const effectiveWidth = Math.max(numberWidth, 0);
5663
5874
  const effectiveHeight = Math.max(numberHeight, 0);
5875
+ const nodeMapForAutoZoom = isDragging.dragStarted && frozenNodeMapForZoomRef.current ? frozenNodeMapForZoomRef.current : nodeMapStruct;
5664
5876
  const { autoZoomLevel, autoCenter } = (0, react_exports.useMemo)(() => {
5665
- return getAutoZoomAndPan(nodeMapStruct, effectiveWidth, effectiveHeight);
5666
- }, [nodeMapStruct, effectiveWidth, effectiveHeight]);
5877
+ return getAutoZoomAndPan(nodeMapForAutoZoom, effectiveWidth, effectiveHeight);
5878
+ }, [nodeMapForAutoZoom, effectiveWidth, effectiveHeight]);
5667
5879
  const { minZoomLevel, minZoomWidth, minZoomHeight } = (0, react_exports.useMemo)(() => {
5668
5880
  return calculateMinZoomBounds(autoZoomLevel, effectiveHeight, effectiveWidth);
5669
5881
  }, [autoZoomLevel, effectiveHeight, effectiveWidth]);
@@ -5676,8 +5888,34 @@ var PureNetworkGraph = ({
5676
5888
  [parentZoomAndPanState.zoom, autoZoomLevel, minZoomLevel]
5677
5889
  );
5678
5890
  (0, react_exports.useEffect)(() => {
5679
- setNodeMapStruct(nodeMapStructWithPositions);
5680
- }, [nodeMapStructWithPositions]);
5891
+ const baseNodeMap = baseNodeMapRef.current;
5892
+ if (!baseNodeMap) {
5893
+ baseNodeMapRef.current = nodeMapStructWithPositions;
5894
+ previousNodeDragPositionsRef.current = nodeDragPositions;
5895
+ return;
5896
+ }
5897
+ const baseLayoutChanged = baseNodeMap !== nodeMapStructWithPositions;
5898
+ baseNodeMapRef.current = nodeMapStructWithPositions;
5899
+ if (baseLayoutChanged) {
5900
+ setNodeMapStruct(updatePositions(nodeMapStructWithPositions, nodeDragPositions));
5901
+ } else {
5902
+ setNodeMapStruct(
5903
+ (previousNodeMap) => patchNodeMapWithDragPositionChanges(
5904
+ previousNodeMap,
5905
+ baseNodeMap,
5906
+ previousNodeDragPositionsRef.current,
5907
+ nodeDragPositions
5908
+ )
5909
+ );
5910
+ }
5911
+ const nextPersistedDragPositions = patchDragPositionsMap(
5912
+ persistedDragPositionsRef.current,
5913
+ previousNodeDragPositionsRef.current,
5914
+ nodeDragPositions
5915
+ );
5916
+ persistedDragPositionsRef.current = nextPersistedDragPositions;
5917
+ previousNodeDragPositionsRef.current = nodeDragPositions;
5918
+ }, [nodeDragPositions, nodeMapStructWithPositions]);
5681
5919
  const zoomFunc = (0, react_exports.useMemo)(
5682
5920
  () => (0, d3_zoom_exports.zoom)().on("zoom", (event) => {
5683
5921
  if (zoomContainerRef.current) {
@@ -5722,6 +5960,7 @@ var PureNetworkGraph = ({
5722
5960
  ]);
5723
5961
  (0, react_exports.useEffect)(() => {
5724
5962
  if (prevLayoutRef.current !== layout) {
5963
+ persistedDragPositionsRef.current = {};
5725
5964
  onOptionsChange({
5726
5965
  nodeDragPositions: {}
5727
5966
  });
@@ -5781,23 +6020,41 @@ var PureNetworkGraph = ({
5781
6020
  // mousedown uses event from d3 which is typed to any
5782
6021
  (e) => {
5783
6022
  const unSanitizedId = unsanitizeSvgId(e.currentTarget.id);
6023
+ frozenNodeMapForZoomRef.current = nodeMapStruct;
6024
+ dragOffsetRef.current = null;
6025
+ const draggedNode = nodeMapStruct[unSanitizedId];
6026
+ if (draggedNode) {
6027
+ const pointerInGraphSpace = getPointerInGraphSpaceFromMouseEvent(
6028
+ e,
6029
+ svgRef.current,
6030
+ parentZoomAndPanState
6031
+ );
6032
+ dragOffsetRef.current = getInitialDragOffset(pointerInGraphSpace, {
6033
+ x: draggedNode.x,
6034
+ y: draggedNode.y
6035
+ });
6036
+ }
5784
6037
  if (e == null ? void 0 : e.preventDefault) {
5785
6038
  e.preventDefault();
5786
6039
  }
5787
6040
  setIsDragging({ dragStarted: true, id: unSanitizedId });
5788
6041
  forwardMouseDownEvent(e, containerRef.current);
5789
6042
  },
5790
- [setIsDragging]
6043
+ [nodeMapStruct, parentZoomAndPanState, setIsDragging]
5791
6044
  );
5792
6045
  const handleMouseUp = (0, react_exports.useCallback)(() => {
5793
- if (nodeMapStruct[isDragging == null ? void 0 : isDragging.id]) {
6046
+ dragOffsetRef.current = null;
6047
+ frozenNodeMapForZoomRef.current = null;
6048
+ if (isDragging.id && nodeMapStruct[isDragging.id]) {
6049
+ const nextPersistedDragPositions = __spreadProps(__spreadValues({}, persistedDragPositionsRef.current), {
6050
+ [isDragging.id]: {
6051
+ x: nodeMapStruct[isDragging.id].x,
6052
+ y: nodeMapStruct[isDragging.id].y
6053
+ }
6054
+ });
6055
+ persistedDragPositionsRef.current = nextPersistedDragPositions;
5794
6056
  onOptionsChange({
5795
- nodeDragPositions: __spreadProps(__spreadValues({}, nodeDragPositions), {
5796
- [isDragging.id]: {
5797
- x: nodeMapStruct[isDragging.id].x,
5798
- y: nodeMapStruct[isDragging.id].y
5799
- }
5800
- })
6057
+ nodeDragPositions: nextPersistedDragPositions
5801
6058
  });
5802
6059
  const metadataForNode = metadata[nodeMapVisual[isDragging.id].index] || {};
5803
6060
  onNodeDrag({
@@ -5813,27 +6070,30 @@ var PureNetworkGraph = ({
5813
6070
  });
5814
6071
  }
5815
6072
  setIsDragging({ dragStarted: false, id: null });
5816
- }, [
5817
- nodeMapStruct,
5818
- isDragging.id,
5819
- onOptionsChange,
5820
- nodeDragPositions,
5821
- metadata,
5822
- nodeMapVisual,
5823
- onNodeDrag
5824
- ]);
6073
+ }, [nodeMapStruct, isDragging.id, onOptionsChange, metadata, nodeMapVisual, onNodeDrag]);
5825
6074
  const handleDrag = (0, react_exports.useCallback)(
5826
6075
  (x, y) => {
5827
- const isZoomValid = parentZoomAndPanState && Number.isFinite(parentZoomAndPanState.zoom) && parentZoomAndPanState.zoom > 0 && Number.isFinite(parentZoomAndPanState.x) && Number.isFinite(parentZoomAndPanState.y);
5828
- if (isDragging.dragStarted) {
5829
- setNodeMapStruct(__spreadProps(__spreadValues({}, nodeMapStruct), {
5830
- // position needs to be adjusted by the current zoom and pan state
5831
- [isDragging.id]: __spreadProps(__spreadValues({}, nodeMapStruct[isDragging.id]), {
5832
- x: isZoomValid ? (x - parentZoomAndPanState.x) / parentZoomAndPanState.zoom : x,
5833
- y: isZoomValid ? (y - parentZoomAndPanState.y) / parentZoomAndPanState.zoom : y
5834
- })
5835
- }));
6076
+ if (!isDragging.dragStarted) {
6077
+ return;
5836
6078
  }
6079
+ const currentNode = nodeMapStruct[isDragging.id];
6080
+ const dragPositionResult = getDraggedNodePositionWithOffset({
6081
+ pendingDragPosition: { x, y },
6082
+ zoomAndPanState: parentZoomAndPanState,
6083
+ currentNodePosition: currentNode ? { x: currentNode.x, y: currentNode.y } : null,
6084
+ existingDragOffset: dragOffsetRef.current
6085
+ });
6086
+ if (!dragPositionResult) {
6087
+ return;
6088
+ }
6089
+ dragOffsetRef.current = dragPositionResult.resolvedDragOffset;
6090
+ setNodeMapStruct(
6091
+ (prevNodeMapStruct) => updateDraggedNodePosition(
6092
+ prevNodeMapStruct,
6093
+ isDragging.id,
6094
+ dragPositionResult.adjustedPositionWithOffset
6095
+ )
6096
+ );
5837
6097
  },
5838
6098
  [isDragging, nodeMapStruct, parentZoomAndPanState]
5839
6099
  );
@@ -5959,9 +6219,9 @@ __export(PresetPalettes_exports, {
5959
6219
  default: () => PresetPalettes_default
5960
6220
  });
5961
6221
  init_define_global();
5962
- var defaultImport117 = __toESM(require("@splunk/visualization-color-palettes/editors/PresetPalettes"));
6222
+ var defaultImport118 = __toESM(require("@splunk/visualization-color-palettes/editors/PresetPalettes"));
5963
6223
  __reExport(PresetPalettes_exports, require("@splunk/visualization-color-palettes/editors/PresetPalettes"));
5964
- var PresetPalettes_default = "default" in defaultImport117 ? defaultImport117.default : defaultImport117;
6224
+ var PresetPalettes_default = "default" in defaultImport118 ? defaultImport118.default : defaultImport118;
5965
6225
 
5966
6226
  // esm-externals:@splunk/visualization-icons
5967
6227
  var visualization_icons_exports = {};
@@ -5969,9 +6229,9 @@ __export(visualization_icons_exports, {
5969
6229
  default: () => visualization_icons_default
5970
6230
  });
5971
6231
  init_define_global();
5972
- var defaultImport118 = __toESM(require("@splunk/visualization-icons"));
6232
+ var defaultImport119 = __toESM(require("@splunk/visualization-icons"));
5973
6233
  __reExport(visualization_icons_exports, require("@splunk/visualization-icons"));
5974
- var visualization_icons_default = "default" in defaultImport118 ? defaultImport118.default : defaultImport118;
6234
+ var visualization_icons_default = "default" in defaultImport119 ? defaultImport119.default : defaultImport119;
5975
6235
 
5976
6236
  // esm-externals:@splunk/visualization-icons/placeholders
5977
6237
  var placeholders_exports = {};
@@ -5979,9 +6239,9 @@ __export(placeholders_exports, {
5979
6239
  default: () => placeholders_default
5980
6240
  });
5981
6241
  init_define_global();
5982
- var defaultImport119 = __toESM(require("@splunk/visualization-icons/placeholders"));
6242
+ var defaultImport120 = __toESM(require("@splunk/visualization-icons/placeholders"));
5983
6243
  __reExport(placeholders_exports, require("@splunk/visualization-icons/placeholders"));
5984
- var placeholders_default = "default" in defaultImport119 ? defaultImport119.default : defaultImport119;
6244
+ var placeholders_default = "default" in defaultImport120 ? defaultImport120.default : defaultImport120;
5985
6245
 
5986
6246
  // src/common/utils/configUtils.ts
5987
6247
  init_define_global();
@@ -5992,9 +6252,9 @@ __export(configUtils_exports, {
5992
6252
  default: () => configUtils_default
5993
6253
  });
5994
6254
  init_define_global();
5995
- var defaultImport120 = __toESM(require("@splunk/visualizations-shared/configUtils"));
6255
+ var defaultImport121 = __toESM(require("@splunk/visualizations-shared/configUtils"));
5996
6256
  __reExport(configUtils_exports, require("@splunk/visualizations-shared/configUtils"));
5997
- var configUtils_default = "default" in defaultImport120 ? defaultImport120.default : defaultImport120;
6257
+ var configUtils_default = "default" in defaultImport121 ? defaultImport121.default : defaultImport121;
5998
6258
 
5999
6259
  // src/common/utils/configUtils.ts
6000
6260
  function enhanceConfig(vizConfig) {
@@ -6014,9 +6274,9 @@ __export(pick_exports, {
6014
6274
  default: () => pick_default
6015
6275
  });
6016
6276
  init_define_global();
6017
- var defaultImport121 = __toESM(require("@splunk/themes/pick"));
6277
+ var defaultImport122 = __toESM(require("@splunk/themes/pick"));
6018
6278
  __reExport(pick_exports, require("@splunk/themes/pick"));
6019
- var pick_default = "default" in defaultImport121 ? defaultImport121.default : defaultImport121;
6279
+ var pick_default = "default" in defaultImport122 ? defaultImport122.default : defaultImport122;
6020
6280
 
6021
6281
  // src/common/ThemedDefaults.tsx
6022
6282
  var defaultBackgroundColor = (props) => pick_default({
@@ -6412,6 +6672,7 @@ var editorConfig = [
6412
6672
  editorProps: {
6413
6673
  min: 0,
6414
6674
  step: 0.1,
6675
+ max: 1,
6415
6676
  help: (0, i18n_exports._)(
6416
6677
  "Strength of spring force between linked nodes. Higher value makes link lengths closer to linkDistance."
6417
6678
  ),