mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
NamedColors: Named colors refactors (#28235)
* NamedColors: Refactoring, performance improvements, and simplifications * More simplifification * Updated to use new function * Updates * Updates * Updated BarGauge to use fallback color intead of magic string * Updates * Fixed unused import
This commit is contained in:
parent
66def25c6d
commit
451836a86a
@ -3,7 +3,7 @@ import { fieldColorModeRegistry, FieldValueColorCalculator } from './fieldColor'
|
|||||||
|
|
||||||
describe('fieldColorModeRegistry', () => {
|
describe('fieldColorModeRegistry', () => {
|
||||||
interface GetCalcOptions {
|
interface GetCalcOptions {
|
||||||
mode: FieldColorModeId;
|
mode: string;
|
||||||
seriesIndex?: number;
|
seriesIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ describe('fieldColorModeRegistry', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it('Schemes should interpolate', () => {
|
it('Schemes should interpolate', () => {
|
||||||
const calcFn = getCalculator({ mode: FieldColorModeId.ContinousGrYlRd });
|
const calcFn = getCalculator({ mode: 'continuous-GrYlRd' });
|
||||||
expect(calcFn(70, 0.5, undefined)).toEqual('rgb(226, 192, 61)');
|
expect(calcFn(70, 0.5, undefined)).toEqual('rgb(226, 192, 61)');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { FALLBACK_COLOR, Field, FieldColorModeId, GrafanaTheme, Threshold } from '../types';
|
import { FALLBACK_COLOR, Field, FieldColorModeId, GrafanaTheme, Threshold } from '../types';
|
||||||
import { classicColors, getColorFromHexRgbOrName, RegistryItem } from '../utils';
|
import { classicColors, getColorForTheme, RegistryItem } from '../utils';
|
||||||
import { Registry } from '../utils/Registry';
|
import { Registry } from '../utils/Registry';
|
||||||
import { interpolateRgbBasis } from 'd3-interpolate';
|
import { interpolateRgbBasis } from 'd3-interpolate';
|
||||||
import { fallBackTreshold } from './thresholds';
|
import { fallBackTreshold } from './thresholds';
|
||||||
@ -23,64 +23,56 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: FieldColorModeId.Thresholds,
|
id: FieldColorModeId.Thresholds,
|
||||||
name: 'Color by thresholds',
|
name: 'From thresholds',
|
||||||
description: 'Derive colors from thresholds',
|
description: 'Derive colors from thresholds',
|
||||||
getCalculator: (_field, theme) => {
|
getCalculator: (_field, theme) => {
|
||||||
return (_value, _percent, threshold) => {
|
return (_value, _percent, threshold) => {
|
||||||
const thresholdSafe = threshold ?? fallBackTreshold;
|
const thresholdSafe = threshold ?? fallBackTreshold;
|
||||||
return getColorFromHexRgbOrName(thresholdSafe.color, theme.type);
|
return getColorForTheme(thresholdSafe.color, theme);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new FieldColorSchemeMode({
|
// new FieldColorSchemeMode({
|
||||||
id: FieldColorModeId.PaletteSaturated,
|
// id: FieldColorModeId.PaletteSaturated,
|
||||||
name: 'Color by series / Saturated palette',
|
// name: 'By series / Saturated palette',
|
||||||
//description: 'Assigns color based on series or field index',
|
// //description: 'Assigns color based on series or field index',
|
||||||
isContinuous: false,
|
// isContinuous: false,
|
||||||
isByValue: false,
|
// isByValue: false,
|
||||||
colors: [
|
// colors: [
|
||||||
'blue',
|
// 'blue',
|
||||||
'red',
|
// 'red',
|
||||||
'green',
|
// 'green',
|
||||||
'yellow',
|
// 'yellow',
|
||||||
'purple',
|
// 'purple',
|
||||||
'orange',
|
// 'orange',
|
||||||
'dark-blue',
|
// 'dark-blue',
|
||||||
'dark-red',
|
// 'dark-red',
|
||||||
'dark-yellow',
|
// 'dark-yellow',
|
||||||
'dark-purple',
|
// 'dark-purple',
|
||||||
'dark-orange',
|
// 'dark-orange',
|
||||||
],
|
// ],
|
||||||
}),
|
// }),
|
||||||
new FieldColorSchemeMode({
|
new FieldColorSchemeMode({
|
||||||
id: FieldColorModeId.PaletteClassic,
|
id: FieldColorModeId.PaletteClassic,
|
||||||
name: 'Color by series / Classic palette',
|
name: 'By series / Classic palette',
|
||||||
//description: 'Assigns color based on series or field index',
|
//description: 'Assigns color based on series or field index',
|
||||||
isContinuous: false,
|
isContinuous: false,
|
||||||
isByValue: false,
|
isByValue: false,
|
||||||
colors: classicColors,
|
colors: classicColors,
|
||||||
}),
|
}),
|
||||||
new FieldColorSchemeMode({
|
new FieldColorSchemeMode({
|
||||||
id: FieldColorModeId.ContinousGrYlRd,
|
id: 'continuous-GrYlRd',
|
||||||
name: 'Color by value / Green-Yellow-Red / Continouous',
|
name: 'By value / Green Yellow Red (gradient)',
|
||||||
//description: 'Interpolated colors based value, min and max',
|
//description: 'Interpolated colors based value, min and max',
|
||||||
isContinuous: true,
|
isContinuous: true,
|
||||||
isByValue: true,
|
isByValue: true,
|
||||||
colors: ['green', 'yellow', 'red'],
|
colors: ['green', 'yellow', 'red'],
|
||||||
}),
|
}),
|
||||||
new FieldColorSchemeMode({
|
|
||||||
id: FieldColorModeId.ContinousBlGrOr,
|
|
||||||
name: 'Color by value / Blue-Green-Orange / Continouous',
|
|
||||||
//description: 'Interpolated colors based value, min and max',
|
|
||||||
isContinuous: true,
|
|
||||||
isByValue: true,
|
|
||||||
colors: ['blue', 'green', 'orange'],
|
|
||||||
}),
|
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
interface FieldColorSchemeModeOptions {
|
interface FieldColorSchemeModeOptions {
|
||||||
id: FieldColorModeId;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
colors: string[];
|
colors: string[];
|
||||||
@ -112,7 +104,7 @@ export class FieldColorSchemeMode implements FieldColorMode {
|
|||||||
return this.colorCache;
|
return this.colorCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colorCache = this.colors.map(c => getColorFromHexRgbOrName(c, theme.type));
|
this.colorCache = this.colors.map(c => getColorForTheme(c, theme));
|
||||||
return this.colorCache;
|
return this.colorCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +149,6 @@ export function getFieldColorMode(mode?: FieldColorModeId): FieldColorMode {
|
|||||||
|
|
||||||
function getFixedColor(field: Field, theme: GrafanaTheme) {
|
function getFixedColor(field: Field, theme: GrafanaTheme) {
|
||||||
return () => {
|
return () => {
|
||||||
return getColorFromHexRgbOrName(field.config.color?.fixedColor ?? FALLBACK_COLOR, theme.type);
|
return getColorForTheme(field.config.color?.fixedColor ?? FALLBACK_COLOR, theme);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
export enum FieldColorModeId {
|
export enum FieldColorModeId {
|
||||||
Thresholds = 'thresholds',
|
Thresholds = 'thresholds',
|
||||||
ContinousGrYlRd = 'continuous-GrYlRd',
|
|
||||||
ContinousBlGrOr = 'continuous-BlGrOr',
|
|
||||||
PaletteClassic = 'palette-classic',
|
PaletteClassic = 'palette-classic',
|
||||||
PaletteSaturated = 'palette-saturated',
|
PaletteSaturated = 'palette-saturated',
|
||||||
Fixed = 'fixed',
|
Fixed = 'fixed',
|
||||||
|
@ -1,48 +1,9 @@
|
|||||||
import {
|
import { getColorFromHexRgbOrName, getColorDefinitionByName } from './namedColorsPalette';
|
||||||
getColorName,
|
|
||||||
getColorDefinition,
|
|
||||||
getColorByName,
|
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
getColorDefinitionByName,
|
|
||||||
} from './namedColorsPalette';
|
|
||||||
import { GrafanaThemeType } from '../types/theme';
|
import { GrafanaThemeType } from '../types/theme';
|
||||||
|
|
||||||
describe('colors', () => {
|
describe('colors', () => {
|
||||||
const SemiDarkBlue = getColorDefinitionByName('semi-dark-blue');
|
const SemiDarkBlue = getColorDefinitionByName('semi-dark-blue');
|
||||||
|
|
||||||
describe('getColorDefinition', () => {
|
|
||||||
it('returns undefined for unknown hex', () => {
|
|
||||||
expect(getColorDefinition('#ff0000', GrafanaThemeType.Light)).toBeUndefined();
|
|
||||||
expect(getColorDefinition('#ff0000', GrafanaThemeType.Dark)).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns definition for known hex', () => {
|
|
||||||
expect(getColorDefinition(SemiDarkBlue.variants.light, GrafanaThemeType.Light)).toEqual(SemiDarkBlue);
|
|
||||||
expect(getColorDefinition(SemiDarkBlue.variants.dark, GrafanaThemeType.Dark)).toEqual(SemiDarkBlue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getColorName', () => {
|
|
||||||
it('returns undefined for unknown hex', () => {
|
|
||||||
expect(getColorName('#ff0000')).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns name for known hex', () => {
|
|
||||||
expect(getColorName(SemiDarkBlue.variants.light, GrafanaThemeType.Light)).toEqual(SemiDarkBlue.name);
|
|
||||||
expect(getColorName(SemiDarkBlue.variants.dark, GrafanaThemeType.Dark)).toEqual(SemiDarkBlue.name);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getColorByName', () => {
|
|
||||||
it('returns undefined for unknown color', () => {
|
|
||||||
expect(getColorByName('aruba-sunshine')).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns color definition for known color', () => {
|
|
||||||
expect(getColorByName(SemiDarkBlue.name)).toBe(SemiDarkBlue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getColorFromHexRgbOrName', () => {
|
describe('getColorFromHexRgbOrName', () => {
|
||||||
it('returns black for unknown color', () => {
|
it('returns black for unknown color', () => {
|
||||||
expect(getColorFromHexRgbOrName('aruba-sunshine')).toBe('#000000');
|
expect(getColorFromHexRgbOrName('aruba-sunshine')).toBe('#000000');
|
||||||
@ -57,7 +18,7 @@ describe('colors', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns color if specified as hex or rgb/a', () => {
|
it('returns color if specified as hex or rgb/a', () => {
|
||||||
expect(getColorFromHexRgbOrName('ff0000')).toBe('ff0000');
|
expect(getColorFromHexRgbOrName('ff0000')).toBe('#ff0000');
|
||||||
expect(getColorFromHexRgbOrName('#ff0000')).toBe('#ff0000');
|
expect(getColorFromHexRgbOrName('#ff0000')).toBe('#ff0000');
|
||||||
expect(getColorFromHexRgbOrName('#FF0000')).toBe('#FF0000');
|
expect(getColorFromHexRgbOrName('#FF0000')).toBe('#FF0000');
|
||||||
expect(getColorFromHexRgbOrName('#CCC')).toBe('#CCC');
|
expect(getColorFromHexRgbOrName('#CCC')).toBe('#CCC');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import flatten from 'lodash/flatten';
|
import flatten from 'lodash/flatten';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { GrafanaThemeType } from '../types/theme';
|
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';
|
||||||
|
|
||||||
type Hue = 'green' | 'yellow' | 'red' | 'blue' | 'orange' | 'purple';
|
type Hue = 'green' | 'yellow' | 'red' | 'blue' | 'orange' | 'purple';
|
||||||
|
|
||||||
@ -49,6 +49,8 @@ export type ColorDefinition = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let colorsPaletteInstance: Map<Hue, ColorDefinition[]>;
|
let colorsPaletteInstance: Map<Hue, ColorDefinition[]>;
|
||||||
|
let colorsMap: Record<Color, string> | undefined;
|
||||||
|
let colorsMapTheme: GrafanaTheme | undefined;
|
||||||
|
|
||||||
const buildColorDefinition = (
|
const buildColorDefinition = (
|
||||||
hue: Hue,
|
hue: Hue,
|
||||||
@ -65,62 +67,60 @@ const buildColorDefinition = (
|
|||||||
isPrimary: !!isPrimary,
|
isPrimary: !!isPrimary,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getColorDefinitionByName = (name: Color): ColorDefinition => {
|
export function getColorDefinitionByName(name: Color): ColorDefinition {
|
||||||
return flatten(Array.from(getNamedColorPalette().values())).filter(definition => definition.name === name)[0];
|
return flatten(Array.from(getNamedColorPalette().values())).filter(definition => definition.name === name)[0];
|
||||||
};
|
}
|
||||||
|
|
||||||
export const getColorDefinition = (hex: string, theme: GrafanaThemeType): ColorDefinition | undefined => {
|
export function buildColorsMapForTheme(theme: GrafanaTheme): Record<Color, string> {
|
||||||
return flatten(Array.from(getNamedColorPalette().values())).filter(
|
theme = theme ?? GrafanaThemeType.Dark;
|
||||||
definition => definition.variants[theme] === hex
|
|
||||||
)[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
const isHex = (color: string) => {
|
colorsMap = {} as Record<Color, string>;
|
||||||
const hexRegex = /^((0x){0,1}|#{0,1})([0-9A-F]{8}|[0-9A-F]{6}|[0-9A-F]{3})$/gi;
|
|
||||||
return hexRegex.test(color);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getColorName = (color?: string, theme?: GrafanaThemeType): Color | undefined => {
|
for (const def of getNamedColorPalette().values()) {
|
||||||
|
for (const c of def) {
|
||||||
|
colorsMap[c.name] = c.variants[theme.type];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colorsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getColorForTheme(color: string, theme: GrafanaTheme): string {
|
||||||
if (!color) {
|
if (!color) {
|
||||||
return undefined;
|
return 'gray';
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we need to rebuild cache
|
||||||
|
if (!colorsMap || colorsMapTheme !== theme) {
|
||||||
|
colorsMap = buildColorsMapForTheme(theme);
|
||||||
|
colorsMapTheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
let realColor = colorsMap[color as Color];
|
||||||
|
if (realColor) {
|
||||||
|
return realColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color[0] === '#') {
|
||||||
|
return (colorsMap[color as Color] = color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color.indexOf('rgb') > -1) {
|
if (color.indexOf('rgb') > -1) {
|
||||||
return undefined;
|
return (colorsMap[color as Color] = color);
|
||||||
}
|
|
||||||
if (isHex(color)) {
|
|
||||||
const definition = getColorDefinition(color, theme || GrafanaThemeType.Dark);
|
|
||||||
return definition ? definition.name : undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return color as Color;
|
return (colorsMap[color as Color] = tinycolor(color).toHexString());
|
||||||
};
|
|
||||||
|
|
||||||
export const getColorByName = (colorName: string) => {
|
|
||||||
const definition = flatten(Array.from(getNamedColorPalette().values())).filter(
|
|
||||||
definition => definition.name === colorName
|
|
||||||
);
|
|
||||||
return definition.length > 0 ? definition[0] : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getColorFromHexRgbOrName = (color: string, theme?: GrafanaThemeType): string => {
|
|
||||||
if (color.indexOf('rgb') > -1 || isHex(color)) {
|
|
||||||
return color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const colorDefinition = getColorByName(color);
|
/**
|
||||||
|
* @deprecated use getColorForTheme
|
||||||
|
*/
|
||||||
|
export function getColorFromHexRgbOrName(color: string, type?: GrafanaThemeType): string {
|
||||||
|
const themeType = type ?? GrafanaThemeType.Dark;
|
||||||
|
|
||||||
if (!colorDefinition) {
|
return getColorForTheme(color, ({ type: themeType } as unknown) as GrafanaTheme);
|
||||||
return new tinycolor(color).toHexString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return theme ? colorDefinition.variants[theme] : colorDefinition.variants.dark;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getColorForTheme = (color: ColorDefinition, theme?: GrafanaThemeType) => {
|
|
||||||
return theme ? color.variants[theme] : color.variants.dark;
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildNamedColorsPalette = () => {
|
const buildNamedColorsPalette = () => {
|
||||||
const palette = new Map<Hue, ColorDefinition[]>();
|
const palette = new Map<Hue, ColorDefinition[]>();
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { useTheme } from '../../themes/ThemeContext';
|
|||||||
import { stylesFactory } from '../../themes/stylesFactory';
|
import { stylesFactory } from '../../themes/stylesFactory';
|
||||||
import { IconName } from '../../types';
|
import { IconName } from '../../types';
|
||||||
import { Tooltip } from '../Tooltip/Tooltip';
|
import { Tooltip } from '../Tooltip/Tooltip';
|
||||||
import { getColorFromHexRgbOrName, GrafanaTheme } from '@grafana/data';
|
import { getColorForTheme, GrafanaTheme } from '@grafana/data';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { HorizontalGroup } from '..';
|
import { HorizontalGroup } from '..';
|
||||||
@ -42,7 +42,7 @@ export const Badge = React.memo<BadgeProps>(({ icon, color, text, tooltip }) =>
|
|||||||
Badge.displayName = 'Badge';
|
Badge.displayName = 'Badge';
|
||||||
|
|
||||||
const getStyles = stylesFactory((theme: GrafanaTheme, color: BadgeColor) => {
|
const getStyles = stylesFactory((theme: GrafanaTheme, color: BadgeColor) => {
|
||||||
let sourceColor = getColorFromHexRgbOrName(color);
|
let sourceColor = getColorForTheme(color, theme);
|
||||||
let borderColor = '';
|
let borderColor = '';
|
||||||
let bgColor = '';
|
let bgColor = '';
|
||||||
let textColor = '';
|
let textColor = '';
|
||||||
|
@ -12,6 +12,8 @@ import {
|
|||||||
FieldConfig,
|
FieldConfig,
|
||||||
FieldColorModeId,
|
FieldColorModeId,
|
||||||
getFieldColorMode,
|
getFieldColorMode,
|
||||||
|
getColorForTheme,
|
||||||
|
FALLBACK_COLOR,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
|
||||||
@ -19,7 +21,6 @@ import { selectors } from '@grafana/e2e-selectors';
|
|||||||
import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay';
|
import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { getColorFromHexRgbOrName } from '@grafana/data';
|
|
||||||
import { measureText, calculateFontSize } from '../../utils/measureText';
|
import { measureText, calculateFontSize } from '../../utils/measureText';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@ -131,8 +132,8 @@ export class BarGauge extends PureComponent<Props> {
|
|||||||
const { value, display } = this.props;
|
const { value, display } = this.props;
|
||||||
if (positionValue === null) {
|
if (positionValue === null) {
|
||||||
return {
|
return {
|
||||||
background: 'gray',
|
background: FALLBACK_COLOR,
|
||||||
border: 'gray',
|
border: FALLBACK_COLOR,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +166,8 @@ export class BarGauge extends PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
background: 'gray',
|
background: FALLBACK_COLOR,
|
||||||
border: 'gray',
|
border: FALLBACK_COLOR,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +527,7 @@ export function getBarGradient(props: Props, maxSize: number): string {
|
|||||||
|
|
||||||
for (let i = 0; i < thresholds.steps.length; i++) {
|
for (let i = 0; i < thresholds.steps.length; i++) {
|
||||||
const threshold = thresholds.steps[i];
|
const threshold = thresholds.steps[i];
|
||||||
const color = getColorFromHexRgbOrName(threshold.color);
|
const color = getColorForTheme(threshold.color, props.theme);
|
||||||
const valuePercent = getValuePercent(threshold.value, minValue, maxValue);
|
const valuePercent = getValuePercent(threshold.value, minValue, maxValue);
|
||||||
const pos = valuePercent * maxSize;
|
const pos = valuePercent * maxSize;
|
||||||
const offset = Math.round(pos - (pos - lastpos) / 2);
|
const offset = Math.round(pos - (pos - lastpos) / 2);
|
||||||
@ -545,7 +546,7 @@ export function getBarGradient(props: Props, maxSize: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode.colors) {
|
if (mode.colors) {
|
||||||
const scheme = mode.colors.map(item => getColorFromHexRgbOrName(item, theme.type));
|
const scheme = mode.colors.map(item => getColorForTheme(item, theme));
|
||||||
for (let i = 0; i < scheme.length; i++) {
|
for (let i = 0; i < scheme.length; i++) {
|
||||||
const color = scheme[i];
|
const color = scheme[i];
|
||||||
|
|
||||||
@ -560,18 +561,19 @@ export function getBarGradient(props: Props, maxSize: number): string {
|
|||||||
return gradient + ')';
|
return gradient + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'gray';
|
return value.color ?? FALLBACK_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only exported to for unit test
|
* Only exported to for unit test
|
||||||
*/
|
*/
|
||||||
export function getValueColor(props: Props): string {
|
export function getValueColor(props: Props): string {
|
||||||
const { theme, value } = props;
|
const { value } = props;
|
||||||
if (value.color) {
|
if (value.color) {
|
||||||
return value.color;
|
return value.color;
|
||||||
}
|
}
|
||||||
return getColorFromHexRgbOrName('gray', theme.type);
|
|
||||||
|
return FALLBACK_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValueStyles(
|
function getValueStyles(
|
||||||
@ -582,7 +584,7 @@ function getValueStyles(
|
|||||||
orientation: VizOrientation
|
orientation: VizOrientation
|
||||||
): CSSProperties {
|
): CSSProperties {
|
||||||
const styles: CSSProperties = {
|
const styles: CSSProperties = {
|
||||||
color: color,
|
color,
|
||||||
height: `${height}px`,
|
height: `${height}px`,
|
||||||
width: `${width}px`,
|
width: `${width}px`,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
@ -4,7 +4,7 @@ import tinycolor from 'tinycolor2';
|
|||||||
import { Chart, Geom } from 'bizcharts';
|
import { Chart, Geom } from 'bizcharts';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { getColorFromHexRgbOrName, formattedValueToString, DisplayValue } from '@grafana/data';
|
import { formattedValueToString, DisplayValue, getColorForTheme } from '@grafana/data';
|
||||||
import { calculateFontSize } from '../../utils/measureText';
|
import { calculateFontSize } from '../../utils/measureText';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@ -30,7 +30,7 @@ export abstract class BigValueLayout {
|
|||||||
constructor(private props: Props) {
|
constructor(private props: Props) {
|
||||||
const { width, height, value, theme } = props;
|
const { width, height, value, theme } = props;
|
||||||
|
|
||||||
this.valueColor = getColorFromHexRgbOrName(value.color || 'green', theme.type);
|
this.valueColor = getColorForTheme(value.color || 'green', theme);
|
||||||
this.panelPadding = height > 100 ? 12 : 8;
|
this.panelPadding = height > 100 ? 12 : 8;
|
||||||
this.textValues = getTextValues(props);
|
this.textValues = getTextValues(props);
|
||||||
this.justifyCenter = shouldJustifyCenter(props.justifyMode, this.textValues.title);
|
this.justifyCenter = shouldJustifyCenter(props.justifyMode, this.textValues.title);
|
||||||
|
@ -3,7 +3,7 @@ import omit from 'lodash/omit';
|
|||||||
import { PopoverController } from '../Tooltip/PopoverController';
|
import { PopoverController } from '../Tooltip/PopoverController';
|
||||||
import { Popover } from '../Tooltip/Popover';
|
import { Popover } from '../Tooltip/Popover';
|
||||||
import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
|
import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
|
||||||
import { getColorFromHexRgbOrName } from '@grafana/data';
|
import { getColorForTheme } from '@grafana/data';
|
||||||
import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
|
import { SeriesColorPickerPopover } from './SeriesColorPickerPopover';
|
||||||
|
|
||||||
import { withTheme } from '../../themes/ThemeContext';
|
import { withTheme } from '../../themes/ThemeContext';
|
||||||
@ -74,7 +74,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
|||||||
ref={this.pickerTriggerRef}
|
ref={this.pickerTriggerRef}
|
||||||
onClick={showPopper}
|
onClick={showPopper}
|
||||||
onMouseLeave={hidePopper}
|
onMouseLeave={hidePopper}
|
||||||
color={getColorFromHexRgbOrName(this.props.color || '#000000', theme.type)}
|
color={getColorForTheme(this.props.color || '#000000', theme)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
@ -4,18 +4,16 @@ import { ColorPickerPopover } from './ColorPickerPopover';
|
|||||||
import { ColorSwatch } from './NamedColorsGroup';
|
import { ColorSwatch } from './NamedColorsGroup';
|
||||||
import flatten from 'lodash/flatten';
|
import flatten from 'lodash/flatten';
|
||||||
import { getTheme } from '../../themes';
|
import { getTheme } from '../../themes';
|
||||||
import { GrafanaThemeType, getColorDefinitionByName, getNamedColorPalette } from '@grafana/data';
|
import { GrafanaThemeType, getNamedColorPalette, getColorFromHexRgbOrName } from '@grafana/data';
|
||||||
|
|
||||||
const allColors = flatten(Array.from(getNamedColorPalette().values()));
|
const allColors = flatten(Array.from(getNamedColorPalette().values()));
|
||||||
|
|
||||||
describe('ColorPickerPopover', () => {
|
describe('ColorPickerPopover', () => {
|
||||||
const BasicGreen = getColorDefinitionByName('green');
|
|
||||||
const BasicBlue = getColorDefinitionByName('blue');
|
|
||||||
|
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
it('should render provided color as selected if color provided by name', () => {
|
it('should render provided color as selected if color provided by name', () => {
|
||||||
const wrapper = mount(<ColorPickerPopover color={BasicGreen.name} onChange={() => {}} theme={getTheme()} />);
|
const theme = getTheme();
|
||||||
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
|
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} theme={theme} />);
|
||||||
|
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === 'green');
|
||||||
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
|
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
|
||||||
|
|
||||||
expect(selectedSwatch.length).toBe(1);
|
expect(selectedSwatch.length).toBe(1);
|
||||||
@ -24,10 +22,10 @@ describe('ColorPickerPopover', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should render provided color as selected if color provided by hex', () => {
|
it('should render provided color as selected if color provided by hex', () => {
|
||||||
const wrapper = mount(
|
const theme = getTheme();
|
||||||
<ColorPickerPopover color={BasicGreen.variants.dark} onChange={() => {}} theme={getTheme()} />
|
const wrapper = mount(<ColorPickerPopover color={'green'} onChange={() => {}} theme={theme} />);
|
||||||
);
|
|
||||||
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicGreen.name);
|
const selectedSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === 'green');
|
||||||
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
|
const notSelectedSwatches = wrapper.find(ColorSwatch).filterWhere(node => node.prop('isSelected') === false);
|
||||||
|
|
||||||
expect(selectedSwatch.length).toBe(1);
|
expect(selectedSwatch.length).toBe(1);
|
||||||
@ -47,35 +45,31 @@ describe('ColorPickerPopover', () => {
|
|||||||
|
|
||||||
it('should pass hex color value to onChange prop by default', () => {
|
it('should pass hex color value to onChange prop by default', () => {
|
||||||
wrapper = mount(
|
wrapper = mount(
|
||||||
<ColorPickerPopover
|
<ColorPickerPopover color={'green'} onChange={onChangeSpy} theme={getTheme(GrafanaThemeType.Light)} />
|
||||||
color={BasicGreen.variants.dark}
|
|
||||||
onChange={onChangeSpy}
|
|
||||||
theme={getTheme(GrafanaThemeType.Light)}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicBlue.name);
|
|
||||||
|
|
||||||
|
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === 'green');
|
||||||
basicBlueSwatch.simulate('click');
|
basicBlueSwatch.simulate('click');
|
||||||
|
|
||||||
expect(onChangeSpy).toBeCalledTimes(1);
|
expect(onChangeSpy).toBeCalledTimes(1);
|
||||||
expect(onChangeSpy).toBeCalledWith(BasicBlue.variants.light);
|
expect(onChangeSpy).toBeCalledWith(getColorFromHexRgbOrName('green', GrafanaThemeType.Light));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass color name to onChange prop when named colors enabled', () => {
|
it('should pass color name to onChange prop when named colors enabled', () => {
|
||||||
wrapper = mount(
|
wrapper = mount(
|
||||||
<ColorPickerPopover
|
<ColorPickerPopover
|
||||||
enableNamedColors
|
enableNamedColors
|
||||||
color={BasicGreen.variants.dark}
|
color={'green'}
|
||||||
onChange={onChangeSpy}
|
onChange={onChangeSpy}
|
||||||
theme={getTheme(GrafanaThemeType.Light)}
|
theme={getTheme(GrafanaThemeType.Light)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === BasicBlue.name);
|
|
||||||
|
|
||||||
|
const basicBlueSwatch = wrapper.find(ColorSwatch).findWhere(node => node.key() === 'green');
|
||||||
basicBlueSwatch.simulate('click');
|
basicBlueSwatch.simulate('click');
|
||||||
|
|
||||||
expect(onChangeSpy).toBeCalledTimes(1);
|
expect(onChangeSpy).toBeCalledTimes(1);
|
||||||
expect(onChangeSpy).toBeCalledWith(BasicBlue.name);
|
expect(onChangeSpy).toBeCalledWith('green');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@ import { PopoverContentProps } from '../Tooltip/Tooltip';
|
|||||||
import SpectrumPalette from './SpectrumPalette';
|
import SpectrumPalette from './SpectrumPalette';
|
||||||
import { Themeable } from '../../types/theme';
|
import { Themeable } from '../../types/theme';
|
||||||
import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation';
|
import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation';
|
||||||
import { GrafanaThemeType, getColorName, getColorFromHexRgbOrName } from '@grafana/data';
|
import { GrafanaThemeType, getColorForTheme } from '@grafana/data';
|
||||||
|
|
||||||
export type ColorPickerChangeHandler = (color: string) => void;
|
export type ColorPickerChangeHandler = (color: string) => void;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
|
|||||||
if (enableNamedColors) {
|
if (enableNamedColors) {
|
||||||
return changeHandler(color);
|
return changeHandler(color);
|
||||||
}
|
}
|
||||||
changeHandler(getColorFromHexRgbOrName(color, theme.type));
|
changeHandler(getColorForTheme(color, theme));
|
||||||
};
|
};
|
||||||
|
|
||||||
onTabChange = (tab: PickerType | keyof T) => {
|
onTabChange = (tab: PickerType | keyof T) => {
|
||||||
@ -72,9 +72,7 @@ export class ColorPickerPopover<T extends CustomPickersDescriptor> extends React
|
|||||||
case 'spectrum':
|
case 'spectrum':
|
||||||
return <SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />;
|
return <SpectrumPalette color={color} onChange={this.handleChange} theme={theme} />;
|
||||||
case 'palette':
|
case 'palette':
|
||||||
return (
|
return <NamedColorsPalette color={color} onChange={this.handleChange} theme={theme} />;
|
||||||
<NamedColorsPalette color={getColorName(color, theme.type)} onChange={this.handleChange} theme={theme} />
|
|
||||||
);
|
|
||||||
default:
|
default:
|
||||||
return this.renderCustomPicker(activePicker);
|
return this.renderCustomPicker(activePicker);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { Themeable } from '../../types';
|
import { Themeable } from '../../types';
|
||||||
import { ColorDefinition, getColorForTheme } from '@grafana/data';
|
import { ColorDefinition } from '@grafana/data';
|
||||||
import { Color } from 'csstype';
|
import { Color } from 'csstype';
|
||||||
import upperFirst from 'lodash/upperFirst';
|
import upperFirst from 'lodash/upperFirst';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
@ -86,7 +86,7 @@ const NamedColorsGroup: FunctionComponent<NamedColorsGroupProps> = ({
|
|||||||
key={primaryColor.name}
|
key={primaryColor.name}
|
||||||
isSelected={primaryColor.name === selectedColor}
|
isSelected={primaryColor.name === selectedColor}
|
||||||
variant={ColorSwatchVariant.Large}
|
variant={ColorSwatchVariant.Large}
|
||||||
color={getColorForTheme(primaryColor, theme.type)}
|
color={primaryColor.variants[theme.type]}
|
||||||
label={upperFirst(primaryColor.hue)}
|
label={upperFirst(primaryColor.hue)}
|
||||||
onClick={() => onColorSelect(primaryColor)}
|
onClick={() => onColorSelect(primaryColor)}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
@ -105,7 +105,7 @@ const NamedColorsGroup: FunctionComponent<NamedColorsGroupProps> = ({
|
|||||||
<ColorSwatch
|
<ColorSwatch
|
||||||
key={color.name}
|
key={color.name}
|
||||||
isSelected={color.name === selectedColor}
|
isSelected={color.name === selectedColor}
|
||||||
color={getColorForTheme(color, theme.type)}
|
color={color.variants[theme.type]}
|
||||||
onClick={() => onColorSelect(color)}
|
onClick={() => onColorSelect(color)}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NamedColorsPalette } from './NamedColorsPalette';
|
import { NamedColorsPalette } from './NamedColorsPalette';
|
||||||
import { getColorName, getColorDefinitionByName } from '@grafana/data';
|
|
||||||
import { select } from '@storybook/addon-knobs';
|
import { select } from '@storybook/addon-knobs';
|
||||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||||
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
|
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
|
||||||
import { UseState } from '../../utils/storybook/UseState';
|
import { UseState } from '../../utils/storybook/UseState';
|
||||||
import mdx from './ColorPicker.mdx';
|
import mdx from './ColorPicker.mdx';
|
||||||
|
|
||||||
const BasicGreen = getColorDefinitionByName('green');
|
|
||||||
const BasicRed = getColorDefinitionByName('red');
|
|
||||||
const LightBlue = getColorDefinitionByName('light-blue');
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Pickers and Editors/ColorPicker/Palettes/NamedColorsPalette',
|
title: 'Pickers and Editors/ColorPicker/Palettes/NamedColorsPalette',
|
||||||
component: NamedColorsPalette,
|
component: NamedColorsPalette,
|
||||||
@ -44,22 +39,3 @@ export const namedColors = () => {
|
|||||||
</UseState>
|
</UseState>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hexValues = () => {
|
|
||||||
let hexVals: any = {};
|
|
||||||
hexVals[BasicGreen.variants.dark] = BasicGreen.variants.dark;
|
|
||||||
hexVals[BasicRed.variants.dark] = BasicRed.variants.dark;
|
|
||||||
hexVals[LightBlue.variants.dark] = LightBlue.variants.dark;
|
|
||||||
|
|
||||||
const selectedColor = select('Selected color', hexVals, 'red');
|
|
||||||
return (
|
|
||||||
<UseState initialState={selectedColor}>
|
|
||||||
{(selectedColor, updateSelectedColor) => {
|
|
||||||
return renderComponentWithTheme(NamedColorsPalette, {
|
|
||||||
color: getColorName(selectedColor),
|
|
||||||
onChange: updateSelectedColor,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
</UseState>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Color, getNamedColorPalette } from '@grafana/data';
|
import { getNamedColorPalette } from '@grafana/data';
|
||||||
import { Themeable } from '../../types/index';
|
import { Themeable } from '../../types/index';
|
||||||
import NamedColorsGroup from './NamedColorsGroup';
|
import NamedColorsGroup from './NamedColorsGroup';
|
||||||
|
|
||||||
export interface NamedColorsPaletteProps extends Themeable {
|
export interface NamedColorsPaletteProps extends Themeable {
|
||||||
color?: Color;
|
color?: string;
|
||||||
onChange: (colorName: string) => void;
|
onChange: (colorName: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import tinycolor from 'tinycolor2';
|
|||||||
import ColorInput from './ColorInput';
|
import ColorInput from './ColorInput';
|
||||||
import { Themeable } from '../../types';
|
import { Themeable } from '../../types';
|
||||||
import SpectrumPalettePointer, { SpectrumPalettePointerProps } from './SpectrumPalettePointer';
|
import SpectrumPalettePointer, { SpectrumPalettePointerProps } from './SpectrumPalettePointer';
|
||||||
import { GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/data';
|
import { GrafanaTheme, getColorForTheme } from '@grafana/data';
|
||||||
|
|
||||||
export interface SpectrumPaletteProps extends Themeable {
|
export interface SpectrumPaletteProps extends Themeable {
|
||||||
color: string;
|
color: string;
|
||||||
@ -86,7 +86,7 @@ const SpectrumPalette: React.FunctionComponent<SpectrumPaletteProps> = ({ color,
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SpectrumPicker
|
<SpectrumPicker
|
||||||
color={tinycolor(getColorFromHexRgbOrName(color)).toRgb()}
|
color={tinycolor(getColorForTheme(color, theme)).toRgb()}
|
||||||
onChange={(a: ColorResult) => {
|
onChange={(a: ColorResult) => {
|
||||||
onChange(tinycolor(a.rgb).toString());
|
onChange(tinycolor(a.rgb).toString());
|
||||||
}}
|
}}
|
||||||
|
@ -2,12 +2,12 @@ import React, { PureComponent } from 'react';
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {
|
import {
|
||||||
DisplayValue,
|
DisplayValue,
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
formattedValueToString,
|
formattedValueToString,
|
||||||
FieldConfig,
|
FieldConfig,
|
||||||
ThresholdsMode,
|
ThresholdsMode,
|
||||||
getActiveThreshold,
|
getActiveThreshold,
|
||||||
Threshold,
|
Threshold,
|
||||||
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { Themeable } from '../../types';
|
import { Themeable } from '../../types';
|
||||||
import { selectThemeVariant } from '../../themes';
|
import { selectThemeVariant } from '../../themes';
|
||||||
@ -67,7 +67,7 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
const first = getActiveThreshold(min, steps);
|
const first = getActiveThreshold(min, steps);
|
||||||
const last = getActiveThreshold(max, steps);
|
const last = getActiveThreshold(max, steps);
|
||||||
const formatted: Threshold[] = [];
|
const formatted: Threshold[] = [];
|
||||||
formatted.push({ value: +min.toFixed(decimals), color: getColorFromHexRgbOrName(first.color, theme.type) });
|
formatted.push({ value: +min.toFixed(decimals), color: getColorForTheme(first.color, theme) });
|
||||||
let skip = true;
|
let skip = true;
|
||||||
for (let i = 0; i < steps.length; i++) {
|
for (let i = 0; i < steps.length; i++) {
|
||||||
const step = steps[i];
|
const step = steps[i];
|
||||||
@ -78,12 +78,12 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const prev = steps[i - 1];
|
const prev = steps[i - 1];
|
||||||
formatted.push({ value: step.value, color: getColorFromHexRgbOrName(prev!.color, theme.type) });
|
formatted.push({ value: step.value, color: getColorForTheme(prev!.color, theme) });
|
||||||
if (step === last) {
|
if (step === last) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formatted.push({ value: +max.toFixed(decimals), color: getColorFromHexRgbOrName(last.color, theme.type) });
|
formatted.push({ value: +max.toFixed(decimals), color: getColorForTheme(last.color, theme) });
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ import {
|
|||||||
FieldType,
|
FieldType,
|
||||||
FieldCache,
|
FieldCache,
|
||||||
FieldColorModeId,
|
FieldColorModeId,
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
GrafanaThemeType,
|
|
||||||
Field,
|
Field,
|
||||||
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { getTheme } from '../../themes';
|
||||||
import { getMultiSeriesGraphHoverInfo, findHoverIndexFromData, graphTimeFormat } from './utils';
|
import { getMultiSeriesGraphHoverInfo, findHoverIndexFromData, graphTimeFormat } from './utils';
|
||||||
|
|
||||||
const mockResult = (
|
const mockResult = (
|
||||||
@ -63,7 +63,7 @@ const cSeries = toDataFrame({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getFixedThemedColor(field: Field): string {
|
function getFixedThemedColor(field: Field): string {
|
||||||
return getColorFromHexRgbOrName(field.config.color!.fixedColor!, GrafanaThemeType.Dark);
|
return getColorForTheme(field.config.color!.fixedColor!, getTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Graph utils', () => {
|
describe('Graph utils', () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { GrafanaTheme, getColorFromHexRgbOrName } from '@grafana/data';
|
import { getColorForTheme, GrafanaTheme } from '@grafana/data';
|
||||||
import { ColorPicker } from '../ColorPicker/ColorPicker';
|
import { ColorPicker } from '../ColorPicker/ColorPicker';
|
||||||
import { stylesFactory, useTheme } from '../../themes';
|
import { stylesFactory, useTheme } from '../../themes';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
@ -25,7 +25,7 @@ export const ColorValueEditor: React.FC<Props> = ({ value, onChange }) => {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={showColorPicker}
|
onClick={showColorPicker}
|
||||||
onMouseLeave={hideColorPicker}
|
onMouseLeave={hideColorPicker}
|
||||||
color={value ? getColorFromHexRgbOrName(value, theme.type) : theme.colors.formInputBorder}
|
color={value ? getColorForTheme(value, theme) : theme.colors.formInputBorder}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className={styles.colorText} onClick={showColorPicker}>
|
{/* <div className={styles.colorText} onClick={showColorPicker}>
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
fieldColorModeRegistry,
|
fieldColorModeRegistry,
|
||||||
FieldColorMode,
|
FieldColorMode,
|
||||||
GrafanaTheme,
|
GrafanaTheme,
|
||||||
getColorFromHexRgbOrName,
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { Select } from '../Select/Select';
|
import { Select } from '../Select/Select';
|
||||||
import { ColorValueEditor } from './color';
|
import { ColorValueEditor } from './color';
|
||||||
@ -70,7 +70,7 @@ const FieldColorModeViz: FC<ModeProps> = ({ mode, theme }) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const colors = mode.colors.map(item => getColorFromHexRgbOrName(item, theme.type));
|
const colors = mode.colors.map(item => getColorForTheme(item, theme));
|
||||||
const style: CSSProperties = {
|
const style: CSSProperties = {
|
||||||
height: '8px',
|
height: '8px',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { AreaProps, LineProps, PointProps } from './types';
|
import { AreaProps, LineProps, PointProps } from './types';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
import { getColorFromHexRgbOrName } from '@grafana/data';
|
|
||||||
|
|
||||||
export const getAreaConfig = (props: AreaProps) => {
|
export const getAreaConfig = (props: AreaProps) => {
|
||||||
|
// TODO can we pass therem here? or make sure color is already correct?
|
||||||
const fill = props.fill
|
const fill = props.fill
|
||||||
? tinycolor(getColorFromHexRgbOrName(props.color))
|
? tinycolor(props.color)
|
||||||
.setAlpha(props.fill)
|
.setAlpha(props.fill)
|
||||||
.toRgbString()
|
.toRgbString()
|
||||||
: undefined;
|
: undefined;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { GraphCustomFieldConfig, GraphLegend, LegendDisplayMode, LegendItem } from '../..';
|
import { GraphCustomFieldConfig, GraphLegend, LegendDisplayMode, LegendItem } from '../..';
|
||||||
import { usePlotData } from '../context';
|
import { usePlotData } from '../context';
|
||||||
import { FieldType, getColorFromHexRgbOrName, getFieldDisplayName } from '@grafana/data';
|
import { FieldType, getColorForTheme, getFieldDisplayName } from '@grafana/data';
|
||||||
import { colors } from '../../../utils';
|
import { colors } from '../../../utils';
|
||||||
|
import { useTheme } from '../../../themes';
|
||||||
|
|
||||||
export type LegendPlacement = 'top' | 'bottom' | 'left' | 'right';
|
export type LegendPlacement = 'top' | 'bottom' | 'left' | 'right';
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ interface LegendPluginProps {
|
|||||||
|
|
||||||
export const LegendPlugin: React.FC<LegendPluginProps> = ({ placement, displayMode = LegendDisplayMode.List }) => {
|
export const LegendPlugin: React.FC<LegendPluginProps> = ({ placement, displayMode = LegendDisplayMode.List }) => {
|
||||||
const { data } = usePlotData();
|
const { data } = usePlotData();
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
const legendItems: LegendItem[] = [];
|
const legendItems: LegendItem[] = [];
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ export const LegendPlugin: React.FC<LegendPluginProps> = ({ placement, displayMo
|
|||||||
legendItems.push({
|
legendItems.push({
|
||||||
color:
|
color:
|
||||||
field.config.color && field.config.color.fixedColor
|
field.config.color && field.config.color.fixedColor
|
||||||
? getColorFromHexRgbOrName(field.config.color.fixedColor)
|
? getColorForTheme(field.config.color.fixedColor, theme)
|
||||||
: colors[seriesIdx],
|
: colors[seriesIdx],
|
||||||
label: getFieldDisplayName(field, data),
|
label: getFieldDisplayName(field, data),
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { colors } from '@grafana/ui';
|
import { colors } from '@grafana/ui';
|
||||||
import {
|
import {
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
TimeRange,
|
TimeRange,
|
||||||
FieldType,
|
FieldType,
|
||||||
Field,
|
Field,
|
||||||
@ -9,6 +8,7 @@ import {
|
|||||||
getTimeField,
|
getTimeField,
|
||||||
dateTime,
|
dateTime,
|
||||||
getFieldDisplayName,
|
getFieldDisplayName,
|
||||||
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
@ -84,7 +84,7 @@ export class DataProcessor {
|
|||||||
const series = new TimeSeries({
|
const series = new TimeSeries({
|
||||||
datapoints: datapoints || [],
|
datapoints: datapoints || [],
|
||||||
alias: alias,
|
alias: alias,
|
||||||
color: getColorFromHexRgbOrName(color, config.theme.type),
|
color: getColorForTheme(color, config.theme),
|
||||||
unit: field.config ? field.config.unit : undefined,
|
unit: field.config ? field.config.unit : undefined,
|
||||||
dataFrameIndex,
|
dataFrameIndex,
|
||||||
fieldIndex,
|
fieldIndex,
|
||||||
|
@ -75,7 +75,7 @@ class GraphElement {
|
|||||||
this.panelWidth = 0;
|
this.panelWidth = 0;
|
||||||
this.eventManager = new EventManager(this.ctrl);
|
this.eventManager = new EventManager(this.ctrl);
|
||||||
this.thresholdManager = new ThresholdManager(this.ctrl);
|
this.thresholdManager = new ThresholdManager(this.ctrl);
|
||||||
this.timeRegionManager = new TimeRegionManager(this.ctrl, config.theme.type);
|
this.timeRegionManager = new TimeRegionManager(this.ctrl);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.tooltip = new GraphTooltip(this.elem, this.ctrl.dashboard, this.scope, () => {
|
this.tooltip = new GraphTooltip(this.elem, this.ctrl.dashboard, this.scope, () => {
|
||||||
return this.sortedSeries;
|
return this.sortedSeries;
|
||||||
|
@ -12,7 +12,7 @@ import { axesEditorComponent } from './axes_editor';
|
|||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import { getProcessedDataFrames } from 'app/features/dashboard/state/runRequest';
|
import { getProcessedDataFrames } from 'app/features/dashboard/state/runRequest';
|
||||||
import { getColorFromHexRgbOrName, PanelEvents, PanelPlugin, DataFrame, FieldConfigProperty } from '@grafana/data';
|
import { PanelEvents, PanelPlugin, DataFrame, FieldConfigProperty, getColorForTheme } from '@grafana/data';
|
||||||
|
|
||||||
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl';
|
import { GraphContextMenuCtrl } from './GraphContextMenuCtrl';
|
||||||
import { graphPanelMigrationHandler } from './GraphMigrations';
|
import { graphPanelMigrationHandler } from './GraphMigrations';
|
||||||
@ -327,7 +327,7 @@ export class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onColorChange = (series: any, color: string) => {
|
onColorChange = (series: any, color: string) => {
|
||||||
series.setColor(getColorFromHexRgbOrName(color, config.theme.type));
|
series.setColor(getColorForTheme(color, config.theme));
|
||||||
this.panel.aliasColors[series.alias] = color;
|
this.panel.aliasColors[series.alias] = color;
|
||||||
this.render();
|
this.render();
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
import TimeSeries from 'app/core/time_series2';
|
import TimeSeries from 'app/core/time_series2';
|
||||||
import { ThresholdManager } from '../threshold_manager';
|
import { ThresholdManager } from '../threshold_manager';
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ describe('ThresholdManager', () => {
|
|||||||
|
|
||||||
describe('When creating plot markings', () => {
|
describe('When creating plot markings', () => {
|
||||||
plotOptionsScenario('for simple gt threshold', (ctx: any) => {
|
plotOptionsScenario('for simple gt threshold', (ctx: any) => {
|
||||||
|
console.log('config', config.theme);
|
||||||
ctx.setup([{ op: 'gt', value: 300, fill: true, line: true, colorMode: 'critical' }]);
|
ctx.setup([{ op: 'gt', value: 300, fill: true, line: true, colorMode: 'critical' }]);
|
||||||
|
|
||||||
it('should add fill for threshold with fill: true', () => {
|
it('should add fill for threshold with fill: true', () => {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'vendor/flot/jquery.flot';
|
import 'vendor/flot/jquery.flot';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { getColorFromHexRgbOrName } from '@grafana/data';
|
import { getColorForTheme } from '@grafana/data';
|
||||||
import { CoreEvents } from 'app/types';
|
import { CoreEvents } from 'app/types';
|
||||||
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
|
|
||||||
export class ThresholdManager {
|
export class ThresholdManager {
|
||||||
plot: any;
|
plot: any;
|
||||||
@ -228,12 +229,12 @@ export class ThresholdManager {
|
|||||||
if (threshold.yaxis === 'right' && this.hasSecondYAxis) {
|
if (threshold.yaxis === 'right' && this.hasSecondYAxis) {
|
||||||
options.grid.markings.push({
|
options.grid.markings.push({
|
||||||
y2axis: { from: threshold.value, to: limit },
|
y2axis: { from: threshold.value, to: limit },
|
||||||
color: getColorFromHexRgbOrName(fillColor),
|
color: getColorForTheme(fillColor, config.theme),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
options.grid.markings.push({
|
options.grid.markings.push({
|
||||||
yaxis: { from: threshold.value, to: limit },
|
yaxis: { from: threshold.value, to: limit },
|
||||||
color: getColorFromHexRgbOrName(fillColor),
|
color: getColorForTheme(fillColor, config.theme),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,12 +242,12 @@ export class ThresholdManager {
|
|||||||
if (threshold.yaxis === 'right' && this.hasSecondYAxis) {
|
if (threshold.yaxis === 'right' && this.hasSecondYAxis) {
|
||||||
options.grid.markings.push({
|
options.grid.markings.push({
|
||||||
y2axis: { from: threshold.value, to: threshold.value },
|
y2axis: { from: threshold.value, to: threshold.value },
|
||||||
color: getColorFromHexRgbOrName(lineColor),
|
color: getColorForTheme(lineColor, config.theme),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
options.grid.markings.push({
|
options.grid.markings.push({
|
||||||
yaxis: { from: threshold.value, to: threshold.value },
|
yaxis: { from: threshold.value, to: threshold.value },
|
||||||
color: getColorFromHexRgbOrName(lineColor),
|
color: getColorForTheme(lineColor, config.theme),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'vendor/flot/jquery.flot';
|
import 'vendor/flot/jquery.flot';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { GrafanaThemeType, getColorFromHexRgbOrName, dateTime, DateTime, AbsoluteTimeRange } from '@grafana/data';
|
import { getColorForTheme, dateTime, DateTime, AbsoluteTimeRange, GrafanaTheme } from '@grafana/data';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
|
|
||||||
type TimeRegionColorDefinition = {
|
type TimeRegionColorDefinition = {
|
||||||
fill: string | null;
|
fill: string | null;
|
||||||
@ -42,27 +43,27 @@ export function getColorModes() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getColor(timeRegion: any, theme: GrafanaThemeType): TimeRegionColorDefinition {
|
function getColor(timeRegion: any, theme: GrafanaTheme): TimeRegionColorDefinition {
|
||||||
if (Object.keys(colorModes).indexOf(timeRegion.colorMode) === -1) {
|
if (Object.keys(colorModes).indexOf(timeRegion.colorMode) === -1) {
|
||||||
timeRegion.colorMode = 'red';
|
timeRegion.colorMode = 'red';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeRegion.colorMode === 'custom') {
|
if (timeRegion.colorMode === 'custom') {
|
||||||
return {
|
return {
|
||||||
fill: timeRegion.fill && timeRegion.fillColor ? getColorFromHexRgbOrName(timeRegion.fillColor, theme) : null,
|
fill: timeRegion.fill && timeRegion.fillColor ? getColorForTheme(timeRegion.fillColor, theme) : null,
|
||||||
line: timeRegion.line && timeRegion.lineColor ? getColorFromHexRgbOrName(timeRegion.lineColor, theme) : null,
|
line: timeRegion.line && timeRegion.lineColor ? getColorForTheme(timeRegion.lineColor, theme) : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const colorMode = colorModes[timeRegion.colorMode];
|
const colorMode = colorModes[timeRegion.colorMode];
|
||||||
|
|
||||||
if (colorMode.themeDependent === true) {
|
if (colorMode.themeDependent === true) {
|
||||||
return theme === GrafanaThemeType.Light ? colorMode.lightColor : colorMode.darkColor;
|
return theme.isLight ? colorMode.lightColor : colorMode.darkColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fill: timeRegion.fill ? getColorFromHexRgbOrName(colorMode.color.fill, theme) : null,
|
fill: timeRegion.fill ? getColorForTheme(colorMode.color.fill, theme) : null,
|
||||||
line: timeRegion.fill ? getColorFromHexRgbOrName(colorMode.color.line, theme) : null,
|
line: timeRegion.fill ? getColorForTheme(colorMode.color.line, theme) : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ export class TimeRegionManager {
|
|||||||
plot: any;
|
plot: any;
|
||||||
timeRegions: any;
|
timeRegions: any;
|
||||||
|
|
||||||
constructor(private panelCtrl: any, private theme: GrafanaThemeType = GrafanaThemeType.Dark) {}
|
constructor(private panelCtrl: any) {}
|
||||||
|
|
||||||
draw(plot: any) {
|
draw(plot: any) {
|
||||||
this.timeRegions = this.panelCtrl.panel.timeRegions;
|
this.timeRegions = this.panelCtrl.panel.timeRegions;
|
||||||
@ -204,7 +205,7 @@ export class TimeRegionManager {
|
|||||||
fromStart.add(24, 'hours');
|
fromStart.add(24, 'hours');
|
||||||
}
|
}
|
||||||
|
|
||||||
timeRegionColor = getColor(timeRegion, this.theme);
|
timeRegionColor = getColor(timeRegion, config.theme);
|
||||||
|
|
||||||
for (let j = 0; j < regions.length; j++) {
|
for (let j = 0; j < regions.length; j++) {
|
||||||
const r = regions[j];
|
const r = regions[j];
|
||||||
|
@ -5,7 +5,8 @@ import { contextSrv } from 'app/core/core';
|
|||||||
import { tickStep } from 'app/core/utils/ticks';
|
import { tickStep } from 'app/core/utils/ticks';
|
||||||
import { getColorScale, getOpacityScale } from './color_scale';
|
import { getColorScale, getOpacityScale } from './color_scale';
|
||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
import { PanelEvents, GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/data';
|
import { PanelEvents, getColorForTheme } from '@grafana/data';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
|
|
||||||
const LEGEND_HEIGHT_PX = 6;
|
const LEGEND_HEIGHT_PX = 6;
|
||||||
const LEGEND_WIDTH_PX = 100;
|
const LEGEND_WIDTH_PX = 100;
|
||||||
@ -272,13 +273,7 @@ function drawSimpleOpacityLegend(elem: JQuery, options: { colorScale: string; ex
|
|||||||
.attr('width', rangeStep)
|
.attr('width', rangeStep)
|
||||||
.attr('height', legendHeight)
|
.attr('height', legendHeight)
|
||||||
.attr('stroke-width', 0)
|
.attr('stroke-width', 0)
|
||||||
.attr(
|
.attr('fill', getColorForTheme(options.cardColor, config.theme))
|
||||||
'fill',
|
|
||||||
getColorFromHexRgbOrName(
|
|
||||||
options.cardColor,
|
|
||||||
contextSrv.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.style('opacity', d => legendOpacityScale(d));
|
.style('opacity', d => legendOpacityScale(d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ import { getColorScale, getOpacityScale } from './color_scale';
|
|||||||
import {
|
import {
|
||||||
toUtc,
|
toUtc,
|
||||||
PanelEvents,
|
PanelEvents,
|
||||||
GrafanaThemeType,
|
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
getValueFormat,
|
getValueFormat,
|
||||||
formattedValueToString,
|
formattedValueToString,
|
||||||
dateTimeFormat,
|
dateTimeFormat,
|
||||||
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { graphTimeFormat } from '@grafana/ui';
|
import { graphTimeFormat } from '@grafana/ui';
|
||||||
import { CoreEvents } from 'app/types';
|
import { CoreEvents } from 'app/types';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
|
|
||||||
const MIN_CARD_SIZE = 1,
|
const MIN_CARD_SIZE = 1,
|
||||||
CARD_PADDING = 1,
|
CARD_PADDING = 1,
|
||||||
@ -682,10 +682,7 @@ export class HeatmapRenderer {
|
|||||||
|
|
||||||
getCardColor(d: { count: any }) {
|
getCardColor(d: { count: any }) {
|
||||||
if (this.panel.color.mode === 'opacity') {
|
if (this.panel.color.mode === 'opacity') {
|
||||||
return getColorFromHexRgbOrName(
|
return getColorForTheme(this.panel.color.cardColor, config.theme);
|
||||||
this.panel.color.cardColor,
|
|
||||||
contextSrv.user.lightTheme ? GrafanaThemeType.Light : GrafanaThemeType.Dark
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return this.colorScale(d.count);
|
return this.colorScale(d.count);
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ import {
|
|||||||
LegacyResponseData,
|
LegacyResponseData,
|
||||||
getFlotPairs,
|
getFlotPairs,
|
||||||
getDisplayProcessor,
|
getDisplayProcessor,
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
PanelEvents,
|
PanelEvents,
|
||||||
formattedValueToString,
|
formattedValueToString,
|
||||||
locationUtil,
|
locationUtil,
|
||||||
getFieldDisplayName,
|
getFieldDisplayName,
|
||||||
|
getColorForTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
|
||||||
import { convertOldAngularValueMapping } from '@grafana/ui';
|
import { convertOldAngularValueMapping } from '@grafana/ui';
|
||||||
@ -542,7 +542,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
show: true,
|
show: true,
|
||||||
fill: 1,
|
fill: 1,
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
fillColor: getColorFromHexRgbOrName(panel.sparkline.fillColor, config.theme.type),
|
fillColor: getColorForTheme(panel.sparkline.fillColor, config.theme),
|
||||||
zero: false,
|
zero: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -564,7 +564,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
|
|
||||||
const plotSeries = {
|
const plotSeries = {
|
||||||
data: data.sparkline,
|
data: data.sparkline,
|
||||||
color: getColorFromHexRgbOrName(panel.sparkline.lineColor, config.theme.type),
|
color: getColorForTheme(panel.sparkline.lineColor, config.theme),
|
||||||
};
|
};
|
||||||
|
|
||||||
$.plot(plotCanvas, [plotSeries], options);
|
$.plot(plotCanvas, [plotSeries], options);
|
||||||
@ -585,7 +585,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
|
|
||||||
// Map panel colors to hex or rgb/a values
|
// Map panel colors to hex or rgb/a values
|
||||||
if (panel.colors) {
|
if (panel.colors) {
|
||||||
data.colorMap = panel.colors.map((color: string) => getColorFromHexRgbOrName(color, config.theme.type));
|
data.colorMap = panel.colors.map((color: string) => getColorForTheme(color, config.theme));
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = panel.gauge.show ? '' : getBigValueHtml();
|
const body = panel.gauge.show ? '' : getBigValueHtml();
|
||||||
|
@ -129,7 +129,7 @@ export class TablePanelCtrl extends MetricsPanelCtrl {
|
|||||||
this.dashboard.getTimezone(),
|
this.dashboard.getTimezone(),
|
||||||
this.$sanitize,
|
this.$sanitize,
|
||||||
this.templateSrv,
|
this.templateSrv,
|
||||||
config.theme.type
|
config.theme
|
||||||
);
|
);
|
||||||
|
|
||||||
return super.render(this.table);
|
return super.render(this.table);
|
||||||
|
@ -2,9 +2,7 @@ import _ from 'lodash';
|
|||||||
import {
|
import {
|
||||||
escapeStringForRegex,
|
escapeStringForRegex,
|
||||||
formattedValueToString,
|
formattedValueToString,
|
||||||
getColorFromHexRgbOrName,
|
|
||||||
getValueFormat,
|
getValueFormat,
|
||||||
GrafanaThemeType,
|
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
stringStartsAsRegEx,
|
stringStartsAsRegEx,
|
||||||
stringToJsRegex,
|
stringToJsRegex,
|
||||||
@ -13,6 +11,8 @@ import {
|
|||||||
TimeZone,
|
TimeZone,
|
||||||
dateTimeFormatISO,
|
dateTimeFormatISO,
|
||||||
dateTimeFormat,
|
dateTimeFormat,
|
||||||
|
getColorForTheme,
|
||||||
|
GrafanaTheme,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
import { getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
import { ColumnRender, TableRenderModel, ColumnStyle } from './types';
|
import { ColumnRender, TableRenderModel, ColumnStyle } from './types';
|
||||||
@ -28,7 +28,7 @@ export class TableRenderer {
|
|||||||
private timeZone: TimeZone,
|
private timeZone: TimeZone,
|
||||||
private sanitize: (v: any) => any,
|
private sanitize: (v: any) => any,
|
||||||
private templateSrv: TemplateSrv = getTemplateSrv(),
|
private templateSrv: TemplateSrv = getTemplateSrv(),
|
||||||
private theme?: GrafanaThemeType
|
private theme: GrafanaTheme
|
||||||
) {
|
) {
|
||||||
this.initColumns();
|
this.initColumns();
|
||||||
}
|
}
|
||||||
@ -75,10 +75,10 @@ export class TableRenderer {
|
|||||||
}
|
}
|
||||||
for (let i = style.thresholds.length; i > 0; i--) {
|
for (let i = style.thresholds.length; i > 0; i--) {
|
||||||
if (value >= style.thresholds[i - 1]) {
|
if (value >= style.thresholds[i - 1]) {
|
||||||
return getColorFromHexRgbOrName(style.colors[i], this.theme);
|
return getColorForTheme(style.colors[i], this.theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getColorFromHexRgbOrName(_.first(style.colors), this.theme);
|
return getColorForTheme(_.first(style.colors), this.theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCellFormatter(v: any, style: ColumnStyle) {
|
defaultCellFormatter(v: any, style: ColumnStyle) {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
import { TableRenderer } from '../renderer';
|
import { TableRenderer } from '../renderer';
|
||||||
import { getColorDefinitionByName, ScopedVars, TimeZone } from '@grafana/data';
|
import { ScopedVars, TimeZone } from '@grafana/data';
|
||||||
import { ColumnRender } from '../types';
|
import { ColumnRender } from '../types';
|
||||||
|
import { config } from 'app/core/config';
|
||||||
|
|
||||||
const utc: TimeZone = 'utc';
|
const utc: TimeZone = 'utc';
|
||||||
|
|
||||||
@ -23,8 +24,6 @@ const templateSrv = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('when rendering table', () => {
|
describe('when rendering table', () => {
|
||||||
const SemiDarkOrange = getColorDefinitionByName('semi-dark-orange');
|
|
||||||
|
|
||||||
describe('given 13 columns', () => {
|
describe('given 13 columns', () => {
|
||||||
const table = new TableModel();
|
const table = new TableModel();
|
||||||
table.columns = [
|
table.columns = [
|
||||||
@ -87,7 +86,7 @@ describe('when rendering table', () => {
|
|||||||
decimals: 1,
|
decimals: 1,
|
||||||
colorMode: 'value',
|
colorMode: 'value',
|
||||||
thresholds: [50, 80],
|
thresholds: [50, 80],
|
||||||
colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'],
|
colors: ['#00ff00', 'semi-dark-orange', 'rgb(1,0,0)'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'String',
|
pattern: 'String',
|
||||||
@ -178,7 +177,7 @@ describe('when rendering table', () => {
|
|||||||
],
|
],
|
||||||
colorMode: 'value',
|
colorMode: 'value',
|
||||||
thresholds: [1, 2],
|
thresholds: [1, 2],
|
||||||
colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'],
|
colors: ['#00ff00', 'semi-dark-orange', 'rgb(1,0,0)'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'RangeMappingColored',
|
pattern: 'RangeMappingColored',
|
||||||
@ -198,7 +197,7 @@ describe('when rendering table', () => {
|
|||||||
],
|
],
|
||||||
colorMode: 'value',
|
colorMode: 'value',
|
||||||
thresholds: [2, 5],
|
thresholds: [2, 5],
|
||||||
colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'],
|
colors: ['#00ff00', 'semi-dark-orange', 'rgb(1,0,0)'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'HiddenType',
|
pattern: 'HiddenType',
|
||||||
@ -212,7 +211,7 @@ describe('when rendering table', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const renderer = new TableRenderer(panel, table, utc, sanitize, templateSrv);
|
const renderer = new TableRenderer(panel, table, utc, sanitize, templateSrv, config.theme);
|
||||||
|
|
||||||
it('time column should be formatted', () => {
|
it('time column should be formatted', () => {
|
||||||
const html = renderer.renderCell(0, 0, 1388556366666);
|
const html = renderer.renderCell(0, 0, 1388556366666);
|
||||||
@ -271,7 +270,7 @@ describe('when rendering table', () => {
|
|||||||
|
|
||||||
it('colored cell should have style (handles named color values', () => {
|
it('colored cell should have style (handles named color values', () => {
|
||||||
const html = renderer.renderCell(2, 0, 55);
|
const html = renderer.renderCell(2, 0, 55);
|
||||||
expect(html).toBe(`<td style="color:${SemiDarkOrange.variants.dark}">55.0</td>`);
|
expect(html).toBe(`<td style="color:${'#FF780A'}">55.0</td>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('colored cell should have style handles(rgb color values)', () => {
|
it('colored cell should have style handles(rgb color values)', () => {
|
||||||
@ -368,12 +367,12 @@ describe('when rendering table', () => {
|
|||||||
|
|
||||||
it('value should be mapped to text and colored cell should have style', () => {
|
it('value should be mapped to text and colored cell should have style', () => {
|
||||||
const html = renderer.renderCell(11, 0, 1);
|
const html = renderer.renderCell(11, 0, 1);
|
||||||
expect(html).toBe(`<td style="color:${SemiDarkOrange.variants.dark}">on</td>`);
|
expect(html).toBe(`<td style="color:${'#FF780A'}">on</td>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('value should be mapped to text and colored cell should have style', () => {
|
it('value should be mapped to text and colored cell should have style', () => {
|
||||||
const html = renderer.renderCell(11, 0, '1');
|
const html = renderer.renderCell(11, 0, '1');
|
||||||
expect(html).toBe(`<td style="color:${SemiDarkOrange.variants.dark}">on</td>`);
|
expect(html).toBe(`<td style="color:${'#FF780A'}">on</td>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('value should be mapped to text and colored cell should have style', () => {
|
it('value should be mapped to text and colored cell should have style', () => {
|
||||||
@ -403,7 +402,7 @@ describe('when rendering table', () => {
|
|||||||
|
|
||||||
it('value should be mapped to text (range) and colored cell should have style', () => {
|
it('value should be mapped to text (range) and colored cell should have style', () => {
|
||||||
const html = renderer.renderCell(12, 0, 4);
|
const html = renderer.renderCell(12, 0, 4);
|
||||||
expect(html).toBe(`<td style="color:${SemiDarkOrange.variants.dark}">off</td>`);
|
expect(html).toBe(`<td style="color:${'#FF780A'}">off</td>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('value should be mapped to text (range) and colored cell should have style', () => {
|
it('value should be mapped to text (range) and colored cell should have style', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user