FieldColor: Group new accessible options within the select menu (#114690)

* group new accessible options within the select menu

* move comment
This commit is contained in:
Ashley Harrison
2025-12-08 15:10:16 +00:00
committed by GitHub
parent ccdb6ff261
commit b50cf6e067
3 changed files with 62 additions and 15 deletions
@@ -9,6 +9,8 @@ import {
import stringHash from 'string-hash';
import tinycolor from 'tinycolor2';
import { t } from '@grafana/i18n';
import { getContrastRatio } from '../themes/colorManipulator';
import { GrafanaTheme2 } from '../themes/types';
import { reduceField } from '../transformations/fieldReducer';
@@ -30,10 +32,14 @@ export interface FieldColorMode extends RegistryItem {
isContinuous?: boolean;
isByValue?: boolean;
useSeriesName?: boolean;
group?: string;
}
/** @internal */
export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
const accessibleGroup = t('grafana-data.field.fieldColor.accessibleGroup', 'Accessible');
const otherGroup = t('grafana-data.field.fieldColor.otherGroup', 'Others');
return [
{
id: FieldColorModeId.Fixed,
@@ -88,6 +94,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
interpolator: interpolateViridis,
group: accessibleGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousMagma,
@@ -95,6 +102,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
interpolator: interpolateMagma,
group: accessibleGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousPlasma,
@@ -102,6 +110,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
interpolator: interpolatePlasma,
group: accessibleGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousInferno,
@@ -109,6 +118,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
interpolator: interpolateInferno,
group: accessibleGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousCividis,
@@ -116,6 +126,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
interpolator: interpolateCividis,
group: accessibleGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousGrYlRd,
@@ -123,6 +134,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['green', 'yellow', 'red'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousRdYlGr,
@@ -130,6 +142,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['red', 'yellow', 'green'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousBlYlRd,
@@ -137,6 +150,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['dark-blue', 'super-light-yellow', 'dark-red'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousYlRd,
@@ -144,6 +158,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['super-light-yellow', 'dark-red'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousBlPu,
@@ -151,6 +166,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['blue', 'purple'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousYlBl,
@@ -158,6 +174,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['super-light-yellow', 'dark-blue'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousBlues,
@@ -165,6 +182,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-blue'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousReds,
@@ -172,6 +190,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-red'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousGreens,
@@ -179,6 +198,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-green'],
group: otherGroup,
}),
new FieldColorSchemeMode({
id: FieldColorModeId.ContinuousPurples,
@@ -186,6 +206,7 @@ export const fieldColorModeRegistry = new Registry<FieldColorMode>(() => {
isContinuous: true,
isByValue: true,
getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-purple'],
group: otherGroup,
}),
];
});
@@ -197,6 +218,7 @@ interface BaseFieldColorSchemeModeOptions {
isContinuous: boolean;
isByValue: boolean;
useSeriesName?: boolean;
group?: string;
}
interface FieldColorSchemeModeInterpolator extends BaseFieldColorSchemeModeOptions {
@@ -222,6 +244,7 @@ export class FieldColorSchemeMode implements FieldColorMode {
colorCacheTheme?: GrafanaTheme2;
interpolator?: (value: number) => string;
getNamedColors?: (theme: GrafanaTheme2) => string[];
group?: string;
constructor(options: FieldColorSchemeModeOptions) {
this.id = options.id;
@@ -232,6 +255,7 @@ export class FieldColorSchemeMode implements FieldColorMode {
this.isByValue = options.isByValue;
this.useSeriesName = options.useSeriesName;
this.interpolator = options.interpolator;
this.group = options.group;
}
getColors(theme: GrafanaTheme2): string[] {
@@ -29,22 +29,39 @@ export const FieldColorEditor = ({ value, onChange, item, id }: Props) => {
? fieldColorModeRegistry.list()
: fieldColorModeRegistry.list().filter((m) => !m.isByValue);
const options = availableOptions
.filter((mode) => !mode.excludeFromPicker)
.map((mode) => {
let suffix = mode.isByValue ? ' (by value)' : '';
const filteredOptions = availableOptions.filter((option) => !option.excludeFromPicker);
return {
value: mode.id,
label: `${mode.name}${suffix}`,
description: mode.description,
isContinuous: mode.isContinuous,
isByValue: mode.isByValue,
component() {
return <FieldColorModeViz mode={mode} theme={theme} />;
},
};
});
const options: Array<SelectableValue<string>> = [];
// collect any grouped options in this map
// this allows us to easily push to the child array without having to rescan the options array
// it also allows us to maintain group position in the order they're first encountered
const groupMap = new Map<string, Array<SelectableValue<string>>>();
for (const option of filteredOptions) {
const suffix = option.isByValue ? ' (by value)' : '';
const groupName = option.group;
const selectOption = {
value: option.id,
label: `${option.name}${suffix}`,
description: option.description,
component() {
return <FieldColorModeViz mode={option} theme={theme} />;
},
};
if (groupName) {
let group = groupMap.get(groupName);
if (!group) {
group = [];
groupMap.set(groupName, group);
options.push({ label: groupName, options: group });
}
group.push(selectOption);
} else {
options.push(selectOption);
}
}
const onModeChange = (newMode: SelectableValue<string>) => {
onChange({
+6
View File
@@ -8251,6 +8251,12 @@
"nextNYears_other": "Next {{count}} years"
}
},
"field": {
"fieldColor": {
"accessibleGroup": "Accessible",
"otherGroup": "Others"
}
},
"valueFormats": {
"categories": {
"acceleration": {