mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
import React from 'react';
|
|
|
|
import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data';
|
|
import { LegendDisplayMode, VisibilityMode } from '@grafana/schema';
|
|
import {
|
|
PanelContext,
|
|
PanelContextRoot,
|
|
GraphNG,
|
|
GraphNGProps,
|
|
UPlotConfigBuilder,
|
|
VizLayout,
|
|
VizLegend,
|
|
VizLegendItem,
|
|
} from '@grafana/ui';
|
|
|
|
import { TimelineMode, TimelineOptions, TimelineValueAlignment } from './types';
|
|
import { preparePlotConfigBuilder } from './utils';
|
|
|
|
/**
|
|
* @alpha
|
|
*/
|
|
export interface TimelineProps
|
|
extends TimelineOptions,
|
|
Omit<GraphNGProps, 'prepConfig' | 'propsToDiff' | 'renderLegend'> {
|
|
mode: TimelineMode;
|
|
rowHeight: number;
|
|
showValue: VisibilityMode;
|
|
alignValue?: TimelineValueAlignment;
|
|
colWidth?: number;
|
|
legendItems?: VizLegendItem[];
|
|
}
|
|
|
|
const propsToDiff = ['rowHeight', 'colWidth', 'showValue', 'mergeValues', 'alignValue'];
|
|
|
|
export class TimelineChart extends React.Component<TimelineProps> {
|
|
static contextType = PanelContextRoot;
|
|
panelContext: PanelContext = {} as PanelContext;
|
|
|
|
getValueColor = (frameIdx: number, fieldIdx: number, value: any) => {
|
|
const field = this.props.frames[frameIdx].fields[fieldIdx];
|
|
|
|
if (field.display) {
|
|
const disp = field.display(value); // will apply color modes
|
|
if (disp.color) {
|
|
return disp.color;
|
|
}
|
|
}
|
|
|
|
return FALLBACK_COLOR;
|
|
};
|
|
|
|
prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => {
|
|
this.panelContext = this.context as PanelContext;
|
|
const { eventBus, sync } = this.panelContext;
|
|
|
|
return preparePlotConfigBuilder({
|
|
frame: alignedFrame,
|
|
getTimeRange,
|
|
eventBus,
|
|
sync,
|
|
allFrames: this.props.frames,
|
|
...this.props,
|
|
|
|
// When there is only one row, use the full space
|
|
rowHeight: alignedFrame.fields.length > 2 ? this.props.rowHeight : 1,
|
|
getValueColor: this.getValueColor,
|
|
});
|
|
};
|
|
|
|
renderLegend = (config: UPlotConfigBuilder) => {
|
|
const { legend, legendItems } = this.props;
|
|
|
|
if (!config || !legendItems || !legend || legend.displayMode === LegendDisplayMode.Hidden) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<VizLayout.Legend placement={legend.placement}>
|
|
<VizLegend placement={legend.placement} items={legendItems} displayMode={legend.displayMode} readonly />
|
|
</VizLayout.Legend>
|
|
);
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<GraphNG
|
|
{...this.props}
|
|
fields={{
|
|
x: (f) => f.type === FieldType.time,
|
|
y: (f) => f.type === FieldType.number || f.type === FieldType.boolean || f.type === FieldType.string,
|
|
}}
|
|
prepConfig={this.prepConfig}
|
|
propsToDiff={propsToDiff}
|
|
renderLegend={this.renderLegend}
|
|
/>
|
|
);
|
|
}
|
|
}
|