XY Panel: Add and use schema for XY Panel configuration (#62148)

* Add schema for XYChart

* Minor cleanup

* remove unessecary fields from ScatterFieldConfigVeneer, and cleaning up more

* Fix counts

Co-authored-by: sam boyer <sdboyer@grafana.com>
This commit is contained in:
Oscar Kilhed
2023-01-25 22:29:07 +00:00
committed by GitHub
co-authored by sam boyer
parent eb1293ebb1
commit f3aa058886
14 changed files with 395 additions and 27 deletions
@@ -7,13 +7,13 @@ import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldName
import { LayerName } from 'app/core/components/Layers/LayerName';
import { ColorDimensionEditor, ScaleDimensionEditor } from 'app/features/dimensions/editors';
import { XYChartOptions, ScatterSeriesConfig, defaultScatterConfig } from './models.gen';
import { PanelOptions, ScatterSeriesConfig, defaultScatterFieldConfig } from './types';
export const ManualEditor = ({
value,
onChange,
context,
}: StandardEditorProps<ScatterSeriesConfig[], any, XYChartOptions>) => {
}: StandardEditorProps<ScatterSeriesConfig[], any, PanelOptions>) => {
const [selected, setSelected] = useState(0);
const style = useStyles2(getStyles);
@@ -33,7 +33,7 @@ export const ManualEditor = ({
...value,
{
pointColor: {} as any,
pointSize: defaultScatterConfig.pointSize,
pointSize: defaultScatterFieldConfig.pointSize,
},
]);
setSelected(value.length);
@@ -26,11 +26,11 @@ import { FacetedData } from '@grafana/ui/src/components/uPlot/types';
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
import { TooltipView } from './TooltipView';
import { SeriesMapping, XYChartOptions } from './models.gen';
import { SeriesMapping } from './models.gen';
import { prepData, prepScatter, ScatterPanelInfo } from './scatter';
import { ScatterHoverEvent, ScatterSeries } from './types';
import { PanelOptions, ScatterHoverEvent, ScatterSeries } from './types';
type Props = PanelProps<XYChartOptions>;
type Props = PanelProps<PanelOptions>;
const TOOLTIP_OFFSET = 10;
export const XYChartPanel2: React.FC<Props> = (props: Props) => {
+1 -1
View File
@@ -10,7 +10,7 @@ import { commonOptionsBuilder } from '@grafana/ui';
import { LineStyleEditor } from '../timeseries/LineStyleEditor';
import { ScatterFieldConfig, ScatterShow } from './models.gen';
import { ScatterFieldConfig, ScatterShow } from './types';
export function getScatterFieldConfig(cfg: ScatterFieldConfig): SetFieldConfigOptionsArgs<ScatterFieldConfig> {
return {
+1 -1
View File
@@ -1,7 +1,7 @@
import { DataFrame, Field, FieldMatcher, FieldType, getFieldDisplayName } from '@grafana/data';
import { XYFieldMatchers } from '@grafana/ui/src/components/GraphNG/types';
import { XYDimensionConfig } from './models.gen';
import { XYDimensionConfig } from './types';
// TODO: fix import
+3 -3
View File
@@ -5,10 +5,10 @@ import { AutoEditor } from './AutoEditor';
import { ManualEditor } from './ManualEditor';
import { XYChartPanel2 } from './XYChartPanel2';
import { getScatterFieldConfig } from './config';
import { defaultScatterConfig, XYChartOptions, ScatterFieldConfig } from './models.gen';
import { defaultScatterFieldConfig, PanelOptions, ScatterFieldConfig } from './types';
export const plugin = new PanelPlugin<XYChartOptions, ScatterFieldConfig>(XYChartPanel2)
.useFieldConfig(getScatterFieldConfig(defaultScatterConfig))
export const plugin = new PanelPlugin<PanelOptions, ScatterFieldConfig>(XYChartPanel2)
.useFieldConfig(getScatterFieldConfig(defaultScatterFieldConfig))
.setPanelOptions((builder) => {
builder
.addRadio({
@@ -0,0 +1,79 @@
// Copyright 2023 Grafana Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package grafanaplugin
import (
"github.com/grafana/grafana/packages/grafana-schema/src/common"
"github.com/grafana/grafana/pkg/plugins/pfs"
)
// This file (with its sibling .cue files) implements pfs.GrafanaPlugin
pfs.GrafanaPlugin
composableKinds: PanelCfg: {
maturity: "experimental"
lineage: {
seqs: [
{
schemas: [
{
SeriesMapping: "auto" | "manual" @cuetsy(kind="enum")
ScatterShow: "points" | "lines" | "points+lines" @cuetsy(kind="enum", memberNames="Points|Lines|PointsAndLines")
XYDimensionConfig: {
frame: int32 & >=0
x?: string
exclude?: [...string]
} @cuetsy(kind="interface")
ScatterFieldConfig: {
common.HideableFieldConfig
common.AxisConfig
show?: ScatterShow | *"points"
pointSize?: common.ScaleDimensionConfig
lineColor?: common.ColorDimensionConfig
pointColor?: common.ColorDimensionConfig
labelValue?: common.TextDimensionConfig
lineWidth?: int32 & >=0
lineStyle?: common.LineStyle
label?: common.VisibilityMode | *"auto"
} @cuetsy(kind="interface",TSVeneer="type")
ScatterSeriesConfig: {
ScatterFieldConfig
x?: string
y?: string
name?: string
} @cuetsy(kind="interface")
PanelOptions: {
common.OptionsWithLegend
common.OptionsWithTooltip
seriesMapping?: SeriesMapping
dims: XYDimensionConfig
series: [...ScatterSeriesConfig]
} @cuetsy(kind="interface")
},
]
},
]
}
}
@@ -0,0 +1,66 @@
// 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 PanelCfgModelVersion = Object.freeze([0, 0]);
export enum SeriesMapping {
Auto = 'auto',
Manual = 'manual',
}
export enum ScatterShow {
Lines = 'lines',
Points = 'points',
PointsAndLines = 'points+lines',
}
export interface XYDimensionConfig {
exclude?: Array<string>;
frame: number;
x?: string;
}
export const defaultXYDimensionConfig: Partial<XYDimensionConfig> = {
exclude: [],
};
export interface ScatterFieldConfig extends common.HideableFieldConfig, common.AxisConfig {
label?: common.VisibilityMode;
labelValue?: common.TextDimensionConfig;
lineColor?: common.ColorDimensionConfig;
lineStyle?: common.LineStyle;
lineWidth?: number;
pointColor?: common.ColorDimensionConfig;
pointSize?: common.ScaleDimensionConfig;
show?: ScatterShow;
}
export const defaultScatterFieldConfig: Partial<ScatterFieldConfig> = {
label: common.VisibilityMode.Auto,
show: ScatterShow.Points,
};
export interface ScatterSeriesConfig extends ScatterFieldConfig {
name?: string;
x?: string;
y?: string;
}
export interface PanelOptions extends common.OptionsWithLegend, common.OptionsWithTooltip {
dims: XYDimensionConfig;
series: Array<ScatterSeriesConfig>;
seriesMapping?: SeriesMapping;
}
export const defaultPanelOptions: Partial<PanelOptions> = {
series: [],
};
+12 -5
View File
@@ -26,8 +26,15 @@ import {
import { pointWithin, Quadtree, Rect } from '../barchart/quadtree';
import { isGraphable } from './dims';
import { defaultScatterConfig, ScatterFieldConfig, ScatterShow, XYChartOptions } from './models.gen';
import { DimensionValues, ScatterHoverCallback, ScatterSeries } from './types';
import {
DimensionValues,
ScatterFieldConfig,
defaultScatterFieldConfig,
ScatterHoverCallback,
ScatterSeries,
PanelOptions,
ScatterShow,
} from './types';
export interface ScatterPanelInfo {
error?: string;
@@ -39,7 +46,7 @@ export interface ScatterPanelInfo {
* This is called when options or structure rev changes
*/
export function prepScatter(
options: XYChartOptions,
options: PanelOptions,
getData: () => DataFrame[],
theme: GrafanaTheme2,
ttip: ScatterHoverCallback,
@@ -100,7 +107,7 @@ function getScatterSeries(
? config.theme2.visualization.getColorByName(dims.pointColorFixed)
: getFieldSeriesColor(y, config.theme2).color;
let pointColor: DimensionValues<string> = () => seriesColor;
const fieldConfig: ScatterFieldConfig = { ...defaultScatterConfig, ...y.config.custom };
const fieldConfig: ScatterFieldConfig = { ...defaultScatterFieldConfig, ...y.config.custom };
let pointColorMode = fieldColorModeRegistry.get(FieldColorModeId.PaletteClassic);
if (dims.pointColorIndex) {
const f = frames[frameIndex].fields[dims.pointColorIndex];
@@ -195,7 +202,7 @@ function getScatterSeries(
};
}
function prepSeries(options: XYChartOptions, frames: DataFrame[]): ScatterSeries[] {
function prepSeries(options: PanelOptions, frames: DataFrame[]): ScatterSeries[] {
let seriesIndex = 0;
if (!frames.length) {
throw 'Missing data';
+25 -2
View File
@@ -1,7 +1,14 @@
import { DataFrame, Field, FieldColorMode } from '@grafana/data';
import { LineStyle, VisibilityMode } from '@grafana/schema';
import { LineStyle, ScaleDimensionConfig, VisibilityMode } from '@grafana/schema';
import { VizLegendItem } from '@grafana/ui';
import { ScaleDimensionConfig } from 'app/features/dimensions';
import { DimensionSupplier } from 'app/features/dimensions';
import {
ScatterFieldConfig as GeneratedScatterFieldConfig,
ScatterSeriesConfig as GeneratedScatterSeriesConfig,
defaultScatterFieldConfig as generatedDefaultScatterFieldConfig,
PanelOptions as GeneratedPanelOptions,
} from './panelcfg.gen';
/**
* @internal
@@ -24,6 +31,20 @@ export interface LegendInfo {
openEditor?: (evt: any) => void;
}
export interface ScatterFieldConfig extends GeneratedScatterFieldConfig {
pointSymbol?: DimensionSupplier<string>;
}
export const defaultScatterFieldConfig: Partial<ScatterFieldConfig> = {
...generatedDefaultScatterFieldConfig,
};
export interface ScatterSeriesConfig extends ScatterFieldConfig, GeneratedScatterSeriesConfig {}
export interface PanelOptions extends Omit<GeneratedPanelOptions, 'series'> {
series: ScatterSeriesConfig[];
}
// Using field where we will need formatting/scale/axis info
// Use raw or DimensionValues when the values can be used directly
export interface ScatterSeries {
@@ -58,3 +79,5 @@ export interface ScatterSeries {
};
};
}
export { ScatterShow, SeriesMapping, XYDimensionConfig } from './panelcfg.gen';