Вход Регистрация
Файл: protected/extensions/widgets/highcharts/assets/modules/exporting.src.js
Строк: 760
<?php
/**
 * @license Highcharts JS v3.0.4 (2013-08-02)
 * Exporting module
 *
 * (c) 2010-2013 Torstein Hønsi
 *
 * License: www.highcharts.com/license
 */

// JSLint options:
/*global Highcharts, document, window, Math, setTimeout */

(function (Highcharts) { // encapsulate

// create shortcuts
var Chart = Highcharts.Chart,
    
addEvent = Highcharts.addEvent,
    
removeEvent = Highcharts.removeEvent,
    
createElement = Highcharts.createElement,
    
discardElement = Highcharts.discardElement,
    
css = Highcharts.css,
    
merge = Highcharts.merge,
    
each = Highcharts.each,
    
extend = Highcharts.extend,
    
math = Math,
    
mathMax = math.max,
    
doc = document,
    
win = window,
    
isTouchDevice = Highcharts.isTouchDevice,
    
M = 'M',
    
L = 'L',
    
DIV = 'div',
    
HIDDEN = 'hidden',
    
NONE = 'none',
    
PREFIX = 'highcharts-',
    
ABSOLUTE = 'absolute',
    
PX = 'px',
    
UNDEFINED,
    
symbols = Highcharts.Renderer.prototype.symbols,
    
defaultOptions = Highcharts.getOptions(),
    
buttonOffset;

    
// Add language
    
extend(defaultOptions.lang, {
        
printChart: 'Print chart',
        
downloadPNG: 'Download PNG image',
        
downloadJPEG: 'Download JPEG image',
        
downloadPDF: 'Download PDF document',
        
downloadSVG: 'Download SVG vector image',
        
contextButtonTitle: 'Chart context menu'
    
});

// Buttons and menus are collected in a separate config option set called 'navigation'.
// This can be extended later to add control buttons like zoom and pan right click menus.
defaultOptions.navigation = {
    
menuStyle: {
        
border: '1px solid #A0A0A0',
        
background: '#FFFFFF',
        
padding: '5px 0'
    
},
    
menuItemStyle: {
        
padding: '0 10px',
        
background: NONE,
        
color: '#303030',
        
fontSize: isTouchDevice ? '14px' : '11px'
    
},
    
menuItemHoverStyle: {
        
background: '#4572A5',
        
color: '#FFFFFF'
    
},

    
buttonOptions: {
        
symbolFill: '#E0E0E0',
        
symbolSize: 14,
        
symbolStroke: '#666',
        
symbolStrokeWidth: 3,
        
symbolX: 12.5,
        
symbolY: 10.5,
        
align: 'right',
        
buttonSpacing: 3, 
        
height: 22,
        
// text: null,
        
theme: {
            
fill: 'white', // capture hover
            
stroke: 'none'
        
},
        
verticalAlign: 'top',
        
width: 24
    
}
};



// Add the export related options
defaultOptions.exporting = {
    
//enabled: true,
    //filename: 'chart',
    
type: 'image/png',
    
url: 'http://export.highcharts.com/',
    
//width: undefined,
    //scale: 2
    
buttons: {
        
contextButton: {
            
//x: -10,
            
symbol: 'menu',
            
_titleKey: 'contextButtonTitle',
            
menuItems: [{
                
textKey: 'printChart',
                
onclick: function () {
                    
this.print();
                }
            }, {
                
separator: true
            
}, {
                
textKey: 'downloadPNG',
                
onclick: function () {
                    
this.exportChart();
                }
            }, {
                
textKey: 'downloadJPEG',
                
onclick: function () {
                    
this.exportChart({
                        
type: 'image/jpeg'
                    
});
                }
            }, {
                
textKey: 'downloadPDF',
                
onclick: function () {
                    
this.exportChart({
                        
type: 'application/pdf'
                    
});
                }
            }, {
                
textKey: 'downloadSVG',
                
onclick: function () {
                    
this.exportChart({
                        
type: 'image/svg+xml'
                    
});
                }
            }
            
// Enable this block to add "View SVG" to the dropdown menu
            /*
            ,{

                text: 'View SVG',
                onclick: function () {
                    var svg = this.getSVG()
                        .replace(/</g, 'n&lt;')
                        .replace(/>/g, '&gt;');

                    doc.body.innerHTML = '<pre>' + svg + '</pre>';
                }
            } // */
            
]
        }
    }
};

// Add the Highcharts.post utility
Highcharts.post = function (url, data) {
    var 
name,
        
form;
    
    
// create the form
    
form = createElement('form', {
        
method: 'post',
        
action: url,
        
enctype: 'multipart/form-data'
    
}, {
        
display: NONE
    
}, doc.body);

    
// add the data
    
for (name in data) {
        
createElement('input', {
            
type: HIDDEN,
            
name: name,
            
value: data[name]
        }, 
null, form);
    }

    
// submit
    
form.submit();

    
// clean up
    
discardElement(form);
};

extend(Chart.prototype, {

    
/**
     * Return an SVG representation of the chart
     *
     * @param additionalOptions {Object} Additional chart options for the generated SVG representation
     */
    
getSVG: function (additionalOptions) {
        var 
chart = this,
            
chartCopy,
            
sandbox,
            
svg,
            
seriesOptions,
            
sourceWidth,
            
sourceHeight,
            
cssWidth,
            
cssHeight,
            
options = merge(chart.options, additionalOptions); // copy the options and add extra options

        // IE compatibility hack for generating SVG content that it doesn't really understand
        
if (!doc.createElementNS) {
            
/*jslint unparam: true*//* allow unused parameter ns in function below */
            
doc.createElementNS = function (ns, tagName) {
                return 
doc.createElement(tagName);
            };
            
/*jslint unparam: false*/
        
}

        
// create a sandbox where a new chart will be generated
        
sandbox = createElement(DIV, null, {
            
position: ABSOLUTE,
            
top: '-9999em',
            
width: chart.chartWidth + PX,
            
height: chart.chartHeight + PX
        
}, doc.body);
        
        
// get the source size
        
cssWidth = chart.renderTo.style.width;
        
cssHeight = chart.renderTo.style.height;
        
sourceWidth = options.exporting.sourceWidth ||
            
options.chart.width ||
            (/
px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||
            
600;
        
sourceHeight = options.exporting.sourceHeight ||
            
options.chart.height ||
            (/
px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||
            
400;

        
// override some options
        
extend(options.chart, {
            
animation: false,
            
renderTo: sandbox,
            
forExport: true,
            
width: sourceWidth,
            
height: sourceHeight
        
});
        
options.exporting.enabled = false; // hide buttons in print
        
        // prepare for replicating the chart
        
options.series = [];
        
each(chart.series, function (serie) {
            
seriesOptions = merge(serie.options, {
                
animation: false, // turn off animation
                
showCheckbox: false,
                
visible: serie.visible
            
});

            if (!
seriesOptions.isInternal) { // used for the navigator series that has its own option set
                
options.series.push(seriesOptions);
            }
        });

        
// generate the chart copy
        
chartCopy = new Highcharts.Chart(options, chart.callback);

        
// reflect axis extremes in the export
        
each(['xAxis', 'yAxis'], function (axisType) {
            
each(chart[axisType], function (axis, i) {
                var 
axisCopy = chartCopy[axisType][i],
                    
extremes = axis.getExtremes(),
                    
userMin = extremes.userMin,
                    
userMax = extremes.userMax;

                if (
axisCopy && (userMin !== UNDEFINED || userMax !== UNDEFINED)) {
                    
axisCopy.setExtremes(userMin, userMax, true, false);
                }
            });
        });

        
// get the SVG from the container's innerHTML
        
svg = chartCopy.container.innerHTML;

        
// free up memory
        
options = null;
        
chartCopy.destroy();
        
discardElement(sandbox);

        
// sanitize
        
svg = svg
            
.replace(/zIndex="[^"]+"/g, '')
            .replace(/isShadow="
[^"]+"/g, '')
            .
replace(/symbolName="[^"]+"/g, '')
            .replace(/jQuery[0-9]+="
[^"]+"/g, '')
            .
replace(/url([^#]+#/g, 'url(#')
            
.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
            .
replace(/ href=/g, ' xlink:href=')
            .
replace(/n/, ' ')
            .
replace(/</svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)
            /* This fails in IE < 8
            .replace(/([0-9]+).([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
                return s2 +'.'+ s3[0];
            })*/

            // Replace HTML entities, issue #347
            
.replace(/&nbsp;/g, 'u00A0') // no-break space
            
.replace(/&shy;/g,  'u00AD') // soft hyphen

            // IE specific
            
.replace(/<IMG /g, '<image ')
            .
replace(/height=([^" ]+)/g, 'height="$1"')
            .replace(/width=([^" 
]+)/g, 'width="$1"')
            .
replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
            .replace(/id=([^" 
>]+)/g, 'id="$1"')
            .
replace(/class=([^" >]+)/g, 'class="$1"')
            .replace(/ transform /g, ' ')
            .replace(/:(path|rect)/g, '$1')
            .replace(/style="
([^"]+)"/g, function (s) {
                return 
s.toLowerCase();
            });

        
// IE9 beta bugs with innerHTML. Test again with final IE9.
        
svg = svg.replace(/(url(#highcharts-[0-9]+)&quot;/g, '$1')
            
.replace(/&quot;/g, "'");

        return 
svg;
    },

    
/**
     * Submit the SVG representation of the chart to the server
     * @param {Object} options Exporting options. Possible members are url, type and width.
     * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
     */
    
exportChart: function (options, chartOptions) {
        
options = options || {};
        
        var 
chart = this,
            
chartExportingOptions = chart.options.exporting,
            
svg = chart.getSVG(merge(
                { 
chart: { borderRadius: 0 } },
                
chartExportingOptions.chartOptions,
                
chartOptions, 
                {
                    
exporting: {
                        
sourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth,
                        
sourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight
                    
}
                }
            ));

        
// merge the options
        
options = merge(chart.options.exporting, options);
        
        
// do the post
        
Highcharts.post(options.url, {
            
filename: options.filename || 'chart',
            
type: options.type,
            
width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
            
scale: options.scale || 2,
            
svg: svg
        
});

    },
    
    
/**
     * Print the chart
     */
    
print: function () {

        var 
chart = this,
            
container = chart.container,
            
origDisplay = [],
            
origParent = container.parentNode,
            
body = doc.body,
            
childNodes = body.childNodes;

        if (
chart.isPrinting) { // block the button while in printing mode
            
return;
        }

        
chart.isPrinting = true;

        
// hide all body content
        
each(childNodes, function (node, i) {
            if (
node.nodeType === 1) {
                
origDisplay[i] = node.style.display;
                
node.style.display = NONE;
            }
        });

        
// pull out the chart
        
body.appendChild(container);

        
// print
        
win.focus(); // #1510
        
win.print();

        
// allow the browser to prepare before reverting
        
setTimeout(function () {

            
// put the chart back in
            
origParent.appendChild(container);

            
// restore all body content
            
each(childNodes, function (node, i) {
                if (
node.nodeType === 1) {
                    
node.style.display = origDisplay[i];
                }
            });

            
chart.isPrinting = false;

        }, 
1000);

    },

    
/**
     * Display a popup menu for choosing the export type
     *
     * @param {String} name An identifier for the menu
     * @param {Array} items A collection with text and onclicks for the items
     * @param {Number} x The x position of the opener button
     * @param {Number} y The y position of the opener button
     * @param {Number} width The width of the opener button
     * @param {Number} height The height of the opener button
     */
    
contextMenu: function (name, items, x, y, width, height, button) {
        var 
chart = this,
            
navOptions = chart.options.navigation,
            
menuItemStyle = navOptions.menuItemStyle,
            
chartWidth = chart.chartWidth,
            
chartHeight = chart.chartHeight,
            
cacheName = 'cache-' + name,
            
menu = chart[cacheName],
            
menuPadding = mathMax(width, height), // for mouse leave detection
            
boxShadow = '3px 3px 10px #888',
            
innerMenu,
            
hide,
            
hideTimer,
            
menuStyle;

        
// create the menu only the first time
        
if (!menu) {

            
// create a HTML element above the SVG
            
chart[cacheName] = menu = createElement(DIV, {
                
className: PREFIX + name
            
}, {
                
position: ABSOLUTE,
                
zIndex: 1000,
                
padding: menuPadding + PX
            
}, chart.container);

            
innerMenu = createElement(DIV, null,
                
extend({
                    
MozBoxShadow: boxShadow,
                    
WebkitBoxShadow: boxShadow,
                    
boxShadow: boxShadow
                
}, navOptions.menuStyle), menu);

            
// hide on mouse out
            
hide = function () {
                
css(menu, { display: NONE });
                if (
button) {
                    
button.setState(0);
                }
                
chart.openMenu = false;
            };

            
// Hide the menu some time after mouse leave (#1357)
            
addEvent(menu, 'mouseleave', function () {
                
hideTimer = setTimeout(hide, 500);
            });
            
addEvent(menu, 'mouseenter', function () {
                
clearTimeout(hideTimer);
            });


            
// create the items
            
each(items, function (item) {
                if (
item) {
                    var 
element = item.separator ? 
                        
createElement('hr', null, null, innerMenu) :
                        
createElement(DIV, {
                            
onmouseover: function () {
                                
css(this, navOptions.menuItemHoverStyle);
                            },
                            
onmouseout: function () {
                                
css(this, menuItemStyle);
                            },
                            
onclick: function () {
                                
hide();
                                
item.onclick.apply(chart, arguments);
                            },
                            
innerHTML: item.text || chart.options.lang[item.textKey]
                        }, 
extend({
                            
cursor: 'pointer'
                        
}, menuItemStyle), innerMenu);


                    
// Keep references to menu divs to be able to destroy them
                    
chart.exportDivElements.push(element);
                }
            });

            
// Keep references to menu and innerMenu div to be able to destroy them
            
chart.exportDivElements.push(innerMenu, menu);

            
chart.exportMenuWidth = menu.offsetWidth;
            
chart.exportMenuHeight = menu.offsetHeight;
        }

        
menuStyle = { display: 'block' };

        
// if outside right, right align it
        
if (x + chart.exportMenuWidth > chartWidth) {
            
menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
        } else {
            
menuStyle.left = (x - menuPadding) + PX;
        }
        
// if outside bottom, bottom align it
        
if (y + height + chart.exportMenuHeight > chartHeight && button.alignOptions.verticalAlign !== 'top') {
            
menuStyle.bottom = (chartHeight - y - menuPadding)  + PX;
        } else {
            
menuStyle.top = (y + height - menuPadding) + PX;
        }

        
css(menu, menuStyle);
        
chart.openMenu = true;
    },

    
/**
     * Add the export button to the chart
     */
    
addButton: function (options) {
        var 
chart = this,
            
renderer = chart.renderer,
            
btnOptions = merge(chart.options.navigation.buttonOptions, options),
            
onclick = btnOptions.onclick,
            
menuItems = btnOptions.menuItems,
            
symbol,
            
button,
            
symbolAttr = {
                
stroke: btnOptions.symbolStroke,
                
fill: btnOptions.symbolFill
            
},
            
symbolSize = btnOptions.symbolSize || 12,
            
menuKey;

        if (!
chart.btnCount) {
            
chart.btnCount = 0;
        }
        
menuKey = chart.btnCount++;

        
// Keeps references to the button elements
        
if (!chart.exportDivElements) {
            
chart.exportDivElements = [];
            
chart.exportSVGElements = [];
        }

        if (
btnOptions.enabled === false) {
            return;
        }


        var 
attr = btnOptions.theme,
            
states = attr.states,
            
hover = states && states.hover,
            
select = states && states.select,
            
callback;

        
delete attr.states;

        if (
onclick) {
            
callback = function () {
                
onclick.apply(chart, arguments);
            };

        } else if (
menuItems) {
            
callback = function () {
                
chart.contextMenu(
                    
'contextmenu', 
                    
menuItems, 
                    
button.translateX, 
                    
button.translateY, 
                    
button.width, 
                    
button.height,
                    
button
                
);
                
button.setState(2);
            };
        }


        if (
btnOptions.text && btnOptions.symbol) {
            
attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
        
        } else if (!
btnOptions.text) {
            
extend(attr, {
                
width: btnOptions.width,
                
height: btnOptions.height,
                
padding: 0
            
});
        }

        
button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
            .
attr({
                
title: chart.options.lang[btnOptions._titleKey],
                
'stroke-linecap': 'round'
            
});

        if (
btnOptions.symbol) {
            
symbol = renderer.symbol(
                    
btnOptions.symbol,
                    
btnOptions.symbolX - (symbolSize / 2),
                    
btnOptions.symbolY - (symbolSize / 2),
                    
symbolSize,                
                    
symbolSize
                
)
                .
attr(extend(symbolAttr, {
                    
'stroke-width': btnOptions.symbolStrokeWidth || 1,
                    
zIndex: 1
                
})).add(button);
        }

        
button.add()
            .
align(extend(btnOptions, {
                
width: button.width,
                
x: Highcharts.pick(btnOptions.x, buttonOffset) // #1654
            
}), true, 'spacingBox');

        
buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);

        
chart.exportSVGElements.push(button, symbol);

    },

    
/**
     * Destroy the buttons.
     */
    
destroyExport: function (e) {
        var 
chart = e.target,
            
i,
            
elem;

        
// Destroy the extra buttons added
        
for (i = 0; i < chart.exportSVGElements.length; i++) {
            
elem = chart.exportSVGElements[i];
            
            
// Destroy and null the svg/vml elements
            
if (elem) { // #1822
                
elem.onclick = elem.ontouchstart = null;
                
chart.exportSVGElements[i] = elem.destroy();
            }
        }

        
// Destroy the divs for the menu
        
for (i = 0; i < chart.exportDivElements.length; i++) {
            
elem = chart.exportDivElements[i];

            
// Remove the event handler
            
removeEvent(elem, 'mouseleave');

            
// Remove inline events
            
chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;

            
// Destroy the div by moving to garbage bin
            
discardElement(elem);
        }
    }
});


symbols.menu = function (x, y, width, height) {
    var 
arr = [
        
M, x, y + 2.5,
        
L, x + width, y + 2.5,
        
M, x, y + height / 2 + 0.5,
        
L, x + width, y + height / 2 + 0.5,
        
M, x, y + height - 1.5,
        
L, x + width, y + height - 1.5
    
];
    return 
arr;
};

// Add the buttons on chart load
Chart.prototype.callbacks.push(function (chart) {
    var 
n,
        
exportingOptions = chart.options.exporting,
        
buttons = exportingOptions.buttons;

    
buttonOffset = 0;

    if (
exportingOptions.enabled !== false) {

        for (
n in buttons) {
            
chart.addButton(buttons[n]);
        }

        
// Destroy the export elements at chart destroy
        
addEvent(chart, 'destroy', chart.destroyExport);
    }

});


}(
Highcharts));
?>
Онлайн: 1
Реклама