1
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

126 lines
3.5 KiB

import React, { PureComponent } from 'react';
import { PanelProps } from '@grafana/data';
import { XYChartOptions } from './models.gen';
import { ScatterHoverEvent, ScatterSeries } from './types';
import {
LegendDisplayMode,
Portal,
UPlotChart,
UPlotConfigBuilder,
VizLayout,
VizLegend,
VizLegendItem,
VizTooltipContainer,
} from '@grafana/ui';
import { FacetedData } from '@grafana/ui/src/components/uPlot/types';
import { prepData, prepScatter } from './scatter';
import { config } from '@grafana/runtime';
import { TooltipView } from './TooltipView';
type Props = PanelProps<XYChartOptions>;
type State = {
error?: string;
series: ScatterSeries[];
builder?: UPlotConfigBuilder;
facets?: FacetedData;
hover?: ScatterHoverEvent;
};
export class XYChartPanel2 extends PureComponent<Props, State> {
state: State = {
series: [],
};
componentDidMount() {
this.initSeries(); // also data
}
componentDidUpdate(oldProps: Props) {
const { options, data } = this.props;
const configsChanged = options !== oldProps.options || data.structureRev !== oldProps.data.structureRev;
if (configsChanged) {
this.initSeries();
} else if (data !== oldProps.data) {
this.initFacets();
}
}
scatterHoverCallback = (hover?: ScatterHoverEvent) => {
this.setState({ hover });
};
getData = () => {
return this.props.data.series;
};
initSeries = () => {
const { options, data } = this.props;
const info: State = prepScatter(options, this.getData, config.theme2, this.scatterHoverCallback);
if (info.series.length && data.series) {
info.facets = prepData(info, data.series);
info.error = undefined;
}
this.setState(info);
};
initFacets = () => {
this.setState({
facets: prepData(this.state, this.props.data.series),
});
};
renderLegend = () => {
const { data } = this.props;
const { series } = this.state;
const items: VizLegendItem[] = [];
for (const s of series) {
const frame = s.frame(data.series);
if (frame) {
for (const item of s.legend(frame)) {
items.push(item);
}
}
}
return (
<VizLayout.Legend placement="bottom">
<VizLegend placement="bottom" items={items} displayMode={LegendDisplayMode.List} />
</VizLayout.Legend>
);
};
render() {
const { width, height, timeRange, data } = this.props;
const { error, facets, builder, hover, series } = this.state;
if (error || !builder) {
return (
<div className="panel-empty">
<p>{error}</p>
</div>
);
}
return (
<>
<VizLayout width={width} height={height} legend={this.renderLegend()}>
{(vizWidth: number, vizHeight: number) => (
// <pre style={{ width: vizWidth, height: vizHeight, border: '1px solid green', margin: '0px' }}>
// {JSON.stringify(scatterData, null, 2)}
// </pre>
<UPlotChart config={builder} data={facets!} width={vizWidth} height={vizHeight} timeRange={timeRange}>
{/*children ? children(config, alignedFrame) : null*/}
</UPlotChart>
)}
</VizLayout>
<Portal>
{hover && (
<VizTooltipContainer position={{ x: hover.pageX, y: hover.pageY }} offset={{ x: 10, y: 10 }}>
<TooltipView series={series[hover.scatterIndex]} rowIndex={hover.xIndex} data={data.series} />
</VizTooltipContainer>
)}
</Portal>
</>
);
}
}