mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'develop' of github.com:grafana/grafana into develop
This commit is contained in:
commit
8ad37ea926
@ -81,7 +81,6 @@ export class DataPanel extends Component<Props, State> {
|
|||||||
try {
|
try {
|
||||||
const dataSourceSrv = getDatasourceSrv();
|
const dataSourceSrv = getDatasourceSrv();
|
||||||
const ds = await dataSourceSrv.get(datasource);
|
const ds = await dataSourceSrv.get(datasource);
|
||||||
|
|
||||||
const queryOptions: DataQueryOptions = {
|
const queryOptions: DataQueryOptions = {
|
||||||
timezone: 'browser',
|
timezone: 'browser',
|
||||||
panelId: panelId,
|
panelId: panelId,
|
||||||
|
@ -2,12 +2,15 @@
|
|||||||
import React, { ComponentClass, PureComponent } from 'react';
|
import React, { ComponentClass, PureComponent } from 'react';
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
import { getTimeSrv } from '../time_srv';
|
import { getTimeSrv, TimeSrv } from '../time_srv';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { PanelHeader } from './PanelHeader/PanelHeader';
|
import { PanelHeader } from './PanelHeader/PanelHeader';
|
||||||
import { DataPanel } from './DataPanel';
|
import { DataPanel } from './DataPanel';
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PanelModel } from '../panel_model';
|
import { PanelModel } from '../panel_model';
|
||||||
import { DashboardModel } from '../dashboard_model';
|
import { DashboardModel } from '../dashboard_model';
|
||||||
@ -22,10 +25,13 @@ export interface Props {
|
|||||||
export interface State {
|
export interface State {
|
||||||
refreshCounter: number;
|
refreshCounter: number;
|
||||||
renderCounter: number;
|
renderCounter: number;
|
||||||
|
timeInfo?: string;
|
||||||
timeRange?: TimeRange;
|
timeRange?: TimeRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PanelChrome extends PureComponent<Props, State> {
|
export class PanelChrome extends PureComponent<Props, State> {
|
||||||
|
timeSrv: TimeSrv = getTimeSrv();
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -46,22 +52,26 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onRefresh = () => {
|
onRefresh = () => {
|
||||||
const timeSrv = getTimeSrv();
|
console.log('onRefresh');
|
||||||
const timeRange = timeSrv.timeRange();
|
if (!this.isVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.setState(prevState => ({
|
const { panel } = this.props;
|
||||||
...prevState,
|
const timeData = applyPanelTimeOverrides(panel, this.timeSrv.timeRange());
|
||||||
|
|
||||||
|
this.setState({
|
||||||
refreshCounter: this.state.refreshCounter + 1,
|
refreshCounter: this.state.refreshCounter + 1,
|
||||||
timeRange: timeRange,
|
timeRange: timeData.timeRange,
|
||||||
}));
|
timeInfo: timeData.timeInfo,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onRender = () => {
|
onRender = () => {
|
||||||
console.log('onRender');
|
console.log('onRender');
|
||||||
this.setState(prevState => ({
|
this.setState({
|
||||||
...prevState,
|
|
||||||
renderCounter: this.state.renderCounter + 1,
|
renderCounter: this.state.renderCounter + 1,
|
||||||
}));
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
get isVisible() {
|
get isVisible() {
|
||||||
@ -70,7 +80,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { panel, dashboard } = this.props;
|
const { panel, dashboard } = this.props;
|
||||||
const { refreshCounter, timeRange, renderCounter } = this.state;
|
const { refreshCounter, timeRange, timeInfo, renderCounter } = this.state;
|
||||||
|
|
||||||
const { datasource, targets } = panel;
|
const { datasource, targets } = panel;
|
||||||
const PanelComponent = this.props.component;
|
const PanelComponent = this.props.component;
|
||||||
@ -78,7 +88,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
console.log('panelChrome render');
|
console.log('panelChrome render');
|
||||||
return (
|
return (
|
||||||
<div className="panel-container">
|
<div className="panel-container">
|
||||||
<PanelHeader panel={panel} dashboard={dashboard} />
|
<PanelHeader panel={panel} dashboard={dashboard} timeInfo={timeInfo} />
|
||||||
<div className="panel-content">
|
<div className="panel-content">
|
||||||
<DataPanel
|
<DataPanel
|
||||||
datasource={datasource}
|
datasource={datasource}
|
||||||
|
@ -9,6 +9,7 @@ import { PanelModel } from 'app/features/dashboard/panel_model';
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
|
timeInfo: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PanelHeader extends PureComponent<Props> {
|
export class PanelHeader extends PureComponent<Props> {
|
||||||
@ -16,7 +17,7 @@ export class PanelHeader extends PureComponent<Props> {
|
|||||||
const isFullscreen = false;
|
const isFullscreen = false;
|
||||||
const isLoading = false;
|
const isLoading = false;
|
||||||
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||||
const { panel, dashboard } = this.props;
|
const { panel, dashboard, timeInfo } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={panelHeaderClass}>
|
<div className={panelHeaderClass}>
|
||||||
@ -39,10 +40,11 @@ export class PanelHeader extends PureComponent<Props> {
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<PanelHeaderMenu panel={panel} dashboard={dashboard} />
|
<PanelHeaderMenu panel={panel} dashboard={dashboard} />
|
||||||
|
{timeInfo && (
|
||||||
<span className="panel-time-info">
|
<span className="panel-time-info">
|
||||||
<i className="fa fa-clock-o" /> 4m
|
<i className="fa fa-clock-o" /> {timeInfo}
|
||||||
</span>
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,6 +42,14 @@ export class PanelModel {
|
|||||||
datasource: string;
|
datasource: string;
|
||||||
thresholds?: any;
|
thresholds?: any;
|
||||||
|
|
||||||
|
snapshotData?: any;
|
||||||
|
timeFrom?: any;
|
||||||
|
timeShift?: any;
|
||||||
|
hideTimeOverride?: any;
|
||||||
|
|
||||||
|
maxDataPoints?: number;
|
||||||
|
interval?: string;
|
||||||
|
|
||||||
// non persisted
|
// non persisted
|
||||||
fullscreen: boolean;
|
fullscreen: boolean;
|
||||||
isEditing: boolean;
|
isEditing: boolean;
|
||||||
|
@ -20,7 +20,7 @@ export class TimeSrv {
|
|||||||
private autoRefreshBlocked: boolean;
|
private autoRefreshBlocked: boolean;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private $rootScope, private $timeout, private $location, private timer, private contextSrv) {
|
constructor($rootScope, private $timeout, private $location, private timer, private contextSrv) {
|
||||||
// default time
|
// default time
|
||||||
this.time = { from: '6h', to: 'now' };
|
this.time = { from: '6h', to: 'now' };
|
||||||
|
|
||||||
@ -189,7 +189,6 @@ export class TimeSrv {
|
|||||||
this.$location.search(urlParams);
|
this.$location.search(urlParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$rootScope.appEvent('time-range-changed', this.time);
|
|
||||||
this.$timeout(this.refreshDashboard.bind(this), 0);
|
this.$timeout(this.refreshDashboard.bind(this), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
import appEvents from 'app/core/app_events';
|
// Store
|
||||||
|
import store from 'app/core/store';
|
||||||
|
|
||||||
|
// Models
|
||||||
import { DashboardModel } from 'app/features/dashboard/dashboard_model';
|
import { DashboardModel } from 'app/features/dashboard/dashboard_model';
|
||||||
import { PanelModel } from 'app/features/dashboard/panel_model';
|
import { PanelModel } from 'app/features/dashboard/panel_model';
|
||||||
import store from 'app/core/store';
|
import { TimeRange } from 'app/types/series';
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
import { isString as _isString } from 'lodash';
|
||||||
|
import * as rangeUtil from 'app/core/utils/rangeutil';
|
||||||
|
import * as dateMath from 'app/core/utils/datemath';
|
||||||
|
import appEvents from 'app/core/app_events';
|
||||||
|
|
||||||
|
// Services
|
||||||
|
import templateSrv from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
|
// Constants
|
||||||
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
||||||
|
|
||||||
export const removePanel = (dashboard: DashboardModel, panel: PanelModel, ask: boolean) => {
|
export const removePanel = (dashboard: DashboardModel, panel: PanelModel, ask: boolean) => {
|
||||||
@ -84,3 +98,70 @@ export const toggleLegend = (panel: PanelModel) => {
|
|||||||
// panel.legend.show = !panel.legend.show;
|
// panel.legend.show = !panel.legend.show;
|
||||||
refreshPanel(panel);
|
refreshPanel(panel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface TimeOverrideResult {
|
||||||
|
timeRange: TimeRange;
|
||||||
|
timeInfo: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyPanelTimeOverrides(panel: PanelModel, timeRange: TimeRange): TimeOverrideResult {
|
||||||
|
const newTimeData = {
|
||||||
|
timeInfo: '',
|
||||||
|
timeRange: timeRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (panel.timeFrom) {
|
||||||
|
const timeFromInterpolated = templateSrv.replace(panel.timeFrom, panel.scopedVars);
|
||||||
|
const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
|
||||||
|
if (timeFromInfo.invalid) {
|
||||||
|
newTimeData.timeInfo = 'invalid time override';
|
||||||
|
return newTimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isString(timeRange.raw.from)) {
|
||||||
|
const timeFromDate = dateMath.parse(timeFromInfo.from);
|
||||||
|
newTimeData.timeInfo = timeFromInfo.display;
|
||||||
|
newTimeData.timeRange = {
|
||||||
|
from: timeFromDate,
|
||||||
|
to: dateMath.parse(timeFromInfo.to),
|
||||||
|
raw: {
|
||||||
|
from: timeFromInfo.from,
|
||||||
|
to: timeFromInfo.to,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel.timeShift) {
|
||||||
|
const timeShiftInterpolated = templateSrv.replace(panel.timeShift, panel.scopedVars);
|
||||||
|
const timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
|
||||||
|
if (timeShiftInfo.invalid) {
|
||||||
|
newTimeData.timeInfo = 'invalid timeshift';
|
||||||
|
return newTimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeShift = '-' + timeShiftInterpolated;
|
||||||
|
newTimeData.timeInfo += ' timeshift ' + timeShift;
|
||||||
|
newTimeData.timeRange = {
|
||||||
|
from: dateMath.parseDateMath(timeShift, timeRange.from, false),
|
||||||
|
to: dateMath.parseDateMath(timeShift, timeRange.to, true),
|
||||||
|
raw: {
|
||||||
|
from: timeRange.from,
|
||||||
|
to: timeRange.to,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel.hideTimeOverride) {
|
||||||
|
newTimeData.timeInfo = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return newTimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getResolution(panel: PanelModel): number {
|
||||||
|
const htmlEl = document.getElementsByTagName('html')[0];
|
||||||
|
const width = htmlEl.getBoundingClientRect().width; // https://stackoverflow.com/a/21454625
|
||||||
|
|
||||||
|
return panel.maxDataPoints ? panel.maxDataPoints : Math.ceil(width * (panel.gridPos.w / 24));
|
||||||
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import $ from 'jquery';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import config from 'app/core/config';
|
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
||||||
import * as rangeUtil from 'app/core/utils/rangeutil';
|
|
||||||
import * as dateMath from 'app/core/utils/datemath';
|
|
||||||
import { getExploreUrl } from 'app/core/utils/explore';
|
import { getExploreUrl } from 'app/core/utils/explore';
|
||||||
import { metricsTabDirective } from './metrics_tab';
|
import { metricsTabDirective } from './metrics_tab';
|
||||||
|
import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/utils/panel';
|
||||||
|
|
||||||
class MetricsPanelCtrl extends PanelCtrl {
|
class MetricsPanelCtrl extends PanelCtrl {
|
||||||
scope: any;
|
scope: any;
|
||||||
@ -134,14 +133,11 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
updateTimeRange(datasource?) {
|
updateTimeRange(datasource?) {
|
||||||
this.datasource = datasource || this.datasource;
|
this.datasource = datasource || this.datasource;
|
||||||
this.range = this.timeSrv.timeRange();
|
this.range = this.timeSrv.timeRange();
|
||||||
|
this.resolution = getResolution(this.panel);
|
||||||
|
|
||||||
this.applyPanelTimeOverrides();
|
const newTimeData = applyPanelTimeOverrides(this.panel, this.range);
|
||||||
|
this.timeInfo = newTimeData.timeInfo;
|
||||||
if (this.panel.maxDataPoints) {
|
this.range = newTimeData.timeRange;
|
||||||
this.resolution = this.panel.maxDataPoints;
|
|
||||||
} else {
|
|
||||||
this.resolution = Math.ceil($(window).width() * (this.panel.gridPos.w / 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.calculateInterval();
|
this.calculateInterval();
|
||||||
|
|
||||||
@ -163,48 +159,6 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
this.intervalMs = res.intervalMs;
|
this.intervalMs = res.intervalMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPanelTimeOverrides() {
|
|
||||||
this.timeInfo = '';
|
|
||||||
|
|
||||||
// check panel time overrrides
|
|
||||||
if (this.panel.timeFrom) {
|
|
||||||
const timeFromInterpolated = this.templateSrv.replace(this.panel.timeFrom, this.panel.scopedVars);
|
|
||||||
const timeFromInfo = rangeUtil.describeTextRange(timeFromInterpolated);
|
|
||||||
if (timeFromInfo.invalid) {
|
|
||||||
this.timeInfo = 'invalid time override';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_.isString(this.range.raw.from)) {
|
|
||||||
const timeFromDate = dateMath.parse(timeFromInfo.from);
|
|
||||||
this.timeInfo = timeFromInfo.display;
|
|
||||||
this.range.from = timeFromDate;
|
|
||||||
this.range.to = dateMath.parse(timeFromInfo.to);
|
|
||||||
this.range.raw.from = timeFromInfo.from;
|
|
||||||
this.range.raw.to = timeFromInfo.to;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.panel.timeShift) {
|
|
||||||
const timeShiftInterpolated = this.templateSrv.replace(this.panel.timeShift, this.panel.scopedVars);
|
|
||||||
const timeShiftInfo = rangeUtil.describeTextRange(timeShiftInterpolated);
|
|
||||||
if (timeShiftInfo.invalid) {
|
|
||||||
this.timeInfo = 'invalid timeshift';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeShift = '-' + timeShiftInterpolated;
|
|
||||||
this.timeInfo += ' timeshift ' + timeShift;
|
|
||||||
this.range.from = dateMath.parseDateMath(timeShift, this.range.from, false);
|
|
||||||
this.range.to = dateMath.parseDateMath(timeShift, this.range.to, true);
|
|
||||||
this.range.raw = { from: this.range.from, to: this.range.to };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.panel.hideTimeOverride) {
|
|
||||||
this.timeInfo = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issueQueries(datasource) {
|
issueQueries(datasource) {
|
||||||
this.datasource = datasource;
|
this.datasource = datasource;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user