"A variwide chart is a column chart where each column has a separate width to represent the third dimension."
Here is a script to convert a column chart to variwide chart.
Steps:
Create a Column chart. It should contain only one field as category and two Value panels (one will be displayed as height of bar and other as width).
2. Add below script to widget
3. Save the script and refresh widget
(function(d) {
"object" === typeof module && module.exports ? module.exports = d : d(Highcharts)
})(function(d) {
(function(b) {
var d = b.seriesType,
l = b.seriesTypes,
k = b.each,
m = b.pick;
d("variwide", "column", {
pointPadding: 0,
groupPadding: 0
}, {
pointArrayMap: ["y", "z"],
parallelArrays: ["x", "y", "z"],
processData: function() {
var a = this;
this.totalZ = 0;
this.relZ = [];
l.column.prototype.processData.call(this);
k(this.zData, function(g, c) {
a.relZ[c] = a.totalZ;
a.totalZ += g
});
this.xAxis.categories && (this.xAxis.variwide = !0)
},
postTranslate: function(a,
g) {
var c = this.relZ,
h = this.xAxis.len,
e = this.totalZ,
f = a / c.length * h,
b = (a + 1) / c.length * h,
d = m(c[a], e) / e * h;
a = m(c[a + 1], e) / e * h;
return d + (g - f) * (a - d) / (b - f)
},
translate: function() {
var a = this.options.crisp;
this.options.crisp = !1;
l.column.prototype.translate.call(this);
this.options.crisp = a;
var b = this.chart.inverted,
c = this.borderWidth % 2 / 2;
k(this.points, function(a, e) {
var f = this.postTranslate(e, a.shapeArgs.x),
d = this.postTranslate(e, a.shapeArgs.x + a.shapeArgs.width);
this.options.crisp && (f = Math.round(f) - c, d = Math.round(d) -
c);
a.shapeArgs.x = f;
a.shapeArgs.width = d - f;
a.tooltipPos[b ? 1 : 0] = this.postTranslate(e, a.tooltipPos[b ? 1 : 0])
}, this)
}
}, {
isValid: function() {
return b.isNumber(this.y, !0) && b.isNumber(this.z, !0)
}
});
b.Tick.prototype.postTranslate = function(a, b, c) {
a[b] = this.axis.pos + this.axis.series[0].postTranslate(c, a[b] - this.axis.pos)
};
b.wrap(b.Tick.prototype, "getPosition", function(a, b, c) {
var d = this.axis,
e = a.apply(this, Array.prototype.slice.call(arguments, 1)),
f = b ? "x" : "y";
d.categories && d.variwide && (this[f + "Orig"] = e[f], this.postTranslate(e,
f, c));
return e
});
b.wrap(b.Tick.prototype, "getLabelPosition", function(a, b, d, h, e, f, l, k) {
var c = Array.prototype.slice.call(arguments, 1),
g = e ? "x" : "y";
this.axis.variwide && "number" === typeof this[g + "Orig"] && (c[e ? 0 : 1] = this[g + "Orig"]);
c = a.apply(this, c);
this.axis.variwide && this.axis.categories && this.postTranslate(c, g, k);
return c
})
})(d)
});
widget.on('processresult', function(widget,ev) {
ev.result.yAxis[0].max = Math.max(...ev.result.series[0].data.map(o => o.y), 0);
ev.result.chart.type = 'variwide'
ev.result.plotOptions['variwide'] = ev.result.plotOptions['column']
delete ev.result.plotOptions['column']
delete ev.result.plotOptions['series']
ev.result.tooltip.enabled = true
variwideArr = []
$.each(ev.result.series[0].data, function(index, value){
value.weight = value.y
variwideArr.push([value.selectionData[0], value.y, ev.result.series[1].data[index].y])
})
ev.result.series[0].data = variwideArr
ev.result.series[0].colorByPoint = true
ev.result.series[0].type = 'variwide'
ev.result.series[0].tooltip = {
pointFormat: `${ev.result.series[0].name}: <b>{point.y}</b><br>
${ev.result.series[1].name}: <b>{point.z}</b><br>`
}
ev.result.series.length = 1
})
widget.on('beforedatapointtooltip', function(widget,ev) {
ev.cancel = true
})
Note: Sometimes you may see some alignment issues with X-axis labels. This happens only when you edit the widget. It will show normally when you refresh the dashboard.
Comments