带有可拖动外半径的 d3 圆环图

d3 donut chart with draggable outerRadius

我正在尝试制作一个在每个楔形处具有可变半径的圆环图。每个 Wedge 都应该可以拖动以更改此楔形的宽度(宽度表示外半径)。 但是我不知道如何实现这个拖动功能。有人可以帮助我吗?

这是我的代码:

var width = 760,
    height = 550;

var innerradius = 200;

var color = d3.scale.category20b();     

var cScale = d3.scale.linear().domain([0, 100]).range([0, 2 * Math.PI]);



var dataset = [
      { label: 'Abulia', count: 10, start: 0, end: 10, radius: 10 }, 
      { label: 'Betelgeuse', count: 20, start: 10, end: 20, radius: 20 },
      { label: 'Cantaloupe', count: 30, start: 30, end: 60, radius: 20 },
      { label: 'Dijkstra', count: 40, start: 60, end: 100, radius: 20 }
];



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


var arc = d3.svg.arc()
      .innerRadius(innerradius)             
      .outerRadius(function(d){return d.radius + innerradius;})
      .startAngle(function(d){return cScale(d.start);}) 
      .endAngle(function(d){return cScale(d.end);});

var path = svg.selectAll('path')
      .data(dataset)
      .enter()
      .append('path')
      .attr('d', arc)
      .style("fill", function(d){return color(d.label);});   

var drag = d3.behavior.drag()
             .on('drag', function() {

                    //don't know what to do

                                    }) 

这是我的解决方案。

             .on('drag', function(d) {
             if (d3.event.sourceEvent.button == 0)
                 d.radius += Math.sqrt(d3.event.dx * d3.event.dx + d3.event.dy * d3.event.dy);
             else if (d3.event.sourceEvent.button == 2){
                 d.radius -= Math.sqrt(d3.event.dx * d3.event.dx + d3.event.dy * d3.event.dy);
                 d.radius = Math.max (d.radius, 1);
             }
                path.each(function (d2){
                    if (d == d2){
                        d3.select(this).attr('d', arc);
                    }
                });
                                });

这样,左键单击并拖动将增加楔形的半径,而右键单击并拖动将减小它。如果您选择保留此行为,那么您还需要覆盖默认的上下文菜单以防止它弹出。

但是,如果您希望能够通过左键单击来展开和收缩,事情就会变得有点复杂。这是因为此方法依赖于 drag 事件的 dxdy 属性,无论弧在哪里,它都会是相同的方向。要通过单个鼠标按钮使用它,您必须相对于圆弧所面对的方向计算 dxdy(可能需要为此深入研究一些三角函数)。