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 { 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 { 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 ( ); }; render() { return ( 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} /> ); } }