Kijan Maharjan Kijan Maharjan - 5 months ago 63
Javascript Question

How to create horizontal funnel like this?

I wish there was a horizontal funnel plugin available in the market. I'm not a good js developer but I'm a designer with html/css skills in hand. I have designed similar funnel like below in psd but I couldn't find any plugin to plug in into the html. The funnel links should be dynamically adjusted too. Please suggest me how to build similar kind of funnel with steps title, conversion % on the second row in the funnel columns. I've also created this in css but css doesn't work because the funnel columns should be totally dynamic.

Hotjar funnel image

Answer

Here's how to draw your horizontal funnel chart for a given set of data using Canvas...

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var height=100;
var baseY=200;
var ascending=35;
var descending=35;
var barheight=50;
var data=[65,14,4,3,3];

filledLineChart(data,height,baseY,descending,ascending,barheight,'gold')

function filledLineChart(data,height,baseY,descending,ascending,barheight,fillcolor){
    var stepWidth=canvas.width/(data.length-1);
    var maxDataValue=0;
    for(var i=0;i<data.length;i++){
        if(data[i]>maxDataValue){maxDataValue=data[i];}
    }
    ctx.beginPath();
    ctx.moveTo(0,baseY-height*data[0]/maxDataValue);
    for(var i=1;i<data.length;i++){
        ctx.lineTo(stepWidth*i,baseY-height*data[i]/maxDataValue);
    }
    ctx.lineTo(stepWidth*(data.length-1),baseY);
    ctx.lineTo(0,baseY);
    ctx.fillStyle=fillcolor;
    ctx.fill();
    ctx.strokeStyle='lightgray';
    ctx.strokeRect(0,baseY-height-ascending,canvas.width,height+descending+ascending);
    ctx.strokeRect(0,baseY-height,canvas.width,height+descending);
    ctx.beginPath();
    for(var i=0;i<data.length;i++){
        ctx.moveTo(i*stepWidth,baseY-height);
        ctx.lineTo(i*stepWidth,baseY);
    }
    ctx.stroke();
    ctx.fillStyle='whitesmoke';
    ctx.fillRect(0,baseY-height-ascending-barheight,canvas.width,barheight);
}
<canvas id="canvas" width=300 height=300></canvas>

You can apply all your text like this:

// set a font and set a font color and draw some text
ctx.font='14px verdana';
ctx.fillStyle='black';     // or red or whatever
ctx.fillText('21.5%', 100, 175)  // 100,175 are the x,y text position

I leave it to you to apply your various text values for the chart using this simple text method.