@neo4j-ndl/react-charts 1.2.12 → 1.2.14

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 (57) hide show
  1. package/lib/cjs/charts/LegendLayout.js +1 -1
  2. package/lib/cjs/charts/LegendLayout.js.map +1 -1
  3. package/lib/cjs/charts/hooks/use-legend-interactions.js +4 -4
  4. package/lib/cjs/charts/hooks/use-legend-interactions.js.map +1 -1
  5. package/lib/cjs/charts/hooks/use-legend-series.js +1 -1
  6. package/lib/cjs/charts/hooks/use-legend-series.js.map +1 -1
  7. package/lib/cjs/charts/hooks/use-legend-visibility.js +1 -1
  8. package/lib/cjs/charts/hooks/use-legend-visibility.js.map +1 -1
  9. package/lib/cjs/charts/tests/ChartZoomHarness.js +3 -1
  10. package/lib/cjs/charts/tests/ChartZoomHarness.js.map +1 -1
  11. package/lib/cjs/charts/tests/PieChartWithRerender.js +1 -1
  12. package/lib/cjs/charts/tests/PieChartWithRerender.js.map +1 -1
  13. package/lib/cjs/charts/tests/chart-test-utils.js +19 -8
  14. package/lib/cjs/charts/tests/chart-test-utils.js.map +1 -1
  15. package/lib/cjs/charts/utils/aria-description.js +7 -7
  16. package/lib/cjs/charts/utils/aria-description.js.map +1 -1
  17. package/lib/cjs/charts/utils/build-chart-option.js +1 -1
  18. package/lib/cjs/charts/utils/build-chart-option.js.map +1 -1
  19. package/lib/cjs/charts/utils/chart-types.js.map +1 -1
  20. package/lib/cjs/charts/utils/format-utils.js.map +1 -1
  21. package/lib/cjs/charts/utils/legend-utils.js +2 -2
  22. package/lib/cjs/charts/utils/legend-utils.js.map +1 -1
  23. package/lib/cjs/charts/utils/user-option-utils.js +2 -2
  24. package/lib/cjs/charts/utils/user-option-utils.js.map +1 -1
  25. package/lib/esm/charts/LegendLayout.js +1 -1
  26. package/lib/esm/charts/LegendLayout.js.map +1 -1
  27. package/lib/esm/charts/hooks/use-legend-interactions.js +4 -4
  28. package/lib/esm/charts/hooks/use-legend-interactions.js.map +1 -1
  29. package/lib/esm/charts/hooks/use-legend-series.js +1 -1
  30. package/lib/esm/charts/hooks/use-legend-series.js.map +1 -1
  31. package/lib/esm/charts/hooks/use-legend-visibility.js +1 -1
  32. package/lib/esm/charts/hooks/use-legend-visibility.js.map +1 -1
  33. package/lib/esm/charts/tests/ChartZoomHarness.js +3 -1
  34. package/lib/esm/charts/tests/ChartZoomHarness.js.map +1 -1
  35. package/lib/esm/charts/tests/PieChartWithRerender.js +1 -1
  36. package/lib/esm/charts/tests/PieChartWithRerender.js.map +1 -1
  37. package/lib/esm/charts/tests/chart-test-utils.js +19 -8
  38. package/lib/esm/charts/tests/chart-test-utils.js.map +1 -1
  39. package/lib/esm/charts/utils/aria-description.js +7 -7
  40. package/lib/esm/charts/utils/aria-description.js.map +1 -1
  41. package/lib/esm/charts/utils/build-chart-option.js +1 -1
  42. package/lib/esm/charts/utils/build-chart-option.js.map +1 -1
  43. package/lib/esm/charts/utils/chart-types.js.map +1 -1
  44. package/lib/esm/charts/utils/format-utils.js.map +1 -1
  45. package/lib/esm/charts/utils/legend-utils.js +2 -2
  46. package/lib/esm/charts/utils/legend-utils.js.map +1 -1
  47. package/lib/esm/charts/utils/user-option-utils.js +2 -2
  48. package/lib/esm/charts/utils/user-option-utils.js.map +1 -1
  49. package/lib/types/charts/hooks/use-legend-visibility.d.ts.map +1 -1
  50. package/lib/types/charts/tests/ChartZoomHarness.d.ts.map +1 -1
  51. package/lib/types/charts/tests/chart-test-utils.d.ts.map +1 -1
  52. package/lib/types/charts/utils/aria-description.d.ts.map +1 -1
  53. package/lib/types/charts/utils/chart-types.d.ts.map +1 -1
  54. package/lib/types/charts/utils/format-utils.d.ts.map +1 -1
  55. package/lib/types/charts/utils/user-option-utils.d.ts.map +1 -1
  56. package/package.json +3 -3
  57. package/skills/ndl-react-charts/components/charts.md +91 -22
@@ -173,7 +173,7 @@ const useCollapsibleLegendLayout = ({ itemCount, legendContainerRef, legendConte
173
173
  setIsMeasuring(false);
174
174
  return;
175
175
  }
176
- const rowTops = Array.from(new Set(legendItems.map((element) => element.offsetTop))).sort((a, b) => a - b);
176
+ const rowTops = Array.from(new Set(legendItems.map((element) => element.offsetTop))).sort((left, right) => left - right);
177
177
  const nextLegendContentHeight = legendContent.scrollHeight;
178
178
  const nextLegendItemsContentHeight = getLegendElementsContentHeight(legendContent, legendItems);
179
179
  if (rowTops.length <= legend_layout_1.COLLAPSED_LEGEND_ROWS) {
@@ -1 +1 @@
1
- {"version":3,"file":"LegendLayout.js","sourceRoot":"","sources":["../../../src/charts/LegendLayout.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,4CAA4C;AAC5C,4DAAoC;AACpC,+CAAwE;AAGxE,yDAK+B;AAgB/B,MAAM,8BAA8B,GAAG,CACrC,aAA0B,EAC1B,QAAuB,EACvB,EAAE;IACF,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAC7B,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CACvE,CAAC;IAEF,OAAO,cAAc,GAAG,aAAa,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,+BAA+B,GAAG,CAAC,EACvC,iBAAiB,EACjB,QAAQ,EACR,aAAa,GAKd,EAAE,EAAE;IACH,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,UAAU,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,UAAU,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,MAAM,YAAY,GAAG,IAAA,uCAAuB,EAAC,OAAO,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC;QAC7D,MAAM,UAAU,GACd,eAAe,GAAG,CAAC,IAAI,eAAe,GAAG,YAAY,GAAG,iBAAiB,CAAC;QAE5E,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAClC,gBAAgB,GAAG,CAAC,CAAC;YACrB,eAAe,GAAG,CAAC,CAAC;QACtB,CAAC;QAED,eAAe,IAAI,YAAY,CAAC;QAChC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;QACzB,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE;QACzD,OAAO,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,OAAO,CACL,UAAU;QACV,UAAU;QACV,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3C,aAAa,CACd,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,uBAAuB,GAAG,CAC9B,kBAA0D,EAC1D,EAAE;IACF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,QAAQ,CAAC,CAAC;IAEzD,MAAM,iBAAiB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;;QACzC,MAAM,SAAS,GAAG,MAAA,kBAAkB,CAAC,OAAO,0CAAE,WAAW,CAAC;QAC1D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,cAAc,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAEzB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,iBAAiB,EAAE,CAAC;QAEpB,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC;QACnD,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC7D,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAExC,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE5C,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,0BAA0B,GAAG,CAAC,EAClC,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,4BAA4B,GAO7B,EAAE,EAAE;IACH,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAAuB;QACzE,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,SAAS;KAC5B,CAAC,CAAC;IACH,MAAM,8BAA8B,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,uBAAuB,CAAC,kBAAkB,CAAC,CAAC;IAEhE,MAAM,kBAAkB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;;QAC1C,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC;QACnD,MAAM,cAAc,GAAG,4BAA4B,CAAC,OAAO,CAAC;QAC5D,IAAI,CAAC,aAAa,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAC5B,aAAa,CAAC,gBAAgB,CAAc,wBAAwB,CAAC,CACtE,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC;QAErD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,iCAC3B,QAAQ,KACX,aAAa,EAAE,CAAC,EAChB,WAAW,EAAE,KAAK,EAClB,gBAAgB,EAAE,SAAS,IAC3B,CAAC,CAAC;YACJ,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CACxB,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CACzD,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxB,MAAM,uBAAuB,GAAG,aAAa,CAAC,YAAY,CAAC;QAC3D,MAAM,4BAA4B,GAAG,8BAA8B,CACjE,aAAa,EACb,WAAW,CACZ,CAAC;QAEF,IAAI,OAAO,CAAC,MAAM,IAAI,qCAAqB,EAAE,CAAC;YAC5C,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,iCAC3B,QAAQ,KACX,aAAa,EAAE,4BAA4B,EAC3C,WAAW,EAAE,KAAK,EAClB,gBAAgB,EAAE,SAAS,IAC3B,CAAC,CAAC;YACJ,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC;QACnD,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAC3D,MAAM,iBAAiB,GACrB,CAAC,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,WAAW,mCAAI,aAAa,CAAC,WAAW,CAAC;YAC3D,CAAC,UAAU,CAAC,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC,UAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACrD,MAAM,mBAAmB,GAAG,IAAA,uCAAuB,EAAC,cAAc,CAAC,CAAC;QACpE,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,CAAC,uCAAuB,CAAC,CAAC;QAClE,MAAM,oBAAoB,GAAG,IAAA,4CAA4B,EACvD,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,CACpB,CAAC;QACF,MAAM,0BAA0B,GAAG,+BAA+B,CAAC;YACjE,iBAAiB;YACjB,QAAQ,EAAE,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,EAAE,cAAc,CAAC;YACzE,aAAa;SACd,CAAC,CAAC;QAEH,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,iCAC3B,QAAQ,KACX,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,0BAA0B,EAC1B,2CAA2B,CAC5B,EACD,aAAa,EAAE,uBAAuB,EACtC,WAAW,EAAE,oBAAoB,GAAG,SAAS,EAC7C,gBAAgB,EAAE,oBAAoB,IACtC,CAAC,CAAC;QACJ,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,EAAE;QACD,SAAS;QACT,kBAAkB;QAClB,oBAAoB;QACpB,4BAA4B;KAC7B,CAAC,CAAC;IAEH,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,UAAU,EAAE,CAAC;YACf,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,8BAA8B,CAAC,OAAO,EAAE,CAAC;YAC3C,8BAA8B,CAAC,OAAO,GAAG,KAAK,CAAC;YAC/C,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAEzC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,oBAAoB,GAAG,CAAC,UAAU,IAAI,WAAW,CAAC;QAExD,MAAM,cAAc,GAAG,qBAAqB,CAAC,GAAG,EAAE;YAChD,IAAI,oBAAoB,EAAE,CAAC;gBACzB,kBAAkB,EAAE,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE;;oBAAC,OAAA,iCAC3B,QAAQ,KACX,aAAa,EAAE,MAAA,MAAA,gBAAgB,CAAC,OAAO,0CAAE,YAAY,mCAAI,CAAC,IAC1D,CAAA;iBAAA,CAAC,CAAC;gBAEJ,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC,WAAW,EAAE,CAAC;oBAC9D,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE;;wBAAC,OAAA,iCAC3B,QAAQ,KACX,eAAe,EACb,MAAA,gBAAgB,CAAC,OAAO,0CAAE,qBAAqB,GAAG,MAAM,IAC1D,CAAA;qBAAA,CAAC,CAAC;gBACN,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACvC,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,UAAU;QACV,WAAW;QACX,gBAAgB;QAChB,cAAc,CAAC,WAAW;QAC1B,kBAAkB;KACnB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACpC,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,aAAa,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,cAAc,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACtC,8BAA8B,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9C,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,cAAc;QACd,YAAY;QACZ,UAAU;QACV,WAAW;QACX,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,YAAY,GAAG,CAAC,EAQwB,EAAE,EAAE;QAR5B,EAC3B,QAAQ,EACR,SAAS,EACT,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,aAAa,EACb,cAAc,OAEqC,EADhD,SAAS,cAPe,0FAQ5B,CADa;IAEZ,MAAM,kBAAkB,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IACtD,MAAM,oBAAoB,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IAC1D,MAAM,8BAA8B,GAAG,IAAA,cAAM,EAAgB,IAAI,CAAC,CAAC;IACnE,MAAM,4BAA4B,GAAG,IAAA,cAAM,EAAoB,IAAI,CAAC,CAAC;IACrE,MAAM,EACJ,cAAc,EACd,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,GACf,GAAG,0BAA0B,CAAC;QAC7B,SAAS;QACT,kBAAkB;QAClB,gBAAgB;QAChB,oBAAoB;QACpB,4BAA4B;KAC7B,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,gBAAgB,GAAG,CAAC,UAAU;QAClC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,gBAAgB,CAAC;QACrD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,YAAY,GAChB,CAAC,WAAW,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC,WAAW;QACvD,CAAC,CAAC,cAAc,CAAC,eAAe;QAChC,CAAC,CAAC,CAAC,WAAW;YACV,CAAC,cAAc,CAAC,WAAW;YAC3B,cAAc,CAAC,aAAa;YAC9B,CAAC,CAAC,cAAc,CAAC,aAAa;YAC9B,CAAC,CAAC,SAAS,CAAC;IAElB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,WAAW,IAAI,cAAc,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YACrD,IAAI,WAA+B,CAAC;YACpC,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,EAAE;gBAC5C,WAAW,GAAG,qBAAqB,CAAC,GAAG,EAAE;oBACvC,aAAa,aAAb,aAAa,uBAAb,aAAa,EAAI,CAAC;gBACpB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,OAAO,GAAG,EAAE;gBACV,oBAAoB,CAAC,UAAU,CAAC,CAAC;gBACjC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,oBAAoB,CAAC,WAAW,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,cAAc,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC;IAE/D,IAAA,iBAAS,EAAC,GAAG,EAAE;;QACb,MAAM,2BAA2B,GAAG,8BAA8B,CAAC,OAAO,CAAC;QAC3E,IAAI,CAAC,UAAU,IAAI,2BAA2B,KAAK,IAAI,EAAE,CAAC;YACxD,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,MAAA,gBAAgB,CAAC,OAAO,0CAAE,gBAAgB,CAC5D,wBAAwB,CACzB,CAAC;QACF,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAG,2BAA2B,CAAC,0CAAE,KAAK,EAAE,CAAC;QACpD,8BAA8B,CAAC,OAAO,GAAG,IAAI,CAAC;IAChD,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,MAAM,uBAAuB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QAC/C,IAAI,UAAU,EAAE,CAAC;YACf,cAAc,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,8BAA8B,CAAC,OAAO,GAAG,cAAc,CAAC,gBAAgB,CAAC;QACzE,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE;QACD,cAAc;QACd,YAAY;QACZ,UAAU;QACV,cAAc,CAAC,gBAAgB;KAChC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAA,oBAAU,EACxB,kBAAkB,EAClB;QACE,8BAA8B,EAAE,CAAC,UAAU,IAAI,WAAW;QAC1D,4BAA4B,EAAE,cAAc,CAAC,WAAW,IAAI,CAAC,UAAU;QACvE,2BAA2B,EAAE,cAAc,CAAC,WAAW,IAAI,UAAU;QACrE,yBAAyB,EAAE,CAAC,aAAa;QACzC,6BAA6B,EAC3B,cAAc,CAAC,WAAW;YAC1B,UAAU;YACV,cAAc,CAAC,aAAa,GAAG,2CAA2B;QAC5D,2BAA2B,EAAE,IAAI;KAClC,EACD,SAAS,CACV,CAAC;IACF,OAAO,CACL,8CACE,GAAG,EAAE,kBAAkB,EACvB,SAAS,EAAC,4BAA4B,IAClC,SAAS,EACT,cAAc,cAElB,iCACE,SAAS,EAAE,OAAO,EAClB,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE;gBACL,MAAM,EAAE,YAAY;gBACpB,SAAS,EACP,cAAc,CAAC,WAAW,IAAI,UAAU;oBACtC,CAAC,CAAC,6CAA6C;oBAC/C,CAAC,CAAC,cAAc,CAAC,WAAW;wBAC1B,CAAC,CAAC,2CAA2B;wBAC7B,CAAC,CAAC,SAAS;aAClB,aAEA,gBAAgB,EAChB,cAAc,CAAC,WAAW,IAAI,CAC7B,uBAAC,gBAAQ,IACP,EAAE,EAAC,QAAQ,EACX,SAAS,EAAC,yBAAyB,EACnC,cAAc,EAAE;wBACd,eAAe,EAAE,UAAU;wBAC3B,OAAO,EAAE,uBAAuB;wBAChC,IAAI,EAAE,QAAQ;qBACf,YAEA,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,GAC9B,CACZ,EACA,WAAW,IAAI,CACd,gDACc,MAAM,EAClB,SAAS,EAAC,8BAA8B,EACxC,GAAG,EAAE,oBAAoB,aAExB,SAAS,EACV,uBAAC,gBAAQ,IACP,EAAE,EAAC,QAAQ,EACX,GAAG,EAAE,4BAA4B,EACjC,SAAS,EAAC,yBAAyB,EACnC,cAAc,EAAE;gCACd,QAAQ,EAAE,CAAC,CAAC;gCACZ,IAAI,EAAE,QAAQ;6BACf,0BAGQ,IACP,CACP,IACG,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AA/JW,QAAA,YAAY,gBA+JvB","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { TextLink } from '@neo4j-ndl/react';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { type CommonProps } from './utils/chart-types';\nimport {\n COLLAPSED_LEGEND_MAX_HEIGHT,\n COLLAPSED_LEGEND_ROWS,\n getCollapsedVisibleItemCount,\n getComputedElementWidth,\n} from './utils/legend-layout';\n\ntype LegendLayoutProps = {\n children: React.ReactNode;\n isLayoutReady?: boolean;\n itemCount: number;\n onLayoutReady?: () => void;\n};\n\ntype LegendLayoutSnapshot = {\n collapsedHeight?: number;\n contentHeight: number;\n hasOverflow: boolean;\n visibleItemCount: number;\n};\n\nconst getLegendElementsContentHeight = (\n legendContent: HTMLElement,\n elements: HTMLElement[],\n) => {\n const legendContentStyle = getComputedStyle(legendContent);\n const paddingBottom = parseFloat(legendContentStyle.paddingBottom) || 0;\n const elementsBottom = Math.max(\n ...elements.map((element) => element.offsetTop + element.offsetHeight),\n );\n\n return elementsBottom + paddingBottom;\n};\n\nconst getCollapsedLegendContentHeight = ({\n availableRowWidth,\n elements,\n legendContent,\n}: {\n availableRowWidth: number;\n elements: HTMLElement[];\n legendContent: HTMLElement;\n}) => {\n const legendContentStyle = getComputedStyle(legendContent);\n const paddingTop = parseFloat(legendContentStyle.paddingTop) || 0;\n const paddingBottom = parseFloat(legendContentStyle.paddingBottom) || 0;\n const rowGap = parseFloat(legendContentStyle.rowGap) || 0;\n let currentRowHeight = 0;\n let currentRowWidth = 0;\n const rowHeights: number[] = [];\n\n elements.forEach((element) => {\n const elementWidth = getComputedElementWidth(element);\n const elementHeight = element.getBoundingClientRect().height;\n const shouldWrap =\n currentRowWidth > 0 && currentRowWidth + elementWidth > availableRowWidth;\n\n if (shouldWrap) {\n rowHeights.push(currentRowHeight);\n currentRowHeight = 0;\n currentRowWidth = 0;\n }\n\n currentRowWidth += elementWidth;\n currentRowHeight = Math.max(currentRowHeight, elementHeight);\n });\n\n if (currentRowHeight > 0) {\n rowHeights.push(currentRowHeight);\n }\n\n const rowsHeight = rowHeights.reduce((height, rowHeight) => {\n return height + rowHeight;\n }, 0);\n\n return (\n paddingTop +\n rowsHeight +\n rowGap * Math.max(rowHeights.length - 1, 0) +\n paddingBottom\n );\n};\n\n/**\n * Tracks legend container width for responsive collapsed-layout recalculation.\n *\n * The width is kept in state so `useCollapsibleLegendLayout` can re-measure item\n * wrapping whenever the available legend width changes.\n */\nconst useLegendContainerWidth = (\n legendContainerRef: React.RefObject<HTMLDivElement | null>,\n) => {\n const [legendWidth, setLegendWidth] = useState(Infinity);\n\n const updateLegendWidth = useCallback(() => {\n const nextWidth = legendContainerRef.current?.clientWidth;\n if (nextWidth === undefined) {\n return;\n }\n\n setLegendWidth(nextWidth);\n }, [legendContainerRef]);\n\n useEffect(() => {\n updateLegendWidth();\n\n const legendContainer = legendContainerRef.current;\n if (!legendContainer) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(updateLegendWidth);\n resizeObserver.observe(legendContainer);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [legendContainerRef, updateLegendWidth]);\n\n return legendWidth;\n};\n\n/**\n * Owns the collapsed, measuring, and expanded layout state for wrapping legends.\n *\n * Collapsed legends only render the visible subset of items. When the item count\n * or container width changes, the hook temporarily renders every item in an\n * invisible measuring pass so it can calculate wrapping, overflow, and the next\n * visible item count. The last collapsed height is preserved during that pass so\n * the chart area does not shrink while the hidden full legend is being measured.\n */\nconst useCollapsibleLegendLayout = ({\n itemCount,\n legendContainerRef,\n legendContentRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n}: {\n itemCount: number;\n legendContainerRef: React.RefObject<HTMLDivElement | null>;\n legendContentRef: React.RefObject<HTMLDivElement | null>;\n legendMeasurementRef: React.RefObject<HTMLDivElement | null>;\n viewMoreButtonMeasurementRef: React.RefObject<HTMLButtonElement | null>;\n}) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const [isMeasuring, setIsMeasuring] = useState(false);\n const [layoutSnapshot, setLayoutSnapshot] = useState<LegendLayoutSnapshot>({\n contentHeight: 0,\n hasOverflow: false,\n visibleItemCount: itemCount,\n });\n const skipNextCollapseMeasurementRef = useRef(false);\n const legendWidth = useLegendContainerWidth(legendContainerRef);\n\n const updateVisibleItems = useCallback(() => {\n const legendContent = legendMeasurementRef.current;\n const viewMoreButton = viewMoreButtonMeasurementRef.current;\n if (!legendContent || !viewMoreButton) {\n setIsMeasuring(false);\n return;\n }\n\n const legendItems = Array.from(\n legendContent.querySelectorAll<HTMLElement>('.ndl-chart-legend-item'),\n ).filter((element) => element.offsetParent !== null);\n\n if (legendItems.length === 0) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: 0,\n hasOverflow: false,\n visibleItemCount: itemCount,\n }));\n setIsMeasuring(false);\n return;\n }\n\n const rowTops = Array.from(\n new Set(legendItems.map((element) => element.offsetTop)),\n ).sort((a, b) => a - b);\n const nextLegendContentHeight = legendContent.scrollHeight;\n const nextLegendItemsContentHeight = getLegendElementsContentHeight(\n legendContent,\n legendItems,\n );\n\n if (rowTops.length <= COLLAPSED_LEGEND_ROWS) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: nextLegendItemsContentHeight,\n hasOverflow: false,\n visibleItemCount: itemCount,\n }));\n setIsMeasuring(false);\n return;\n }\n\n const legendContainer = legendContainerRef.current;\n const legendContentStyle = getComputedStyle(legendContent);\n const availableRowWidth =\n (legendContainer?.clientWidth ?? legendContent.clientWidth) -\n (parseFloat(legendContentStyle.paddingLeft) || 0) -\n (parseFloat(legendContentStyle.paddingRight) || 0);\n const viewMoreButtonWidth = getComputedElementWidth(viewMoreButton);\n const legendItemWidths = legendItems.map(getComputedElementWidth);\n const nextVisibleItemCount = getCollapsedVisibleItemCount(\n legendItemWidths,\n availableRowWidth,\n viewMoreButtonWidth,\n );\n const nextCollapsedContentHeight = getCollapsedLegendContentHeight({\n availableRowWidth,\n elements: [...legendItems.slice(0, nextVisibleItemCount), viewMoreButton],\n legendContent,\n });\n\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n collapsedHeight: Math.min(\n nextCollapsedContentHeight,\n COLLAPSED_LEGEND_MAX_HEIGHT,\n ),\n contentHeight: nextLegendContentHeight,\n hasOverflow: nextVisibleItemCount < itemCount,\n visibleItemCount: nextVisibleItemCount,\n }));\n setIsMeasuring(false);\n }, [\n itemCount,\n legendContainerRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n ]);\n\n useEffect(() => {\n setIsExpanded(false);\n }, [itemCount]);\n\n useEffect(() => {\n if (isExpanded) {\n setIsMeasuring(false);\n return;\n }\n\n if (skipNextCollapseMeasurementRef.current) {\n skipNextCollapseMeasurementRef.current = false;\n setIsMeasuring(false);\n return;\n }\n\n setIsMeasuring(true);\n }, [isExpanded, itemCount, legendWidth]);\n\n useEffect(() => {\n const isMeasuringCollapsed = !isExpanded && isMeasuring;\n\n const animationFrame = requestAnimationFrame(() => {\n if (isMeasuringCollapsed) {\n updateVisibleItems();\n } else {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: legendContentRef.current?.scrollHeight ?? 0,\n }));\n\n if (!isMeasuring && !isExpanded && layoutSnapshot.hasOverflow) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n collapsedHeight:\n legendContentRef.current?.getBoundingClientRect().height,\n }));\n }\n }\n });\n\n return () => {\n cancelAnimationFrame(animationFrame);\n };\n }, [\n isExpanded,\n isMeasuring,\n legendContentRef,\n layoutSnapshot.hasOverflow,\n updateVisibleItems,\n ]);\n\n const expandLegend = useCallback(() => {\n setIsMeasuring(false);\n setIsExpanded(true);\n }, []);\n\n const collapseLegend = useCallback(() => {\n skipNextCollapseMeasurementRef.current = true;\n setIsExpanded(false);\n }, []);\n\n return {\n collapseLegend,\n expandLegend,\n isExpanded,\n isMeasuring,\n layoutSnapshot,\n };\n};\n\n/**\n * Renders the responsive legend layout shell.\n *\n * The component switches between a two-row collapsed view, an invisible\n * measurement view, and an expanded scrollable view while keeping the\n * \"View more\"/\"View less\" action wired to the measured overflow state.\n */\nexport const LegendLayout = ({\n children,\n className,\n isLayoutReady = true,\n itemCount,\n onLayoutReady,\n htmlAttributes,\n ...restProps\n}: Omit<CommonProps<'div', LegendLayoutProps>, 'ref'>) => {\n const legendContainerRef = useRef<HTMLDivElement>(null);\n const legendContentRef = useRef<HTMLDivElement>(null);\n const legendMeasurementRef = useRef<HTMLDivElement>(null);\n const pendingFocusLegendItemIndexRef = useRef<number | null>(null);\n const viewMoreButtonMeasurementRef = useRef<HTMLButtonElement>(null);\n const {\n collapseLegend,\n expandLegend,\n isExpanded,\n isMeasuring,\n layoutSnapshot,\n } = useCollapsibleLegendLayout({\n itemCount,\n legendContainerRef,\n legendContentRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n });\n\n const childList = React.Children.toArray(children);\n const childrenToRender = !isExpanded\n ? childList.slice(0, layoutSnapshot.visibleItemCount)\n : childList;\n const legendHeight =\n !isMeasuring && !isExpanded && layoutSnapshot.hasOverflow\n ? layoutSnapshot.collapsedHeight\n : !isMeasuring &&\n !layoutSnapshot.hasOverflow &&\n layoutSnapshot.contentHeight\n ? layoutSnapshot.contentHeight\n : undefined;\n\n useEffect(() => {\n if (!isMeasuring && layoutSnapshot.contentHeight > 0) {\n let secondFrame: number | undefined;\n const firstFrame = requestAnimationFrame(() => {\n secondFrame = requestAnimationFrame(() => {\n onLayoutReady?.();\n });\n });\n\n return () => {\n cancelAnimationFrame(firstFrame);\n if (secondFrame !== undefined) {\n cancelAnimationFrame(secondFrame);\n }\n };\n }\n }, [isMeasuring, layoutSnapshot.contentHeight, onLayoutReady]);\n\n useEffect(() => {\n const pendingFocusLegendItemIndex = pendingFocusLegendItemIndexRef.current;\n if (!isExpanded || pendingFocusLegendItemIndex === null) {\n return;\n }\n\n const legendItems = legendContentRef.current?.querySelectorAll<HTMLElement>(\n '.ndl-chart-legend-item',\n );\n legendItems?.[pendingFocusLegendItemIndex]?.focus();\n pendingFocusLegendItemIndexRef.current = null;\n }, [isExpanded]);\n\n const handleLegendActionClick = useCallback(() => {\n if (isExpanded) {\n collapseLegend();\n return;\n }\n\n pendingFocusLegendItemIndexRef.current = layoutSnapshot.visibleItemCount;\n expandLegend();\n }, [\n collapseLegend,\n expandLegend,\n isExpanded,\n layoutSnapshot.visibleItemCount,\n ]);\n\n const classes = classNames(\n 'ndl-chart-legend',\n {\n 'ndl-chart-legend-calculating': !isExpanded && isMeasuring,\n 'ndl-chart-legend-collapsed': layoutSnapshot.hasOverflow && !isExpanded,\n 'ndl-chart-legend-expanded': layoutSnapshot.hasOverflow && isExpanded,\n 'ndl-chart-legend-hidden': !isLayoutReady,\n 'ndl-chart-legend-scrollable':\n layoutSnapshot.hasOverflow &&\n isExpanded &&\n layoutSnapshot.contentHeight > COLLAPSED_LEGEND_MAX_HEIGHT,\n 'ndl-chart-legend-wrapping': true,\n },\n className,\n );\n return (\n <div\n ref={legendContainerRef}\n className=\"ndl-chart-legend-container\"\n {...restProps}\n {...htmlAttributes}\n >\n <div\n className={classes}\n ref={legendContentRef}\n style={{\n height: legendHeight,\n maxHeight:\n layoutSnapshot.hasOverflow && isExpanded\n ? 'var(--ndl-chart-legend-expanded-max-height)'\n : layoutSnapshot.hasOverflow\n ? COLLAPSED_LEGEND_MAX_HEIGHT\n : undefined,\n }}\n >\n {childrenToRender}\n {layoutSnapshot.hasOverflow && (\n <TextLink\n as=\"button\"\n className=\"ndl-chart-legend-action\"\n htmlAttributes={{\n 'aria-expanded': isExpanded,\n onClick: handleLegendActionClick,\n type: 'button',\n }}\n >\n {isExpanded ? 'View less' : 'View more'}\n </TextLink>\n )}\n {isMeasuring && (\n <div\n aria-hidden=\"true\"\n className=\"ndl-chart-legend-measurement\"\n ref={legendMeasurementRef}\n >\n {childList}\n <TextLink\n as=\"button\"\n ref={viewMoreButtonMeasurementRef}\n className=\"ndl-chart-legend-action\"\n htmlAttributes={{\n tabIndex: -1,\n type: 'button',\n }}\n >\n View more\n </TextLink>\n </div>\n )}\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"LegendLayout.js","sourceRoot":"","sources":["../../../src/charts/LegendLayout.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { TextLink } from '@neo4j-ndl/react';\nimport classNames from 'classnames';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { type CommonProps } from './utils/chart-types';\nimport {\n COLLAPSED_LEGEND_MAX_HEIGHT,\n COLLAPSED_LEGEND_ROWS,\n getCollapsedVisibleItemCount,\n getComputedElementWidth,\n} from './utils/legend-layout';\n\ntype LegendLayoutProps = {\n children: React.ReactNode;\n isLayoutReady?: boolean;\n itemCount: number;\n onLayoutReady?: () => void;\n};\n\ntype LegendLayoutSnapshot = {\n collapsedHeight?: number;\n contentHeight: number;\n hasOverflow: boolean;\n visibleItemCount: number;\n};\n\nconst getLegendElementsContentHeight = (\n legendContent: HTMLElement,\n elements: HTMLElement[],\n) => {\n const legendContentStyle = getComputedStyle(legendContent);\n const paddingBottom = parseFloat(legendContentStyle.paddingBottom) || 0;\n const elementsBottom = Math.max(\n ...elements.map((element) => element.offsetTop + element.offsetHeight),\n );\n\n return elementsBottom + paddingBottom;\n};\n\nconst getCollapsedLegendContentHeight = ({\n availableRowWidth,\n elements,\n legendContent,\n}: {\n availableRowWidth: number;\n elements: HTMLElement[];\n legendContent: HTMLElement;\n}) => {\n const legendContentStyle = getComputedStyle(legendContent);\n const paddingTop = parseFloat(legendContentStyle.paddingTop) || 0;\n const paddingBottom = parseFloat(legendContentStyle.paddingBottom) || 0;\n const rowGap = parseFloat(legendContentStyle.rowGap) || 0;\n let currentRowHeight = 0;\n let currentRowWidth = 0;\n const rowHeights: number[] = [];\n\n elements.forEach((element) => {\n const elementWidth = getComputedElementWidth(element);\n const elementHeight = element.getBoundingClientRect().height;\n const shouldWrap =\n currentRowWidth > 0 && currentRowWidth + elementWidth > availableRowWidth;\n\n if (shouldWrap) {\n rowHeights.push(currentRowHeight);\n currentRowHeight = 0;\n currentRowWidth = 0;\n }\n\n currentRowWidth += elementWidth;\n currentRowHeight = Math.max(currentRowHeight, elementHeight);\n });\n\n if (currentRowHeight > 0) {\n rowHeights.push(currentRowHeight);\n }\n\n const rowsHeight = rowHeights.reduce((height, rowHeight) => {\n return height + rowHeight;\n }, 0);\n\n return (\n paddingTop +\n rowsHeight +\n rowGap * Math.max(rowHeights.length - 1, 0) +\n paddingBottom\n );\n};\n\n/**\n * Tracks legend container width for responsive collapsed-layout recalculation.\n *\n * The width is kept in state so `useCollapsibleLegendLayout` can re-measure item\n * wrapping whenever the available legend width changes.\n */\nconst useLegendContainerWidth = (\n legendContainerRef: React.RefObject<HTMLDivElement | null>,\n) => {\n const [legendWidth, setLegendWidth] = useState(Infinity);\n\n const updateLegendWidth = useCallback(() => {\n const nextWidth = legendContainerRef.current?.clientWidth;\n if (nextWidth === undefined) {\n return;\n }\n\n setLegendWidth(nextWidth);\n }, [legendContainerRef]);\n\n useEffect(() => {\n updateLegendWidth();\n\n const legendContainer = legendContainerRef.current;\n if (!legendContainer) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(updateLegendWidth);\n resizeObserver.observe(legendContainer);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [legendContainerRef, updateLegendWidth]);\n\n return legendWidth;\n};\n\n/**\n * Owns the collapsed, measuring, and expanded layout state for wrapping legends.\n *\n * Collapsed legends only render the visible subset of items. When the item count\n * or container width changes, the hook temporarily renders every item in an\n * invisible measuring pass so it can calculate wrapping, overflow, and the next\n * visible item count. The last collapsed height is preserved during that pass so\n * the chart area does not shrink while the hidden full legend is being measured.\n */\nconst useCollapsibleLegendLayout = ({\n itemCount,\n legendContainerRef,\n legendContentRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n}: {\n itemCount: number;\n legendContainerRef: React.RefObject<HTMLDivElement | null>;\n legendContentRef: React.RefObject<HTMLDivElement | null>;\n legendMeasurementRef: React.RefObject<HTMLDivElement | null>;\n viewMoreButtonMeasurementRef: React.RefObject<HTMLButtonElement | null>;\n}) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const [isMeasuring, setIsMeasuring] = useState(false);\n const [layoutSnapshot, setLayoutSnapshot] = useState<LegendLayoutSnapshot>({\n contentHeight: 0,\n hasOverflow: false,\n visibleItemCount: itemCount,\n });\n const skipNextCollapseMeasurementRef = useRef(false);\n const legendWidth = useLegendContainerWidth(legendContainerRef);\n\n const updateVisibleItems = useCallback(() => {\n const legendContent = legendMeasurementRef.current;\n const viewMoreButton = viewMoreButtonMeasurementRef.current;\n if (!legendContent || !viewMoreButton) {\n setIsMeasuring(false);\n return;\n }\n\n const legendItems = Array.from(\n legendContent.querySelectorAll<HTMLElement>('.ndl-chart-legend-item'),\n ).filter((element) => element.offsetParent !== null);\n\n if (legendItems.length === 0) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: 0,\n hasOverflow: false,\n visibleItemCount: itemCount,\n }));\n setIsMeasuring(false);\n return;\n }\n\n const rowTops = Array.from(\n new Set(legendItems.map((element) => element.offsetTop)),\n ).sort((left, right) => left - right);\n const nextLegendContentHeight = legendContent.scrollHeight;\n const nextLegendItemsContentHeight = getLegendElementsContentHeight(\n legendContent,\n legendItems,\n );\n\n if (rowTops.length <= COLLAPSED_LEGEND_ROWS) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: nextLegendItemsContentHeight,\n hasOverflow: false,\n visibleItemCount: itemCount,\n }));\n setIsMeasuring(false);\n return;\n }\n\n const legendContainer = legendContainerRef.current;\n const legendContentStyle = getComputedStyle(legendContent);\n const availableRowWidth =\n (legendContainer?.clientWidth ?? legendContent.clientWidth) -\n (parseFloat(legendContentStyle.paddingLeft) || 0) -\n (parseFloat(legendContentStyle.paddingRight) || 0);\n const viewMoreButtonWidth = getComputedElementWidth(viewMoreButton);\n const legendItemWidths = legendItems.map(getComputedElementWidth);\n const nextVisibleItemCount = getCollapsedVisibleItemCount(\n legendItemWidths,\n availableRowWidth,\n viewMoreButtonWidth,\n );\n const nextCollapsedContentHeight = getCollapsedLegendContentHeight({\n availableRowWidth,\n elements: [...legendItems.slice(0, nextVisibleItemCount), viewMoreButton],\n legendContent,\n });\n\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n collapsedHeight: Math.min(\n nextCollapsedContentHeight,\n COLLAPSED_LEGEND_MAX_HEIGHT,\n ),\n contentHeight: nextLegendContentHeight,\n hasOverflow: nextVisibleItemCount < itemCount,\n visibleItemCount: nextVisibleItemCount,\n }));\n setIsMeasuring(false);\n }, [\n itemCount,\n legendContainerRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n ]);\n\n useEffect(() => {\n setIsExpanded(false);\n }, [itemCount]);\n\n useEffect(() => {\n if (isExpanded) {\n setIsMeasuring(false);\n return;\n }\n\n if (skipNextCollapseMeasurementRef.current) {\n skipNextCollapseMeasurementRef.current = false;\n setIsMeasuring(false);\n return;\n }\n\n setIsMeasuring(true);\n }, [isExpanded, itemCount, legendWidth]);\n\n useEffect(() => {\n const isMeasuringCollapsed = !isExpanded && isMeasuring;\n\n const animationFrame = requestAnimationFrame(() => {\n if (isMeasuringCollapsed) {\n updateVisibleItems();\n } else {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n contentHeight: legendContentRef.current?.scrollHeight ?? 0,\n }));\n\n if (!isMeasuring && !isExpanded && layoutSnapshot.hasOverflow) {\n setLayoutSnapshot((snapshot) => ({\n ...snapshot,\n collapsedHeight:\n legendContentRef.current?.getBoundingClientRect().height,\n }));\n }\n }\n });\n\n return () => {\n cancelAnimationFrame(animationFrame);\n };\n }, [\n isExpanded,\n isMeasuring,\n legendContentRef,\n layoutSnapshot.hasOverflow,\n updateVisibleItems,\n ]);\n\n const expandLegend = useCallback(() => {\n setIsMeasuring(false);\n setIsExpanded(true);\n }, []);\n\n const collapseLegend = useCallback(() => {\n skipNextCollapseMeasurementRef.current = true;\n setIsExpanded(false);\n }, []);\n\n return {\n collapseLegend,\n expandLegend,\n isExpanded,\n isMeasuring,\n layoutSnapshot,\n };\n};\n\n/**\n * Renders the responsive legend layout shell.\n *\n * The component switches between a two-row collapsed view, an invisible\n * measurement view, and an expanded scrollable view while keeping the\n * \"View more\"/\"View less\" action wired to the measured overflow state.\n */\nexport const LegendLayout = ({\n children,\n className,\n isLayoutReady = true,\n itemCount,\n onLayoutReady,\n htmlAttributes,\n ...restProps\n}: Omit<CommonProps<'div', LegendLayoutProps>, 'ref'>) => {\n const legendContainerRef = useRef<HTMLDivElement>(null);\n const legendContentRef = useRef<HTMLDivElement>(null);\n const legendMeasurementRef = useRef<HTMLDivElement>(null);\n const pendingFocusLegendItemIndexRef = useRef<number | null>(null);\n const viewMoreButtonMeasurementRef = useRef<HTMLButtonElement>(null);\n const {\n collapseLegend,\n expandLegend,\n isExpanded,\n isMeasuring,\n layoutSnapshot,\n } = useCollapsibleLegendLayout({\n itemCount,\n legendContainerRef,\n legendContentRef,\n legendMeasurementRef,\n viewMoreButtonMeasurementRef,\n });\n\n const childList = React.Children.toArray(children);\n const childrenToRender = !isExpanded\n ? childList.slice(0, layoutSnapshot.visibleItemCount)\n : childList;\n const legendHeight =\n !isMeasuring && !isExpanded && layoutSnapshot.hasOverflow\n ? layoutSnapshot.collapsedHeight\n : !isMeasuring &&\n !layoutSnapshot.hasOverflow &&\n layoutSnapshot.contentHeight\n ? layoutSnapshot.contentHeight\n : undefined;\n\n useEffect(() => {\n if (!isMeasuring && layoutSnapshot.contentHeight > 0) {\n let secondFrame: number | undefined;\n const firstFrame = requestAnimationFrame(() => {\n secondFrame = requestAnimationFrame(() => {\n onLayoutReady?.();\n });\n });\n\n return () => {\n cancelAnimationFrame(firstFrame);\n if (secondFrame !== undefined) {\n cancelAnimationFrame(secondFrame);\n }\n };\n }\n }, [isMeasuring, layoutSnapshot.contentHeight, onLayoutReady]);\n\n useEffect(() => {\n const pendingFocusLegendItemIndex = pendingFocusLegendItemIndexRef.current;\n if (!isExpanded || pendingFocusLegendItemIndex === null) {\n return;\n }\n\n const legendItems = legendContentRef.current?.querySelectorAll<HTMLElement>(\n '.ndl-chart-legend-item',\n );\n legendItems?.[pendingFocusLegendItemIndex]?.focus();\n pendingFocusLegendItemIndexRef.current = null;\n }, [isExpanded]);\n\n const handleLegendActionClick = useCallback(() => {\n if (isExpanded) {\n collapseLegend();\n return;\n }\n\n pendingFocusLegendItemIndexRef.current = layoutSnapshot.visibleItemCount;\n expandLegend();\n }, [\n collapseLegend,\n expandLegend,\n isExpanded,\n layoutSnapshot.visibleItemCount,\n ]);\n\n const classes = classNames(\n 'ndl-chart-legend',\n {\n 'ndl-chart-legend-calculating': !isExpanded && isMeasuring,\n 'ndl-chart-legend-collapsed': layoutSnapshot.hasOverflow && !isExpanded,\n 'ndl-chart-legend-expanded': layoutSnapshot.hasOverflow && isExpanded,\n 'ndl-chart-legend-hidden': !isLayoutReady,\n 'ndl-chart-legend-scrollable':\n layoutSnapshot.hasOverflow &&\n isExpanded &&\n layoutSnapshot.contentHeight > COLLAPSED_LEGEND_MAX_HEIGHT,\n 'ndl-chart-legend-wrapping': true,\n },\n className,\n );\n return (\n <div\n ref={legendContainerRef}\n className=\"ndl-chart-legend-container\"\n {...restProps}\n {...htmlAttributes}\n >\n <div\n className={classes}\n ref={legendContentRef}\n style={{\n height: legendHeight,\n maxHeight:\n layoutSnapshot.hasOverflow && isExpanded\n ? 'var(--ndl-chart-legend-expanded-max-height)'\n : layoutSnapshot.hasOverflow\n ? COLLAPSED_LEGEND_MAX_HEIGHT\n : undefined,\n }}\n >\n {childrenToRender}\n {layoutSnapshot.hasOverflow && (\n <TextLink\n as=\"button\"\n className=\"ndl-chart-legend-action\"\n htmlAttributes={{\n 'aria-expanded': isExpanded,\n onClick: handleLegendActionClick,\n type: 'button',\n }}\n >\n {isExpanded ? 'View less' : 'View more'}\n </TextLink>\n )}\n {isMeasuring && (\n <div\n aria-hidden=\"true\"\n className=\"ndl-chart-legend-measurement\"\n ref={legendMeasurementRef}\n >\n {childList}\n <TextLink\n as=\"button\"\n ref={viewMoreButtonMeasurementRef}\n className=\"ndl-chart-legend-action\"\n htmlAttributes={{\n tabIndex: -1,\n type: 'button',\n }}\n >\n View more\n </TextLink>\n </div>\n )}\n </div>\n </div>\n );\n};\n"]}
@@ -34,11 +34,11 @@ const LEGEND_SELECTION_EVENT_TYPES = [
34
34
  'legendselected',
35
35
  'legendunselected',
36
36
  ];
37
- const getAllSeriesSelected = (series) => Object.fromEntries(series.map((s) => { var _a; return [(_a = s.name) !== null && _a !== void 0 ? _a : '', true]; }));
37
+ const getAllSeriesSelected = (series) => Object.fromEntries(series.map((seriesItem) => { var _a; return [(_a = seriesItem.name) !== null && _a !== void 0 ? _a : '', true]; }));
38
38
  const hasSelectionForCurrentSeries = (selection, series) => {
39
39
  const selectedNames = Object.keys(selection);
40
40
  return (selectedNames.length === series.length &&
41
- series.every((s) => { var _a; return Object.prototype.hasOwnProperty.call(selection, (_a = s.name) !== null && _a !== void 0 ? _a : ''); }));
41
+ series.every((seriesItem) => { var _a; return Object.prototype.hasOwnProperty.call(selection, (_a = seriesItem.name) !== null && _a !== void 0 ? _a : ''); }));
42
42
  };
43
43
  const filterThresholdLineSelection = (selected) => Object.fromEntries(Object.entries(selected).filter(([key]) => { var _a; return !((_a = (0, threshold_1.isThresholdLine)(key)) !== null && _a !== void 0 ? _a : false); }));
44
44
  const clearTimeoutRef = (timeoutRef) => {
@@ -77,8 +77,8 @@ function useLegendSelection({ series }) {
77
77
  var _a, _b, _c;
78
78
  const prev = (_a = legendSelectedRef.current) !== null && _a !== void 0 ? _a : {};
79
79
  const next = {};
80
- for (const s of series) {
81
- const name = (_b = s.name) !== null && _b !== void 0 ? _b : '';
80
+ for (const seriesItem of series) {
81
+ const name = (_b = seriesItem.name) !== null && _b !== void 0 ? _b : '';
82
82
  next[name] = (_c = prev[name]) !== null && _c !== void 0 ? _c : true;
83
83
  }
84
84
  setSelectedSeries(next);
@@ -1 +1 @@
1
- {"version":3,"file":"use-legend-interactions.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-interactions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type EChartsType, getInstanceByDom } from 'echarts';\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport type { LegendProps } from '../utils/chart-types';\nimport {\n highlightOrDownplaySeries,\n resetAllSeriesHighlight,\n} from '../utils/legend-utils';\nimport { isThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nconst LEGEND_HOVER_HIGHLIGHT_DELAY_MS = 80;\nconst LEGEND_SELECTION_EVENT_TYPES = [\n 'legendselectchanged',\n 'legendselectall',\n 'legendselected',\n 'legendunselected',\n] as const;\n\ntype LegendSeries = LegendProps['series'];\ntype LegendSelectionEventType = (typeof LEGEND_SELECTION_EVENT_TYPES)[number];\n\ntype LegendSelectionEventParams = {\n selected?: Record<string, boolean> | null;\n};\n\ntype UseLegendHoverHighlightParams = {\n selectedSeries: Record<string, boolean>;\n series: LegendSeries;\n};\n\ntype UseLegendSelectionParams = {\n series: LegendProps['series'];\n};\n\nconst getAllSeriesSelected = (series: LegendProps['series']) =>\n Object.fromEntries(series.map((s) => [s.name ?? '', true]));\n\nconst hasSelectionForCurrentSeries = (\n selection: Record<string, boolean>,\n series: LegendProps['series'],\n) => {\n const selectedNames = Object.keys(selection);\n\n return (\n selectedNames.length === series.length &&\n series.every((s) =>\n Object.prototype.hasOwnProperty.call(selection, s.name ?? ''),\n )\n );\n};\n\nconst filterThresholdLineSelection = (selected: Record<string, boolean>) =>\n Object.fromEntries(\n Object.entries(selected).filter(\n ([key]) => !(isThresholdLine(key) ?? false),\n ),\n );\n\nconst clearTimeoutRef = (\n timeoutRef: MutableRefObject<ReturnType<typeof setTimeout> | null>,\n) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n};\n\nconst createLegendSelectionEventHandler =\n (\n chart: EChartsType,\n eventType: LegendSelectionEventType,\n setSelectedSeries: Dispatch<SetStateAction<Record<string, boolean>>>,\n ) =>\n (params: unknown) => {\n if (\n typeof params !== 'object' ||\n params === null ||\n !('selected' in params) ||\n params.selected === null\n ) {\n return;\n }\n\n if (eventType === 'legendselectchanged') {\n resetAllSeriesHighlight(chart);\n }\n\n setSelectedSeries(\n filterThresholdLineSelection(\n (params as LegendSelectionEventParams).selected ?? {},\n ),\n );\n };\n\n/**\n * Owns React legend selection and keeps it synchronized with ECharts.\n *\n * Current series changes preserve existing selection by name, new series default\n * to visible, removed series are dropped, and ECharts legend events update the\n * React state used to render legend items.\n */\nexport function useLegendSelection({ series }: UseLegendSelectionParams) {\n const { chartEchartRef, legendSelectedRef } = useChartRefsContext();\n const initialSelected = useMemo(() => getAllSeriesSelected(series), [series]);\n const [selectedSeries, setSelectedSeries] =\n useState<Record<string, boolean>>(initialSelected);\n\n const renderedSelectedSeries = hasSelectionForCurrentSeries(\n selectedSeries,\n series,\n )\n ? selectedSeries\n : initialSelected;\n\n useEffect(() => {\n const prev = legendSelectedRef.current ?? {};\n const next: Record<string, boolean> = {};\n\n for (const s of series) {\n const name = s.name ?? '';\n next[name] = prev[name] ?? true;\n }\n\n setSelectedSeries(next);\n }, [legendSelectedRef, series]);\n\n useEffect(() => {\n legendSelectedRef.current = selectedSeries;\n }, [legendSelectedRef, selectedSeries]);\n\n useEffect(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n if (!chart) {\n return;\n }\n\n const eventHandlers = LEGEND_SELECTION_EVENT_TYPES.map((eventType) => {\n const handler = createLegendSelectionEventHandler(\n chart,\n eventType,\n setSelectedSeries,\n );\n chart.on(eventType, handler);\n\n return { eventType, handler };\n });\n\n return () => {\n eventHandlers.forEach(({ eventType, handler }) => {\n chart.off(eventType, handler);\n });\n };\n }, [chartEchartRef]);\n\n return { renderedSelectedSeries };\n}\n\n/**\n * Creates a delayed ECharts highlighter for legend item hover state.\n *\n * Legend hover moves often happen as a quick leave/enter pair between adjacent\n * items. Keeping separate highlight and downplay timers lets the next hover\n * cancel the previous opposite action, preventing the chart from flickering\n * between emphasized and reset states. Deselected legend items are ignored so\n * hidden series do not get emphasized through hover.\n */\nexport function useLegendHoverHighlight({\n selectedSeries,\n series,\n}: UseLegendHoverHighlightParams) {\n const { chartEchartRef } = useChartRefsContext();\n const highlightTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n const downplayTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n clearTimeoutRef(highlightTimeOut);\n clearTimeoutRef(downplayTimeOut);\n };\n }, []);\n\n const toggleHighlight = useCallback(\n (\n seriesToUpdate: { name: string; color: string },\n shouldHighlight: boolean,\n ) => {\n const isDeselected =\n seriesToUpdate.name === undefined\n ? false\n : !selectedSeries[seriesToUpdate.name];\n\n if (isDeselected) {\n return;\n }\n\n const timeoutToClear = shouldHighlight\n ? downplayTimeOut\n : highlightTimeOut;\n const timeoutToSet = shouldHighlight ? highlightTimeOut : downplayTimeOut;\n\n if (timeoutToClear.current) {\n clearTimeout(timeoutToClear.current);\n }\n\n timeoutToSet.current = setTimeout(() => {\n highlightOrDownplaySeries(\n chartEchartRef,\n series,\n selectedSeries,\n [seriesToUpdate],\n shouldHighlight ? 'highlight' : 'downplay',\n );\n }, LEGEND_HOVER_HIGHLIGHT_DELAY_MS);\n },\n [chartEchartRef, selectedSeries, series],\n );\n\n return { toggleHighlight };\n}\n"]}
1
+ {"version":3,"file":"use-legend-interactions.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-interactions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type EChartsType, getInstanceByDom } from 'echarts';\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport type { LegendProps } from '../utils/chart-types';\nimport {\n highlightOrDownplaySeries,\n resetAllSeriesHighlight,\n} from '../utils/legend-utils';\nimport { isThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nconst LEGEND_HOVER_HIGHLIGHT_DELAY_MS = 80;\nconst LEGEND_SELECTION_EVENT_TYPES = [\n 'legendselectchanged',\n 'legendselectall',\n 'legendselected',\n 'legendunselected',\n] as const;\n\ntype LegendSeries = LegendProps['series'];\ntype LegendSelectionEventType = (typeof LEGEND_SELECTION_EVENT_TYPES)[number];\n\ntype LegendSelectionEventParams = {\n selected?: Record<string, boolean> | null;\n};\n\ntype UseLegendHoverHighlightParams = {\n selectedSeries: Record<string, boolean>;\n series: LegendSeries;\n};\n\ntype UseLegendSelectionParams = {\n series: LegendProps['series'];\n};\n\nconst getAllSeriesSelected = (series: LegendProps['series']) =>\n Object.fromEntries(series.map((seriesItem) => [seriesItem.name ?? '', true]));\n\nconst hasSelectionForCurrentSeries = (\n selection: Record<string, boolean>,\n series: LegendProps['series'],\n) => {\n const selectedNames = Object.keys(selection);\n\n return (\n selectedNames.length === series.length &&\n series.every((seriesItem) =>\n Object.prototype.hasOwnProperty.call(selection, seriesItem.name ?? ''),\n )\n );\n};\n\nconst filterThresholdLineSelection = (selected: Record<string, boolean>) =>\n Object.fromEntries(\n Object.entries(selected).filter(\n ([key]) => !(isThresholdLine(key) ?? false),\n ),\n );\n\nconst clearTimeoutRef = (\n timeoutRef: MutableRefObject<ReturnType<typeof setTimeout> | null>,\n) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n};\n\nconst createLegendSelectionEventHandler =\n (\n chart: EChartsType,\n eventType: LegendSelectionEventType,\n setSelectedSeries: Dispatch<SetStateAction<Record<string, boolean>>>,\n ) =>\n (params: unknown) => {\n if (\n typeof params !== 'object' ||\n params === null ||\n !('selected' in params) ||\n params.selected === null\n ) {\n return;\n }\n\n if (eventType === 'legendselectchanged') {\n resetAllSeriesHighlight(chart);\n }\n\n setSelectedSeries(\n filterThresholdLineSelection(\n (params as LegendSelectionEventParams).selected ?? {},\n ),\n );\n };\n\n/**\n * Owns React legend selection and keeps it synchronized with ECharts.\n *\n * Current series changes preserve existing selection by name, new series default\n * to visible, removed series are dropped, and ECharts legend events update the\n * React state used to render legend items.\n */\nexport function useLegendSelection({ series }: UseLegendSelectionParams) {\n const { chartEchartRef, legendSelectedRef } = useChartRefsContext();\n const initialSelected = useMemo(() => getAllSeriesSelected(series), [series]);\n const [selectedSeries, setSelectedSeries] =\n useState<Record<string, boolean>>(initialSelected);\n\n const renderedSelectedSeries = hasSelectionForCurrentSeries(\n selectedSeries,\n series,\n )\n ? selectedSeries\n : initialSelected;\n\n useEffect(() => {\n const prev = legendSelectedRef.current ?? {};\n const next: Record<string, boolean> = {};\n\n for (const seriesItem of series) {\n const name = seriesItem.name ?? '';\n next[name] = prev[name] ?? true;\n }\n\n setSelectedSeries(next);\n }, [legendSelectedRef, series]);\n\n useEffect(() => {\n legendSelectedRef.current = selectedSeries;\n }, [legendSelectedRef, selectedSeries]);\n\n useEffect(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n if (!chart) {\n return;\n }\n\n const eventHandlers = LEGEND_SELECTION_EVENT_TYPES.map((eventType) => {\n const handler = createLegendSelectionEventHandler(\n chart,\n eventType,\n setSelectedSeries,\n );\n chart.on(eventType, handler);\n\n return { eventType, handler };\n });\n\n return () => {\n eventHandlers.forEach(({ eventType, handler }) => {\n chart.off(eventType, handler);\n });\n };\n }, [chartEchartRef]);\n\n return { renderedSelectedSeries };\n}\n\n/**\n * Creates a delayed ECharts highlighter for legend item hover state.\n *\n * Legend hover moves often happen as a quick leave/enter pair between adjacent\n * items. Keeping separate highlight and downplay timers lets the next hover\n * cancel the previous opposite action, preventing the chart from flickering\n * between emphasized and reset states. Deselected legend items are ignored so\n * hidden series do not get emphasized through hover.\n */\nexport function useLegendHoverHighlight({\n selectedSeries,\n series,\n}: UseLegendHoverHighlightParams) {\n const { chartEchartRef } = useChartRefsContext();\n const highlightTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n const downplayTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n clearTimeoutRef(highlightTimeOut);\n clearTimeoutRef(downplayTimeOut);\n };\n }, []);\n\n const toggleHighlight = useCallback(\n (\n seriesToUpdate: { name: string; color: string },\n shouldHighlight: boolean,\n ) => {\n const isDeselected =\n seriesToUpdate.name === undefined\n ? false\n : !selectedSeries[seriesToUpdate.name];\n\n if (isDeselected) {\n return;\n }\n\n const timeoutToClear = shouldHighlight\n ? downplayTimeOut\n : highlightTimeOut;\n const timeoutToSet = shouldHighlight ? highlightTimeOut : downplayTimeOut;\n\n if (timeoutToClear.current) {\n clearTimeout(timeoutToClear.current);\n }\n\n timeoutToSet.current = setTimeout(() => {\n highlightOrDownplaySeries(\n chartEchartRef,\n series,\n selectedSeries,\n [seriesToUpdate],\n shouldHighlight ? 'highlight' : 'downplay',\n );\n }, LEGEND_HOVER_HIGHLIGHT_DELAY_MS);\n },\n [chartEchartRef, selectedSeries, series],\n );\n\n return { toggleHighlight };\n}\n"]}
@@ -134,7 +134,7 @@ function useLegendSeries({ chartOption, isWaitingForFirstResize, }) {
134
134
  const chart = (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
135
135
  const optionSeries = (_a = chartOption === null || chartOption === void 0 ? void 0 : chartOption.series) !== null && _a !== void 0 ? _a : [];
136
136
  const optionDataset = chartOption === null || chartOption === void 0 ? void 0 : chartOption.dataset;
137
- const isAllLegendSeriesVisible = Object.values(legendSelectedRef.current).every((v) => v);
137
+ const isAllLegendSeriesVisible = Object.values(legendSelectedRef.current).every((isVisible) => isVisible);
138
138
  const legendSeries = [];
139
139
  if (Array.isArray(optionSeries)) {
140
140
  optionSeries.forEach((currentSeries, index) => {
@@ -1 +1 @@
1
- {"version":3,"file":"use-legend-series.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-series.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n DatasetComponentOption,\n EChartsOption,\n EChartsType,\n} from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useMemo } from 'react';\n\nimport type {\n LegendProps,\n NeedleSeries,\n SeriesOption,\n} from '../utils/chart-types';\nimport { isThresholdLine } from '../utils/threshold';\nimport { type ChartRefs, useChartRefsContext } from './use-chart-refs';\n\ntype UseLegendSeriesParams = {\n chartOption: EChartsOption | undefined;\n isWaitingForFirstResize: boolean;\n};\n\ntype LegendSeries = LegendProps['series'];\ntype NeedleSeriesItem = NeedleSeries[number];\ntype SeriesWithDataset = SeriesOption & {\n datasetId?: string;\n datasetIndex?: number;\n};\n\ntype PieLegendSeriesParams = {\n chart: EChartsType | undefined;\n dataset: DatasetComponentOption | undefined;\n encodedItemName: unknown;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n seriesIndex: number;\n};\n\ntype GetCachedLegendColorParams = {\n chart: EChartsType | undefined;\n dataIndexInside: number;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n name: string;\n seriesIndex: number;\n};\n\nconst isThresholdLineSeries = (series: NeedleSeriesItem) =>\n series.type === 'line' &&\n typeof series.name === 'string' &&\n isThresholdLine(series.name);\n\nconst getDatasetForSeries = (\n optionDataset: EChartsOption['dataset'],\n series: SeriesWithDataset,\n) => {\n const datasetList = Array.isArray(optionDataset)\n ? optionDataset\n : [optionDataset];\n\n if (series.datasetId && Array.isArray(optionDataset)) {\n return datasetList.find((dataset) => dataset?.id === series.datasetId);\n }\n\n if (series.datasetIndex !== undefined) {\n return datasetList[series.datasetIndex];\n }\n\n return datasetList[0];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst getCachedLegendColor = ({\n chart,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n dataIndexInside,\n}: GetCachedLegendColorParams) => {\n const freshColor = chart?.getVisual(\n { dataIndexInside, seriesIndex },\n 'color',\n );\n\n if (isAllVisible && typeof freshColor === 'string') {\n legendColorCacheRef.current.set(name, freshColor);\n }\n\n return (\n legendColorCacheRef.current.get(name) ??\n (typeof freshColor === 'string' ? freshColor : '#000000')\n );\n};\n\nconst createPieLegendSeriesItem = ({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n}: GetCachedLegendColorParams) => ({\n color: getCachedLegendColor({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n }),\n name,\n});\n\nconst getPieLegendSeriesFromArrayRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || !Array.isArray(source[0])) {\n return [];\n }\n\n const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);\n if (itemNameIndex === -1) {\n return [];\n }\n\n return source.slice(1).flatMap((row, rowIndex) => {\n if (!Array.isArray(row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[itemNameIndex]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeriesFromObjectRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || typeof encodedItemName !== 'string') {\n return [];\n }\n\n return source.flatMap((row, rowIndex) => {\n if (!isRecord(row) || !(encodedItemName in row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[encodedItemName]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeries = (params: PieLegendSeriesParams): LegendSeries => {\n const source = params.dataset?.source;\n if (!Array.isArray(source) || source.length === 0) {\n return [];\n }\n\n return Array.isArray(source[0])\n ? getPieLegendSeriesFromArrayRows(params)\n : getPieLegendSeriesFromObjectRows(params);\n};\n\n/**\n * Derives Needle legend rows from ECharts' normalized option and visual state.\n *\n * Standard series map one-to-one with legend items. Pie charts instead create a\n * legend item for each data row, so the hook reads the encoded item-name column\n * from the dataset and asks ECharts for each slice color. Fresh colors are\n * cached while all slices are visible because ECharts reports dimmed colors for\n * deselected slices.\n *\n * The hook waits until the first chart resize has completed so color lookups run\n * against an initialized ECharts instance.\n */\nexport function useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n}: UseLegendSeriesParams): LegendSeries | undefined {\n const { chartEchartRef, legendColorCacheRef, legendSelectedRef } =\n useChartRefsContext();\n\n return useMemo(() => {\n if (chartEchartRef.current === null || isWaitingForFirstResize) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n const optionSeries = (chartOption?.series as NeedleSeries) ?? [];\n const optionDataset = chartOption?.dataset;\n const isAllLegendSeriesVisible = Object.values(\n legendSelectedRef.current,\n ).every((v) => v);\n\n const legendSeries: LegendSeries = [];\n if (Array.isArray(optionSeries)) {\n optionSeries.forEach((currentSeries, index) => {\n if (currentSeries === null) {\n return;\n } else if (isThresholdLineSeries(currentSeries)) {\n return;\n } else if (currentSeries.type === 'pie') {\n legendSeries.push(\n ...getPieLegendSeries({\n chart,\n dataset: getDatasetForSeries(\n optionDataset,\n currentSeries as SeriesWithDataset,\n ),\n encodedItemName: currentSeries.encode?.itemName,\n isAllVisible: isAllLegendSeriesVisible,\n legendColorCacheRef,\n seriesIndex: index,\n }),\n );\n return;\n } else {\n const name = currentSeries.name;\n\n if (name === undefined) {\n return;\n }\n\n const color = chart?.getVisual({ seriesIndex: index }, 'color');\n legendSeries.push({\n color: typeof color === 'string' ? color : '#000000',\n name: String(name),\n });\n }\n });\n }\n return legendSeries;\n }, [\n chartEchartRef,\n chartOption,\n isWaitingForFirstResize,\n legendColorCacheRef,\n legendSelectedRef,\n ]);\n}\n"]}
1
+ {"version":3,"file":"use-legend-series.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-series.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n DatasetComponentOption,\n EChartsOption,\n EChartsType,\n} from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useMemo } from 'react';\n\nimport type {\n LegendProps,\n NeedleSeries,\n SeriesOption,\n} from '../utils/chart-types';\nimport { isThresholdLine } from '../utils/threshold';\nimport { type ChartRefs, useChartRefsContext } from './use-chart-refs';\n\ntype UseLegendSeriesParams = {\n chartOption: EChartsOption | undefined;\n isWaitingForFirstResize: boolean;\n};\n\ntype LegendSeries = LegendProps['series'];\ntype NeedleSeriesItem = NeedleSeries[number];\ntype SeriesWithDataset = SeriesOption & {\n datasetId?: string;\n datasetIndex?: number;\n};\n\ntype PieLegendSeriesParams = {\n chart: EChartsType | undefined;\n dataset: DatasetComponentOption | undefined;\n encodedItemName: unknown;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n seriesIndex: number;\n};\n\ntype GetCachedLegendColorParams = {\n chart: EChartsType | undefined;\n dataIndexInside: number;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n name: string;\n seriesIndex: number;\n};\n\nconst isThresholdLineSeries = (series: NeedleSeriesItem) =>\n series.type === 'line' &&\n typeof series.name === 'string' &&\n isThresholdLine(series.name);\n\nconst getDatasetForSeries = (\n optionDataset: EChartsOption['dataset'],\n series: SeriesWithDataset,\n) => {\n const datasetList = Array.isArray(optionDataset)\n ? optionDataset\n : [optionDataset];\n\n if (series.datasetId && Array.isArray(optionDataset)) {\n return datasetList.find((dataset) => dataset?.id === series.datasetId);\n }\n\n if (series.datasetIndex !== undefined) {\n return datasetList[series.datasetIndex];\n }\n\n return datasetList[0];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst getCachedLegendColor = ({\n chart,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n dataIndexInside,\n}: GetCachedLegendColorParams) => {\n const freshColor = chart?.getVisual(\n { dataIndexInside, seriesIndex },\n 'color',\n );\n\n if (isAllVisible && typeof freshColor === 'string') {\n legendColorCacheRef.current.set(name, freshColor);\n }\n\n return (\n legendColorCacheRef.current.get(name) ??\n (typeof freshColor === 'string' ? freshColor : '#000000')\n );\n};\n\nconst createPieLegendSeriesItem = ({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n}: GetCachedLegendColorParams) => ({\n color: getCachedLegendColor({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n }),\n name,\n});\n\nconst getPieLegendSeriesFromArrayRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || !Array.isArray(source[0])) {\n return [];\n }\n\n const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);\n if (itemNameIndex === -1) {\n return [];\n }\n\n return source.slice(1).flatMap((row, rowIndex) => {\n if (!Array.isArray(row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[itemNameIndex]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeriesFromObjectRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || typeof encodedItemName !== 'string') {\n return [];\n }\n\n return source.flatMap((row, rowIndex) => {\n if (!isRecord(row) || !(encodedItemName in row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[encodedItemName]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeries = (params: PieLegendSeriesParams): LegendSeries => {\n const source = params.dataset?.source;\n if (!Array.isArray(source) || source.length === 0) {\n return [];\n }\n\n return Array.isArray(source[0])\n ? getPieLegendSeriesFromArrayRows(params)\n : getPieLegendSeriesFromObjectRows(params);\n};\n\n/**\n * Derives Needle legend rows from ECharts' normalized option and visual state.\n *\n * Standard series map one-to-one with legend items. Pie charts instead create a\n * legend item for each data row, so the hook reads the encoded item-name column\n * from the dataset and asks ECharts for each slice color. Fresh colors are\n * cached while all slices are visible because ECharts reports dimmed colors for\n * deselected slices.\n *\n * The hook waits until the first chart resize has completed so color lookups run\n * against an initialized ECharts instance.\n */\nexport function useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n}: UseLegendSeriesParams): LegendSeries | undefined {\n const { chartEchartRef, legendColorCacheRef, legendSelectedRef } =\n useChartRefsContext();\n\n return useMemo(() => {\n if (chartEchartRef.current === null || isWaitingForFirstResize) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n const optionSeries = (chartOption?.series as NeedleSeries) ?? [];\n const optionDataset = chartOption?.dataset;\n const isAllLegendSeriesVisible = Object.values(\n legendSelectedRef.current,\n ).every((isVisible) => isVisible);\n\n const legendSeries: LegendSeries = [];\n if (Array.isArray(optionSeries)) {\n optionSeries.forEach((currentSeries, index) => {\n if (currentSeries === null) {\n return;\n } else if (isThresholdLineSeries(currentSeries)) {\n return;\n } else if (currentSeries.type === 'pie') {\n legendSeries.push(\n ...getPieLegendSeries({\n chart,\n dataset: getDatasetForSeries(\n optionDataset,\n currentSeries as SeriesWithDataset,\n ),\n encodedItemName: currentSeries.encode?.itemName,\n isAllVisible: isAllLegendSeriesVisible,\n legendColorCacheRef,\n seriesIndex: index,\n }),\n );\n return;\n } else {\n const name = currentSeries.name;\n\n if (name === undefined) {\n return;\n }\n\n const color = chart?.getVisual({ seriesIndex: index }, 'color');\n legendSeries.push({\n color: typeof color === 'string' ? color : '#000000',\n name: String(name),\n });\n }\n });\n }\n return legendSeries;\n }, [\n chartEchartRef,\n chartOption,\n isWaitingForFirstResize,\n legendColorCacheRef,\n legendSelectedRef,\n ]);\n}\n"]}
@@ -36,7 +36,7 @@ const useLegendVisibility = (selectedSeries) => {
36
36
  name: name,
37
37
  type: 'legendSelect',
38
38
  });
39
- const otherNames = Object.keys(selectedSeries).filter((n) => n !== name);
39
+ const otherNames = Object.keys(selectedSeries).filter((seriesName) => seriesName !== name);
40
40
  otherNames.forEach((name) => {
41
41
  if ((0, threshold_1.isThresholdLine)(name)) {
42
42
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-legend-visibility.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-visibility.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,qCAA2C;AAC3C,iCAAoC;AAEpC,kDAAqD;AACrD,qDAAuD;AAEhD,MAAM,mBAAmB,GAAG,CACjC,cAAuC,EACvC,EAAE;IACF,MAAM,EAAE,cAAc,EAAE,GAAG,IAAA,oCAAmB,GAAE,CAAC;IAEjD,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,IAAwB,EAAE,EAAE;QAC3B,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;YACpB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACzE,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,IAAI,IAAA,2BAAe,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;gBACpB,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,gBAAgB;aACvB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,cAAc,EAAE,cAAc,CAAC,CACjC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACrC,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;YACpB,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB;;;;;;;;;;OAUG;IACH,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CACE,IAAwB,EACxB,mBAA4B,EAC5B,aAAsB,EACtB,EAAE;QACF,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,EAAE,CAAC;QAClB,CAAC;aAAM,IAAI,mBAAmB,EAAE,CAAC;YAC/B,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;gBACpB,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EACD,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC,CAChD,CAAC;IAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC;AACpC,CAAC,CAAC;AAlFW,QAAA,mBAAmB,uBAkF9B","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { getInstanceByDom } from 'echarts';\nimport { useCallback } from 'react';\n\nimport { isThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nexport const useLegendVisibility = (\n selectedSeries: Record<string, boolean>,\n) => {\n const { chartEchartRef } = useChartRefsContext();\n\n const setOnlyVisible = useCallback(\n (name: string | undefined) => {\n if (chartEchartRef.current === null) {\n return;\n }\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n name: name,\n type: 'legendSelect',\n });\n\n const otherNames = Object.keys(selectedSeries).filter((n) => n !== name);\n otherNames.forEach((name) => {\n if (isThresholdLine(name)) {\n return;\n }\n\n chart?.dispatchAction({\n name: name,\n type: 'legendUnSelect',\n });\n });\n },\n [chartEchartRef, selectedSeries],\n );\n\n const setAllVisible = useCallback(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n type: 'legendAllSelect',\n });\n }, [chartEchartRef]);\n\n /**\n * Toggle the visibility of a legend series\n *\n * The toggle logic depends on the current state of the series:\n * - If only the legend series that was selected is visible: show all series\n * - If all series are visible: hide all except the series that was selected\n * - Otherwise: toggle the legend series\n *\n * The isOnlyVisible and isAllSeriesSelected states can't be calculated in this\n * function since different legend types require different logic.\n */\n const toggleLegendVisibility = useCallback(\n (\n name: string | undefined,\n isAllSeriesSelected: boolean,\n isOnlyVisible: boolean,\n ) => {\n if (chartEchartRef.current === null || name === undefined) {\n return;\n }\n\n if (isOnlyVisible) {\n setAllVisible();\n } else if (isAllSeriesSelected) {\n setOnlyVisible(name);\n } else {\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n name: name,\n type: 'legendToggleSelect',\n });\n }\n },\n [chartEchartRef, setOnlyVisible, setAllVisible],\n );\n\n return { toggleLegendVisibility };\n};\n"]}
1
+ {"version":3,"file":"use-legend-visibility.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-visibility.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,qCAA2C;AAC3C,iCAAoC;AAEpC,kDAAqD;AACrD,qDAAuD;AAEhD,MAAM,mBAAmB,GAAG,CACjC,cAAuC,EACvC,EAAE;IACF,MAAM,EAAE,cAAc,EAAE,GAAG,IAAA,oCAAmB,GAAE,CAAC;IAEjD,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,IAAwB,EAAE,EAAE;QAC3B,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;YACpB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CACnD,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,KAAK,IAAI,CACpC,CAAC;QACF,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,IAAI,IAAA,2BAAe,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;gBACpB,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,gBAAgB;aACvB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,cAAc,EAAE,cAAc,CAAC,CACjC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACrC,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;YACpB,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB;;;;;;;;;;OAUG;IACH,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CACE,IAAwB,EACxB,mBAA4B,EAC5B,aAAsB,EACtB,EAAE;QACF,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,EAAE,CAAC;QAClB,CAAC;aAAM,IAAI,mBAAmB,EAAE,CAAC;YAC/B,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAEvD,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,cAAc,CAAC;gBACpB,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EACD,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC,CAChD,CAAC;IAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC;AACpC,CAAC,CAAC;AApFW,QAAA,mBAAmB,uBAoF9B","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { getInstanceByDom } from 'echarts';\nimport { useCallback } from 'react';\n\nimport { isThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nexport const useLegendVisibility = (\n selectedSeries: Record<string, boolean>,\n) => {\n const { chartEchartRef } = useChartRefsContext();\n\n const setOnlyVisible = useCallback(\n (name: string | undefined) => {\n if (chartEchartRef.current === null) {\n return;\n }\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n name: name,\n type: 'legendSelect',\n });\n\n const otherNames = Object.keys(selectedSeries).filter(\n (seriesName) => seriesName !== name,\n );\n otherNames.forEach((name) => {\n if (isThresholdLine(name)) {\n return;\n }\n\n chart?.dispatchAction({\n name: name,\n type: 'legendUnSelect',\n });\n });\n },\n [chartEchartRef, selectedSeries],\n );\n\n const setAllVisible = useCallback(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n type: 'legendAllSelect',\n });\n }, [chartEchartRef]);\n\n /**\n * Toggle the visibility of a legend series\n *\n * The toggle logic depends on the current state of the series:\n * - If only the legend series that was selected is visible: show all series\n * - If all series are visible: hide all except the series that was selected\n * - Otherwise: toggle the legend series\n *\n * The isOnlyVisible and isAllSeriesSelected states can't be calculated in this\n * function since different legend types require different logic.\n */\n const toggleLegendVisibility = useCallback(\n (\n name: string | undefined,\n isAllSeriesSelected: boolean,\n isOnlyVisible: boolean,\n ) => {\n if (chartEchartRef.current === null || name === undefined) {\n return;\n }\n\n if (isOnlyVisible) {\n setAllVisible();\n } else if (isAllSeriesSelected) {\n setOnlyVisible(name);\n } else {\n const chart = getInstanceByDom(chartEchartRef.current);\n\n chart?.dispatchAction({\n name: name,\n type: 'legendToggleSelect',\n });\n }\n },\n [chartEchartRef, setOnlyVisible, setAllVisible],\n );\n\n return { toggleLegendVisibility };\n};\n"]}
@@ -28,7 +28,7 @@ const react_1 = require("react");
28
28
  const POINT_COUNT = 180;
29
29
  const zoomHarnessDataset = [
30
30
  ['time', 'value'],
31
- ...Array.from({ length: POINT_COUNT }, (_, index) => [
31
+ ...Array.from({ length: POINT_COUNT }, (_unused, index) => [
32
32
  index,
33
33
  Number((40 + Math.sin(index / 6) * 12).toFixed(2)),
34
34
  ]),
@@ -73,6 +73,8 @@ const ChartZoomHarness = ({ settings, }) => {
73
73
  }, []);
74
74
  return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, style: { height: '420px', width: '900px' }, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "force-rerender", onClick: () => setRerenderCount((count) => count + 1), children: "Re-render" }), (0, jsx_runtime_1.jsx)("div", { className: "ndl-chart", style: { height: '380px', width: '100%' }, children: (0, jsx_runtime_1.jsx)(react_charts_1.Chart, { callbacks: { onZoom: handleZoom }, dataset: [{ source: zoomHarnessDataset }], series: [
75
75
  {
76
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
77
+ // oxlint-disable-next-line id-length
76
78
  encode: { x: 'time', y: 'value' },
77
79
  name: 'Value',
78
80
  type: 'line',
@@ -1 +1 @@
1
- {"version":3,"file":"ChartZoomHarness.js","sourceRoot":"","sources":["../../../../src/charts/tests/ChartZoomHarness.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport { getInstanceByDom } from 'echarts';\nimport {\n type ComponentProps,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\ntype ChartSettings = ComponentProps<typeof Chart>['settings'];\n\nexport type ZoomCall = { endValue: number; startValue: number };\n\nexport type ZoomHarnessApi = {\n /** Applied zoom windows, in data values, as ECharts currently has them. */\n getAppliedZoomWindows: () => ZoomCall[];\n /** Every `callbacks.onZoom` invocation the consumer received. */\n getZoomCalls: () => ZoomCall[];\n /** Data value at a pixel offset inside the chart element. */\n pixelToValue: (pixelX: number) => number;\n resetZoomCalls: () => void;\n};\n\ntype HarnessWindow = Window & { chartZoomHarness?: ZoomHarnessApi };\n\nconst POINT_COUNT = 180;\n\nconst zoomHarnessDataset = [\n ['time', 'value'],\n ...Array.from({ length: POINT_COUNT }, (_, index) => [\n index,\n Number((40 + Math.sin(index / 6) * 12).toFixed(2)),\n ]),\n];\n\n/**\n * Reproduces the consumer setup from the metrics UI: a chart with toolbox\n * brush-zoom whose parent re-renders while the chart stays mounted, passing a\n * freshly built `option` object on every render.\n */\nexport const ChartZoomHarness = ({\n settings,\n}: {\n settings?: ChartSettings;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const zoomCallsRef = useRef<ZoomCall[]>([]);\n const [, setRerenderCount] = useState(0);\n\n const handleZoom = useCallback((zoom: ZoomCall) => {\n zoomCallsRef.current = [...zoomCallsRef.current, zoom];\n }, []);\n\n useEffect(() => {\n const getChart = () => {\n const echartElement =\n containerRef.current?.querySelector('.ndl-chart-echart');\n return echartElement instanceof HTMLElement\n ? getInstanceByDom(echartElement)\n : undefined;\n };\n\n (window as HarnessWindow).chartZoomHarness = {\n getAppliedZoomWindows: () => {\n const dataZoom = (\n getChart()?.getOption() as\n | { dataZoom?: { endValue?: number; startValue?: number }[] }\n | undefined\n )?.dataZoom;\n\n return (dataZoom ?? [])\n .filter(\n (item) =>\n item.startValue !== undefined && item.endValue !== undefined,\n )\n .map((item) => ({\n endValue: item.endValue as number,\n startValue: item.startValue as number,\n }));\n },\n getZoomCalls: () => zoomCallsRef.current,\n pixelToValue: (pixelX: number) =>\n getChart()?.convertFromPixel({ xAxisIndex: 0 }, pixelX) as number,\n resetZoomCalls: () => {\n zoomCallsRef.current = [];\n },\n };\n }, []);\n\n return (\n <div ref={containerRef} style={{ height: '420px', width: '900px' }}>\n <button\n type=\"button\"\n data-testid=\"force-rerender\"\n onClick={() => setRerenderCount((count) => count + 1)}\n >\n Re-render\n </button>\n <div className=\"ndl-chart\" style={{ height: '380px', width: '100%' }}>\n <Chart\n callbacks={{ onZoom: handleZoom }}\n dataset={[{ source: zoomHarnessDataset }]}\n series={[\n {\n encode: { x: 'time', y: 'value' },\n name: 'Value',\n type: 'line',\n },\n ]}\n settings={settings}\n xAxis={{ type: 'value' }}\n yAxis={{ type: 'value' }}\n option={{\n dataZoom: [\n {\n filterMode: 'none',\n type: 'inside',\n zoomOnMouseWheel: false,\n },\n ],\n toolbox: {\n feature: {\n dataZoom: {\n yAxisIndex: false,\n },\n },\n },\n }}\n />\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"ChartZoomHarness.js","sourceRoot":"","sources":["../../../../src/charts/tests/ChartZoomHarness.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport { getInstanceByDom } from 'echarts';\nimport {\n type ComponentProps,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\ntype ChartSettings = ComponentProps<typeof Chart>['settings'];\n\nexport type ZoomCall = { endValue: number; startValue: number };\n\nexport type ZoomHarnessApi = {\n /** Applied zoom windows, in data values, as ECharts currently has them. */\n getAppliedZoomWindows: () => ZoomCall[];\n /** Every `callbacks.onZoom` invocation the consumer received. */\n getZoomCalls: () => ZoomCall[];\n /** Data value at a pixel offset inside the chart element. */\n pixelToValue: (pixelX: number) => number;\n resetZoomCalls: () => void;\n};\n\ntype HarnessWindow = Window & { chartZoomHarness?: ZoomHarnessApi };\n\nconst POINT_COUNT = 180;\n\nconst zoomHarnessDataset = [\n ['time', 'value'],\n ...Array.from({ length: POINT_COUNT }, (_unused, index) => [\n index,\n Number((40 + Math.sin(index / 6) * 12).toFixed(2)),\n ]),\n];\n\n/**\n * Reproduces the consumer setup from the metrics UI: a chart with toolbox\n * brush-zoom whose parent re-renders while the chart stays mounted, passing a\n * freshly built `option` object on every render.\n */\nexport const ChartZoomHarness = ({\n settings,\n}: {\n settings?: ChartSettings;\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const zoomCallsRef = useRef<ZoomCall[]>([]);\n const [, setRerenderCount] = useState(0);\n\n const handleZoom = useCallback((zoom: ZoomCall) => {\n zoomCallsRef.current = [...zoomCallsRef.current, zoom];\n }, []);\n\n useEffect(() => {\n const getChart = () => {\n const echartElement =\n containerRef.current?.querySelector('.ndl-chart-echart');\n return echartElement instanceof HTMLElement\n ? getInstanceByDom(echartElement)\n : undefined;\n };\n\n (window as HarnessWindow).chartZoomHarness = {\n getAppliedZoomWindows: () => {\n const dataZoom = (\n getChart()?.getOption() as\n | { dataZoom?: { endValue?: number; startValue?: number }[] }\n | undefined\n )?.dataZoom;\n\n return (dataZoom ?? [])\n .filter(\n (item) =>\n item.startValue !== undefined && item.endValue !== undefined,\n )\n .map((item) => ({\n endValue: item.endValue as number,\n startValue: item.startValue as number,\n }));\n },\n getZoomCalls: () => zoomCallsRef.current,\n pixelToValue: (pixelX: number) =>\n getChart()?.convertFromPixel({ xAxisIndex: 0 }, pixelX) as number,\n resetZoomCalls: () => {\n zoomCallsRef.current = [];\n },\n };\n }, []);\n\n return (\n <div ref={containerRef} style={{ height: '420px', width: '900px' }}>\n <button\n type=\"button\"\n data-testid=\"force-rerender\"\n onClick={() => setRerenderCount((count) => count + 1)}\n >\n Re-render\n </button>\n <div className=\"ndl-chart\" style={{ height: '380px', width: '100%' }}>\n <Chart\n callbacks={{ onZoom: handleZoom }}\n dataset={[{ source: zoomHarnessDataset }]}\n series={[\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'time', y: 'value' },\n name: 'Value',\n type: 'line',\n },\n ]}\n settings={settings}\n xAxis={{ type: 'value' }}\n yAxis={{ type: 'value' }}\n option={{\n dataZoom: [\n {\n filterMode: 'none',\n type: 'inside',\n zoomOnMouseWheel: false,\n },\n ],\n toolbox: {\n feature: {\n dataZoom: {\n yAxisIndex: false,\n },\n },\n },\n }}\n />\n </div>\n </div>\n );\n};\n"]}
@@ -34,7 +34,7 @@ function PieChartWithRerenderComponent({ dataset1, dataset2, datasetNewCategorie
34
34
  : renderCount % 2 === 0
35
35
  ? dataset1
36
36
  : dataset2;
37
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '8px', marginBottom: '12px' }, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "rerender-button", onClick: () => setRenderCount((c) => c + 1), children: "Re-render" }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "switch-categories-button", onClick: () => setShouldUseNewCategories((v) => !v), children: "Switch categories" }), (0, jsx_runtime_1.jsx)("span", { "data-testid": "render-count", children: chartRenderCount.current })] }), (0, jsx_runtime_1.jsx)("div", { style: { height: '350px', width: '100%' }, children: (0, jsx_runtime_1.jsx)(react_charts_1.Chart, { legend: { show: true }, series: [
37
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '8px', marginBottom: '12px' }, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "rerender-button", onClick: () => setRenderCount((count) => count + 1), children: "Re-render" }), (0, jsx_runtime_1.jsx)("button", { type: "button", "data-testid": "switch-categories-button", onClick: () => setShouldUseNewCategories((value) => !value), children: "Switch categories" }), (0, jsx_runtime_1.jsx)("span", { "data-testid": "render-count", children: chartRenderCount.current })] }), (0, jsx_runtime_1.jsx)("div", { style: { height: '350px', width: '100%' }, children: (0, jsx_runtime_1.jsx)(react_charts_1.Chart, { legend: { show: true }, series: [
38
38
  {
39
39
  center: ['50%', '50%'],
40
40
  encode: { itemName: 'product', value: '2015' },
@@ -1 +1 @@
1
- {"version":3,"file":"PieChartWithRerender.js","sourceRoot":"","sources":["../../../../src/charts/tests/PieChartWithRerender.tsx"],"names":[],"mappings":";;AA+BA,sEAmDC;;AAlFD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0DAAgD;AAEhD,iCAAyC;AAQzC,SAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EACR,QAAQ,EACR,oBAAoB,GACM;IAC1B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAC5E,MAAM,gBAAgB,GAAG,IAAA,cAAM,EAAC,CAAC,CAAC,CAAC;IACnC,gBAAgB,CAAC,OAAO,IAAI,CAAC,CAAC;IAE9B,MAAM,cAAc,GAAG,sBAAsB;QAC3C,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,WAAW,GAAG,CAAC,KAAK,CAAC;YACrB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,QAAQ,CAAC;IAEf,OAAO,CACL,4CACE,iCAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAC/D,mCACE,IAAI,EAAC,QAAQ,iBACD,iBAAiB,EAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,0BAGpC,EACT,mCACE,IAAI,EAAC,QAAQ,iBACD,0BAA0B,EACtC,OAAO,EAAE,GAAG,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,kCAG5C,EACT,gDAAkB,cAAc,YAAE,gBAAgB,CAAC,OAAO,GAAQ,IAC9D,EACN,gCAAK,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAC5C,uBAAC,oBAAK,IACJ,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EACtB,MAAM,EAAE;wBACN;4BACE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;4BACtB,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;4BAC9C,MAAM,EAAE,KAAK;4BACb,IAAI,EAAE,KAAK;yBACZ;qBACF,EACD,OAAO,EAAE,cAAc,GACvB,GACE,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport type { EChartsOption } from 'echarts';\nimport { useRef, useState } from 'react';\n\ntype PieChartWithRerenderProps = {\n dataset1: EChartsOption['dataset'];\n dataset2: EChartsOption['dataset'];\n datasetNewCategories: EChartsOption['dataset'];\n};\n\nexport function PieChartWithRerenderComponent({\n dataset1,\n dataset2,\n datasetNewCategories,\n}: PieChartWithRerenderProps) {\n const [renderCount, setRenderCount] = useState(0);\n const [shouldUseNewCategories, setShouldUseNewCategories] = useState(false);\n const chartRenderCount = useRef(0);\n chartRenderCount.current += 1;\n\n const currentDataset = shouldUseNewCategories\n ? datasetNewCategories\n : renderCount % 2 === 0\n ? dataset1\n : dataset2;\n\n return (\n <div>\n <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>\n <button\n type=\"button\"\n data-testid=\"rerender-button\"\n onClick={() => setRenderCount((c) => c + 1)}\n >\n Re-render\n </button>\n <button\n type=\"button\"\n data-testid=\"switch-categories-button\"\n onClick={() => setShouldUseNewCategories((v) => !v)}\n >\n Switch categories\n </button>\n <span data-testid=\"render-count\">{chartRenderCount.current}</span>\n </div>\n <div style={{ height: '350px', width: '100%' }}>\n <Chart\n legend={{ show: true }}\n series={[\n {\n center: ['50%', '50%'],\n encode: { itemName: 'product', value: '2015' },\n radius: '90%',\n type: 'pie',\n },\n ]}\n dataset={currentDataset}\n />\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"PieChartWithRerender.js","sourceRoot":"","sources":["../../../../src/charts/tests/PieChartWithRerender.tsx"],"names":[],"mappings":";;AA+BA,sEAmDC;;AAlFD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0DAAgD;AAEhD,iCAAyC;AAQzC,SAAgB,6BAA6B,CAAC,EAC5C,QAAQ,EACR,QAAQ,EACR,oBAAoB,GACM;IAC1B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAC5E,MAAM,gBAAgB,GAAG,IAAA,cAAM,EAAC,CAAC,CAAC,CAAC;IACnC,gBAAgB,CAAC,OAAO,IAAI,CAAC,CAAC;IAE9B,MAAM,cAAc,GAAG,sBAAsB;QAC3C,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,WAAW,GAAG,CAAC,KAAK,CAAC;YACrB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,QAAQ,CAAC;IAEf,OAAO,CACL,4CACE,iCAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAC/D,mCACE,IAAI,EAAC,QAAQ,iBACD,iBAAiB,EAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,0BAG5C,EACT,mCACE,IAAI,EAAC,QAAQ,iBACD,0BAA0B,EACtC,OAAO,EAAE,GAAG,EAAE,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,kCAGpD,EACT,gDAAkB,cAAc,YAAE,gBAAgB,CAAC,OAAO,GAAQ,IAC9D,EACN,gCAAK,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAC5C,uBAAC,oBAAK,IACJ,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EACtB,MAAM,EAAE;wBACN;4BACE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;4BACtB,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;4BAC9C,MAAM,EAAE,KAAK;4BACb,IAAI,EAAE,KAAK;yBACZ;qBACF,EACD,OAAO,EAAE,cAAc,GACvB,GACE,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport type { EChartsOption } from 'echarts';\nimport { useRef, useState } from 'react';\n\ntype PieChartWithRerenderProps = {\n dataset1: EChartsOption['dataset'];\n dataset2: EChartsOption['dataset'];\n datasetNewCategories: EChartsOption['dataset'];\n};\n\nexport function PieChartWithRerenderComponent({\n dataset1,\n dataset2,\n datasetNewCategories,\n}: PieChartWithRerenderProps) {\n const [renderCount, setRenderCount] = useState(0);\n const [shouldUseNewCategories, setShouldUseNewCategories] = useState(false);\n const chartRenderCount = useRef(0);\n chartRenderCount.current += 1;\n\n const currentDataset = shouldUseNewCategories\n ? datasetNewCategories\n : renderCount % 2 === 0\n ? dataset1\n : dataset2;\n\n return (\n <div>\n <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>\n <button\n type=\"button\"\n data-testid=\"rerender-button\"\n onClick={() => setRenderCount((count) => count + 1)}\n >\n Re-render\n </button>\n <button\n type=\"button\"\n data-testid=\"switch-categories-button\"\n onClick={() => setShouldUseNewCategories((value) => !value)}\n >\n Switch categories\n </button>\n <span data-testid=\"render-count\">{chartRenderCount.current}</span>\n </div>\n <div style={{ height: '350px', width: '100%' }}>\n <Chart\n legend={{ show: true }}\n series={[\n {\n center: ['50%', '50%'],\n encode: { itemName: 'product', value: '2015' },\n radius: '90%',\n type: 'pie',\n },\n ]}\n dataset={currentDataset}\n />\n </div>\n </div>\n );\n}\n"]}
@@ -38,7 +38,7 @@ const ChartWrapperWithTooltipFormatter_1 = require("./ChartWrapperWithTooltipFor
38
38
  /**
39
39
  * Convert hex color to rgb format
40
40
  *
41
- * @param hex color in hex code format
41
+ * @param hex - Color in hex code format
42
42
  * @returns color in rgb format rgb(_, _, _)
43
43
  */
44
44
  const convertHexToRGB = (hex) => {
@@ -50,9 +50,6 @@ const convertHexToRGB = (hex) => {
50
50
  };
51
51
  exports.chartColorsAfterHighlighting = {
52
52
  1: 'rgb(93,207,216)',
53
- 10: 'rgb(210,126,49)',
54
- 11: 'rgb(78,151,121)',
55
- 12: 'rgb(190,255,117)',
56
53
  2: 'rgb(84,80,223)',
57
54
  3: 'rgb(242,152,62)',
58
55
  4: 'rgb(221,75,155)',
@@ -61,6 +58,9 @@ exports.chartColorsAfterHighlighting = {
61
58
  7: 'rgb(69,140,249)',
62
59
  8: 'rgb(113,69,188)',
63
60
  9: 'rgb(240,210,70)',
61
+ 10: 'rgb(210,126,49)',
62
+ 11: 'rgb(78,151,121)',
63
+ 12: 'rgb(190,255,117)',
64
64
  };
65
65
  const pieChartProps = (seriesName, value, rgbSeriesColor) => ({
66
66
  dataset: [
@@ -100,10 +100,9 @@ const barChartProps = (seriesName, value, rgbSeriesColor) => ({
100
100
  },
101
101
  series: [
102
102
  {
103
- encode: {
104
- x: 'Country',
105
- y: 'Sales',
106
- },
103
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
104
+ // oxlint-disable-next-line id-length
105
+ encode: { x: 'Country', y: 'Sales' },
107
106
  itemStyle: {
108
107
  color: rgbSeriesColor,
109
108
  },
@@ -136,31 +135,43 @@ exports.multiSeriesChartProps = {
136
135
  option: {},
137
136
  series: [
138
137
  {
138
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
139
+ // oxlint-disable-next-line id-length
139
140
  encode: { x: 'day', y: 'first' },
140
141
  name: 'First Series',
141
142
  type: 'line',
142
143
  },
143
144
  {
145
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
146
+ // oxlint-disable-next-line id-length
144
147
  encode: { x: 'day', y: 'second' },
145
148
  name: 'Second Series',
146
149
  type: 'line',
147
150
  },
148
151
  {
152
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
153
+ // oxlint-disable-next-line id-length
149
154
  encode: { x: 'day', y: 'third' },
150
155
  name: 'Third Series',
151
156
  type: 'line',
152
157
  },
153
158
  {
159
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
160
+ // oxlint-disable-next-line id-length
154
161
  encode: { x: 'day', y: 'fourth' },
155
162
  name: 'Fourth Series',
156
163
  type: 'line',
157
164
  },
158
165
  {
166
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
167
+ // oxlint-disable-next-line id-length
159
168
  encode: { x: 'day', y: 'fifth' },
160
169
  name: 'Fifth Series',
161
170
  type: 'line',
162
171
  },
163
172
  {
173
+ // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode
174
+ // oxlint-disable-next-line id-length
164
175
  encode: { x: 'day', y: 'sixth' },
165
176
  name: 'Sixth Series',
166
177
  type: 'line',