@splunk/visualizations 27.0.0 → 27.2.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 (89) hide show
  1. package/Area.config.js +269 -122
  2. package/Area.config.js.map +4 -4
  3. package/Area.js +1065 -209
  4. package/Area.js.map +4 -4
  5. package/Bar.config.js +266 -82
  6. package/Bar.config.js.map +4 -4
  7. package/Bar.js +1065 -171
  8. package/Bar.js.map +4 -4
  9. package/Bubble.config.js +127 -1
  10. package/Bubble.config.js.map +4 -4
  11. package/Bubble.js +323 -80
  12. package/Bubble.js.map +4 -4
  13. package/ChoroplethSvg.js +64 -37
  14. package/ChoroplethSvg.js.map +4 -4
  15. package/Column.config.js +271 -82
  16. package/Column.config.js.map +4 -4
  17. package/Column.js +1070 -171
  18. package/Column.js.map +4 -4
  19. package/Ellipse.js +44 -14
  20. package/Ellipse.js.map +4 -4
  21. package/Events.js +172 -527
  22. package/Events.js.map +4 -4
  23. package/FillerGauge.js +45 -15
  24. package/FillerGauge.js.map +4 -4
  25. package/Image.js +42 -12
  26. package/Image.js.map +4 -4
  27. package/Line.config.js +271 -119
  28. package/Line.config.js.map +4 -4
  29. package/Line.js +1067 -206
  30. package/Line.js.map +4 -4
  31. package/LinkGraph.js +584 -545
  32. package/LinkGraph.js.map +4 -4
  33. package/Map.config.js +114 -72
  34. package/Map.config.js.map +4 -4
  35. package/Map.js +177 -94
  36. package/Map.js.map +4 -4
  37. package/Markdown.js +46 -16
  38. package/Markdown.js.map +4 -4
  39. package/MarkerGauge.js +42 -12
  40. package/MarkerGauge.js.map +4 -4
  41. package/ParallelCoordinates.js +123 -87
  42. package/ParallelCoordinates.js.map +4 -4
  43. package/Pie.js +198 -81
  44. package/Pie.js.map +4 -4
  45. package/Punchcard.js +241 -38
  46. package/Punchcard.js.map +4 -4
  47. package/Rectangle.js +56 -26
  48. package/Rectangle.js.map +4 -4
  49. package/Sankey.js +68 -38
  50. package/Sankey.js.map +4 -4
  51. package/Scatter.config.js +127 -1
  52. package/Scatter.config.js.map +4 -4
  53. package/Scatter.js +323 -80
  54. package/Scatter.js.map +4 -4
  55. package/SingleValue.config.js +43 -67
  56. package/SingleValue.config.js.map +4 -4
  57. package/SingleValue.js +1434 -1356
  58. package/SingleValue.js.map +4 -4
  59. package/SingleValueBasic.js +1 -1
  60. package/SingleValueBasic.js.map +3 -3
  61. package/SingleValueIcon.config.js +45 -69
  62. package/SingleValueIcon.config.js.map +4 -4
  63. package/SingleValueIcon.js +1739 -1407
  64. package/SingleValueIcon.js.map +4 -4
  65. package/SingleValueRadial.config.js +43 -67
  66. package/SingleValueRadial.config.js.map +4 -4
  67. package/SingleValueRadial.js +1366 -1273
  68. package/SingleValueRadial.js.map +4 -4
  69. package/SparkLine.js +1 -1
  70. package/SparkLine.js.map +3 -3
  71. package/TRELLIS.md +16 -15
  72. package/Table.js +65 -30
  73. package/Table.js.map +4 -4
  74. package/Timeline.config.js +418 -0
  75. package/Timeline.config.js.map +7 -0
  76. package/Timeline.js +3074 -0
  77. package/Timeline.js.map +7 -0
  78. package/common/Charting.js +133 -27
  79. package/common/Charting.js.map +4 -4
  80. package/common/OptionsDoc.js +8 -3
  81. package/common/OptionsDoc.js.map +2 -2
  82. package/common/utils/mapUtils.js.map +2 -2
  83. package/common/utils/singleValueUtils.js +26 -15
  84. package/common/utils/singleValueUtils.js.map +2 -2
  85. package/common/utils/trellisUtils.js +41 -1
  86. package/common/utils/trellisUtils.js.map +2 -2
  87. package/common/withDashboardViz.js +42 -12
  88. package/common/withDashboardViz.js.map +4 -4
  89. package/package.json +49 -38
package/Punchcard.js CHANGED
@@ -60,7 +60,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
60
60
  ));
61
61
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
62
62
 
63
- // src/Punchcard/Punchcard.ts
63
+ // src/Punchcard/index.ts
64
64
  var Punchcard_exports = {};
65
65
  __export(Punchcard_exports, {
66
66
  PurePunchcard: () => PurePunchcard,
@@ -762,7 +762,7 @@ var withFixedSizeContainer = (Viz) => {
762
762
  FixSizeItem,
763
763
  {
764
764
  "data-test": "fix-size-item",
765
- "data-splunk-visualization-version": "27.0.0 - 9bf093b7d",
765
+ "data-splunk-visualization-version": "27.2.0 - 2e7eda8d4",
766
766
  width,
767
767
  height,
768
768
  backgroundColor
@@ -828,7 +828,7 @@ var Cover = styled_components_default.div`
828
828
  bottom: 0;
829
829
  `;
830
830
  var Blocker = styled_components_default.div.attrs({
831
- "data-splunk-visualization-version": "27.0.0 - 9bf093b7d"
831
+ "data-splunk-visualization-version": "27.2.0 - 2e7eda8d4"
832
832
  })`
833
833
  position: relative;
834
834
  width: 100%;
@@ -1315,6 +1315,25 @@ var getFeatureFlag = (context, flagName) => {
1315
1315
  return false;
1316
1316
  };
1317
1317
 
1318
+ // esm-externals:@splunk/visualizations-shared/trellisUtils
1319
+ var trellisUtils_exports = {};
1320
+ __export(trellisUtils_exports, {
1321
+ default: () => trellisUtils_default
1322
+ });
1323
+ var defaultImport29 = __toESM(require("@splunk/visualizations-shared/trellisUtils"));
1324
+ __reExport(trellisUtils_exports, require("@splunk/visualizations-shared/trellisUtils"));
1325
+ var trellisUtils_default = "default" in defaultImport29 ? defaultImport29.default : defaultImport29;
1326
+
1327
+ // src/common/utils/trellisUtils.ts
1328
+ var turnOffLegendDisplayWhenTrellisIsOn = (isTrellisOn, options) => {
1329
+ if (isTrellisOn && !options.legendDisplay) {
1330
+ return {
1331
+ legendDisplay: "off"
1332
+ };
1333
+ }
1334
+ return {};
1335
+ };
1336
+
1318
1337
  // src/common/withDashboardViz.tsx
1319
1338
  var withDashboardViz = (opts) => {
1320
1339
  const {
@@ -1322,6 +1341,8 @@ var withDashboardViz = (opts) => {
1322
1341
  vizConfig,
1323
1342
  computeVizProps: computeVizProps2 = () => {
1324
1343
  },
1344
+ computeVizPropsBeforeEval = () => {
1345
+ },
1325
1346
  disableEditModeCover,
1326
1347
  useIconPlaceholder
1327
1348
  } = opts;
@@ -1371,14 +1392,26 @@ var withDashboardViz = (opts) => {
1371
1392
  const isDownsamplingEnabledByFeatureFlag = Boolean(
1372
1393
  featureFlagContext == null ? void 0 : featureFlagContext.visualizations_enableDownsampling
1373
1394
  );
1395
+ const isTrellisFeatureFlagOn = Boolean(
1396
+ featureFlagContext && featureFlagContext.visualizations_enableTrellis
1397
+ );
1398
+ const isTrellisOn = isTrellisFeatureFlagOn && ((_a = vizConfig == null ? void 0 : vizConfig.supports) == null ? void 0 : _a.includes("trellis" /* TRELLIS */)) && (options == null ? void 0 : options.splitByLayout) === "trellis" /* TRELLIS */;
1374
1399
  const isMounted = react_exports.useRef(true);
1375
- const optionsToEvaluate = react_exports.useMemo(
1376
- () => ({
1400
+ const optionsToEvaluate = react_exports.useMemo(() => {
1401
+ var _a2;
1402
+ const legendDisplay = turnOffLegendDisplayWhenTrellisIsOn(isTrellisOn, options);
1403
+ const computedOptions = (_a2 = computeVizPropsBeforeEval(options)) != null ? _a2 : {};
1404
+ return {
1377
1405
  context: (0, lodash_exports.defaultsDeep)({}, context, vizConfig.defaultContext),
1378
- options: (0, hocUtils_exports.deepMergeWithArrayPrimitiveOverrides)({}, options, defaultOptions)
1379
- }),
1380
- [options, context]
1381
- );
1406
+ options: (0, hocUtils_exports.deepMergeWithArrayPrimitiveOverrides)(
1407
+ {},
1408
+ legendDisplay,
1409
+ computedOptions,
1410
+ options,
1411
+ defaultOptions
1412
+ )
1413
+ };
1414
+ }, [isTrellisOn, options, context]);
1382
1415
  const [threshold, setThreshold] = react_exports.useState(Number(width));
1383
1416
  const onDownsamplingThresholdChange = react_exports.useCallback((newThreshold) => {
1384
1417
  setThreshold(newThreshold);
@@ -1459,11 +1492,8 @@ var withDashboardViz = (opts) => {
1459
1492
  useAsyncEvaluatedOptions
1460
1493
  ]);
1461
1494
  const evaluatedOptionsToUse = !useAsyncEvaluatedOptions ? evaluatedOptions : evaluatedOptionsAsync;
1462
- const isTrellisFeatureFlagOn = Boolean(
1463
- featureFlagContext && featureFlagContext.visualizations_enableTrellis
1464
- );
1465
1495
  let clonedEvaluatedOptions = evaluatedOptionsToUse;
1466
- if (isTrellisFeatureFlagOn && ((_a = vizConfig == null ? void 0 : vizConfig.supports) == null ? void 0 : _a.includes("trellis" /* TRELLIS */)) && (clonedEvaluatedOptions == null ? void 0 : clonedEvaluatedOptions.splitByLayout) === "trellis" /* TRELLIS */) {
1496
+ if (isTrellisOn) {
1467
1497
  clonedEvaluatedOptions = __spreadProps(__spreadValues({}, evaluatedOptionsToUse), {
1468
1498
  backgroundColor: clonedEvaluatedOptions == null ? void 0 : clonedEvaluatedOptions.trellisBackgroundColor
1469
1499
  });
@@ -1574,18 +1604,27 @@ var types_exports = {};
1574
1604
  __export(types_exports, {
1575
1605
  default: () => types_default
1576
1606
  });
1577
- var defaultImport29 = __toESM(require("@splunk/visualization-encoding/utils/types"));
1607
+ var defaultImport30 = __toESM(require("@splunk/visualization-encoding/utils/types"));
1578
1608
  __reExport(types_exports, require("@splunk/visualization-encoding/utils/types"));
1579
- var types_default = "default" in defaultImport29 ? defaultImport29.default : defaultImport29;
1609
+ var types_default = "default" in defaultImport30 ? defaultImport30.default : defaultImport30;
1610
+
1611
+ // esm-externals:@splunk/ui-utils/keyboard
1612
+ var keyboard_exports = {};
1613
+ __export(keyboard_exports, {
1614
+ default: () => keyboard_default
1615
+ });
1616
+ var defaultImport31 = __toESM(require("@splunk/ui-utils/keyboard"));
1617
+ __reExport(keyboard_exports, require("@splunk/ui-utils/keyboard"));
1618
+ var keyboard_default = "default" in defaultImport31 ? defaultImport31.default : defaultImport31;
1580
1619
 
1581
1620
  // esm-externals:d3-scale
1582
1621
  var d3_scale_exports = {};
1583
1622
  __export(d3_scale_exports, {
1584
1623
  default: () => d3_scale_default
1585
1624
  });
1586
- var defaultImport30 = __toESM(require("d3-scale"));
1625
+ var defaultImport32 = __toESM(require("d3-scale"));
1587
1626
  __reExport(d3_scale_exports, require("d3-scale"));
1588
- var d3_scale_default = "default" in defaultImport30 ? defaultImport30.default : defaultImport30;
1627
+ var d3_scale_default = "default" in defaultImport32 ? defaultImport32.default : defaultImport32;
1589
1628
 
1590
1629
  // src/Punchcard/PurePunchcard/src/utils/punchcardUtils.ts
1591
1630
  var AXIS_ORIENTATION_TYPES = /* @__PURE__ */ ((AXIS_ORIENTATION_TYPES2) => {
@@ -1777,42 +1816,144 @@ var truncateAxisLabelText = ({
1777
1816
  }
1778
1817
  return `${label.slice(0, endMarker)}...`;
1779
1818
  };
1819
+ var getBubbleAccessibleName = ({ categoryValue, xValue, yValue, sizeValue }) => {
1820
+ if (sizeValue) {
1821
+ return categoryValue ? `Category: ${categoryValue}, X: ${xValue}, Y: ${yValue}, Size: ${sizeValue}` : `X: ${xValue}, Y: ${yValue}, Size: ${sizeValue}`;
1822
+ }
1823
+ return `There's no data for point: X: ${xValue}, Y: ${yValue}`;
1824
+ };
1825
+ var addNullValuesToRowData = ({ rowData, uniqX }) => {
1826
+ const newRowData = uniqX.flatMap((singleX) => {
1827
+ const indexesOfSingleXInRowData = rowData.rowXValues.map((element, index) => element === singleX ? index : -1).filter((index) => index !== -1);
1828
+ if (indexesOfSingleXInRowData.length === 0) {
1829
+ return {
1830
+ rowXValues: singleX,
1831
+ rowSizeValues: null,
1832
+ rowCategoryValues: null,
1833
+ rowColorValues: null,
1834
+ rowFillOpacityValues: null,
1835
+ rowRadiusValues: null
1836
+ };
1837
+ }
1838
+ return indexesOfSingleXInRowData.map((indexOfSingleXInRowData) => {
1839
+ return {
1840
+ rowXValues: singleX,
1841
+ rowSizeValues: rowData.rowSizeValues[indexOfSingleXInRowData],
1842
+ rowCategoryValues: rowData.rowCategoryValues[indexOfSingleXInRowData],
1843
+ rowColorValues: rowData.rowColorValues[indexOfSingleXInRowData],
1844
+ rowFillOpacityValues: rowData.rowFillOpacityValues[indexOfSingleXInRowData],
1845
+ rowRadiusValues: rowData.rowRadiusValues[indexOfSingleXInRowData]
1846
+ };
1847
+ });
1848
+ });
1849
+ return newRowData.reduce(
1850
+ (acc, obj) => {
1851
+ Object.keys(obj).forEach((key) => {
1852
+ acc[key].push(obj[key]);
1853
+ });
1854
+ return acc;
1855
+ },
1856
+ {
1857
+ rowXValues: [],
1858
+ rowSizeValues: [],
1859
+ rowCategoryValues: [],
1860
+ rowColorValues: [],
1861
+ rowFillOpacityValues: [],
1862
+ rowRadiusValues: [],
1863
+ rowSizeScale: rowData.rowSizeScale
1864
+ }
1865
+ );
1866
+ };
1867
+ var getElementToFocus = ({
1868
+ category,
1869
+ bubbleSizes,
1870
+ x,
1871
+ y,
1872
+ uniqX,
1873
+ uniqY,
1874
+ selectedX,
1875
+ selectedY,
1876
+ selectedCategory,
1877
+ key
1878
+ }) => {
1879
+ const elementsByColumnsWithValues = x.map((el, i) => {
1880
+ var _a;
1881
+ return {
1882
+ x: el,
1883
+ y: y[i],
1884
+ category: (_a = category[i]) != null ? _a : null,
1885
+ size: bubbleSizes[i]
1886
+ };
1887
+ });
1888
+ const elementsByColumns = uniqX.flatMap(
1889
+ (uX) => uniqY.flatMap((uY) => {
1890
+ const indexesOfElement = elementsByColumnsWithValues.map((el, index) => el.x === uX && el.y === uY ? index : -1).filter((index) => index !== -1);
1891
+ if (indexesOfElement.length > 0) {
1892
+ return indexesOfElement.map((indexOfElement) => elementsByColumnsWithValues[indexOfElement]);
1893
+ }
1894
+ return {
1895
+ x: uX,
1896
+ y: uY,
1897
+ size: null,
1898
+ category: null
1899
+ };
1900
+ })
1901
+ );
1902
+ const elementsByRows = uniqY.flatMap((uniqYEl) => elementsByColumns.filter((el) => el.y === uniqYEl));
1903
+ const currentElIndexInColumns = elementsByColumns.findIndex(
1904
+ (el) => el.x === selectedX && el.y === selectedY && el.category === selectedCategory
1905
+ );
1906
+ const currentElIndexInRows = elementsByRows.findIndex(
1907
+ (el) => el.x === selectedX && el.y === selectedY && el.category === selectedCategory
1908
+ );
1909
+ let newEl;
1910
+ if (key === "down") {
1911
+ newEl = elementsByColumns[currentElIndexInColumns + 1];
1912
+ } else if (key === "up") {
1913
+ newEl = elementsByColumns[currentElIndexInColumns - 1];
1914
+ } else if (key === "right") {
1915
+ newEl = elementsByRows[currentElIndexInRows + 1];
1916
+ } else if (key === "left") {
1917
+ newEl = elementsByRows[currentElIndexInRows - 1];
1918
+ }
1919
+ return newEl;
1920
+ };
1780
1921
 
1781
1922
  // esm-externals:lodash/findIndex
1782
1923
  var findIndex_exports = {};
1783
1924
  __export(findIndex_exports, {
1784
1925
  default: () => findIndex_default
1785
1926
  });
1786
- var defaultImport31 = __toESM(require("lodash/findIndex"));
1927
+ var defaultImport33 = __toESM(require("lodash/findIndex"));
1787
1928
  __reExport(findIndex_exports, require("lodash/findIndex"));
1788
- var findIndex_default = "default" in defaultImport31 ? defaultImport31.default : defaultImport31;
1929
+ var findIndex_default = "default" in defaultImport33 ? defaultImport33.default : defaultImport33;
1789
1930
 
1790
1931
  // esm-externals:lodash/find
1791
1932
  var find_exports = {};
1792
1933
  __export(find_exports, {
1793
1934
  default: () => find_default
1794
1935
  });
1795
- var defaultImport32 = __toESM(require("lodash/find"));
1936
+ var defaultImport34 = __toESM(require("lodash/find"));
1796
1937
  __reExport(find_exports, require("lodash/find"));
1797
- var find_default = "default" in defaultImport32 ? defaultImport32.default : defaultImport32;
1938
+ var find_default = "default" in defaultImport34 ? defaultImport34.default : defaultImport34;
1798
1939
 
1799
1940
  // esm-externals:lodash/sortBy
1800
1941
  var sortBy_exports = {};
1801
1942
  __export(sortBy_exports, {
1802
1943
  default: () => sortBy_default
1803
1944
  });
1804
- var defaultImport33 = __toESM(require("lodash/sortBy"));
1945
+ var defaultImport35 = __toESM(require("lodash/sortBy"));
1805
1946
  __reExport(sortBy_exports, require("lodash/sortBy"));
1806
- var sortBy_default = "default" in defaultImport33 ? defaultImport33.default : defaultImport33;
1947
+ var sortBy_default = "default" in defaultImport35 ? defaultImport35.default : defaultImport35;
1807
1948
 
1808
1949
  // esm-externals:lodash/flattenDeep
1809
1950
  var flattenDeep_exports = {};
1810
1951
  __export(flattenDeep_exports, {
1811
1952
  default: () => flattenDeep_default
1812
1953
  });
1813
- var defaultImport34 = __toESM(require("lodash/flattenDeep"));
1954
+ var defaultImport36 = __toESM(require("lodash/flattenDeep"));
1814
1955
  __reExport(flattenDeep_exports, require("lodash/flattenDeep"));
1815
- var flattenDeep_default = "default" in defaultImport34 ? defaultImport34.default : defaultImport34;
1956
+ var flattenDeep_default = "default" in defaultImport36 ? defaultImport36.default : defaultImport36;
1816
1957
 
1817
1958
  // src/Punchcard/PurePunchcard/src/utils/sortUtils.js
1818
1959
  var TIME_RANGES = {
@@ -2067,7 +2208,7 @@ var BubbleLabelText = styled_components_default.text`
2067
2208
  light: variables_default.white
2068
2209
  },
2069
2210
  prisma: variables_default.contentColorActive
2070
- })(props)}};
2211
+ })(props)};
2071
2212
  font-size: ${(props) => props.hover ? "12px" : "10px"};
2072
2213
  font-weight: ${(props) => props.hover ? 500 : "normal"};
2073
2214
  text-anchor: middle;
@@ -2089,11 +2230,14 @@ var PunchcardBubble = (props) => {
2089
2230
  pulsate,
2090
2231
  value,
2091
2232
  r,
2092
- handlePointClick
2233
+ handlePointClick,
2234
+ accessibleLabel,
2235
+ tabindex
2093
2236
  } = props;
2094
2237
  const outline = value < 0;
2095
2238
  const showPulsateBubble = pulsate && !muted && !hover;
2096
2239
  const displayLabel = hover || showBubbleLabel && r >= MIN_BUBBLE_SIZE_TO_DISPLAY_LABEL;
2240
+ const hasData = !!value;
2097
2241
  let bubbleLabelValueText = value <= MAX_DISPLAYABLE_VALUE ? (0, numberUtils_exports.formatNumber)(value, 0, { useTrendUnits: true }) : VALUE_OVERFLOW_TEXT;
2098
2242
  if (hover) {
2099
2243
  bubbleLabelValueText = (0, numberUtils_exports.formatNumber)(value, 2);
@@ -2103,9 +2247,12 @@ var PunchcardBubble = (props) => {
2103
2247
  {
2104
2248
  "data-test": "bubble",
2105
2249
  muted,
2106
- onMouseEnter: handleMouseEnter,
2107
- onMouseLeave: handleMouseLeave,
2108
- onClick: () => handlePointClick(value)
2250
+ onMouseEnter: hasData ? handleMouseEnter : void 0,
2251
+ onMouseLeave: hasData ? handleMouseLeave : void 0,
2252
+ onClick: () => hasData && handlePointClick(value),
2253
+ onFocus: handleMouseEnter,
2254
+ onBlur: handleMouseLeave,
2255
+ tabIndex: tabindex
2109
2256
  },
2110
2257
  showPulsateBubble && /* @__PURE__ */ react_exports.createElement(PulsateBubble, { cx, cy, r, color, outline: true, hover: null }),
2111
2258
  /* @__PURE__ */ react_exports.createElement(
@@ -2120,7 +2267,18 @@ var PunchcardBubble = (props) => {
2120
2267
  outline
2121
2268
  }
2122
2269
  ),
2123
- /* @__PURE__ */ react_exports.createElement(BubbleLabelText, { x: cx, y: cy, hover, outline, displayLabel }, bubbleLabelValueText)
2270
+ /* @__PURE__ */ react_exports.createElement(
2271
+ BubbleLabelText,
2272
+ {
2273
+ x: cx,
2274
+ y: cy,
2275
+ hover,
2276
+ outline,
2277
+ displayLabel,
2278
+ "aria-label": accessibleLabel
2279
+ },
2280
+ hasData ? bubbleLabelValueText : (0, i18n_exports._)("Null")
2281
+ )
2124
2282
  );
2125
2283
  };
2126
2284
  var propTypes4 = {
@@ -2136,7 +2294,9 @@ var propTypes4 = {
2136
2294
  pulsate: prop_types_exports.bool,
2137
2295
  value: prop_types_exports.number,
2138
2296
  r: prop_types_exports.number,
2139
- handlePointClick: prop_types_exports.func
2297
+ handlePointClick: prop_types_exports.func,
2298
+ accessibleLabel: prop_types_exports.string,
2299
+ tabindex: prop_types_exports.number
2140
2300
  };
2141
2301
  var defaultProps2 = {
2142
2302
  showBubbleLabel: true,
@@ -2154,7 +2314,9 @@ var defaultProps2 = {
2154
2314
  r: 1,
2155
2315
  value: void 0,
2156
2316
  handlePointClick: () => {
2157
- }
2317
+ },
2318
+ accessibleLabel: "",
2319
+ tabindex: -1
2158
2320
  };
2159
2321
  PunchcardBubble.propTypes = propTypes4;
2160
2322
  PunchcardBubble.defaultProps = defaultProps2;
@@ -2178,6 +2340,7 @@ var PunchcardRow = (props) => {
2178
2340
  size: size2,
2179
2341
  x,
2180
2342
  xScale,
2343
+ yIndex,
2181
2344
  yPosition,
2182
2345
  yValue,
2183
2346
  handlePointClick
@@ -2199,6 +2362,7 @@ var PunchcardRow = (props) => {
2199
2362
  });
2200
2363
  const muted = isSomethingSelected({ selectedX, selectedY, selectedCategory }) && !hover;
2201
2364
  const showBubbleLabel = showBubbleLabels === "all" /* ALL */ || showBubbleLabels === "max" /* MAX */ && maxSizeValue === sizeValue;
2365
+ const accessibleLabel = getBubbleAccessibleName({ categoryValue, xValue, yValue, sizeValue });
2202
2366
  return /* @__PURE__ */ react_exports.createElement(
2203
2367
  PunchcardBubble_default,
2204
2368
  {
@@ -2217,7 +2381,9 @@ var PunchcardRow = (props) => {
2217
2381
  pulsate: showMaxValuePulsation && sizeValue === maxSizeValue,
2218
2382
  value: sizeValue,
2219
2383
  r,
2220
- handlePointClick
2384
+ handlePointClick,
2385
+ accessibleLabel,
2386
+ tabindex: hover || !muted && yIndex === 0 && index === 0 ? 0 : -1
2221
2387
  }
2222
2388
  );
2223
2389
  }));
@@ -2238,6 +2404,7 @@ var propTypes5 = {
2238
2404
  size: prop_types_exports.arrayOf(prop_types_exports.number),
2239
2405
  x: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
2240
2406
  xScale: prop_types_exports.func,
2407
+ yIndex: prop_types_exports.number,
2241
2408
  yPosition: prop_types_exports.number,
2242
2409
  yValue: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2243
2410
  handlePointClick: prop_types_exports.func
@@ -2261,6 +2428,7 @@ var defaultProps3 = {
2261
2428
  // eslint-disable-next-line react/default-props-match-prop-types
2262
2429
  x: null,
2263
2430
  xScale: null,
2431
+ yIndex: null,
2264
2432
  yPosition: null,
2265
2433
  yValue: null,
2266
2434
  handlePointClick: () => {
@@ -2294,6 +2462,7 @@ var PunchcardChartArea = (props) => {
2294
2462
  selectedX,
2295
2463
  selectedY,
2296
2464
  size: size2,
2465
+ uniqX,
2297
2466
  x,
2298
2467
  xScale,
2299
2468
  y,
@@ -2318,7 +2487,8 @@ var PunchcardChartArea = (props) => {
2318
2487
  maxBubbleRadius,
2319
2488
  minBubbleRadius
2320
2489
  });
2321
- return /* @__PURE__ */ react_exports.createElement("g", null, Object.entries(dataByRows).map(([row, rowData]) => {
2490
+ return /* @__PURE__ */ react_exports.createElement("g", null, Object.entries(dataByRows).map(([row, rowData], index) => {
2491
+ const yPosition = yScale(row);
2322
2492
  const {
2323
2493
  rowXValues,
2324
2494
  rowSizeValues,
@@ -2327,8 +2497,7 @@ var PunchcardChartArea = (props) => {
2327
2497
  rowFillOpacityValues,
2328
2498
  rowSizeScale,
2329
2499
  rowRadiusValues
2330
- } = rowData;
2331
- const yPosition = yScale(row);
2500
+ } = addNullValuesToRowData({ rowData, uniqX });
2332
2501
  return /* @__PURE__ */ react_exports.createElement(
2333
2502
  PunchcardRow_default,
2334
2503
  {
@@ -2349,6 +2518,7 @@ var PunchcardChartArea = (props) => {
2349
2518
  size: rowSizeValues,
2350
2519
  x: rowXValues,
2351
2520
  xScale,
2521
+ yIndex: index,
2352
2522
  yPosition,
2353
2523
  yValue: row,
2354
2524
  handlePointClick
@@ -2378,6 +2548,7 @@ var propTypes6 = {
2378
2548
  selectedX: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2379
2549
  selectedY: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2380
2550
  size: prop_types_exports.arrayOf(prop_types_exports.number).isRequired,
2551
+ uniqX: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
2381
2552
  x: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
2382
2553
  xScale: prop_types_exports.func,
2383
2554
  y: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
@@ -2410,6 +2581,8 @@ var defaultProps4 = {
2410
2581
  // eslint-disable-next-line react/default-props-match-prop-types
2411
2582
  size: null,
2412
2583
  // eslint-disable-next-line react/default-props-match-prop-types
2584
+ uniqX: null,
2585
+ // eslint-disable-next-line react/default-props-match-prop-types
2413
2586
  x: null,
2414
2587
  xScale: null,
2415
2588
  // eslint-disable-next-line react/default-props-match-prop-types
@@ -2708,6 +2881,33 @@ var Punchcard = (props) => {
2708
2881
  }
2709
2882
  });
2710
2883
  };
2884
+ const chartRef = react_exports.useRef();
2885
+ const handleKeyDown = (e) => {
2886
+ var _a, _b;
2887
+ const key = (0, keyboard_exports.keycode)(e);
2888
+ const elementToFocus = getElementToFocus({
2889
+ category,
2890
+ bubbleSizes,
2891
+ x,
2892
+ y,
2893
+ uniqX,
2894
+ uniqY,
2895
+ selectedX,
2896
+ selectedY,
2897
+ selectedCategory,
2898
+ key
2899
+ });
2900
+ if (!elementToFocus) {
2901
+ return;
2902
+ }
2903
+ const ariaLabel = getBubbleAccessibleName({
2904
+ categoryValue: elementToFocus.category,
2905
+ xValue: elementToFocus.x,
2906
+ yValue: elementToFocus.y,
2907
+ sizeValue: elementToFocus.size
2908
+ });
2909
+ (_b = (_a = chartRef.current.querySelector(`[aria-label="${ariaLabel}"]`)) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.focus();
2910
+ };
2711
2911
  const renderVisualization = () => {
2712
2912
  if (!containerWidth || !containerHeight) {
2713
2913
  return null;
@@ -2741,7 +2941,9 @@ var Punchcard = (props) => {
2741
2941
  {
2742
2942
  "data-test": "punchcard-container",
2743
2943
  width: containerWidth,
2744
- height: containerHeight
2944
+ height: containerHeight,
2945
+ ref: chartRef,
2946
+ onKeyDown: handleKeyDown
2745
2947
  },
2746
2948
  /* @__PURE__ */ react_exports.createElement(PunchcardSVG, { width: containerWidth, height: containerHeight }, /* @__PURE__ */ react_exports.createElement(
2747
2949
  PunchcardGridLines_default,
@@ -2815,6 +3017,7 @@ var Punchcard = (props) => {
2815
3017
  selectedX,
2816
3018
  selectedY,
2817
3019
  size: bubbleSizes,
3020
+ uniqX,
2818
3021
  x,
2819
3022
  xScale: xPositionScale,
2820
3023
  y,