2017-12-19 16:06:54 +01:00
|
|
|
import angular from "angular";
|
|
|
|
|
import _ from "lodash";
|
|
|
|
|
import $ from "jquery";
|
|
|
|
|
import PerfectScrollbar from "perfect-scrollbar";
|
|
|
|
|
import { updateLegendValues } from "app/core/core";
|
2017-12-06 11:29:13 +03:00
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
var module = angular.module("grafana.directives");
|
2017-12-06 11:29:13 +03:00
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
module.directive("graphLegend", function(popoverSrv, $timeout) {
|
2017-12-06 11:29:13 +03:00
|
|
|
return {
|
|
|
|
|
link: function(scope, elem) {
|
|
|
|
|
var firstRender = true;
|
|
|
|
|
var ctrl = scope.ctrl;
|
|
|
|
|
var panel = ctrl.panel;
|
|
|
|
|
var data;
|
|
|
|
|
var seriesList;
|
|
|
|
|
var i;
|
|
|
|
|
var legendScrollbar;
|
|
|
|
|
|
2017-12-07 18:13:56 +01:00
|
|
|
scope.$on("$destroy", function() {
|
2017-12-08 12:17:09 +01:00
|
|
|
if (legendScrollbar) {
|
2017-12-07 19:53:32 +01:00
|
|
|
legendScrollbar.destroy();
|
|
|
|
|
}
|
2017-12-07 18:13:56 +01:00
|
|
|
});
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
ctrl.events.on("render-legend", () => {
|
2017-12-06 11:29:13 +03:00
|
|
|
data = ctrl.seriesList;
|
|
|
|
|
if (data) {
|
|
|
|
|
render();
|
|
|
|
|
}
|
2017-12-19 16:06:54 +01:00
|
|
|
ctrl.events.emit("legend-rendering-complete");
|
2017-12-06 11:29:13 +03:00
|
|
|
});
|
|
|
|
|
|
2017-12-07 18:13:56 +01:00
|
|
|
function updateLegendDecimals() {
|
|
|
|
|
updateLegendValues(data, panel);
|
2017-12-06 23:50:29 +03:00
|
|
|
}
|
|
|
|
|
|
2017-12-06 11:29:13 +03:00
|
|
|
function getSeriesIndexForElement(el) {
|
2017-12-19 16:06:54 +01:00
|
|
|
return el.parents("[data-series-index]").data("series-index");
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function openColorSelector(e) {
|
|
|
|
|
// if we clicked inside poup container ignore click
|
2017-12-19 16:06:54 +01:00
|
|
|
if ($(e.target).parents(".popover").length) {
|
2017-12-06 11:29:13 +03:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
var el = $(e.currentTarget).find(".fa-minus");
|
2017-12-06 11:29:13 +03:00
|
|
|
var index = getSeriesIndexForElement(el);
|
|
|
|
|
var series = seriesList[index];
|
|
|
|
|
|
|
|
|
|
$timeout(function() {
|
|
|
|
|
popoverSrv.show({
|
|
|
|
|
element: el[0],
|
2017-12-19 16:06:54 +01:00
|
|
|
position: "bottom left",
|
|
|
|
|
targetAttachment: "top left",
|
|
|
|
|
template:
|
|
|
|
|
'<series-color-picker series="series" onToggleAxis="toggleAxis" onColorChange="colorSelected">' +
|
|
|
|
|
"</series-color-picker>",
|
|
|
|
|
openOn: "hover",
|
2017-12-06 11:29:13 +03:00
|
|
|
model: {
|
|
|
|
|
series: series,
|
|
|
|
|
toggleAxis: function() {
|
|
|
|
|
ctrl.toggleAxis(series);
|
|
|
|
|
},
|
|
|
|
|
colorSelected: function(color) {
|
|
|
|
|
ctrl.changeSeriesColor(series, color);
|
|
|
|
|
}
|
2017-12-19 16:06:54 +01:00
|
|
|
}
|
2017-12-06 11:29:13 +03:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function toggleSeries(e) {
|
|
|
|
|
var el = $(e.currentTarget);
|
|
|
|
|
var index = getSeriesIndexForElement(el);
|
|
|
|
|
var seriesInfo = seriesList[index];
|
2017-12-19 16:06:54 +01:00
|
|
|
var scrollPosition = $(elem.children("tbody")).scrollTop();
|
2017-12-06 11:29:13 +03:00
|
|
|
ctrl.toggleSeries(seriesInfo, e);
|
2017-12-19 16:06:54 +01:00
|
|
|
$(elem.children("tbody")).scrollTop(scrollPosition);
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function sortLegend(e) {
|
|
|
|
|
var el = $(e.currentTarget);
|
2017-12-19 16:06:54 +01:00
|
|
|
var stat = el.data("stat");
|
2017-12-06 11:29:13 +03:00
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
if (stat !== panel.legend.sort) {
|
|
|
|
|
panel.legend.sortDesc = null;
|
|
|
|
|
}
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
// if already sort ascending, disable sorting
|
|
|
|
|
if (panel.legend.sortDesc === false) {
|
|
|
|
|
panel.legend.sort = null;
|
|
|
|
|
panel.legend.sortDesc = null;
|
|
|
|
|
ctrl.render();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
panel.legend.sortDesc = !panel.legend.sortDesc;
|
|
|
|
|
panel.legend.sort = stat;
|
|
|
|
|
ctrl.render();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTableHeaderHtml(statName) {
|
2017-12-19 16:06:54 +01:00
|
|
|
if (!panel.legend[statName]) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
var html =
|
|
|
|
|
'<th class="pointer" data-stat="' + statName + '">' + statName;
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
if (panel.legend.sort === statName) {
|
2017-12-19 16:06:54 +01:00
|
|
|
var cssClass = panel.legend.sortDesc
|
|
|
|
|
? "fa fa-caret-down"
|
|
|
|
|
: "fa fa-caret-up";
|
2017-12-06 11:29:13 +03:00
|
|
|
html += ' <span class="' + cssClass + '"></span>';
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
return html + "</th>";
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function render() {
|
|
|
|
|
if (!ctrl.panel.legend.show) {
|
|
|
|
|
elem.empty();
|
|
|
|
|
firstRender = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (firstRender) {
|
2017-12-19 16:06:54 +01:00
|
|
|
elem.on("click", ".graph-legend-icon", openColorSelector);
|
|
|
|
|
elem.on("click", ".graph-legend-alias", toggleSeries);
|
|
|
|
|
elem.on("click", "th", sortLegend);
|
2017-12-06 11:29:13 +03:00
|
|
|
firstRender = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seriesList = data;
|
|
|
|
|
|
2017-12-07 19:53:32 +01:00
|
|
|
elem.empty();
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
// Set min-width if side style and there is a value, otherwise remove the CSS propery
|
2017-12-19 16:06:54 +01:00
|
|
|
var width =
|
|
|
|
|
panel.legend.rightSide && panel.legend.sideWidth
|
|
|
|
|
? panel.legend.sideWidth + "px"
|
|
|
|
|
: "";
|
2017-12-07 19:53:32 +01:00
|
|
|
elem.css("min-width", width);
|
2017-12-06 11:29:13 +03:00
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
elem.toggleClass(
|
|
|
|
|
"graph-legend-table",
|
|
|
|
|
panel.legend.alignAsTable === true
|
|
|
|
|
);
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
var tableHeaderElem;
|
|
|
|
|
if (panel.legend.alignAsTable) {
|
2017-12-19 16:06:54 +01:00
|
|
|
var header = "<tr>";
|
2017-12-06 11:29:13 +03:00
|
|
|
header += '<th colspan="2" style="text-align:left"></th>';
|
|
|
|
|
if (panel.legend.values) {
|
2017-12-19 16:06:54 +01:00
|
|
|
header += getTableHeaderHtml("min");
|
|
|
|
|
header += getTableHeaderHtml("max");
|
|
|
|
|
header += getTableHeaderHtml("avg");
|
|
|
|
|
header += getTableHeaderHtml("current");
|
|
|
|
|
header += getTableHeaderHtml("total");
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
2017-12-19 16:06:54 +01:00
|
|
|
header += "</tr>";
|
2017-12-06 11:29:13 +03:00
|
|
|
tableHeaderElem = $(header);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (panel.legend.sort) {
|
|
|
|
|
seriesList = _.sortBy(seriesList, function(series) {
|
|
|
|
|
return series.stats[panel.legend.sort];
|
|
|
|
|
});
|
|
|
|
|
if (panel.legend.sortDesc) {
|
|
|
|
|
seriesList = seriesList.reverse();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-07 12:03:39 +03:00
|
|
|
// render first time for getting proper legend height
|
|
|
|
|
if (!panel.legend.rightSide) {
|
|
|
|
|
renderLegendElement(tableHeaderElem);
|
2017-12-07 18:13:56 +01:00
|
|
|
updateLegendDecimals();
|
2017-12-07 19:53:32 +01:00
|
|
|
elem.empty();
|
2017-12-07 12:03:39 +03:00
|
|
|
} else {
|
2017-12-07 18:13:56 +01:00
|
|
|
updateLegendDecimals();
|
2017-12-07 12:03:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderLegendElement(tableHeaderElem);
|
|
|
|
|
}
|
2017-12-06 11:29:13 +03:00
|
|
|
|
2017-12-07 12:03:39 +03:00
|
|
|
function renderSeriesLegendElements() {
|
|
|
|
|
let seriesElements = [];
|
2017-12-06 11:29:13 +03:00
|
|
|
for (i = 0; i < seriesList.length; i++) {
|
|
|
|
|
var series = seriesList[i];
|
|
|
|
|
|
|
|
|
|
if (series.hideFromLegend(panel.legend)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var html = '<div class="graph-legend-series';
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
if (series.yaxis === 2) {
|
|
|
|
|
html += " graph-legend-series--right-y";
|
|
|
|
|
}
|
|
|
|
|
if (ctrl.hiddenSeries[series.alias]) {
|
|
|
|
|
html += " graph-legend-series-hidden";
|
|
|
|
|
}
|
2017-12-06 11:29:13 +03:00
|
|
|
html += '" data-series-index="' + i + '">';
|
|
|
|
|
html += '<div class="graph-legend-icon">';
|
2017-12-19 16:06:54 +01:00
|
|
|
html +=
|
|
|
|
|
'<i class="fa fa-minus pointer" style="color:' +
|
|
|
|
|
series.color +
|
|
|
|
|
'"></i>';
|
|
|
|
|
html += "</div>";
|
|
|
|
|
|
|
|
|
|
html +=
|
|
|
|
|
'<a class="graph-legend-alias pointer" title="' +
|
|
|
|
|
series.aliasEscaped +
|
|
|
|
|
'">' +
|
|
|
|
|
series.aliasEscaped +
|
|
|
|
|
"</a>";
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
if (panel.legend.values) {
|
|
|
|
|
var avg = series.formatValue(series.stats.avg);
|
|
|
|
|
var current = series.formatValue(series.stats.current);
|
|
|
|
|
var min = series.formatValue(series.stats.min);
|
|
|
|
|
var max = series.formatValue(series.stats.max);
|
|
|
|
|
var total = series.formatValue(series.stats.total);
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
if (panel.legend.min) {
|
|
|
|
|
html += '<div class="graph-legend-value min">' + min + "</div>";
|
|
|
|
|
}
|
|
|
|
|
if (panel.legend.max) {
|
|
|
|
|
html += '<div class="graph-legend-value max">' + max + "</div>";
|
|
|
|
|
}
|
|
|
|
|
if (panel.legend.avg) {
|
|
|
|
|
html += '<div class="graph-legend-value avg">' + avg + "</div>";
|
|
|
|
|
}
|
|
|
|
|
if (panel.legend.current) {
|
|
|
|
|
html +=
|
|
|
|
|
'<div class="graph-legend-value current">' + current + "</div>";
|
|
|
|
|
}
|
|
|
|
|
if (panel.legend.total) {
|
|
|
|
|
html +=
|
|
|
|
|
'<div class="graph-legend-value total">' + total + "</div>";
|
|
|
|
|
}
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 16:06:54 +01:00
|
|
|
html += "</div>";
|
2017-12-06 11:29:13 +03:00
|
|
|
seriesElements.push($(html));
|
|
|
|
|
}
|
2017-12-07 12:03:39 +03:00
|
|
|
return seriesElements;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderLegendElement(tableHeaderElem) {
|
|
|
|
|
var seriesElements = renderSeriesLegendElements();
|
2017-12-06 11:29:13 +03:00
|
|
|
|
|
|
|
|
if (panel.legend.alignAsTable) {
|
2017-12-19 16:06:54 +01:00
|
|
|
var tbodyElem = $("<tbody></tbody>");
|
2017-12-06 11:29:13 +03:00
|
|
|
tbodyElem.append(tableHeaderElem);
|
|
|
|
|
tbodyElem.append(seriesElements);
|
2017-12-07 19:53:32 +01:00
|
|
|
elem.append(tbodyElem);
|
2017-12-06 11:29:13 +03:00
|
|
|
} else {
|
2017-12-07 19:53:32 +01:00
|
|
|
elem.append(seriesElements);
|
2017-12-12 19:02:19 +03:00
|
|
|
}
|
2017-12-07 18:13:56 +01:00
|
|
|
|
2017-12-12 19:02:19 +03:00
|
|
|
if (!panel.legend.rightSide) {
|
|
|
|
|
addScrollbar();
|
|
|
|
|
} else {
|
|
|
|
|
destroyScrollbar();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addScrollbar() {
|
|
|
|
|
const scrollbarOptions = {
|
|
|
|
|
// Number of pixels the content height can surpass the container height without enabling the scroll bar.
|
|
|
|
|
scrollYMarginOffset: 2,
|
|
|
|
|
suppressScrollX: true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!legendScrollbar) {
|
|
|
|
|
legendScrollbar = new PerfectScrollbar(elem[0], scrollbarOptions);
|
|
|
|
|
} else {
|
|
|
|
|
legendScrollbar.update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function destroyScrollbar() {
|
|
|
|
|
if (legendScrollbar) {
|
|
|
|
|
legendScrollbar.destroy();
|
2017-12-06 11:29:13 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
});
|