mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tech: rewrite of how the legend is implement, performance increase, and will make future legend enhancements easier
This commit is contained in:
parent
d150bc1e52
commit
e530e4d4bc
@ -46,10 +46,6 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
||||
scope.get_data();
|
||||
});
|
||||
|
||||
scope.$on('toggleLegend', function() {
|
||||
render_panel();
|
||||
});
|
||||
|
||||
// Receive render events
|
||||
scope.$on('render',function(event, renderData) {
|
||||
data = renderData || data;
|
||||
|
@ -1,50 +0,0 @@
|
||||
<section class="graph-legend" ng-class="{'graph-legend-table': panel.legend.alignAsTable}">
|
||||
|
||||
<div class="graph-legend-series" ng-repeat='series in legend'
|
||||
ng-class="{'pull-right': series.yaxis === 2, 'graph-legend-series-hidden': hiddenSeries[series.alias]}">
|
||||
<div class="graph-legend-icon">
|
||||
<i class='icon-minus pointer' ng-style="{color: series.color}" bs-popover="'colorPopup.html'" data-placement="bottom"></i>
|
||||
</div>
|
||||
<div class="graph-legend-alias small">
|
||||
<a ng-click="toggleSeries(series, $event)" data-unique="1" data-placement="{{series.yaxis === 2 ? 'bottomRight' : 'bottomLeft'}}">
|
||||
{{series.alias}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="graph-legend-value current small" ng-show="panel.legend.values && panel.legend.current" ng-bind="series.current"></div>
|
||||
<div class="graph-legend-value min small" ng-show="panel.legend.values && panel.legend.min" ng-bind="series.min"></div>
|
||||
<div class="graph-legend-value max small" ng-show="panel.legend.values && panel.legend.max" ng-bind="series.max"></div>
|
||||
<div class="graph-legend-value total small" ng-show="panel.legend.values && panel.legend.total" ng-bind="series.total"></div>
|
||||
<div class="graph-legend-value avg small" ng-show="panel.legend.values && panel.legend.avg" ng-bind="series.avg"></div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<script type="text/ng-template" id="colorPopup.html">
|
||||
<div class="graph-legend-popover">
|
||||
<a class="close" ng-click="dismiss();" href="">×</a>
|
||||
|
||||
<div class="editor-row small" style="padding-bottom: 0;">
|
||||
<label>Axis:</label>
|
||||
<button ng-click="toggleYAxis(series);dismiss();"
|
||||
class="btn btn-mini"
|
||||
ng-class="{'btn-success': series.yaxis === 1 }">
|
||||
Left
|
||||
</button>
|
||||
<button ng-click="toggleYAxis(series);dismiss();"
|
||||
class="btn btn-mini"
|
||||
ng-class="{'btn-success': series.yaxis === 2 }">
|
||||
Right
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="editor-row">
|
||||
<i ng-repeat="color in colors"
|
||||
class="pointer"
|
||||
ng-class="{'icon-circle-blank': color === series.color,'icon-circle': color !== series.color}"
|
||||
ng-style="{color:color}"
|
||||
ng-click="changeSeriesColor(series, color);dismiss();">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
98
src/app/panels/graph/legend.js
Normal file
98
src/app/panels/graph/legend.js
Normal file
@ -0,0 +1,98 @@
|
||||
define([
|
||||
'angular',
|
||||
'app',
|
||||
'lodash',
|
||||
'kbn',
|
||||
'jquery',
|
||||
'jquery.flot',
|
||||
'jquery.flot.time',
|
||||
],
|
||||
function (angular, app, _, kbn, $) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.panels.graph');
|
||||
|
||||
module.directive('graphLegend', function(popoverSrv) {
|
||||
|
||||
return {
|
||||
link: function(scope, elem) {
|
||||
var $container = $('<section class="graph-legend"></section>');
|
||||
var firstRender = true;
|
||||
var panel = scope.panel;
|
||||
var data;
|
||||
var i;
|
||||
|
||||
scope.$on('render', function(event, renderData) {
|
||||
data = renderData || data;
|
||||
if (data) {
|
||||
render();
|
||||
}
|
||||
});
|
||||
|
||||
function getSeriesIndexForElement(el) {
|
||||
return el.parents('[data-series-index]').data('series-index');
|
||||
}
|
||||
|
||||
function openColorSelector(e) {
|
||||
var el = $(e.currentTarget);
|
||||
var index = getSeriesIndexForElement(el);
|
||||
var seriesInfo = data[index].info;
|
||||
var popoverScope = scope.$new();
|
||||
popoverScope.series = seriesInfo;
|
||||
popoverSrv.show({
|
||||
element: $(':first-child', el),
|
||||
templateUrl: 'app/panels/graph/legend.popover.html',
|
||||
scope: popoverScope
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSeries(e) {
|
||||
var el = $(e.currentTarget);
|
||||
var index = getSeriesIndexForElement(el);
|
||||
var seriesInfo = data[index].info;
|
||||
scope.toggleSeries(seriesInfo, e);
|
||||
}
|
||||
|
||||
function render() {
|
||||
if (firstRender) {
|
||||
elem.append($container);
|
||||
$container.on('click', '.graph-legend-icon', openColorSelector);
|
||||
$container.on('click', '.graph-legend-alias', toggleSeries);
|
||||
firstRender = false;
|
||||
}
|
||||
|
||||
$container.empty();
|
||||
|
||||
$container.toggleClass('graph-legend-table', panel.legend.alignAsTable);
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
var series = data[i];
|
||||
var html = '<div class="graph-legend-series';
|
||||
if (series.info.yaxis === 2) { html += ' pull-right'; }
|
||||
if (scope.hiddenSeries[series.label]) { html += ' graph-legend-series-hidden'; }
|
||||
html += '" data-series-index="' + i + '">';
|
||||
html += '<div class="graph-legend-icon">';
|
||||
html += '<i class="icon-minus pointer" style="color:' + series.color + '"></i>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="graph-legend-alias small">';
|
||||
html += '<a>' + series.label + '</a>';
|
||||
html += '</div>';
|
||||
|
||||
if (panel.legend.values) {
|
||||
if (panel.legend.min) { html += '<div class="graph-legend-value min small">' + series.info.min + '</div>'; }
|
||||
if (panel.legend.max) { html += '<div class="graph-legend-value max small">' + series.info.max + '</div>'; }
|
||||
if (panel.legend.avg) { html += '<div class="graph-legend-value avg small">' + series.info.avg + '</div>'; }
|
||||
if (panel.legend.current) { html += '<div class="graph-legend-value current small">' + series.info.current + '</div>'; }
|
||||
if (panel.legend.total) { html += '<div class="graph-legend-value total small">' + series.info.total + '</div>'; }
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
$container.append($(html));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
});
|
27
src/app/panels/graph/legend.popover.html
Normal file
27
src/app/panels/graph/legend.popover.html
Normal file
@ -0,0 +1,27 @@
|
||||
<div class="graph-legend-popover">
|
||||
<a class="close" ng-click="dismiss();" href="">×</a>
|
||||
|
||||
<div class="editor-row small" style="padding-bottom: 0;">
|
||||
<label>Axis:</label>
|
||||
<button ng-click="toggleYAxis(series);dismiss();"
|
||||
class="btn btn-mini"
|
||||
ng-class="{'btn-success': series.yaxis === 1 }">
|
||||
Left
|
||||
</button>
|
||||
<button ng-click="toggleYAxis(series);dismiss();"
|
||||
class="btn btn-mini"
|
||||
ng-class="{'btn-success': series.yaxis === 2 }">
|
||||
Right
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="editor-row">
|
||||
<i ng-repeat="color in colors"
|
||||
class="pointer"
|
||||
ng-class="{'icon-circle-blank': color === series.color,'icon-circle': color !== series.color}"
|
||||
ng-style="{color:color}"
|
||||
ng-click="changeSeriesColor(series, color);dismiss();">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,25 +1,22 @@
|
||||
<div ng-controller='GraphCtrl'>
|
||||
|
||||
<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
|
||||
<div class="graph-canvas-wrapper">
|
||||
<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>Can be caused by timezone mismatch between browser and graphite server</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 ng-if="datapointsWarning" class="datapoints-warning">
|
||||
<span class="small" ng-show="!datapointsCount">No datapoints <tip>Can be caused by timezone mismatch between browser and graphite server</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">
|
||||
</div>
|
||||
<div grafana-graph class="histogram-chart">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="graph-legend-wrapper"
|
||||
ng-if="panel.legend.show"
|
||||
ng-include="'app/panels/graph/legend.html'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="graph-legend-wrapper" ng-if="panel.legend.show" graph-legend></div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div style="margin-top: 30px" ng-if="editMode">
|
||||
<div class="dashboard-editor-header">
|
||||
|
@ -7,6 +7,7 @@ define([
|
||||
'moment',
|
||||
'components/timeSeries',
|
||||
'./seriesOverridesCtrl',
|
||||
'./legend',
|
||||
'services/panelSrv',
|
||||
'services/annotationsSrv',
|
||||
'services/datasourceSrv',
|
||||
@ -23,7 +24,6 @@ function (angular, app, $, _, kbn, moment, TimeSeries) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.panels.graph');
|
||||
app.useModule(module);
|
||||
|
||||
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
|
||||
|
||||
@ -270,7 +270,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries) {
|
||||
};
|
||||
|
||||
$scope.render = function(data) {
|
||||
$scope.$emit('render', data);
|
||||
$scope.$broadcast('render', data);
|
||||
};
|
||||
|
||||
$scope.changeSeriesColor = function(series, color) {
|
||||
@ -291,7 +291,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries) {
|
||||
$scope.toggleSeriesExclusiveMode(serie);
|
||||
}
|
||||
|
||||
$scope.$emit('toggleLegend', $scope.legend);
|
||||
$scope.render();
|
||||
};
|
||||
|
||||
$scope.toggleSeriesExclusiveMode = function(serie) {
|
||||
|
@ -9,6 +9,7 @@ define([
|
||||
'./timer',
|
||||
'./keyboardManager',
|
||||
'./annotationsSrv',
|
||||
'./popoverSrv',
|
||||
'./playlistSrv',
|
||||
'./unsavedChangesSrv',
|
||||
'./dashboard/dashboardKeyBindings',
|
||||
|
45
src/app/services/popoverSrv.js
Normal file
45
src/app/services/popoverSrv.js
Normal file
@ -0,0 +1,45 @@
|
||||
define([
|
||||
'angular',
|
||||
],
|
||||
function (angular) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.service('popoverSrv', function($templateCache, $timeout, $q, $http, $compile) {
|
||||
|
||||
this.getTemplate = function(url) {
|
||||
return $q.when($templateCache.get(url) || $http.get(url, {cache: true}));
|
||||
};
|
||||
|
||||
this.show = function(options) {
|
||||
var popover = options.element.data('popover');
|
||||
if (popover) {
|
||||
popover.scope.$destroy();
|
||||
popover.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
this.getTemplate(options.templateUrl).then(function(result) {
|
||||
var template = result.data;
|
||||
|
||||
options.element.popover({
|
||||
content: template,
|
||||
placement: 'bottom',
|
||||
html: true
|
||||
});
|
||||
|
||||
popover = options.element.data('popover');
|
||||
popover.hasContent = function () {
|
||||
return template;
|
||||
};
|
||||
|
||||
popover.toggle();
|
||||
popover.scope = options.scope;
|
||||
$compile(popover.$tip)(popover.scope);
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -60,9 +60,6 @@
|
||||
padding-left: 0;
|
||||
&.pull-right {
|
||||
float: none;
|
||||
.graph-legend-alias::after {
|
||||
content: 'y\00B2';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user