mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
working on react data / query exectution
This commit is contained in:
parent
2e1d45a875
commit
cd4619dad1
@ -8,7 +8,8 @@ import appEvents from 'app/core/app_events';
|
||||
import Drop from 'tether-drop';
|
||||
import colors from 'app/core/utils/colors';
|
||||
import { BackendSrv, setBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { TimeSrv, setTimeSrv } from 'app/features/dashboard/time_srv';
|
||||
import { DatasourceSrv, setDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
import { AngularLoader, setAngularLoader } from 'app/core/services/AngularLoader';
|
||||
import { configureStore } from 'app/store/configureStore';
|
||||
|
||||
@ -23,12 +24,15 @@ export class GrafanaCtrl {
|
||||
contextSrv,
|
||||
bridgeSrv,
|
||||
backendSrv: BackendSrv,
|
||||
timeSrv: TimeSrv,
|
||||
datasourceSrv: DatasourceSrv,
|
||||
angularLoader: AngularLoader
|
||||
) {
|
||||
// make angular loader service available to react components
|
||||
setAngularLoader(angularLoader);
|
||||
setBackendSrv(backendSrv);
|
||||
setDatasourceSrv(datasourceSrv);
|
||||
setTimeSrv(timeSrv);
|
||||
configureStore();
|
||||
|
||||
$scope.init = () => {
|
||||
|
@ -1,5 +1,11 @@
|
||||
// Library
|
||||
import React, { Component } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
// Services
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
|
||||
// Types
|
||||
import { TimeRange, LoadingState } from 'app/types';
|
||||
|
||||
interface RenderProps {
|
||||
loading: LoadingState;
|
||||
@ -9,6 +15,11 @@ interface RenderProps {
|
||||
export interface Props {
|
||||
datasource: string | null;
|
||||
queries: any[];
|
||||
panelId?: number;
|
||||
dashboardId?: number;
|
||||
isVisible?: boolean;
|
||||
timeRange?: TimeRange;
|
||||
refreshCounter: number;
|
||||
children: (r: RenderProps) => JSX.Element;
|
||||
}
|
||||
|
||||
@ -18,16 +29,13 @@ export interface State {
|
||||
data: any;
|
||||
}
|
||||
|
||||
export enum LoadingState {
|
||||
NotStarted = 'NotStarted',
|
||||
Loading = 'Loading',
|
||||
Done = 'Done',
|
||||
Error = 'Error',
|
||||
}
|
||||
export class DataPanel extends PureComponent<Props, State> {
|
||||
static defaultProps = {
|
||||
isVisible: true,
|
||||
panelId: 1,
|
||||
dashboardId: 1,
|
||||
};
|
||||
|
||||
export interface PanelProps extends RenderProps {}
|
||||
|
||||
export class DataPanel extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
@ -44,20 +52,50 @@ export class DataPanel extends Component<Props, State> {
|
||||
}
|
||||
|
||||
issueQueries = async () => {
|
||||
const { isVisible, queries, datasource, panelId, dashboardId, timeRange } = this.props;
|
||||
|
||||
if (!isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!queries.length) {
|
||||
this.setState({ data: [], loading: LoadingState.Done });
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ loading: LoadingState.Loading });
|
||||
|
||||
await new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
this.setState({ loading: LoadingState.Done, data: [{ value: 10 }], isFirstLoad: false });
|
||||
}, 500);
|
||||
});
|
||||
try {
|
||||
const dataSourceSrv = getDatasourceSrv();
|
||||
const ds = await dataSourceSrv.get(datasource);
|
||||
|
||||
const queryOptions = {
|
||||
timezone: 'browser',
|
||||
panelId: panelId,
|
||||
dashboardId: dashboardId,
|
||||
range: timeRange,
|
||||
rangeRaw: timeRange.raw,
|
||||
interval: '1s',
|
||||
intervalMs: 1000,
|
||||
targets: queries,
|
||||
maxDataPoints: 500,
|
||||
scopedVars: {},
|
||||
cacheTimeout: null,
|
||||
};
|
||||
|
||||
const resp = await ds.query(queryOptions);
|
||||
console.log(resp);
|
||||
} catch (err) {
|
||||
console.log('Loading error', err);
|
||||
this.setState({ loading: LoadingState.Error });
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, loading, isFirstLoad } = this.state;
|
||||
console.log('data panel render');
|
||||
|
||||
if (isFirstLoad && loading === LoadingState.Loading) {
|
||||
if (isFirstLoad && (loading === LoadingState.Loading || loading === LoadingState.NotStarted)) {
|
||||
return (
|
||||
<div className="loading">
|
||||
<p>Loading</p>
|
||||
|
@ -1,8 +1,17 @@
|
||||
import React, { ComponentClass } from 'react';
|
||||
// Libraries
|
||||
import React, { ComponentClass, PureComponent } from 'react';
|
||||
|
||||
// Services
|
||||
import { getTimeSrv } from '../time_srv';
|
||||
|
||||
// Components
|
||||
import { PanelHeader } from './PanelHeader';
|
||||
import { DataPanel } from './DataPanel';
|
||||
|
||||
// Types
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { PanelHeader } from './PanelHeader';
|
||||
import { DataPanel, PanelProps } from './DataPanel';
|
||||
import { TimeRange, PanelProps } from 'app/types';
|
||||
|
||||
export interface Props {
|
||||
panel: PanelModel;
|
||||
@ -10,30 +19,59 @@ export interface Props {
|
||||
component: ComponentClass<PanelProps>;
|
||||
}
|
||||
|
||||
interface State {}
|
||||
|
||||
export class PanelChrome extends React.Component<Props, State> {
|
||||
panelComponent: DataPanel;
|
||||
export interface State {
|
||||
refreshCounter: number;
|
||||
timeRange?: TimeRange;
|
||||
}
|
||||
|
||||
export class PanelChrome extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
refreshCounter: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dashboard.panelInitialized(this.props.panel);
|
||||
this.props.panel.events.on('refresh', this.onRefresh);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.panel.events.off('refresh', this.onRefresh);
|
||||
}
|
||||
|
||||
onRefresh = () => {
|
||||
const timeSrv = getTimeSrv();
|
||||
const timeRange = timeSrv.timeRange();
|
||||
|
||||
this.setState({
|
||||
refreshCounter: this.state.refreshCounter + 1,
|
||||
timeRange: timeRange,
|
||||
});
|
||||
};
|
||||
|
||||
get isVisible() {
|
||||
return this.props.dashboard.otherPanelInFullscreen(this.props.panel);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { datasource, targets } = this.props.panel;
|
||||
const { panel, dashboard } = this.props;
|
||||
const { datasource, targets } = panel;
|
||||
const { refreshCounter } = this.state;
|
||||
const PanelComponent = this.props.component;
|
||||
|
||||
// if (!PanelComponent) {
|
||||
// PanelComponent = dataPanels[type] = DataPanelWrapper(this.props.component);
|
||||
// }
|
||||
|
||||
console.log('PanelChrome render', PanelComponent);
|
||||
|
||||
return (
|
||||
<div className="panel-container">
|
||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
<PanelHeader panel={panel} dashboard={dashboard} />
|
||||
<div className="panel-content">
|
||||
<DataPanel datasource={datasource} queries={targets}>
|
||||
<DataPanel
|
||||
datasource={datasource}
|
||||
queries={targets}
|
||||
isVisible={this.isVisible}
|
||||
refreshCounter={refreshCounter}
|
||||
>
|
||||
{({ loading, data }) => {
|
||||
return <PanelComponent loading={loading} data={data} />;
|
||||
}}
|
||||
|
@ -1,9 +1,15 @@
|
||||
// Libraries
|
||||
import moment from 'moment';
|
||||
import _ from 'lodash';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
// Utils
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import * as dateMath from 'app/core/utils/datemath';
|
||||
|
||||
// Types
|
||||
import { TimeRange } from 'app/types';
|
||||
|
||||
export class TimeSrv {
|
||||
time: any;
|
||||
refreshTimer: any;
|
||||
@ -200,7 +206,7 @@ export class TimeSrv {
|
||||
return range;
|
||||
}
|
||||
|
||||
timeRange() {
|
||||
timeRange(): TimeRange {
|
||||
// make copies if they are moment (do not want to return out internal moment, because they are mutable!)
|
||||
const raw = {
|
||||
from: moment.isMoment(this.time.from) ? moment(this.time.from) : this.time.from,
|
||||
@ -222,17 +228,21 @@ export class TimeSrv {
|
||||
const timespan = range.to.valueOf() - range.from.valueOf();
|
||||
const center = range.to.valueOf() - timespan / 2;
|
||||
|
||||
let to = center + timespan * factor / 2;
|
||||
let from = center - timespan * factor / 2;
|
||||
|
||||
if (to > Date.now() && range.to <= Date.now()) {
|
||||
const offset = to - Date.now();
|
||||
from = from - offset;
|
||||
to = Date.now();
|
||||
}
|
||||
const to = center + timespan * factor / 2;
|
||||
const from = center - timespan * factor / 2;
|
||||
|
||||
this.setTime({ from: moment.utc(from), to: moment.utc(to) });
|
||||
}
|
||||
}
|
||||
|
||||
let singleton;
|
||||
|
||||
export function setTimeSrv(srv: TimeSrv) {
|
||||
singleton = srv;
|
||||
}
|
||||
|
||||
export function getTimeSrv(): TimeSrv {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
coreModule.service('timeSrv', TimeSrv);
|
||||
|
@ -145,7 +145,6 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
ctrl.calculatePanelHeight();
|
||||
|
||||
ctrl.events.on('render', () => {
|
||||
console.log('panel_directive: render', ctrl.panel.id);
|
||||
if (transparentLastState !== ctrl.panel.transparent) {
|
||||
panelContainer.toggleClass('panel-transparent', ctrl.panel.transparent === true);
|
||||
transparentLastState = ctrl.panel.transparent;
|
||||
|
@ -162,5 +162,15 @@ export class DatasourceSrv {
|
||||
}
|
||||
}
|
||||
|
||||
let singleton: DatasourceSrv;
|
||||
|
||||
export function setDatasourceSrv(srv: DatasourceSrv) {
|
||||
singleton = srv;
|
||||
}
|
||||
|
||||
export function getDatasourceSrv(): DatasourceSrv {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
coreModule.service('datasourceSrv', DatasourceSrv);
|
||||
export default DatasourceSrv;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class CloudWatchQueryParameter {
|
||||
@ -239,5 +240,5 @@ export class CloudWatchQueryParameterCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('grafana.controllers').directive('cloudwatchQueryParameter', CloudWatchQueryParameter);
|
||||
angular.module('grafana.controllers').controller('CloudWatchQueryParameterCtrl', CloudWatchQueryParameterCtrl);
|
||||
coreModule.directive('cloudwatchQueryParameter', CloudWatchQueryParameter);
|
||||
coreModule.controller('CloudWatchQueryParameterCtrl', CloudWatchQueryParameterCtrl);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import * as queryDef from './query_def';
|
||||
|
||||
@ -226,6 +226,5 @@ export class ElasticBucketAggCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
const module = angular.module('grafana.directives');
|
||||
module.directive('elasticBucketAgg', elasticBucketAgg);
|
||||
module.controller('ElasticBucketAggCtrl', ElasticBucketAggCtrl);
|
||||
coreModule.directive('elasticBucketAgg', elasticBucketAgg);
|
||||
coreModule.controller('ElasticBucketAggCtrl', ElasticBucketAggCtrl);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import * as queryDef from './query_def';
|
||||
|
||||
@ -203,6 +203,5 @@ export class ElasticMetricAggCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
const module = angular.module('grafana.directives');
|
||||
module.directive('elasticMetricAgg', elasticMetricAgg);
|
||||
module.controller('ElasticMetricAggCtrl', ElasticMetricAggCtrl);
|
||||
coreModule.directive('elasticMetricAgg', elasticMetricAgg);
|
||||
coreModule.controller('ElasticMetricAggCtrl', ElasticMetricAggCtrl);
|
||||
|
@ -1,8 +1,8 @@
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import rst2html from 'rst2html';
|
||||
import Drop from 'tether-drop';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
/** @ngInject */
|
||||
export function graphiteAddFunc($compile) {
|
||||
@ -130,7 +130,7 @@ export function graphiteAddFunc($compile) {
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('grafana.directives').directive('graphiteAddFunc', graphiteAddFunc);
|
||||
coreModule.directive('graphiteAddFunc', graphiteAddFunc);
|
||||
|
||||
function createFunctionDropDownMenu(funcDefs) {
|
||||
const categories = {};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import rst2html from 'rst2html';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
/** @ngInject */
|
||||
export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
|
||||
@ -315,4 +315,4 @@ export function graphiteFuncEditor($compile, templateSrv, popoverSrv) {
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('grafana.directives').directive('graphiteFuncEditor', graphiteFuncEditor);
|
||||
coreModule.directive('graphiteFuncEditor', graphiteFuncEditor);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import * as options from './constants';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
@ -83,5 +83,5 @@ export class StackdriverAggregationCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('grafana.controllers').directive('stackdriverAggregation', StackdriverAggregation);
|
||||
angular.module('grafana.controllers').controller('StackdriverAggregationCtrl', StackdriverAggregationCtrl);
|
||||
coreModule.directive('stackdriverAggregation', StackdriverAggregation);
|
||||
coreModule.controller('StackdriverAggregationCtrl', StackdriverAggregationCtrl);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import { FilterSegments, DefaultRemoveFilterValue } from './filter_segments';
|
||||
import appEvents from 'app/core/app_events';
|
||||
@ -281,5 +281,5 @@ export class StackdriverFilterCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('grafana.controllers').directive('stackdriverFilter', StackdriverFilter);
|
||||
angular.module('grafana.controllers').controller('StackdriverFilterCtrl', StackdriverFilterCtrl);
|
||||
coreModule.directive('stackdriverFilter', StackdriverFilter);
|
||||
coreModule.controller('StackdriverFilterCtrl', StackdriverFilterCtrl);
|
||||
|
@ -80,7 +80,6 @@ class GraphElement {
|
||||
this.annotations = this.ctrl.annotations || [];
|
||||
this.buildFlotPairs(this.data);
|
||||
const graphHeight = this.elem.height();
|
||||
console.log('graphHeight', graphHeight);
|
||||
updateLegendValues(this.data, this.panel, graphHeight);
|
||||
|
||||
this.ctrl.events.emit('render-legend');
|
||||
|
@ -1,11 +1,9 @@
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import baron from 'baron';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
const module = angular.module('grafana.directives');
|
||||
|
||||
module.directive('graphLegend', (popoverSrv, $timeout) => {
|
||||
coreModule.directive('graphLegend', (popoverSrv, $timeout) => {
|
||||
return {
|
||||
link: (scope, elem) => {
|
||||
let firstRender = true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import angular from 'angular';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
/** @ngInject */
|
||||
export function SeriesOverridesCtrl($scope, $element, popoverSrv) {
|
||||
@ -156,4 +156,4 @@ export function SeriesOverridesCtrl($scope, $element, popoverSrv) {
|
||||
$scope.updateCurrentOverrides();
|
||||
}
|
||||
|
||||
angular.module('grafana.controllers').controller('SeriesOverridesCtrl', SeriesOverridesCtrl);
|
||||
coreModule.controller('SeriesOverridesCtrl', SeriesOverridesCtrl);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { PanelProps } from 'app/features/dashboard/dashgrid/DataPanel';
|
||||
import { PanelProps } from 'app/types';
|
||||
|
||||
interface Options {
|
||||
showBars: boolean;
|
||||
@ -22,6 +22,8 @@ export class Graph2 extends PureComponent<Props> {
|
||||
value = data[0].value;
|
||||
}
|
||||
|
||||
console.log('graph2 render');
|
||||
|
||||
return <h2>Text Panel {value}</h2>;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import * as d3 from 'd3';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { tickStep } from 'app/core/utils/ticks';
|
||||
import { getColorScale, getOpacityScale } from './color_scale';
|
||||
|
||||
const module = angular.module('grafana.directives');
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
const LEGEND_HEIGHT_PX = 6;
|
||||
const LEGEND_WIDTH_PX = 100;
|
||||
@ -16,7 +14,7 @@ const LEGEND_VALUE_MARGIN = 0;
|
||||
/**
|
||||
* Color legend for heatmap editor.
|
||||
*/
|
||||
module.directive('colorLegend', () => {
|
||||
coreModule.directive('colorLegend', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<div class="heatmap-color-legend"><svg width="16.5rem" height="24px"></svg></div>',
|
||||
@ -52,7 +50,7 @@ module.directive('colorLegend', () => {
|
||||
/**
|
||||
* Heatmap legend with scale values.
|
||||
*/
|
||||
module.directive('heatmapLegend', () => {
|
||||
coreModule.directive('heatmapLegend', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: `<div class="heatmap-color-legend"><svg width="${LEGEND_WIDTH_PX}px" height="${LEGEND_HEIGHT_PX}px"></svg></div>`,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { PanelProps } from 'app/features/dashboard/dashgrid/DataPanel';
|
||||
import { PanelProps } from 'app/types';
|
||||
|
||||
export class Text2 extends PureComponent<PanelProps> {
|
||||
constructor(props) {
|
||||
@ -14,7 +14,7 @@ export class Text2 extends PureComponent<PanelProps> {
|
||||
value = data[0].value;
|
||||
}
|
||||
|
||||
return <h2>Graph Panel! {value}</h2>;
|
||||
return <h2>Text Panel! {value}</h2>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys';
|
||||
import { Invitee, OrgUser, User, UsersState } from './user';
|
||||
import { DataSource, DataSourcesState } from './datasources';
|
||||
import { PluginMeta, Plugin, PluginsState } from './plugins';
|
||||
import { TimeRange, LoadingState } from './queries';
|
||||
import { PanelProps } from './panel';
|
||||
|
||||
export {
|
||||
Team,
|
||||
@ -45,6 +47,9 @@ export {
|
||||
OrgUser,
|
||||
User,
|
||||
UsersState,
|
||||
TimeRange,
|
||||
LoadingState,
|
||||
PanelProps,
|
||||
};
|
||||
|
||||
export interface StoreState {
|
||||
|
6
public/app/types/panel.ts
Normal file
6
public/app/types/panel.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { LoadingState } from './queries';
|
||||
|
||||
export interface PanelProps {
|
||||
data: any;
|
||||
loading: LoadingState;
|
||||
}
|
19
public/app/types/queries.ts
Normal file
19
public/app/types/queries.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Moment } from 'moment';
|
||||
|
||||
export enum LoadingState {
|
||||
NotStarted = 'NotStarted',
|
||||
Loading = 'Loading',
|
||||
Done = 'Done',
|
||||
Error = 'Error',
|
||||
}
|
||||
|
||||
export interface RawTimeRange {
|
||||
from: Moment | string;
|
||||
to: Moment | string;
|
||||
}
|
||||
|
||||
export interface TimeRange {
|
||||
from: Moment;
|
||||
to: Moment;
|
||||
raw: RawTimeRange;
|
||||
}
|
Loading…
Reference in New Issue
Block a user