@perses-dev/heatmap-chart-plugin 0.4.0-rc.0 → 0.4.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 (81) hide show
  1. package/__mf/js/{HeatMapChart.64173994.js → HeatMapChart.a5f52cc0.js} +3 -3
  2. package/__mf/js/async/12.4ae967ba.js +2 -0
  3. package/__mf/js/async/180.c67f24c4.js +71 -0
  4. package/__mf/js/async/392.81aab132.js +2 -0
  5. package/__mf/js/async/980.092bc51a.js +83 -0
  6. package/__mf/js/async/__federation_expose_HeatMapChart.c74c73d1.js +23 -0
  7. package/__mf/js/{main.73ddd86d.js → main.69b7f04b.js} +3 -3
  8. package/lib/HeatMapChart.js +1 -1
  9. package/lib/HeatMapChart.js.map +1 -1
  10. package/lib/bootstrap.js +1 -1
  11. package/lib/bootstrap.js.map +1 -1
  12. package/lib/cjs/HeatMapChart.js +1 -1
  13. package/lib/cjs/bootstrap.js +1 -1
  14. package/lib/cjs/components/HeatMapChart.js +97 -20
  15. package/lib/cjs/components/HeatMapChartOptionsEditorSettings.js +61 -6
  16. package/lib/cjs/components/HeatMapChartPanel.js +87 -38
  17. package/lib/cjs/components/HeatMapTooltip.js +6 -6
  18. package/lib/cjs/components/index.js +1 -1
  19. package/lib/cjs/env.d.js +1 -1
  20. package/lib/cjs/getPluginModule.js +12 -0
  21. package/lib/cjs/heat-map-chart-model.js +25 -1
  22. package/lib/cjs/index-federation.js +1 -1
  23. package/lib/cjs/index.js +1 -1
  24. package/lib/cjs/setup-tests.js +1 -1
  25. package/lib/cjs/utils/data-transform.js +12 -0
  26. package/lib/cjs/utils/get-formatted-axis-label.js +1 -1
  27. package/lib/cjs/utils/index.js +1 -1
  28. package/lib/cjs/utils/thresholds.js +12 -0
  29. package/lib/components/HeatMapChart.d.ts +6 -3
  30. package/lib/components/HeatMapChart.d.ts.map +1 -1
  31. package/lib/components/HeatMapChart.js +97 -20
  32. package/lib/components/HeatMapChart.js.map +1 -1
  33. package/lib/components/HeatMapChartOptionsEditorSettings.d.ts.map +1 -1
  34. package/lib/components/HeatMapChartOptionsEditorSettings.js +64 -9
  35. package/lib/components/HeatMapChartOptionsEditorSettings.js.map +1 -1
  36. package/lib/components/HeatMapChartPanel.d.ts.map +1 -1
  37. package/lib/components/HeatMapChartPanel.js +87 -38
  38. package/lib/components/HeatMapChartPanel.js.map +1 -1
  39. package/lib/components/HeatMapTooltip.d.ts +1 -2
  40. package/lib/components/HeatMapTooltip.d.ts.map +1 -1
  41. package/lib/components/HeatMapTooltip.js +6 -6
  42. package/lib/components/HeatMapTooltip.js.map +1 -1
  43. package/lib/components/index.js +1 -1
  44. package/lib/components/index.js.map +1 -1
  45. package/lib/env.d.js +1 -1
  46. package/lib/env.d.js.map +1 -1
  47. package/lib/getPluginModule.d.ts.map +1 -1
  48. package/lib/getPluginModule.js +12 -0
  49. package/lib/getPluginModule.js.map +1 -1
  50. package/lib/heat-map-chart-model.d.ts +13 -0
  51. package/lib/heat-map-chart-model.d.ts.map +1 -1
  52. package/lib/heat-map-chart-model.js +19 -1
  53. package/lib/heat-map-chart-model.js.map +1 -1
  54. package/lib/index-federation.js +1 -1
  55. package/lib/index-federation.js.map +1 -1
  56. package/lib/index.js +1 -1
  57. package/lib/index.js.map +1 -1
  58. package/lib/setup-tests.js +1 -1
  59. package/lib/setup-tests.js.map +1 -1
  60. package/lib/utils/data-transform.d.ts.map +1 -1
  61. package/lib/utils/data-transform.js +12 -0
  62. package/lib/utils/data-transform.js.map +1 -1
  63. package/lib/utils/get-formatted-axis-label.js +1 -1
  64. package/lib/utils/get-formatted-axis-label.js.map +1 -1
  65. package/lib/utils/index.js +1 -1
  66. package/lib/utils/index.js.map +1 -1
  67. package/lib/utils/thresholds.d.ts.map +1 -1
  68. package/lib/utils/thresholds.js +12 -0
  69. package/lib/utils/thresholds.js.map +1 -1
  70. package/mf-manifest.json +13 -13
  71. package/mf-stats.json +13 -13
  72. package/package.json +4 -4
  73. package/__mf/js/async/12.4a0642db.js +0 -2
  74. package/__mf/js/async/277.34ae0ac5.js +0 -71
  75. package/__mf/js/async/392.de783cd4.js +0 -2
  76. package/__mf/js/async/700.a5530423.js +0 -83
  77. package/__mf/js/async/__federation_expose_HeatMapChart.5ef80ecb.js +0 -23
  78. /package/__mf/js/async/{12.4a0642db.js.LICENSE.txt → 12.4ae967ba.js.LICENSE.txt} +0 -0
  79. /package/__mf/js/async/{277.34ae0ac5.js.LICENSE.txt → 180.c67f24c4.js.LICENSE.txt} +0 -0
  80. /package/__mf/js/async/{392.de783cd4.js.LICENSE.txt → 392.81aab132.js.LICENSE.txt} +0 -0
  81. /package/__mf/js/async/{700.a5530423.js.LICENSE.txt → 980.092bc51a.js.LICENSE.txt} +0 -0
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -22,14 +22,15 @@ Object.defineProperty(exports, "HeatMapChart", {
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
24
  const _react = require("react");
25
+ const _core = require("@perses-dev/core");
25
26
  const _components = require("@perses-dev/components");
26
- const _core = require("echarts/core");
27
+ const _core1 = require("echarts/core");
27
28
  const _charts = require("echarts/charts");
28
29
  const _material = require("@mui/material");
29
30
  const _utils = require("../utils");
30
31
  const _HeatMapTooltip = require("./HeatMapTooltip");
31
- (0, _core.use)([
32
- _charts.HeatmapChart
32
+ (0, _core1.use)([
33
+ _charts.CustomChart
33
34
  ]);
34
35
  // The default coloring is a blue->yellow->red gradient
35
36
  const DEFAULT_VISUAL_MAP_COLORS = [
@@ -45,7 +46,7 @@ const DEFAULT_VISUAL_MAP_COLORS = [
45
46
  '#d73027',
46
47
  '#a50026'
47
48
  ];
48
- function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, yAxisFormat, countFormat, countMin, countMax, timeScale, showVisualMap }) {
49
+ function HeatMapChart({ width, height, data, xAxisCategories, yAxisFormat, countFormat, countMin, countMax, timeScale, showVisualMap, min, max, logBase }) {
49
50
  const chartsTheme = (0, _components.useChartsTheme)();
50
51
  const theme = (0, _material.useTheme)();
51
52
  const { timeZone } = (0, _components.useTimeZone)();
@@ -59,7 +60,6 @@ function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, y
59
60
  label: params.data.label,
60
61
  marker: params.marker,
61
62
  xAxisCategories,
62
- yAxisCategories,
63
63
  theme,
64
64
  yAxisFormat: yAxisFormat,
65
65
  countFormat: countFormat
@@ -74,10 +74,27 @@ function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, y
74
74
  formatter: (0, _utils.getFormattedHeatmapAxisLabel)(timeScale?.rangeMs ?? 0, timeZone)
75
75
  }
76
76
  },
77
- yAxis: (0, _components.getFormattedAxis)({
78
- type: 'category',
79
- data: yAxisCategories
80
- }, yAxisFormat),
77
+ yAxis: {
78
+ type: logBase !== undefined ? 'log' : 'value',
79
+ logBase: logBase,
80
+ boundaryGap: [
81
+ 0,
82
+ '10%'
83
+ ],
84
+ min: min,
85
+ max: max,
86
+ axisLabel: {
87
+ hideOverlap: true,
88
+ formatter: (value)=>{
89
+ // On log scales, ECharts may generate a tick at 0 which is mathematically
90
+ // invalid (log(0) is undefined). Return empty string to hide such labels.
91
+ if (logBase !== undefined && value === 0) {
92
+ return '';
93
+ }
94
+ return (0, _core.formatValue)(value, yAxisFormat);
95
+ }
96
+ }
97
+ },
81
98
  visualMap: {
82
99
  show: showVisualMap ?? false,
83
100
  type: 'continuous',
@@ -96,19 +113,77 @@ function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, y
96
113
  color: theme.palette.text.primary,
97
114
  textBorderColor: theme.palette.background.default,
98
115
  textBorderWidth: 5
99
- }
116
+ },
117
+ // Color by the count dimension (index 3)
118
+ dimension: 3
100
119
  },
101
120
  series: [
102
121
  {
103
- name: 'Gaussian',
104
- type: 'heatmap',
105
- data: data,
106
- emphasis: {
107
- itemStyle: {
108
- borderColor: '#333',
109
- borderWidth: 1
122
+ name: 'HeatMap',
123
+ type: 'custom',
124
+ renderItem: function(params, api) {
125
+ const xIndex = api.value(0);
126
+ const yLower = api.value(1);
127
+ const yUpper = api.value(2);
128
+ // Pixel coordinates
129
+ const upperStart = api.coord([
130
+ xIndex,
131
+ yUpper
132
+ ]);
133
+ const lowerStart = api.coord([
134
+ xIndex,
135
+ yLower
136
+ ]);
137
+ const upperNext = api.coord([
138
+ xIndex + 1,
139
+ yUpper
140
+ ]);
141
+ const startX = upperStart?.[0];
142
+ const upperY = upperStart?.[1];
143
+ const lowerY = lowerStart?.[1];
144
+ const nextX = upperNext?.[0];
145
+ if (startX === undefined || upperY === undefined || lowerY === undefined || nextX === undefined) {
146
+ return null;
110
147
  }
148
+ const topY = Math.min(upperY, lowerY);
149
+ const bottomY = Math.max(upperY, lowerY);
150
+ const width = nextX - startX;
151
+ const height = bottomY - topY;
152
+ return {
153
+ type: 'rect',
154
+ shape: {
155
+ x: startX,
156
+ y: topY,
157
+ width,
158
+ height
159
+ },
160
+ style: {
161
+ fill: api.visual('color')
162
+ }
163
+ };
111
164
  },
165
+ label: {
166
+ show: false
167
+ },
168
+ dimensions: [
169
+ 'xIndex',
170
+ 'yLower',
171
+ 'yUpper',
172
+ 'count'
173
+ ],
174
+ encode: {
175
+ x: 0,
176
+ y: [
177
+ 1,
178
+ 2
179
+ ],
180
+ tooltip: [
181
+ 1,
182
+ 2,
183
+ 3
184
+ ]
185
+ },
186
+ data: data,
112
187
  progressive: 1000,
113
188
  animation: false
114
189
  }
@@ -118,7 +193,6 @@ function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, y
118
193
  xAxisCategories,
119
194
  timeScale?.rangeMs,
120
195
  timeZone,
121
- yAxisCategories,
122
196
  yAxisFormat,
123
197
  showVisualMap,
124
198
  countMin,
@@ -126,7 +200,10 @@ function HeatMapChart({ width, height, data, xAxisCategories, yAxisCategories, y
126
200
  height,
127
201
  theme,
128
202
  data,
129
- countFormat
203
+ countFormat,
204
+ min,
205
+ max,
206
+ logBase
130
207
  ]);
131
208
  const chart = (0, _react.useMemo)(()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.EChart, {
132
209
  style: {
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -51,6 +51,9 @@ function HeatMapChartOptionsEditorSettings(props) {
51
51
  // ensures decimalPlaces defaults to correct value
52
52
  const yAxisFormat = (0, _merge.default)({}, _heatmapchartmodel.DEFAULT_FORMAT, value.yAxisFormat);
53
53
  const countFormat = (0, _merge.default)({}, _heatmapchartmodel.DEFAULT_FORMAT, value.countFormat);
54
+ // Get the current log base configuration, defaulting to 'none' if not set
55
+ const logBaseKey = value.logBase ? String(value.logBase) : 'none';
56
+ const logBase = _heatmapchartmodel.LOG_BASE_CONFIG[logBaseKey] ?? _heatmapchartmodel.LOG_BASE_CONFIG['none'];
54
57
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_components.OptionsEditorGrid, {
55
58
  children: [
56
59
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorColumn, {
@@ -72,12 +75,64 @@ function HeatMapChartOptionsEditorSettings(props) {
72
75
  })
73
76
  }),
74
77
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorColumn, {
75
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorGroup, {
78
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_components.OptionsEditorGroup, {
76
79
  title: "Y Axis",
77
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.FormatControls, {
78
- value: yAxisFormat,
79
- onChange: handleYAxisFormatChange
80
- })
80
+ children: [
81
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.FormatControls, {
82
+ value: yAxisFormat,
83
+ onChange: handleYAxisFormatChange
84
+ }),
85
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
86
+ label: "Min",
87
+ control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
88
+ type: "number",
89
+ value: value.min ?? '',
90
+ onChange: (e)=>{
91
+ const newValue = e.target.value ? Number(e.target.value) : undefined;
92
+ onChange((0, _immer.produce)(value, (draft)=>{
93
+ draft.min = newValue;
94
+ }));
95
+ },
96
+ placeholder: "Auto",
97
+ sx: {
98
+ width: '100%'
99
+ }
100
+ })
101
+ }),
102
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
103
+ label: "Max",
104
+ control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
105
+ type: "number",
106
+ value: value.max ?? '',
107
+ onChange: (e)=>{
108
+ const newValue = e.target.value ? Number(e.target.value) : undefined;
109
+ onChange((0, _immer.produce)(value, (draft)=>{
110
+ draft.max = newValue;
111
+ }));
112
+ },
113
+ placeholder: "Auto",
114
+ sx: {
115
+ width: '100%'
116
+ }
117
+ })
118
+ }),
119
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsEditorControl, {
120
+ label: "Log Base",
121
+ control: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.SettingsAutocomplete, {
122
+ value: {
123
+ ...logBase,
124
+ id: logBase?.label ?? 'None'
125
+ },
126
+ options: _heatmapchartmodel.LOG_BASE_OPTIONS,
127
+ onChange: (__, newValue)=>{
128
+ onChange((0, _immer.produce)(value, (draft)=>{
129
+ draft.logBase = newValue.log;
130
+ }));
131
+ },
132
+ disableClearable: true
133
+ })
134
+ })
135
+ ]
81
136
  })
82
137
  })
83
138
  ]
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -32,19 +32,29 @@ function _interop_require_default(obj) {
32
32
  default: obj
33
33
  };
34
34
  }
35
- const HEATMAP_MIN_HEIGHT = 200;
36
- const HEATMAP_ITEM_MIN_HEIGHT = 2;
35
+ /**
36
+ * Helper function to get the effective lower bound for log scale.
37
+ * For values <= 0, we use a small fraction of the upper bound.
38
+ */ const getEffectiveLowerBound = (lowerBound, upperBound, logBase)=>{
39
+ if (logBase === undefined || lowerBound > 0) {
40
+ return lowerBound;
41
+ }
42
+ // For log scales with non-positive lower bounds, use a small fraction of upper bound
43
+ // This ensures the bucket is still visible on the log scale
44
+ return upperBound * 0.001;
45
+ };
37
46
  function HeatMapChartPanel(props) {
38
47
  const { spec: pluginSpec, contentDimensions, queryResults } = props;
39
48
  // ensures all default format properties set if undef
40
49
  const yAxisFormat = (0, _merge.default)({}, _heatmapchartmodel.DEFAULT_FORMAT, pluginSpec.yAxisFormat);
41
50
  const countFormat = (0, _merge.default)({}, _heatmapchartmodel.DEFAULT_FORMAT, pluginSpec.countFormat);
42
- const { data, xAxisCategories, yAxisCategories, countMin, countMax, timeScale } = (0, _react.useMemo)(()=>{
51
+ const { data, xAxisCategories, min, max, countMin, countMax, timeScale } = (0, _react.useMemo)(()=>{
43
52
  if (!queryResults || queryResults.length === 0) {
44
53
  return {
45
54
  data: [],
46
55
  xAxisCategories: [],
47
- yAxisCategories: [],
56
+ min: 0,
57
+ max: 0,
48
58
  countMin: 0,
49
59
  countMax: 0,
50
60
  timeScale: undefined
@@ -54,7 +64,8 @@ function HeatMapChartPanel(props) {
54
64
  return {
55
65
  data: [],
56
66
  xAxisCategories: [],
57
- yAxisCategories: [],
67
+ min: 0,
68
+ max: 0,
58
69
  countMin: 0,
59
70
  countMax: 0,
60
71
  timeScale: undefined
@@ -63,19 +74,26 @@ function HeatMapChartPanel(props) {
63
74
  const series = queryResults[0].data.series[0];
64
75
  const timeScale = (0, _utils.getCommonTimeScaleForQueries)(queryResults);
65
76
  const xAxisCategories = (0, _utils.generateCompleteTimestamps)(timeScale);
77
+ const logBase = pluginSpec.logBase;
66
78
  // Dummy value that will be replaced at the first iteration
67
79
  let lowestBound = Infinity;
68
80
  let highestBound = -Infinity;
69
81
  let countMin = Infinity;
70
82
  let countMax = -Infinity;
71
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
72
- for (const [_, histogram] of series?.histograms ?? []){
83
+ for (const [, histogram] of series?.histograms ?? []){
73
84
  for (const bucket of histogram?.buckets ?? []){
74
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
75
- const [_, lowerBound, upperBound, count] = bucket;
76
- const lowerBoundFloat = parseFloat(lowerBound);
85
+ const [, lowerBound, upperBound, count] = bucket;
86
+ let lowerBoundFloat = parseFloat(lowerBound);
77
87
  const upperBoundFloat = parseFloat(upperBound);
78
88
  const countFloat = parseFloat(count);
89
+ // For logarithmic scales, skip buckets that would be entirely non-positive
90
+ if (logBase !== undefined && upperBoundFloat <= 0) {
91
+ continue;
92
+ }
93
+ // For log scales, adjust non-positive lower bounds
94
+ if (logBase !== undefined) {
95
+ lowerBoundFloat = getEffectiveLowerBound(lowerBoundFloat, upperBoundFloat, logBase);
96
+ }
79
97
  if (lowerBoundFloat < lowestBound) {
80
98
  lowestBound = lowerBoundFloat;
81
99
  }
@@ -90,48 +108,77 @@ function HeatMapChartPanel(props) {
90
108
  }
91
109
  }
92
110
  }
93
- const height = contentDimensions?.height ?? HEATMAP_MIN_HEIGHT;
94
- const totalRange = highestBound - lowestBound;
95
- const rangePerItem = totalRange * HEATMAP_ITEM_MIN_HEIGHT / height;
96
- const totalItems = Math.ceil(height / HEATMAP_ITEM_MIN_HEIGHT);
97
- // Generating value of the Y axis based on the height divided by the size of a cell (item)
98
- const yAxisCategories = Array.from({
99
- length: totalItems
100
- }, (_, index)=>(lowestBound + index * rangePerItem).toFixed(3));
101
111
  const data = [];
102
- // Logic for filling all cells where a bucket is present
112
+ // Each bucket becomes a rectangle spanning [lowerBound, upperBound] at the given x index
103
113
  for (const [time, histogram] of series?.histograms ?? []){
104
114
  const itemIndexOnXaxis = xAxisCategories.findIndex((v)=>v === time * 1000);
105
115
  for (const bucket of histogram?.buckets ?? []){
106
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
107
- const [_, lowerBound, upperBound, count] = bucket;
108
- const yLowerBoundItem = Math.floor((parseFloat(lowerBound) - lowestBound) / rangePerItem);
109
- const yUpperBoundItem = Math.ceil((parseFloat(upperBound) - lowestBound) / rangePerItem);
110
- for(let i = 0; i < yUpperBoundItem - yLowerBoundItem; i++){
111
- // TODO: some bucket may have overlapping cells, we could use avg value. Probably will need to move to a matrix data structure for performance reasons
112
- data.push({
113
- value: [
114
- itemIndexOnXaxis,
115
- yLowerBoundItem + i,
116
- parseFloat(count)
117
- ],
118
- label: count
119
- });
116
+ const [, lowerBound, upperBound, count] = bucket;
117
+ let lowerBoundFloat = parseFloat(lowerBound);
118
+ const upperBoundFloat = parseFloat(upperBound);
119
+ // For logarithmic scales, skip buckets that would be entirely non-positive
120
+ if (logBase !== undefined && upperBoundFloat <= 0) {
121
+ continue;
120
122
  }
123
+ // For log scales, adjust non-positive lower bounds
124
+ if (logBase !== undefined) {
125
+ lowerBoundFloat = getEffectiveLowerBound(lowerBoundFloat, upperBoundFloat, logBase);
126
+ }
127
+ data.push({
128
+ value: [
129
+ itemIndexOnXaxis,
130
+ lowerBoundFloat,
131
+ upperBoundFloat,
132
+ parseFloat(count)
133
+ ],
134
+ label: count
135
+ });
121
136
  }
122
137
  }
123
138
  return {
124
139
  data,
125
140
  xAxisCategories,
126
- yAxisCategories,
141
+ min: lowestBound === Infinity ? undefined : lowestBound,
142
+ max: highestBound === -Infinity ? undefined : highestBound,
127
143
  countMin,
128
144
  countMax,
129
145
  timeScale
130
146
  };
131
147
  }, [
132
- contentDimensions?.height,
148
+ pluginSpec.logBase,
133
149
  queryResults
134
150
  ]);
151
+ // Use configured min/max if provided, otherwise use calculated values
152
+ // For logarithmic scales, ignore user-provided min if it's <= 0 (log of non-positive is undefined)
153
+ // and let ECharts auto-calculate the range to avoid rendering issues
154
+ const finalMin = (0, _react.useMemo)(()=>{
155
+ if (pluginSpec.logBase !== undefined) {
156
+ // For log scale, ignore min if it's <= 0 or let ECharts auto-calculate
157
+ if (pluginSpec.min !== undefined && pluginSpec.min <= 0) {
158
+ return undefined; // Let ECharts auto-calculate
159
+ }
160
+ return pluginSpec.min ?? min;
161
+ }
162
+ return pluginSpec.min ?? min;
163
+ }, [
164
+ pluginSpec.logBase,
165
+ pluginSpec.min,
166
+ min
167
+ ]);
168
+ const finalMax = (0, _react.useMemo)(()=>{
169
+ if (pluginSpec.logBase !== undefined) {
170
+ // For log scale, ignore max if it's <= 0
171
+ if (pluginSpec.max !== undefined && pluginSpec.max <= 0) {
172
+ return undefined; // Let ECharts auto-calculate
173
+ }
174
+ return pluginSpec.max ?? max;
175
+ }
176
+ return pluginSpec.max ?? max;
177
+ }, [
178
+ pluginSpec.logBase,
179
+ pluginSpec.max,
180
+ max
181
+ ]);
135
182
  // TODO: add support for multiple queries
136
183
  if (queryResults.length > 1) {
137
184
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
@@ -166,13 +213,15 @@ function HeatMapChartPanel(props) {
166
213
  height: contentDimensions.height,
167
214
  data: data,
168
215
  xAxisCategories: xAxisCategories,
169
- yAxisCategories: yAxisCategories,
170
216
  yAxisFormat: yAxisFormat,
171
217
  countFormat: countFormat,
172
218
  countMin: countMin,
173
219
  countMax: countMax,
174
220
  timeScale: timeScale,
175
- showVisualMap: pluginSpec.showVisualMap
221
+ showVisualMap: pluginSpec.showVisualMap,
222
+ min: finalMin,
223
+ max: finalMax,
224
+ logBase: pluginSpec.logBase
176
225
  })
177
226
  });
178
227
  }
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -23,9 +23,9 @@ Object.defineProperty(exports, "generateTooltipHTML", {
23
23
  const _material = require("@mui/material");
24
24
  const _components = require("@perses-dev/components");
25
25
  const _core = require("@perses-dev/core");
26
- function generateTooltipHTML({ data, label, marker, xAxisCategories, yAxisCategories, theme, yAxisFormat, countFormat }) {
27
- const [x, y] = data;
28
- const xAxisLabel = xAxisCategories[x];
26
+ function generateTooltipHTML({ data, label, marker, xAxisCategories, theme, yAxisFormat, countFormat }) {
27
+ const [xIndex, yLower, yUpper] = data;
28
+ const xAxisLabel = xAxisCategories[xIndex];
29
29
  const { formattedDate, formattedTime } = (0, _components.getDateAndTime)(xAxisLabel);
30
30
  const tooltipHeader = (0, _material.css)`
31
31
  border-bottom: 1px solid ${theme.palette.grey[500]};
@@ -39,8 +39,8 @@ function generateTooltipHTML({ data, label, marker, xAxisCategories, yAxisCatego
39
39
  const labelStyles = (0, _material.css)`
40
40
  margin-right: 16px;
41
41
  `;
42
- const lowerBound = parseFloat(yAxisCategories[y]);
43
- const upperBound = yAxisCategories[y + 1] ? parseFloat(yAxisCategories[y + 1]) : parseFloat(yAxisCategories[y]) + parseFloat(yAxisCategories[y]) - parseFloat(yAxisCategories[y - 1]); // Top cell, upper bound need to be calculated from previous cell
42
+ const lowerBound = yLower;
43
+ const upperBound = yUpper;
44
44
  return `
45
45
  <div>
46
46
  <div style="${tooltipHeader.styles}">${formattedDate} ${formattedTime}</div>
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
package/lib/cjs/env.d.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -1,3 +1,15 @@
1
+ // Copyright 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.
1
13
  "use strict";
2
14
  Object.defineProperty(exports, "__esModule", {
3
15
  value: true
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -36,6 +36,12 @@ _export(exports, {
36
36
  get DEFAULT_MIN_PERCENT_DECIMAL () {
37
37
  return DEFAULT_MIN_PERCENT_DECIMAL;
38
38
  },
39
+ get LOG_BASE_CONFIG () {
40
+ return LOG_BASE_CONFIG;
41
+ },
42
+ get LOG_BASE_OPTIONS () {
43
+ return LOG_BASE_OPTIONS;
44
+ },
39
45
  get createInitialHeatMapChartOptions () {
40
46
  return createInitialHeatMapChartOptions;
41
47
  }
@@ -47,6 +53,24 @@ const DEFAULT_MIN_PERCENT = 0;
47
53
  const DEFAULT_MAX_PERCENT = 100;
48
54
  const DEFAULT_MIN_PERCENT_DECIMAL = 0;
49
55
  const DEFAULT_MAX_PERCENT_DECIMAL = 1;
56
+ const LOG_BASE_CONFIG = {
57
+ none: {
58
+ label: 'None',
59
+ log: undefined
60
+ },
61
+ '2': {
62
+ label: '2',
63
+ log: 2
64
+ },
65
+ '10': {
66
+ label: '10',
67
+ log: 10
68
+ }
69
+ };
70
+ const LOG_BASE_OPTIONS = Object.entries(LOG_BASE_CONFIG).map(([id, config])=>({
71
+ id: id,
72
+ ...config
73
+ }));
50
74
  function createInitialHeatMapChartOptions() {
51
75
  return {
52
76
  yAxisFormat: DEFAULT_FORMAT,
@@ -40,7 +40,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
40
40
  }
41
41
  return newObj;
42
42
  }
43
- // Copyright 2025 The Perses Authors
43
+ // Copyright The Perses Authors
44
44
  // Licensed under the Apache License, Version 2.0 (the "License");
45
45
  // you may not use this file except in compliance with the License.
46
46
  // You may obtain a copy of the License at
package/lib/cjs/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -1,3 +1,15 @@
1
+ // Copyright 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.
1
13
  "use strict";
2
14
  Object.defineProperty(exports, "__esModule", {
3
15
  value: true
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -1,4 +1,4 @@
1
- // Copyright 2025 The Perses Authors
1
+ // Copyright The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -1,3 +1,15 @@
1
+ // Copyright 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.
1
13
  "use strict";
2
14
  Object.defineProperty(exports, "__esModule", {
3
15
  value: true