Subversion-Projekte lars-tiefland.cienc

Revision

Blame | Letzte Änderung | Log anzeigen | RSS feed

/**
 * Highcharts JS v4.1.8 (2015-08-20)
 * Highcharts Broken Axis module
 * 
 * Author: Stephane Vanraes, Torstein Honsi
 * License: www.highcharts.com/license
 */

/*global HighchartsAdapter*/
(function (H) { 

        "use strict";

        var pick = H.pick,
                wrap = H.wrap,
                extend = H.extend,
                fireEvent = HighchartsAdapter.fireEvent,
                Axis = H.Axis,
                Series = H.Series;

        function stripArguments() {
                return Array.prototype.slice.call(arguments, 1);
        }

        extend(Axis.prototype, {
                isInBreak: function (brk, val) {
                        var ret,
                                repeat = brk.repeat || Infinity,
                                from = brk.from,
                                length = brk.to - brk.from,
                                test = (val >= from ? (val - from) % repeat :  repeat - ((from - val) % repeat));

                        if (!brk.inclusive) {
                                ret = test < length && test !== 0;
                        } else {
                                ret = test <= length;
                        }
                        return ret;
                },

                isInAnyBreak: function (val, testKeep) {

                        var breaks = this.options.breaks,
                                i = breaks && breaks.length,
                                inbrk,
                                keep,
                                ret;

                        
                        if (i) { 

                                while (i--) {
                                        if (this.isInBreak(breaks[i], val)) {
                                                inbrk = true;
                                                if (!keep) {
                                                        keep = pick(breaks[i].showPoints, this.isXAxis ? false : true);
                                                }
                                        }
                                }

                                if (inbrk && testKeep) {
                                        ret = inbrk && !keep;
                                } else {
                                        ret = inbrk;
                                }
                        }
                        return ret;
                }
        });

        wrap(Axis.prototype, 'setTickPositions', function (proceed) {
                proceed.apply(this, Array.prototype.slice.call(arguments, 1));
                
                if (this.options.breaks) {
                        var axis = this,
                                tickPositions = this.tickPositions,
                                info = this.tickPositions.info,
                                newPositions = [],
                                i;

                        if (info && info.totalRange >= axis.closestPointRange) { 
                                return;
                        }

                        for (i = 0; i < tickPositions.length; i++) {
                                if (!axis.isInAnyBreak(tickPositions[i])) {
                                        newPositions.push(tickPositions[i]);
                                }
                        }

                        this.tickPositions = newPositions;
                        this.tickPositions.info = info;
                }
        });
        
        wrap(Axis.prototype, 'init', function (proceed, chart, userOptions) {
                // Force Axis to be not-ordinal when breaks are defined
                if (userOptions.breaks && userOptions.breaks.length) {
                        userOptions.ordinal = false;
                }

                proceed.call(this, chart, userOptions);

                if (this.options.breaks) {

                        var axis = this;
                        
                        axis.doPostTranslate = true;

                        this.val2lin = function (val) {
                                var nval = val,
                                        brk,
                                        i;

                                for (i = 0; i < axis.breakArray.length; i++) {
                                        brk = axis.breakArray[i];
                                        if (brk.to <= val) {
                                                nval -= brk.len;
                                        } else if (brk.from >= val) {
                                                break;
                                        } else if (axis.isInBreak(brk, val)) {
                                                nval -= (val - brk.from);
                                                break;
                                        }
                                }

                                return nval;
                        };
                        
                        this.lin2val = function (val) {
                                var nval = val,
                                        brk,
                                        i;

                                for (i = 0; i < axis.breakArray.length; i++) {
                                        brk = axis.breakArray[i];
                                        if (brk.from >= nval) {
                                                break;
                                        } else if (brk.to < nval) {
                                                nval += brk.len;
                                        } else if (axis.isInBreak(brk, nval)) {
                                                nval += brk.len;
                                        }
                                }
                                return nval;
                        };

                        this.setExtremes = function (newMin, newMax, redraw, animation, eventArguments) {
                                // If trying to set extremes inside a break, extend it to before and after the break ( #3857 )
                                while (this.isInAnyBreak(newMin)) {
                                        newMin -= this.closestPointRange;
                                }                               
                                while (this.isInAnyBreak(newMax)) {
                                        newMax -= this.closestPointRange;
                                }
                                Axis.prototype.setExtremes.call(this, newMin, newMax, redraw, animation, eventArguments);
                        };

                        this.setAxisTranslation = function (saveOld) {
                                Axis.prototype.setAxisTranslation.call(this, saveOld);

                                var breaks = axis.options.breaks,
                                        breakArrayT = [],       // Temporary one
                                        breakArray = [],
                                        length = 0, 
                                        inBrk,
                                        repeat,
                                        brk,
                                        min = axis.userMin || axis.min,
                                        max = axis.userMax || axis.max,
                                        start,
                                        i,
                                        j;

                                // Min & max check (#4247)
                                for (i in breaks) {
                                        brk = breaks[i];
                                        repeat = brk.repeat || Infinity;
                                        if (axis.isInBreak(brk, min)) {
                                                min += (brk.to % repeat) - (min % repeat);
                                        }
                                        if (axis.isInBreak(brk, max)) {
                                                max -= (max % repeat) - (brk.from % repeat);
                                        }
                                }

                                // Construct an array holding all breaks in the axis
                                for (i in breaks) {
                                        brk = breaks[i];
                                        start = brk.from;
                                        repeat = brk.repeat || Infinity;

                                        while (start - repeat > min) {
                                                start -= repeat;
                                        }
                                        while (start < min) {
                                                start += repeat;
                                        }

                                        for (j = start; j < max; j += repeat) {
                                                breakArrayT.push({
                                                        value: j,
                                                        move: 'in'
                                                });
                                                breakArrayT.push({
                                                        value: j + (brk.to - brk.from),
                                                        move: 'out',
                                                        size: brk.breakSize
                                                });
                                        }
                                }

                                breakArrayT.sort(function (a, b) {
                                        if (a.value === b.value) {
                                                return (a.move === 'in' ? 0 : 1) - (b.move === 'in' ? 0 : 1);
                                        } else {
                                                return a.value - b.value;
                                        }
                                });
                                
                                // Simplify the breaks
                                inBrk = 0;
                                start = min;

                                for (i in breakArrayT) {
                                        brk = breakArrayT[i];
                                        inBrk += (brk.move === 'in' ? 1 : -1);

                                        if (inBrk === 1 && brk.move === 'in') {
                                                start = brk.value;
                                        }
                                        if (inBrk === 0) {
                                                breakArray.push({
                                                        from: start,
                                                        to: brk.value,
                                                        len: brk.value - start - (brk.size || 0)
                                                });
                                                length += brk.value - start - (brk.size || 0);
                                        }
                                }

                                axis.breakArray = breakArray;

                                fireEvent(axis, 'afterBreaks');
                                
                                axis.transA *= ((max - axis.min) / (max - min - length));

                                axis.min = min;
                                axis.max = max;
                        };
                }
        });

        wrap(Series.prototype, 'generatePoints', function (proceed) {

                proceed.apply(this, stripArguments(arguments));

                var series = this,
                        xAxis = series.xAxis,
                        yAxis = series.yAxis,
                        points = series.points,
                        point,
                        i = points.length,
                        connectNulls = series.options.connectNulls,
                        nullGap;


                if (xAxis && yAxis && (xAxis.options.breaks || yAxis.options.breaks)) {
                        while (i--) {
                                point = points[i];

                                nullGap = point.y === null && connectNulls === false; // respect nulls inside the break (#4275)
                                if (!nullGap && (xAxis.isInAnyBreak(point.x, true) || yAxis.isInAnyBreak(point.y, true))) {
                                        points.splice(i, 1);
                                        if (this.data[i]) {
                                                this.data[i].destroyElements(); // removes the graphics for this point if they exist
                                        }
                                }
                        }
                }

        });

        wrap(H.seriesTypes.column.prototype, 'drawPoints', function (proceed) {
                proceed.apply(this);

                var series = this,
                        points = series.points,
                        yAxis = series.yAxis,
                        breaks = yAxis.breakArray || [],
                        threshold = pick(this.options.threshold, yAxis.min),
                        eventName,
                        point,
                        brk,
                        i,
                        j,
                        y;

                for (i = 0; i < points.length; i++) {
                        point = points[i];
                        y = point.stackY || point.y;
                        for (j = 0; j < breaks.length; j++) {
                                brk = breaks[j];
                                eventName = false;

                                if ((threshold < brk.from && y > brk.to) || (threshold > brk.from && y < brk.from)) { 
                                                eventName = 'pointBreak';
                                } else if ((threshold < brk.from && y > brk.from && y < brk.to) || (threshold > brk.from && y > brk.to && y < brk.from)) { // point falls inside the break
                                                eventName = 'pointInBreak'; // docs
                                } 
                                if (eventName) {
                                        fireEvent(yAxis, eventName, {point: point, brk: brk});
                                }
                        }
                }

        });
}(Highcharts));