mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
feat: copy pairs on click in legend (#2087)
This commit is contained in:
parent
ede93469ea
commit
e46b7d33a7
4 changed files with 48 additions and 5 deletions
|
@ -1,9 +1,10 @@
|
|||
import React, {FC, useMemo} from "preact/compat";
|
||||
import React, {FC, useMemo, useState} from "preact/compat";
|
||||
import {hexToRGB} from "../../utils/color";
|
||||
import {useAppState} from "../../state/common/StateContext";
|
||||
import {LegendItem} from "../../utils/uplot/types";
|
||||
import "./legend.css";
|
||||
import {getDashLine} from "../../utils/uplot/helpers";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
export interface LegendProps {
|
||||
labels: LegendItem[];
|
||||
|
@ -13,10 +14,18 @@ export interface LegendProps {
|
|||
const Legend: FC<LegendProps> = ({labels, onChange}) => {
|
||||
const {query} = useAppState();
|
||||
|
||||
const [copiedValue, setCopiedValue] = useState("");
|
||||
|
||||
const groups = useMemo(() => {
|
||||
return Array.from(new Set(labels.map(l => l.group)));
|
||||
}, [labels]);
|
||||
|
||||
const handleClickFreeField = async (val: string, id: string) => {
|
||||
await navigator.clipboard.writeText(val);
|
||||
setCopiedValue(id);
|
||||
setTimeout(() => setCopiedValue(""), 2000);
|
||||
};
|
||||
|
||||
return <>
|
||||
<div className="legendWrapper">
|
||||
{groups.map((group) => <div className="legendGroup" key={group}>
|
||||
|
@ -39,7 +48,25 @@ const Legend: FC<LegendProps> = ({labels, onChange}) => {
|
|||
borderColor: legendItem.color,
|
||||
backgroundColor: `rgba(${hexToRGB(legendItem.color)}, 0.1)`
|
||||
}}/>
|
||||
<div className="legendLabel">{legendItem.label}</div>
|
||||
<div className="legendLabel">
|
||||
{legendItem.freeFormFields.__name__ || `Query ${legendItem.group} result`}
|
||||
{!!Object.keys(legendItem.freeFormFields).length && <>
|
||||
 {
|
||||
{Object.keys(legendItem.freeFormFields).filter(f => f !== "__name__").map((f) => {
|
||||
const freeField = `${f}="${legendItem.freeFormFields[f]}"`;
|
||||
const fieldId = `${legendItem.group}.${legendItem.label}.${freeField}`;
|
||||
return <Tooltip arrow key={f} open={copiedValue === fieldId} title={"Copied!"}>
|
||||
<span className="legendFreeFields" onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleClickFreeField(freeField, fieldId);
|
||||
}}>
|
||||
{f}: {legendItem.freeFormFields[f]}
|
||||
</span>
|
||||
</Tooltip>;
|
||||
})}
|
||||
}
|
||||
</>}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
grid-gap: 6px;
|
||||
align-items: start;
|
||||
justify-content: start;
|
||||
padding: 5px 10px;
|
||||
padding: 7px 50px 7px 10px;
|
||||
background-color: #FFF;
|
||||
cursor: pointer;
|
||||
transition: 0.2s ease;
|
||||
|
@ -56,14 +56,27 @@
|
|||
border-style: solid;
|
||||
box-sizing: border-box;
|
||||
transition: 0.2s ease;
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.legendLabel {
|
||||
font-size: 11px;
|
||||
line-height: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.legendFreeFields {
|
||||
padding: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.legendFreeFields:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.legendFreeFields:not(:last-child):after {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
.legendWrapperHotkey {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -10,6 +10,7 @@ export const getSeriesItem = (d: MetricResult, hideSeries: string[]): Series =>
|
|||
return {
|
||||
label,
|
||||
dash: getDashLine(d.group),
|
||||
class: JSON.stringify(d.metric),
|
||||
width: 1.4,
|
||||
stroke: getColorLine(d.group, label),
|
||||
show: !includesHideSeries(label, d.group, hideSeries),
|
||||
|
@ -25,7 +26,8 @@ export const getLegendItem = (s: Series, group: number): LegendItem => ({
|
|||
group,
|
||||
label: s.label || "",
|
||||
color: s.stroke as string,
|
||||
checked: s.show || false
|
||||
checked: s.show || false,
|
||||
freeFormFields: JSON.parse(s.class || "{}"),
|
||||
});
|
||||
|
||||
export const getHideSeries = ({hideSeries, legend, metaKey, series}: HideSeriesArgs): string[] => {
|
||||
|
|
|
@ -36,4 +36,5 @@ export interface LegendItem {
|
|||
label: string;
|
||||
color: string;
|
||||
checked: boolean;
|
||||
freeFormFields: {[key: string]: string};
|
||||
}
|
Loading…
Reference in a new issue