Commit a1d764bd by Torkel Ödegaard

Merge branch 'master' into valuepanel

Conflicts:
	src/app/components/settings.js
parents 22297be3 61f6bd2c
......@@ -3,8 +3,13 @@
**UI Improvements*
- [Issue #770](https://github.com/grafana/grafana/issues/770). UI: Panel dropdown menu replaced with a new panel menu
**Graph**
- [Issue #877](https://github.com/grafana/grafana/issues/877). Graph: Smart auto decimal precision when using scaled unit formats
- [Issue #850](https://github.com/grafana/grafana/issues/850). Graph: Shared tooltip that shows multiple series & crosshair line, thx @toni-moreno
- [Issue #940](https://github.com/grafana/grafana/issues/940). Graph: New series style override option "Fill below to", useful to visualize max & min as a shadow for the mean
**Misc**
- [Issue #938](https://github.com/grafana/grafana/issues/938). Panel: Plugin panels now reside outside of app/panels directory
**Fixes**
- [Issue #925](https://github.com/grafana/grafana/issues/925). Graph: bar width calculation fix for some edge cases (bars would render on top of each other)
......
......@@ -57,7 +57,6 @@ function (angular, $, _, appLevelRequire, config) {
register_fns.factory = $provide.factory;
register_fns.service = $provide.service;
register_fns.filter = $filterProvider.register;
});
var apps_deps = [
......
......@@ -40,6 +40,7 @@ require.config({
'jquery.flot.stackpercent':'../vendor/jquery/jquery.flot.stackpercent',
'jquery.flot.time': '../vendor/jquery/jquery.flot.time',
'jquery.flot.crosshair': '../vendor/jquery/jquery.flot.crosshair',
'jquery.flot.fillbelow': '../vendor/jquery/jquery.flot.fillbelow',
modernizr: '../vendor/modernizr-2.6.1',
......@@ -83,6 +84,7 @@ require.config({
'jquery.flot.stackpercent':['jquery', 'jquery.flot'],
'jquery.flot.time': ['jquery', 'jquery.flot'],
'jquery.flot.crosshair':['jquery', 'jquery.flot'],
'jquery.flot.fillbelow':['jquery', 'jquery.flot'],
'angular-cookies': ['angular'],
'angular-dragdrop': ['jquery', 'angular'],
'angular-loader': ['angular'],
......
......@@ -15,7 +15,10 @@ function (_, crypto) {
var defaults = {
datasources : {},
window_title_prefix : 'Grafana - ',
panels : ['graph', 'text', 'stats'],
panels : {
'graph': { path: 'panels/graph' },
'text': { path: 'panels/text' }
},
plugins : {},
default_route : '/dashboard/file/default.json',
playlist_timespan : "1m",
......@@ -76,7 +79,7 @@ function (_, crypto) {
});
if (settings.plugins.panels) {
settings.panels = _.union(settings.panels, settings.plugins.panels);
_.extend(settings.panels, settings.plugins.panels);
}
if (!settings.plugins.dependencies) {
......
......@@ -9,6 +9,7 @@ function (_, kbn) {
this.datapoints = opts.datapoints;
this.info = opts.info;
this.label = opts.info.alias;
this.id = opts.info.alias;
this.valueFormater = kbn.valueFormats.none;
this.stats = {};
}
......@@ -50,6 +51,8 @@ function (_, kbn) {
if (override.pointradius !== void 0) { this.points.radius = override.pointradius; }
if (override.steppedLine !== void 0) { this.lines.steps = override.steppedLine; }
if (override.zindex !== void 0) { this.zindex = override.zindex; }
if (override.fillBelowTo !== void 0) { this.fillBelowTo = override.fillBelowTo; }
if (override.yaxis !== void 0) {
this.info.yaxis = override.yaxis;
}
......
......@@ -21,7 +21,7 @@ function (angular, $, config, _) {
$timeout) {
$scope.editor = { index: 0 };
$scope.panelNames = config.panels;
$scope.panelNames = _.map(config.panels, function(value, key) { return key; });
var resizeEventTimeout;
this.init = function(dashboardData) {
......@@ -90,21 +90,12 @@ function (angular, $, config, _) {
};
};
$scope.edit_path = function(type) {
var p = $scope.panel_path(type);
if(p) {
return p+'/editor.html';
} else {
return false;
}
$scope.panelEditorPath = function(type) {
return 'app/' + config.panels[type].path + '/editor.html';
};
$scope.panel_path =function(type) {
if(type) {
return 'app/panels/'+type.replace(".","/");
} else {
return false;
}
$scope.pulldownEditorPath = function(type) {
return 'app/panels/'+type+'/editor.html';
};
$scope.showJsonEditor = function(evt, options) {
......
......@@ -201,7 +201,7 @@ function (angular, _, config, gfunc, Parser) {
$scope.targetTextChanged = function() {
parseTarget();
$scope.$parent.get_data();
$scope.get_data();
};
$scope.targetChanged = function() {
......
......@@ -18,5 +18,6 @@ define([
'./templateParamSelector',
'./graphiteSegment',
'./grafanaVersionCheck',
'./dropdown.typeahead',
'./influxdbFuncEditor'
], function () {});
define([
'angular',
'app',
'lodash',
'jquery',
],
function (angular, app, _, $) {
'use strict';
angular
.module('grafana.directives')
.directive('dropdownTypeahead', function($compile) {
var inputTemplate = '<input type="text"'+
' class="grafana-target-segment-input input-medium grafana-target-segment-input"' +
' spellcheck="false" style="display:none"></input>';
var buttonTemplate = '<a class="grafana-target-segment grafana-target-function dropdown-toggle"' +
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
' data-placement="top"><i class="icon-plus"></i></a>';
return {
scope: {
"menuItems": "=dropdownTypeahead",
"dropdownTypeaheadOnSelect": "&dropdownTypeaheadOnSelect"
},
link: function($scope, elem) {
var $input = $(inputTemplate);
var $button = $(buttonTemplate);
$input.appendTo(elem);
$button.appendTo(elem);
var typeaheadValues = _.reduce($scope.menuItems, function(memo, value) {
_.each(value.submenu, function(item) {
memo.push(value.text + ' ' + item.text);
});
return memo;
}, []);
$input.attr('data-provide', 'typeahead');
$input.typeahead({
source: typeaheadValues,
minLength: 1,
items: 10,
updater: function (value) {
var result = {};
_.each($scope.menuItems, function(menuItem, optionIndex) {
_.each(menuItem.submenu, function(submenuItem, valueIndex) {
if (value === (menuItem.text + ' ' + submenuItem.text)) {
result.$item = submenuItem;
result.$optionIndex = optionIndex;
result.$valueIndex = valueIndex;
}
});
});
if (result.$item) {
$scope.$apply(function() {
$scope.dropdownTypeaheadOnSelect(result);
});
}
$input.trigger('blur');
return '';
}
});
$button.click(function() {
$button.hide();
$input.show();
$input.focus();
});
$input.keyup(function() {
elem.toggleClass('open', $input.val() === '');
});
$input.blur(function() {
$input.hide();
$input.val('');
$button.show();
$button.focus();
// clicking the function dropdown menu wont
// work if you remove class at once
setTimeout(function() {
elem.removeClass('open');
}, 200);
});
$compile(elem.contents())($scope);
}
};
});
});
......@@ -177,6 +177,7 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
var series = data[i];
series.applySeriesOverrides(panel.seriesOverrides);
series.data = series.getFlotPairs(panel.nullPointMode, panel.y_formats);
// if hidden remove points and disable stack
if (scope.hiddenSeries[series.info.alias]) {
series.data = [];
......
define([
'angular',
'jquery',
'config',
'./panelMenu',
],
function (angular, $) {
function (angular, $, config) {
'use strict';
angular
......@@ -68,10 +69,12 @@ function (angular, $) {
elem.addClass('ng-cloak');
var panelPath = config.panels[panelType].path;
$scope.require([
'jquery',
'text!panels/'+panelType+'/module.html',
'panels/' + panelType + "/module",
'text!'+panelPath+'/module.html',
panelPath + "/module",
], function ($, moduleTemplate) {
var $module = $(moduleTemplate);
$module.prepend(panelHeader);
......
......@@ -16,6 +16,7 @@ define([
'jquery.flot.time',
'jquery.flot.stack',
'jquery.flot.stackpercent',
'jquery.flot.fillbelow',
'jquery.flot.crosshair'
],
function (angular, app, $, _, kbn, moment, TimeSeries) {
......@@ -340,8 +341,8 @@ function (angular, app, $, _, kbn, moment, TimeSeries) {
$scope.render();
};
$scope.addSeriesOverride = function() {
$scope.panel.seriesOverrides.push({});
$scope.addSeriesOverride = function(override) {
$scope.panel.seriesOverrides.push(override || {});
};
$scope.removeSeriesOverride = function(override) {
......
......@@ -34,6 +34,14 @@ define([
var option = $scope.overrideMenu[optionIndex];
var value = option.values[valueIndex];
$scope.override[option.propertyName] = value;
// automatically disable lines for this series and the fill bellow to series
// can be removed by the user if they still want lines
if (option.propertyName === 'fillBelowTo') {
$scope.override['lines'] = false;
$scope.addSeriesOverride({ alias: value, lines: false });
}
$scope.updateCurrentOverrides();
$scope.render();
};
......@@ -67,6 +75,7 @@ define([
$scope.addOverrideOption('Lines', 'lines', [true, false]);
$scope.addOverrideOption('Line fill', 'fill', [0,1,2,3,4,5,6,7,8,9,10]);
$scope.addOverrideOption('Line width', 'linewidth', [0,1,2,3,4,5,6,7,8,9,10]);
$scope.addOverrideOption('Fill below to', 'fillBelowTo', $scope.getSeriesNames());
$scope.addOverrideOption('Staircase line', 'steppedLine', [true, false]);
$scope.addOverrideOption('Points', 'points', [true, false]);
$scope.addOverrideOption('Points Radius', 'pointradius', [1,2,3,4,5]);
......
......@@ -88,11 +88,10 @@
<i class="pointer icon-remove" ng-click="removeOverride(option)"></i>
{{option.name}}: {{option.value}}
</li>
<li class="dropdown">
<a class="dropdown-toggle grafana-target-segment" data-toggle="dropdown" gf-dropdown="overrideMenu" bs-tooltip="'set option to override'" data-placement="top">
<i class="icon-plus"></i>
</a>
<li class="dropdown" dropdown-typeahead="overrideMenu" dropdown-typeahead-on-select="setOverride($optionIndex, $valueIndex)">
</li>
</ul>
<div class="clearfix"></div>
</div>
......
......@@ -84,7 +84,7 @@
</div>
<div ng-repeat="pulldown in dashboard.nav" ng-controller="SubmenuCtrl" ng-show="editor.index == 4+$index">
<ng-include ng-show="pulldown.enable" src="edit_path(pulldown.type)"></ng-include>
<ng-include ng-show="pulldown.enable" src="pulldownEditorPath(pulldown.type)"></ng-include>
<button ng-hide="pulldown.enable" class="btn" ng-click="pulldown.enable = true">Enable the {{pulldown.type}}</button>
</div>
......
......@@ -17,7 +17,7 @@
</div>
<div ng-show="editorTabs[editor.index] == 'Panel'">
<div ng-include src="edit_path(panel.type)"></div>
<div ng-include src="panelEditorPath(panel.type)"></div>
</div>
<div ng-repeat="tab in panelMeta.editorTabs" ng-show="editorTabs[editor.index] == tab.title">
......
<div>
<div class="row-fluid">
<div class="span4">
<label class="small">Mode</label> <select class="input-medium" ng-model="panel.mode" ng-options="f for f in ['html','markdown','text']"></select>
</div>
<div class="span2" ng-show="panel.mode == 'text'">
<label class="small">Font Size</label> <select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
</div>
</div>
</div>
<div ng-controller='CustomPanelCtrl'>
<h2>Custom panel</h2>
</div>
define([
'angular',
'app',
'lodash',
'require',
],
function (angular, app, _) {
'use strict';
var module = angular.module('grafana.panels.custom', []);
app.useModule(module);
module.controller('CustomPanelCtrl', function($scope, panelSrv) {
$scope.panelMeta = {
description : "Example plugin panel",
};
// set and populate defaults
var _d = {
};
_.defaults($scope.panel, _d);
$scope.init = function() {
panelSrv.init($scope);
};
$scope.init();
});
});
......@@ -70,6 +70,17 @@ define([
});
});
describe('series option overrides, fill below to', function() {
beforeEach(function() {
series.info.alias = 'test';
series.applySeriesOverrides([{ alias: 'test', fillBelowTo: 'min' }]);
});
it('should disable line fill and add fillBelowTo', function() {
expect(series.fillBelowTo).to.be('min');
});
});
describe('series option overrides, pointradius, steppedLine', function() {
beforeEach(function() {
series.info.alias = 'test';
......
......@@ -42,6 +42,7 @@ require.config({
'jquery.flot.stackpercent':'../vendor/jquery/jquery.flot.stackpercent',
'jquery.flot.time': '../vendor/jquery/jquery.flot.time',
'jquery.flot.crosshair': '../vendor/jquery/jquery.flot.crosshair',
'jquery.flot.fillbelow': '../vendor/jquery/jquery.flot.fillbelow',
modernizr: '../vendor/modernizr-2.6.1',
},
......@@ -68,7 +69,6 @@ require.config({
exports: 'Crypto'
},
'jquery-ui': ['jquery'],
'jquery.flot': ['jquery'],
'jquery.flot.pie': ['jquery', 'jquery.flot'],
'jquery.flot.events': ['jquery', 'jquery.flot'],
......@@ -77,6 +77,7 @@ require.config({
'jquery.flot.stackpercent':['jquery', 'jquery.flot'],
'jquery.flot.time': ['jquery', 'jquery.flot'],
'jquery.flot.crosshair':['jquery', 'jquery.flot'],
'jquery.flot.fillbelow':['jquery', 'jquery.flot'],
'angular-route': ['angular'],
'angular-cookies': ['angular'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment