mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 03:11:01 -06:00
feat(graph): updating graph panel to new format progress
This commit is contained in:
parent
aa251fc9ce
commit
ebba7a0327
@ -49,9 +49,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
}
|
||||
|
||||
initEditMode() {
|
||||
this.addEditorTab('Metrics', () => {
|
||||
return { templateUrl: 'public/app/partials/metrics.html' };
|
||||
});
|
||||
this.addEditorTab('Metrics', 'public/app/partials/metrics.html');
|
||||
this.datasources = this.datasourceSrv.getMetricSources();
|
||||
}
|
||||
|
||||
@ -108,15 +106,6 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
this.timing.queryEnd = new Date().getTime();
|
||||
}
|
||||
|
||||
setTimeRenderStart() {
|
||||
this.timing = this.timing || {};
|
||||
this.timing.renderStart = new Date().getTime();
|
||||
}
|
||||
|
||||
setTimeRenderEnd() {
|
||||
this.timing.renderEnd = new Date().getTime();
|
||||
}
|
||||
|
||||
updateTimeRange() {
|
||||
this.range = this.timeSrv.timeRange();
|
||||
this.rangeRaw = this.timeSrv.timeRange(false);
|
||||
|
@ -2,29 +2,28 @@
|
||||
|
||||
import config from 'app/core/config';
|
||||
|
||||
function generalOptionsTabEditorTab() {
|
||||
return {templateUrl: 'public/app/partials/panelgeneral.html'};
|
||||
}
|
||||
|
||||
export class PanelCtrl {
|
||||
panel: any;
|
||||
row: any;
|
||||
dashboard: any;
|
||||
editorTabIndex: number;
|
||||
name: string;
|
||||
pluginName: string;
|
||||
pluginId: string;
|
||||
icon: string;
|
||||
editorTabs: any;
|
||||
$scope: any;
|
||||
$injector: any;
|
||||
fullscreen: boolean;
|
||||
inspector: any;
|
||||
editModeInitiated: boolean;
|
||||
|
||||
constructor($scope, $injector) {
|
||||
var plugin = config.panels[this.panel.type];
|
||||
|
||||
this.$injector = $injector;
|
||||
this.$scope = $scope;
|
||||
this.name = plugin.name;
|
||||
this.pluginName = plugin.name;
|
||||
this.pluginId = plugin.id;
|
||||
this.icon = plugin.info.icon;
|
||||
this.editorTabIndex = 0;
|
||||
|
||||
@ -59,9 +58,9 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
editPanel() {
|
||||
if (!this.editorTabs) {
|
||||
if (!this.editModeInitiated) {
|
||||
this.editorTabs = [];
|
||||
this.editorTabs.push({title: 'General', directiveFn: generalOptionsTabEditorTab});
|
||||
this.addEditorTab('General', 'public/app/partials/panelgeneral.html');
|
||||
this.initEditMode();
|
||||
}
|
||||
|
||||
@ -76,8 +75,13 @@ export class PanelCtrl {
|
||||
return;
|
||||
}
|
||||
|
||||
addEditorTab(title, directiveFn) {
|
||||
this.editorTabs.push({title: title, directiveFn: directiveFn});
|
||||
addEditorTab(title, templateUrl) {
|
||||
this.editorTabs.push({
|
||||
title: title,
|
||||
directiveFn: function() {
|
||||
return {templateUrl: templateUrl};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getMenu() {
|
||||
@ -92,4 +96,8 @@ export class PanelCtrl {
|
||||
otherPanelInFullscreenMode() {
|
||||
return this.dashboard.meta.fullscreen && !this.fullscreen;
|
||||
}
|
||||
|
||||
broadcastRender(arg1?, arg2?) {
|
||||
this.$scope.$broadcast('render', arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,14 @@ function panelEditorTab(dynamicDirectiveSrv) {
|
||||
scope: {
|
||||
ctrl: "=",
|
||||
editorTab: "=",
|
||||
index: "=",
|
||||
},
|
||||
directive: scope => {
|
||||
var pluginId = scope.ctrl.pluginId;
|
||||
var tabIndex = scope.index;
|
||||
|
||||
return Promise.resolve({
|
||||
name: 'panel-editor-tab-' + scope.editorTab.title,
|
||||
name: `panel-editor-tab-${pluginId}${tabIndex}`,
|
||||
fn: scope.editorTab.directiveFn,
|
||||
});
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
<div class="gf-box-body">
|
||||
<div ng-repeat="tab in ctrl.editorTabs" ng-if="ctrl.editorTabIndex === $index">
|
||||
<panel-editor-tab editor-tab="tab" ctrl="ctrl"></panel-editor-tab>
|
||||
<panel-editor-tab editor-tab="tab" ctrl="ctrl" index="$index"></panel-editor-tab>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,14 +24,16 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
restrict: 'A',
|
||||
template: '<div> </div>',
|
||||
link: function(scope, elem) {
|
||||
var dashboard = scope.dashboard;
|
||||
var ctrl = scope.ctrl;
|
||||
var dashboard = ctrl.dashboard;
|
||||
var panel = ctrl.panel;
|
||||
var data, annotations;
|
||||
var sortedSeries;
|
||||
var graphHeight;
|
||||
var legendSideLastValue = null;
|
||||
scope.crosshairEmiter = false;
|
||||
var rootScope = scope.$root;
|
||||
|
||||
scope.onAppEvent('setCrosshair', function(event, info) {
|
||||
rootScope.onAppEvent('setCrosshair', function(event, info) {
|
||||
// do not need to to this if event is from this panel
|
||||
if (info.scope === scope) {
|
||||
return;
|
||||
@ -43,20 +45,20 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
plot.setCrosshair({ x: info.pos.x, y: info.pos.y });
|
||||
}
|
||||
}
|
||||
});
|
||||
}, scope);
|
||||
|
||||
scope.onAppEvent('clearCrosshair', function() {
|
||||
rootScope.onAppEvent('clearCrosshair', function() {
|
||||
var plot = elem.data().plot;
|
||||
if (plot) {
|
||||
plot.clearCrosshair();
|
||||
}
|
||||
});
|
||||
}, scope);
|
||||
|
||||
// Receive render events
|
||||
scope.$on('render',function(event, renderData) {
|
||||
data = renderData || data;
|
||||
if (!data) {
|
||||
scope.get_data();
|
||||
ctrl.refresh();
|
||||
return;
|
||||
}
|
||||
annotations = data.annotations || annotations;
|
||||
@ -64,10 +66,10 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
});
|
||||
|
||||
function getLegendHeight(panelHeight) {
|
||||
if (!scope.panel.legend.show || scope.panel.legend.rightSide) {
|
||||
if (!panel.legend.show || panel.legend.rightSide) {
|
||||
return 0;
|
||||
}
|
||||
if (scope.panel.legend.alignAsTable) {
|
||||
if (panel.legend.alignAsTable) {
|
||||
var total = 30 + (25 * data.length);
|
||||
return Math.min(total, Math.floor(panelHeight/2));
|
||||
} else {
|
||||
@ -77,14 +79,13 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
|
||||
function setElementHeight() {
|
||||
try {
|
||||
graphHeight = scope.height || scope.panel.height || scope.row.height;
|
||||
graphHeight = ctrl.height || panel.height || ctrl.row.height;
|
||||
if (_.isString(graphHeight)) {
|
||||
graphHeight = parseInt(graphHeight.replace('px', ''), 10);
|
||||
}
|
||||
|
||||
graphHeight -= 5; // padding
|
||||
graphHeight -= scope.panel.title ? 24 : 9; // subtract panel title bar
|
||||
|
||||
graphHeight -= panel.title ? 24 : 9; // subtract panel title bar
|
||||
graphHeight = graphHeight - getLegendHeight(graphHeight); // subtract one line legend
|
||||
|
||||
elem.css('height', graphHeight + 'px');
|
||||
@ -100,7 +101,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($rootScope.fullscreen && !scope.fullscreen) {
|
||||
if (ctrl.otherPanelInFullscreenMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -122,11 +123,11 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var series = data[i];
|
||||
var axis = yaxis[series.yaxis - 1];
|
||||
var formater = kbn.valueFormats[scope.panel.y_formats[series.yaxis - 1]];
|
||||
var formater = kbn.valueFormats[panel.y_formats[series.yaxis - 1]];
|
||||
|
||||
// decimal override
|
||||
if (_.isNumber(scope.panel.decimals)) {
|
||||
series.updateLegendValues(formater, scope.panel.decimals, null);
|
||||
if (_.isNumber(panel.decimals)) {
|
||||
series.updateLegendValues(formater, panel.decimals, null);
|
||||
} else {
|
||||
// auto decimals
|
||||
// legend and tooltip gets one more decimal precision
|
||||
@ -135,22 +136,22 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
series.updateLegendValues(formater, tickDecimals, axis.scaledDecimals + 2);
|
||||
}
|
||||
|
||||
if(!scope.$$phase) { scope.$digest(); }
|
||||
if(!rootScope.$$phase) { scope.$digest(); }
|
||||
}
|
||||
|
||||
// add left axis labels
|
||||
if (scope.panel.leftYAxisLabel) {
|
||||
if (panel.leftYAxisLabel) {
|
||||
var yaxisLabel = $("<div class='axisLabel left-yaxis-label'></div>")
|
||||
.text(scope.panel.leftYAxisLabel)
|
||||
.text(panel.leftYAxisLabel)
|
||||
.appendTo(elem);
|
||||
|
||||
yaxisLabel.css("margin-top", yaxisLabel.width() / 2);
|
||||
}
|
||||
|
||||
// add right axis labels
|
||||
if (scope.panel.rightYAxisLabel) {
|
||||
if (panel.rightYAxisLabel) {
|
||||
var rightLabel = $("<div class='axisLabel right-yaxis-label'></div>")
|
||||
.text(scope.panel.rightYAxisLabel)
|
||||
.text(panel.rightYAxisLabel)
|
||||
.appendTo(elem);
|
||||
|
||||
rightLabel.css("margin-top", rightLabel.width() / 2);
|
||||
@ -158,8 +159,8 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
}
|
||||
|
||||
function processOffsetHook(plot, gridMargin) {
|
||||
if (scope.panel.leftYAxisLabel) { gridMargin.left = 20; }
|
||||
if (scope.panel.rightYAxisLabel) { gridMargin.right = 20; }
|
||||
if (panel.leftYAxisLabel) { gridMargin.left = 20; }
|
||||
if (panel.rightYAxisLabel) { gridMargin.right = 20; }
|
||||
}
|
||||
|
||||
// Function for rendering panel
|
||||
@ -168,7 +169,6 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
return;
|
||||
}
|
||||
|
||||
var panel = scope.panel;
|
||||
var stack = panel.stack ? true : null;
|
||||
|
||||
// Populate element
|
||||
@ -230,7 +230,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
series.data = series.getFlotPairs(series.nullPointMode || panel.nullPointMode, panel.y_formats);
|
||||
|
||||
// if hidden remove points and disable stack
|
||||
if (scope.hiddenSeries[series.alias]) {
|
||||
if (ctrl.hiddenSeries[series.alias]) {
|
||||
series.data = [];
|
||||
series.stack = false;
|
||||
}
|
||||
@ -255,7 +255,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
}
|
||||
|
||||
if (incrementRenderCounter) {
|
||||
scope.panelRenderingComplete();
|
||||
ctrl.renderingCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,18 +285,18 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
|
||||
function addTimeAxis(options) {
|
||||
var ticks = elem.width() / 100;
|
||||
var min = _.isUndefined(scope.range.from) ? null : scope.range.from.valueOf();
|
||||
var max = _.isUndefined(scope.range.to) ? null : scope.range.to.valueOf();
|
||||
var min = _.isUndefined(ctrl.range.from) ? null : ctrl.range.from.valueOf();
|
||||
var max = _.isUndefined(ctrl.range.to) ? null : ctrl.range.to.valueOf();
|
||||
|
||||
options.xaxis = {
|
||||
timezone: dashboard.timezone,
|
||||
show: scope.panel['x-axis'],
|
||||
show: panel['x-axis'],
|
||||
mode: "time",
|
||||
min: min,
|
||||
max: max,
|
||||
label: "Datetime",
|
||||
ticks: ticks,
|
||||
timeformat: time_format(scope.interval, ticks, min, max),
|
||||
timeformat: time_format(ctrl.interval, ticks, min, max),
|
||||
};
|
||||
}
|
||||
|
||||
@ -361,11 +361,11 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
function configureAxisOptions(data, options) {
|
||||
var defaults = {
|
||||
position: 'left',
|
||||
show: scope.panel['y-axis'],
|
||||
min: scope.panel.grid.leftMin,
|
||||
show: panel['y-axis'],
|
||||
min: panel.grid.leftMin,
|
||||
index: 1,
|
||||
logBase: scope.panel.grid.leftLogBase || 1,
|
||||
max: scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.leftMax,
|
||||
logBase: panel.grid.leftLogBase || 1,
|
||||
max: panel.percentage && panel.stack ? 100 : panel.grid.leftMax,
|
||||
};
|
||||
|
||||
options.yaxes.push(defaults);
|
||||
@ -373,18 +373,18 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
if (_.findWhere(data, {yaxis: 2})) {
|
||||
var secondY = _.clone(defaults);
|
||||
secondY.index = 2,
|
||||
secondY.logBase = scope.panel.grid.rightLogBase || 1,
|
||||
secondY.logBase = panel.grid.rightLogBase || 1,
|
||||
secondY.position = 'right';
|
||||
secondY.min = scope.panel.grid.rightMin;
|
||||
secondY.max = scope.panel.percentage && scope.panel.stack ? 100 : scope.panel.grid.rightMax;
|
||||
secondY.min = panel.grid.rightMin;
|
||||
secondY.max = panel.percentage && panel.stack ? 100 : panel.grid.rightMax;
|
||||
options.yaxes.push(secondY);
|
||||
|
||||
applyLogScale(options.yaxes[1], data);
|
||||
configureAxisMode(options.yaxes[1], scope.panel.percentage && scope.panel.stack ? "percent" : scope.panel.y_formats[1]);
|
||||
configureAxisMode(options.yaxes[1], panel.percentage && panel.stack ? "percent" : panel.y_formats[1]);
|
||||
}
|
||||
|
||||
applyLogScale(options.yaxes[0], data);
|
||||
configureAxisMode(options.yaxes[0], scope.panel.percentage && scope.panel.stack ? "percent" : scope.panel.y_formats[0]);
|
||||
configureAxisMode(options.yaxes[0], panel.percentage && panel.stack ? "percent" : panel.y_formats[0]);
|
||||
}
|
||||
|
||||
function applyLogScale(axis, data) {
|
||||
@ -463,18 +463,18 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
url += '&height=' + elem.css('height').replace('px', '');
|
||||
url += '&bgcolor=1f1f1f'; // @grayDarker & @grafanaPanelBackground
|
||||
url += '&fgcolor=BBBFC2'; // @textColor & @grayLighter
|
||||
url += scope.panel.stack ? '&areaMode=stacked' : '';
|
||||
url += scope.panel.fill !== 0 ? ('&areaAlpha=' + (scope.panel.fill/10).toFixed(1)) : '';
|
||||
url += scope.panel.linewidth !== 0 ? '&lineWidth=' + scope.panel.linewidth : '';
|
||||
url += scope.panel.legend.show ? '&hideLegend=false' : '&hideLegend=true';
|
||||
url += scope.panel.grid.leftMin !== null ? '&yMin=' + scope.panel.grid.leftMin : '';
|
||||
url += scope.panel.grid.leftMax !== null ? '&yMax=' + scope.panel.grid.leftMax : '';
|
||||
url += scope.panel.grid.rightMin !== null ? '&yMin=' + scope.panel.grid.rightMin : '';
|
||||
url += scope.panel.grid.rightMax !== null ? '&yMax=' + scope.panel.grid.rightMax : '';
|
||||
url += scope.panel['x-axis'] ? '' : '&hideAxes=true';
|
||||
url += scope.panel['y-axis'] ? '' : '&hideYAxis=true';
|
||||
url += panel.stack ? '&areaMode=stacked' : '';
|
||||
url += panel.fill !== 0 ? ('&areaAlpha=' + (panel.fill/10).toFixed(1)) : '';
|
||||
url += panel.linewidth !== 0 ? '&lineWidth=' + panel.linewidth : '';
|
||||
url += panel.legend.show ? '&hideLegend=false' : '&hideLegend=true';
|
||||
url += panel.grid.leftMin !== null ? '&yMin=' + panel.grid.leftMin : '';
|
||||
url += panel.grid.leftMax !== null ? '&yMax=' + panel.grid.leftMax : '';
|
||||
url += panel.grid.rightMin !== null ? '&yMin=' + panel.grid.rightMin : '';
|
||||
url += panel.grid.rightMax !== null ? '&yMax=' + panel.grid.rightMax : '';
|
||||
url += panel['x-axis'] ? '' : '&hideAxes=true';
|
||||
url += panel['y-axis'] ? '' : '&hideYAxis=true';
|
||||
|
||||
switch(scope.panel.y_formats[0]) {
|
||||
switch(panel.y_formats[0]) {
|
||||
case 'bytes':
|
||||
url += '&yUnitSystem=binary';
|
||||
break;
|
||||
@ -507,7 +507,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(scope.panel.nullPointMode) {
|
||||
switch(panel.nullPointMode) {
|
||||
case 'connected':
|
||||
url += '&lineMode=connected';
|
||||
break;
|
||||
@ -518,7 +518,7 @@ function (angular, $, moment, _, kbn, GraphTooltip) {
|
||||
break;
|
||||
}
|
||||
|
||||
url += scope.panel.steppedLine ? '&lineMode=staircase' : '';
|
||||
url += panel.steppedLine ? '&lineMode=staircase' : '';
|
||||
|
||||
elem.html('<img src="' + url + '"></img>');
|
||||
}
|
||||
|
292
public/app/plugins/panel/graph/graph_ctrl.ts
Normal file
292
public/app/plugins/panel/graph/graph_ctrl.ts
Normal file
@ -0,0 +1,292 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import moment from 'moment';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import _ from 'lodash';
|
||||
import TimeSeries from '../../../core/time_series2';
|
||||
import * as fileExport from '../../../core/utils/file_export';
|
||||
import {MetricsPanelCtrl} from '../../../features/panel/panel';
|
||||
|
||||
var panelDefaults = {
|
||||
// datasource name, null = default datasource
|
||||
datasource: null,
|
||||
// sets client side (flot) or native graphite png renderer (png)
|
||||
renderer: 'flot',
|
||||
// Show/hide the x-axis
|
||||
'x-axis' : true,
|
||||
// Show/hide y-axis
|
||||
'y-axis' : true,
|
||||
// y axis formats, [left axis,right axis]
|
||||
y_formats : ['short', 'short'],
|
||||
// grid options
|
||||
grid : {
|
||||
leftLogBase: 1,
|
||||
leftMax: null,
|
||||
rightMax: null,
|
||||
leftMin: null,
|
||||
rightMin: null,
|
||||
rightLogBase: 1,
|
||||
threshold1: null,
|
||||
threshold2: null,
|
||||
threshold1Color: 'rgba(216, 200, 27, 0.27)',
|
||||
threshold2Color: 'rgba(234, 112, 112, 0.22)'
|
||||
},
|
||||
// show/hide lines
|
||||
lines : true,
|
||||
// fill factor
|
||||
fill : 1,
|
||||
// line width in pixels
|
||||
linewidth : 2,
|
||||
// show hide points
|
||||
points : false,
|
||||
// point radius in pixels
|
||||
pointradius : 5,
|
||||
// show hide bars
|
||||
bars : false,
|
||||
// enable/disable stacking
|
||||
stack : false,
|
||||
// stack percentage mode
|
||||
percentage : false,
|
||||
// legend options
|
||||
legend: {
|
||||
show: true, // disable/enable legend
|
||||
values: false, // disable/enable legend values
|
||||
min: false,
|
||||
max: false,
|
||||
current: false,
|
||||
total: false,
|
||||
avg: false
|
||||
},
|
||||
// how null points should be handled
|
||||
nullPointMode : 'connected',
|
||||
// staircase line mode
|
||||
steppedLine: false,
|
||||
// tooltip options
|
||||
tooltip : {
|
||||
value_type: 'cumulative',
|
||||
shared: true,
|
||||
},
|
||||
// time overrides
|
||||
timeFrom: null,
|
||||
timeShift: null,
|
||||
// metric queries
|
||||
targets: [{}],
|
||||
// series color overrides
|
||||
aliasColors: {},
|
||||
// other style overrides
|
||||
seriesOverrides: [],
|
||||
};
|
||||
|
||||
class GraphCtrl extends MetricsPanelCtrl {
|
||||
hiddenSeries: any = {};
|
||||
seriesList: any = [];
|
||||
logScales: any;
|
||||
unitFormats: any;
|
||||
annotationsPromise: any;
|
||||
datapointsCount: number;
|
||||
datapointsOutside: boolean;
|
||||
datapointsWarning: boolean;
|
||||
colors: any = [];
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $injector, private annotationsSrv) {
|
||||
super($scope, $injector);
|
||||
|
||||
_.defaults(this.panel, panelDefaults);
|
||||
_.defaults(this.panel.tooltip, panelDefaults.tooltip);
|
||||
_.defaults(this.panel.grid, panelDefaults.grid);
|
||||
_.defaults(this.panel.legend, panelDefaults.legend);
|
||||
|
||||
this.colors = $scope.$root.colors;
|
||||
}
|
||||
|
||||
initEditMode() {
|
||||
super.initEditMode();
|
||||
|
||||
this.icon = "fa fa-bar-chart";
|
||||
this.addEditorTab('Axes & Grid', 'public/app/plugins/panel/graph/axisEditor.html');
|
||||
this.addEditorTab('Display Styles', 'public/app/plugins/panel/graph/styleEditor.html');
|
||||
|
||||
// $scope.panelMeta.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
|
||||
// $scope.panelMeta.addExtendedMenuItem('Export CSV', '', 'exportCsv()');
|
||||
// $scope.panelMeta.addExtendedMenuItem('Toggle legend', '', 'toggleLegend()');
|
||||
//
|
||||
this.logScales = {
|
||||
'linear': 1,
|
||||
'log (base 2)': 2,
|
||||
'log (base 10)': 10,
|
||||
'log (base 32)': 32,
|
||||
'log (base 1024)': 1024
|
||||
};
|
||||
this.unitFormats = kbn.getUnitFormats();
|
||||
}
|
||||
|
||||
setUnitFormat(axis, subItem) {
|
||||
this.panel.y_formats[axis] = subItem.value;
|
||||
this.render();
|
||||
}
|
||||
|
||||
refreshData(datasource) {
|
||||
this.annotationsPromise = this.annotationsSrv.getAnnotations(this.dashboard);
|
||||
|
||||
return this.issueQueries()
|
||||
.then(res => this.dataHandler(res))
|
||||
.catch(err => {
|
||||
this.seriesList = [];
|
||||
this.render([]);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
zoomOut(evt) {
|
||||
this.publishAppEvent('zoom-out', evt);
|
||||
}
|
||||
|
||||
loadSnapshot(snapshotData) {
|
||||
this.updateTimeRange();
|
||||
this.annotationsPromise = this.annotationsSrv.getAnnotations(this.dashboard);
|
||||
this.dataHandler(snapshotData);
|
||||
}
|
||||
|
||||
dataHandler(results) {
|
||||
// png renderer returns just a url
|
||||
if (_.isString(results)) {
|
||||
this.render(results);
|
||||
return;
|
||||
}
|
||||
|
||||
this.datapointsWarning = false;
|
||||
this.datapointsCount = 0;
|
||||
this.datapointsOutside = false;
|
||||
this.seriesList = _.map(results.data, (series, i) => this.seriesHandler(series, i));
|
||||
this.datapointsWarning = this.datapointsCount === 0 || this.datapointsOutside;
|
||||
|
||||
this.annotationsPromise.then(annotations => {
|
||||
this.loading = false;
|
||||
this.seriesList.annotations = annotations;
|
||||
this.render(this.seriesList);
|
||||
}, () => {
|
||||
this.loading = false;
|
||||
this.render(this.seriesList);
|
||||
});
|
||||
};
|
||||
|
||||
seriesHandler(seriesData, index) {
|
||||
var datapoints = seriesData.datapoints;
|
||||
var alias = seriesData.target;
|
||||
var colorIndex = index % this.colors.length;
|
||||
var color = this.panel.aliasColors[alias] || this.colors[colorIndex];
|
||||
|
||||
var series = new TimeSeries({
|
||||
datapoints: datapoints,
|
||||
alias: alias,
|
||||
color: color,
|
||||
});
|
||||
|
||||
if (datapoints && datapoints.length > 0) {
|
||||
var last = moment.utc(datapoints[datapoints.length - 1][1]);
|
||||
var from = moment.utc(this.range.from);
|
||||
if (last - from < -10000) {
|
||||
this.datapointsOutside = true;
|
||||
}
|
||||
|
||||
this.datapointsCount += datapoints.length;
|
||||
}
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
render(data?: any) {
|
||||
this.broadcastRender(data);
|
||||
}
|
||||
|
||||
changeSeriesColor(series, color) {
|
||||
series.color = color;
|
||||
this.panel.aliasColors[series.alias] = series.color;
|
||||
this.render();
|
||||
}
|
||||
|
||||
toggleSeries(serie, event) {
|
||||
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
||||
if (this.hiddenSeries[serie.alias]) {
|
||||
delete this.hiddenSeries[serie.alias];
|
||||
} else {
|
||||
this.hiddenSeries[serie.alias] = true;
|
||||
}
|
||||
} else {
|
||||
this.toggleSeriesExclusiveMode(serie);
|
||||
}
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
toggleSeriesExclusiveMode (serie) {
|
||||
var hidden = this.hiddenSeries;
|
||||
|
||||
if (hidden[serie.alias]) {
|
||||
delete hidden[serie.alias];
|
||||
}
|
||||
|
||||
// check if every other series is hidden
|
||||
var alreadyExclusive = _.every(this.seriesList, value => {
|
||||
if (value.alias === serie.alias) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hidden[value.alias];
|
||||
});
|
||||
|
||||
if (alreadyExclusive) {
|
||||
// remove all hidden series
|
||||
_.each(this.seriesList, value => {
|
||||
delete this.hiddenSeries[value.alias];
|
||||
});
|
||||
} else {
|
||||
// hide all but this serie
|
||||
_.each(this.seriesList, value => {
|
||||
if (value.alias === serie.alias) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hiddenSeries[value.alias] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
toggleYAxis(info) {
|
||||
var override = _.findWhere(this.panel.seriesOverrides, { alias: info.alias });
|
||||
if (!override) {
|
||||
override = { alias: info.alias };
|
||||
this.panel.seriesOverrides.push(override);
|
||||
}
|
||||
override.yaxis = info.yaxis === 2 ? 1 : 2;
|
||||
this.render();
|
||||
};
|
||||
|
||||
addSeriesOverride(override) {
|
||||
this.panel.seriesOverrides.push(override || {});
|
||||
}
|
||||
|
||||
removeSeriesOverride(override) {
|
||||
this.panel.seriesOverrides = _.without(this.panel.seriesOverrides, override);
|
||||
this.render();
|
||||
}
|
||||
|
||||
// Called from panel menu
|
||||
toggleLegend() {
|
||||
this.panel.legend.show = !this.panel.legend.show;
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
legendValuesOptionChanged() {
|
||||
var legend = this.panel.legend;
|
||||
legend.values = legend.min || legend.max || legend.avg || legend.current || legend.total;
|
||||
this.render();
|
||||
}
|
||||
|
||||
exportCsv() {
|
||||
fileExport.exportSeriesListToCsv(this.seriesList);
|
||||
}
|
||||
}
|
||||
|
||||
export {GraphCtrl}
|
@ -6,6 +6,8 @@ function ($) {
|
||||
|
||||
function GraphTooltip(elem, dashboard, scope, getSeriesFn) {
|
||||
var self = this;
|
||||
var ctrl = scope.ctrl;
|
||||
var panel = ctrl.panel;
|
||||
|
||||
var $tooltip = $('<div id="tooltip">');
|
||||
|
||||
@ -47,12 +49,12 @@ function ($) {
|
||||
for (i = 0; i < seriesList.length; i++) {
|
||||
series = seriesList[i];
|
||||
|
||||
if (!series.data.length || (scope.panel.legend.hideEmpty && series.allIsNull)) {
|
||||
if (!series.data.length || (panel.legend.hideEmpty && series.allIsNull)) {
|
||||
results.push({ hidden: true });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!series.data.length || (scope.panel.legend.hideZero && series.allIsZero)) {
|
||||
if (!series.data.length || (panel.legend.hideZero && series.allIsZero)) {
|
||||
results.push({ hidden: true });
|
||||
continue;
|
||||
}
|
||||
@ -61,7 +63,7 @@ function ($) {
|
||||
results.time = series.data[hoverIndex][0];
|
||||
|
||||
if (series.stack) {
|
||||
if (scope.panel.tooltip.value_type === 'individual') {
|
||||
if (panel.tooltip.value_type === 'individual') {
|
||||
value = series.data[hoverIndex][1];
|
||||
} else if (!series.stack) {
|
||||
value = series.data[hoverIndex][1];
|
||||
@ -89,7 +91,7 @@ function ($) {
|
||||
};
|
||||
|
||||
elem.mouseleave(function () {
|
||||
if (scope.panel.tooltip.shared) {
|
||||
if (panel.tooltip.shared) {
|
||||
var plot = elem.data().plot;
|
||||
if (plot) {
|
||||
$tooltip.detach();
|
||||
@ -98,7 +100,7 @@ function ($) {
|
||||
}
|
||||
|
||||
if (dashboard.sharedCrosshair) {
|
||||
scope.appEvent('clearCrosshair');
|
||||
ctrl.publishAppEvent('clearCrosshair');
|
||||
}
|
||||
});
|
||||
|
||||
@ -108,15 +110,15 @@ function ($) {
|
||||
var seriesList = getSeriesFn();
|
||||
var group, value, absoluteTime, relativeTime, hoverInfo, i, series, seriesHtml;
|
||||
|
||||
if(dashboard.sharedCrosshair){
|
||||
scope.appEvent('setCrosshair', { pos: pos, scope: scope });
|
||||
if (dashboard.sharedCrosshair) {
|
||||
ctrl.publishAppEvent('setCrosshair', { pos: pos, scope: scope });
|
||||
}
|
||||
|
||||
if (seriesList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (scope.panel.tooltip.shared) {
|
||||
if (panel.tooltip.shared) {
|
||||
plot.unhighlight();
|
||||
|
||||
var seriesHoverInfo = self.getMultiSeriesPlotHoverInfo(plotData, pos);
|
||||
@ -153,7 +155,7 @@ function ($) {
|
||||
group = '<div class="graph-tooltip-list-item"><div class="graph-tooltip-series-name">';
|
||||
group += '<i class="fa fa-minus" style="color:' + item.series.color +';"></i> ' + series.label + ':</div>';
|
||||
|
||||
if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual') {
|
||||
if (panel.stack && panel.tooltip.value_type === 'individual') {
|
||||
value = item.datapoint[1] - item.datapoint[2];
|
||||
}
|
||||
else {
|
||||
|
3
public/app/plugins/panel/graph/module.d.ts
vendored
3
public/app/plugins/panel/graph/module.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
declare var panel: any;
|
||||
declare var GraphCtrl: any;
|
||||
export {panel, GraphCtrl};
|
@ -1,25 +1,22 @@
|
||||
<grafana-panel>
|
||||
|
||||
<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
|
||||
<div class="graph-canvas-wrapper">
|
||||
|
||||
<div ng-if="datapointsWarning" class="datapoints-warning">
|
||||
<span class="small" ng-show="!datapointsCount">
|
||||
No datapoints <tip>No datapoints returned from metric query</tip>
|
||||
</span>
|
||||
<span class="small" ng-show="datapointsOutside">Datapoints outside time range <tip>Can be caused by timezone mismatch between browser and graphite server</tip></span>
|
||||
</div>
|
||||
|
||||
<div grafana-graph class="histogram-chart" ng-dblclick="zoomOut()">
|
||||
</div>
|
||||
<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
|
||||
<div class="graph-canvas-wrapper">
|
||||
|
||||
<div ng-if="datapointsWarning" class="datapoints-warning">
|
||||
<span class="small" ng-show="!datapointsCount">
|
||||
No datapoints <tip>No datapoints returned from metric query</tip>
|
||||
</span>
|
||||
<span class="small" ng-show="datapointsOutside">Datapoints outside time range <tip>Can be caused by timezone mismatch between browser and graphite server</tip></span>
|
||||
</div>
|
||||
|
||||
<div grafana-graph class="histogram-chart" ng-dblclick="zoomOut()">
|
||||
</div>
|
||||
|
||||
<div class="graph-legend-wrapper" ng-if="panel.legend.show" graph-legend></div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="graph-legend-wrapper" ng-if="panel.legend.show" graph-legend></div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
</grafana-panel>
|
||||
|
||||
|
||||
|
@ -1,303 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'moment',
|
||||
'app/core/utils/kbn',
|
||||
'app/core/utils/file_export',
|
||||
'app/core/time_series',
|
||||
'app/features/panel/panel_meta',
|
||||
'./seriesOverridesCtrl',
|
||||
'./graph',
|
||||
'./legend',
|
||||
],
|
||||
function (angular, _, moment, kbn, fileExport, TimeSeries, PanelMeta) {
|
||||
'use strict';
|
||||
|
||||
/** @ngInject */
|
||||
function GraphCtrl($scope, $rootScope, panelSrv, annotationsSrv, panelHelper) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
panelName: 'Graph',
|
||||
editIcon: "fa fa-bar-chart",
|
||||
fullscreen: true,
|
||||
metricsEditor: true,
|
||||
});
|
||||
|
||||
$scope.panelMeta.addEditorTab('Axes & Grid', 'app/plugins/panel/graph/axisEditor.html');
|
||||
$scope.panelMeta.addEditorTab('Display Styles', 'app/plugins/panel/graph/styleEditor.html');
|
||||
$scope.panelMeta.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
|
||||
|
||||
$scope.panelMeta.addExtendedMenuItem('Export CSV', '', 'exportCsv()');
|
||||
$scope.panelMeta.addExtendedMenuItem('Toggle legend', '', 'toggleLegend()');
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
// datasource name, null = default datasource
|
||||
datasource: null,
|
||||
// sets client side (flot) or native graphite png renderer (png)
|
||||
renderer: 'flot',
|
||||
// Show/hide the x-axis
|
||||
'x-axis' : true,
|
||||
// Show/hide y-axis
|
||||
'y-axis' : true,
|
||||
// y axis formats, [left axis,right axis]
|
||||
y_formats : ['short', 'short'],
|
||||
// grid options
|
||||
grid : {
|
||||
leftLogBase: 1,
|
||||
leftMax: null,
|
||||
rightMax: null,
|
||||
leftMin: null,
|
||||
rightMin: null,
|
||||
rightLogBase: 1,
|
||||
threshold1: null,
|
||||
threshold2: null,
|
||||
threshold1Color: 'rgba(216, 200, 27, 0.27)',
|
||||
threshold2Color: 'rgba(234, 112, 112, 0.22)'
|
||||
},
|
||||
// show/hide lines
|
||||
lines : true,
|
||||
// fill factor
|
||||
fill : 1,
|
||||
// line width in pixels
|
||||
linewidth : 2,
|
||||
// show hide points
|
||||
points : false,
|
||||
// point radius in pixels
|
||||
pointradius : 5,
|
||||
// show hide bars
|
||||
bars : false,
|
||||
// enable/disable stacking
|
||||
stack : false,
|
||||
// stack percentage mode
|
||||
percentage : false,
|
||||
// legend options
|
||||
legend: {
|
||||
show: true, // disable/enable legend
|
||||
values: false, // disable/enable legend values
|
||||
min: false,
|
||||
max: false,
|
||||
current: false,
|
||||
total: false,
|
||||
avg: false
|
||||
},
|
||||
// how null points should be handled
|
||||
nullPointMode : 'connected',
|
||||
// staircase line mode
|
||||
steppedLine: false,
|
||||
// tooltip options
|
||||
tooltip : {
|
||||
value_type: 'cumulative',
|
||||
shared: true,
|
||||
},
|
||||
// time overrides
|
||||
timeFrom: null,
|
||||
timeShift: null,
|
||||
// metric queries
|
||||
targets: [{}],
|
||||
// series color overrides
|
||||
aliasColors: {},
|
||||
// other style overrides
|
||||
seriesOverrides: [],
|
||||
};
|
||||
|
||||
_.defaults($scope.panel,_d);
|
||||
_.defaults($scope.panel.tooltip, _d.tooltip);
|
||||
_.defaults($scope.panel.annotate, _d.annotate);
|
||||
_.defaults($scope.panel.grid, _d.grid);
|
||||
_.defaults($scope.panel.legend, _d.legend);
|
||||
|
||||
$scope.logScales = {'linear': 1, 'log (base 2)': 2, 'log (base 10)': 10, 'log (base 32)': 32, 'log (base 1024)': 1024};
|
||||
|
||||
$scope.hiddenSeries = {};
|
||||
$scope.seriesList = [];
|
||||
$scope.unitFormats = kbn.getUnitFormats();
|
||||
|
||||
$scope.setUnitFormat = function(axis, subItem) {
|
||||
$scope.panel.y_formats[axis] = subItem.value;
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.refreshData = function(datasource) {
|
||||
panelHelper.updateTimeRange($scope);
|
||||
|
||||
$scope.annotationsPromise = annotationsSrv.getAnnotations($scope.dashboard);
|
||||
|
||||
return panelHelper.issueMetricQuery($scope, datasource)
|
||||
.then($scope.dataHandler, function(err) {
|
||||
$scope.seriesList = [];
|
||||
$scope.render([]);
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.zoomOut = function(evt) {
|
||||
$scope.appEvent('zoom-out', evt);
|
||||
};
|
||||
|
||||
$scope.loadSnapshot = function(snapshotData) {
|
||||
panelHelper.updateTimeRange($scope);
|
||||
$scope.annotationsPromise = annotationsSrv.getAnnotations($scope.dashboard);
|
||||
$scope.dataHandler(snapshotData);
|
||||
};
|
||||
|
||||
$scope.dataHandler = function(results) {
|
||||
// png renderer returns just a url
|
||||
if (_.isString(results)) {
|
||||
$scope.render(results);
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.datapointsWarning = false;
|
||||
$scope.datapointsCount = 0;
|
||||
$scope.datapointsOutside = false;
|
||||
|
||||
$scope.seriesList = _.map(results.data, $scope.seriesHandler);
|
||||
|
||||
$scope.datapointsWarning = $scope.datapointsCount === 0 || $scope.datapointsOutside;
|
||||
|
||||
$scope.annotationsPromise
|
||||
.then(function(annotations) {
|
||||
$scope.panelMeta.loading = false;
|
||||
$scope.seriesList.annotations = annotations;
|
||||
$scope.render($scope.seriesList);
|
||||
}, function() {
|
||||
$scope.panelMeta.loading = false;
|
||||
$scope.render($scope.seriesList);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.seriesHandler = function(seriesData, index) {
|
||||
var datapoints = seriesData.datapoints;
|
||||
var alias = seriesData.target;
|
||||
var colorIndex = index % $rootScope.colors.length;
|
||||
var color = $scope.panel.aliasColors[alias] || $rootScope.colors[colorIndex];
|
||||
|
||||
var series = new TimeSeries({
|
||||
datapoints: datapoints,
|
||||
alias: alias,
|
||||
color: color,
|
||||
});
|
||||
|
||||
if (datapoints && datapoints.length > 0) {
|
||||
var last = moment.utc(datapoints[datapoints.length - 1][1]);
|
||||
var from = moment.utc($scope.range.from);
|
||||
if (last - from < -10000) {
|
||||
$scope.datapointsOutside = true;
|
||||
}
|
||||
|
||||
$scope.datapointsCount += datapoints.length;
|
||||
}
|
||||
|
||||
return series;
|
||||
};
|
||||
|
||||
$scope.render = function(data) {
|
||||
panelHelper.broadcastRender($scope, data);
|
||||
};
|
||||
|
||||
$scope.changeSeriesColor = function(series, color) {
|
||||
series.color = color;
|
||||
$scope.panel.aliasColors[series.alias] = series.color;
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.toggleSeries = function(serie, event) {
|
||||
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
||||
if ($scope.hiddenSeries[serie.alias]) {
|
||||
delete $scope.hiddenSeries[serie.alias];
|
||||
}
|
||||
else {
|
||||
$scope.hiddenSeries[serie.alias] = true;
|
||||
}
|
||||
} else {
|
||||
$scope.toggleSeriesExclusiveMode(serie);
|
||||
}
|
||||
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.toggleSeriesExclusiveMode = function(serie) {
|
||||
var hidden = $scope.hiddenSeries;
|
||||
|
||||
if (hidden[serie.alias]) {
|
||||
delete hidden[serie.alias];
|
||||
}
|
||||
|
||||
// check if every other series is hidden
|
||||
var alreadyExclusive = _.every($scope.seriesList, function(value) {
|
||||
if (value.alias === serie.alias) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hidden[value.alias];
|
||||
});
|
||||
|
||||
if (alreadyExclusive) {
|
||||
// remove all hidden series
|
||||
_.each($scope.seriesList, function(value) {
|
||||
delete $scope.hiddenSeries[value.alias];
|
||||
});
|
||||
}
|
||||
else {
|
||||
// hide all but this serie
|
||||
_.each($scope.seriesList, function(value) {
|
||||
if (value.alias === serie.alias) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.hiddenSeries[value.alias] = true;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleYAxis = function(info) {
|
||||
var override = _.findWhere($scope.panel.seriesOverrides, { alias: info.alias });
|
||||
if (!override) {
|
||||
override = { alias: info.alias };
|
||||
$scope.panel.seriesOverrides.push(override);
|
||||
}
|
||||
override.yaxis = info.yaxis === 2 ? 1 : 2;
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.addSeriesOverride = function(override) {
|
||||
$scope.panel.seriesOverrides.push(override || {});
|
||||
};
|
||||
|
||||
$scope.removeSeriesOverride = function(override) {
|
||||
$scope.panel.seriesOverrides = _.without($scope.panel.seriesOverrides, override);
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
// Called from panel menu
|
||||
$scope.toggleLegend = function() {
|
||||
$scope.panel.legend.show = !$scope.panel.legend.show;
|
||||
$scope.get_data();
|
||||
};
|
||||
|
||||
$scope.legendValuesOptionChanged = function() {
|
||||
var legend = $scope.panel.legend;
|
||||
legend.values = legend.min || legend.max || legend.avg || legend.current || legend.total;
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.exportCsv = function() {
|
||||
fileExport.exportSeriesListToCsv($scope.seriesList);
|
||||
};
|
||||
|
||||
panelSrv.init($scope);
|
||||
}
|
||||
|
||||
function graphPanelDirective() {
|
||||
return {
|
||||
controller: GraphCtrl,
|
||||
templateUrl: 'app/plugins/panel/graph/module.html',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
GraphCtrl: GraphCtrl,
|
||||
panel: graphPanelDirective,
|
||||
};
|
||||
});
|
15
public/app/plugins/panel/graph/module.ts
Normal file
15
public/app/plugins/panel/graph/module.ts
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
import {PanelDirective} from '../../../features/panel/panel';
|
||||
import {GraphCtrl} from './graph_ctrl';
|
||||
|
||||
import './graph';
|
||||
|
||||
class GraphPanel extends PanelDirective {
|
||||
controller = GraphCtrl;
|
||||
templateUrl = 'public/app/plugins/panel/graph/module.html';
|
||||
}
|
||||
|
||||
export {
|
||||
GraphPanel,
|
||||
GraphPanel as Panel
|
||||
}
|
@ -1,60 +1,60 @@
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>Chart Options</h5>
|
||||
<editor-opt-bool text="Bars" model="panel.bars" change="render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Lines" model="panel.lines" change="render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Points" model="panel.points" change="render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Bars" model="ctrl.panel.bars" change="ctrl.render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Lines" model="ctrl.panel.lines" change="ctrl.render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Points" model="ctrl.panel.points" change="ctrl.render()"></editor-opt-bool>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h5>Line options</h5>
|
||||
<div class="editor-option" ng-show="panel.lines">
|
||||
<div class="editor-option" ng-show="ctrl.panel.lines">
|
||||
<label class="small">Line Fill</label>
|
||||
<select class="input-mini" ng-model="panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="render()"></select>
|
||||
<select class="input-mini" ng-model="ctrl.panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
<div class="editor-option" ng-show="panel.lines">
|
||||
<div class="editor-option" ng-show="ctrl.panel.lines">
|
||||
<label class="small">Line Width</label>
|
||||
<select class="input-mini" ng-model="panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="render()"></select>
|
||||
<select class="input-mini" ng-model="ctrl.panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
<div class="editor-option" ng-show="panel.points">
|
||||
<div class="editor-option" ng-show="ctrl.panel.points">
|
||||
<label class="small">Point Radius</label>
|
||||
<select class="input-mini" ng-model="panel.pointradius" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10]" ng-change="render()"></select>
|
||||
<select class="input-mini" ng-model="ctrl.panel.pointradius" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10]" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
<div class="editor-option">
|
||||
<label class="small">Null point mode<tip>Define how null values should be drawn</tip></label>
|
||||
<select class="input-medium" ng-model="panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="render()"></select>
|
||||
<select class="input-medium" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['connected', 'null', 'null as zero']" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
|
||||
<editor-opt-bool text="Staircase line" model="panel.steppedLine" change="render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Staircase line" model="ctrl.panel.steppedLine" change="ctrl.render()"></editor-opt-bool>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h5>Multiple Series</h5>
|
||||
|
||||
<editor-opt-bool text="Stack" model="panel.stack" change="render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Percent" model="panel.percentage" change="render()" tip="Stack as a percentage of total"></editor-opt-bool>
|
||||
<editor-opt-bool text="Stack" model="ctrl.panel.stack" change="ctrl.render()"></editor-opt-bool>
|
||||
<editor-opt-bool text="Percent" model="ctrl.panel.percentage" change="ctrl.render()" tip="Stack as a percentage of total"></editor-opt-bool>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h5>Rendering</h5>
|
||||
<div class="editor-option">
|
||||
<label class="small">Flot <tip>client side</tip></label>
|
||||
<input type="radio" class="input-small" ng-model="panel.renderer" value="flot" ng-change="get_data()" />
|
||||
<input type="radio" class="input-small" ng-model="ctrl.panel.renderer" value="flot" ng-change="ctrl.refresh()" />
|
||||
</div>
|
||||
<div class="editor-option">
|
||||
<label class="small">Graphite PNG <tip>server side</tip></label>
|
||||
<input type="radio" class="input-small" ng-model="panel.renderer" value="png" ng-change="get_data()" />
|
||||
<input type="radio" class="input-small" ng-model="ctrl.panel.renderer" value="png" ng-change="ctr.refresh()" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h5>Tooltip</h5>
|
||||
<editor-opt-bool
|
||||
text="All series" model="panel.tooltip.shared" change="render()"
|
||||
text="All series" model="ctrl.panel.tooltip.shared" change="ctrl.render()"
|
||||
tip="Show all series on same tooltip and a x croshair to help follow all series">
|
||||
</editor-opt-bool>
|
||||
<div class="editor-option" ng-show="panel.stack">
|
||||
<div class="editor-option" ng-show="ctrl.panel.stack">
|
||||
<label class="small">Stacked Values <tip>How should the values in stacked charts to be calculated?</tip></label>
|
||||
<select class="input-small" ng-model="panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="render()"></select>
|
||||
<select class="input-small" ng-model="ctrl.panel.tooltip.value_type" ng-options="f for f in ['cumulative','individual']" ng-change="ctrl.render()"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -64,10 +64,10 @@
|
||||
<div class="section">
|
||||
<h5>Series specific overrides <tip>Regex match example: /server[0-3]/i </tip></h5>
|
||||
<div class="tight-form-container">
|
||||
<div class="tight-form" ng-repeat="override in panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
|
||||
<div class="tight-form" ng-repeat="override in ctrl.panel.seriesOverrides" ng-controller="SeriesOverridesCtrl">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
<i class="fa fa-remove pointer" ng-click="removeSeriesOverride(override)"></i>
|
||||
<i class="fa fa-remove pointer" ng-click="ctrl.removeSeriesOverride(override)"></i>
|
||||
</li>
|
||||
|
||||
<li class="tight-form-item">
|
||||
@ -75,7 +75,7 @@
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="render()" data-min-length=0 data-items=100 class="input-medium tight-form-input" >
|
||||
<input type="text" ng-model="override.alias" bs-typeahead="getSeriesNames" ng-blur="ctrl.render()" data-min-length=0 data-items=100 class="input-medium tight-form-input" >
|
||||
</li>
|
||||
|
||||
<li class="tight-form-item" ng-repeat="option in currentOverrides">
|
||||
@ -95,7 +95,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-inverse" style="margin-top: 20px" ng-click="addSeriesOverride()">
|
||||
<button class="btn btn-inverse" style="margin-top: 20px" ng-click="ctrl.addSeriesOverride()">
|
||||
Add series specific option
|
||||
</button>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user