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 23:29:07 +01:00 committed by GitHub
parent eb1293ebb1
commit f3aa058886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 395 additions and 27 deletions

View File

@ -0,0 +1,132 @@
---
keywords:
- grafana
- schema
title: XYChartPanelCfg kind
---
> Both documentation generation and kinds schemas are in active development and subject to change without prior notice.
# XYChartPanelCfg kind
## Maturity: experimental
## Version: 0.0
## Properties
| Property | Type | Required | Description |
|-----------------------|--------------------------------|----------|---------------------------------------------------------|
| `PanelOptions` | [object](#paneloptions) | **Yes** | |
| `ScatterFieldConfig` | [object](#scatterfieldconfig) | **Yes** | |
| `ScatterSeriesConfig` | [object](#scatterseriesconfig) | **Yes** | |
| `ScatterShow` | string | **Yes** | Possible values are: `points`, `lines`, `points+lines`. |
| `SeriesMapping` | string | **Yes** | Possible values are: `auto`, `manual`. |
| `XYDimensionConfig` | [object](#xydimensionconfig) | **Yes** | |
## PanelOptions
### Properties
| Property | Type | Required | Description |
|-----------------|-----------------------------------------------|----------|----------------------------------------|
| `dims` | [XYDimensionConfig](#xydimensionconfig) | No | |
| `seriesMapping` | string | No | Possible values are: `auto`, `manual`. |
| `series` | [ScatterSeriesConfig](#scatterseriesconfig)[] | No | |
### ScatterSeriesConfig
#### Properties
| Property | Type | Required | Description |
|----------|--------|----------|-------------|
| `name` | string | No | |
| `x` | string | No | |
| `y` | string | No | |
### XYDimensionConfig
#### Properties
| Property | Type | Required | Description |
|-----------|----------|----------|-------------|
| `frame` | integer | **Yes** | |
| `exclude` | string[] | No | |
| `x` | string | No | |
## ScatterFieldConfig
### Properties
| Property | Type | Required | Description |
|--------------|-----------------------------------------------|----------|-------------------------------------------------------------|
| `labelValue` | [TextDimensionConfig](#textdimensionconfig) | No | |
| `label` | string | No | TODO docs Possible values are: `auto`, `never`, `always`. |
| `lineColor` | [ColorDimensionConfig](#colordimensionconfig) | No | This is actually an empty interface used mainly for naming? |
| `lineStyle` | [LineStyle](#linestyle) | No | TODO docs |
| `lineWidth` | integer | No | |
| `pointColor` | [ColorDimensionConfig](#colordimensionconfig) | No | This is actually an empty interface used mainly for naming? |
| `pointSize` | [ScaleDimensionConfig](#scaledimensionconfig) | No | |
| `show` | string | No | Possible values are: `points`, `lines`, `points+lines`. |
### ColorDimensionConfig
This is actually an empty interface used mainly for naming?
| Property | Type | Required | Description |
|----------|------|----------|-------------|
### ColorDimensionConfig
This is actually an empty interface used mainly for naming?
| Property | Type | Required | Description |
|----------|------|----------|-------------|
### LineStyle
TODO docs
#### Properties
| Property | Type | Required | Description |
|----------|----------|----------|--------------------------------------------------------|
| `dash` | number[] | No | |
| `fill` | string | No | Possible values are: `solid`, `dash`, `dot`, `square`. |
### ScaleDimensionConfig
#### Properties
| Property | Type | Required | Description |
|----------|---------|----------|-------------|
| `max` | integer | No | |
| `min` | integer | No | |
### TextDimensionConfig
#### Properties
| Property | Type | Required | Description |
|----------|--------|----------|----------------------------------------------------|
| `mode` | string | No | Possible values are: `fixed`, `field`, `template`. |
## ScatterSeriesConfig
### Properties
| Property | Type | Required | Description |
|----------|--------|----------|-------------|
| `name` | string | No | |
| `x` | string | No | |
| `y` | string | No | |
## XYDimensionConfig
### Properties
| Property | Type | Required | Description |
|-----------|----------|----------|-------------|
| `frame` | integer | **Yes** | |
| `exclude` | string[] | No | |
| `x` | string | No | |

View File

@ -51,6 +51,27 @@ export interface DataQuery {
refId: string;
}
export interface BaseDimensionConfig {
field?: string;
fixed: (string | number);
}
export interface ScaleDimensionConfig extends BaseDimensionConfig {
max: number;
min: number;
}
/**
* This is actually an empty interface used mainly for naming?
*/
export interface ColorDimensionConfig extends BaseDimensionConfig {}
export enum TextDimensionMode {
Field = 'field',
Fixed = 'fixed',
Template = 'template',
}
export interface MapLayerOptions {
/**
* Custom options depending on the type
@ -651,6 +672,10 @@ export interface DataSourceRef {
uid?: string;
}
export interface TextDimensionConfig extends BaseDimensionConfig {
mode: TextDimensionMode;
}
export interface FrameGeometrySource {
/**
* Path to Gazetteer

View File

@ -0,0 +1,25 @@
package common
BaseDimensionConfig: {
field?: string
fixed: string | number
}@cuetsy(kind="interface")
ScaleDimensionConfig: {
BaseDimensionConfig
min: int32
max: int32
}@cuetsy(kind="interface")
// This is actually an empty interface used mainly for naming?
ColorDimensionConfig: {
BaseDimensionConfig
_empty: _
}@cuetsy(kind="interface")
TextDimensionMode: "fixed" | "field" | "template" @cuetsy(kind="enum")
TextDimensionConfig: {
BaseDimensionConfig
mode: TextDimensionMode
}@cuetsy(kind="interface")

View File

@ -12,5 +12,14 @@ export interface DataQuery extends raw.DataQuery {
// TODO remove explicit nulls
datasource?: raw.DataSourceRef | null;
}
export interface BaseDimensionConfig<T = string | number> extends Omit<raw.BaseDimensionConfig, 'fixed'> {
fixed: T;
}
export interface ScaleDimensionConfig extends BaseDimensionConfig<number>, Omit<raw.ScaleDimensionConfig, 'fixed'> {}
export interface TextDimensionConfig extends BaseDimensionConfig<string>, Omit<raw.TextDimensionConfig, 'fixed'> {}
export interface ColorDimensionConfig extends BaseDimensionConfig<string>, Omit<raw.ColorDimensionConfig, 'fixed'> {}
export * from '../common/common.gen';

View File

@ -1621,7 +1621,9 @@
},
"xychartpanelcfg": {
"category": "composable",
"codeowners": [],
"codeowners": [
"grafana/grafana-bi-squad"
],
"currentVersion": [
0,
0
@ -1629,13 +1631,13 @@
"grafanaMaturityCount": 0,
"lineageIsGroup": true,
"links": {
"docs": "n/a",
"docs": "https://grafana.com/docs/grafana/next/developers/kinds/composable/xychartpanelcfg/schema-reference",
"go": "n/a",
"schema": "n/a",
"ts": "n/a"
"schema": "https://github.com/grafana/grafana/tree/main/public/app/plugins/panel/xychart/panelcfg.cue",
"ts": "https://github.com/grafana/grafana/tree/main/public/app/plugins/panel/xychart/panelcfg.gen.ts"
},
"machineName": "xychartpanelcfg",
"maturity": "planned",
"maturity": "experimental",
"name": "XYChartPanelCfg",
"pluralMachineName": "xychartpanelcfgs",
"pluralName": "XYChartPanelCfgs",
@ -1790,9 +1792,10 @@
"newspanelcfg",
"piechartpanelcfg",
"statpanelcfg",
"textpanelcfg"
"textpanelcfg",
"xychartpanelcfg"
],
"count": 11
"count": 12
},
"mature": {
"name": "mature",
@ -1869,11 +1872,10 @@
"tracespanelcfg",
"user",
"welcomepanelcfg",
"xychartpanelcfg",
"zipkindataquery",
"zipkindatasourcecfg"
],
"count": 59
"count": 58
},
"stable": {
"name": "stable",

View File

@ -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);

View File

@ -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) => {

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 {

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

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({

View File

@ -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")
},
]
},
]
}
}

View File

@ -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: [],
};

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';

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';