D3.JS - Rotate a pie chart on mouse down event

2019-03-07 09:44发布

问题:

I am looking for an example for to rotate a pie chart on mouse down event. On mouse down, I need to rotate the pie chart either clock wise or anti clock wise direction.

If there is any example how to do this in D3.js, that will help me a lot. I found an example using FusionChart and I want to achieve the same using D3.js

回答1:

Pretty easy with d3:

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var g = svg.selectAll(".arc")
    .data(pie(data))
    .enter().append("g")
    .attr("class", "arc");

g.append("path")
    .attr("d", arc)
    .style("fill", function(d) {
      return color(d.data.age);
    });

var curAngle = 0;
var interval = null;

svg.on("mousedown", function(d) {
    interval = setInterval(goRotate,10);
});

svg.on("mouseup", function(d){
    clearInterval(interval);
})

function goRotate() {
    curAngle += 1;
    svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ") rotate(" + curAngle + "," + 0 + "," + 0 + ")");
  }

Working example.



回答2:

I did a similar thing with a compass instead of pie chart. You mainly need three methods - each bound to a different mouse event.

Bind this to the mousedown event on your compass circle:

function beginCompassRotate(el) {

    var rect = compassCircle[0][0].getBBox(); //compassCircle would be your piechart d3 object
    compassMoving = true;
    compassCenter = {
        x: (rect.width / 2),
        y: (rect.height / 2)
    }
}

Bind this to the mouse move on your canvas or whatever is holding your pie chart - you can bind it to the circle (your pie chart) but it makes the movement a little glitchy. Binding it to the circle's container keeps it smooth.

function rotateCompass() {
    if (compassMoving) {
        var mouse = d3.mouse(svg[0][0]);

        var p2 = {
            x: mouse[0],
            y: mouse[1]
        };

        var newAngle = getAngle(compassCenter, p2) + 90;
        //again this v is your pie chart instead of compass
        compass.attr("transform", "translate(90,90) rotate(" + newAngle + "," + 0 + "," + 0 + ")");
    }
}

Finally bind this to the mouseup on your canvas - again you can bind it to the circle but this way you can end the rotation without the mouse over the circle. If it is on the circle you will keep rotating the circle until you have a mouse up event over the circle.

function endCompassRotate(el) {
    compassMoving = false;
}

Here is a jsfiddle showing it working: http://jsfiddle.net/4oy2ggdt/