Skip to content

Commit

Permalink
Added rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
fooker committed Jun 1, 2017
1 parent 5135907 commit a29ee12
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 20 deletions.
8 changes: 7 additions & 1 deletion Gruntfile.js
Expand Up @@ -16,6 +16,12 @@ module.exports = function(grunt) {
src: ['**/*', '!**/*.js', '!**/*.scss'],
dest: 'dist'
},
vendor_to_dist: {
cwd: 'vendor',
expand: true,
src: ['**/*'],
dest: 'dist'
},
pluginDef: {
expand: true,
src: ['README.md'],
Expand All @@ -25,7 +31,7 @@ module.exports = function(grunt) {

watch: {
rebuild_all: {
files: ['src/**/*', 'README.md'],
files: ['src/**/*', 'vendor/**/*', 'README.md'],
tasks: ['default'],
options: {spawn: false}
},
Expand Down
72 changes: 59 additions & 13 deletions src/panels/alarm-histogram/ctrl.js
Expand Up @@ -2,30 +2,41 @@ import {MetricsPanelCtrl} from 'app/plugins/sdk';

import _ from 'lodash';

import 'jquery.flot';
import 'jquery.flot.selection';
import 'jquery.flot.crosshair';

import '../../jquery.flot.categories';


class AlarmHistogramCtrl extends MetricsPanelCtrl {

constructor($scope, $injector) {
super($scope, $injector);

this.scope = $scope;

_.defaults(this.panel, {
groupProperty: 'acknowledged',
});

this.events.on('render', this.onRender.bind(this));
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('data-received', this.onDataReceived.bind(this));
this.events.on('data-error', this.onDataError.bind(this));
this.events.on('data-snapshot-load', this.onDataReceived.bind(this));
this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
this.events.on('render', this.onRender.bind(this));
}

onRender() {
link($scope, elem, attrs, ctrl) {
this.elem = elem.find('.histogram-chart');
this.ctrl = ctrl;
}

onInitEditMode() {
this.addEditorTab('Grouping', 'public/plugins/opennms-helm-app/panels/alarm-histogram/editor.html', 2);
}

onDataReceived(data) {
console.log(data);

switch (this.panel.groupProperty) {
case 'acknowledged': {
const counts = _.countBy(this.query(data, 'AckedBy'), _.isNil);
Expand All @@ -44,7 +55,7 @@ class AlarmHistogramCtrl extends MetricsPanelCtrl {

case 'severity': {
const counts = _.countBy(this.query(data, 'Severity'));
this.series = _.map(counts, function (group, count) {
this.series = _.map(counts, function (count, group) {
return {
name: group,
count: count,
Expand All @@ -54,23 +65,58 @@ class AlarmHistogramCtrl extends MetricsPanelCtrl {
}
}

console.log(this.series);

this.render();
this.render(this.series);
}

onDataError() {
this.series = [];
this.render();
this.render(this.series);
}

onInitEditMode() {
this.addEditorTab('Grouping', 'public/plugins/opennms-helm-app/panels/alarm-histogram/editor.html', 2);
onRender() {
// Size handling
if (this.elem.width() === 0) {
return true;
}

let height = this.ctrl.height || this.ctrl.panel.height || this.ctrl.row.height;
if (_.isString(height)) {
height = parseInt(height.replace('px', ''), 10);
}
height -= 5; // padding
height -= this.ctrl.panel.title ? 24 : 9; // subtract panel title bar

this.elem.css('height', height + 'px');

// Convert data to series
const data = _.map(this.series, function(serie) { return [serie.name, serie.count]; });

// Draw graph
$.plot(this.elem, [data], {
series: {
bars: {
show: true,
barWidth: 0.5,
align: "center",
fill: true,
lineWidth: 0,
}
},
xaxis: {
mode: "categories",
tickLength: 0,
autoscaleMargin: .02,
},
grid: {
borderWidth: 0,
},
colors: this.scope.$root.colors,
});
}

query(data, column) {
// TODO: Make this a generator to save memory
let result = []
let result = [];

for (let i = 0; i < data.length; i++) {
let columnIndex = _.findIndex(data[i].columns, {text: column});
Expand Down
8 changes: 2 additions & 6 deletions src/panels/alarm-histogram/module.html
@@ -1,4 +1,4 @@
<div class="graph-wrapper" ng-class="{'graph-legend-rightside': ctrl.panel.legend.rightSide}">
<div class="graph-wrapper">
<div class="graph-canvas-wrapper">
<div ng-if="datapointsWarning"
class="datapoints-warning">
Expand All @@ -12,13 +12,9 @@
</span>
</div>

<div grafana-histogram
ng-dblclick="ctrl.zoomOut()"
class="histogram-chart">
<div class="histogram-chart">
</div>
</div>
<div graph-legend
class="graph-legend-wrapper"></div>
</div>

<div class="clearfix"></div>
190 changes: 190 additions & 0 deletions vendor/jquery.flot.categories.js
@@ -0,0 +1,190 @@
/* Flot plugin for plotting textual data or categories.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
allows you to plot such a dataset directly.
To enable it, you must specify mode: "categories" on the axis with the textual
labels, e.g.
$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
By default, the labels are ordered as they are met in the data series. If you
need a different ordering, you can specify "categories" on the axis options
and list the categories there:
xaxis: {
mode: "categories",
categories: ["February", "March", "April"]
}
If you need to customize the distances between the categories, you can specify
"categories" as an object mapping labels to values
xaxis: {
mode: "categories",
categories: { "February": 1, "March": 3, "April": 4 }
}
If you don't specify all categories, the remaining categories will be numbered
from the max value plus 1 (with a spacing of 1 between each).
Internally, the plugin works by transforming the input data through an auto-
generated mapping where the first category becomes 0, the second 1, etc.
Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
is visible in hover and click events that return numbers rather than the
category labels). The plugin also overrides the tick generator to spit out the
categories as ticks instead of the values.
If you need to map a value back to its label, the mapping is always accessible
as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
*/

(function ($) {
var options = {
xaxis: {
categories: null
},
yaxis: {
categories: null
}
};

function processRawData(plot, series, data, datapoints) {
// if categories are enabled, we need to disable
// auto-transformation to numbers so the strings are intact
// for later processing

var xCategories = series.xaxis.options.mode == "categories",
yCategories = series.yaxis.options.mode == "categories";

if (!(xCategories || yCategories))
return;

var format = datapoints.format;

if (!format) {
// FIXME: auto-detection should really not be defined here
var s = series;
format = [];
format.push({ x: true, number: true, required: true });
format.push({ y: true, number: true, required: true });

if (s.bars.show || (s.lines.show && s.lines.fill)) {
var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
if (s.bars.horizontal) {
delete format[format.length - 1].y;
format[format.length - 1].x = true;
}
}

datapoints.format = format;
}

for (var m = 0; m < format.length; ++m) {
if (format[m].x && xCategories)
format[m].number = false;

if (format[m].y && yCategories)
format[m].number = false;
}
}

function getNextIndex(categories) {
var index = -1;

for (var v in categories)
if (categories[v] > index)
index = categories[v];

return index + 1;
}

function categoriesTickGenerator(axis) {
var res = [];
for (var label in axis.categories) {
var v = axis.categories[label];
if (v >= axis.min && v <= axis.max)
res.push([v, label]);
}

res.sort(function (a, b) { return a[0] - b[0]; });

return res;
}

function setupCategoriesForAxis(series, axis, datapoints) {
if (series[axis].options.mode != "categories")
return;

if (!series[axis].categories) {
// parse options
var c = {}, o = series[axis].options.categories || {};
if ($.isArray(o)) {
for (var i = 0; i < o.length; ++i)
c[o[i]] = i;
}
else {
for (var v in o)
c[v] = o[v];
}

series[axis].categories = c;
}

// fix ticks
if (!series[axis].options.ticks)
series[axis].options.ticks = categoriesTickGenerator;

transformPointsOnAxis(datapoints, axis, series[axis].categories);
}

function transformPointsOnAxis(datapoints, axis, categories) {
// go through the points, transforming them
var points = datapoints.points,
ps = datapoints.pointsize,
format = datapoints.format,
formatColumn = axis.charAt(0),
index = getNextIndex(categories);

for (var i = 0; i < points.length; i += ps) {
if (points[i] == null)
continue;

for (var m = 0; m < ps; ++m) {
var val = points[i + m];

if (val == null || !format[m][formatColumn])
continue;

if (!(val in categories)) {
categories[val] = index;
++index;
}

points[i + m] = categories[val];
}
}
}

function processDatapoints(plot, series, datapoints) {
setupCategoriesForAxis(series, "xaxis", datapoints);
setupCategoriesForAxis(series, "yaxis", datapoints);
}

function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.processDatapoints.push(processDatapoints);
}

$.plot.plugins.push({
init: init,
options: options,
name: 'categories',
version: '1.0'
});
})(jQuery);

0 comments on commit a29ee12

Please sign in to comment.