contour 0.5.7 → 0.6.0
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.
- data/CHANGELOG.rdoc +9 -0
- data/README.rdoc +4 -4
- data/contour.gemspec +2 -4
- data/lib/contour/version.rb +8 -1
- data/vendor/assets/javascripts/contour.js +2 -2
- data/vendor/assets/javascripts/external/{exporting-2.1.4.src.js → exporting-2.1.9.src.js} +245 -160
- data/vendor/assets/javascripts/external/{highcharts-2.1.4.src.js → highcharts-2.1.9.src.js} +11454 -10668
- data/vendor/assets/stylesheets/contour/global.css +8 -0
- metadata +11 -14
data/CHANGELOG.rdoc
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
== 0.6.0
|
|
2
|
+
|
|
3
|
+
* Enhancements
|
|
4
|
+
* Underlying HighCharts Library updated to 2.1.9 to work with jQuery 1.7.0
|
|
5
|
+
* Added jquery-rails ~> 1.0.17 as a dependency
|
|
6
|
+
|
|
7
|
+
* Bug Fix
|
|
8
|
+
* CSS classes negative and positive now properly apply color to their corresponding links
|
|
9
|
+
|
|
1
10
|
== 0.5.7
|
|
2
11
|
|
|
3
12
|
* Enhancements
|
data/README.rdoc
CHANGED
|
@@ -42,7 +42,7 @@ In order to get registration working, you can use the modified Contour Authentic
|
|
|
42
42
|
|
|
43
43
|
== Setting up a new project with quick authentication
|
|
44
44
|
|
|
45
|
-
Make sure you have Rails 3.1.
|
|
45
|
+
Make sure you have Rails 3.1.1
|
|
46
46
|
|
|
47
47
|
rails -v
|
|
48
48
|
|
|
@@ -52,9 +52,9 @@ Make sure you have Rails 3.1.0
|
|
|
52
52
|
|
|
53
53
|
Modify Gemfile and add
|
|
54
54
|
|
|
55
|
-
gem 'contour', '~> 0.
|
|
56
|
-
gem 'devise'
|
|
57
|
-
gem 'omniauth'
|
|
55
|
+
gem 'contour', '~> 0.6.0' # Basic Layout and Assets
|
|
56
|
+
gem 'devise' # User Authorization
|
|
57
|
+
gem 'omniauth' # User Multi-Authentication
|
|
58
58
|
|
|
59
59
|
Run Bundle install
|
|
60
60
|
|
data/contour.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ require 'contour/version'
|
|
|
11
11
|
|
|
12
12
|
Gem::Specification.new do |s|
|
|
13
13
|
s.name = 'contour'
|
|
14
|
-
s.version = Contour::VERSION
|
|
14
|
+
s.version = Contour::VERSION::STRING
|
|
15
15
|
s.platform = Gem::Platform::RUBY
|
|
16
16
|
s.summary = 'Basic Rails framework files and assets for layout and authentication'
|
|
17
17
|
s.email = 'remosm@gmail.com'
|
|
@@ -21,9 +21,7 @@ Gem::Specification.new do |s|
|
|
|
21
21
|
|
|
22
22
|
s.add_dependency('devise', '~> 1.4.9')
|
|
23
23
|
s.add_dependency('omniauth', '=0.2.6')
|
|
24
|
-
|
|
25
|
-
# HighCharts 2.1.4 requires jQuery 1.6.4
|
|
26
|
-
s.add_dependency('jquery-rails', '>= 1.0.0', '<= 1.0.16')
|
|
24
|
+
s.add_dependency('jquery-rails', '~> 1.0.17')
|
|
27
25
|
|
|
28
26
|
s.files = `git ls-files`.split("\n")
|
|
29
27
|
end
|
data/lib/contour/version.rb
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Highcharts JS v2.1.
|
|
1
|
+
/**
|
|
2
|
+
* @license Highcharts JS v2.1.9 (2011-11-11)
|
|
3
3
|
* Exporting module
|
|
4
|
-
*
|
|
5
|
-
* (c) 2010 Torstein Hønsi
|
|
6
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* (c) 2010-2011 Torstein Hønsi
|
|
6
|
+
*
|
|
7
7
|
* License: www.highcharts.com/license
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// JSLint options:
|
|
11
11
|
/*global Highcharts, document, window, Math, setTimeout */
|
|
12
12
|
|
|
13
|
-
(function() { // encapsulate
|
|
13
|
+
(function () { // encapsulate
|
|
14
14
|
|
|
15
15
|
// create shortcuts
|
|
16
16
|
var HC = Highcharts,
|
|
17
17
|
Chart = HC.Chart,
|
|
18
18
|
addEvent = HC.addEvent,
|
|
19
|
+
removeEvent = HC.removeEvent,
|
|
19
20
|
createElement = HC.createElement,
|
|
20
21
|
discardElement = HC.discardElement,
|
|
21
22
|
css = HC.css,
|
|
@@ -26,7 +27,7 @@ var HC = Highcharts,
|
|
|
26
27
|
mathMax = math.max,
|
|
27
28
|
doc = document,
|
|
28
29
|
win = window,
|
|
29
|
-
hasTouch =
|
|
30
|
+
hasTouch = doc.documentElement.ontouchstart !== undefined,
|
|
30
31
|
M = 'M',
|
|
31
32
|
L = 'L',
|
|
32
33
|
DIV = 'div',
|
|
@@ -35,19 +36,17 @@ var HC = Highcharts,
|
|
|
35
36
|
PREFIX = 'highcharts-',
|
|
36
37
|
ABSOLUTE = 'absolute',
|
|
37
38
|
PX = 'px',
|
|
39
|
+
UNDEFINED,
|
|
40
|
+
defaultOptions = HC.getOptions();
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
downloadSVG: 'Download SVG vector image',
|
|
48
|
-
exportButtonTitle: 'Export to raster or vector image',
|
|
49
|
-
printButtonTitle: 'Print the chart'
|
|
50
|
-
}
|
|
42
|
+
// Add language
|
|
43
|
+
extend(defaultOptions.lang, {
|
|
44
|
+
downloadPNG: 'Download PNG image',
|
|
45
|
+
downloadJPEG: 'Download JPEG image',
|
|
46
|
+
downloadPDF: 'Download PDF document',
|
|
47
|
+
downloadSVG: 'Download SVG vector image',
|
|
48
|
+
exportButtonTitle: 'Export to raster or vector image',
|
|
49
|
+
printButtonTitle: 'Print the chart'
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
// Buttons and menus are collected in a separate config option set called 'navigation'.
|
|
@@ -67,7 +66,7 @@ defaultOptions.navigation = {
|
|
|
67
66
|
background: '#4572A5',
|
|
68
67
|
color: '#FFFFFF'
|
|
69
68
|
},
|
|
70
|
-
|
|
69
|
+
|
|
71
70
|
buttonOptions: {
|
|
72
71
|
align: 'right',
|
|
73
72
|
backgroundColor: {
|
|
@@ -93,7 +92,7 @@ defaultOptions.navigation = {
|
|
|
93
92
|
symbolY: 10.5,
|
|
94
93
|
verticalAlign: 'top',
|
|
95
94
|
width: 24,
|
|
96
|
-
y: 10
|
|
95
|
+
y: 10
|
|
97
96
|
}
|
|
98
97
|
};
|
|
99
98
|
|
|
@@ -106,6 +105,7 @@ defaultOptions.exporting = {
|
|
|
106
105
|
type: 'image/png',
|
|
107
106
|
url: 'http://export.highcharts.com/',
|
|
108
107
|
width: 800,
|
|
108
|
+
enableImages: false,
|
|
109
109
|
buttons: {
|
|
110
110
|
exportButton: {
|
|
111
111
|
//enabled: true,
|
|
@@ -113,29 +113,30 @@ defaultOptions.exporting = {
|
|
|
113
113
|
x: -10,
|
|
114
114
|
symbolFill: '#A8BF77',
|
|
115
115
|
hoverSymbolFill: '#768F3E',
|
|
116
|
+
_id: 'exportButton',
|
|
116
117
|
_titleKey: 'exportButtonTitle',
|
|
117
118
|
menuItems: [{
|
|
118
119
|
textKey: 'downloadPNG',
|
|
119
|
-
onclick: function() {
|
|
120
|
+
onclick: function () {
|
|
120
121
|
this.exportChart();
|
|
121
122
|
}
|
|
122
123
|
}, {
|
|
123
124
|
textKey: 'downloadJPEG',
|
|
124
|
-
onclick: function() {
|
|
125
|
+
onclick: function () {
|
|
125
126
|
this.exportChart({
|
|
126
127
|
type: 'image/jpeg'
|
|
127
128
|
});
|
|
128
129
|
}
|
|
129
130
|
}, {
|
|
130
131
|
textKey: 'downloadPDF',
|
|
131
|
-
onclick: function() {
|
|
132
|
+
onclick: function () {
|
|
132
133
|
this.exportChart({
|
|
133
134
|
type: 'application/pdf'
|
|
134
135
|
});
|
|
135
136
|
}
|
|
136
137
|
}, {
|
|
137
138
|
textKey: 'downloadSVG',
|
|
138
|
-
onclick: function() {
|
|
139
|
+
onclick: function () {
|
|
139
140
|
this.exportChart({
|
|
140
141
|
type: 'image/svg+xml'
|
|
141
142
|
});
|
|
@@ -146,11 +147,11 @@ defaultOptions.exporting = {
|
|
|
146
147
|
var svg = this.getSVG()
|
|
147
148
|
.replace(/</g, '\n<')
|
|
148
149
|
.replace(/>/g, '>');
|
|
149
|
-
|
|
150
|
+
|
|
150
151
|
doc.body.innerHTML = '<pre>'+ svg +'</pre>';
|
|
151
152
|
}
|
|
152
153
|
}*/]
|
|
153
|
-
|
|
154
|
+
|
|
154
155
|
},
|
|
155
156
|
printButton: {
|
|
156
157
|
//enabled: true,
|
|
@@ -158,8 +159,9 @@ defaultOptions.exporting = {
|
|
|
158
159
|
x: -36,
|
|
159
160
|
symbolFill: '#B5C9DF',
|
|
160
161
|
hoverSymbolFill: '#779ABF',
|
|
162
|
+
_id: 'printButton',
|
|
161
163
|
_titleKey: 'printButtonTitle',
|
|
162
|
-
onclick: function() {
|
|
164
|
+
onclick: function () {
|
|
163
165
|
this.print();
|
|
164
166
|
}
|
|
165
167
|
}
|
|
@@ -171,10 +173,10 @@ defaultOptions.exporting = {
|
|
|
171
173
|
extend(Chart.prototype, {
|
|
172
174
|
/**
|
|
173
175
|
* Return an SVG representation of the chart
|
|
174
|
-
*
|
|
176
|
+
*
|
|
175
177
|
* @param additionalOptions {Object} Additional chart options for the generated SVG representation
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
|
+
*/
|
|
179
|
+
getSVG: function (additionalOptions) {
|
|
178
180
|
var chart = this,
|
|
179
181
|
chartCopy,
|
|
180
182
|
sandbox,
|
|
@@ -184,18 +186,20 @@ extend(Chart.prototype, {
|
|
|
184
186
|
pointOptions,
|
|
185
187
|
pointMarker,
|
|
186
188
|
options = merge(chart.options, additionalOptions); // copy the options and add extra options
|
|
187
|
-
|
|
189
|
+
|
|
188
190
|
// IE compatibility hack for generating SVG content that it doesn't really understand
|
|
189
191
|
if (!doc.createElementNS) {
|
|
190
|
-
|
|
192
|
+
/*jslint unparam: true*//* allow unused parameter ns in function below */
|
|
193
|
+
doc.createElementNS = function (ns, tagName) {
|
|
191
194
|
var elem = doc.createElement(tagName);
|
|
192
|
-
elem.getBBox = function() {
|
|
193
|
-
return
|
|
195
|
+
elem.getBBox = function () {
|
|
196
|
+
return HC.Renderer.prototype.Element.prototype.getBBox.apply({ element: elem });
|
|
194
197
|
};
|
|
195
198
|
return elem;
|
|
196
199
|
};
|
|
200
|
+
/*jslint unparam: false*/
|
|
197
201
|
}
|
|
198
|
-
|
|
202
|
+
|
|
199
203
|
// create a sandbox where a new chart will be generated
|
|
200
204
|
sandbox = createElement(DIV, null, {
|
|
201
205
|
position: ABSOLUTE,
|
|
@@ -203,31 +207,38 @@ extend(Chart.prototype, {
|
|
|
203
207
|
width: chart.chartWidth + PX,
|
|
204
208
|
height: chart.chartHeight + PX
|
|
205
209
|
}, doc.body);
|
|
206
|
-
|
|
210
|
+
|
|
207
211
|
// override some options
|
|
208
212
|
extend(options.chart, {
|
|
209
213
|
renderTo: sandbox,
|
|
210
214
|
forExport: true
|
|
211
215
|
});
|
|
212
216
|
options.exporting.enabled = false; // hide buttons in print
|
|
213
|
-
|
|
217
|
+
|
|
218
|
+
if (!options.exporting.enableImages) {
|
|
219
|
+
options.chart.plotBackgroundImage = null; // the converter doesn't handle images
|
|
220
|
+
}
|
|
221
|
+
|
|
214
222
|
// prepare for replicating the chart
|
|
215
223
|
options.series = [];
|
|
216
|
-
each(chart.series, function(serie) {
|
|
217
|
-
seriesOptions = serie.options;
|
|
218
|
-
|
|
224
|
+
each(chart.series, function (serie) {
|
|
225
|
+
seriesOptions = serie.options;
|
|
226
|
+
|
|
219
227
|
seriesOptions.animation = false; // turn off animation
|
|
220
228
|
seriesOptions.showCheckbox = false;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
|
|
229
|
+
seriesOptions.visible = serie.visible;
|
|
230
|
+
|
|
231
|
+
if (!options.exporting.enableImages) {
|
|
232
|
+
// remove image markers
|
|
233
|
+
if (seriesOptions && seriesOptions.marker && /^url\(/.test(seriesOptions.marker.symbol)) {
|
|
234
|
+
seriesOptions.marker.symbol = 'circle';
|
|
235
|
+
}
|
|
225
236
|
}
|
|
226
|
-
|
|
237
|
+
|
|
227
238
|
seriesOptions.data = [];
|
|
228
|
-
|
|
229
|
-
each(serie.data, function(point) {
|
|
230
|
-
|
|
239
|
+
|
|
240
|
+
each(serie.data, function (point) {
|
|
241
|
+
|
|
231
242
|
// extend the options by those values that can be expressed in a number or array config
|
|
232
243
|
config = point.config;
|
|
233
244
|
pointOptions = {
|
|
@@ -236,81 +247,108 @@ extend(Chart.prototype, {
|
|
|
236
247
|
name: point.name
|
|
237
248
|
};
|
|
238
249
|
|
|
239
|
-
if (typeof config
|
|
250
|
+
if (typeof config === 'object' && point.config && config.constructor !== Array) {
|
|
240
251
|
extend(pointOptions, config);
|
|
241
252
|
}
|
|
242
253
|
|
|
254
|
+
pointOptions.visible = point.visible;
|
|
243
255
|
seriesOptions.data.push(pointOptions); // copy fresh updated data
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
|
|
257
|
+
if (!options.exporting.enableImages) {
|
|
258
|
+
// remove image markers
|
|
259
|
+
pointMarker = point.config && point.config.marker;
|
|
260
|
+
if (pointMarker && /^url\(/.test(pointMarker.symbol)) {
|
|
261
|
+
delete pointMarker.symbol;
|
|
262
|
+
}
|
|
249
263
|
}
|
|
250
|
-
});
|
|
251
|
-
|
|
264
|
+
});
|
|
265
|
+
|
|
252
266
|
options.series.push(seriesOptions);
|
|
253
267
|
});
|
|
254
|
-
|
|
268
|
+
|
|
255
269
|
// generate the chart copy
|
|
256
270
|
chartCopy = new Highcharts.Chart(options);
|
|
257
|
-
|
|
271
|
+
|
|
272
|
+
// reflect axis extremes in the export
|
|
273
|
+
each(['xAxis', 'yAxis'], function (axisType) {
|
|
274
|
+
each(chart[axisType], function (axis, i) {
|
|
275
|
+
var axisCopy = chartCopy[axisType][i],
|
|
276
|
+
extremes = axis.getExtremes(),
|
|
277
|
+
userMin = extremes.userMin,
|
|
278
|
+
userMax = extremes.userMax;
|
|
279
|
+
|
|
280
|
+
if (userMin !== UNDEFINED || userMax !== UNDEFINED) {
|
|
281
|
+
axisCopy.setExtremes(userMin, userMax, true, false);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
258
286
|
// get the SVG from the container's innerHTML
|
|
259
287
|
svg = chartCopy.container.innerHTML;
|
|
260
|
-
|
|
288
|
+
|
|
261
289
|
// free up memory
|
|
262
290
|
options = null;
|
|
263
291
|
chartCopy.destroy();
|
|
264
292
|
discardElement(sandbox);
|
|
265
|
-
|
|
293
|
+
|
|
266
294
|
// sanitize
|
|
267
295
|
svg = svg
|
|
268
|
-
.replace(/zIndex="[^"]+"/g, '')
|
|
296
|
+
.replace(/zIndex="[^"]+"/g, '')
|
|
269
297
|
.replace(/isShadow="[^"]+"/g, '')
|
|
270
298
|
.replace(/symbolName="[^"]+"/g, '')
|
|
271
299
|
.replace(/jQuery[0-9]+="[^"]+"/g, '')
|
|
272
300
|
.replace(/isTracker="[^"]+"/g, '')
|
|
273
301
|
.replace(/url\([^#]+#/g, 'url(#')
|
|
274
|
-
|
|
275
|
-
.replace(/ href
|
|
276
|
-
|
|
302
|
+
.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
|
|
303
|
+
.replace(/ href=/g, ' xlink:href=')
|
|
304
|
+
/*.replace(/preserveAspectRatio="none">/g, 'preserveAspectRatio="none"/>')*/
|
|
277
305
|
/* This fails in IE < 8
|
|
278
306
|
.replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
|
|
279
307
|
return s2 +'.'+ s3[0];
|
|
280
|
-
})*/
|
|
281
|
-
|
|
308
|
+
})*/
|
|
309
|
+
|
|
310
|
+
// Replace HTML entities, issue #347
|
|
311
|
+
.replace(/ /g, '\u00A0') // no-break space
|
|
312
|
+
.replace(/­/g, '\u00AD') // soft hyphen
|
|
313
|
+
|
|
282
314
|
// IE specific
|
|
283
|
-
.replace(/id=([^" >]+)/g, 'id="$1"')
|
|
315
|
+
.replace(/id=([^" >]+)/g, 'id="$1"')
|
|
284
316
|
.replace(/class=([^" ]+)/g, 'class="$1"')
|
|
285
317
|
.replace(/ transform /g, ' ')
|
|
286
318
|
.replace(/:(path|rect)/g, '$1')
|
|
287
|
-
.replace(
|
|
319
|
+
.replace(/<img ([^>]*)>/gi, '<image $1 />')
|
|
320
|
+
.replace(/<\/image>/g, '') // remove closing tags for images as they'll never have any content
|
|
321
|
+
.replace(/<image ([^>]*)([^\/])>/gi, '<image $1$2 />') // closes image tags for firefox
|
|
322
|
+
.replace(/width=(\d+)/g, 'width="$1"')
|
|
323
|
+
.replace(/height=(\d+)/g, 'height="$1"')
|
|
324
|
+
.replace(/hc-svg-href="/g, 'xlink:href="')
|
|
325
|
+
.replace(/style="([^"]+)"/g, function (s) {
|
|
288
326
|
return s.toLowerCase();
|
|
289
327
|
});
|
|
290
|
-
|
|
328
|
+
|
|
291
329
|
// IE9 beta bugs with innerHTML. Test again with final IE9.
|
|
292
330
|
svg = svg.replace(/(url\(#highcharts-[0-9]+)"/g, '$1')
|
|
293
331
|
.replace(/"/g, "'");
|
|
294
|
-
if (svg.match(/ xmlns="/g).length
|
|
332
|
+
if (svg.match(/ xmlns="/g).length === 2) {
|
|
295
333
|
svg = svg.replace(/xmlns="[^"]+"/, '');
|
|
296
334
|
}
|
|
297
|
-
|
|
335
|
+
|
|
298
336
|
return svg;
|
|
299
337
|
},
|
|
300
|
-
|
|
338
|
+
|
|
301
339
|
/**
|
|
302
340
|
* Submit the SVG representation of the chart to the server
|
|
303
341
|
* @param {Object} options Exporting options. Possible members are url, type and width.
|
|
304
342
|
* @param {Object} chartOptions Additional chart options for the SVG representation of the chart
|
|
305
343
|
*/
|
|
306
|
-
exportChart: function(options, chartOptions) {
|
|
344
|
+
exportChart: function (options, chartOptions) {
|
|
307
345
|
var form,
|
|
308
346
|
chart = this,
|
|
309
347
|
svg = chart.getSVG(chartOptions);
|
|
310
|
-
|
|
348
|
+
|
|
311
349
|
// merge the options
|
|
312
350
|
options = merge(chart.options.exporting, options);
|
|
313
|
-
|
|
351
|
+
|
|
314
352
|
// create the form
|
|
315
353
|
form = createElement('form', {
|
|
316
354
|
method: 'post',
|
|
@@ -318,82 +356,82 @@ extend(Chart.prototype, {
|
|
|
318
356
|
}, {
|
|
319
357
|
display: NONE
|
|
320
358
|
}, doc.body);
|
|
321
|
-
|
|
359
|
+
|
|
322
360
|
// add the values
|
|
323
|
-
each(['filename', 'type', 'width', 'svg'], function(name) {
|
|
361
|
+
each(['filename', 'type', 'width', 'svg'], function (name) {
|
|
324
362
|
createElement('input', {
|
|
325
363
|
type: HIDDEN,
|
|
326
364
|
name: name,
|
|
327
|
-
value: {
|
|
328
|
-
filename: options.filename || 'chart',
|
|
329
|
-
type: options.type,
|
|
330
|
-
width: options.width,
|
|
331
|
-
svg: svg
|
|
365
|
+
value: {
|
|
366
|
+
filename: options.filename || 'chart',
|
|
367
|
+
type: options.type,
|
|
368
|
+
width: options.width,
|
|
369
|
+
svg: svg
|
|
332
370
|
}[name]
|
|
333
371
|
}, null, form);
|
|
334
372
|
});
|
|
335
|
-
|
|
373
|
+
|
|
336
374
|
// submit
|
|
337
375
|
form.submit();
|
|
338
|
-
|
|
376
|
+
|
|
339
377
|
// clean up
|
|
340
378
|
discardElement(form);
|
|
341
379
|
},
|
|
342
|
-
|
|
380
|
+
|
|
343
381
|
/**
|
|
344
382
|
* Print the chart
|
|
345
383
|
*/
|
|
346
|
-
print: function() {
|
|
347
|
-
|
|
384
|
+
print: function () {
|
|
385
|
+
|
|
348
386
|
var chart = this,
|
|
349
387
|
container = chart.container,
|
|
350
388
|
origDisplay = [],
|
|
351
389
|
origParent = container.parentNode,
|
|
352
390
|
body = doc.body,
|
|
353
391
|
childNodes = body.childNodes;
|
|
354
|
-
|
|
392
|
+
|
|
355
393
|
if (chart.isPrinting) { // block the button while in printing mode
|
|
356
394
|
return;
|
|
357
395
|
}
|
|
358
|
-
|
|
396
|
+
|
|
359
397
|
chart.isPrinting = true;
|
|
360
|
-
|
|
361
|
-
// hide all body content
|
|
362
|
-
each(childNodes, function(node, i) {
|
|
363
|
-
if (node.nodeType
|
|
398
|
+
|
|
399
|
+
// hide all body content
|
|
400
|
+
each(childNodes, function (node, i) {
|
|
401
|
+
if (node.nodeType === 1) {
|
|
364
402
|
origDisplay[i] = node.style.display;
|
|
365
403
|
node.style.display = NONE;
|
|
366
404
|
}
|
|
367
405
|
});
|
|
368
|
-
|
|
406
|
+
|
|
369
407
|
// pull out the chart
|
|
370
408
|
body.appendChild(container);
|
|
371
|
-
|
|
409
|
+
|
|
372
410
|
// print
|
|
373
|
-
win.print();
|
|
374
|
-
|
|
411
|
+
win.print();
|
|
412
|
+
|
|
375
413
|
// allow the browser to prepare before reverting
|
|
376
|
-
setTimeout(function() {
|
|
414
|
+
setTimeout(function () {
|
|
377
415
|
|
|
378
416
|
// put the chart back in
|
|
379
417
|
origParent.appendChild(container);
|
|
380
|
-
|
|
418
|
+
|
|
381
419
|
// restore all body content
|
|
382
|
-
each(childNodes, function(node, i) {
|
|
383
|
-
if (node.nodeType
|
|
420
|
+
each(childNodes, function (node, i) {
|
|
421
|
+
if (node.nodeType === 1) {
|
|
384
422
|
node.style.display = origDisplay[i];
|
|
385
423
|
}
|
|
386
424
|
});
|
|
387
|
-
|
|
425
|
+
|
|
388
426
|
chart.isPrinting = false;
|
|
389
|
-
|
|
427
|
+
|
|
390
428
|
}, 1000);
|
|
391
429
|
|
|
392
430
|
},
|
|
393
|
-
|
|
431
|
+
|
|
394
432
|
/**
|
|
395
|
-
* Display a popup menu for choosing the export type
|
|
396
|
-
*
|
|
433
|
+
* Display a popup menu for choosing the export type
|
|
434
|
+
*
|
|
397
435
|
* @param {String} name An identifier for the menu
|
|
398
436
|
* @param {Array} items A collection with text and onclicks for the items
|
|
399
437
|
* @param {Number} x The x position of the opener button
|
|
@@ -401,24 +439,24 @@ extend(Chart.prototype, {
|
|
|
401
439
|
* @param {Number} width The width of the opener button
|
|
402
440
|
* @param {Number} height The height of the opener button
|
|
403
441
|
*/
|
|
404
|
-
contextMenu: function(name, items, x, y, width, height) {
|
|
442
|
+
contextMenu: function (name, items, x, y, width, height) {
|
|
405
443
|
var chart = this,
|
|
406
444
|
navOptions = chart.options.navigation,
|
|
407
445
|
menuItemStyle = navOptions.menuItemStyle,
|
|
408
446
|
chartWidth = chart.chartWidth,
|
|
409
447
|
chartHeight = chart.chartHeight,
|
|
410
|
-
cacheName = 'cache-'+ name,
|
|
448
|
+
cacheName = 'cache-' + name,
|
|
411
449
|
menu = chart[cacheName],
|
|
412
450
|
menuPadding = mathMax(width, height), // for mouse leave detection
|
|
413
451
|
boxShadow = '3px 3px 10px #888',
|
|
414
452
|
innerMenu,
|
|
415
453
|
hide,
|
|
416
|
-
menuStyle;
|
|
417
|
-
|
|
454
|
+
menuStyle;
|
|
455
|
+
|
|
418
456
|
// create the menu only the first time
|
|
419
457
|
if (!menu) {
|
|
420
|
-
|
|
421
|
-
// create a HTML element above the SVG
|
|
458
|
+
|
|
459
|
+
// create a HTML element above the SVG
|
|
422
460
|
chart[cacheName] = menu = createElement(DIV, {
|
|
423
461
|
className: PREFIX + name
|
|
424
462
|
}, {
|
|
@@ -426,51 +464,56 @@ extend(Chart.prototype, {
|
|
|
426
464
|
zIndex: 1000,
|
|
427
465
|
padding: menuPadding + PX
|
|
428
466
|
}, chart.container);
|
|
429
|
-
|
|
430
|
-
innerMenu = createElement(DIV, null,
|
|
467
|
+
|
|
468
|
+
innerMenu = createElement(DIV, null,
|
|
431
469
|
extend({
|
|
432
470
|
MozBoxShadow: boxShadow,
|
|
433
471
|
WebkitBoxShadow: boxShadow,
|
|
434
472
|
boxShadow: boxShadow
|
|
435
|
-
}, navOptions.menuStyle)
|
|
436
|
-
|
|
473
|
+
}, navOptions.menuStyle), menu);
|
|
474
|
+
|
|
437
475
|
// hide on mouse out
|
|
438
|
-
hide = function() {
|
|
476
|
+
hide = function () {
|
|
439
477
|
css(menu, { display: NONE });
|
|
440
478
|
};
|
|
441
|
-
|
|
479
|
+
|
|
442
480
|
addEvent(menu, 'mouseleave', hide);
|
|
443
|
-
|
|
444
|
-
|
|
481
|
+
|
|
482
|
+
|
|
445
483
|
// create the items
|
|
446
|
-
each(items, function(item) {
|
|
484
|
+
each(items, function (item) {
|
|
447
485
|
if (item) {
|
|
448
486
|
var div = createElement(DIV, {
|
|
449
|
-
onmouseover: function() {
|
|
487
|
+
onmouseover: function () {
|
|
450
488
|
css(this, navOptions.menuItemHoverStyle);
|
|
451
489
|
},
|
|
452
|
-
onmouseout: function() {
|
|
490
|
+
onmouseout: function () {
|
|
453
491
|
css(this, menuItemStyle);
|
|
454
492
|
},
|
|
455
|
-
innerHTML: item.text ||
|
|
493
|
+
innerHTML: item.text || chart.options.lang[item.textKey]
|
|
456
494
|
}, extend({
|
|
457
495
|
cursor: 'pointer'
|
|
458
496
|
}, menuItemStyle), innerMenu);
|
|
459
|
-
|
|
460
|
-
div[hasTouch ? 'ontouchstart' : 'onclick'] = function() {
|
|
497
|
+
|
|
498
|
+
div[hasTouch ? 'ontouchstart' : 'onclick'] = function () {
|
|
461
499
|
hide();
|
|
462
500
|
item.onclick.apply(chart, arguments);
|
|
463
501
|
};
|
|
464
|
-
|
|
502
|
+
|
|
503
|
+
// Keep references to menu divs to be able to destroy them
|
|
504
|
+
chart.exportDivElements.push(div);
|
|
465
505
|
}
|
|
466
506
|
});
|
|
467
|
-
|
|
507
|
+
|
|
508
|
+
// Keep references to menu and innerMenu div to be able to destroy them
|
|
509
|
+
chart.exportDivElements.push(innerMenu, menu);
|
|
510
|
+
|
|
468
511
|
chart.exportMenuWidth = menu.offsetWidth;
|
|
469
512
|
chart.exportMenuHeight = menu.offsetHeight;
|
|
470
513
|
}
|
|
471
|
-
|
|
514
|
+
|
|
472
515
|
menuStyle = { display: 'block' };
|
|
473
|
-
|
|
516
|
+
|
|
474
517
|
// if outside right, right align it
|
|
475
518
|
if (x + chart.exportMenuWidth > chartWidth) {
|
|
476
519
|
menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
|
|
@@ -483,14 +526,14 @@ extend(Chart.prototype, {
|
|
|
483
526
|
} else {
|
|
484
527
|
menuStyle.top = (y + height - menuPadding) + PX;
|
|
485
528
|
}
|
|
486
|
-
|
|
529
|
+
|
|
487
530
|
css(menu, menuStyle);
|
|
488
531
|
},
|
|
489
|
-
|
|
532
|
+
|
|
490
533
|
/**
|
|
491
534
|
* Add the export button to the chart
|
|
492
535
|
*/
|
|
493
|
-
addButton: function(options) {
|
|
536
|
+
addButton: function (options) {
|
|
494
537
|
var chart = this,
|
|
495
538
|
renderer = chart.renderer,
|
|
496
539
|
btnOptions = merge(chart.options.navigation.buttonOptions, options),
|
|
@@ -503,32 +546,38 @@ extend(Chart.prototype, {
|
|
|
503
546
|
buttonHeight = btnOptions.height,
|
|
504
547
|
box,
|
|
505
548
|
symbol,
|
|
506
|
-
button,
|
|
549
|
+
button,
|
|
507
550
|
borderWidth = btnOptions.borderWidth,
|
|
508
551
|
boxAttr = {
|
|
509
552
|
stroke: btnOptions.borderColor
|
|
510
|
-
|
|
553
|
+
|
|
511
554
|
},
|
|
512
555
|
symbolAttr = {
|
|
513
556
|
stroke: btnOptions.symbolStroke,
|
|
514
557
|
fill: btnOptions.symbolFill
|
|
515
558
|
};
|
|
516
|
-
|
|
559
|
+
|
|
560
|
+
// Keeps references to the button elements
|
|
561
|
+
if (!chart.exportDivElements) {
|
|
562
|
+
chart.exportDivElements = [];
|
|
563
|
+
chart.exportSVGElements = [];
|
|
564
|
+
}
|
|
565
|
+
|
|
517
566
|
if (btnOptions.enabled === false) {
|
|
518
567
|
return;
|
|
519
568
|
}
|
|
520
|
-
|
|
569
|
+
|
|
521
570
|
// element to capture the click
|
|
522
571
|
function revert() {
|
|
523
572
|
symbol.attr(symbolAttr);
|
|
524
573
|
box.attr(boxAttr);
|
|
525
574
|
}
|
|
526
|
-
|
|
575
|
+
|
|
527
576
|
// the box border
|
|
528
577
|
box = renderer.rect(
|
|
529
578
|
0,
|
|
530
579
|
0,
|
|
531
|
-
buttonWidth,
|
|
580
|
+
buttonWidth,
|
|
532
581
|
buttonHeight,
|
|
533
582
|
btnOptions.borderRadius,
|
|
534
583
|
borderWidth
|
|
@@ -540,9 +589,9 @@ extend(Chart.prototype, {
|
|
|
540
589
|
'stroke-width': borderWidth,
|
|
541
590
|
zIndex: 19
|
|
542
591
|
}, boxAttr)).add();
|
|
543
|
-
|
|
592
|
+
|
|
544
593
|
// the invisible element to track the clicks
|
|
545
|
-
button = renderer.rect(
|
|
594
|
+
button = renderer.rect(
|
|
546
595
|
0,
|
|
547
596
|
0,
|
|
548
597
|
buttonWidth,
|
|
@@ -551,13 +600,14 @@ extend(Chart.prototype, {
|
|
|
551
600
|
)
|
|
552
601
|
.align(btnOptions)
|
|
553
602
|
.attr({
|
|
603
|
+
id: btnOptions._id,
|
|
554
604
|
fill: 'rgba(255, 255, 255, 0.001)',
|
|
555
|
-
title:
|
|
605
|
+
title: chart.options.lang[btnOptions._titleKey],
|
|
556
606
|
zIndex: 21
|
|
557
607
|
}).css({
|
|
558
608
|
cursor: 'pointer'
|
|
559
609
|
})
|
|
560
|
-
.on('mouseover', function() {
|
|
610
|
+
.on('mouseover', function () {
|
|
561
611
|
symbol.attr({
|
|
562
612
|
stroke: btnOptions.hoverSymbolStroke,
|
|
563
613
|
fill: btnOptions.hoverSymbolFill
|
|
@@ -569,12 +619,12 @@ extend(Chart.prototype, {
|
|
|
569
619
|
.on('mouseout', revert)
|
|
570
620
|
.on('click', revert)
|
|
571
621
|
.add();
|
|
572
|
-
|
|
622
|
+
|
|
573
623
|
//addEvent(button.element, 'click', revert);
|
|
574
|
-
|
|
624
|
+
|
|
575
625
|
// add the click event
|
|
576
626
|
if (menuItems) {
|
|
577
|
-
onclick = function(
|
|
627
|
+
onclick = function () {
|
|
578
628
|
revert();
|
|
579
629
|
var bBox = button.getBBox();
|
|
580
630
|
chart.contextMenu('export-menu', menuItems, bBox.x, bBox.y, buttonWidth, buttonHeight);
|
|
@@ -583,30 +633,61 @@ extend(Chart.prototype, {
|
|
|
583
633
|
/*addEvent(button.element, 'click', function() {
|
|
584
634
|
onclick.apply(chart, arguments);
|
|
585
635
|
});*/
|
|
586
|
-
button.on('click', function() {
|
|
636
|
+
button.on('click', function () {
|
|
587
637
|
onclick.apply(chart, arguments);
|
|
588
638
|
});
|
|
589
|
-
|
|
639
|
+
|
|
590
640
|
// the icon
|
|
591
641
|
symbol = renderer.symbol(
|
|
592
|
-
btnOptions.symbol,
|
|
593
|
-
btnOptions.symbolX,
|
|
594
|
-
btnOptions.symbolY,
|
|
642
|
+
btnOptions.symbol,
|
|
643
|
+
btnOptions.symbolX,
|
|
644
|
+
btnOptions.symbolY,
|
|
595
645
|
(btnOptions.symbolSize || 12) / 2
|
|
596
646
|
)
|
|
597
647
|
.align(btnOptions, true)
|
|
598
648
|
.attr(extend(symbolAttr, {
|
|
599
649
|
'stroke-width': btnOptions.symbolStrokeWidth || 1,
|
|
600
|
-
zIndex: 20
|
|
650
|
+
zIndex: 20
|
|
601
651
|
})).add();
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
652
|
+
|
|
653
|
+
// Keep references to the renderer element so to be able to destroy them later.
|
|
654
|
+
chart.exportSVGElements.push(box, button, symbol);
|
|
655
|
+
},
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Destroy the buttons.
|
|
659
|
+
*/
|
|
660
|
+
destroyExport: function () {
|
|
661
|
+
var i,
|
|
662
|
+
chart = this,
|
|
663
|
+
elem;
|
|
664
|
+
|
|
665
|
+
// Destroy the extra buttons added
|
|
666
|
+
for (i = 0; i < chart.exportSVGElements.length; i++) {
|
|
667
|
+
elem = chart.exportSVGElements[i];
|
|
668
|
+
// Destroy and null the svg/vml elements
|
|
669
|
+
elem.onclick = elem.ontouchstart = null;
|
|
670
|
+
chart.exportSVGElements[i] = elem.destroy();
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Destroy the divs for the menu
|
|
674
|
+
for (i = 0; i < chart.exportDivElements.length; i++) {
|
|
675
|
+
elem = chart.exportDivElements[i];
|
|
676
|
+
|
|
677
|
+
// Remove the event handler
|
|
678
|
+
removeEvent(elem, 'mouseleave');
|
|
679
|
+
|
|
680
|
+
// Remove inline events
|
|
681
|
+
chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;
|
|
682
|
+
|
|
683
|
+
// Destroy the div by moving to garbage bin
|
|
684
|
+
discardElement(elem);
|
|
685
|
+
}
|
|
605
686
|
}
|
|
606
687
|
});
|
|
607
688
|
|
|
608
689
|
// Create the export icon
|
|
609
|
-
HC.Renderer.prototype.symbols.exportIcon = function(x, y, radius) {
|
|
690
|
+
HC.Renderer.prototype.symbols.exportIcon = function (x, y, radius) {
|
|
610
691
|
return [
|
|
611
692
|
M, // the disk
|
|
612
693
|
x - radius, y + radius,
|
|
@@ -628,7 +709,7 @@ HC.Renderer.prototype.symbols.exportIcon = function(x, y, radius) {
|
|
|
628
709
|
];
|
|
629
710
|
};
|
|
630
711
|
// Create the print icon
|
|
631
|
-
HC.Renderer.prototype.symbols.printIcon = function(x, y, radius) {
|
|
712
|
+
HC.Renderer.prototype.symbols.printIcon = function (x, y, radius) {
|
|
632
713
|
return [
|
|
633
714
|
M, // the printer
|
|
634
715
|
x - radius, y + radius * 0.5,
|
|
@@ -656,7 +737,7 @@ HC.Renderer.prototype.symbols.printIcon = function(x, y, radius) {
|
|
|
656
737
|
|
|
657
738
|
|
|
658
739
|
// Add the buttons on chart load
|
|
659
|
-
Chart.prototype.callbacks.push(function(chart) {
|
|
740
|
+
Chart.prototype.callbacks.push(function (chart) {
|
|
660
741
|
var n,
|
|
661
742
|
exportingOptions = chart.options.exporting,
|
|
662
743
|
buttons = exportingOptions.buttons;
|
|
@@ -666,8 +747,12 @@ Chart.prototype.callbacks.push(function(chart) {
|
|
|
666
747
|
for (n in buttons) {
|
|
667
748
|
chart.addButton(buttons[n]);
|
|
668
749
|
}
|
|
750
|
+
|
|
751
|
+
// Destroy the export elements at chart destroy
|
|
752
|
+
addEvent(chart, 'destroy', chart.destroyExport);
|
|
669
753
|
}
|
|
754
|
+
|
|
670
755
|
});
|
|
671
756
|
|
|
672
757
|
|
|
673
|
-
}
|
|
758
|
+
}());
|