source: consulta_publica/static/js/exporting.src.js @ 7095598

estudiantesgeneralplan_patriasala
Last change on this file since 7095598 was 4ba8671, checked in by rudmanmrrod <rudman22@…>, 7 años ago

Agregado archivo para exportar gráficos

  • Propiedad mode establecida a 100755
File size: 16.6 KB
Línea 
1/**
2 * @license Highcharts JS v3.0.5 (2013-08-23)
3 * Exporting module
4 *
5 * (c) 2010-2013 Torstein HÞnsi
6 *
7 * License: www.highcharts.com/license
8 */
9
10// JSLint options:
11/*global Highcharts, document, window, Math, setTimeout */
12
13(function (Highcharts) { // encapsulate
14
15// create shortcuts
16var Chart = Highcharts.Chart,
17        addEvent = Highcharts.addEvent,
18        removeEvent = Highcharts.removeEvent,
19        createElement = Highcharts.createElement,
20        discardElement = Highcharts.discardElement,
21        css = Highcharts.css,
22        merge = Highcharts.merge,
23        each = Highcharts.each,
24        extend = Highcharts.extend,
25        math = Math,
26        mathMax = math.max,
27        doc = document,
28        win = window,
29        isTouchDevice = Highcharts.isTouchDevice,
30        M = 'M',
31        L = 'L',
32        DIV = 'div',
33        HIDDEN = 'hidden',
34        NONE = 'none',
35        PREFIX = 'highcharts-',
36        ABSOLUTE = 'absolute',
37        PX = 'px',
38        UNDEFINED,
39        symbols = Highcharts.Renderer.prototype.symbols,
40        defaultOptions = Highcharts.getOptions(),
41        buttonOffset;
42
43        // Add language
44        extend(defaultOptions.lang, {
45                printChart: 'Imprimir Gráfico',
46                downloadPNG: 'Descargar imagen PNG',
47                downloadJPEG: 'Descargar imagen JPEG',
48                downloadPDF: 'Descargar documento PDF',
49                downloadSVG: 'Descargar imagen de vector SVG',
50                contextButtonTitle: 'Chart context menu'
51        });
52
53// Buttons and menus are collected in a separate config option set called 'navigation'.
54// This can be extended later to add control buttons like zoom and pan right click menus.
55defaultOptions.navigation = {
56        menuStyle: {
57                border: '1px solid #A0A0A0',
58                background: '#FFFFFF',
59                padding: '5px 0'
60        },
61        menuItemStyle: {
62                padding: '0 10px',
63                background: NONE,
64                color: '#303030',
65                fontSize: isTouchDevice ? '14px' : '11px'
66        },
67        menuItemHoverStyle: {
68                background: '#4572A5',
69                color: '#FFFFFF'
70        },
71
72        buttonOptions: {
73                symbolFill: '#E0E0E0',
74                symbolSize: 14,
75                symbolStroke: '#666',
76                symbolStrokeWidth: 3,
77                symbolX: 12.5,
78                symbolY: 10.5,
79                align: 'right',
80                buttonSpacing: 3, 
81                height: 22,
82                // text: null,
83                theme: {
84                        fill: 'white', // capture hover
85                        stroke: 'none'
86                },
87                verticalAlign: 'top',
88                width: 24
89        }
90};
91
92
93
94// Add the export related options
95defaultOptions.exporting = {
96        //enabled: true,
97        //filename: 'chart',
98        type: 'image/png',
99        url: 'http://export.highcharts.com/',
100        //width: undefined,
101        //scale: 2
102        buttons: {
103                contextButton: {
104                        //x: -10,
105                        symbol: 'menu',
106                        _titleKey: 'contextButtonTitle',
107                        menuItems: [{
108                                textKey: 'printChart',
109                                onclick: function () {
110                                        this.print();
111                                }
112                        }, {
113                                separator: true
114                        }, {
115                                textKey: 'downloadPNG',
116                                onclick: function () {
117                                        this.exportChart();
118                                }
119                        }, {
120                                textKey: 'downloadJPEG',
121                                onclick: function () {
122                                        this.exportChart({
123                                                type: 'image/jpeg'
124                                        });
125                                }
126                        }, {
127                                textKey: 'downloadPDF',
128                                onclick: function () {
129                                        this.exportChart({
130                                                type: 'application/pdf'
131                                        });
132                                }
133                        }, {
134                                textKey: 'downloadSVG',
135                                onclick: function () {
136                                        this.exportChart({
137                                                type: 'image/svg+xml'
138                                        });
139                                }
140                        }
141                        // Enable this block to add "View SVG" to the dropdown menu
142                        /*
143                        ,{
144
145                                text: 'View SVG',
146                                onclick: function () {
147                                        var svg = this.getSVG()
148                                                .replace(/</g, '\n&lt;')
149                                                .replace(/>/g, '&gt;');
150
151                                        doc.body.innerHTML = '<pre>' + svg + '</pre>';
152                                }
153                        } // */
154                        ]
155                }
156        }
157};
158
159// Add the Highcharts.post utility
160Highcharts.post = function (url, data) {
161        var name,
162                form;
163       
164        // create the form
165        form = createElement('form', {
166                method: 'post',
167                action: url,
168                enctype: 'multipart/form-data'
169        }, {
170                display: NONE
171        }, doc.body);
172
173        // add the data
174        for (name in data) {
175                createElement('input', {
176                        type: HIDDEN,
177                        name: name,
178                        value: data[name]
179                }, null, form);
180        }
181
182        // submit
183        form.submit();
184
185        // clean up
186        discardElement(form);
187};
188
189extend(Chart.prototype, {
190
191        /**
192         * Return an SVG representation of the chart
193         *
194         * @param additionalOptions {Object} Additional chart options for the generated SVG representation
195         */
196        getSVG: function (additionalOptions) {
197                var chart = this,
198                        chartCopy,
199                        sandbox,
200                        svg,
201                        seriesOptions,
202                        sourceWidth,
203                        sourceHeight,
204                        cssWidth,
205                        cssHeight,
206                        options = merge(chart.options, additionalOptions); // copy the options and add extra options
207
208                // IE compatibility hack for generating SVG content that it doesn't really understand
209                if (!doc.createElementNS) {
210                        /*jslint unparam: true*//* allow unused parameter ns in function below */
211                        doc.createElementNS = function (ns, tagName) {
212                                return doc.createElement(tagName);
213                        };
214                        /*jslint unparam: false*/
215                }
216
217                // create a sandbox where a new chart will be generated
218                sandbox = createElement(DIV, null, {
219                        position: ABSOLUTE,
220                        top: '-9999em',
221                        width: chart.chartWidth + PX,
222                        height: chart.chartHeight + PX
223                }, doc.body);
224               
225                // get the source size
226                cssWidth = chart.renderTo.style.width;
227                cssHeight = chart.renderTo.style.height;
228                sourceWidth = options.exporting.sourceWidth ||
229                        options.chart.width ||
230                        (/px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||
231                        600;
232                sourceHeight = options.exporting.sourceHeight ||
233                        options.chart.height ||
234                        (/px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||
235                        400;
236
237                // override some options
238                extend(options.chart, {
239                        animation: false,
240                        renderTo: sandbox,
241                        forExport: true,
242                        width: sourceWidth,
243                        height: sourceHeight
244                });
245                options.exporting.enabled = false; // hide buttons in print
246               
247                // prepare for replicating the chart
248                options.series = [];
249                each(chart.series, function (serie) {
250                        seriesOptions = merge(serie.options, {
251                                animation: false, // turn off animation
252                                showCheckbox: false,
253                                visible: serie.visible
254                        });
255
256                        if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
257                                options.series.push(seriesOptions);
258                        }
259                });
260
261                // generate the chart copy
262                chartCopy = new Highcharts.Chart(options, chart.callback);
263
264                // reflect axis extremes in the export
265                each(['xAxis', 'yAxis'], function (axisType) {
266                        each(chart[axisType], function (axis, i) {
267                                var axisCopy = chartCopy[axisType][i],
268                                        extremes = axis.getExtremes(),
269                                        userMin = extremes.userMin,
270                                        userMax = extremes.userMax;
271
272                                if (axisCopy && (userMin !== UNDEFINED || userMax !== UNDEFINED)) {
273                                        axisCopy.setExtremes(userMin, userMax, true, false);
274                                }
275                        });
276                });
277
278                // get the SVG from the container's innerHTML
279                svg = chartCopy.container.innerHTML;
280
281                // free up memory
282                options = null;
283                chartCopy.destroy();
284                discardElement(sandbox);
285
286                // sanitize
287                svg = svg
288                        .replace(/zIndex="[^"]+"/g, '')
289                        .replace(/isShadow="[^"]+"/g, '')
290                        .replace(/symbolName="[^"]+"/g, '')
291                        .replace(/jQuery[0-9]+="[^"]+"/g, '')
292                        .replace(/url\([^#]+#/g, 'url(#')
293                        .replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
294                        .replace(/ href=/g, ' xlink:href=')
295                        .replace(/\n/, ' ')
296                        .replace(/<\/svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)
297                        /* This fails in IE < 8
298                        .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
299                                return s2 +'.'+ s3[0];
300                        })*/
301
302                        // Replace HTML entities, issue #347
303                        .replace(/&nbsp;/g, '\u00A0') // no-break space
304                        .replace(/&shy;/g,  '\u00AD') // soft hyphen
305
306                        // IE specific
307                        .replace(/<IMG /g, '<image ')
308                        .replace(/height=([^" ]+)/g, 'height="$1"')
309                        .replace(/width=([^" ]+)/g, 'width="$1"')
310                        .replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
311                        .replace(/id=([^" >]+)/g, 'id="$1"')
312                        .replace(/class=([^" >]+)/g, 'class="$1"')
313                        .replace(/ transform /g, ' ')
314                        .replace(/:(path|rect)/g, '$1')
315                        .replace(/style="([^"]+)"/g, function (s) {
316                                return s.toLowerCase();
317                        });
318
319                // IE9 beta bugs with innerHTML. Test again with final IE9.
320                svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
321                        .replace(/&quot;/g, "'");
322
323                return svg;
324        },
325
326        /**
327         * Submit the SVG representation of the chart to the server
328         * @param {Object} options Exporting options. Possible members are url, type and width.
329         * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
330         */
331        exportChart: function (options, chartOptions) {
332                options = options || {};
333               
334                var chart = this,
335                        chartExportingOptions = chart.options.exporting,
336                        svg = chart.getSVG(merge(
337                                { chart: { borderRadius: 0 } },
338                                chartExportingOptions.chartOptions,
339                                chartOptions, 
340                                {
341                                        exporting: {
342                                                sourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth,
343                                                sourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight
344                                        }
345                                }
346                        ));
347
348                // merge the options
349                options = merge(chart.options.exporting, options);
350               
351                // do the post
352                Highcharts.post(options.url, {
353                        filename: options.filename || 'chart',
354                        type: options.type,
355                        width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
356                        scale: options.scale || 2,
357                        svg: svg
358                });
359
360        },
361       
362        /**
363         * Print the chart
364         */
365        print: function () {
366
367                var chart = this,
368                        container = chart.container,
369                        origDisplay = [],
370                        origParent = container.parentNode,
371                        body = doc.body,
372                        childNodes = body.childNodes;
373
374                if (chart.isPrinting) { // block the button while in printing mode
375                        return;
376                }
377
378                chart.isPrinting = true;
379
380                // hide all body content
381                each(childNodes, function (node, i) {
382                        if (node.nodeType === 1) {
383                                origDisplay[i] = node.style.display;
384                                node.style.display = NONE;
385                        }
386                });
387
388                // pull out the chart
389                body.appendChild(container);
390
391                // print
392                win.focus(); // #1510
393                win.print();
394
395                // allow the browser to prepare before reverting
396                setTimeout(function () {
397
398                        // put the chart back in
399                        origParent.appendChild(container);
400
401                        // restore all body content
402                        each(childNodes, function (node, i) {
403                                if (node.nodeType === 1) {
404                                        node.style.display = origDisplay[i];
405                                }
406                        });
407
408                        chart.isPrinting = false;
409
410                }, 1000);
411
412        },
413
414        /**
415         * Display a popup menu for choosing the export type
416         *
417         * @param {String} name An identifier for the menu
418         * @param {Array} items A collection with text and onclicks for the items
419         * @param {Number} x The x position of the opener button
420         * @param {Number} y The y position of the opener button
421         * @param {Number} width The width of the opener button
422         * @param {Number} height The height of the opener button
423         */
424        contextMenu: function (name, items, x, y, width, height, button) {
425                var chart = this,
426                        navOptions = chart.options.navigation,
427                        menuItemStyle = navOptions.menuItemStyle,
428                        chartWidth = chart.chartWidth,
429                        chartHeight = chart.chartHeight,
430                        cacheName = 'cache-' + name,
431                        menu = chart[cacheName],
432                        menuPadding = mathMax(width, height), // for mouse leave detection
433                        boxShadow = '3px 3px 10px #888',
434                        innerMenu,
435                        hide,
436                        hideTimer,
437                        menuStyle;
438
439                // create the menu only the first time
440                if (!menu) {
441
442                        // create a HTML element above the SVG
443                        chart[cacheName] = menu = createElement(DIV, {
444                                className: PREFIX + name
445                        }, {
446                                position: ABSOLUTE,
447                                zIndex: 1000,
448                                padding: menuPadding + PX
449                        }, chart.container);
450
451                        innerMenu = createElement(DIV, null,
452                                extend({
453                                        MozBoxShadow: boxShadow,
454                                        WebkitBoxShadow: boxShadow,
455                                        boxShadow: boxShadow
456                                }, navOptions.menuStyle), menu);
457
458                        // hide on mouse out
459                        hide = function () {
460                                css(menu, { display: NONE });
461                                if (button) {
462                                        button.setState(0);
463                                }
464                                chart.openMenu = false;
465                        };
466
467                        // Hide the menu some time after mouse leave (#1357)
468                        addEvent(menu, 'mouseleave', function () {
469                                hideTimer = setTimeout(hide, 500);
470                        });
471                        addEvent(menu, 'mouseenter', function () {
472                                clearTimeout(hideTimer);
473                        });
474
475
476                        // create the items
477                        each(items, function (item) {
478                                if (item) {
479                                        var element = item.separator ? 
480                                                createElement('hr', null, null, innerMenu) :
481                                                createElement(DIV, {
482                                                        onmouseover: function () {
483                                                                css(this, navOptions.menuItemHoverStyle);
484                                                        },
485                                                        onmouseout: function () {
486                                                                css(this, menuItemStyle);
487                                                        },
488                                                        onclick: function () {
489                                                                hide();
490                                                                item.onclick.apply(chart, arguments);
491                                                        },
492                                                        innerHTML: item.text || chart.options.lang[item.textKey]
493                                                }, extend({
494                                                        cursor: 'pointer'
495                                                }, menuItemStyle), innerMenu);
496
497
498                                        // Keep references to menu divs to be able to destroy them
499                                        chart.exportDivElements.push(element);
500                                }
501                        });
502
503                        // Keep references to menu and innerMenu div to be able to destroy them
504                        chart.exportDivElements.push(innerMenu, menu);
505
506                        chart.exportMenuWidth = menu.offsetWidth;
507                        chart.exportMenuHeight = menu.offsetHeight;
508                }
509
510                menuStyle = { display: 'block' };
511
512                // if outside right, right align it
513                if (x + chart.exportMenuWidth > chartWidth) {
514                        menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
515                } else {
516                        menuStyle.left = (x - menuPadding) + PX;
517                }
518                // if outside bottom, bottom align it
519                if (y + height + chart.exportMenuHeight > chartHeight && button.alignOptions.verticalAlign !== 'top') {
520                        menuStyle.bottom = (chartHeight - y - menuPadding)  + PX;
521                } else {
522                        menuStyle.top = (y + height - menuPadding) + PX;
523                }
524
525                css(menu, menuStyle);
526                chart.openMenu = true;
527        },
528
529        /**
530         * Add the export button to the chart
531         */
532        addButton: function (options) {
533                var chart = this,
534                        renderer = chart.renderer,
535                        btnOptions = merge(chart.options.navigation.buttonOptions, options),
536                        onclick = btnOptions.onclick,
537                        menuItems = btnOptions.menuItems,
538                        symbol,
539                        button,
540                        symbolAttr = {
541                                stroke: btnOptions.symbolStroke,
542                                fill: btnOptions.symbolFill
543                        },
544                        symbolSize = btnOptions.symbolSize || 12,
545                        menuKey;
546
547                if (!chart.btnCount) {
548                        chart.btnCount = 0;
549                }
550                menuKey = chart.btnCount++;
551
552                // Keeps references to the button elements
553                if (!chart.exportDivElements) {
554                        chart.exportDivElements = [];
555                        chart.exportSVGElements = [];
556                }
557
558                if (btnOptions.enabled === false) {
559                        return;
560                }
561
562
563                var attr = btnOptions.theme,
564                        states = attr.states,
565                        hover = states && states.hover,
566                        select = states && states.select,
567                        callback;
568
569                delete attr.states;
570
571                if (onclick) {
572                        callback = function () {
573                                onclick.apply(chart, arguments);
574                        };
575
576                } else if (menuItems) {
577                        callback = function () {
578                                chart.contextMenu(
579                                        'contextmenu', 
580                                        menuItems, 
581                                        button.translateX, 
582                                        button.translateY, 
583                                        button.width, 
584                                        button.height,
585                                        button
586                                );
587                                button.setState(2);
588                        };
589                }
590
591
592                if (btnOptions.text && btnOptions.symbol) {
593                        attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
594               
595                } else if (!btnOptions.text) {
596                        extend(attr, {
597                                width: btnOptions.width,
598                                height: btnOptions.height,
599                                padding: 0
600                        });
601                }
602
603                button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
604                        .attr({
605                                title: chart.options.lang[btnOptions._titleKey],
606                                'stroke-linecap': 'round'
607                        });
608
609                if (btnOptions.symbol) {
610                        symbol = renderer.symbol(
611                                        btnOptions.symbol,
612                                        btnOptions.symbolX - (symbolSize / 2),
613                                        btnOptions.symbolY - (symbolSize / 2),
614                                        symbolSize,                             
615                                        symbolSize
616                                )
617                                .attr(extend(symbolAttr, {
618                                        'stroke-width': btnOptions.symbolStrokeWidth || 1,
619                                        zIndex: 1
620                                })).add(button);
621                }
622
623                button.add()
624                        .align(extend(btnOptions, {
625                                width: button.width,
626                                x: Highcharts.pick(btnOptions.x, buttonOffset) // #1654
627                        }), true, 'spacingBox');
628
629                buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);
630
631                chart.exportSVGElements.push(button, symbol);
632
633        },
634
635        /**
636         * Destroy the buttons.
637         */
638        destroyExport: function (e) {
639                var chart = e.target,
640                        i,
641                        elem;
642
643                // Destroy the extra buttons added
644                for (i = 0; i < chart.exportSVGElements.length; i++) {
645                        elem = chart.exportSVGElements[i];
646                       
647                        // Destroy and null the svg/vml elements
648                        if (elem) { // #1822
649                                elem.onclick = elem.ontouchstart = null;
650                                chart.exportSVGElements[i] = elem.destroy();
651                        }
652                }
653
654                // Destroy the divs for the menu
655                for (i = 0; i < chart.exportDivElements.length; i++) {
656                        elem = chart.exportDivElements[i];
657
658                        // Remove the event handler
659                        removeEvent(elem, 'mouseleave');
660
661                        // Remove inline events
662                        chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;
663
664                        // Destroy the div by moving to garbage bin
665                        discardElement(elem);
666                }
667        }
668});
669
670
671symbols.menu = function (x, y, width, height) {
672        var arr = [
673                M, x, y + 2.5,
674                L, x + width, y + 2.5,
675                M, x, y + height / 2 + 0.5,
676                L, x + width, y + height / 2 + 0.5,
677                M, x, y + height - 1.5,
678                L, x + width, y + height - 1.5
679        ];
680        return arr;
681};
682
683// Add the buttons on chart load
684Chart.prototype.callbacks.push(function (chart) {
685        var n,
686                exportingOptions = chart.options.exporting,
687                buttons = exportingOptions.buttons;
688
689        buttonOffset = 0;
690
691        if (exportingOptions.enabled !== false) {
692
693                for (n in buttons) {
694                        chart.addButton(buttons[n]);
695                }
696
697                // Destroy the export elements at chart destroy
698                addEvent(chart, 'destroy', chart.destroyExport);
699        }
700
701});
702
703
704}(Highcharts));
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.