contour 0.5.7 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}());
|