Histogram: move histogram from alpha to beta panel (#34246)

* add legend

* tooltip off-by-one

* units in x axis

* update function call

* remove tooltip
This commit is contained in:
Ryan McKinley 2021-05-19 17:13:17 -07:00 committed by GitHub
parent 348e76fc8e
commit 8147a65b5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 26 deletions

View File

@ -203,16 +203,17 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
}
const bucketMin = {
...counts[0],
name: histogramFrameBucketMinFieldName,
values: new ArrayVector(joinedHists[0]),
type: FieldType.number,
config: {},
state: undefined,
};
const bucketMax = {
...bucketMin,
name: histogramFrameBucketMaxFieldName,
values: new ArrayVector(joinedHists[0].map((v) => v + bucketSize!)),
type: FieldType.number,
config: {},
state: undefined,
};
if (options?.combine) {
@ -227,6 +228,8 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
...counts[0],
name: 'Count',
values: new ArrayVector(vals),
type: FieldType.number,
state: undefined,
},
];
} else {

View File

@ -93,7 +93,7 @@ export class UPlotAxisBuilder extends PlotConfigBuilder<AxisProps, Axis> {
} else if (isTime) {
config.values = formatTime;
} else if (formatValue) {
config.values = (u: uPlot, vals: any[]) => vals.map((v) => formatValue!(v));
config.values = (u: uPlot, vals: any[]) => vals.map(formatValue!);
}
// store timezone

View File

@ -2,6 +2,7 @@ import React from 'react';
import uPlot, { AlignedData } from 'uplot';
import {
DataFrame,
formattedValueToString,
getFieldColorModeForField,
getFieldDisplayName,
getFieldSeriesColor,
@ -16,6 +17,8 @@ import {
AxisPlacement,
ScaleDirection,
ScaleOrientation,
LegendDisplayMode,
PlotLegend,
} from '@grafana/ui';
import {
@ -32,12 +35,7 @@ export interface HistogramProps extends Themeable2 {
height: number;
structureRev?: number; // a number that will change when the frames[] structure changes
legend: VizLegendOptions;
//onLegendClick?: (event: GraphNGLegendEvent) => void;
children?: (builder: UPlotConfigBuilder, frame: DataFrame) => React.ReactNode;
//prepConfig: (frame: DataFrame) => UPlotConfigBuilder;
//propsToDiff?: string[];
//renderLegend: (config: UPlotConfigBuilder) => React.ReactElement;
}
const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
@ -84,12 +82,18 @@ const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
direction: ScaleDirection.Up,
});
const fmt = frame.fields[0].display!;
const xAxisFormatter = (v: number) => {
return formattedValueToString(fmt(v));
};
builder.addAxis({
scaleKey: 'x',
isTime: false,
placement: AxisPlacement.Bottom,
incrs: histogramBucketSizes,
splits: xSplits,
values: (u: uPlot, vals: any[]) => vals.map(xAxisFormatter),
//incrs: () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((mult) => mult * bucketSize),
//splits: config.xSplits,
//values: config.xValues,
@ -138,15 +142,15 @@ const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
colorMode,
pathBuilder,
//pointsBuilder: config.drawPoints,
show: !customConfig.hideFrom?.graph,
show: !customConfig.hideFrom?.vis,
gradientMode: customConfig.gradientMode,
thresholds: field.config.thresholds,
// The following properties are not used in the uPlot config, but are utilized as transport for legend config
// dataFrameFieldIndex: {
// fieldIndex: i,
// frameIndex: 0,
// },
dataFrameFieldIndex: {
fieldIndex: i,
frameIndex: 0,
},
fieldName: getFieldDisplayName(field, frame),
hideInLegend: customConfig.hideFrom?.legend,
});
@ -178,10 +182,6 @@ const preparePlotData = (frame: DataFrame) => {
return data;
};
const renderLegend = (config: UPlotConfigBuilder) => {
return null;
};
interface State {
alignedData: AlignedData;
config?: UPlotConfigBuilder;
@ -210,6 +210,15 @@ export class Histogram extends React.Component<HistogramProps, State> {
return state;
}
renderLegend(config: UPlotConfigBuilder) {
const { legend } = this.props;
if (!config || legend.displayMode === LegendDisplayMode.Hidden) {
return null;
}
return <PlotLegend data={[this.props.alignedFrame]} config={config} maxHeight="35%" maxWidth="60%" {...legend} />;
}
componentDidUpdate(prevProps: HistogramProps) {
const { structureRev, alignedFrame } = this.props;
@ -241,7 +250,7 @@ export class Histogram extends React.Component<HistogramProps, State> {
}
return (
<VizLayout width={width} height={height} legend={renderLegend(config) as any}>
<VizLayout width={width} height={height} legend={this.renderLegend(config)}>
{(vizWidth: number, vizHeight: number) => (
<UPlotChart
config={this.state.config!}

View File

@ -26,6 +26,7 @@ export const HistogramPanel: React.FC<Props> = ({ data, options, width, height }
if (!hist) {
return undefined;
}
return histogramFieldsToFrame(hist);
}, [data.series, options]);
@ -41,11 +42,15 @@ export const HistogramPanel: React.FC<Props> = ({ data, options, width, height }
<Histogram
options={options}
theme={theme}
legend={null as any} // TODO!
legend={options.legend}
structureRev={data.structureRev}
width={width}
height={height}
alignedFrame={histogram}
/>
>
{(config, alignedFrame) => {
return null; // <TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />;
}}
</Histogram>
);
};

View File

@ -3,11 +3,18 @@
// It is currenty hand written but will serve as the target for cuetsy
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import { GraphGradientMode } from '@grafana/ui';
import {
GraphGradientMode,
HideableFieldConfig,
LegendDisplayMode,
OptionsWithLegend,
OptionsWithTooltip,
TooltipDisplayMode,
} from '@grafana/ui';
export const modelVersion = Object.freeze([1, 0]);
export interface PanelOptions {
export interface PanelOptions extends OptionsWithLegend, OptionsWithTooltip {
bucketSize?: number;
bucketOffset?: number;
combine?: boolean;
@ -15,12 +22,20 @@ export interface PanelOptions {
export const defaultPanelOptions: PanelOptions = {
bucketOffset: 0,
legend: {
displayMode: LegendDisplayMode.List,
placement: 'bottom',
calcs: [],
},
tooltip: {
mode: TooltipDisplayMode.Multi,
},
};
/**
* @alpha
*/
export interface PanelFieldConfig {
export interface PanelFieldConfig extends HideableFieldConfig {
lineWidth?: number; // 0
fillOpacity?: number; // 100
gradientMode?: GraphGradientMode;

View File

@ -1,6 +1,6 @@
import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data';
import { HistogramPanel } from './HistogramPanel';
import { graphFieldOptions } from '@grafana/ui';
import { commonOptionsBuilder, graphFieldOptions } from '@grafana/ui';
import { PanelFieldConfig, PanelOptions, defaultPanelFieldConfig, defaultPanelOptions } from './models.gen';
import { originalDataHasHistogram } from './utils';
@ -44,6 +44,9 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(HistogramP
defaultValue: defaultPanelOptions.combine,
showIf: (opts, data) => !originalDataHasHistogram(data),
});
// commonOptionsBuilder.addTooltipOptions(builder);
commonOptionsBuilder.addLegendOptions(builder);
})
.useFieldConfig({
standardOptions: {
@ -88,5 +91,7 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(HistogramP
options: graphFieldOptions.fillGradient,
},
});
commonOptionsBuilder.addHideFrom(builder);
},
});

View File

@ -3,7 +3,7 @@
"name": "Histogram",
"id": "histogram",
"state": "alpha",
"state": "beta",
"info": {
"author": {