@perses-dev/timeseries-chart-plugin 0.13.0-beta.2 → 0.13.0-rc.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.
- package/__mf/js/TimeSeriesChart.3eab0aad.js +7 -0
- package/__mf/js/async/121.c3c0e54f.js +2 -0
- package/__mf/js/async/137.59c998ab.js +38 -0
- package/__mf/js/async/177.2fef2962.js +1 -0
- package/__mf/js/async/187.f5e8932b.js +1 -0
- package/__mf/js/async/192.c3dd56d5.js +1 -0
- package/__mf/js/async/2.60fa4a40.js +1 -0
- package/__mf/js/async/208.b9f374ad.js +7 -0
- package/__mf/js/async/235.d23c8ef0.js +1 -0
- package/__mf/js/async/274.72dfa9c8.js +2 -0
- package/__mf/js/async/356.8170c96d.js +1 -0
- package/__mf/js/async/392.b9ba5bf2.js +2 -0
- package/__mf/js/async/470.e09f33b7.js +2 -0
- package/__mf/js/async/491.85194549.js +1 -0
- package/__mf/js/async/52.0d78de2b.js +1 -0
- package/__mf/js/async/527.f97d1b86.js +110 -0
- package/__mf/js/async/558.8ac6d4e3.js +3 -0
- package/__mf/js/async/568.45da2c30.js +1 -0
- package/__mf/js/async/587.c9460696.js +1 -0
- package/__mf/js/async/588.0a1aa144.js +1 -0
- package/__mf/js/async/603.3b771310.js +2 -0
- package/__mf/js/async/603.3b771310.js.LICENSE.txt +9 -0
- package/__mf/js/async/616.79484ac8.js +1 -0
- package/__mf/js/async/655.dbf8c618.js +1 -0
- package/__mf/js/async/694.0fb9ee5a.js +2 -0
- package/__mf/js/async/702.785cd635.js +2 -0
- package/__mf/js/async/71.8c6cf914.js +1 -0
- package/__mf/js/async/724.c45dcf5b.js +1 -0
- package/__mf/js/async/873.04a201bf.js +1 -0
- package/__mf/js/async/941.b89f8595.js +2 -0
- package/__mf/js/async/955.176fe200.js +1 -0
- package/__mf/js/async/968.2a9fb1a0.js +1 -0
- package/__mf/js/async/978.a9865b23.js +1 -0
- package/__mf/js/async/984.4793f667.js +22 -0
- package/__mf/js/async/{90.16425d5a.js.LICENSE.txt → 984.4793f667.js.LICENSE.txt} +0 -10
- package/__mf/js/async/__federation_expose_TimeSeriesChart.62d8f589.js +1 -0
- package/__mf/js/async/lib-router.319c02cd.js +2 -0
- package/__mf/js/main.23e38819.js +7 -0
- package/lib/QuerySettingsEditor.d.ts.map +1 -1
- package/lib/QuerySettingsEditor.js +93 -14
- package/lib/QuerySettingsEditor.js.map +1 -1
- package/lib/TimeSeriesChartBase.d.ts +2 -0
- package/lib/TimeSeriesChartBase.d.ts.map +1 -1
- package/lib/TimeSeriesChartBase.js +90 -7
- package/lib/TimeSeriesChartBase.js.map +1 -1
- package/lib/TimeSeriesChartPanel.d.ts.map +1 -1
- package/lib/TimeSeriesChartPanel.js +24 -3
- package/lib/TimeSeriesChartPanel.js.map +1 -1
- package/lib/VisualOptionsEditor.js.map +1 -1
- package/lib/annotations/AnnotationTooltip.d.ts +18 -0
- package/lib/annotations/AnnotationTooltip.d.ts.map +1 -0
- package/lib/annotations/AnnotationTooltip.js +352 -0
- package/lib/annotations/AnnotationTooltip.js.map +1 -0
- package/lib/cjs/QuerySettingsEditor.js +91 -12
- package/lib/cjs/TimeSeriesChartBase.js +90 -7
- package/lib/cjs/TimeSeriesChartPanel.js +24 -3
- package/lib/cjs/annotations/AnnotationTooltip.js +370 -0
- package/lib/cjs/utils/annotation.js +37 -0
- package/lib/cjs/utils/data-transform.js +9 -13
- package/lib/time-series-chart-model.d.ts +7 -0
- package/lib/time-series-chart-model.d.ts.map +1 -1
- package/lib/time-series-chart-model.js.map +1 -1
- package/lib/utils/annotation.d.ts +5 -0
- package/lib/utils/annotation.d.ts.map +1 -0
- package/lib/utils/annotation.js +29 -0
- package/lib/utils/annotation.js.map +1 -0
- package/lib/utils/data-transform.d.ts +1 -0
- package/lib/utils/data-transform.d.ts.map +1 -1
- package/lib/utils/data-transform.js +9 -13
- package/lib/utils/data-transform.js.map +1 -1
- package/mf-manifest.json +61 -36
- package/mf-stats.json +68 -36
- package/package.json +5 -4
- package/__mf/js/TimeSeriesChart.e9912623.js +0 -7
- package/__mf/js/async/121.df4898d6.js +0 -2
- package/__mf/js/async/177.56f1be10.js +0 -1
- package/__mf/js/async/192.beef3a1a.js +0 -1
- package/__mf/js/async/2.c3740bb9.js +0 -1
- package/__mf/js/async/235.c24f24f7.js +0 -1
- package/__mf/js/async/274.d112354f.js +0 -2
- package/__mf/js/async/291.5ce0f3cb.js +0 -39
- package/__mf/js/async/356.9f551c8a.js +0 -1
- package/__mf/js/async/392.2350fb02.js +0 -2
- package/__mf/js/async/470.a4fd777e.js +0 -2
- package/__mf/js/async/491.6f81cf51.js +0 -1
- package/__mf/js/async/568.cdcaf97d.js +0 -1
- package/__mf/js/async/587.c12780da.js +0 -1
- package/__mf/js/async/588.6662e16a.js +0 -1
- package/__mf/js/async/616.52acb1b4.js +0 -1
- package/__mf/js/async/681.8d61b348.js +0 -110
- package/__mf/js/async/702.de247ad8.js +0 -2
- package/__mf/js/async/71.84e486c9.js +0 -1
- package/__mf/js/async/724.3439df06.js +0 -1
- package/__mf/js/async/78.91de282a.js +0 -1
- package/__mf/js/async/821.aa2ab3e8.js +0 -7
- package/__mf/js/async/873.9aad328a.js +0 -1
- package/__mf/js/async/90.16425d5a.js +0 -24
- package/__mf/js/async/941.c0e2d25e.js +0 -2
- package/__mf/js/async/968.6de5fa7c.js +0 -1
- package/__mf/js/async/978.5c14e175.js +0 -1
- package/__mf/js/async/__federation_expose_TimeSeriesChart.58a7f341.js +0 -1
- package/__mf/js/async/lib-router.7a3f7bb4.js +0 -2
- package/__mf/js/main.de1f5d2f.js +0 -7
- /package/__mf/css/async/{821.85c2cbf6.css → 208.85c2cbf6.css} +0 -0
- /package/__mf/js/async/{121.df4898d6.js.LICENSE.txt → 121.c3c0e54f.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{821.aa2ab3e8.js.LICENSE.txt → 208.b9f374ad.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{274.d112354f.js.LICENSE.txt → 274.72dfa9c8.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{392.2350fb02.js.LICENSE.txt → 392.b9ba5bf2.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{470.a4fd777e.js.LICENSE.txt → 470.e09f33b7.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{681.8d61b348.js.LICENSE.txt → 527.f97d1b86.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{291.5ce0f3cb.js.LICENSE.txt → 694.0fb9ee5a.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{702.de247ad8.js.LICENSE.txt → 702.785cd635.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{941.c0e2d25e.js.LICENSE.txt → 941.b89f8595.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{lib-router.7a3f7bb4.js.LICENSE.txt → lib-router.319c02cd.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/annotations/AnnotationTooltip.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Divider, Portal, Stack, Typography } from '@mui/material';\nimport Pin from 'mdi-material-ui/Pin';\nimport PinOutline from 'mdi-material-ui/PinOutline';\nimport useResizeObserver from 'use-resize-observer';\nimport type { LineSeriesOption } from 'echarts';\nimport {\n assembleTransform,\n CursorCoordinates,\n getDateAndTime,\n getTooltipStyles,\n PIN_TOOLTIP_HELP_TEXT,\n TOOLTIP_BG_COLOR_FALLBACK,\n TOOLTIP_MAX_WIDTH,\n UNPIN_TOOLTIP_HELP_TEXT,\n useMousePosition,\n} from '@perses-dev/components';\nimport { DEFAULT_ANNOTATION_COLOR } from '@perses-dev/plugin-system';\nimport { TimeSeriesAnnotation } from '../utils/annotation';\n\nexport interface AnnotationTooltipProps {\n annotation: TimeSeriesAnnotation;\n containerId?: string;\n formatWithUserTimeZone: (date: Date, formatString: string) => string;\n pinnedPos: CursorCoordinates | null;\n enablePinning?: boolean;\n onUnpinClick?: () => void;\n}\n\nexport function AnnotationTooltip({\n annotation,\n containerId,\n formatWithUserTimeZone,\n pinnedPos,\n enablePinning = true,\n onUnpinClick,\n}: AnnotationTooltipProps): JSX.Element | null {\n const mousePos = useMousePosition();\n const { height, width, ref: tooltipRef } = useResizeObserver<HTMLDivElement>();\n\n const isPinned = pinnedPos !== null;\n if (!isPinned && mousePos === null) return null;\n\n const containerElement = containerId ? document.querySelector(containerId) : undefined;\n const maxHeight = containerElement ? containerElement.getBoundingClientRect().height : undefined;\n const transform = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);\n\n const start = getDateAndTime(annotation.start, formatWithUserTimeZone);\n const end = annotation.end !== undefined ? getDateAndTime(annotation.end, formatWithUserTimeZone) : null;\n\n return (\n <Portal container={containerElement}>\n <Box ref={tooltipRef} sx={(theme) => getTooltipStyles(theme, pinnedPos, maxHeight)} style={{ transform }}>\n <Stack spacing={0.5}>\n <Box\n sx={(theme) => ({\n width: '100%',\n maxWidth: TOOLTIP_MAX_WIDTH,\n padding: theme.spacing(1.5, 2, 0.5, 2),\n backgroundColor: theme.palette.designSystem?.grey[800] ?? TOOLTIP_BG_COLOR_FALLBACK,\n position: 'sticky',\n top: 0,\n left: 0,\n })}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', paddingBottom: 0.5, width: '100%' }}>\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: annotation.color ?? DEFAULT_ANNOTATION_COLOR,\n marginRight: 1,\n flexShrink: 0,\n }}\n />\n <Box sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"caption\">\n {start.formattedDate} - <strong>{start.formattedTime}</strong>\n </Typography>\n {end && (\n <>\n <Typography variant=\"caption\">{' → '}</Typography>\n <Typography variant=\"caption\">\n {end.formattedDate} - <strong>{end.formattedTime}</strong>\n </Typography>\n </>\n )}\n </Box>\n {enablePinning && (\n <Stack direction=\"row\" alignItems=\"center\" sx={{ marginLeft: 1, flexShrink: 0 }}>\n <Typography sx={{ marginRight: 0.5, fontSize: 11, verticalAlign: 'middle' }}>\n {isPinned ? UNPIN_TOOLTIP_HELP_TEXT : PIN_TOOLTIP_HELP_TEXT}\n </Typography>\n {isPinned ? (\n <Pin\n onClick={() => {\n if (onUnpinClick !== undefined) onUnpinClick();\n }}\n sx={{ fontSize: 16, cursor: 'pointer' }}\n />\n ) : (\n <PinOutline sx={{ fontSize: 16 }} />\n )}\n </Stack>\n )}\n </Box>\n <Divider sx={(theme) => ({ width: '100%', borderColor: theme.palette.grey['500'] })} />\n </Box>\n <Box sx={(theme) => ({ padding: theme.spacing(0.5, 2, 1.5, 2) })}>\n {annotation.title && (\n <Typography variant=\"caption\" sx={{ display: 'block', fontWeight: 'bold', marginBottom: 0.5 }}>\n {annotation.title}\n </Typography>\n )}\n {annotation.legend && (\n <Typography variant=\"caption\" sx={{ display: 'block', marginBottom: 0.5 }}>\n {annotation.legend}\n </Typography>\n )}\n {annotation.tags && Object.keys(annotation.tags).length > 0 && (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, marginTop: 0.5 }}>\n {Object.entries(annotation.tags).map(([key, value]) => (\n <Box\n key={key}\n sx={(theme) => ({\n backgroundColor: theme.palette.grey['700'],\n borderRadius: '4px',\n padding: '2px 6px',\n fontSize: '0.7rem',\n fontFamily: 'monospace',\n })}\n >\n {key}: {value}\n </Box>\n ))}\n </Box>\n )}\n </Box>\n </Stack>\n </Box>\n </Portal>\n );\n}\n\n/**\n * Build ECharts series options for rendering annotations as markArea (range),\n * markLine (vertical dashed lines) and markPoint (triangle markers under the X-axis).\n */\nexport function buildAnnotationSeries(annotations: TimeSeriesAnnotation[] | undefined): LineSeriesOption[] {\n if (!annotations?.length) return [];\n\n const markAreaData: Array<[{ xAxis: number; itemStyle?: { color: string; opacity: number } }, { xAxis: number }]> =\n [];\n const markLineData: Array<{\n xAxis: number;\n lineStyle?: { color: string; width: number; type: 'dashed' | 'solid' | 'dotted' };\n label?: { show: boolean };\n annotationIndex?: number;\n }> = [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const markPointData: any[] = [];\n\n annotations.forEach((annotation, index) => {\n const color = annotation.color ?? DEFAULT_ANNOTATION_COLOR;\n const opacity = 0.3;\n\n if (annotation.end !== undefined) {\n // Range annotation - use markArea and markLine (silent) + markers at start/end\n markLineData.push({\n xAxis: annotation.start,\n lineStyle: { color, width: 2, type: 'dashed' as const },\n label: { show: false },\n annotationIndex: index,\n });\n\n markLineData.push({\n xAxis: annotation.end,\n lineStyle: { color, width: 2, type: 'dashed' as const },\n label: { show: false },\n annotationIndex: index,\n });\n\n markAreaData.push([\n {\n xAxis: annotation.start,\n itemStyle: { color, opacity },\n },\n { xAxis: annotation.end },\n ]);\n\n // Add start and end markers\n for (const isStart of [true, false]) {\n markPointData.push({\n coord: [isStart ? annotation.start : annotation.end, 0],\n symbol: 'triangle',\n symbolSize: [12, 12],\n symbolRotate: 0,\n symbolOffset: [0, 4], // Position below X-axis\n itemStyle: { color },\n annotationIndex: index,\n emphasis: {\n disabled: true,\n },\n isStart: isStart,\n isEnd: !isStart,\n });\n }\n } else {\n // Point annotation - use markLine (silent) + single marker\n markLineData.push({\n xAxis: annotation.start,\n lineStyle: { color, width: 2, type: 'dashed' as const },\n label: { show: false },\n annotationIndex: index,\n });\n\n // Add point marker\n markPointData.push({\n coord: [annotation.start, 0],\n symbol: 'triangle',\n symbolSize: [12, 10],\n symbolRotate: 0,\n symbolOffset: [0, '120%'], // Position below X-axis\n itemStyle: { color },\n annotationIndex: index,\n isPoint: true,\n });\n }\n });\n\n const series: LineSeriesOption = {\n type: 'line',\n data: [],\n silent: false,\n markArea:\n markAreaData.length > 0\n ? {\n silent: true, // Make area silent, only markers are interactive\n data: markAreaData,\n label: {\n show: false,\n },\n }\n : undefined,\n markLine:\n markLineData.length > 0\n ? {\n silent: true, // Non-interactive: hovering the dashed line keeps the TimeSeries tooltip\n symbol: ['none', 'none'],\n data: markLineData,\n lineStyle: {\n type: 'dashed',\n },\n }\n : undefined,\n markPoint:\n markPointData.length > 0\n ? {\n silent: false, // Markers are interactive\n data: markPointData,\n label: {\n show: false,\n },\n }\n : undefined,\n };\n\n return [series];\n}\n"],"names":["Box","Divider","Portal","Stack","Typography","Pin","PinOutline","useResizeObserver","assembleTransform","getDateAndTime","getTooltipStyles","PIN_TOOLTIP_HELP_TEXT","TOOLTIP_BG_COLOR_FALLBACK","TOOLTIP_MAX_WIDTH","UNPIN_TOOLTIP_HELP_TEXT","useMousePosition","DEFAULT_ANNOTATION_COLOR","AnnotationTooltip","annotation","containerId","formatWithUserTimeZone","pinnedPos","enablePinning","onUnpinClick","mousePos","height","width","ref","tooltipRef","isPinned","containerElement","document","querySelector","undefined","maxHeight","getBoundingClientRect","transform","start","end","container","sx","theme","style","spacing","maxWidth","padding","backgroundColor","palette","designSystem","grey","position","top","left","display","alignItems","paddingBottom","borderRadius","color","marginRight","flexShrink","flexGrow","minWidth","variant","formattedDate","strong","formattedTime","direction","marginLeft","fontSize","verticalAlign","onClick","cursor","borderColor","title","fontWeight","marginBottom","legend","tags","Object","keys","length","flexWrap","gap","marginTop","entries","map","key","value","fontFamily","buildAnnotationSeries","annotations","markAreaData","markLineData","markPointData","forEach","index","opacity","push","xAxis","lineStyle","type","label","show","annotationIndex","itemStyle","isStart","coord","symbol","symbolSize","symbolRotate","symbolOffset","emphasis","disabled","isEnd","isPoint","series","data","silent","markArea","markLine","markPoint"],"mappings":"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"}
|
|
@@ -225,12 +225,41 @@ function QuerySettingsEditor(props) {
|
|
|
225
225
|
qs.format = undefined;
|
|
226
226
|
});
|
|
227
227
|
};
|
|
228
|
+
const addStack = (i)=>{
|
|
229
|
+
updateQuerySettings(i, (qs)=>{
|
|
230
|
+
qs.stack = false;
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
const removeStack = (i)=>{
|
|
234
|
+
updateQuerySettings(i, (qs)=>{
|
|
235
|
+
qs.stack = undefined;
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
const handleStackChange = (i, checked)=>{
|
|
239
|
+
updateQuerySettings(i, (qs)=>{
|
|
240
|
+
qs.stack = checked;
|
|
241
|
+
});
|
|
242
|
+
};
|
|
228
243
|
const handleFormatChange = (i, format)=>{
|
|
229
244
|
updateQuerySettings(i, (qs)=>{
|
|
230
245
|
qs.format = format;
|
|
231
246
|
});
|
|
232
247
|
};
|
|
233
|
-
const
|
|
248
|
+
const addNegativeY = (i)=>{
|
|
249
|
+
updateQuerySettings(i, (qs)=>{
|
|
250
|
+
qs.negativeY = true;
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
const removeNegativeY = (i)=>{
|
|
254
|
+
updateQuerySettings(i, (qs)=>{
|
|
255
|
+
qs.negativeY = undefined;
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
const { queryDefinitions } = (0, _pluginsystem.useDataQueriesContext)();
|
|
259
|
+
const queryCount = queryDefinitions.length;
|
|
260
|
+
const queryNames = (0, _react.useMemo)(()=>(0, _pluginsystem.generateQueryNames)(queryDefinitions), [
|
|
261
|
+
queryDefinitions
|
|
262
|
+
]);
|
|
234
263
|
// Compute the list of query indexes for which query settings are not already defined.
|
|
235
264
|
// This is to avoid already-booked indexes to still be selectable in the dropdown(s)
|
|
236
265
|
const availableQueryIndexes = (0, _react.useMemo)(()=>{
|
|
@@ -269,10 +298,11 @@ function QuerySettingsEditor(props) {
|
|
|
269
298
|
mb: 2,
|
|
270
299
|
fontStyle: "italic",
|
|
271
300
|
children: "No query defined"
|
|
272
|
-
}) : querySettingsList?.
|
|
301
|
+
}) : querySettingsList?.map((querySettings, i)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(QuerySettingsInput, {
|
|
273
302
|
inputRef: i === querySettingsList.length - 1 ? recentlyAddedInputRef : undefined,
|
|
274
303
|
querySettings: querySettings,
|
|
275
304
|
availableQueryIndexes: availableQueryIndexes,
|
|
305
|
+
queryNames: queryNames,
|
|
276
306
|
onQueryIndexChange: (e)=>{
|
|
277
307
|
handleQueryIndexChange(e, i);
|
|
278
308
|
},
|
|
@@ -291,7 +321,12 @@ function QuerySettingsEditor(props) {
|
|
|
291
321
|
onRemoveAreaOpacity: ()=>removeAreaOpacity(i),
|
|
292
322
|
onAddFormat: ()=>addFormat(i),
|
|
293
323
|
onRemoveFormat: ()=>removeFormat(i),
|
|
294
|
-
onFormatChange: (format)=>handleFormatChange(i, format)
|
|
324
|
+
onFormatChange: (format)=>handleFormatChange(i, format),
|
|
325
|
+
onAddNegativeY: ()=>addNegativeY(i),
|
|
326
|
+
onRemoveNegativeY: ()=>removeNegativeY(i),
|
|
327
|
+
onAddStack: ()=>addStack(i),
|
|
328
|
+
onRemoveStack: ()=>removeStack(i),
|
|
329
|
+
onStackChange: (checked)=>handleStackChange(i, checked)
|
|
295
330
|
}, i)),
|
|
296
331
|
queryCount > 0 && firstAvailableQueryIndex !== NO_INDEX_AVAILABLE && /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Button, {
|
|
297
332
|
variant: "contained",
|
|
@@ -305,7 +340,7 @@ function QuerySettingsEditor(props) {
|
|
|
305
340
|
]
|
|
306
341
|
});
|
|
307
342
|
}
|
|
308
|
-
function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue, lineStyle, areaOpacity, format }, availableQueryIndexes, onQueryIndexChange, onColorModeChange, onColorValueChange, onLineStyleChange, onAreaOpacityChange, onDelete, inputRef, onAddColor: onAddColor, onRemoveColor: onRemoveColor, onAddLineStyle, onRemoveLineStyle, onAddAreaOpacity, onRemoveAreaOpacity, onAddFormat, onRemoveFormat, onFormatChange }) {
|
|
343
|
+
function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue, lineStyle, areaOpacity, format, negativeY, stack }, availableQueryIndexes, queryNames, onQueryIndexChange, onColorModeChange, onColorValueChange, onLineStyleChange, onAreaOpacityChange, onDelete, inputRef, onAddColor: onAddColor, onRemoveColor: onRemoveColor, onAddLineStyle, onRemoveLineStyle, onAddAreaOpacity, onRemoveAreaOpacity, onAddFormat, onRemoveFormat, onFormatChange, onAddNegativeY, onRemoveNegativeY, onAddStack, onRemoveStack, onStackChange }) {
|
|
309
344
|
// current query index should also be selectable
|
|
310
345
|
const selectableQueryIndexes = availableQueryIndexes.concat(queryIndex).sort((a, b)=>a - b);
|
|
311
346
|
// State for dropdown menu
|
|
@@ -333,16 +368,30 @@ function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue
|
|
|
333
368
|
label: 'Format',
|
|
334
369
|
action: onAddFormat
|
|
335
370
|
});
|
|
371
|
+
if (!negativeY) options.push({
|
|
372
|
+
key: 'negativeY',
|
|
373
|
+
label: 'Negative Y',
|
|
374
|
+
action: onAddNegativeY
|
|
375
|
+
});
|
|
376
|
+
if (stack === undefined) options.push({
|
|
377
|
+
key: 'stack',
|
|
378
|
+
label: 'Stack',
|
|
379
|
+
action: onAddStack
|
|
380
|
+
});
|
|
336
381
|
return options;
|
|
337
382
|
}, [
|
|
338
383
|
colorMode,
|
|
339
384
|
lineStyle,
|
|
340
385
|
areaOpacity,
|
|
341
386
|
format,
|
|
387
|
+
negativeY,
|
|
388
|
+
stack,
|
|
342
389
|
onAddColor,
|
|
343
390
|
onAddLineStyle,
|
|
344
391
|
onAddAreaOpacity,
|
|
345
|
-
onAddFormat
|
|
392
|
+
onAddFormat,
|
|
393
|
+
onAddNegativeY,
|
|
394
|
+
onAddStack
|
|
346
395
|
]);
|
|
347
396
|
const handleAddMenuClick = (event)=>{
|
|
348
397
|
if (availableOptions.length === 1 && availableOptions[0]) {
|
|
@@ -389,12 +438,9 @@ function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue
|
|
|
389
438
|
sx: {
|
|
390
439
|
minWidth: '75px'
|
|
391
440
|
},
|
|
392
|
-
children: selectableQueryIndexes.map((qi)=>/*#__PURE__*/ (0, _jsxruntime.
|
|
441
|
+
children: selectableQueryIndexes.map((qi)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
|
|
393
442
|
value: qi,
|
|
394
|
-
children: [
|
|
395
|
-
"#",
|
|
396
|
-
qi + 1
|
|
397
|
-
]
|
|
443
|
+
children: queryNames[qi] ?? `#${qi + 1}`
|
|
398
444
|
}, `query-${qi}`))
|
|
399
445
|
}),
|
|
400
446
|
colorMode && /*#__PURE__*/ (0, _jsxruntime.jsxs)(SettingsSection, {
|
|
@@ -421,7 +467,7 @@ function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue
|
|
|
421
467
|
]
|
|
422
468
|
}),
|
|
423
469
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.OptionsColorPicker, {
|
|
424
|
-
label: `Query n°${queryIndex + 1}`,
|
|
470
|
+
label: queryNames[queryIndex] ?? `Query n°${queryIndex + 1}`,
|
|
425
471
|
color: colorValue || DEFAULT_COLOR_VALUE,
|
|
426
472
|
onColorChange: onColorValueChange
|
|
427
473
|
})
|
|
@@ -489,6 +535,39 @@ function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue
|
|
|
489
535
|
})
|
|
490
536
|
})
|
|
491
537
|
}),
|
|
538
|
+
negativeY && /*#__PURE__*/ (0, _jsxruntime.jsx)(SettingsSection, {
|
|
539
|
+
label: "Negative Y",
|
|
540
|
+
onRemove: onRemoveNegativeY,
|
|
541
|
+
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Typography, {
|
|
542
|
+
variant: "body2",
|
|
543
|
+
color: "text.secondary",
|
|
544
|
+
sx: {
|
|
545
|
+
flexGrow: 1,
|
|
546
|
+
py: 0.5
|
|
547
|
+
},
|
|
548
|
+
children: "Series rendered below the X axis"
|
|
549
|
+
})
|
|
550
|
+
}),
|
|
551
|
+
stack !== undefined && /*#__PURE__*/ (0, _jsxruntime.jsxs)(SettingsSection, {
|
|
552
|
+
label: "Stack",
|
|
553
|
+
onRemove: onRemoveStack,
|
|
554
|
+
children: [
|
|
555
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Switch, {
|
|
556
|
+
checked: stack,
|
|
557
|
+
onChange: (e)=>onStackChange(e.target.checked),
|
|
558
|
+
slotProps: {
|
|
559
|
+
input: {
|
|
560
|
+
'aria-label': 'stack override'
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}),
|
|
564
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
|
|
565
|
+
sx: {
|
|
566
|
+
flexGrow: 1
|
|
567
|
+
}
|
|
568
|
+
})
|
|
569
|
+
]
|
|
570
|
+
}),
|
|
492
571
|
availableOptions.length > 0 && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
493
572
|
children: [
|
|
494
573
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
@@ -531,7 +610,7 @@ function QuerySettingsInput({ querySettings: { queryIndex, colorMode, colorValue
|
|
|
531
610
|
justifyContent: 'center'
|
|
532
611
|
},
|
|
533
612
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
|
|
534
|
-
"aria-label": `delete settings for query n°${queryIndex + 1}`,
|
|
613
|
+
"aria-label": `delete settings for ${queryNames[queryIndex] ?? `query n°${queryIndex + 1}`}`,
|
|
535
614
|
onClick: onDelete,
|
|
536
615
|
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_DeleteOutline.default, {})
|
|
537
616
|
})
|
|
@@ -31,6 +31,7 @@ const _components = require("echarts/components");
|
|
|
31
31
|
const _renderers = require("echarts/renderers");
|
|
32
32
|
const _components1 = require("@perses-dev/components");
|
|
33
33
|
const _timezoneformatter = require("./utils/timezone-formatter");
|
|
34
|
+
const _AnnotationTooltip = require("./annotations/AnnotationTooltip");
|
|
34
35
|
function _interop_require_default(obj) {
|
|
35
36
|
return obj && obj.__esModule ? obj : {
|
|
36
37
|
default: obj
|
|
@@ -50,7 +51,7 @@ function _interop_require_default(obj) {
|
|
|
50
51
|
_components.TooltipComponent,
|
|
51
52
|
_renderers.CanvasRenderer
|
|
52
53
|
]);
|
|
53
|
-
const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeChart({ height, data, seriesMapping, timeScale: timeScaleProp, yAxis, format, seriesFormatMap, grid, isStackedBar = false, tooltipConfig = _components1.DEFAULT_TOOLTIP_CONFIG, noDataVariant = 'message', syncGroup, onDataZoom, onDoubleClick, __experimentalEChartsOptionsOverride }, ref) {
|
|
54
|
+
const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeChart({ height, data, seriesMapping, annotations, timeScale: timeScaleProp, yAxis, format, seriesFormatMap, grid, isStackedBar = false, tooltipConfig = _components1.DEFAULT_TOOLTIP_CONFIG, noDataVariant = 'message', syncGroup, onDataZoom, onDoubleClick, __experimentalEChartsOptionsOverride }, ref) {
|
|
54
55
|
const { chartsTheme, enablePinning, enableSyncGrouping, lastTooltipPinnedCoords, setLastTooltipPinnedCoords } = (0, _components1.useChartsContext)();
|
|
55
56
|
const isPinningEnabled = tooltipConfig.enablePinning && enablePinning;
|
|
56
57
|
const chartRef = (0, _react.useRef)();
|
|
@@ -59,7 +60,10 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
59
60
|
const [pinnedCrosshair, setPinnedCrosshair] = (0, _react.useState)(null);
|
|
60
61
|
const [isDragging, setIsDragging] = (0, _react.useState)(false);
|
|
61
62
|
const [startX, setStartX] = (0, _react.useState)(0);
|
|
62
|
-
const
|
|
63
|
+
const [hoveredAnnotation, setHoveredAnnotation] = (0, _react.useState)(null);
|
|
64
|
+
const [pinnedAnnotation, setPinnedAnnotation] = (0, _react.useState)(null);
|
|
65
|
+
const [pinnedAnnotationPos, setPinnedAnnotationPos] = (0, _react.useState)(null);
|
|
66
|
+
const { timeZone, formatWithUserTimeZone } = (0, _components1.useTimeZone)();
|
|
63
67
|
const getTimezoneAwareAxisFormatter = (0, _react.useCallback)((rangeMs)=>(0, _timezoneformatter.createTimezoneAwareAxisFormatter)(rangeMs, timeZone), [
|
|
64
68
|
timeZone
|
|
65
69
|
]);
|
|
@@ -130,11 +134,44 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
130
134
|
if (chartRef.current !== undefined) {
|
|
131
135
|
(0, _components1.enableDataZoom)(chartRef.current);
|
|
132
136
|
}
|
|
137
|
+
},
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
|
+
mouseover: (params)=>{
|
|
140
|
+
// Only markPoint (triangles under the X-axis) opens the annotation tooltip.
|
|
141
|
+
// Hovering markLine or anything else keeps the regular TimeSeries tooltip visible
|
|
142
|
+
// and clears any stale hovered annotation (mouseout is sometimes missed by ECharts).
|
|
143
|
+
if (annotations && params.componentType === 'markPoint' && params.data?.annotationIndex !== undefined) {
|
|
144
|
+
const matchedAnnotation = annotations[params.data.annotationIndex] || null;
|
|
145
|
+
if (matchedAnnotation) {
|
|
146
|
+
setHoveredAnnotation(matchedAnnotation);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
setHoveredAnnotation(null);
|
|
151
|
+
},
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
153
|
+
mouseout: (params)=>{
|
|
154
|
+
if (annotations && params.componentType === 'markPoint' && params.data?.annotationIndex !== undefined && annotations) {
|
|
155
|
+
// Only clear if the mouseout corresponds to the currently hovered annotation, so that
|
|
156
|
+
// a quick move from one markPoint to another isn't cancelled by a late mouseout event.
|
|
157
|
+
const leaving = annotations[params.data.annotationIndex] || null;
|
|
158
|
+
setHoveredAnnotation((current)=>current === leaving ? null : current);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
globalout: ()=>{
|
|
162
|
+
if (annotations) {
|
|
163
|
+
// Cursor left the chart canvas — guarantee the annotation tooltip is dismissed.
|
|
164
|
+
setHoveredAnnotation(null);
|
|
165
|
+
}
|
|
133
166
|
}
|
|
134
167
|
};
|
|
135
168
|
}, [
|
|
136
|
-
|
|
137
|
-
|
|
169
|
+
annotations,
|
|
170
|
+
onDataZoom
|
|
171
|
+
]);
|
|
172
|
+
// Generate annotation series for ECharts markArea (range), markLine (point), and markPoint (markers under X-axis)
|
|
173
|
+
const annotationSeries = (0, _react.useMemo)(()=>(0, _AnnotationTooltip.buildAnnotationSeries)(annotations), [
|
|
174
|
+
annotations
|
|
138
175
|
]);
|
|
139
176
|
const { noDataOption } = chartsTheme;
|
|
140
177
|
const option = (0, _react.useMemo)(()=>{
|
|
@@ -165,8 +202,12 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
165
202
|
});
|
|
166
203
|
const updatedSeriesMapping = enablePinning && pinnedCrosshair !== null ? [
|
|
167
204
|
...seriesMapping,
|
|
168
|
-
pinnedCrosshair
|
|
169
|
-
|
|
205
|
+
pinnedCrosshair,
|
|
206
|
+
...annotationSeries
|
|
207
|
+
] : [
|
|
208
|
+
...seriesMapping,
|
|
209
|
+
...annotationSeries
|
|
210
|
+
];
|
|
170
211
|
const option = {
|
|
171
212
|
dataset: dataset,
|
|
172
213
|
series: updatedSeriesMapping,
|
|
@@ -218,6 +259,7 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
218
259
|
}, [
|
|
219
260
|
data,
|
|
220
261
|
seriesMapping,
|
|
262
|
+
annotationSeries,
|
|
221
263
|
timeScale,
|
|
222
264
|
yAxis,
|
|
223
265
|
format,
|
|
@@ -258,6 +300,34 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
258
300
|
// e.preventDefault(); // Prevent the default behaviour when right clicked
|
|
259
301
|
// }}
|
|
260
302
|
onClick: (e)=>{
|
|
303
|
+
// If clicking while hovering an annotation, toggle the annotation tooltip pin
|
|
304
|
+
// instead of pinning the TimeChartTooltip, so pinned TimeChartTooltip is preserved.
|
|
305
|
+
if (hoveredAnnotation !== null && e.target instanceof HTMLCanvasElement) {
|
|
306
|
+
const pinnedPos = {
|
|
307
|
+
page: {
|
|
308
|
+
x: e.pageX,
|
|
309
|
+
y: e.pageY
|
|
310
|
+
},
|
|
311
|
+
client: {
|
|
312
|
+
x: e.clientX,
|
|
313
|
+
y: e.clientY
|
|
314
|
+
},
|
|
315
|
+
plotCanvas: {
|
|
316
|
+
x: e.nativeEvent.offsetX,
|
|
317
|
+
y: e.nativeEvent.offsetY
|
|
318
|
+
},
|
|
319
|
+
target: e.target
|
|
320
|
+
};
|
|
321
|
+
setPinnedAnnotation((current)=>{
|
|
322
|
+
if (current === hoveredAnnotation) {
|
|
323
|
+
setPinnedAnnotationPos(null);
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
setPinnedAnnotationPos(pinnedPos);
|
|
327
|
+
return hoveredAnnotation;
|
|
328
|
+
});
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
261
331
|
// Allows user to opt-in to multi tooltip pinning when Ctrl or Cmd key held down
|
|
262
332
|
const isControlKeyPressed = e.ctrlKey || e.metaKey;
|
|
263
333
|
if (isControlKeyPressed) {
|
|
@@ -350,6 +420,8 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
350
420
|
if (tooltipPinnedCoords === null) {
|
|
351
421
|
setShowTooltip(false);
|
|
352
422
|
}
|
|
423
|
+
// Defensive: clear hovered annotation in case ECharts missed a mouseout event.
|
|
424
|
+
setHoveredAnnotation(null);
|
|
353
425
|
if (chartRef.current !== undefined) {
|
|
354
426
|
(0, _components1.clearHighlightedSeries)(chartRef.current);
|
|
355
427
|
}
|
|
@@ -372,7 +444,7 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
372
444
|
}
|
|
373
445
|
},
|
|
374
446
|
children: [
|
|
375
|
-
showTooltip === true && option.tooltip?.showContent === false && tooltipConfig.hidden !== true && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.TimeChartTooltip, {
|
|
447
|
+
showTooltip === true && (tooltipPinnedCoords !== null || hoveredAnnotation === null) && option.tooltip?.showContent === false && tooltipConfig.hidden !== true && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.TimeChartTooltip, {
|
|
376
448
|
containerId: chartsTheme.tooltipPortalContainerId,
|
|
377
449
|
chartRef: chartRef,
|
|
378
450
|
data: data,
|
|
@@ -389,6 +461,17 @@ const TimeSeriesChartBase = /*#__PURE__*/ (0, _react.forwardRef)(function TimeCh
|
|
|
389
461
|
setPinnedCrosshair(null);
|
|
390
462
|
}
|
|
391
463
|
}),
|
|
464
|
+
(pinnedAnnotation ?? hoveredAnnotation) && /*#__PURE__*/ (0, _jsxruntime.jsx)(_AnnotationTooltip.AnnotationTooltip, {
|
|
465
|
+
annotation: pinnedAnnotation ?? hoveredAnnotation,
|
|
466
|
+
containerId: chartsTheme.tooltipPortalContainerId,
|
|
467
|
+
formatWithUserTimeZone: formatWithUserTimeZone,
|
|
468
|
+
pinnedPos: pinnedAnnotation !== null ? pinnedAnnotationPos : null,
|
|
469
|
+
enablePinning: isPinningEnabled,
|
|
470
|
+
onUnpinClick: ()=>{
|
|
471
|
+
setPinnedAnnotation(null);
|
|
472
|
+
setPinnedAnnotationPos(null);
|
|
473
|
+
}
|
|
474
|
+
}),
|
|
392
475
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.EChart, {
|
|
393
476
|
sx: {
|
|
394
477
|
width: '100%',
|
|
@@ -26,10 +26,12 @@ const _material = require("@mui/material");
|
|
|
26
26
|
const _merge = /*#__PURE__*/ _interop_require_default(require("lodash/merge"));
|
|
27
27
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
28
28
|
const _components = require("@perses-dev/components");
|
|
29
|
+
const _dashboards = require("@perses-dev/dashboards");
|
|
29
30
|
const _timeserieschartmodel = require("./time-series-chart-model");
|
|
30
31
|
const _datatransform = require("./utils/data-transform");
|
|
31
32
|
const _palettegen = require("./utils/palette-gen");
|
|
32
33
|
const _TimeSeriesChartBase = require("./TimeSeriesChartBase");
|
|
34
|
+
const _annotation = require("./utils/annotation");
|
|
33
35
|
function _interop_require_default(obj) {
|
|
34
36
|
return obj && obj.__esModule ? obj : {
|
|
35
37
|
default: obj
|
|
@@ -107,6 +109,10 @@ function TimeSeriesChartPanel(props) {
|
|
|
107
109
|
const [selectedLegendItems, setSelectedLegendItems] = (0, _react.useState)('ALL');
|
|
108
110
|
const [legendSorting, setLegendSorting] = (0, _react.useState)();
|
|
109
111
|
const { setTimeRange } = (0, _pluginsystem.useTimeRange)();
|
|
112
|
+
const annotationsWithData = (0, _dashboards.useAnnotationsWithData)();
|
|
113
|
+
const annotations = (0, _react.useMemo)(()=>(0, _annotation.convertAnnotationToTimeSeriesAnnotation)(annotationsWithData), [
|
|
114
|
+
annotationsWithData
|
|
115
|
+
]);
|
|
110
116
|
// Populate series data based on query results
|
|
111
117
|
const { timeScale, timeChartData, timeSeriesMapping, legendItems, seriesFormatMap: computedSeriesFormatMap, maxValuesByFormat } = (0, _react.useMemo)(()=>{
|
|
112
118
|
const timeScale = (0, _datatransform.getCommonTimeScaleForQueries)(queryResults);
|
|
@@ -197,9 +203,21 @@ function TimeSeriesChartPanel(props) {
|
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
205
|
}
|
|
206
|
+
// When negativeY is set on this query, negate the rendered values so the
|
|
207
|
+
// series renders below the X axis. The original (positive) values are
|
|
208
|
+
// preserved in `timeSeries.values` (used for legend calculations) and in
|
|
209
|
+
// `queryResults` (used for CSV export).
|
|
210
|
+
const baseValues = (0, _components.getTimeSeriesValues)(timeSeries, timeScale);
|
|
211
|
+
const renderedValues = querySettings?.negativeY ? baseValues.map((tuple)=>{
|
|
212
|
+
const [t, v] = tuple;
|
|
213
|
+
return [
|
|
214
|
+
t,
|
|
215
|
+
v === null ? null : -v
|
|
216
|
+
];
|
|
217
|
+
}) : baseValues;
|
|
200
218
|
timeChartData.push({
|
|
201
219
|
name: formattedSeriesName,
|
|
202
|
-
values:
|
|
220
|
+
values: renderedValues
|
|
203
221
|
});
|
|
204
222
|
}
|
|
205
223
|
if (legend && legendItems) {
|
|
@@ -355,8 +373,10 @@ function TimeSeriesChartPanel(props) {
|
|
|
355
373
|
end: new Date(event.end)
|
|
356
374
|
});
|
|
357
375
|
};
|
|
358
|
-
// Used to opt in to ECharts trigger item which show subgroup data accurately
|
|
359
|
-
|
|
376
|
+
// Used to opt in to ECharts trigger item which show subgroup data accurately.
|
|
377
|
+
// Derived from the actual series mapping rather than `visual.stack` alone so that
|
|
378
|
+
// bar charts stacked only via per-query overrides also use the right tooltip mode.
|
|
379
|
+
const isStackedBar = visual.display === 'bar' && timeSeriesMapping.some((s)=>s?.type === 'bar' && s.stack === 'all');
|
|
360
380
|
// Turn on tooltip pinning by default but opt out for stacked bar or if explicitly set in tooltip panel spec
|
|
361
381
|
let enablePinning = true;
|
|
362
382
|
if (isStackedBar) {
|
|
@@ -414,6 +434,7 @@ function TimeSeriesChartPanel(props) {
|
|
|
414
434
|
height: height,
|
|
415
435
|
data: timeChartData,
|
|
416
436
|
seriesMapping: timeSeriesMapping,
|
|
437
|
+
annotations: annotations,
|
|
417
438
|
timeScale: timeScale,
|
|
418
439
|
yAxis: multipleYAxes ?? echartsYAxis,
|
|
419
440
|
format: format,
|