all files / chart/series/ box-and-whisker-series.js

96.92% Statements 189/195
92.47% Branches 86/93
100% Functions 24/24
96.88% Lines 186/192
11 statements, 6 functions, 9 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278          50×   53× 53× 53× 419× 419×   53× 52×     422× 422×   1484× 1484× 416× 416×     1068× 1068×   1484×   428× 428× 428× 428× 422× 422× 422× 422× 422×         422× 416×                   19×       416× 416× 416× 416×   416× 416× 416× 416× 416× 390× 390× 390× 390× 390×   390× 390× 390× 390×         26× 26× 26× 26× 26×   26× 26× 26× 26×       416×   416× 416× 416× 416× 416× 416× 416×   416×     416× 416×   416× 230× 230× 230× 230×         416×   422× 422×           422× 33× 33× 33×   389× 10× 10× 10×     379× 379×   422× 422× 422× 422× 422× 422× 422× 422×   99×     99×   96× 96× 96× 96× 96×     96×       96×   96×   30×     30×   27× 27× 27× 27× 27× 27×   379×   378× 378× 378× 378× 378× 378×   422× 422× 422× 422×       422× 422×     422× 657× 235×     422× 422×         41538×          
/* istanbul ignore next */ 
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
define(["require", "exports", "../../common/utils/helper", "../../common/utils/helper", "@syncfusion/ej2-svg-base", "@syncfusion/ej2-base", "./column-base", "../../common/utils/helper"], function (require, exports, helper_1, helper_2, ej2_svg_base_1, ej2_base_1, column_base_1, helper_3) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var BoxAndWhiskerSeries = (function (_super) {
        __extends(BoxAndWhiskerSeries, _super);
        function BoxAndWhiskerSeries() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        BoxAndWhiskerSeries.prototype.render = function (series, xAxis, yAxis, isInverted) {
            this.sideBySideInfo = this.getSideBySideInfo(series);
            var argsData;
            for (var _i = 0, _a = series.points; _i < _a.length; _i++) {
                var point = _a[_i];
                this.renderPoint(series, point, this.sideBySideInfo, argsData, xAxis, yAxis, isInverted);
            }
            if (series.marker.visible) {
                series.chart.markerRender.render(series);
            }
        };
        BoxAndWhiskerSeries.prototype.updateTipRegion = function (series, point, sideBySideInfo) {
            var tipRegion = this.getRectangle((point.xValue + sideBySideInfo.median), point.maximum, (point.xValue + sideBySideInfo.median), point.minimum, series);
            this.updateTipSize(series, point, tipRegion, series.chart.requireInvertedAxis);
        };
        BoxAndWhiskerSeries.prototype.updateTipSize = function (series, point, region, isInverted) {
            var borderWidth = series.border.width || 1;
            if (!isInverted) {
                region.x -= borderWidth / 2;
                region.width = region.width || borderWidth;
            }
            else {
                region.y -= borderWidth / 2;
                region.height = region.height || borderWidth;
            }
            point.regions.push(region);
        };
        BoxAndWhiskerSeries.prototype.renderPoint = function (series, point, sideBySideInfo, argsData, xAxis, yAxis, isInverted) {
            point.symbolLocations = [];
            point.regions = [];
            var centerRegion;
            if (point.visible && helper_1.withInRange(series.points[point.index - 1], point, series.points[point.index + 1], series)) {
                this.findBoxPlotValues(point.y, point, series.boxPlotMode);
                this.updateTipRegion(series, point, sideBySideInfo);
                centerRegion = this.getRectangle((point.xValue + sideBySideInfo.start), point.upperQuartile, (point.xValue + sideBySideInfo.end), point.lowerQuartile, series);
                point.regions.push(centerRegion);
                argsData = this.triggerEvent(series, point, series.interior, {
                    color: (!ej2_base_1.isNullOrUndefined(series.border.color) && series.border.color !== 'transparent') ? series.border.color :
                        helper_2.getSaturationColor(series.interior, -0.6),
                    width: series.border.width ? series.border.width : 1
                });
                if (!argsData.cancel) {
                    this.renderBoxAndWhisker(series, point, argsData, this.getPathString(point, series, helper_2.getPoint(point.xValue, point.median, xAxis, yAxis, isInverted), helper_2.getPoint(point.xValue + sideBySideInfo.median, point.average, xAxis, yAxis, isInverted)), sideBySideInfo.median);
                }
            }
        };
        BoxAndWhiskerSeries.prototype.updateDirection = function (series, point, isInverted) {
            var argsData;
            for (var i = 0; i < point.length; i++) {
                var visiblePoint = series.points[point[i]];
                this.renderPoint(series, visiblePoint, this.sideBySideInfo, argsData, series.xAxis, series.yAxis, isInverted);
                if (visiblePoint.symbolLocations && visiblePoint.symbolLocations.length && series.marker.visible) {
                    series.chart.markerRender.renderMarker(series, visiblePoint, visiblePoint.symbolLocations[0], visiblePoint.symbolLocations.length - 1, true);
                }
                Eif (series.marker.dataLabel.visible && series.chart.dataLabelModule) {
                    series.chart.dataLabelCollections = [];
                    series.chart.dataLabelModule.commonId = series.chart.element.id + '_Series_' + series.index + '_Point_';
                    if (visiblePoint.outliers.length === 0) {
                        var element = helper_1.getElement(series.chart.dataLabelModule.commonId + visiblePoint.index + '_Text_' + 5);
                        Iif (element) {
                            element.remove();
                        }
                    }
                    series.chart.dataLabelModule.renderDataLabel(series, visiblePoint, null, series.marker.dataLabel);
                }
            }
            var children = series.seriesElement.children;
            for (var i = children.length - 1; i >= 0; i--) {
                if (children[i].children.length === 0) {
                    series.seriesElement.removeChild(children[i]);
                }
            }
        };
        BoxAndWhiskerSeries.prototype.getPathString = function (point, series, median, average) {
            var topRect = point.regions[0];
            var midRect = point.regions[1];
            var direction = '';
            var center = series.chart.requireInvertedAxis ? topRect.y + topRect.height / 2 :
                topRect.x + topRect.width / 2;
            var midWidth = midRect.x + midRect.width;
            var midHeight = midRect.y + midRect.height;
            var topWidth = topRect.x + topRect.width;
            var topHeight = topRect.y + topRect.height;
            if (!series.chart.requireInvertedAxis) {
                this.updateTipSize(series, point, { x: midRect.x, y: topRect.y, width: midWidth - midRect.x, height: 0 }, true);
                this.updateTipSize(series, point, { x: midRect.x, y: topHeight, width: midWidth - midRect.x, height: 0 }, true);
                direction += 'M ' + midRect.x + ' ' + topRect.y + ' ' + 'L ' + midWidth + ' ' + topRect.y;
                direction += ' M ' + center + ' ' + topRect.y + ' ' + 'L ' + center + ' ' + midRect.y;
                direction += ' M ' + midRect.x + ' ' + midRect.y + ' ' + 'L ' + midWidth + ' ' + midRect.y +
                    ' L ' + midWidth + ' ' + midHeight + ' L ' + midRect.x + ' ' + midHeight + ' Z';
                direction += ' M ' + center + ' ' + midHeight + ' L ' + center + ' ' + topHeight;
                direction += ' M ' + midRect.x + ' ' + topHeight + ' L ' + midWidth + ' ' + topHeight;
                direction += ' M ' + midRect.x + ' ' + median.y + ' L ' + midWidth + ' ' + median.y;
                direction += series.showMean ?
                    ' M ' + (average.x - 5) + ' ' + (average.y - 5) + ' L ' + (average.x + 5) + ' ' + (average.y + 5) +
                        ' M ' + (average.x + 5) + ' ' + (average.y - 5) + ' L ' + (average.x - 5) + ' ' + (average.y + 5) : '';
            }
            else {
                this.updateTipSize(series, point, { x: topRect.x, y: midRect.y, width: 0, height: midHeight - midRect.y }, false);
                this.updateTipSize(series, point, { x: topWidth, y: midRect.y, width: 0, height: midHeight - midRect.y }, true);
                direction += 'M ' + topRect.x + ' ' + midRect.y + ' L ' + topRect.x + ' ' + midHeight;
                direction += 'M ' + topRect.x + ' ' + center + ' ' + 'L ' + midRect.x + ' ' + center;
                direction += ' M ' + midRect.x + ' ' + midRect.y + ' ' + 'L ' + midWidth + ' ' + midRect.y +
                    ' L ' + midWidth + ' ' + midHeight + ' L ' + midRect.x + ' ' + midHeight + ' Z';
                direction += ' M ' + midWidth + ' ' + center + ' L ' + topWidth + ' ' + center;
                direction += ' M ' + topWidth + ' ' + midRect.y + ' L ' + topWidth + ' ' + midHeight;
                direction += ' M ' + median.x + ' ' + midRect.y + ' ' + 'L ' + median.x + ' ' + midHeight;
                direction += series.showMean ?
                    'M ' + (average.x + 5) + ' ' + (average.y - 5) + ' L ' + (average.x - 5) + ' ' + (average.y + 5) +
                        'M ' + (average.x - 5) + ' ' + (average.y - 5) + ' L ' + (average.x + 5) + ' ' + (average.y + 5) : '';
            }
            return direction;
        };
        BoxAndWhiskerSeries.prototype.renderBoxAndWhisker = function (series, point, argsData, direction, median) {
            var location;
            var size;
            var symbolId = series.chart.element.id + '_Series_' + series.index + '_Point_' + ((series.removedPointIndex !== null && series.removedPointIndex <= point.index) ? (point.index + 1) : point.index);
            var previusDirection = helper_1.getElement(symbolId + '_BoxPath') ? helper_1.getElement((symbolId + '_BoxPath')).getAttribute('d') : '';
            var element = series.chart.renderer.drawPath(new ej2_svg_base_1.PathOption(symbolId + '_BoxPath', argsData.fill, argsData.border.width, argsData.border.color, series.opacity, series.border.dashArray, direction), new Int32Array([series.clipRect.x, series.clipRect.y]));
            element.setAttribute('role', 'img');
            element.setAttribute('aria-label', point.x.toString() + ':' + point.maximum.toString()
                + ':' + point.minimum.toString() + ':' + point.lowerQuartile.toString() + ':' + point.upperQuartile.toString());
            var parentElement = series.chart.renderer.createGroup({
                'id': symbolId
            });
            helper_1.appendChildElement(series.chart.enableCanvas, parentElement, element, series.chart.redraw, true, null, null, null, previusDirection, null, null, null, series.chart.duration);
            if (series.removedPointIndex !== null && series.removedPointIndex <= point.index) {
                parentElement.id = series.chart.element.id + '_Series_' + series.index + '_Point_' + point.index;
                element.id = series.chart.element.id + '_Series_' + series.index + '_Point_' + point.index + '_BoxPath';
            }
            for (var i = 0; i < point.outliers.length; i++) {
                location = helper_2.getPoint((point.xValue + median), point.outliers[i], series.xAxis, series.yAxis, series.chart.requireInvertedAxis);
                size = new ej2_svg_base_1.Size(series.marker.width, series.marker.height);
                point.symbolLocations.push(location);
                this.updateTipSize(series, point, {
                    x: location.x - (size.width / 2), y: location.y - (size.height / 2),
                    width: size.width, height: size.height
                }, true);
            }
            helper_1.appendChildElement(series.chart.enableCanvas, series.seriesElement, parentElement, series.chart.redraw, false, null, null, null, null, null, null, null, series.chart.duration, true);
        };
        BoxAndWhiskerSeries.prototype.findBoxPlotValues = function (yValues, point, mode) {
            var yCount = yValues.length;
            var quartile = {
                average: helper_1.sum(yValues) / yCount,
                lowerQuartile: 0, upperQuartile: 0,
                maximum: 0, minimum: 0,
                median: 0, outliers: []
            };
            if (mode === 'Exclusive') {
                quartile.lowerQuartile = this.getExclusiveQuartileValue(yValues, yCount, 0.25);
                quartile.upperQuartile = this.getExclusiveQuartileValue(yValues, yCount, 0.75);
                quartile.median = this.getExclusiveQuartileValue(yValues, yCount, 0.5);
            }
            else if (mode === 'Inclusive') {
                quartile.lowerQuartile = this.getInclusiveQuartileValue(yValues, yCount, 0.25);
                quartile.upperQuartile = this.getInclusiveQuartileValue(yValues, yCount, 0.75);
                quartile.median = this.getInclusiveQuartileValue(yValues, yCount, 0.5);
            }
            else {
                quartile.median = helper_3.getMedian(yValues);
                this.getQuartileValues(yValues, yCount, quartile);
            }
            this.getMinMaxOutlier(yValues, yCount, quartile);
            point.minimum = quartile.minimum;
            point.maximum = quartile.maximum;
            point.lowerQuartile = quartile.lowerQuartile;
            point.upperQuartile = quartile.upperQuartile;
            point.median = quartile.median;
            point.outliers = quartile.outliers;
            point.average = quartile.average;
        };
        BoxAndWhiskerSeries.prototype.getExclusiveQuartileValue = function (yValues, count, percentile) {
            Iif (count === 0) {
                return 0;
            }
            else if (count === 1) {
                return yValues[0];
            }
            var value = 0;
            var rank = percentile * (count + 1);
            var integerRank = Math.floor(Math.abs(rank));
            var fractionRank = rank - integerRank;
            Iif (integerRank === 0) {
                value = yValues[0];
            }
            else Iif (integerRank > count - 1) {
                value = yValues[count - 1];
            }
            else {
                value = fractionRank * (yValues[integerRank] - yValues[integerRank - 1]) + yValues[integerRank - 1];
            }
            return value;
        };
        BoxAndWhiskerSeries.prototype.getInclusiveQuartileValue = function (yValues, count, percentile) {
            Iif (count === 0) {
                return 0;
            }
            else if (count === 1) {
                return yValues[0];
            }
            var value = 0;
            var rank = percentile * (count - 1);
            var integerRank = Math.floor(Math.abs(rank));
            var fractionRank = rank - integerRank;
            value = fractionRank * (yValues[integerRank + 1] - yValues[integerRank]) + yValues[integerRank];
            return value;
        };
        BoxAndWhiskerSeries.prototype.getQuartileValues = function (yValues, count, quartile) {
            if (count === 1) {
                quartile.lowerQuartile = yValues[0];
                quartile.upperQuartile = yValues[0];
                return null;
            }
            var isEvenList = count % 2 === 0;
            var halfLength = count / 2;
            var lowerQuartileArray = yValues.slice(0, halfLength);
            var upperQuartileArray = yValues.slice(isEvenList ? halfLength : halfLength + 1, count);
            quartile.lowerQuartile = helper_3.getMedian(lowerQuartileArray);
            quartile.upperQuartile = helper_3.getMedian(upperQuartileArray);
        };
        BoxAndWhiskerSeries.prototype.getMinMaxOutlier = function (yValues, count, quartile) {
            var interquartile = quartile.upperQuartile - quartile.lowerQuartile;
            var rangeIQR = 1.5 * interquartile;
            for (var i = 0; i < count; i++) {
                Iif (yValues[i] < quartile.lowerQuartile - rangeIQR) {
                    quartile.outliers.push(yValues[i]);
                }
                else {
                    quartile.minimum = yValues[i];
                    break;
                }
            }
            for (var i = count - 1; i >= 0; i--) {
                if (yValues[i] > quartile.upperQuartile + rangeIQR) {
                    quartile.outliers.push(yValues[i]);
                }
                else {
                    quartile.maximum = yValues[i];
                    break;
                }
            }
        };
        BoxAndWhiskerSeries.prototype.doAnimation = function (series) {
            this.animate(series);
        };
        BoxAndWhiskerSeries.prototype.getModuleName = function () {
            return 'BoxAndWhiskerSeries';
        };
        BoxAndWhiskerSeries.prototype.destroy = function () {
        };
        return BoxAndWhiskerSeries;
    }(column_base_1.ColumnBase));
    exports.BoxAndWhiskerSeries = BoxAndWhiskerSeries;
});