@perses-dev/components 0.30.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/ContentWithLegend/ContentWithLegend.d.ts +11 -0
  2. package/dist/ContentWithLegend/ContentWithLegend.d.ts.map +1 -0
  3. package/dist/ContentWithLegend/ContentWithLegend.js +65 -0
  4. package/dist/ContentWithLegend/ContentWithLegend.js.map +1 -0
  5. package/dist/ContentWithLegend/index.d.ts +2 -0
  6. package/dist/ContentWithLegend/index.d.ts.map +1 -0
  7. package/dist/ContentWithLegend/index.js +15 -0
  8. package/dist/ContentWithLegend/index.js.map +1 -0
  9. package/dist/ContentWithLegend/model/content-with-legend-model.d.ts +68 -0
  10. package/dist/ContentWithLegend/model/content-with-legend-model.d.ts.map +1 -0
  11. package/dist/ContentWithLegend/model/content-with-legend-model.js +90 -0
  12. package/dist/ContentWithLegend/model/content-with-legend-model.js.map +1 -0
  13. package/dist/EChart/EChart.d.ts.map +1 -1
  14. package/dist/EChart/EChart.js +9 -1
  15. package/dist/EChart/EChart.js.map +1 -1
  16. package/dist/Legend/CompactLegend.d.ts +6 -4
  17. package/dist/Legend/CompactLegend.d.ts.map +1 -1
  18. package/dist/Legend/CompactLegend.js +4 -1
  19. package/dist/Legend/CompactLegend.js.map +1 -1
  20. package/dist/Legend/Legend.d.ts +11 -9
  21. package/dist/Legend/Legend.d.ts.map +1 -1
  22. package/dist/Legend/Legend.js +70 -21
  23. package/dist/Legend/Legend.js.map +1 -1
  24. package/dist/Legend/ListLegend.d.ts +5 -8
  25. package/dist/Legend/ListLegend.d.ts.map +1 -1
  26. package/dist/Legend/ListLegend.js +17 -103
  27. package/dist/Legend/ListLegend.js.map +1 -1
  28. package/dist/Legend/ListLegendItem.d.ts +8 -8
  29. package/dist/Legend/ListLegendItem.d.ts.map +1 -1
  30. package/dist/Legend/ListLegendItem.js +9 -12
  31. package/dist/Legend/ListLegendItem.js.map +1 -1
  32. package/dist/Legend/TableLegend.d.ts +12 -0
  33. package/dist/Legend/TableLegend.d.ts.map +1 -0
  34. package/dist/Legend/TableLegend.js +61 -0
  35. package/dist/Legend/TableLegend.js.map +1 -0
  36. package/dist/LegendOptionsEditor/LegendOptionsEditor.d.ts.map +1 -1
  37. package/dist/LegendOptionsEditor/LegendOptionsEditor.js +35 -3
  38. package/dist/LegendOptionsEditor/LegendOptionsEditor.js.map +1 -1
  39. package/dist/LineChart/LineChart.d.ts +2 -1
  40. package/dist/LineChart/LineChart.d.ts.map +1 -1
  41. package/dist/LineChart/LineChart.js +83 -36
  42. package/dist/LineChart/LineChart.js.map +1 -1
  43. package/dist/StatChart/StatChart.d.ts.map +1 -1
  44. package/dist/StatChart/StatChart.js +8 -1
  45. package/dist/StatChart/StatChart.js.map +1 -1
  46. package/dist/Table/InnerTable.d.ts +9 -0
  47. package/dist/Table/InnerTable.d.ts.map +1 -0
  48. package/dist/Table/InnerTable.js +38 -0
  49. package/dist/Table/InnerTable.js.map +1 -0
  50. package/dist/Table/Table.d.ts +10 -0
  51. package/dist/Table/Table.d.ts.map +1 -0
  52. package/dist/Table/Table.js +101 -0
  53. package/dist/Table/Table.js.map +1 -0
  54. package/dist/Table/TableBody.d.ts +6 -0
  55. package/dist/Table/TableBody.d.ts.map +1 -0
  56. package/dist/Table/TableBody.js +23 -0
  57. package/dist/Table/TableBody.js.map +1 -0
  58. package/dist/Table/TableCell.d.ts +18 -0
  59. package/dist/Table/TableCell.d.ts.map +1 -0
  60. package/dist/Table/TableCell.js +91 -0
  61. package/dist/Table/TableCell.js.map +1 -0
  62. package/dist/Table/TableCheckbox.d.ts +9 -0
  63. package/dist/Table/TableCheckbox.d.ts.map +1 -0
  64. package/dist/Table/TableCheckbox.js +49 -0
  65. package/dist/Table/TableCheckbox.js.map +1 -0
  66. package/dist/Table/TableHead.d.ts +6 -0
  67. package/dist/Table/TableHead.d.ts.map +1 -0
  68. package/dist/Table/TableHead.js +23 -0
  69. package/dist/Table/TableHead.js.map +1 -0
  70. package/dist/Table/TableRow.d.ts +9 -0
  71. package/dist/Table/TableRow.d.ts.map +1 -0
  72. package/dist/Table/TableRow.js +29 -0
  73. package/dist/Table/TableRow.js.map +1 -0
  74. package/dist/Table/VirtualizedTable.d.ts +11 -0
  75. package/dist/Table/VirtualizedTable.d.ts.map +1 -0
  76. package/dist/Table/VirtualizedTable.js +152 -0
  77. package/dist/Table/VirtualizedTable.js.map +1 -0
  78. package/dist/Table/VirtualizedTableContainer.d.ts +6 -0
  79. package/dist/Table/VirtualizedTableContainer.d.ts.map +1 -0
  80. package/dist/Table/VirtualizedTableContainer.js +24 -0
  81. package/dist/Table/VirtualizedTableContainer.js.map +1 -0
  82. package/dist/Table/hooks/useTableKeyboardNav.d.ts +32 -0
  83. package/dist/Table/hooks/useTableKeyboardNav.d.ts.map +1 -0
  84. package/dist/Table/hooks/useTableKeyboardNav.js +98 -0
  85. package/dist/Table/hooks/useTableKeyboardNav.js.map +1 -0
  86. package/dist/Table/hooks/useVirtualizedTableKeyboardNav.d.ts +29 -0
  87. package/dist/Table/hooks/useVirtualizedTableKeyboardNav.d.ts.map +1 -0
  88. package/dist/Table/hooks/useVirtualizedTableKeyboardNav.js +89 -0
  89. package/dist/Table/hooks/useVirtualizedTableKeyboardNav.js.map +1 -0
  90. package/dist/Table/index.d.ts +4 -0
  91. package/dist/Table/index.d.ts.map +1 -0
  92. package/dist/Table/index.js +16 -0
  93. package/dist/Table/index.js.map +1 -0
  94. package/dist/Table/model/table-model.d.ts +83 -0
  95. package/dist/Table/model/table-model.d.ts.map +1 -0
  96. package/dist/Table/model/table-model.js +73 -0
  97. package/dist/Table/model/table-model.js.map +1 -0
  98. package/dist/TimeSeriesTooltip/SeriesInfo.d.ts +1 -0
  99. package/dist/TimeSeriesTooltip/SeriesInfo.d.ts.map +1 -1
  100. package/dist/TimeSeriesTooltip/SeriesInfo.js +11 -9
  101. package/dist/TimeSeriesTooltip/SeriesInfo.js.map +1 -1
  102. package/dist/TimeSeriesTooltip/TimeSeriesTooltip.d.ts +6 -5
  103. package/dist/TimeSeriesTooltip/TimeSeriesTooltip.d.ts.map +1 -1
  104. package/dist/TimeSeriesTooltip/TimeSeriesTooltip.js +48 -21
  105. package/dist/TimeSeriesTooltip/TimeSeriesTooltip.js.map +1 -1
  106. package/dist/TimeSeriesTooltip/TooltipContent.d.ts +3 -3
  107. package/dist/TimeSeriesTooltip/TooltipContent.d.ts.map +1 -1
  108. package/dist/TimeSeriesTooltip/TooltipContent.js +28 -67
  109. package/dist/TimeSeriesTooltip/TooltipContent.js.map +1 -1
  110. package/dist/TimeSeriesTooltip/TooltipHeader.d.ts +12 -0
  111. package/dist/TimeSeriesTooltip/TooltipHeader.d.ts.map +1 -0
  112. package/dist/TimeSeriesTooltip/TooltipHeader.js +163 -0
  113. package/dist/TimeSeriesTooltip/TooltipHeader.js.map +1 -0
  114. package/dist/TimeSeriesTooltip/index.d.ts +2 -1
  115. package/dist/TimeSeriesTooltip/index.d.ts.map +1 -1
  116. package/dist/TimeSeriesTooltip/index.js +2 -1
  117. package/dist/TimeSeriesTooltip/index.js.map +1 -1
  118. package/dist/TimeSeriesTooltip/nearby-series.d.ts +46 -0
  119. package/dist/TimeSeriesTooltip/nearby-series.d.ts.map +1 -0
  120. package/dist/TimeSeriesTooltip/nearby-series.js +200 -0
  121. package/dist/TimeSeriesTooltip/nearby-series.js.map +1 -0
  122. package/dist/TimeSeriesTooltip/tooltip-model.d.ts +17 -17
  123. package/dist/TimeSeriesTooltip/tooltip-model.d.ts.map +1 -1
  124. package/dist/TimeSeriesTooltip/tooltip-model.js +7 -2
  125. package/dist/TimeSeriesTooltip/tooltip-model.js.map +1 -1
  126. package/dist/TimeSeriesTooltip/utils.d.ts +1 -1
  127. package/dist/TimeSeriesTooltip/utils.d.ts.map +1 -1
  128. package/dist/TimeSeriesTooltip/utils.js +6 -5
  129. package/dist/TimeSeriesTooltip/utils.js.map +1 -1
  130. package/dist/cjs/ContentWithLegend/ContentWithLegend.js +70 -0
  131. package/dist/cjs/ContentWithLegend/index.js +28 -0
  132. package/dist/cjs/ContentWithLegend/model/content-with-legend-model.js +100 -0
  133. package/dist/cjs/EChart/EChart.js +9 -1
  134. package/dist/cjs/Legend/CompactLegend.js +4 -1
  135. package/dist/cjs/Legend/Legend.js +70 -21
  136. package/dist/cjs/Legend/ListLegend.js +17 -103
  137. package/dist/cjs/Legend/ListLegendItem.js +8 -11
  138. package/dist/cjs/Legend/TableLegend.js +67 -0
  139. package/dist/cjs/LegendOptionsEditor/LegendOptionsEditor.js +34 -2
  140. package/dist/cjs/LineChart/LineChart.js +83 -36
  141. package/dist/cjs/StatChart/StatChart.js +8 -1
  142. package/dist/cjs/Table/InnerTable.js +44 -0
  143. package/dist/cjs/Table/Table.js +102 -0
  144. package/dist/cjs/Table/TableBody.js +29 -0
  145. package/dist/cjs/Table/TableCell.js +97 -0
  146. package/dist/cjs/Table/TableCheckbox.js +55 -0
  147. package/dist/cjs/Table/TableHead.js +29 -0
  148. package/dist/cjs/Table/TableRow.js +35 -0
  149. package/dist/cjs/Table/VirtualizedTable.js +155 -0
  150. package/dist/cjs/Table/VirtualizedTableContainer.js +30 -0
  151. package/dist/cjs/Table/hooks/useTableKeyboardNav.js +99 -0
  152. package/dist/cjs/Table/hooks/useVirtualizedTableKeyboardNav.js +93 -0
  153. package/dist/cjs/Table/index.js +33 -0
  154. package/dist/cjs/Table/model/table-model.js +80 -0
  155. package/dist/cjs/TimeSeriesTooltip/SeriesInfo.js +10 -8
  156. package/dist/cjs/TimeSeriesTooltip/TimeSeriesTooltip.js +45 -57
  157. package/dist/cjs/TimeSeriesTooltip/TooltipContent.js +26 -65
  158. package/dist/cjs/TimeSeriesTooltip/TooltipHeader.js +174 -0
  159. package/dist/cjs/TimeSeriesTooltip/index.js +2 -1
  160. package/dist/cjs/TimeSeriesTooltip/nearby-series.js +206 -0
  161. package/dist/cjs/TimeSeriesTooltip/tooltip-model.js +13 -3
  162. package/dist/cjs/TimeSeriesTooltip/utils.js +5 -4
  163. package/dist/cjs/context/SnackbarProvider.js +66 -0
  164. package/dist/cjs/index.js +3 -0
  165. package/dist/cjs/model/legend.js +37 -2
  166. package/dist/cjs/theme/palette/grey.js +6 -2
  167. package/dist/context/SnackbarProvider.d.ts +23 -0
  168. package/dist/context/SnackbarProvider.d.ts.map +1 -0
  169. package/dist/context/SnackbarProvider.js +59 -0
  170. package/dist/context/SnackbarProvider.js.map +1 -0
  171. package/dist/index.d.ts +3 -0
  172. package/dist/index.d.ts.map +1 -1
  173. package/dist/index.js +3 -0
  174. package/dist/index.js.map +1 -1
  175. package/dist/model/legend.d.ts +19 -5
  176. package/dist/model/legend.d.ts.map +1 -1
  177. package/dist/model/legend.js +31 -1
  178. package/dist/model/legend.js.map +1 -1
  179. package/dist/theme/palette/grey.d.ts.map +1 -1
  180. package/dist/theme/palette/grey.js +6 -2
  181. package/dist/theme/palette/grey.js.map +1 -1
  182. package/package.json +6 -6
  183. package/dist/TimeSeriesTooltip/focused-series.d.ts +0 -25
  184. package/dist/TimeSeriesTooltip/focused-series.d.ts.map +0 -1
  185. package/dist/TimeSeriesTooltip/focused-series.js +0 -110
  186. package/dist/TimeSeriesTooltip/focused-series.js.map +0 -1
  187. package/dist/cjs/TimeSeriesTooltip/focused-series.js +0 -116
@@ -62,7 +62,7 @@ function _interopRequireWildcard(obj, nodeInterop) {
62
62
  }
63
63
  return newObj;
64
64
  }
65
- const ListLegendItemBase = /*#__PURE__*/ (0, _react.forwardRef)(function ListLegendItem({ item , sx , truncateLabel , onLayoutChange , ...others }, ref) {
65
+ const ListLegendItemBase = /*#__PURE__*/ (0, _react.forwardRef)(function ListLegendItem({ item , sx , truncateLabel , onClick , isVisuallySelected , ...others }, ref) {
66
66
  const [noWrap, setNoWrap] = (0, _react.useState)(truncateLabel);
67
67
  function handleMouseOver() {
68
68
  if (truncateLabel) {
@@ -74,14 +74,11 @@ const ListLegendItemBase = /*#__PURE__*/ (0, _react.forwardRef)(function ListLeg
74
74
  setNoWrap(true);
75
75
  }
76
76
  }
77
- (0, _react.useEffect)(()=>{
78
- // When `noWrap` changes, so does the layout of the component. Notifies the
79
- // parent, so it can handle those changes.
80
- onLayoutChange === null || onLayoutChange === void 0 ? void 0 : onLayoutChange();
81
- }, [
82
- noWrap,
83
- onLayoutChange
84
- ]);
77
+ const handleClick = (e)=>{
78
+ var ref;
79
+ onClick(e, item.id);
80
+ (ref = item.onClick) === null || ref === void 0 ? void 0 : ref.call(item, e);
81
+ };
85
82
  return /*#__PURE__*/ (0, _react.createElement)(_material.ListItem, {
86
83
  ...others,
87
84
  component: "div",
@@ -92,8 +89,8 @@ const ListLegendItemBase = /*#__PURE__*/ (0, _react.forwardRef)(function ListLeg
92
89
  }, sx),
93
90
  dense: true,
94
91
  key: item.id,
95
- onClick: item.onClick,
96
- selected: item.isSelected,
92
+ onClick: handleClick,
93
+ selected: isVisuallySelected,
97
94
  ref: ref,
98
95
  children: [
99
96
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
@@ -0,0 +1,67 @@
1
+ // Copyright 2023 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "TableLegend", {
18
+ enumerable: true,
19
+ get: ()=>TableLegend
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _react = require("react");
23
+ const _table = require("../Table");
24
+ const COLUMNS = [
25
+ {
26
+ accessorKey: 'label',
27
+ header: 'Name',
28
+ // Starting with `title` attr instead of a tooltip because it is easier to
29
+ // implement. We should try adding a tooltip in the future, but we'll need
30
+ // to be very careful about performance when doing so with large tables.
31
+ cell: ({ getValue })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)("span", {
32
+ title: getValue(),
33
+ children: getValue()
34
+ })
35
+ }
36
+ ];
37
+ const getRowId = (data)=>{
38
+ return data.id;
39
+ };
40
+ const getCheckboxColor = (data)=>{
41
+ return data.color;
42
+ };
43
+ function TableLegend({ items , selectedItems: initRowSelection , onSelectedItemsChange , height , width }) {
44
+ const rowSelection = (0, _react.useMemo)(()=>{
45
+ return typeof initRowSelection !== 'string' ? initRowSelection : // items for checkboxes.
46
+ // TODO: clean this up if we switch to also using checkboxes in list legend.
47
+ items.reduce((allRowSelection, item, index)=>{
48
+ allRowSelection[getRowId(item, index)] = true;
49
+ return allRowSelection;
50
+ }, {});
51
+ }, [
52
+ initRowSelection,
53
+ items
54
+ ]);
55
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_table.Table, {
56
+ height: height,
57
+ width: width,
58
+ rowSelection: rowSelection,
59
+ onRowSelectionChange: onSelectedItemsChange,
60
+ data: items,
61
+ columns: COLUMNS,
62
+ density: "compact",
63
+ getRowId: getRowId,
64
+ getCheckboxColor: getCheckboxColor,
65
+ checkboxSelection: true
66
+ });
67
+ }
@@ -29,6 +29,12 @@ const POSITION_OPTIONS = Object.entries(_model.LEGEND_POSITIONS_CONFIG).map(([id
29
29
  ...config
30
30
  };
31
31
  });
32
+ const MODE_OPTIONS = Object.entries(_model.LEGEND_MODE_CONFIG).map(([id, config])=>{
33
+ return {
34
+ id: id,
35
+ ...config
36
+ };
37
+ });
32
38
  function LegendOptionsEditor({ value , onChange }) {
33
39
  const handleLegendShowChange = (_, checked)=>{
34
40
  // legend is hidden when legend obj is undefined
@@ -43,9 +49,18 @@ function LegendOptionsEditor({ value , onChange }) {
43
49
  position: newValue.id
44
50
  });
45
51
  };
52
+ const handleLegendModeChange = (_, newValue)=>{
53
+ onChange({
54
+ ...value,
55
+ position: currentPosition,
56
+ mode: newValue.id
57
+ });
58
+ };
46
59
  const isValidLegend = (0, _model.validateLegendSpec)(value);
47
60
  const currentPosition = (0, _model.getLegendPosition)(value === null || value === void 0 ? void 0 : value.position);
48
- const legendConfig = _model.LEGEND_POSITIONS_CONFIG[currentPosition];
61
+ const legendPositionConfig = _model.LEGEND_POSITIONS_CONFIG[currentPosition];
62
+ const currentMode = (0, _model.getLegendMode)(value === null || value === void 0 ? void 0 : value.mode);
63
+ const legendModeConfig = _model.LEGEND_MODE_CONFIG[currentMode];
49
64
  return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
50
65
  children: [
51
66
  !isValidLegend && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_errorAlert.ErrorAlert, {
@@ -65,7 +80,7 @@ function LegendOptionsEditor({ value , onChange }) {
65
80
  label: "Position",
66
81
  control: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Autocomplete, {
67
82
  value: {
68
- ...legendConfig,
83
+ ...legendPositionConfig,
69
84
  id: currentPosition
70
85
  },
71
86
  options: POSITION_OPTIONS,
@@ -77,6 +92,23 @@ function LegendOptionsEditor({ value , onChange }) {
77
92
  disabled: value === undefined,
78
93
  disableClearable: true
79
94
  })
95
+ }),
96
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_optionsEditorLayout.OptionsEditorControl, {
97
+ label: "Mode",
98
+ control: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Autocomplete, {
99
+ value: {
100
+ ...legendModeConfig,
101
+ id: currentMode
102
+ },
103
+ options: MODE_OPTIONS,
104
+ isOptionEqualToValue: (option, value)=>option.id === value.id,
105
+ renderInput: (params)=>/*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.TextField, {
106
+ ...params
107
+ }),
108
+ onChange: handleLegendModeChange,
109
+ disabled: value === undefined,
110
+ disableClearable: true
111
+ })
80
112
  })
81
113
  ]
82
114
  });
@@ -26,7 +26,6 @@ const _charts = require("echarts/charts");
26
26
  const _components = require("echarts/components");
27
27
  const _renderers = require("echarts/renderers");
28
28
  const _echart = require("../EChart");
29
- const _graph = require("../model/graph");
30
29
  const _chartsThemeProvider = require("../context/ChartsThemeProvider");
31
30
  const _timeSeriesTooltip = require("../TimeSeriesTooltip");
32
31
  const _timeZoneProvider = require("../context/TimeZoneProvider");
@@ -85,20 +84,22 @@ function _interopRequireWildcard(obj, nodeInterop) {
85
84
  ]);
86
85
  function LineChart({ height , data , yAxis , unit , grid , legend , tooltipConfig ={
87
86
  wrapLabels: true
88
- } , onDataZoom , onDoubleClick , __experimentalEChartsOptionsOverride }) {
87
+ } , noDataVariant ='message' , onDataZoom , onDoubleClick , __experimentalEChartsOptionsOverride }) {
89
88
  var ref;
90
89
  const chartsTheme = (0, _chartsThemeProvider.useChartsTheme)();
91
90
  const chartRef = (0, _react.useRef)();
92
91
  const [showTooltip, setShowTooltip] = (0, _react.useState)(true);
93
- const [pinTooltip, setPinTooltip] = (0, _react.useState)(false);
92
+ const [tooltipPinnedCoords, setTooltipPinnedCoords] = (0, _react.useState)(null);
94
93
  const { timeZone } = (0, _timeZoneProvider.useTimeZone)();
94
+ const [isDragging, setIsDragging] = (0, _react.useState)(false);
95
+ const [startX, setStartX] = (0, _react.useState)(0);
95
96
  const handleEvents = (0, _react.useMemo)(()=>{
96
97
  return {
97
98
  datazoom: (params)=>{
98
99
  if (onDataZoom === undefined) {
99
100
  setTimeout(()=>{
100
101
  // workaround so unpin happens after click event
101
- setPinTooltip(false);
102
+ setTooltipPinnedCoords(null);
102
103
  }, 10);
103
104
  }
104
105
  if (onDataZoom === undefined || params.batch[0] === undefined) return;
@@ -122,28 +123,17 @@ function LineChart({ height , data , yAxis , unit , grid , legend , tooltipConfi
122
123
  }, [
123
124
  data,
124
125
  onDataZoom,
125
- setPinTooltip
126
+ setTooltipPinnedCoords
126
127
  ]);
127
128
  if (chartRef.current !== undefined) {
128
129
  (0, _utils.enableDataZoom)(chartRef.current);
129
130
  }
130
- const handleOnDoubleClick = (e)=>{
131
- setPinTooltip(false);
132
- // either dispatch ECharts restore action to return to orig state or allow consumer to define behavior
133
- if (onDoubleClick === undefined) {
134
- if (chartRef.current !== undefined) {
135
- (0, _utils.restoreChart)(chartRef.current);
136
- }
137
- } else {
138
- onDoubleClick(e);
139
- }
140
- };
141
131
  const { noDataOption } = chartsTheme;
142
132
  const option = (0, _react.useMemo)(()=>{
143
133
  if (data.timeSeries === undefined) return {};
144
- if (data.timeSeries === null || data.timeSeries.length === 0) return noDataOption;
145
- // show symbols and axisPointer dashed line on hover
146
- const isOptimizedMode = data.timeSeries.length > _graph.OPTIMIZED_MODE_SERIES_LIMIT;
134
+ // The "chart" `noDataVariant` is only used when the `timeSeries` is an
135
+ // empty array because a `null` value will throw an error.
136
+ if (data.timeSeries === null || data.timeSeries.length === 0 && noDataVariant === 'message') return noDataOption;
147
137
  var _rangeMs;
148
138
  const rangeMs = (_rangeMs = data.rangeMs) !== null && _rangeMs !== void 0 ? _rangeMs : (0, _utils.getDateRange)(data.xAxis);
149
139
  const option = {
@@ -161,13 +151,17 @@ function LineChart({ height , data , yAxis , unit , grid , legend , tooltipConfi
161
151
  yAxis: (0, _utils.getYAxes)(yAxis, unit),
162
152
  animation: false,
163
153
  tooltip: {
164
- show: !isOptimizedMode,
154
+ show: true,
165
155
  trigger: 'axis',
166
- showContent: false,
167
- axisPointer: {
168
- type: isOptimizedMode ? 'none' : 'line',
169
- z: 0
170
- }
156
+ showContent: false
157
+ },
158
+ // https://echarts.apache.org/en/option.html#axisPointer
159
+ axisPointer: {
160
+ type: 'line',
161
+ z: 0,
162
+ triggerEmphasis: false,
163
+ triggerTooltip: false,
164
+ snap: true
171
165
  },
172
166
  toolbox: {
173
167
  feature: {
@@ -192,27 +186,67 @@ function LineChart({ height , data , yAxis , unit , grid , legend , tooltipConfi
192
186
  legend,
193
187
  noDataOption,
194
188
  timeZone,
195
- __experimentalEChartsOptionsOverride
189
+ __experimentalEChartsOptionsOverride,
190
+ noDataVariant
196
191
  ]);
197
192
  return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
198
193
  sx: {
199
194
  height
200
195
  },
201
- onClick: ()=>{
202
- setPinTooltip((current)=>!current);
196
+ onClick: (e)=>{
197
+ // Pin and unpin when clicking on chart canvas but not tooltip text.
198
+ if (e.target instanceof HTMLCanvasElement) {
199
+ setTooltipPinnedCoords((current)=>{
200
+ if (current === null) {
201
+ return {
202
+ page: {
203
+ x: e.pageX,
204
+ y: e.pageY
205
+ },
206
+ client: {
207
+ x: e.clientX,
208
+ y: e.clientY
209
+ },
210
+ plotCanvas: {
211
+ x: e.nativeEvent.offsetX,
212
+ y: e.nativeEvent.offsetY
213
+ },
214
+ target: e.target
215
+ };
216
+ } else {
217
+ return null;
218
+ }
219
+ });
220
+ }
203
221
  },
204
222
  onMouseDown: (e)=>{
205
- // hide tooltip when user drags to zoom, but allow clicking inside tooltip to copy labels
206
- if (e.target instanceof HTMLCanvasElement) {
207
- setShowTooltip(false);
223
+ const { clientX } = e;
224
+ setIsDragging(true);
225
+ setStartX(clientX);
226
+ },
227
+ onMouseMove: (e)=>{
228
+ // Allow clicking inside tooltip to copy labels.
229
+ if (!(e.target instanceof HTMLCanvasElement)) {
230
+ return;
231
+ }
232
+ const { clientX } = e;
233
+ if (isDragging) {
234
+ const deltaX = clientX - startX;
235
+ if (deltaX > 0) {
236
+ // Hide tooltip when user drags to zoom.
237
+ setShowTooltip(false);
238
+ }
208
239
  }
209
240
  },
210
241
  onMouseUp: ()=>{
242
+ setIsDragging(false);
243
+ setStartX(0);
211
244
  setShowTooltip(true);
212
245
  },
213
246
  onMouseLeave: ()=>{
214
- setShowTooltip(false);
215
- setPinTooltip(false);
247
+ if (tooltipPinnedCoords === null) {
248
+ setShowTooltip(false);
249
+ }
216
250
  },
217
251
  onMouseEnter: ()=>{
218
252
  setShowTooltip(true);
@@ -220,14 +254,27 @@ function LineChart({ height , data , yAxis , unit , grid , legend , tooltipConfi
220
254
  (0, _utils.enableDataZoom)(chartRef.current);
221
255
  }
222
256
  },
223
- onDoubleClick: handleOnDoubleClick,
257
+ onDoubleClick: (e)=>{
258
+ setTooltipPinnedCoords(null);
259
+ // either dispatch ECharts restore action to return to orig state or allow consumer to define behavior
260
+ if (onDoubleClick === undefined) {
261
+ if (chartRef.current !== undefined) {
262
+ (0, _utils.restoreChart)(chartRef.current);
263
+ }
264
+ } else {
265
+ onDoubleClick(e);
266
+ }
267
+ },
224
268
  children: [
225
269
  showTooltip === true && ((ref = option.tooltip) === null || ref === void 0 ? void 0 : ref.showContent) === false && tooltipConfig.hidden !== true && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeSeriesTooltip.TimeSeriesTooltip, {
226
270
  chartRef: chartRef,
227
271
  chartData: data,
228
272
  wrapLabels: tooltipConfig.wrapLabels,
229
- pinTooltip: pinTooltip,
230
- unit: unit
273
+ pinnedPos: tooltipPinnedCoords,
274
+ unit: unit,
275
+ onUnpinClick: ()=>{
276
+ setTooltipPinnedCoords(null);
277
+ }
231
278
  }),
232
279
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_echart.EChart, {
233
280
  sx: {
@@ -80,7 +80,14 @@ function StatChart(props) {
80
80
  },
81
81
  yAxis: {
82
82
  type: 'value',
83
- show: false
83
+ show: false,
84
+ min: (value)=>{
85
+ if (value.min >= 0 && value.min <= 1) {
86
+ // helps with PercentDecimal units, or datasets that return 0 or 1 booleans
87
+ return 0;
88
+ }
89
+ return value.min;
90
+ }
84
91
  },
85
92
  tooltip: {
86
93
  show: false
@@ -0,0 +1,44 @@
1
+ // Copyright 2023 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "InnerTable", {
18
+ enumerable: true,
19
+ get: ()=>InnerTable
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ const _react = require("react");
24
+ const StyledMuiTable = (0, _material.styled)(_material.Table)(({ theme })=>({
25
+ // This value is needed to have a consistent table layout when scrolling.
26
+ tableLayout: 'fixed',
27
+ borderCollapse: 'separate',
28
+ backgroundColor: theme.palette.background.paper
29
+ }));
30
+ const TABLE_DENSITY_CONFIG = {
31
+ compact: 'small',
32
+ standard: 'medium'
33
+ };
34
+ const InnerTable = /*#__PURE__*/ (0, _react.forwardRef)(function InnerTable({ density , width , ...otherProps }, ref) {
35
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(StyledMuiTable, {
36
+ ...otherProps,
37
+ tabIndex: -1,
38
+ size: TABLE_DENSITY_CONFIG[density],
39
+ ref: ref,
40
+ sx: {
41
+ width: width
42
+ }
43
+ });
44
+ });
@@ -0,0 +1,102 @@
1
+ // Copyright 2023 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "Table", {
18
+ enumerable: true,
19
+ get: ()=>Table
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _reactTable = require("@tanstack/react-table");
23
+ const _material = require("@mui/material");
24
+ const _react = require("react");
25
+ const _virtualizedTable = require("./VirtualizedTable");
26
+ const _tableCheckbox = require("./TableCheckbox");
27
+ const _tableModel = require("./model/table-model");
28
+ const DEFAULT_GET_ROW_ID = (data, index)=>{
29
+ return `${index}`;
30
+ };
31
+ function Table({ data , columns , density ='standard' , checkboxSelection , onRowSelectionChange , getCheckboxColor , getRowId =DEFAULT_GET_ROW_ID , rowSelection ={} , ...otherProps }) {
32
+ const theme = (0, _material.useTheme)();
33
+ const handleRowSelectionChange = (rowSelectionUpdater)=>{
34
+ const newRowSelection = typeof rowSelectionUpdater === 'function' ? rowSelectionUpdater(rowSelection) : rowSelectionUpdater;
35
+ onRowSelectionChange === null || onRowSelectionChange === void 0 ? void 0 : onRowSelectionChange(newRowSelection);
36
+ };
37
+ const checkboxColumn = (0, _react.useMemo)(()=>{
38
+ return {
39
+ id: 'checkboxRowSelect',
40
+ size: 32,
41
+ header: ({ table })=>{
42
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_tableCheckbox.TableCheckbox, {
43
+ checked: table.getIsAllRowsSelected(),
44
+ indeterminate: table.getIsSomeRowsSelected(),
45
+ onChange: table.getToggleAllRowsSelectedHandler(),
46
+ color: theme.palette.text.primary,
47
+ density: density
48
+ });
49
+ },
50
+ cell: ({ row })=>{
51
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_tableCheckbox.TableCheckbox, {
52
+ checked: row.getIsSelected(),
53
+ indeterminate: row.getIsSomeSelected(),
54
+ onChange: (e)=>{
55
+ row.getToggleSelectedHandler()(e);
56
+ },
57
+ color: getCheckboxColor === null || getCheckboxColor === void 0 ? void 0 : getCheckboxColor(row.original),
58
+ density: density
59
+ });
60
+ }
61
+ };
62
+ }, [
63
+ density,
64
+ getCheckboxColor,
65
+ theme.palette.text.primary
66
+ ]);
67
+ const tableColumns = (0, _react.useMemo)(()=>{
68
+ const initTableColumns = (0, _tableModel.persesColumnsToTanstackColumns)(columns);
69
+ if (checkboxSelection) {
70
+ initTableColumns.unshift(checkboxColumn);
71
+ }
72
+ return initTableColumns;
73
+ }, [
74
+ checkboxColumn,
75
+ checkboxSelection,
76
+ columns
77
+ ]);
78
+ const table = (0, _reactTable.useReactTable)({
79
+ data,
80
+ columns: tableColumns,
81
+ getRowId,
82
+ getCoreRowModel: (0, _reactTable.getCoreRowModel)(),
83
+ enableRowSelection: !!checkboxSelection,
84
+ onRowSelectionChange: handleRowSelectionChange,
85
+ state: {
86
+ rowSelection
87
+ }
88
+ });
89
+ const handleRowClick = (0, _react.useCallback)((rowId)=>{
90
+ table.getRow(rowId).toggleSelected();
91
+ }, [
92
+ table
93
+ ]);
94
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_virtualizedTable.VirtualizedTable, {
95
+ ...otherProps,
96
+ density: density,
97
+ onRowClick: handleRowClick,
98
+ rows: table.getRowModel().rows,
99
+ columns: table.getAllFlatColumns(),
100
+ headers: table.getHeaderGroups()
101
+ });
102
+ }
@@ -0,0 +1,29 @@
1
+ // Copyright 2023 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "TableBody", {
18
+ enumerable: true,
19
+ get: ()=>TableBody
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ const _react = require("react");
24
+ const TableBody = /*#__PURE__*/ (0, _react.forwardRef)(function TableBody(props, ref) {
25
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.TableBody, {
26
+ ...props,
27
+ ref: ref
28
+ });
29
+ });
@@ -0,0 +1,97 @@
1
+ // Copyright 2023 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "TableCell", {
18
+ enumerable: true,
19
+ get: ()=>TableCell
20
+ });
21
+ const _jsxRuntime = require("react/jsx-runtime");
22
+ const _material = require("@mui/material");
23
+ const _react = require("react");
24
+ const _tableModel = require("./model/table-model");
25
+ const StyledMuiTableCell = (0, _material.styled)(_material.TableCell)(({ theme })=>({
26
+ padding: 0,
27
+ backgroundColor: 'inherit',
28
+ '&.MuiTableCell-head': {
29
+ // Important to avoid scrolling behind the header showing through.
30
+ backgroundColor: theme.palette.background.paper
31
+ },
32
+ '&:focus-visible': {
33
+ outline: `solid 1px ${theme.palette.primary.main}`,
34
+ // Move inward a little to avoid getting cut off when focusing on items
35
+ // at the edge of the table.
36
+ outlineOffset: '-1px',
37
+ borderRadius: 0
38
+ }
39
+ }));
40
+ function TableCell({ children , density , variant , width , focusState ='none' , onFocusTrigger , ...otherProps }) {
41
+ const theme = (0, _material.useTheme)();
42
+ const elRef = (0, _react.useRef)();
43
+ const isHeader = variant === 'head';
44
+ (0, _react.useEffect)(()=>{
45
+ if (focusState === 'trigger-focus' && elRef.current) {
46
+ elRef.current.focus();
47
+ }
48
+ }, [
49
+ focusState
50
+ ]);
51
+ const handleFocus = (e)=>{
52
+ var ref;
53
+ // From https://zellwk.com/blog/keyboard-focusable-elements/
54
+ const nestedFocusTarget = (ref = e.currentTarget) === null || ref === void 0 ? void 0 : ref.querySelector('a[href], button, input, textarea, select, details');
55
+ if (nestedFocusTarget) {
56
+ // If the cell has a focusable child, focus it instead. Mostly used for
57
+ // checkbox cells, but could have other uses.
58
+ nestedFocusTarget.focus();
59
+ }
60
+ };
61
+ const handleInteractionFocusTrigger = (e)=>{
62
+ // We use `onClick` and `onKeyUp` events instead of `onFocus` because of
63
+ // some ordering issues with when the browser calls events and how this
64
+ // plays with the triggering of focus with keyboard interactions.
65
+ // These report that a focus event happened, so we can adjust the current
66
+ // tabindex and focuses to the right cell.
67
+ onFocusTrigger === null || onFocusTrigger === void 0 ? void 0 : onFocusTrigger(e);
68
+ };
69
+ return /*#__PURE__*/ (0, _jsxRuntime.jsx)(StyledMuiTableCell, {
70
+ ...otherProps,
71
+ // Modify the tab index based on the currently focused cell. It's important
72
+ // to avoid having tabindex 0 on everything because it essentially traps
73
+ // a keyboard user in the table until they hit "tab" for every single
74
+ // cell.
75
+ tabIndex: focusState !== 'none' ? 0 : -1,
76
+ onFocus: handleFocus,
77
+ onClick: handleInteractionFocusTrigger,
78
+ onKeyUp: handleInteractionFocusTrigger,
79
+ sx: {
80
+ width: width,
81
+ borderBottom: isHeader ? (theme)=>`solid 1px ${theme.palette.grey[100]}` : `solid 1px ${theme.palette.grey[50]}`
82
+ },
83
+ ref: elRef,
84
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
85
+ sx: {
86
+ ...(0, _tableModel.getTableCellLayout)(theme, density),
87
+ position: 'relative',
88
+ // Text truncation. Currently enforced on all cells. We may control
89
+ // this with a prop on column config in the future.
90
+ whiteSpace: 'nowrap',
91
+ overflow: 'hidden',
92
+ textOverflow: 'ellipsis'
93
+ },
94
+ children: children
95
+ })
96
+ });
97
+ }