Canvas chart

by Alon Rotem

HTML

<canvas id="canvas" width="600" height="200"></canvas>

JavaScript

const ctx = canvas.getContext('2d'), mouse = { x:0 , y:0 };



const styles = {
     default: { fillStyle: "#0C0", strokeStyle: "#F00", lineWidth: 1 },
     over: { fillStyle: "#C008", strokeStyle: "#F0F8", lineWidth: 1 },
};


const paths = [
		//[0,0, 0, 164, 129, 164, 82  , 168,   128, 0],
    [0,0 ,129,0, 168,82, 129,164, 0, 164],
    [ 129*1,0, 129*2, 0, 129*2+(168-129), 82, 129*2, 164, 129, 164, 168,82],
    [ 129*2, 0, 129*3, 0, 129*3 + (168-129), 82, 129*3, 82*2, 129*2, 82*2, 129*2 + (168-129),82],

].map(createPath);



canvas.addEventListener("mousemove", (e) => {
   mouse.x = e.offsetX;
   mouse.y = e.offsetY;
   checkMouseOver(paths);
   canvas.style.cursor = mouse.overPath ? "pointer" : "default"; 
});
function checkMouseOver(paths) {
    var over;
    for(const p of paths) { ctx.isPointInPath(p, mouse.x, mouse.y) && (over = p) }
    if (over !== mouse.overPath) {
        mouse.overPath = over;
        ctx.clearRect(0, 0, 600, 200);
        for (const p of paths) {
            if (p === over) { drawPath(p, styles.over) }
            else { drawPath(p) }
        }
    }
}
function createPath(path) {
    var i = 0, p = new Path2D();
    while (i < path.length) { p.lineTo(path[i++], path[i++]) }
    p.closePath();
    return p;       
}

function drawPath(path, style = styles.default) {
    Object.assign(ctx, style).fill(path);
    ctx.stroke(path);    
}