You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
7.3 KiB
253 lines
7.3 KiB
import PerfectScrollbar from 'perfect-scrollbar'; |
|
import _ from 'lodash'; |
|
import 'jquery'; |
|
|
|
|
|
export class GraphLegend { |
|
firstRender = true; |
|
ctrl: any; |
|
panel: any; |
|
data; |
|
seriesList; |
|
legendScrollbar; |
|
|
|
constructor(private $elem: JQuery<HTMLElement>, private popoverSrv, private scope) { |
|
this.ctrl = scope.ctrl; |
|
this.panel = this.ctrl.panel; |
|
scope.$on('$destroy', () => { |
|
if (this.legendScrollbar) { |
|
this.legendScrollbar.destroy(); |
|
} |
|
}); |
|
} |
|
|
|
getSeriesIndexForElement(el) { |
|
return el.parents('[data-series-index]').data('series-index'); |
|
} |
|
|
|
openColorSelector(e) { |
|
// if we clicked inside poup container ignore click |
|
if ($(e.target).parents('.popover').length) { |
|
return; |
|
} |
|
|
|
var el = $(e.currentTarget).find('.fa-minus'); |
|
var index = this.getSeriesIndexForElement(el); |
|
var series = this.seriesList[index]; |
|
|
|
this.popoverSrv.show({ |
|
element: el[0], |
|
position: 'bottom left', |
|
targetAttachment: 'top left', |
|
template: |
|
'<series-color-picker series="series" onToggleAxis="toggleAxis" onColorChange="colorSelected"/>', |
|
openOn: 'hover', |
|
model: { |
|
series: series, |
|
toggleAxis: () => { |
|
this.ctrl.toggleAxis(series); |
|
}, |
|
colorSelected: color => { |
|
this.ctrl.changeSeriesColor(series, color); |
|
}, |
|
}, |
|
}); |
|
|
|
} |
|
|
|
toggleSeries(e) { |
|
var el = $(e.currentTarget); |
|
var index = this.getSeriesIndexForElement(el); |
|
var seriesInfo = this.seriesList[index]; |
|
var scrollPosition = this.$elem.find('tbody').scrollTop(); |
|
this.ctrl.toggleSeries(seriesInfo, e); |
|
this.$elem.find('tbody').scrollTop(scrollPosition); |
|
} |
|
|
|
sortLegend(e) { |
|
var el = $(e.currentTarget); |
|
var stat = el.data('stat'); |
|
|
|
if (stat !== this.panel.legend.sort) { |
|
this.panel.legend.sortDesc = null; |
|
} |
|
|
|
// if already sort ascending, disable sorting |
|
if (this.panel.legend.sortDesc === false) { |
|
this.panel.legend.sort = null; |
|
this.panel.legend.sortDesc = null; |
|
this.ctrl.render(); |
|
return; |
|
} |
|
|
|
this.panel.legend.sortDesc = !this.panel.legend.sortDesc; |
|
this.panel.legend.sort = stat; |
|
this.ctrl.render(); |
|
} |
|
|
|
getTableHeaderHtml(statName) { |
|
if (!this.panel.legend[statName]) { |
|
return ''; |
|
} |
|
var html = '<th class="pointer" data-stat="' + statName + '">' + statName; |
|
|
|
if (this.panel.legend.sort === statName) { |
|
var cssClass = this.panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up'; |
|
html += ' <span class="' + cssClass + '"></span>'; |
|
} |
|
|
|
return html + '</th>'; |
|
} |
|
|
|
render() { |
|
this.data = this.ctrl.seriesList; |
|
if (!this.ctrl.panel.legend.show) { |
|
this.$elem.empty(); |
|
this.firstRender = true; |
|
return; |
|
} |
|
|
|
if (this.firstRender) { |
|
this.$elem.on('click', '.graph-legend-icon', this.openColorSelector.bind(this)); |
|
this.$elem.on('click', '.graph-legend-alias', this.toggleSeries.bind(this)); |
|
this.$elem.on('click', 'th', this.sortLegend.bind(this)); |
|
this.firstRender = false; |
|
} |
|
|
|
this.seriesList = this.data; |
|
|
|
this.$elem.empty(); |
|
|
|
// Set min-width if side style and there is a value, otherwise remove the CSS propery |
|
var width = this.panel.legend.rightSide && this.panel.legend.sideWidth ? this.panel.legend.sideWidth + 'px' : ''; |
|
this.$elem.css('min-width', width); |
|
|
|
this.$elem.toggleClass('graph-legend-table', this.panel.legend.alignAsTable === true); |
|
|
|
var tableHeaderElem; |
|
if (this.panel.legend.alignAsTable) { |
|
var header = '<tr>'; |
|
header += '<th colspan="2" style="text-align:left"></th>'; |
|
if (this.panel.legend.values) { |
|
header += this.getTableHeaderHtml('min'); |
|
header += this.getTableHeaderHtml('max'); |
|
header += this.getTableHeaderHtml('avg'); |
|
header += this.getTableHeaderHtml('current'); |
|
header += this.getTableHeaderHtml('total'); |
|
} |
|
header += '</tr>'; |
|
tableHeaderElem = $(header); |
|
} |
|
|
|
if (this.panel.legend.sort) { |
|
this.seriesList = _.sortBy(this.seriesList, function(series) { |
|
return series.stats[this.panel.legend.sort]; |
|
}); |
|
if (this.panel.legend.sortDesc) { |
|
this.seriesList = this.seriesList.reverse(); |
|
} |
|
} |
|
|
|
// render first time for getting proper legend height |
|
if (!this.panel.legend.rightSide) { |
|
this.renderLegendElement(tableHeaderElem); |
|
this.$elem.empty(); |
|
} |
|
|
|
this.renderLegendElement(tableHeaderElem); |
|
} |
|
|
|
renderSeriesLegendElements() { |
|
let seriesElements = []; |
|
for (let i = 0; i < this.seriesList.length; i++) { |
|
var series = this.seriesList[i]; |
|
|
|
if (series.hideFromLegend(this.panel.legend)) { |
|
continue; |
|
} |
|
|
|
var html = '<div class="graph-legend-series'; |
|
|
|
if (series.yaxis === 2) { |
|
html += ' graph-legend-series--right-y'; |
|
} |
|
if (this.ctrl.hiddenSeries[series.alias]) { |
|
html += ' graph-legend-series-hidden'; |
|
} |
|
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>'; |
|
|
|
if (this.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 (this.panel.legend.min) { |
|
html += '<div class="graph-legend-value min">' + min + '</div>'; |
|
} |
|
if (this.panel.legend.max) { |
|
html += '<div class="graph-legend-value max">' + max + '</div>'; |
|
} |
|
if (this.panel.legend.avg) { |
|
html += '<div class="graph-legend-value avg">' + avg + '</div>'; |
|
} |
|
if (this.panel.legend.current) { |
|
html += '<div class="graph-legend-value current">' + current + '</div>'; |
|
} |
|
if (this.panel.legend.total) { |
|
html += '<div class="graph-legend-value total">' + total + '</div>'; |
|
} |
|
} |
|
|
|
html += '</div>'; |
|
seriesElements.push($(html)); |
|
} |
|
return seriesElements; |
|
} |
|
|
|
renderLegendElement(tableHeaderElem) { |
|
var seriesElements = this.renderSeriesLegendElements(); |
|
|
|
if (this.panel.legend.alignAsTable) { |
|
var tbodyElem = $('<tbody></tbody>'); |
|
tbodyElem.append(tableHeaderElem); |
|
tbodyElem.append(seriesElements); |
|
this.$elem.append(tbodyElem); |
|
} else { |
|
this.$elem.append(seriesElements); |
|
} |
|
|
|
if (!this.panel.legend.rightSide) { |
|
this.addScrollbar(); |
|
} else { |
|
this.destroyScrollbar(); |
|
} |
|
} |
|
|
|
addScrollbar() { |
|
const scrollbarOptions = { |
|
// Number of pixels the content height can surpass the container height without enabling the scroll bar. |
|
scrollYMarginOffset: 2, |
|
suppressScrollX: true, |
|
}; |
|
|
|
if (!this.legendScrollbar) { |
|
this.legendScrollbar = new PerfectScrollbar(this.$elem[0], scrollbarOptions); |
|
} else { |
|
this.legendScrollbar.update(); |
|
} |
|
} |
|
|
|
destroyScrollbar() { |
|
if (this.legendScrollbar) { |
|
this.legendScrollbar.destroy(); |
|
} |
|
} |
|
}
|
|
|