You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
9.7 KiB
JavaScript

/**
* @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<Object|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));
}));