<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div id="funnel1" ></div>
*{box-sizing: border-box;}
body{background: #efefef;}
#funnel1{width: 800px; max-width: 100%;}
var funnel1Area = document.getElementById("funnel1");
var ContainerWidth = funnel1Area.offsetWidth;
var funnel1 = document.createElement("CANVAS");
funnel1.width = ContainerWidth;
funnel1.height = funnel1.width * 4 / 5;
var funnel1Width = funnel1.width;
var funnel1Height = funnel1.height;
// console.log(funnel1Width);
var part = funnel1Width/2 - 7;
var part2Offset = funnel1Width/2 + 7;
var ctx = funnel1.getContext("2d");
function checkParams(){
funnel1.width = ContainerWidth;
funnel1.height = funnel1.width * 4 / 5;
funnel1Width = funnel1.width;
funnel1Height = funnel1.height;
part = funnel1Width/2 - 7;
part2Offset = funnel1Width/2 + 7;
}
function Tooltip(tooltipXCoord, tooltipYCoord, data){
var rectX = tooltipXCoord + 5 ;
var rectY = tooltipYCoord + 10;
// var rectWidth = part / 3;
var rectWidth = 20;
var rectHeight = 20;
var cornerRadius = 10;
ctx.lineJoin = "round";
ctx.lineWidth = cornerRadius;
var txt = data;
var measureWid = ctx.measureText(txt).width;
// console.log(measureWid);
ctx.beginPath();
ctx.globalCompositeOperation='source-over';
ctx.globalAlpha = 1;
ctx.fillStyle = '#313131';
ctx.fill();
ctx.strokeStyle = "#313131";
ctx.strokeRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), measureWid + 10, rectHeight-cornerRadius);
ctx.fillRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), measureWid + 10, rectHeight-cornerRadius);
ctx.closePath();
// // tooltip arrow
// ctx.beginPath();
// ctx.moveTo(rectX + measureWid/2 + 20 , rectY - 5);
// ctx.lineTo(rectX + measureWid/2 + 20 + 5, rectY );
// ctx.lineTo(rectX + measureWid/2 + 20 - 5, rectY );
// ctx.fillStyle = '#313131';
// ctx.fill();
// ctx.closePath();
ctx.font = "14px sans";
ctx.fillStyle = "#fff";
ctx.fillText(
data, //value
rectX + 10, //x coord
rectY + 15 //y coord
);
}
// Tooltip(50, 200, 250);
function GraphCreation(){
// data calculation
var data1 = [450, 150, 200, 200, 200];
var data1Bg = ['#b175ff', '#c497fe', '#ebdcff', '#f9f6fd', '#ffffff'];
var data2 = [250, 150, 200, 200, 200];
var data2Bg = ['#ff8a67', '#ffa88d', '#fee1d8', '#fef8f6', '#ffffff'];
var data1Total = data1.reduce((a, b) => a + b);
var data2Total = data2.reduce((a, b) => a + b);
var concatData = data1.concat(data2);
var percentageData1 = [];
var mainData1 = [];
var percentageData2 = [];
var mainData2 = [];
// ****** data calculations ***********
// find the percentage of number in array
convertToPerc(data1, data1Total, percentageData1);
convertToPerc(data2, data2Total, percentageData2);
function convertToPerc(arr, total, percDataArray){
arr.forEach(myFunc);
function myFunc(value, index, array){
var calcPercentage = value/total * 100;
percDataArray.push(calcPercentage);
}
}
// find the coord number from percentage in array
percToNumber(percentageData1, mainData1);
percToNumber(percentageData2, mainData2);
function percToNumber(percArray, mainArr){
percArray.forEach(percentageToNumber);
function percentageToNumber(value, index, array) {
var calcNumber = value * funnel1Height / 100;
mainArr.push(calcNumber);
}
}
var xblock = funnel1Width / 10;
var yblock = funnel1Height / 10;
// // funnel 1 shape
ctx.beginPath();
// ctx.globalCompositeOperation='destination-over';
ctx.moveTo(xblock,0);
ctx.lineTo(xblock * 10, 0);
ctx.lineTo(xblock * 8, yblock * 2.4);
ctx.lineTo(xblock * 7.8, yblock * 4);
ctx.lineTo(xblock * 7.8, yblock * 6.2);
ctx.lineTo(xblock * 7.2, yblock * 8);
ctx.lineTo(xblock * 6, yblock * 10);
ctx.lineTo(xblock * 3, yblock * 10);
ctx.lineTo(xblock * 3, yblock * 8.1);
ctx.lineTo(xblock * 2.2, yblock * 6.2);
ctx.lineTo(xblock * 1.9, yblock * 4.2);
ctx.lineTo(xblock * 1.9, yblock * 2.4);
ctx.fillStyle = "transparent";
ctx.fill();
ctx.closePath();
ctx.clip();
// final coordinate calc
var leftRects1 = [];
var rightRects1 = [];
createCoords(mainData1, leftRects1, data1Bg, 'leftPart');
createCoords(mainData2, rightRects1, data2Bg, 'rightPart');
function createCoords(mainArray, coordArray, color, key){
var xCord = 0;
var yCord = 0;
if(key == 'rightPart'){
xCord = part2Offset;
}
for(var i =0; i<mainArray.length; i++){
var obj = {
x:xCord,
y:yCord,
w:part,
h:mainArray[i],
bg:color[i]
}
coordArray.push(obj);
yCord = yCord+mainArray[i];
}
}
// console.log('leftRects1', leftRects1)
// console.log('rightRects1', rightRects1)
var MainCoordsArray = leftRects1.concat(rightRects1);
var mouseEve = false;
// create final shapes
function createShapes(xpointPath, ypointPath){
for(var i=0; i < MainCoordsArray.length; i++){
ctx.beginPath();
ctx.globalCompositeOperation='destination-over';
ctx.rect(MainCoordsArray[i].x, MainCoordsArray[i].y, MainCoordsArray[i].w, MainCoordsArray[i].h);
ctx.fillStyle = MainCoordsArray[i].bg;
ctx.globalAlpha = mouseEve ? ctx.isPointInPath(xpointPath, ypointPath) ? 1 : 0.8 : 0.8;
ctx.fill();
ctx.closePath();
var cordie = MainCoordsArray[i].x;
var tooltipXCoord = MainCoordsArray[i].x;
var tooltipYCoord = MainCoordsArray[i].y;
if(cordie == 0){
tooltipXCoord = MainCoordsArray[i].w - MainCoordsArray[i].w/3;
}
if(ctx.isPointInPath(xpointPath, ypointPath)){
Tooltip(tooltipXCoord, tooltipYCoord, concatData[i]);
}
}
mouseEve = false;
}
createShapes();
funnel1.onmousemove = function(e) {
mouseEve = true;
var rect = this.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top;
ctx.clearRect(0, 0, funnel1.width, funnel1.height);
createShapes(x, y);
};
}
GraphCreation();
window.onresize = function() {
ContainerWidth = funnel1Area.offsetWidth;
checkParams()
GraphCreation()
}
funnel1Area.append(funnel1);