使用D3创建多层饼图

5
如何使用d3.js创建一个多层饼图,效果如下:

enter image description here

每个部分都没有内部子部分,而当它有子部分时,其颜色比外部子部分更深,如上图所示。
我尝试搜索多层饼图,但我能做的只有这些。

http://jsfiddle.net/ZpQ3x/

这里是相应的JavaScript代码。
var dataset = {
  final: [7000],
  process: [1000, 1000, 1000, 7000],
  initial: [10000],
};

var width = 660,
    height = 500,
    cwidth = 75;

var color = d3.scale.category20();

var pie = d3.layout.pie()
    .sort(null);

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

var gs = svg.selectAll("g.wrapper").data(d3.values(dataset)).enter()
        .append("g")
        .attr("id",function(d,i){
            return Object.keys(dataset)[i];
        });

var gsLabels = svg.selectAll("g.wrapper").data(d3.values(dataset)).enter()
        .append("g")
        .attr("id",function(d,i){
            return "label_" + Object.keys(dataset)[i];
        });

var count = 0;
var path = gs.selectAll("path")
    .data(function(d) { return pie(d); })
  .enter().append("path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", function(d, i, j) { 
        d._tmp = d.endAngle;
        d.endAngle = d.startAngle;
        if(Object.keys(dataset)[j] === "final"){
            d.arc = d3.svg.arc().innerRadius(cwidth*j).outerRadius(cwidth*(j+1)); 
        }
        else{
            d.arc = d3.svg.arc().innerRadius(10+cwidth*j).outerRadius(cwidth*(j+1)); 
        }
        return d.arc(d);
        })
    .transition().delay(function(d, i, j) {
            return i * 500; 
    }).duration(500)
    .attrTween('d', function(d,x,y) {
       var i = d3.interpolate(d.startAngle, d._tmp);
       return function(t) {
           d.endAngle = i(t);
         return d.arc(d);
       }
    });

非常感谢。


这不是你想要的吗?https://pankajkumar005.wordpress.com/2015/08/14/multilevel-pie-chart-using-d3/ - Cyril Cherian
@ Cyril,我在搜索时遇到了提到的代码,但是如果你仔细看,有一个部分没有从圆周到饼图中心,这正是我想要的。 - Artiga
一个问题不太清楚,即内部子段有时很长,有时很短,这是什么标准?为什么不所有的子段都有相同的半径? - Cyril Cherian
也许你可以让你那里的饼图对应你的数据?你想让它看起来怎样?能否解释一下你的数据集 :) - thatOneGuy
好的,但是X1和X之间将会有一对一的对应关系,也就是说X和X1将拥有相同数量的元素,对吗? - Cyril Cherian
显示剩余5条评论
1个回答

3

我已将您的数据集转换为单个JSON格式。

为了确保上述提到的数组x和x1之间有关联,我制作了这样的数据集。

data = [{
    major: 100,//this is the X array first element
    minor: 70,//this is the X1 array first element
    grp: 1//here grp is for coloring the segment
}, {
    major: 100,
    minor: 30,
    grp: 2
}, {
    major: 100,
    minor: 50,
    grp: 3
}, {
    major: 140,
    minor: 70,
    grp: 4
}, {
    major: 80,
    minor: 10,
    grp: 5
}];

我已经创建了两个弧函数。

var arcMajor = d3.svg.arc()
    .outerRadius(function (d) {
    return radius - 10;
})
    .innerRadius(0);

//this for making the minor arc with variable radius as per scale 
var arcMinor = d3.svg.arc()
    .outerRadius(function (d) {
    // scale for calculating the radius range([20, radius - 40])
    return scale((d.data.major - d.data.minor));
})

这是生成路径的代码。

//this makes the major arc
g.append("path")
    .attr("d", function (d) {
    return arcMajor(d);
})
    .style("fill", function (d) {
    return d3.rgb(color(d.data.grp));
});

//this makes the minor arcs
g.append("path")
    .attr("d", function (d) {
    return arcMinor(d);
})
    .style("fill", function (d) {
    return d3.rgb(color(d.data.grp)).darker(2);//for making the inner path darker
});

这里有相关的it技术代码示例,并且还有注释。

希望这能帮到你!


1
优秀的解决方案 Cyril :) - Gilsha
@ Cyril,非常感谢您的回答,但我已经尝试更改数据集,饼图出现了问题。请看一下这个链接:http://jsfiddle.net/6e8aue0h/3/ - Artiga
1
只需要调整一下比例尺,就可以返回内半径了。现在试试:http://jsfiddle.net/cyril123/6e8aue0h/4/。 - Cyril Cherian
@ Cyril,再次感谢您。当所有较小的值都等于0时,我们如何完全消除较暗的颜色?就像这个例子:http://jsfiddle.net/6e8aue0h/5/ - Artiga
1
@Artiga 像我之前说的一样,这只是你如何设置比例尺的问题。正如你在评论部分中提到的那样,在我的代码示例中,半径由主轴和次轴之差定义为 _X2 = X-X1_。同样,在这里完成了相同的操作 _return scale((d.data.major - d.data.minor));_。现在,如果主轴和次轴都相同,则半径将为0。例如,在第5组中检查此处 http://jsfiddle.net/cyril123/6e8aue0h/7/。为了使半径为0,将最小值设为0,定义了一个名为scale的变量:_var scale = d3.scale.linear().range([0, radius - d3.min(data, function (d) { return d.major; })]);_。 - Cyril Cherian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接