NodeGraph: Show gradient fields in legend (#34078)

* Add gradient fields to legend

* Fix test

* Remove unnecessary mapping

* Add tests
This commit is contained in:
Andrej Ocenas
2021-05-18 16:30:27 +02:00
committed by GitHub
parent bbaa7a9b62
commit 2e7ccf0e42
14 changed files with 161 additions and 46 deletions
@@ -1,7 +1,7 @@
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';
/**
* @deprecated use theme.vizColors.getByName
* @deprecated use theme.visualization.getColorByName
*/
export function getColorForTheme(color: string, theme: GrafanaTheme): string {
return theme.visualization.getColorByName(color);
@@ -0,0 +1,20 @@
import React from 'react';
import { render } from '@testing-library/react';
import { SeriesIcon } from './SeriesIcon';
describe('SeriesIcon', () => {
it('renders gradient correctly', () => {
const { container } = render(<SeriesIcon gradient={'continuous-GrYlRd'} />);
const div = container.firstChild! as HTMLDivElement;
// There is issue in JSDOM which means we cannot actually get the gradient value. I guess if it's empty at least
// we know it is setting some gradient instead of a single color.
// https://github.com/jsdom/jsdom/issues/2166
expect(div.style.getPropertyValue('background')).toBe('');
});
it('renders color correctly', () => {
const { container } = render(<SeriesIcon color={'red'} />);
const div = container.firstChild! as HTMLDivElement;
expect(div.style.getPropertyValue('background')).toBe('red');
});
});
@@ -1,20 +1,40 @@
import React, { CSSProperties } from 'react';
import { useTheme2 } from '../../themes';
import { fieldColorModeRegistry } from '@grafana/data';
export interface Props extends React.HTMLAttributes<HTMLDivElement> {
color: string;
color?: string;
gradient?: string;
}
export const SeriesIcon = React.forwardRef<HTMLDivElement, Props>(({ color, className, ...restProps }, ref) => {
const styles: CSSProperties = {
backgroundColor: color,
width: '14px',
height: '4px',
borderRadius: '1px',
display: 'inline-block',
marginRight: '8px',
};
export const SeriesIcon = React.forwardRef<HTMLDivElement, Props>(
({ color, className, gradient, ...restProps }, ref) => {
const theme = useTheme2();
let cssColor: string;
return <div ref={ref} className={className} style={styles} {...restProps} />;
});
if (gradient) {
const colors = fieldColorModeRegistry.get(gradient).getColors?.(theme);
if (colors?.length) {
cssColor = `linear-gradient(90deg, ${colors.join(', ')})`;
} else {
// Not sure what to default to, this will return gray, this should not happen though.
cssColor = theme.visualization.getColorByName('');
}
} else {
cssColor = color!;
}
const styles: CSSProperties = {
background: cssColor,
width: '14px',
height: '4px',
borderRadius: '1px',
display: 'inline-block',
marginRight: '8px',
};
return <div ref={ref} className={className} style={styles} {...restProps} />;
}
);
SeriesIcon.displayName = 'SeriesIcon';
@@ -59,7 +59,7 @@ export const VizLegendListItem = <T extends unknown = any>({
className={cx(styles.itemWrapper, className)}
aria-label={selectors.components.VizLegend.seriesName(item.label)}
>
<VizLegendSeriesIcon seriesName={item.label} color={item.color} />
<VizLegendSeriesIcon seriesName={item.label} color={item.color} gradient={item.gradient} />
<div
onMouseEnter={onMouseEnter}
onMouseOut={onMouseOut}
@@ -5,13 +5,14 @@ import { SeriesIcon } from './SeriesIcon';
interface Props {
seriesName: string;
color: string;
color?: string;
gradient?: string;
}
/**
* @internal
*/
export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName, color }) => {
export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName, color, gradient }) => {
const { onSeriesColorChange } = usePanelContext();
const onChange = useCallback(
(color: string) => {
@@ -20,7 +21,7 @@ export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName
[seriesName, onSeriesColorChange]
);
if (seriesName && onSeriesColorChange) {
if (seriesName && onSeriesColorChange && color) {
return (
<SeriesColorPicker color={color} onChange={onChange} enableNamedColors>
{({ ref, showColorPicker, hideColorPicker }) => (
@@ -35,7 +36,7 @@ export const VizLegendSeriesIcon: React.FunctionComponent<Props> = ({ seriesName
</SeriesColorPicker>
);
}
return <SeriesIcon color={color} />;
return <SeriesIcon color={color} gradient={gradient} />;
};
VizLegendSeriesIcon.displayName = 'VizLegendSeriesIcon';
@@ -31,7 +31,8 @@ export interface LegendProps<T = any> extends VizLegendBaseProps<T>, VizLegendTa
export interface VizLegendItem<T = any> {
getItemKey?: () => string;
label: string;
color: string;
color?: string;
gradient?: string;
yAxis: number;
disabled?: boolean;
// displayValues?: DisplayValue[];