简体   繁体   中英

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM