vmui: give more visually different colors to graph lines (#3656)

* feat: make more different colors of graph lines

* docs/CHANGELOG.md: give more visually different colors to graph lines
This commit is contained in:
Yury Molodov 2023-01-18 05:25:37 +01:00 committed by Aliaksandr Valialkin
parent 0498377837
commit 6e033b93b0
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
5 changed files with 57 additions and 29 deletions

View file

@ -1,9 +1,9 @@
import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat"; import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat";
import { MetricResult } from "../../../api/types"; import { MetricResult } from "../../../api/types";
import LineChart from "../../Chart/LineChart/LineChart"; import LineChart from "../../Chart/LineChart/LineChart";
import { AlignedData as uPlotData, Series as uPlotSeries } from "uplot"; import { AlignedData as uPlotData, Series as uPlotSeries } from "uplot";
import Legend from "../../Chart/Legend/Legend"; import Legend from "../../Chart/Legend/Legend";
import { getHideSeries, getLegendItem, getSeriesItem } from "../../../utils/uplot/series"; import { getHideSeries, getLegendItem, getSeriesItemContext } from "../../../utils/uplot/series";
import { getLimitsYAxis, getMinMaxBuffer, getTimeSeries } from "../../../utils/uplot/axes"; import { getLimitsYAxis, getMinMaxBuffer, getTimeSeries } from "../../../utils/uplot/axes";
import { LegendItemType } from "../../../utils/uplot/types"; import { LegendItemType } from "../../../utils/uplot/types";
import { TimeParams } from "../../../types"; import { TimeParams } from "../../../types";
@ -59,6 +59,7 @@ const GraphView: FC<GraphViewProps> = ({
}) => { }) => {
const { timezone } = useTimeState(); const { timezone } = useTimeState();
const currentStep = useMemo(() => customStep || period.step || "1s", [period.step, customStep]); const currentStep = useMemo(() => customStep || period.step || "1s", [period.step, customStep]);
const getSeriesItem = useCallback(getSeriesItemContext(), [data]);
const [dataChart, setDataChart] = useState<uPlotData>([[]]); const [dataChart, setDataChart] = useState<uPlotData>([[]]);
const [series, setSeries] = useState<uPlotSeries[]>([]); const [series, setSeries] = useState<uPlotSeries[]>([]);

View file

@ -1,14 +1,35 @@
export const getColorFromString = (str: string): string => { export const baseContrastColors = [
let hash = 0; "#e54040",
for (let i = 0; i < str.length; i++) { "#32a9dc",
hash = str.charCodeAt(i) + ((hash << 5) - hash); "#2ee329",
"#7126a1",
"#e38f0f",
"#3d811a",
"#ffea00",
"#2d2d2d",
"#da42a6",
"#a44e0c",
];
export const getColorFromString = (text: string): string => {
const SEED = 16777215;
const FACTOR = 49979693;
let b = 1;
let d = 0;
let f = 1;
if (text.length > 0) {
for (let i = 0; i < text.length; i++) {
text[i].charCodeAt(0) > d && (d = text[i].charCodeAt(0));
f = parseInt(String(SEED / d));
b = (b + text[i].charCodeAt(0) * f * FACTOR) % SEED;
} }
let colour = "#";
for (let i = 0; i < 3; i++) {
const value = (hash >> (i * 8)) & 0xFF;
colour += ("00" + value.toString(16)).substr(-2);
} }
return colour;
let hex = ((b * text.length) % SEED).toString(16);
hex = hex.padEnd(6, hex);
return `#${hex}`;
}; };
export const hexToRGB = (hex: string): string => { export const hexToRGB = (hex: string): string => {

View file

@ -1,5 +1,4 @@
import uPlot, { Axis } from "uplot"; import uPlot, { Axis } from "uplot";
import { getColorFromString } from "../color";
export const defaultOptions = { export const defaultOptions = {
legend: { legend: {
@ -85,6 +84,4 @@ export const sizeAxis = (u: uPlot, values: string[], axisIdx: number, cycleNum:
return Math.ceil(axisSize); return Math.ceil(axisSize);
}; };
export const getColorLine = (label: string): string => getColorFromString(label);
export const getDashLine = (group: number): number[] => group <= 1 ? [] : [group*4, group*1.2]; export const getDashLine = (group: number): number[] => group <= 1 ? [] : [group*4, group*1.2];

View file

@ -2,20 +2,27 @@ import { MetricResult } from "../../api/types";
import { Series } from "uplot"; import { Series } from "uplot";
import { getNameForMetric } from "../metric"; import { getNameForMetric } from "../metric";
import { BarSeriesItem, Disp, Fill, LegendItemType, Stroke } from "./types"; import { BarSeriesItem, Disp, Fill, LegendItemType, Stroke } from "./types";
import { getColorLine } from "./helpers";
import { HideSeriesArgs } from "./types"; import { HideSeriesArgs } from "./types";
import { baseContrastColors, getColorFromString } from "../color";
interface SeriesItem extends Series { interface SeriesItem extends Series {
freeFormFields: {[key: string]: string}; freeFormFields: {[key: string]: string};
} }
export const getSeriesItem = (d: MetricResult, hideSeries: string[], alias: string[]): SeriesItem => { export const getSeriesItemContext = () => {
const colorState: {[key: string]: string} = {};
return (d: MetricResult, hideSeries: string[], alias: string[]): SeriesItem => {
const label = getNameForMetric(d, alias[d.group - 1]); const label = getNameForMetric(d, alias[d.group - 1]);
const countSavedColors = Object.keys(colorState).length;
const hasBasicColors = countSavedColors < baseContrastColors.length;
if (hasBasicColors) colorState[label] = colorState[label] || baseContrastColors[countSavedColors];
return { return {
label, label,
freeFormFields: d.metric, freeFormFields: d.metric,
width: 1.4, width: 1.4,
stroke: getColorLine(label), stroke: colorState[label] || getColorFromString(label),
show: !includesHideSeries(label, hideSeries), show: !includesHideSeries(label, hideSeries),
scale: "1", scale: "1",
points: { points: {
@ -23,6 +30,7 @@ export const getSeriesItem = (d: MetricResult, hideSeries: string[], alias: stri
width: 1.4 width: 1.4
} }
}; };
};
}; };
export const getLegendItem = (s: SeriesItem, group: number): LegendItemType => ({ export const getLegendItem = (s: SeriesItem, group: number): LegendItemType => ({

View file

@ -17,6 +17,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add ability to show custom dashboards at vmui by specifying a path to a directory with dashboard config files via `-vmui.customDashboardsPath` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3322) and [these docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmui/packages/vmui/public/dashboards). * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add ability to show custom dashboards at vmui by specifying a path to a directory with dashboard config files via `-vmui.customDashboardsPath` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3322) and [these docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmui/packages/vmui/public/dashboards).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): apply the `step` globally to all the displayed graphs. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3574). * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): apply the `step` globally to all the displayed graphs. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3574).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): improve the appearance of graph lines by using more visually distinct colors. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3656).
* BUGFIX: do not slow down concurrently executed queries during assisted merges, since assisted merges already prioritize data ingestion over queries. The probability of assisted merges has been increased starting from [v1.85.0](https://docs.victoriametrics.com/CHANGELOG.html#v1850) because of internal refactoring. This could result in slowed down queries when there is a plenty of free CPU resources. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3647) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3641) issues. * BUGFIX: do not slow down concurrently executed queries during assisted merges, since assisted merges already prioritize data ingestion over queries. The probability of assisted merges has been increased starting from [v1.85.0](https://docs.victoriametrics.com/CHANGELOG.html#v1850) because of internal refactoring. This could result in slowed down queries when there is a plenty of free CPU resources. See [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3647) and [this](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3641) issues.
* BUGFIX: reduce the increased CPU usage at `vmselect` to v1.85.3 level when processing heavy queries. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3641). * BUGFIX: reduce the increased CPU usage at `vmselect` to v1.85.3 level when processing heavy queries. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3641).