A
A
Andy Oker2020-12-08 11:39:05
JavaScript
Andy Oker, 2020-12-08 11:39:05

How to make a hover effect on the share of a circular canvas chart?

I want to make an effect when hovering the mouse over the chart area. As I understand it, the areas are separated by the beginPath() and closePath() methods inside the loop. Interested in how these areas can work?
The first argument to isPointInPath(path) can be just this very path. Is it possible to get it somehow with the beginPath() and closePath() methods, or is it necessary to use something like Path2D() here?

var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");


Render functions
function drawLine(ctx, startX, startY, endX, endY){
    ctx.beginPath();
    ctx.moveTo(startX,startY);
    ctx.lineTo(endX,endY);
    ctx.stroke();
}

function drawArc(ctx, centerX, centerY, radius, startAngle, endAngle){
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, startAngle, endAngle);
    ctx.stroke();
}

function drawPieSlice(id ,ctx,centerX, centerY, radius, startAngle, endAngle, color ){
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.moveTo(centerX,centerY);
    ctx.arc(centerX, centerY, radius, startAngle, endAngle);
    ctx.closePath();
    ctx.fill();
}


Executing class
let Piechart = function(options){
    this.options = options;
    this.canvas = options.canvas;
    this.ctx = this.canvas.getContext("2d");
    this.colors = options.colors;
 
    this.draw = function(){
        let total_value = 0;
        let color_index = 0;
        let val;
        for (let categ in this.options.data){
            val = this.options.data[categ];
            total_value += val;
        }

        let start_angle = 0;
        for (categ in this.options.data){
            let = this.options.data[categ];
            let slice_angle = 2 * Math.PI * val / total_value;
    
            drawPieSlice(
                Math.round(start_angle),
                this.ctx,
                this.canvas.width/2,
                this.canvas.height/2,
                Math.min(this.canvas.width/2,this.canvas.height/2),
                start_angle,
                start_angle+slice_angle,
                this.colors[color_index%this.colors.length]
            );
 
            start_angle += slice_angle;
            color_index++;
        }
      
      start_angle = 0;
    }
}


Chart Data
var myVinyls = {
    "Classical music": 10,
    "Alternative rock": 14,
    "Pop": 5,
    "Jazz": 12
};


Initialization and call
var myPiechart = new Piechart(
    {
        canvas:myCanvas,
        data:myVinyls,
        colors:["#fde23e","#f16e23", "#57d9ff","red"]
    }
);

myPiechart.draw();


Event Handler
myCanvas.addEventListener('mousemove', function (event) {
  console.log(ctx.isPointInPath(event.offsetX, event.offsetY));
})

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
twobomb, 2020-12-09
@Ashlis

Yes, you can like this , only you have a joint here

let = this.options.data[categ];
            let slice_angle = 2 * Math.PI * val / total_value;

probably it was supposed to let val .., so it was not drawn correctly yet

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question