diff --git a/app/vmui/packages/vmui/src/components/Chart/BarHitsChart/BarHitsChart.tsx b/app/vmui/packages/vmui/src/components/Chart/BarHitsChart/BarHitsChart.tsx index 2742fa64a..3303b5856 100644 --- a/app/vmui/packages/vmui/src/components/Chart/BarHitsChart/BarHitsChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/BarHitsChart/BarHitsChart.tsx @@ -33,12 +33,15 @@ const BarHitsChart: FC = ({ logHits, data: _data, period, setPeriod, onAp graphStyle: GRAPH_STYLES.LINE_STEPPED, stacked: false, fill: false, + hideChart: false, }); const { xRange, setPlotScale } = usePlotScale({ period, setPeriod }); const { onReadyChart, isPanning } = useReadyChart(setPlotScale); useZoomChart({ uPlotInst, xRange, setPlotScale }); + const isEmptyData = useMemo(() => _data.every(d => d.length === 0), [_data]); + const { data, bands } = useMemo(() => { return graphOptions.stacked ? stack(_data, () => false) : { data: _data, bands: [] }; }, [graphOptions, _data]); @@ -88,26 +91,33 @@ const BarHitsChart: FC = ({ logHits, data: _data, period, setPeriod, onAp }, [data]); return ( -
-
+
+ {!graphOptions.hideChart && (
- -
+ className={classNames({ + "vm-bar-hits-chart": true, + "vm-bar-hits-chart_panning": isPanning + })} + ref={containerRef} + > +
+ +
+ )} - {uPlotInst && ( + {uPlotInst && !isEmptyData && !graphOptions.hideChart && ( = ({ onChange }) => { const [graphStyle, setGraphStyle] = useStateSearchParams(GRAPH_STYLES.LINE_STEPPED, "graph"); const [stacked, setStacked] = useStateSearchParams(false, "stacked"); const [fill, setFill] = useStateSearchParams(false, "fill"); + const [hideChart, setHideChart] = useStateSearchParams(false, "hide_chart"); const options: GraphOptions = useMemo(() => ({ graphStyle, stacked, fill, - }), [graphStyle, stacked, fill]); + hideChart, + }), [graphStyle, stacked, fill, hideChart]); const handleChangeGraphStyle = (val: string) => () => { setGraphStyle(val as GRAPH_STYLES); @@ -52,24 +54,41 @@ const BarHitsOptions: FC = ({ onChange }) => { setSearchParams(searchParams); }; + const toggleHideChart = () => { + setHideChart(prev => { + const newVal = !prev; + newVal ? searchParams.set("hide_chart", "true") : searchParams.delete("hide_chart"); + setSearchParams(searchParams); + return newVal; + }); + }; + useEffect(() => { onChange(options); }, [options]); return ( -
- +
+
{ const { serverUrl } = useAppState(); const { duration, relativeTime, period: periodState } = useTimeState(); const { setSearchParamsFromKeys } = useSearchParamsFromObject(); + const [searchParams] = useSearchParams(); + const hideChart = useMemo(() => searchParams.get("hide_chart"), [searchParams]); const [limit, setLimit] = useStateSearchParams(defaultLimit, "limit"); const [query, setQuery] = useStateSearchParams("*", "query"); @@ -49,7 +52,7 @@ const ExploreLogs: FC = () => { const newPeriod = getPeriod(); setPeriod(newPeriod); fetchLogs(newPeriod).then((isSuccess) => { - isSuccess && fetchLogHits(newPeriod); + isSuccess && !hideChart && fetchLogHits(newPeriod); }).catch(e => e); setSearchParamsFromKeys( { query, @@ -88,6 +91,10 @@ const ExploreLogs: FC = () => { setTmpQuery(query); }, [query]); + useEffect(() => { + !hideChart && fetchLogHits(period); + }, [hideChart]); + return (
= ({ logHits, period, error, isLoading, onApplyFilter }) => { const { isMobile } = useDeviceDetect(); const timeDispatch = useTimeDispatch(); + const [searchParams] = useSearchParams(); + const hideChart = useMemo(() => searchParams.get("hide_chart"), [searchParams]); const getYAxes = (logHits: LogHits[], timestamps: number[]) => { return logHits.map(hits => { @@ -69,14 +72,16 @@ const ExploreLogsBarChart: FC = ({ logHits, period, error, isLoading, onA const noData = data.every(d => d.length === 0); const noTimestamps = data[0].length === 0; const noValues = data[1].length === 0; - if (noData) { + if (hideChart) { + return "Chart hidden. Hits updates paused."; + } else if (noData) { return "No logs volume available\nNo volume information available for the current queries and time range."; } else if (noTimestamps) { return "No timestamp information available for the current queries and time range."; } else if (noValues) { return "No value information available for the current queries and time range."; } return ""; - }, [data]); + }, [data, hideChart]); const setPeriod = ({ from, to }: {from: Date, to: Date}) => { timeDispatch({ type: "SET_PERIOD", payload: { from, to } }); diff --git a/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsBarChart/style.scss b/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsBarChart/style.scss index 1c0b9c9de..283ea83b7 100644 --- a/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsBarChart/style.scss +++ b/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsBarChart/style.scss @@ -13,8 +13,12 @@ } &__empty { + display: flex; + align-items: center; + justify-content: center; position: absolute; - transform: translateY(-25px); + top: 0; + bottom: 0; z-index: 2; } } diff --git a/app/vmui/packages/vmui/src/pages/ExploreLogs/GroupLogs/style.scss b/app/vmui/packages/vmui/src/pages/ExploreLogs/GroupLogs/style.scss index 00c97496b..1d7910a6e 100644 --- a/app/vmui/packages/vmui/src/pages/ExploreLogs/GroupLogs/style.scss +++ b/app/vmui/packages/vmui/src/pages/ExploreLogs/GroupLogs/style.scss @@ -7,7 +7,6 @@ display: flex; align-items: center; justify-content: flex-end; - gap: $padding-global; &-keys { max-height: 300px; diff --git a/docs/VictoriaLogs/CHANGELOG.md b/docs/VictoriaLogs/CHANGELOG.md index f9a40d7ca..4c8dcdfbc 100644 --- a/docs/VictoriaLogs/CHANGELOG.md +++ b/docs/VictoriaLogs/CHANGELOG.md @@ -15,6 +15,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta ## tip + +* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add ability to hide hits chart. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/7117). * FEATURE: add basic [alerting rules](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-vlogs.yml) for VictoriaLogs process. See details at [monitoring docs](https://docs.victoriametrics.com/victorialogs/#monitoring). * FEATURE: improve [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe) performance on systems with many CPU cores when `by(...)` fields contain big number of unique values. For example, `_time:1d | stats by (user_id) count() x` should be executed much faster when `user_id` field contains millions of unique values. * FEATURE: improve performance for [`top`](https://docs.victoriametrics.com/victorialogs/logsql/#top-pipe), [`uniq`](https://docs.victoriametrics.com/victorialogs/logsql/#uniq-pipe) and [`field_values`](https://docs.victoriametrics.com/victorialogs/logsql/#field_values-pipe) pipes on systems with many CPU cores when it is applied to [log fields](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model) with big number of unique values. For example, `_time:1d | top 5 (user_id)` should be executed much faster when `user_id` field contains millions of unique values.