Files
grafana/public/app/plugins/panel/graph/legend.ts

292 lines
8.5 KiB
TypeScript
Raw Normal View History

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
var module = angular.module("grafana.directives");
2017-12-06 11:29:13 +03: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;
scope.$on("$destroy", function() {
2017-12-08 12:17:09 +01:00
if (legendScrollbar) {
legendScrollbar.destroy();
}
});
ctrl.events.on("render-legend", () => {
2017-12-06 11:29:13 +03:00
data = ctrl.seriesList;
if (data) {
render();
}
ctrl.events.emit("legend-rendering-complete");
2017-12-06 11:29:13 +03:00
});
function updateLegendDecimals() {
updateLegendValues(data, panel);
}
2017-12-06 11:29:13 +03:00
function getSeriesIndexForElement(el) {
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
if ($(e.target).parents(".popover").length) {
2017-12-06 11:29:13 +03:00
return;
}
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],
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-06 11:29:13 +03:00
});
});
}
function toggleSeries(e) {
var el = $(e.currentTarget);
var index = getSeriesIndexForElement(el);
var seriesInfo = seriesList[index];
var scrollPosition = $(elem.children("tbody")).scrollTop();
2017-12-06 11:29:13 +03:00
ctrl.toggleSeries(seriesInfo, e);
$(elem.children("tbody")).scrollTop(scrollPosition);
2017-12-06 11:29:13 +03:00
}
function sortLegend(e) {
var el = $(e.currentTarget);
var stat = el.data("stat");
2017-12-06 11:29:13 +03: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) {
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) {
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>';
}
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) {
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;
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
var width =
panel.legend.rightSide && panel.legend.sideWidth
? panel.legend.sideWidth + "px"
: "";
elem.css("min-width", width);
2017-12-06 11:29:13 +03:00
elem.toggleClass(
"graph-legend-table",
panel.legend.alignAsTable === true
);
2017-12-06 11:29:13 +03:00
var tableHeaderElem;
if (panel.legend.alignAsTable) {
var header = "<tr>";
2017-12-06 11:29:13 +03:00
header += '<th colspan="2" style="text-align:left"></th>';
if (panel.legend.values) {
header += getTableHeaderHtml("min");
header += getTableHeaderHtml("max");
header += getTableHeaderHtml("avg");
header += getTableHeaderHtml("current");
header += getTableHeaderHtml("total");
2017-12-06 11:29:13 +03: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);
updateLegendDecimals();
elem.empty();
2017-12-07 12:03:39 +03:00
} else {
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';
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">';
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);
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
}
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) {
var tbodyElem = $("<tbody></tbody>");
2017-12-06 11:29:13 +03:00
tbodyElem.append(tableHeaderElem);
tbodyElem.append(seriesElements);
elem.append(tbodyElem);
2017-12-06 11:29:13 +03:00
} else {
elem.append(seriesElements);
}
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
}
}
}
};
});