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

时间:2016-02-08 13:44:27

标签: javascript d3.js

我正在努力了解Donut3D.js中的功能 - > http://plnkr.co/edit/g5kgAPCHMlFWKjljUc3j?p=preview处理插入的数据:

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

enter image description here

我找到了这个功能:

        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;});              
        }

并尝试插入如下的弧:

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; });

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

  

编辑1

第一个答案通过改变:

帮助旋转内饼
var _data = d3.layout.pie().sort(null).value(function(d) {
              return d.value;
            })(data);

var _data = d3.layout.pie()
            .startAngle(45*Math.PI/180)
            .endAngle(405*Math.PI/180).sort(null).value(function(d) {
              return d.value;
            })(data);
问题是现在外面的饼干坏了 - > http://plnkr.co/edit/g5kgAPCHMlFWKjljUc3j?p=preview

我想解决方案与函数函数pieOuter(d, rx, ry, h )以及两个startAngleendAngle变量有关,但它们的工作方式显然不可预测。

谢谢

  

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

2 个答案:

答案 0 :(得分: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 */ ) {

draw功能中,修改角度。我没有使用pie角度拧紧,而是直接对数据进行操作:

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

然后你需要纠正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(" ");

}

Here's the full code

答案 1 :(得分:2)

更改默认开始角度

Donut3D用户d3的饼图布局功能here,其中default startAngle of 0

如果要更改起始角度,则应修改donut3d.js。

首先,如果您关心可视化的可用性和可读性,您当然应该避免使用3d饼图/圆环图 - explained here

修复底角布局

您使用的endAngle不正确,导致&#34;淡蓝色&#34;切片重叠&#34;蓝色&#34;一。应该是405(即45 + 360)而不是415。

var _data = d3.layout.pie()
  .startAngle(45*Math.PI/180)
  .endAngle(405*Math.PI/180)

然后,&#34; pieOuter&#34;应更新角度计算以正确运行。不起作用的弧是endAngle > 2 * PI的弧,并且应该为它更新角度计算。

这就是诀窍(不要问我为什么):

// fix right-side outer shape
if (d.endAngle > 2 * Math.PI) {
  startAngle = Math.PI / 120
  endAngle = Math.PI/4
}

演示:http://plnkr.co/edit/wmPnS9XVyQcrNu4WLa0D?p=preview