/** * @license Highcharts JS v6.0.4 (2017-12-15) * Highcharts variwide module * * (c) 2010-2017 Torstein Honsi * * License: www.highcharts.com/license */ 'use strict'; (function(factory) { if (typeof module === 'object' && module.exports) { module.exports = factory; } else { factory(Highcharts); } }(function(Highcharts) { (function(H) { /** * Highcharts variwide module * * (c) 2010-2017 Torstein Honsi * * License: www.highcharts.com/license */ /** * To do: * - When X axis is not categorized, the scale should reflect how the z values * increase, like a horizontal stack. But then the actual X values aren't * reflected the the axis.. Should we introduce a Z axis too? */ var seriesType = H.seriesType, seriesTypes = H.seriesTypes, each = H.each, pick = H.pick; /** * A variwide chart (related to marimekko chart) is a column chart with a * variable width expressing a third dimension. * * @extends {plotOptions.column} * @excluding boostThreshold,crisp,depth,edgeColor,edgeWidth,groupZPadding * @product highcharts * @sample {highcharts} highcharts/demo/variwide/ * Variwide chart * @since 6.0.0 * @optionparent plotOptions.variwide */ seriesType('variwide', 'column', { /** * In a variwide chart, the point padding is 0 in order to express the * horizontal stacking of items. */ pointPadding: 0, /** * In a variwide chart, the group padding is 0 in order to express the * horizontal stacking of items. */ groupPadding: 0 }, { pointArrayMap: ['y', 'z'], parallelArrays: ['x', 'y', 'z'], processData: function() { var series = this; this.totalZ = 0; this.relZ = []; seriesTypes.column.prototype.processData.call(this); each(this.zData, function(z, i) { series.relZ[i] = series.totalZ; series.totalZ += z; }); if (this.xAxis.categories) { this.xAxis.variwide = true; } }, /** * Translate an x value inside a given category index into the distorted * axis translation. * @param {Number} index The category index * @param {Number} x The X pixel position in undistorted axis pixels * @return {Number} Distorted X position */ postTranslate: function(index, x) { var axis = this.xAxis, relZ = this.relZ, i = index, len = axis.len, totalZ = this.totalZ, linearSlotLeft = i / relZ.length * len, linearSlotRight = (i + 1) / relZ.length * len, slotLeft = (pick(relZ[i], totalZ) / totalZ) * len, slotRight = (pick(relZ[i + 1], totalZ) / totalZ) * len, xInsideLinearSlot = x - linearSlotLeft, ret; ret = slotLeft + xInsideLinearSlot * (slotRight - slotLeft) / (linearSlotRight - linearSlotLeft); return ret; }, /** * Extend translation by distoring X position based on Z. */ translate: function() { // Temporarily disable crisping when computing original shapeArgs var crispOption = this.options.crisp; this.options.crisp = false; seriesTypes.column.prototype.translate.call(this); // Reset option this.options.crisp = crispOption; var inverted = this.chart.inverted, crisp = this.borderWidth % 2 / 2; // Distort the points to reflect z dimension each(this.points, function(point, i) { var left = this.postTranslate( i, point.shapeArgs.x ), right = this.postTranslate( i, point.shapeArgs.x + point.shapeArgs.width ); if (this.options.crisp) { left = Math.round(left) - crisp; right = Math.round(right) - crisp; } point.shapeArgs.x = left; point.shapeArgs.width = right - left; point.tooltipPos[inverted ? 1 : 0] = this.postTranslate( i, point.tooltipPos[inverted ? 1 : 0] ); }, this); } // Point functions }, { isValid: function() { return H.isNumber(this.y, true) && H.isNumber(this.z, true); } }); H.Tick.prototype.postTranslate = function(xy, xOrY, index) { xy[xOrY] = this.axis.pos + this.axis.series[0].postTranslate(index, xy[xOrY] - this.axis.pos); }; H.wrap(H.Tick.prototype, 'getPosition', function(proceed, horiz, pos) { var axis = this.axis, xy = proceed.apply(this, Array.prototype.slice.call(arguments, 1)), xOrY = horiz ? 'x' : 'y'; if (axis.categories && axis.variwide) { this[xOrY + 'Orig'] = xy[xOrY]; this.postTranslate(xy, xOrY, pos); } return xy; }); H.wrap(H.Tick.prototype, 'getLabelPosition', function( proceed, x, y, label, horiz, labelOptions, tickmarkOffset, index ) { var args = Array.prototype.slice.call(arguments, 1), xy, xOrY = horiz ? 'x' : 'y'; // Replace the x with the original x if (this.axis.variwide && typeof this[xOrY + 'Orig'] === 'number') { args[horiz ? 0 : 1] = this[xOrY + 'Orig']; } xy = proceed.apply(this, args); // Post-translate if (this.axis.variwide && this.axis.categories) { this.postTranslate(xy, xOrY, index); } return xy; }); /** * A `variwide` series. If the [type](#series.variwide.type) option is * not specified, it is inherited from [chart.type](#chart.type). * * For options that apply to multiple series, it is recommended to add * them to the [plotOptions.series](#plotOptions.series) options structure. * To apply to all series of this specific type, apply it to [plotOptions. * variwide](#plotOptions.variwide). * * @type {Object} * @extends series,plotOptions.variwide * @product highcharts * @apioption series.variwide */ /** * An array of data points for the series. For the `variwide` series type, * points can be given in the following ways: * * 1. An array of arrays with 3 or 2 values. In this case, the values * correspond to `x,y,z`. If the first value is a string, it is applied * as the name of the point, and the `x` value is inferred. The `x` * value can also be omitted, in which case the inner arrays should * be of length 2\. Then the `x` value is automatically calculated, * either starting at 0 and incremented by 1, or from `pointStart` and * `pointInterval` given in the series options. * * ```js * data: [ * [0, 1, 2], * [1, 5, 5], * [2, 0, 2] * ] * ``` * * 2. An array of objects with named values. The objects are point * configuration objects as seen below. If the total number of data * points exceeds the series' [turboThreshold](#series.variwide.turboThreshold), * this option is not available. * * ```js * data: [{ * x: 1, * y: 1, * z: 1, * name: "Point2", * color: "#00FF00" * }, { * x: 1, * y: 5, * z: 4, * name: "Point1", * color: "#FF00FF" * }] * ``` * * @type {Array} * @extends series.line.data * @excluding marker * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects * @product highcharts * @apioption series.variwide.data */ /** * The relative width for each column. The widths are distributed so they sum * up to the X axis length. * * @type {Number} * @product highcharts * @apioption series.variwide.data.z */ }(Highcharts)); }));