XYChart: Refactor to new model (behind feature toggle) (#82499)

Co-authored-by: drew08t <drew08@gmail.com>
Co-authored-by: Ihor Yeromin <yeryomin.igor@gmail.com>
This commit is contained in:
Leon Sorokin
2024-03-22 10:44:37 -05:00
committed by GitHub
co-authored by drew08t Ihor Yeromin
parent 7df8d6e8cb
commit d7fa99e2df
33 changed files with 2456 additions and 10 deletions
@@ -1,6 +1,5 @@
export * from './DataFrameView';
export * from './FieldCache';
export * from './CircularDataFrame';
export * from './MutableDataFrame';
export * from './processDataFrame';
export * from './dimensions';
+56 -1
View File
@@ -1,4 +1,12 @@
import { DataFrame, Field, TIME_SERIES_VALUE_FIELD_NAME, FieldType, TIME_SERIES_TIME_FIELD_NAME } from '../types';
import { getFieldMatcher } from '../transformations';
import {
DataFrame,
Field,
TIME_SERIES_VALUE_FIELD_NAME,
FieldType,
TIME_SERIES_TIME_FIELD_NAME,
FieldConfigSource,
} from '../types';
import { formatLabels } from '../utils/labels';
/**
@@ -51,6 +59,53 @@ export function cacheFieldDisplayNames(frames: DataFrame[]) {
});
}
/**
*
* moves each field's config.custom.hideFrom to field.state.hideFrom
* and mutates orgiginal field.config.custom.hideFrom to one with explicit overrides only, (without the ad-hoc stateful __system override from legend toggle)
*/
export function decoupleHideFromState(frames: DataFrame[], fieldConfig: FieldConfigSource<any>) {
frames.forEach((frame) => {
frame.fields.forEach((field) => {
const hideFrom = {
legend: false,
tooltip: false,
viz: false,
...fieldConfig.defaults.custom?.hideFrom,
};
// with ad hoc __system override applied
const hideFromState = field.config.custom?.hideFrom;
fieldConfig.overrides.forEach((o) => {
if ('__systemRef' in o) {
return;
}
const m = getFieldMatcher(o.matcher);
if (m(field, frame, frames)) {
for (const p of o.properties) {
if (p.id === 'custom.hideFrom') {
Object.assign(hideFrom, p.value);
}
}
}
});
field.state = {
...field.state,
hideFrom: {
...hideFromState,
},
};
// original with perm overrides
field.config.custom.hideFrom = hideFrom;
});
});
}
export function getFieldDisplayName(field: Field, frame?: DataFrame, allFrames?: DataFrame[]): string {
const existingTitle = field.state?.displayName;
const multipleFrames = Boolean(allFrames && allFrames.length > 1);
+1
View File
@@ -48,3 +48,4 @@ export { getLinksSupplier } from './field/fieldOverrides';
export { CircularVector } from './vector/CircularVector';
export { vectorator } from './vector/FunctionalVector';
export { ArrayVector } from './vector/ArrayVector';
export * from './dataframe/CircularDataFrame';
@@ -1,3 +1,5 @@
import { HideSeriesConfig } from '@grafana/schema';
import { ScopedVars } from './ScopedVars';
import { QueryResultBase, Labels, NullValueMode } from './data';
import { DataLink, LinkModel } from './dataLink';
@@ -231,6 +233,15 @@ export interface FieldState {
* It's up to each visualization to calculate and set this.
*/
alignmentFactors?: DisplayValueAlignmentFactors;
/**
* This is the current ad-hoc state of whether this series is hidden in viz, tooltip, and legend.
*
* Currently this will match field.config.custom.hideFrom because fieldOverrides applies the special __system
* override to the actual config during toggle via legend. This should go away once we have a unified system
* for layering ad hoc field overrides and options but still being able to get the stateless fieldConfig and panel options
*/
hideFrom?: HideSeriesConfig;
}
/** @public */
@@ -38,6 +38,7 @@ export interface FeatureToggles {
autoMigratePiechartPanel?: boolean;
autoMigrateWorldmapPanel?: boolean;
autoMigrateStatPanel?: boolean;
autoMigrateXYChartPanel?: boolean;
disableAngular?: boolean;
canvasPanelNesting?: boolean;
newVizTooltips?: boolean;
@@ -0,0 +1,95 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// public/app/plugins/gen.go
// Using jennies:
// TSTypesJenny
// PluginTsTypesJenny
//
// Run 'make gen-cue' from repository root to regenerate.
import * as common from '@grafana/schema';
export const pluginVersion = "11.0.0-pre";
/**
* Auto is "table" in the UI
*/
export enum SeriesMapping {
Auto = 'auto',
Manual = 'manual',
}
export enum XYShowMode {
Lines = 'lines',
Points = 'points',
PointsAndLines = 'points+lines',
}
/**
* NOTE: (copied from dashboard_kind.cue, since not exported)
* Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.
* It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.
*/
export interface MatcherConfig {
/**
* The matcher id. This is used to find the matcher implementation from registry.
*/
id: string;
/**
* The matcher options. This is specific to the matcher implementation.
*/
options?: unknown;
}
export const defaultMatcherConfig: Partial<MatcherConfig> = {
id: '',
};
export interface FieldConfig extends common.HideableFieldConfig, common.AxisConfig {
lineStyle?: common.LineStyle;
/**
* lineColor?: common.ColorDimensionConfig
*/
lineWidth?: number;
pointSize?: {
fixed?: number;
min?: number;
max?: number;
};
show?: XYShowMode;
}
export const defaultFieldConfig: Partial<FieldConfig> = {
show: XYShowMode.Points,
};
export interface XYSeriesConfig {
color?: {
matcher: MatcherConfig;
};
frame?: {
matcher: MatcherConfig;
};
name?: {
fixed?: string;
};
size?: {
matcher: MatcherConfig;
};
x?: {
matcher: MatcherConfig;
};
y?: {
matcher: MatcherConfig;
};
}
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip {
mapping: SeriesMapping;
series: Array<XYSeriesConfig>;
}
export const defaultOptions: Partial<Options> = {
series: [],
};
@@ -72,7 +72,7 @@ export function VizLegend<T>({
}
if (onToggleSeriesVisibility) {
onToggleSeriesVisibility(
item.label,
item.fieldName ?? item.label,
seriesVisibilityChangeBehavior === SeriesVisibilityChangeBehavior.Hide
? SeriesVisibilityChangeMode.AppendToSelection
: mapMouseEventToMode(event)
@@ -70,7 +70,12 @@ export const VizLegendListItem = <T = unknown,>({
className={cx(styles.itemWrapper, item.disabled && styles.itemDisabled, className)}
data-testid={selectors.components.VizLegend.seriesName(item.label)}
>
<VizLegendSeriesIcon seriesName={item.label} color={item.color} gradient={item.gradient} readonly={readonly} />
<VizLegendSeriesIcon
seriesName={item.fieldName ?? item.label}
color={item.color}
gradient={item.gradient}
readonly={readonly}
/>
<button
disabled={readonly}
type="button"
@@ -69,7 +69,7 @@ export const LegendTableItem = ({
<tr className={cx(styles.row, className)}>
<td>
<span className={styles.itemWrapper}>
<VizLegendSeriesIcon color={item.color} seriesName={item.label} readonly={readonly} />
<VizLegendSeriesIcon color={item.color} seriesName={item.fieldName ?? item.label} readonly={readonly} />
<button
disabled={readonly}
type="button"
@@ -47,5 +47,6 @@ export interface VizLegendItem<T = any> {
// displayValues?: DisplayValue[];
getDisplayValues?: () => DisplayValue[];
fieldIndex?: DataFrameFieldIndex;
fieldName?: string;
data?: T;
}