@splunk/visualizations 27.1.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 (52) hide show
  1. package/Area.js +2 -2
  2. package/Bar.js +2 -2
  3. package/Bubble.js +2 -2
  4. package/ChoroplethSvg.js +6 -9
  5. package/ChoroplethSvg.js.map +3 -3
  6. package/Column.js +2 -2
  7. package/Ellipse.js +2 -2
  8. package/Events.js +106 -491
  9. package/Events.js.map +4 -4
  10. package/FillerGauge.js +3 -3
  11. package/FillerGauge.js.map +3 -3
  12. package/Image.js +2 -2
  13. package/Line.js +2 -2
  14. package/LinkGraph.js +23 -18
  15. package/LinkGraph.js.map +2 -2
  16. package/Map.config.js +114 -72
  17. package/Map.config.js.map +4 -4
  18. package/Map.js +139 -86
  19. package/Map.js.map +4 -4
  20. package/Markdown.js +2 -2
  21. package/MarkerGauge.js +2 -2
  22. package/ParallelCoordinates.js +3 -3
  23. package/ParallelCoordinates.js.map +3 -3
  24. package/Pie.js +2 -2
  25. package/Punchcard.js +199 -26
  26. package/Punchcard.js.map +4 -4
  27. package/Rectangle.js +2 -2
  28. package/Sankey.js +2 -2
  29. package/Scatter.js +2 -2
  30. package/SingleValue.js +19 -9
  31. package/SingleValue.js.map +3 -3
  32. package/SingleValueBasic.js +1 -1
  33. package/SingleValueBasic.js.map +3 -3
  34. package/SingleValueIcon.js +380 -117
  35. package/SingleValueIcon.js.map +4 -4
  36. package/SingleValueRadial.js +16 -9
  37. package/SingleValueRadial.js.map +3 -3
  38. package/SparkLine.js +1 -1
  39. package/SparkLine.js.map +3 -3
  40. package/Table.js +15 -10
  41. package/Table.js.map +3 -3
  42. package/Timeline.config.js +418 -0
  43. package/Timeline.config.js.map +7 -0
  44. package/Timeline.js +3074 -0
  45. package/Timeline.js.map +7 -0
  46. package/common/OptionsDoc.js +2 -2
  47. package/common/OptionsDoc.js.map +1 -1
  48. package/common/utils/mapUtils.js.map +2 -2
  49. package/common/utils/singleValueUtils.js +18 -8
  50. package/common/utils/singleValueUtils.js.map +2 -2
  51. package/common/withDashboardViz.js +2 -2
  52. package/package.json +43 -31
package/Pie.js CHANGED
@@ -1556,7 +1556,7 @@ var withFixedSizeContainer = (Viz) => {
1556
1556
  FixSizeItem,
1557
1557
  {
1558
1558
  "data-test": "fix-size-item",
1559
- "data-splunk-visualization-version": "27.1.0 - fe8b048df",
1559
+ "data-splunk-visualization-version": "27.2.0 - 2e7eda8d4",
1560
1560
  width,
1561
1561
  height,
1562
1562
  backgroundColor
@@ -1622,7 +1622,7 @@ var Cover = styled_components_default.div`
1622
1622
  bottom: 0;
1623
1623
  `;
1624
1624
  var Blocker = styled_components_default.div.attrs({
1625
- "data-splunk-visualization-version": "27.1.0 - fe8b048df"
1625
+ "data-splunk-visualization-version": "27.2.0 - 2e7eda8d4"
1626
1626
  })`
1627
1627
  position: relative;
1628
1628
  width: 100%;
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.1.0 - fe8b048df",
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.1.0 - fe8b048df"
831
+ "data-splunk-visualization-version": "27.2.0 - 2e7eda8d4"
832
832
  })`
833
833
  position: relative;
834
834
  width: 100%;
@@ -1608,14 +1608,23 @@ var defaultImport30 = __toESM(require("@splunk/visualization-encoding/utils/type
1608
1608
  __reExport(types_exports, require("@splunk/visualization-encoding/utils/types"));
1609
1609
  var types_default = "default" in defaultImport30 ? defaultImport30.default : defaultImport30;
1610
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;
1619
+
1611
1620
  // esm-externals:d3-scale
1612
1621
  var d3_scale_exports = {};
1613
1622
  __export(d3_scale_exports, {
1614
1623
  default: () => d3_scale_default
1615
1624
  });
1616
- var defaultImport31 = __toESM(require("d3-scale"));
1625
+ var defaultImport32 = __toESM(require("d3-scale"));
1617
1626
  __reExport(d3_scale_exports, require("d3-scale"));
1618
- var d3_scale_default = "default" in defaultImport31 ? defaultImport31.default : defaultImport31;
1627
+ var d3_scale_default = "default" in defaultImport32 ? defaultImport32.default : defaultImport32;
1619
1628
 
1620
1629
  // src/Punchcard/PurePunchcard/src/utils/punchcardUtils.ts
1621
1630
  var AXIS_ORIENTATION_TYPES = /* @__PURE__ */ ((AXIS_ORIENTATION_TYPES2) => {
@@ -1807,42 +1816,144 @@ var truncateAxisLabelText = ({
1807
1816
  }
1808
1817
  return `${label.slice(0, endMarker)}...`;
1809
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
+ };
1810
1921
 
1811
1922
  // esm-externals:lodash/findIndex
1812
1923
  var findIndex_exports = {};
1813
1924
  __export(findIndex_exports, {
1814
1925
  default: () => findIndex_default
1815
1926
  });
1816
- var defaultImport32 = __toESM(require("lodash/findIndex"));
1927
+ var defaultImport33 = __toESM(require("lodash/findIndex"));
1817
1928
  __reExport(findIndex_exports, require("lodash/findIndex"));
1818
- var findIndex_default = "default" in defaultImport32 ? defaultImport32.default : defaultImport32;
1929
+ var findIndex_default = "default" in defaultImport33 ? defaultImport33.default : defaultImport33;
1819
1930
 
1820
1931
  // esm-externals:lodash/find
1821
1932
  var find_exports = {};
1822
1933
  __export(find_exports, {
1823
1934
  default: () => find_default
1824
1935
  });
1825
- var defaultImport33 = __toESM(require("lodash/find"));
1936
+ var defaultImport34 = __toESM(require("lodash/find"));
1826
1937
  __reExport(find_exports, require("lodash/find"));
1827
- var find_default = "default" in defaultImport33 ? defaultImport33.default : defaultImport33;
1938
+ var find_default = "default" in defaultImport34 ? defaultImport34.default : defaultImport34;
1828
1939
 
1829
1940
  // esm-externals:lodash/sortBy
1830
1941
  var sortBy_exports = {};
1831
1942
  __export(sortBy_exports, {
1832
1943
  default: () => sortBy_default
1833
1944
  });
1834
- var defaultImport34 = __toESM(require("lodash/sortBy"));
1945
+ var defaultImport35 = __toESM(require("lodash/sortBy"));
1835
1946
  __reExport(sortBy_exports, require("lodash/sortBy"));
1836
- var sortBy_default = "default" in defaultImport34 ? defaultImport34.default : defaultImport34;
1947
+ var sortBy_default = "default" in defaultImport35 ? defaultImport35.default : defaultImport35;
1837
1948
 
1838
1949
  // esm-externals:lodash/flattenDeep
1839
1950
  var flattenDeep_exports = {};
1840
1951
  __export(flattenDeep_exports, {
1841
1952
  default: () => flattenDeep_default
1842
1953
  });
1843
- var defaultImport35 = __toESM(require("lodash/flattenDeep"));
1954
+ var defaultImport36 = __toESM(require("lodash/flattenDeep"));
1844
1955
  __reExport(flattenDeep_exports, require("lodash/flattenDeep"));
1845
- var flattenDeep_default = "default" in defaultImport35 ? defaultImport35.default : defaultImport35;
1956
+ var flattenDeep_default = "default" in defaultImport36 ? defaultImport36.default : defaultImport36;
1846
1957
 
1847
1958
  // src/Punchcard/PurePunchcard/src/utils/sortUtils.js
1848
1959
  var TIME_RANGES = {
@@ -2097,7 +2208,7 @@ var BubbleLabelText = styled_components_default.text`
2097
2208
  light: variables_default.white
2098
2209
  },
2099
2210
  prisma: variables_default.contentColorActive
2100
- })(props)}};
2211
+ })(props)};
2101
2212
  font-size: ${(props) => props.hover ? "12px" : "10px"};
2102
2213
  font-weight: ${(props) => props.hover ? 500 : "normal"};
2103
2214
  text-anchor: middle;
@@ -2119,11 +2230,14 @@ var PunchcardBubble = (props) => {
2119
2230
  pulsate,
2120
2231
  value,
2121
2232
  r,
2122
- handlePointClick
2233
+ handlePointClick,
2234
+ accessibleLabel,
2235
+ tabindex
2123
2236
  } = props;
2124
2237
  const outline = value < 0;
2125
2238
  const showPulsateBubble = pulsate && !muted && !hover;
2126
2239
  const displayLabel = hover || showBubbleLabel && r >= MIN_BUBBLE_SIZE_TO_DISPLAY_LABEL;
2240
+ const hasData = !!value;
2127
2241
  let bubbleLabelValueText = value <= MAX_DISPLAYABLE_VALUE ? (0, numberUtils_exports.formatNumber)(value, 0, { useTrendUnits: true }) : VALUE_OVERFLOW_TEXT;
2128
2242
  if (hover) {
2129
2243
  bubbleLabelValueText = (0, numberUtils_exports.formatNumber)(value, 2);
@@ -2133,9 +2247,12 @@ var PunchcardBubble = (props) => {
2133
2247
  {
2134
2248
  "data-test": "bubble",
2135
2249
  muted,
2136
- onMouseEnter: handleMouseEnter,
2137
- onMouseLeave: handleMouseLeave,
2138
- 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
2139
2256
  },
2140
2257
  showPulsateBubble && /* @__PURE__ */ react_exports.createElement(PulsateBubble, { cx, cy, r, color, outline: true, hover: null }),
2141
2258
  /* @__PURE__ */ react_exports.createElement(
@@ -2150,7 +2267,18 @@ var PunchcardBubble = (props) => {
2150
2267
  outline
2151
2268
  }
2152
2269
  ),
2153
- /* @__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
+ )
2154
2282
  );
2155
2283
  };
2156
2284
  var propTypes4 = {
@@ -2166,7 +2294,9 @@ var propTypes4 = {
2166
2294
  pulsate: prop_types_exports.bool,
2167
2295
  value: prop_types_exports.number,
2168
2296
  r: prop_types_exports.number,
2169
- handlePointClick: prop_types_exports.func
2297
+ handlePointClick: prop_types_exports.func,
2298
+ accessibleLabel: prop_types_exports.string,
2299
+ tabindex: prop_types_exports.number
2170
2300
  };
2171
2301
  var defaultProps2 = {
2172
2302
  showBubbleLabel: true,
@@ -2184,7 +2314,9 @@ var defaultProps2 = {
2184
2314
  r: 1,
2185
2315
  value: void 0,
2186
2316
  handlePointClick: () => {
2187
- }
2317
+ },
2318
+ accessibleLabel: "",
2319
+ tabindex: -1
2188
2320
  };
2189
2321
  PunchcardBubble.propTypes = propTypes4;
2190
2322
  PunchcardBubble.defaultProps = defaultProps2;
@@ -2208,6 +2340,7 @@ var PunchcardRow = (props) => {
2208
2340
  size: size2,
2209
2341
  x,
2210
2342
  xScale,
2343
+ yIndex,
2211
2344
  yPosition,
2212
2345
  yValue,
2213
2346
  handlePointClick
@@ -2229,6 +2362,7 @@ var PunchcardRow = (props) => {
2229
2362
  });
2230
2363
  const muted = isSomethingSelected({ selectedX, selectedY, selectedCategory }) && !hover;
2231
2364
  const showBubbleLabel = showBubbleLabels === "all" /* ALL */ || showBubbleLabels === "max" /* MAX */ && maxSizeValue === sizeValue;
2365
+ const accessibleLabel = getBubbleAccessibleName({ categoryValue, xValue, yValue, sizeValue });
2232
2366
  return /* @__PURE__ */ react_exports.createElement(
2233
2367
  PunchcardBubble_default,
2234
2368
  {
@@ -2247,7 +2381,9 @@ var PunchcardRow = (props) => {
2247
2381
  pulsate: showMaxValuePulsation && sizeValue === maxSizeValue,
2248
2382
  value: sizeValue,
2249
2383
  r,
2250
- handlePointClick
2384
+ handlePointClick,
2385
+ accessibleLabel,
2386
+ tabindex: hover || !muted && yIndex === 0 && index === 0 ? 0 : -1
2251
2387
  }
2252
2388
  );
2253
2389
  }));
@@ -2268,6 +2404,7 @@ var propTypes5 = {
2268
2404
  size: prop_types_exports.arrayOf(prop_types_exports.number),
2269
2405
  x: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
2270
2406
  xScale: prop_types_exports.func,
2407
+ yIndex: prop_types_exports.number,
2271
2408
  yPosition: prop_types_exports.number,
2272
2409
  yValue: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2273
2410
  handlePointClick: prop_types_exports.func
@@ -2291,6 +2428,7 @@ var defaultProps3 = {
2291
2428
  // eslint-disable-next-line react/default-props-match-prop-types
2292
2429
  x: null,
2293
2430
  xScale: null,
2431
+ yIndex: null,
2294
2432
  yPosition: null,
2295
2433
  yValue: null,
2296
2434
  handlePointClick: () => {
@@ -2324,6 +2462,7 @@ var PunchcardChartArea = (props) => {
2324
2462
  selectedX,
2325
2463
  selectedY,
2326
2464
  size: size2,
2465
+ uniqX,
2327
2466
  x,
2328
2467
  xScale,
2329
2468
  y,
@@ -2348,7 +2487,8 @@ var PunchcardChartArea = (props) => {
2348
2487
  maxBubbleRadius,
2349
2488
  minBubbleRadius
2350
2489
  });
2351
- 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);
2352
2492
  const {
2353
2493
  rowXValues,
2354
2494
  rowSizeValues,
@@ -2357,8 +2497,7 @@ var PunchcardChartArea = (props) => {
2357
2497
  rowFillOpacityValues,
2358
2498
  rowSizeScale,
2359
2499
  rowRadiusValues
2360
- } = rowData;
2361
- const yPosition = yScale(row);
2500
+ } = addNullValuesToRowData({ rowData, uniqX });
2362
2501
  return /* @__PURE__ */ react_exports.createElement(
2363
2502
  PunchcardRow_default,
2364
2503
  {
@@ -2379,6 +2518,7 @@ var PunchcardChartArea = (props) => {
2379
2518
  size: rowSizeValues,
2380
2519
  x: rowXValues,
2381
2520
  xScale,
2521
+ yIndex: index,
2382
2522
  yPosition,
2383
2523
  yValue: row,
2384
2524
  handlePointClick
@@ -2408,6 +2548,7 @@ var propTypes6 = {
2408
2548
  selectedX: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2409
2549
  selectedY: prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number]),
2410
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,
2411
2552
  x: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
2412
2553
  xScale: prop_types_exports.func,
2413
2554
  y: prop_types_exports.arrayOf(prop_types_exports.oneOfType([prop_types_exports.string, prop_types_exports.number])).isRequired,
@@ -2440,6 +2581,8 @@ var defaultProps4 = {
2440
2581
  // eslint-disable-next-line react/default-props-match-prop-types
2441
2582
  size: null,
2442
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
2443
2586
  x: null,
2444
2587
  xScale: null,
2445
2588
  // eslint-disable-next-line react/default-props-match-prop-types
@@ -2738,6 +2881,33 @@ var Punchcard = (props) => {
2738
2881
  }
2739
2882
  });
2740
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
+ };
2741
2911
  const renderVisualization = () => {
2742
2912
  if (!containerWidth || !containerHeight) {
2743
2913
  return null;
@@ -2771,7 +2941,9 @@ var Punchcard = (props) => {
2771
2941
  {
2772
2942
  "data-test": "punchcard-container",
2773
2943
  width: containerWidth,
2774
- height: containerHeight
2944
+ height: containerHeight,
2945
+ ref: chartRef,
2946
+ onKeyDown: handleKeyDown
2775
2947
  },
2776
2948
  /* @__PURE__ */ react_exports.createElement(PunchcardSVG, { width: containerWidth, height: containerHeight }, /* @__PURE__ */ react_exports.createElement(
2777
2949
  PunchcardGridLines_default,
@@ -2845,6 +3017,7 @@ var Punchcard = (props) => {
2845
3017
  selectedX,
2846
3018
  selectedY,
2847
3019
  size: bubbleSizes,
3020
+ uniqX,
2848
3021
  x,
2849
3022
  xScale: xPositionScale,
2850
3023
  y,