sw2at-ui 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/swat/app/app.coffee +13 -0
- data/app/assets/javascripts/swat/app/controllers/revisions.coffee +1 -1
- data/app/assets/javascripts/swat/app/controllers/root.coffee +1 -1
- data/app/assets/javascripts/swat/app/controllers/summary.coffee +72 -0
- data/app/assets/javascripts/swat/app/factories/fails_graph.coffee +45 -0
- data/app/assets/javascripts/swat/app/factories/helpers.coffee +7 -0
- data/app/assets/javascripts/swat/app/factories/revision_model.coffee +1 -2
- data/app/assets/javascripts/swat/bower_components.coffee +4 -1
- data/app/assets/javascripts/swat/lib/highcharts-ng.js +396 -0
- data/app/assets/javascripts/swat/lib/highcharts.src.js +18635 -0
- data/app/assets/stylesheets/swat/application.scss +55 -0
- data/app/assets/stylesheets/swat/swat_theme.scss +261 -0
- data/app/models/revision.rb +1 -2
- data/app/views/swat/pages/revisions/index.slim +7 -7
- data/app/views/swat/pages/revisions/partials/_exceptions.slim +31 -0
- data/app/views/swat/pages/revisions/partials/_test_cases.slim +29 -0
- data/app/views/swat/pages/revisions/show.slim +5 -32
- data/app/views/swat/pages/revisions/summary.slim +52 -0
- data/config/routes.rb +1 -1
- data/sw2at-ui.gemspec +15 -7
- metadata +13 -5
- data/app/assets/stylesheets/swat/application.sass +0 -59
- data/app/assets/stylesheets/swat/swat_theme.sass +0 -192
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7857e82e50e84a809a23b3954a5e09d0d8d2cf11
|
4
|
+
data.tar.gz: 01c616fd52714cf6109fe0fb072a26d57f11702d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a34ae34569c6985f5f9736d260a2834f431381884d0b5ac088bf57f44b9c3388a29671059bec6534befa0edfa9be47a3198b72b67789b8695f9d409457e1e93
|
7
|
+
data.tar.gz: 40f01fde652e0c708f8f381db0ff20144da05007208fbb145553239b31cf36f52ae50fa5b5ac0a7a553a1c07c569930a129709c0209fd84b445b19b0693d576a
|
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
@@ -4,6 +4,11 @@
|
|
4
4
|
#= require_tree ./factories
|
5
5
|
#= require_tree ./controllers
|
6
6
|
|
7
|
+
window.Swat =
|
8
|
+
debug: true#false
|
9
|
+
log: (message)->
|
10
|
+
return unless window.Swat.debug
|
11
|
+
console.log(message)
|
7
12
|
|
8
13
|
App = angular.module 'SWAT', [
|
9
14
|
'ngResource'
|
@@ -11,6 +16,7 @@ App = angular.module 'SWAT', [
|
|
11
16
|
'ui.router'
|
12
17
|
'ui.bootstrap'
|
13
18
|
'ngClipboard'
|
19
|
+
'highcharts-ng'
|
14
20
|
]
|
15
21
|
|
16
22
|
App.config ($urlRouterProvider, $stateProvider) ->
|
@@ -29,6 +35,13 @@ App.config ($urlRouterProvider, $stateProvider) ->
|
|
29
35
|
templateUrl: "/swat/pages/revisions/show.html"
|
30
36
|
controller: 'RevisionCtrl'
|
31
37
|
)
|
38
|
+
.state("summary",
|
39
|
+
url: "/swat/summary/revisions/:branch/:user/:time"
|
40
|
+
views:
|
41
|
+
content:
|
42
|
+
templateUrl: "/swat/pages/revisions/summary.html"
|
43
|
+
controller: 'SummaryCtrl'
|
44
|
+
)
|
32
45
|
App.config(['ngClipProvider', (ngClipProvider)->
|
33
46
|
ngClipProvider.setPath("/assets/swat/bower_components/zeroclipboard/dist/ZeroClipboard.swf")
|
34
47
|
])
|
@@ -1,7 +1,7 @@
|
|
1
1
|
angular.module("SWAT").controller "RevisionsCtrl", ($rootScope, $scope, $state, RevisionService)->
|
2
2
|
|
3
3
|
$scope.init = ->
|
4
|
-
|
4
|
+
window.Swat.log('Revisions Controller initalized!')
|
5
5
|
$scope.initRevisions()
|
6
6
|
|
7
7
|
$scope.initRevisions = ->
|
@@ -0,0 +1,72 @@
|
|
1
|
+
angular.module("SWAT").controller "SummaryCtrl", ($rootScope, $scope, $state, $stateParams
|
2
|
+
RevisionService, FailsGraph, SwatHelpers) ->
|
3
|
+
|
4
|
+
$scope.init = ->
|
5
|
+
$scope.summary = {}
|
6
|
+
$scope.reloadData()
|
7
|
+
|
8
|
+
$scope.reloadData = ->
|
9
|
+
return if $scope.revisionPromise && !$scope.revisionPromise.$resolved
|
10
|
+
params = { branch: $stateParams.branch, user: $stateParams.user, time: $stateParams.time }
|
11
|
+
$scope.revisionPromise = RevisionService.get(params)
|
12
|
+
$scope.revisionPromise.$promise.then($scope.initInformation)
|
13
|
+
|
14
|
+
$scope.initInformation = (revision)->
|
15
|
+
$scope.revision = revision
|
16
|
+
$scope.tests = _.flatten(_.map($scope.revision.data.threads, (thread)-> thread.tests || []))
|
17
|
+
window.Swat.log($scope.tests)
|
18
|
+
$scope.initFails()
|
19
|
+
$scope.initExceptions()
|
20
|
+
$scope.initMetrics()
|
21
|
+
$scope.initFailsStatsGraph()
|
22
|
+
|
23
|
+
$scope.initFails = ->
|
24
|
+
$scope.summary.fails = _.select($scope.tests, (t)->(t.exception) )
|
25
|
+
|
26
|
+
$scope.initExceptions = ->
|
27
|
+
groups = _.groupBy($scope.summary.fails, (f)->(f.exception.message) )
|
28
|
+
window.Swat.log(groups)
|
29
|
+
|
30
|
+
result = []
|
31
|
+
for exMessage in _.keys(groups)
|
32
|
+
exception =
|
33
|
+
message: exMessage
|
34
|
+
backtrace: groups[exMessage][0].exception.backtrace
|
35
|
+
tests: groups[exMessage]
|
36
|
+
result.push(exception)
|
37
|
+
|
38
|
+
window.Swat.log(result)
|
39
|
+
$scope.summary.exceptions = result
|
40
|
+
|
41
|
+
$scope.initFailsStatsGraph = ->
|
42
|
+
$scope.failsStats = new FailsGraph($scope.tests, $scope.summary.fails)
|
43
|
+
return
|
44
|
+
$scope.failsStats =1
|
45
|
+
|
46
|
+
$scope.initMetrics = ->
|
47
|
+
result = []
|
48
|
+
totalTests = $scope.tests.length
|
49
|
+
totalFailedTests = $scope.summary.fails.length
|
50
|
+
totalDuration = _.sum($scope.tests, 'run_time')
|
51
|
+
totalThreadDuration = _.sum($scope.revision.data.threads, 'total_runtime')
|
52
|
+
successPercentage = (($scope.tests.length - $scope.summary.fails.length) / $scope.tests.length*100)
|
53
|
+
|
54
|
+
result.push({ name: 'Revision Name', value: $scope.revision.data.name })
|
55
|
+
result.push({ name: 'Revision Status', value: $scope.revision.data.status.name })
|
56
|
+
result.push({ name: 'Revision Branch', value: $scope.revision.data.branch })
|
57
|
+
result.push({ name: 'Revisor', value: $scope.revision.data.user })
|
58
|
+
result.push({ name: 'Threads Count', value: $scope.revision.data.threads_count })
|
59
|
+
|
60
|
+
result.push({ name: 'Total Tests', value: totalTests })
|
61
|
+
result.push({ name: 'Total Failed Tests', value: totalFailedTests })
|
62
|
+
|
63
|
+
result.push({ name: 'Total Tests Duration', value: SwatHelpers.formatTime(totalDuration) })
|
64
|
+
result.push({ name: 'Total Threads Duration', value: SwatHelpers.formatTime(totalThreadDuration) })
|
65
|
+
|
66
|
+
result.push({ name: 'Success Percentage', value: (successPercentage.toFixed(2)+'%') })
|
67
|
+
|
68
|
+
$scope.summary.metrics = result
|
69
|
+
|
70
|
+
$scope.init()
|
71
|
+
|
72
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class FailsGraph
|
2
|
+
constructor: (@tests, @fails) ->
|
3
|
+
conf: ->
|
4
|
+
|
5
|
+
res =
|
6
|
+
options:
|
7
|
+
chart:
|
8
|
+
plotBackgroundColor: null
|
9
|
+
plotBorderWidth: null
|
10
|
+
plotShadow: false
|
11
|
+
type: 'pie'
|
12
|
+
title:
|
13
|
+
text: 'Fail Rate'
|
14
|
+
|
15
|
+
tooltip:
|
16
|
+
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
|
17
|
+
plotOptions: pie:
|
18
|
+
allowPointSelect: true
|
19
|
+
cursor: 'pointer'
|
20
|
+
dataLabels:
|
21
|
+
enabled: true
|
22
|
+
format:
|
23
|
+
'<b>{point.name}</b>: {point.percentage:.1f} %'
|
24
|
+
style:
|
25
|
+
color:
|
26
|
+
Highcharts.theme and Highcharts.theme.contrastTextColor or 'black'
|
27
|
+
series: [ {
|
28
|
+
name: 'Results'
|
29
|
+
colors: [ '#1FEC33', '#EC243B', '#90ed7d', '#f7a35c', '#8085e9', '#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1']
|
30
|
+
colorByPoint: true
|
31
|
+
data: [
|
32
|
+
{
|
33
|
+
name: 'Passed Examples'
|
34
|
+
y: (@tests.length - @fails.length)
|
35
|
+
}
|
36
|
+
{
|
37
|
+
name: 'Failed Examples'
|
38
|
+
y: @fails.length
|
39
|
+
}
|
40
|
+
]
|
41
|
+
} ]
|
42
|
+
|
43
|
+
angular.module("SWAT").factory "FailsGraph", ->
|
44
|
+
(tests, fails)->
|
45
|
+
new FailsGraph(tests, fails).conf()
|
@@ -0,0 +1,7 @@
|
|
1
|
+
angular.module("SWAT").factory "SwatHelpers", ->
|
2
|
+
Helpers =
|
3
|
+
formatTime: (seconds) ->
|
4
|
+
hh = Math.floor(seconds / 3600)
|
5
|
+
mm = Math.floor(seconds / 60) % 60
|
6
|
+
ss = Math.floor(seconds) % 60
|
7
|
+
(if hh then (if hh < 10 then '0' else '') + hh + ':' else '') + (if mm < 10 and hh then '0' else '') + mm + ':' + (if ss < 10 then '0' else '') + ss
|
@@ -12,4 +12,7 @@
|
|
12
12
|
#= require swat/bower_components/angular-bootstrap/ui-bootstrap.js
|
13
13
|
#= require swat/bower_components/angular-bootstrap/ui-bootstrap-tpls.js
|
14
14
|
#= require swat/bower_components/ng-clip/src/ngClip
|
15
|
-
#= require swat/bower_components/zeroclipboard/dist/ZeroClipboard.js
|
15
|
+
#= require swat/bower_components/zeroclipboard/dist/ZeroClipboard.js
|
16
|
+
|
17
|
+
#= require swat/lib/highcharts.src.js
|
18
|
+
#= require swat/lib/highcharts-ng.js
|
@@ -0,0 +1,396 @@
|
|
1
|
+
if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports === exports){
|
2
|
+
module.exports = 'highcharts-ng';
|
3
|
+
}
|
4
|
+
(function () {
|
5
|
+
'use strict';
|
6
|
+
/*global angular: false, Highcharts: false */
|
7
|
+
|
8
|
+
angular.module('highcharts-ng', [])
|
9
|
+
.factory('highchartsNGUtils', highchartsNGUtils)
|
10
|
+
.directive('highchart', ['highchartsNGUtils', '$timeout', highchart]);
|
11
|
+
|
12
|
+
function highchartsNGUtils() {
|
13
|
+
|
14
|
+
return {
|
15
|
+
|
16
|
+
//IE8 support
|
17
|
+
indexOf: function (arr, find, i /*opt*/) {
|
18
|
+
if (i === undefined) i = 0;
|
19
|
+
if (i < 0) i += arr.length;
|
20
|
+
if (i < 0) i = 0;
|
21
|
+
for (var n = arr.length; i < n; i++)
|
22
|
+
if (i in arr && arr[i] === find)
|
23
|
+
return i;
|
24
|
+
return -1;
|
25
|
+
},
|
26
|
+
|
27
|
+
prependMethod: function (obj, method, func) {
|
28
|
+
var original = obj[method];
|
29
|
+
obj[method] = function () {
|
30
|
+
var args = Array.prototype.slice.call(arguments);
|
31
|
+
func.apply(this, args);
|
32
|
+
if (original) {
|
33
|
+
return original.apply(this, args);
|
34
|
+
} else {
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
|
38
|
+
};
|
39
|
+
},
|
40
|
+
|
41
|
+
deepExtend: function deepExtend(destination, source) {
|
42
|
+
//Slightly strange behaviour in edge cases (e.g. passing in non objects)
|
43
|
+
//But does the job for current use cases.
|
44
|
+
if (angular.isArray(source)) {
|
45
|
+
destination = angular.isArray(destination) ? destination : [];
|
46
|
+
for (var i = 0; i < source.length; i++) {
|
47
|
+
destination[i] = deepExtend(destination[i] || {}, source[i]);
|
48
|
+
}
|
49
|
+
} else if (angular.isObject(source)) {
|
50
|
+
for (var property in source) {
|
51
|
+
destination[property] = deepExtend(destination[property] || {}, source[property]);
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
destination = source;
|
55
|
+
}
|
56
|
+
return destination;
|
57
|
+
}
|
58
|
+
};
|
59
|
+
}
|
60
|
+
|
61
|
+
function highchart(highchartsNGUtils, $timeout) {
|
62
|
+
|
63
|
+
// acceptable shared state
|
64
|
+
var seriesId = 0;
|
65
|
+
var ensureIds = function (series) {
|
66
|
+
var changed = false;
|
67
|
+
angular.forEach(series, function(s) {
|
68
|
+
if (!angular.isDefined(s.id)) {
|
69
|
+
s.id = 'series-' + seriesId++;
|
70
|
+
changed = true;
|
71
|
+
}
|
72
|
+
});
|
73
|
+
return changed;
|
74
|
+
};
|
75
|
+
|
76
|
+
// immutable
|
77
|
+
var axisNames = [ 'xAxis', 'yAxis' ];
|
78
|
+
var chartTypeMap = {
|
79
|
+
'stock': 'StockChart',
|
80
|
+
'map': 'Map',
|
81
|
+
'chart': 'Chart'
|
82
|
+
};
|
83
|
+
|
84
|
+
var getMergedOptions = function (scope, element, config) {
|
85
|
+
var mergedOptions = {};
|
86
|
+
|
87
|
+
var defaultOptions = {
|
88
|
+
chart: {
|
89
|
+
events: {}
|
90
|
+
},
|
91
|
+
title: {},
|
92
|
+
subtitle: {},
|
93
|
+
series: [],
|
94
|
+
credits: {},
|
95
|
+
plotOptions: {},
|
96
|
+
navigator: {enabled: false}
|
97
|
+
};
|
98
|
+
|
99
|
+
if (config.options) {
|
100
|
+
mergedOptions = highchartsNGUtils.deepExtend(defaultOptions, config.options);
|
101
|
+
} else {
|
102
|
+
mergedOptions = defaultOptions;
|
103
|
+
}
|
104
|
+
mergedOptions.chart.renderTo = element[0];
|
105
|
+
|
106
|
+
angular.forEach(axisNames, function(axisName) {
|
107
|
+
if(angular.isDefined(config[axisName])) {
|
108
|
+
mergedOptions[axisName] = angular.copy(config[axisName]);
|
109
|
+
|
110
|
+
if(angular.isDefined(config[axisName].currentMin) ||
|
111
|
+
angular.isDefined(config[axisName].currentMax)) {
|
112
|
+
|
113
|
+
highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'selection', function(e){
|
114
|
+
var thisChart = this;
|
115
|
+
if (e[axisName]) {
|
116
|
+
scope.$apply(function () {
|
117
|
+
scope.config[axisName].currentMin = e[axisName][0].min;
|
118
|
+
scope.config[axisName].currentMax = e[axisName][0].max;
|
119
|
+
});
|
120
|
+
} else {
|
121
|
+
//handle reset button - zoom out to all
|
122
|
+
scope.$apply(function () {
|
123
|
+
scope.config[axisName].currentMin = thisChart[axisName][0].dataMin;
|
124
|
+
scope.config[axisName].currentMax = thisChart[axisName][0].dataMax;
|
125
|
+
});
|
126
|
+
}
|
127
|
+
});
|
128
|
+
|
129
|
+
highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'addSeries', function(e){
|
130
|
+
scope.config[axisName].currentMin = this[axisName][0].min || scope.config[axisName].currentMin;
|
131
|
+
scope.config[axisName].currentMax = this[axisName][0].max || scope.config[axisName].currentMax;
|
132
|
+
});
|
133
|
+
}
|
134
|
+
}
|
135
|
+
});
|
136
|
+
|
137
|
+
if(config.title) {
|
138
|
+
mergedOptions.title = config.title;
|
139
|
+
}
|
140
|
+
if (config.subtitle) {
|
141
|
+
mergedOptions.subtitle = config.subtitle;
|
142
|
+
}
|
143
|
+
if (config.credits) {
|
144
|
+
mergedOptions.credits = config.credits;
|
145
|
+
}
|
146
|
+
if(config.size) {
|
147
|
+
if (config.size.width) {
|
148
|
+
mergedOptions.chart.width = config.size.width;
|
149
|
+
}
|
150
|
+
if (config.size.height) {
|
151
|
+
mergedOptions.chart.height = config.size.height;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
return mergedOptions;
|
155
|
+
};
|
156
|
+
|
157
|
+
var updateZoom = function (axis, modelAxis) {
|
158
|
+
var extremes = axis.getExtremes();
|
159
|
+
if(modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) {
|
160
|
+
axis.setExtremes(modelAxis.currentMin, modelAxis.currentMax, false);
|
161
|
+
}
|
162
|
+
};
|
163
|
+
|
164
|
+
var processExtremes = function(chart, axis, axisName) {
|
165
|
+
if(axis.currentMin || axis.currentMax) {
|
166
|
+
chart[axisName][0].setExtremes(axis.currentMin, axis.currentMax, true);
|
167
|
+
}
|
168
|
+
};
|
169
|
+
|
170
|
+
var chartOptionsWithoutEasyOptions = function (options) {
|
171
|
+
return highchartsNGUtils.deepExtend({}, options, {data: null, visible: null});
|
172
|
+
};
|
173
|
+
|
174
|
+
var getChartType = function(scope) {
|
175
|
+
if (scope.config === undefined) return 'Chart';
|
176
|
+
return chartTypeMap[('' + scope.config.chartType).toLowerCase()] ||
|
177
|
+
(scope.config.useHighStocks ? 'StockChart' : 'Chart');
|
178
|
+
};
|
179
|
+
|
180
|
+
return {
|
181
|
+
restrict: 'EAC',
|
182
|
+
replace: true,
|
183
|
+
template: '<div></div>',
|
184
|
+
scope: {
|
185
|
+
config: '=',
|
186
|
+
disableDataWatch: '='
|
187
|
+
},
|
188
|
+
link: function (scope, element, attrs) {
|
189
|
+
// We keep some chart-specific variables here as a closure
|
190
|
+
// instead of storing them on 'scope'.
|
191
|
+
|
192
|
+
// prevSeriesOptions is maintained by processSeries
|
193
|
+
var prevSeriesOptions = {};
|
194
|
+
|
195
|
+
var processSeries = function(series) {
|
196
|
+
var i;
|
197
|
+
var ids = [];
|
198
|
+
|
199
|
+
if(series) {
|
200
|
+
var setIds = ensureIds(series);
|
201
|
+
if(setIds) {
|
202
|
+
//If we have set some ids this will trigger another digest cycle.
|
203
|
+
//In this scenario just return early and let the next cycle take care of changes
|
204
|
+
return false;
|
205
|
+
}
|
206
|
+
|
207
|
+
//Find series to add or update
|
208
|
+
angular.forEach(series, function(s) {
|
209
|
+
ids.push(s.id);
|
210
|
+
var chartSeries = chart.get(s.id);
|
211
|
+
if (chartSeries) {
|
212
|
+
if (!angular.equals(prevSeriesOptions[s.id], chartOptionsWithoutEasyOptions(s))) {
|
213
|
+
chartSeries.update(angular.copy(s), false);
|
214
|
+
} else {
|
215
|
+
if (s.visible !== undefined && chartSeries.visible !== s.visible) {
|
216
|
+
chartSeries.setVisible(s.visible, false);
|
217
|
+
}
|
218
|
+
chartSeries.setData(angular.copy(s.data), false);
|
219
|
+
}
|
220
|
+
} else {
|
221
|
+
chart.addSeries(angular.copy(s), false);
|
222
|
+
}
|
223
|
+
prevSeriesOptions[s.id] = chartOptionsWithoutEasyOptions(s);
|
224
|
+
});
|
225
|
+
|
226
|
+
// Shows no data text if all series are empty
|
227
|
+
if(scope.config.noData) {
|
228
|
+
var chartContainsData = false;
|
229
|
+
|
230
|
+
for(i = 0; i < series.length; i++) {
|
231
|
+
if (series[i].data && series[i].data.length > 0) {
|
232
|
+
chartContainsData = true;
|
233
|
+
|
234
|
+
break;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
if (!chartContainsData) {
|
239
|
+
chart.showLoading(scope.config.noData);
|
240
|
+
} else {
|
241
|
+
chart.hideLoading();
|
242
|
+
}
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
//Now remove any missing series
|
247
|
+
for(i = chart.series.length - 1; i >= 0; i--) {
|
248
|
+
var s = chart.series[i];
|
249
|
+
if (s.options.id !== 'highcharts-navigator-series' && highchartsNGUtils.indexOf(ids, s.options.id) < 0) {
|
250
|
+
s.remove(false);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
return true;
|
255
|
+
};
|
256
|
+
|
257
|
+
// chart is maintained by initChart
|
258
|
+
var chart = false;
|
259
|
+
var initChart = function() {
|
260
|
+
if (chart) chart.destroy();
|
261
|
+
prevSeriesOptions = {};
|
262
|
+
var config = scope.config || {};
|
263
|
+
var mergedOptions = getMergedOptions(scope, element, config);
|
264
|
+
var func = config.func || undefined;
|
265
|
+
var chartType = getChartType(scope);
|
266
|
+
|
267
|
+
chart = new Highcharts[chartType](mergedOptions, func);
|
268
|
+
|
269
|
+
for (var i = 0; i < axisNames.length; i++) {
|
270
|
+
if (config[axisNames[i]]) {
|
271
|
+
processExtremes(chart, config[axisNames[i]], axisNames[i]);
|
272
|
+
}
|
273
|
+
}
|
274
|
+
if(config.loading) {
|
275
|
+
chart.showLoading();
|
276
|
+
}
|
277
|
+
config.getHighcharts = function() {
|
278
|
+
return chart;
|
279
|
+
};
|
280
|
+
|
281
|
+
};
|
282
|
+
initChart();
|
283
|
+
|
284
|
+
|
285
|
+
if(scope.disableDataWatch){
|
286
|
+
scope.$watchCollection('config.series', function (newSeries, oldSeries) {
|
287
|
+
processSeries(newSeries);
|
288
|
+
chart.redraw();
|
289
|
+
});
|
290
|
+
} else {
|
291
|
+
scope.$watch('config.series', function (newSeries, oldSeries) {
|
292
|
+
var needsRedraw = processSeries(newSeries);
|
293
|
+
if(needsRedraw) {
|
294
|
+
chart.redraw();
|
295
|
+
}
|
296
|
+
}, true);
|
297
|
+
}
|
298
|
+
|
299
|
+
scope.$watch('config.title', function (newTitle) {
|
300
|
+
chart.setTitle(newTitle, true);
|
301
|
+
}, true);
|
302
|
+
|
303
|
+
scope.$watch('config.subtitle', function (newSubtitle) {
|
304
|
+
chart.setTitle(true, newSubtitle);
|
305
|
+
}, true);
|
306
|
+
|
307
|
+
scope.$watch('config.loading', function (loading) {
|
308
|
+
if(loading) {
|
309
|
+
chart.showLoading(loading === true ? null : loading);
|
310
|
+
} else {
|
311
|
+
chart.hideLoading();
|
312
|
+
}
|
313
|
+
});
|
314
|
+
scope.$watch('config.noData', function (noData) {
|
315
|
+
if(scope.config && scope.config.loading) {
|
316
|
+
chart.showLoading(noData);
|
317
|
+
}
|
318
|
+
}, true);
|
319
|
+
|
320
|
+
scope.$watch('config.credits.enabled', function (enabled) {
|
321
|
+
if (enabled) {
|
322
|
+
chart.credits.show();
|
323
|
+
} else if (chart.credits) {
|
324
|
+
chart.credits.hide();
|
325
|
+
}
|
326
|
+
});
|
327
|
+
|
328
|
+
scope.$watch(getChartType, function (chartType, oldChartType) {
|
329
|
+
if (chartType === oldChartType) return;
|
330
|
+
initChart();
|
331
|
+
});
|
332
|
+
|
333
|
+
angular.forEach(axisNames, function(axisName) {
|
334
|
+
scope.$watch('config.' + axisName, function(newAxes, oldAxes) {
|
335
|
+
if (newAxes === oldAxes || !newAxes) {
|
336
|
+
return;
|
337
|
+
}
|
338
|
+
|
339
|
+
if (angular.isArray(newAxes)) {
|
340
|
+
|
341
|
+
for (var axisIndex = 0; axisIndex < newAxes.length; axisIndex++) {
|
342
|
+
var axis = newAxes[axisIndex];
|
343
|
+
|
344
|
+
if (axisIndex < chart[axisName].length) {
|
345
|
+
chart[axisName][axisIndex].update(axis, false);
|
346
|
+
updateZoom(chart[axisName][axisIndex], angular.copy(axis));
|
347
|
+
}
|
348
|
+
|
349
|
+
}
|
350
|
+
|
351
|
+
} else {
|
352
|
+
// update single axis
|
353
|
+
chart[axisName][0].update(newAxes, false);
|
354
|
+
updateZoom(chart[axisName][0], angular.copy(newAxes));
|
355
|
+
}
|
356
|
+
|
357
|
+
chart.redraw();
|
358
|
+
}, true);
|
359
|
+
});
|
360
|
+
scope.$watch('config.options', function (newOptions, oldOptions, scope) {
|
361
|
+
//do nothing when called on registration
|
362
|
+
if (newOptions === oldOptions) return;
|
363
|
+
initChart();
|
364
|
+
processSeries(scope.config.series);
|
365
|
+
chart.redraw();
|
366
|
+
}, true);
|
367
|
+
|
368
|
+
scope.$watch('config.size', function (newSize, oldSize) {
|
369
|
+
if(newSize === oldSize) return;
|
370
|
+
if(newSize) {
|
371
|
+
chart.setSize(newSize.width || chart.chartWidth, newSize.height || chart.chartHeight);
|
372
|
+
}
|
373
|
+
}, true);
|
374
|
+
|
375
|
+
scope.$on('highchartsng.reflow', function () {
|
376
|
+
chart.reflow();
|
377
|
+
});
|
378
|
+
|
379
|
+
scope.$on('$destroy', function() {
|
380
|
+
if (chart) {
|
381
|
+
try{
|
382
|
+
chart.destroy();
|
383
|
+
}catch(ex){
|
384
|
+
// fail silently as highcharts will throw exception if element doesn't exist
|
385
|
+
}
|
386
|
+
|
387
|
+
$timeout(function(){
|
388
|
+
element.remove();
|
389
|
+
}, 0);
|
390
|
+
}
|
391
|
+
});
|
392
|
+
|
393
|
+
}
|
394
|
+
};
|
395
|
+
}
|
396
|
+
}());
|