如何在此3D饼图中解析数据?

Cri*_*llo 8 javascript d3.js

我正在尝试掌握Donut3D.js- > http://plnkr.co/edit/g5kgAPCHMlFWKjljUc3j?p=preview中的函数如何处理插入的数据:

最重要的是,在哪里设置数据startAngle设置为0度?我想将其更改为45º,然后更改为135º,225º和315º(请参见上图).

在此输入图像描述

我找到了这个功能:

        Donut3D.draw = function(id, data, x /*center x*/, y/*center y*/, 
                rx/*radius x*/, ry/*radius y*/, h/*height*/, ir/*inner radius*/){

            var _data = d3.layout.pie().sort(null).value(function(d) {return d.value;})(data);

            var slices = d3.select("#"+id).append("g").attr("transform", "translate(" + x + "," + y + ")")
                .attr("class", "slices");              

            slices.selectAll(".innerSlice").data(_data).enter().append("path").attr("class", "innerSlice")
                .style("fill", function(d) { 
                    return d3.hsl(d.data.color).darker(0.7); })
                .attr("d",function(d){ 
                    return pieInner(d, rx+0.5,ry+0.5, h, ir);})
                .each(function(d){this._current=d;});

            slices.selectAll(".topSlice").data(_data).enter().append("path").attr("class", "topSlice")
                .style("fill", function(d) { 
                    return d.data.color; })
                .style("stroke", function(d) { 
                    return d.data.color; })
                .attr("d",function(d){ 
                    return pieTop(d, rx, ry, ir);})
                .each(function(d){this._current=d;});

            slices.selectAll(".outerSlice").data(_data).enter().append("path").attr("class", "outerSlice")
                .style("fill", function(d) { 
                    return d3.hsl(d.data.color).darker(0.7); })
                .attr("d",function(d){ 
                    return pieOuter(d, rx-.5,ry-.5, h);})
                .each(function(d){this._current=d;});

            slices.selectAll(".percent").data(_data).enter().append("text").attr("class", "percent")
                .attr("x",function(d){ 
                    return 0.6*rx*Math.cos(0.5*(d.startAngle+d.endAngle));})
                .attr("y",function(d){ 
                    return 0.6*ry*Math.sin(0.5*(d.startAngle+d.endAngle));})
                .text(getPercent).each(function(d){this._current=d;});              
        }
Run Code Online (Sandbox Code Playgroud)

并尝试插入如下的弧:

var arc = d3.svg.arc().outerRadius(r)
        .startAngle(function(d) { return d.startAngle + Math.PI/2; })
        .endAngle(function(d) { return d.endAngle + Math.PI/2; });
Run Code Online (Sandbox Code Playgroud)

但它不会产生预期的效果.

编辑1

第一个答案有助于旋转内饼,改变:

var _data = d3.layout.pie().sort(null).value(function(d) {
              return d.value;
            })(data);
Run Code Online (Sandbox Code Playgroud)

var _data = d3.layout.pie()
            .startAngle(45*Math.PI/180)
            .endAngle(405*Math.PI/180).sort(null).value(function(d) {
              return d.value;
            })(data);
Run Code Online (Sandbox Code Playgroud)

问题是现在外面的饼干坏了 - > http://plnkr.co/edit/g5kgAPCHMlFWKjljUc3j?p=preview

我猜解有事情做与功能功能pieOuter(d, rx, ry, h )和两个startAngleendAngle变数,但他们的工作显然是在不可预知的方式.

谢谢

我知道饼图很糟糕,特别是在3D中; 但是这项工作是我论文的一部分,我的工作实际上是在展示PieCharts是如何糟糕的!我想旋转这个PieChart,以显示如果3D饼图片位于顶部,数据显示为不太重要,或者如果位于底部则更重要.因此,"邪恶的记者"可以通过简单地倾斜和旋转PieChart来改变数据的视觉感知!

Mar*_*ark 3

这是一个允许旋转的更正函数。

首先,修改函数签名以包含旋转变量:

Donut3D.draw = function(id, data, x /*center x*/ , y /*center y*/ ,
        rx /*radius x*/ , ry /*radius y*/ , h /*height*/ , ir /*inner radius*/, rotate /* start angle for first slice IN DEGREES */ ) {
Run Code Online (Sandbox Code Playgroud)

draw函数中,修改角度。我不会直接处理pie角度,而是直接对数据进行处理:

_data.forEach(function(d,i){
  d.startAngle += rotate * Math.PI/180; //<-- convert to radians
  d.endAngle += rotate * Math.PI/180;
});
Run Code Online (Sandbox Code Playgroud)

然后您需要更正该pieOuter函数来修复绘图伪影:

function pieOuter(d, rx, ry, h) {

    var startAngle = d.startAngle,
        endAngle = d.endAngle;

    var sx = rx * Math.cos(startAngle),
      sy = ry * Math.sin(startAngle),
      ex = rx * Math.cos(endAngle),
      ey = ry * Math.sin(endAngle);

    // both the start and end y values are above
    // the middle of the pie, don't bother drawing anything
    if (ey < 0 && sy < 0)
      return "M0,0";

    // the end is above the pie, fix the points
    if (ey < 0){
      ey = 0;
      ex = -rx;
    }
    // the beginning is above the pie, fix the points.
    if (sy < 0){
      sy = 0;
      sx = rx;
    }

    var ret = [];
    ret.push("M", sx, h + sy, "A", rx, ry, "0 0 1", ex, h + ey, "L", ex, ey, "A", rx, ry, "0 0 0", sx, sy, "z");
    return ret.join(" ");

}
Run Code Online (Sandbox Code Playgroud)

这是完整的代码