mondego
mondego

Reputation: 27

Canvas Rect Mouse Hover on Chart

Iterating over plotData creates a rect around certain values on a chart based on a condition.

plotData.forEach( (each, index) => {

    if ( each.a > each.b ) {
       try {
            ctx.beginPath();
            ctx.fillStyle = 'yellow';
            ctx.rect(zone[index].x, zone[index].y, zone[index].width, zone[index].height);
            ctx.closePath();
            ctx.fill();
       }
       ...

I want to change the color of the rect when the mouse hovers over it. The chart is scrollable and zoomable therefore the rect coordinates change dynamically.

Upvotes: 1

Views: 82

Answers (1)

Firstly, outside of this function, somewhere else in the document code, in fact: at the very top of your code, define a variable to keep track of the mouses location, and if its clicked or not:

var mouseInfo = {x:0, y:0, clicked: false};

Now, somewhere else make some event listeners that keep track of that location (sometime after the canvas element has been made), I'm assuming the canvas element is stored in a variable called canvas:

canvas.addEventListener("mousemove", e=> {
    mouseInfo.x = e.offsetX;
    mouseInfo.y = e.offsetY;
});

next, another 2 to keep track of if the mouse is down or not (doesn't have to be on the canvas element, in fact, better that it should be on the window element):

window.addEventListener("mousedown", e=> {
     mouseInfo.clicked = true;
});

window.addEventListener("mouseup", e=> {
     mouseInfo.clicked = false;
});

Now make a function to determine if a point is intersecting a rectangle, assuming a rectangle is an object with an x, y, width, height:

function isPointInRet(point, rect) {
    return (
        point.x > rect.x &&
        point.x < rect.x + rect.width && 
        point.y > rect.y && 
        point.y < rect.y + rect.height
    );
}

Now, back in your function that you quoted above:

plotData.forEach( (each, index) => {

    if ( each.a > each.b ) {
       try {
            ctx.beginPath();
            ctx.fillStyle = 'yellow';
            ctx.rect(zone[index].x, zone[index].y, zone[index].width, zone[index].height);
            ctx.closePath();
            ctx.fill();
       }

So, right before the fillStyle part, change it all to the following:

var x = zone[index].x,
    y = zone[index].y,
    width = zone[index].width,
    height = zone[index].height;
if(isPointInRect(mouseInfo, {x, y, width, height}) {
     //perhaps if you want to make a hover color, do that here, just un-comment if you want:
     /*ctx.fillStyle = "#ffaaee";*/
     if(mouseInfo.clicked) {
         ctx.fillStyle = "ff0000"; //red
     }
}
ctx.fillStyle = 'yellow';
ctx.rect(x, y, width, height);
...

(warning: untested code);

let me know if that helps, and if it works with the zooming etc.

Upvotes: 1

Related Questions