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);
}