/** * BoxPlot series sprite that manages {@link Ext.chart.sprite.BoxPlot} instances. */Ext.define('Ext.chart.series.sprite.BoxPlot', { alias: 'sprite.boxplotSeries', extend: 'Ext.chart.series.sprite.Cartesian', inheritableStatics: { def: { processors: { /** * @cfg {Number[]} [dataLow=null] Array of coordinated minimum values. */ dataLow: 'data', /** * @cfg {Number[]} [dataQ1=null] Array of coordinated 1-st quartile values. */ dataQ1: 'data', /** * @cfg {Number[]} [dataQ3=null] Array of coordinated 3-rd quartile values. */ dataQ3: 'data', /** * @cfg {Number[]} [dataHigh=null] Array of coordinated maximum values. */ dataHigh: 'data', /** * @cfg {Number} [minBoxWidth=2] The minimum box width. */ minBoxWidth: 'number', /** * @cfg {Number} [maxBoxWidth=20] The maximum box width. */ maxBoxWidth: 'number', /** * @cfg {Number} [minGapWidth=5] The minimum gap between boxes. */ minGapWidth: 'number' }, aliases: { /** * The `dataMedian` attribute can be used to set the value of * the `dataY` attribute. E.g.: * * sprite.setAttributes({ * dataMedian: [...] * }); * * To fetch the value of the attribute one has to use * * sprite.attr.dataY // array of coordinated median values * * and not * * sprite.attr.dataMedian // WRONG! * * `dataY` attribute is defined by the `Ext.chart.series.sprite.Series`. * * @cfg {Number[]} [dataMedian=null] Array of coordinated median values. */ dataMedian: 'dataY' }, defaults: { minBoxWidth: 2, maxBoxWidth: 40, minGapWidth: 5 } } }, renderClipped: function (surface, ctx, dataClipRect) { if (this.cleanRedraw) { return; } var me = this, attr = me.attr, series = me.getSeries(), renderer = attr.renderer, rendererData = {store: me.getStore()}, itemCfg = {}, dataX = attr.dataX, dataLow = attr.dataLow, dataQ1 = attr.dataQ1, dataMedian = attr.dataY, dataQ3 = attr.dataQ3, dataHigh = attr.dataHigh, min = Math.min(dataClipRect[0], dataClipRect[2]), max = Math.max(dataClipRect[0], dataClipRect[2]), start = Math.max(0, Math.floor(min)), end = Math.min(dataX.length - 1, Math.ceil(max)), // surfaceMatrix = me.surfaceMatrix, matrix = attr.matrix, xx = matrix.elements[0], // horizontal scaling can be < 0, if RTL yy = matrix.elements[3], dx = matrix.elements[4], dy = matrix.elements[5], // `xx` essentially represents the distance between data points in surface coordinates. maxBoxWidth = Math.abs(xx) - attr.minGapWidth, minBoxWidth = Math.min(maxBoxWidth, attr.maxBoxWidth), boxWidth = Math.round( Math.max(attr.minBoxWidth, minBoxWidth) ), x, low, q1, median, q3, high, rendererParams, changes, i; if (renderer) { rendererParams = [me, itemCfg, rendererData]; } for (i = start; i <= end; i++) { x = dataX[i] * xx + dx; low = dataLow[i] * yy + dy; q1 = dataQ1[i] * yy + dy; median = dataMedian[i] * yy + dy; q3 = dataQ3[i] * yy + dy; high = dataHigh[i] * yy + dy; // --- Draw Box --- // Reuse 'itemCfg' object and 'rendererParams' arrays for better performance. itemCfg.x = x; itemCfg.low = low; itemCfg.q1 = q1; itemCfg.median = median; itemCfg.q3 = q3; itemCfg.high = high; itemCfg.boxWidth = boxWidth; if (renderer) { rendererParams[3] = i; changes = Ext.callback(renderer, null, rendererParams, 0, series); Ext.apply(itemCfg, changes); } me.putMarker('items', itemCfg, i, !renderer); } } });