aboutsummaryrefslogtreecommitdiff
path: root/kamon-dashboard/src/main/resources/web/js/highcharts-ng.js
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-dashboard/src/main/resources/web/js/highcharts-ng.js')
-rw-r--r--kamon-dashboard/src/main/resources/web/js/highcharts-ng.js188
1 files changed, 188 insertions, 0 deletions
diff --git a/kamon-dashboard/src/main/resources/web/js/highcharts-ng.js b/kamon-dashboard/src/main/resources/web/js/highcharts-ng.js
new file mode 100644
index 00000000..19c25e28
--- /dev/null
+++ b/kamon-dashboard/src/main/resources/web/js/highcharts-ng.js
@@ -0,0 +1,188 @@
+'use strict';
+
+angular.module('highcharts-ng', [])
+ .directive('highchart', function () {
+
+ function prependMethod(obj, method, func) {
+ var original = obj[method];
+ obj[method] = function () {
+ var args = Array.prototype.slice.call(arguments);
+ func.apply(this, args);
+ if(original) {
+ return original.apply(this, args);
+ } else {
+ return;
+ }
+
+ };
+ }
+
+ function deepExtend(destination, source) {
+ for (var property in source) {
+ if (source[property] && source[property].constructor &&
+ source[property].constructor === Object) {
+ destination[property] = destination[property] || {};
+ deepExtend(destination[property], source[property]);
+ } else {
+ destination[property] = source[property];
+ }
+ }
+ return destination;
+ }
+
+ var seriesId = 0;
+ var ensureIds = function (series) {
+ series.forEach(function (s) {
+ if (!angular.isDefined(s.id)) {
+ s.id = "series-" + seriesId++;
+ }
+ });
+ }
+
+ var defaultOptions = {
+ chart: {
+ events: {}
+ },
+ title: {},
+ series: [],
+ navigator: {enabled: false}
+ }
+
+ var getMergedOptions = function (scope, element, config) {
+ var mergedOptions = {}
+ if (config.options) {
+ mergedOptions = deepExtend(defaultOptions, config.options);
+ } else {
+ mergedOptions = defaultOptions;
+ }
+ mergedOptions.chart.renderTo = element[0];
+ if(scope.config.xAxis) {
+ prependMethod(mergedOptions.chart.events, 'selection', function(e){
+ var thisChart = this;
+ if(e.xAxis) {
+ scope.$apply(function () {
+ scope.config.xAxis.currentMin = e.xAxis[0].min;
+ scope.config.xAxis.currentMax = e.xAxis[0].max;
+ });
+ } else {
+ //handle reset button - zoom out to all
+ scope.$apply(function () {
+ scope.config.xAxis.currentMin = thisChart.xAxis[0].dataMin;
+ scope.config.xAxis.currentMax = thisChart.xAxis[0].dataMax;
+ });
+ }
+ });
+
+ prependMethod(mergedOptions.chart.events, 'addSeries', function(e){
+ scope.config.xAxis.currentMin = this.xAxis[0].min || scope.config.xAxis.currentMin;
+ scope.config.xAxis.currentMax = this.xAxis[0].max || scope.config.xAxis.currentMax;
+ });
+ }
+
+ if(config.xAxis) {
+ mergedOptions.xAxis = angular.copy(config.xAxis)
+ }
+ if(config.title) {
+ mergedOptions.title = config.title
+ }
+ return mergedOptions
+ }
+
+ var updateZoom = function (axis, modelAxis) {
+ var extremes = axis.getExtremes();
+ if(modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) {
+ axis.setExtremes(modelAxis.currentMin, modelAxis.currentMax, false);
+ }
+ }
+
+ var processExtremes = function(chart, axis) {
+ if(axis.currentMin || axis.currentMax) {
+ chart.xAxis[0].setExtremes(axis.currentMin, axis.currentMax, true);
+ }
+ }
+
+ var processSeries = function(chart, series) {
+ var ids = []
+ if(series) {
+ ensureIds(series);
+
+ //Find series to add or update
+ series.forEach(function (s) {
+ ids.push(s.id)
+ var chartSeries = chart.get(s.id);
+ if (chartSeries) {
+ chartSeries.update(angular.copy(s), false);
+ } else {
+ chart.addSeries(angular.copy(s), false)
+ }
+ });
+ }
+
+ //Now remove any missing series
+ chart.series.forEach(function (s) {
+ if (ids.indexOf(s.options.id) < 0) {
+ s.remove(false);
+ }
+ });
+ }
+
+ var initialiseChart = function(scope, element, config) {
+ var mergedOptions = getMergedOptions(scope, element, config);
+ var chart = new Highcharts.Chart(mergedOptions);
+ if(config.xAxis) {
+ processExtremes(chart, config.xAxis);
+ }
+ processSeries(chart, config.series);
+ chart.redraw();
+ return chart;
+ }
+
+
+ return {
+ restrict: 'EC',
+ replace: true,
+ template: '<div></div>',
+ scope: {
+ config: '='
+ },
+ link: function (scope, element, attrs) {
+
+ var chart = initialiseChart(scope, element, scope.config);
+
+ scope.$watch("config.series", function (newSeries, oldSeries) {
+ //do nothing when called on registration
+ if (newSeries === oldSeries) return;
+ processSeries(chart, newSeries);
+ chart.redraw();
+ }, true);
+
+ scope.$watch("config.title", function (newTitle) {
+ chart.setTitle(newTitle, true);
+ }, true);
+
+ scope.$watch("config.loading", function (loading) {
+ if(loading === false) {
+ chart.hideLoading()
+ } else {
+ chart.showLoading()
+ }
+ }, true);
+
+ scope.$watch("config.xAxis", function (newAxes, oldAxes) {
+ if (newAxes === oldAxes) return;
+ if(newAxes) {
+ chart.xAxis[0].update(newAxes);
+ updateZoom(chart.xAxis[0], angular.copy(newAxes));
+ chart.redraw();
+ }
+ }, true);
+ scope.$watch("config.options", function (newOptions, oldOptions, scope) {
+ //do nothing when called on registration
+ if (newOptions === oldOptions) return;
+ chart.destroy();
+ chart = initialiseChart(scope, element, scope.config);
+
+ }, true);
+ }
+ }
+ }); \ No newline at end of file