top of page

Convert Column chart to Variwide chart

"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:

  1. 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.



118 views0 comments

Recent Posts

See All
bottom of page