【问题标题】:Multilevel D3 Pie/Donut-chart doesnt show and no error messages多级 D3 饼图/甜甜圈图不显示,也没有错误消息
【发布时间】:2019-11-24 09:38:38
【问题描述】:

我正在尝试获取多级饼图/甜甜圈图。数据没有数值,应均匀分布在环中。因此,我给了他们所有相同的号码。也许有一种更优雅的方式,但在简单的数据集中它有效。可悲的是,现在我采用了一个与我的最终目标更相似的数据集,但它停止了工作。我是一个血腥的 d3 新手,如果我没有收到任何错误消息,我将非常感谢任何可能出现问题的帮助。干杯,非常感谢! (我在 html 文件中有脚本)。我以此为灵感:fiddle

编辑:要查看我的图形,我使用本地网络服务器,以便能够在本地加载内容

/* Old simple data set
         var dataset = {
          ring0 : [1],  
          ring1: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
          ring2: [1,1,1],
          ring3: [1,1,1,1,1,1,1,1,1,1,1,1,1,1],
          ring4: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
        }; */

        var dataset = {
            ring0:[{"Arbeitsbereich":"IT", "number": 1}],
            ring1:[{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
            ring2:[{"Arbeitsbereich":"IT", "number": 1}, {"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
            ring3:[{"Arbeitsbereich":"IT", "number": 1}, {"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
            ring4:[{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}]
        };

        
       
        var width  = d3.select('#pie-chart').node().offsetWidth,
            height = 600,
            cwidth = 60;
        
        var colorO = '#8a0101';
        var colorA = '#db3131';
        var colorB = '#ff4a4a';
        var colorC = '#aa0000';
        var colorD = '#ff0000';

                        
        var pie = d3.pie()
            .value(function(d){return d.number;});

            console.log(pie(dataset.ring1))

        var svg = d3.select("#duration svg")
            .append("g") //used to group svg elements
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        console.log(dataset);
 
        var arc = d3.arc();

        var gs = svg.selectAll("g").data(pie(dataset)).enter().append("g"); 

        var path = gs.selectAll("path")
            .data(function(d) { return pie(d); }) //.data(function(d, i)
            .enter().append("path")
            .attr("fill", function(d, i, j) {
                switch (j) {
                case 0:
                    return colorO(d.dataset.number);
                    break;
                case 1:
                    return colorA(d.dataset.number);
                    break;
                case 2:
                    return colorB(d.dataset.number);
                    break;
                case 3:
                    return colorC(d.dataset.number);
                    break;
                case 4:
                    return colorD(d.dataset.number);
                } 
            
            })

            .attr("d", function(d, i, j) {
                if (j == 0) {
                    
                    return arc.innerRadius(0).outerRadius(40)(d);
                    
                } else if (j == 1) {
                    
                    return arc.innerRadius(40).outerRadius(cwidth * (j + 1))(d);        

            } else {
                    
                    return arc.innerRadius(cwidth * j).outerRadius(cwidth * (j + 1))(d);
                    
                }        
            });
body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    margin: auto;
    position: relative;
    width: 960px;
  }
  
  text {
    font: 10px sans-serif;
  }
  
  form {
    position: absolute;
    right: 10px;
    top: 10px;
  }
<!DOCTYPE html>
<html>
<head>
    <script src="https://d3js.org/d3.v5.js"></script>
    <link rel="stylesheet" href="./style.css" type="text/css" />
    <meta charset="utf-8"
</head>
        <body> 
                <div id="pie-chart">
                        <svg style="height:1000px;width:100%"></svg>
                    </div>
        </body>    
</html>

【问题讨论】:

    标签: javascript d3.js data-visualization pie-chart donut-chart


    【解决方案1】:

    当您刚接触 D3 时,它可能会让您的大脑有些疲倦,别担心!

    我更改了一些小东西以使您的代码在下面的“全部组合”html 中运行。其中一些看起来像是在你调试时可能已经出现的错误,还有一些更多是关于理解的。我认为关键是:

    • 您的 svg 选择 d3.select("#duration svg") 实际上并没有指向您文档中的任何内容,因此实际上没有发生任何其他事情,这就是您没有收到任何错误的原因。当您从小提琴中获取代码时,这可能就是我所说的“facepalm”错误,如果您将其更改为d3.select("#pie-chart svg"),您应该会开始看到一些更严重的错误!为了调试这种东西,我总是去浏览器调试工具检查文档,你会看到你的 svg 下没有 &lt;g&gt; 元素,然后从那里开始解决问题
    • 您的数据只是一个对象,由一组大括号 {} 包围表示。这在 d3 中绑定是一件很奇怪的事情,我们通常绑定一个对象数组并根据这些数据项做不同的事情。果然,在小提琴中,对象的形状相同,但它不仅仅绑定在对象上(本来是.data(dataset),而是使用d3.values()首先使用@将数据的形状更改为数组987654329@
    • 在尝试绑定到pie(d) 数据集的地方,您已经有点过头了。此示例使用两个级别的数据连接(当您有足够的时间和茶时,请查看https://bost.ocks.org/mike/nest/!)顶级数据连接(即.data(d3.values(dataset)) 在您的圆环图中每个“环”都有一个元素 - 所以每个环有一个 &lt;g&gt; 元素,其中包含所有环的数据作为一个对象。然后还有另一个数据连接(.data(function(d, i) { return pie(d); }) 在小提琴中,我在下面做了一些微妙的不同)来创建环的&lt;g&gt; 元素中的一组&lt;path&gt; 元素,每个&lt;path&gt; 都是你甜甜圈的一部分。

    希望对您有所帮助,这就是我最终如何将您的代码混搭成可以在屏幕上显示某些内容的方法,尽管您可能想要对颜色进行排序!注意:我确实通过说所有数据访问器只返回 1 来简化事情(因为在您的情况下,您总是想要均匀分段的环,然后每个数据点的形状无关紧要,它们都算作 1 )

    <!DOCTYPE html>
    <html>
    <head>
        <script src="https://d3js.org/d3.v5.js"></script>
        <style>
        body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        margin: auto;
        position: relative;
        width: 960px;
      }
    
      text {
        font: 10px sans-serif;
      }
    
      form {
        position: absolute;
        right: 10px;
        top: 10px;
      }
        </style>
        <meta charset="utf-8">
    </head>
            <body> 
                    <div id="pie-chart">
                            <svg style="height:1000px;width:100%"></svg>
                        </div>
    
                    <script>
          /* Old simple data set */
          /* var dataset = {
              ring0:[1],  
              ring1:[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
              ring2:[1,1,1],
              ring3:[1,1,1,1,1,1,1,1,1,1,1,1,1,1],
              ring4:[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
           }; 
         */
    
    
         ///*
         var dataset = {
                ring0:[{"Arbeitsbereich":"IT", "number": 1}],
                ring1:[{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
                ring2:[{"Arbeitsbereich":"IT", "number": 1}, {"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
                ring3:[{"Arbeitsbereich":"IT", "number": 1}, {"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}],
                ring4:[{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1},{"Arbeitsbereich":"IT", "number": 1}]
            };
    
    
    
            var width  = d3.select('#pie-chart').node().offsetWidth,
                height = 600,
                cwidth = 60;
    
            var colorO = '#8a0101';
            var colorA = '#db3131';
            var colorB = '#ff4a4a';
            var colorC = '#aa0000';
            var colorD = '#ff0000';
    
    
            var pie = d3.pie().value(function(d){return 1})
    
            var svg = d3.select("#pie-chart svg")
                .append("g") //used to group svg elements
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
            var arc = d3.arc();
    
            var gs = svg.selectAll("g")
              .data(d3.values(dataset)).enter().append("g"); 
    
            var path = gs
                .selectAll("path")
                .data(function(d,i) {
                    return pie(d).map(function(e){e.ringIndex = i; return e});
                })
                .enter()
                .append("path")
                .attr("fill", function(d, i, j) {
                    switch (i) {
                    case 0:
                        return colorO;
                        break;
                    case 1:
                        return colorA;
                        break;
                    case 2:
                        return colorB;
                        break;
                    case 3:
                        return colorC;
                        break;
                    case 4:
                        return colorD;
                    } 
    
                })
    
                .attr("d", function(d, i, j) {
                    return arc.innerRadius(cwidth * d.ringIndex).outerRadius(cwidth * (d.ringIndex + 1))(d);
                });
                </script>
    
            </body>  
    </html>
    

    【讨论】:

    • 非常感谢!!!!你拯救了我的一天。你说我的数据集方法有点奇怪。如果我重组它会改变很多吗?我打算稍后使用包含更多信息的 json 文件。然后也许使用 d3.json 来处理它? :)
    • 不是你的数据集很奇怪,只是你不会在d3中那样绑定任何文档元素,可能我说的不太对!事实上,寻找与你的形状相似的数据是如此普遍,以至于 d3 附带了一些小辅助函数,就像在那个小提琴中使用的那样,可以将它们变成绑定到文档元素的形状。我会像你一样出击,并在需要重组它时使用 d3.values()
    • 好的。另一个问题:地图功能。如果我签入 attr("fill",...) 函数 j 是什么..它给了我大量的数组。例如 19 个数组,每个数组有 19 个元素。我发布的小提琴返回了 j 的数值。这就是为什么 j 可用于给出环特定值 + 环特定颜色的原因。我假设地图与它有关。我尝试将 switch/if-else 更改为可以识别每个环的东西(因此数组索引 0 直到数组长度)。但是无论我怎么玩,除了把所有东西都变黑之外,它并没有改变。帮助 .map 可能会有所帮助
    • 是的,这有点让人头疼——第三个参数 'j' 是当前节点的集合(d3 文档非常好,但你需要习惯使用它,如果你是新手——第三个参数记录在github.com/d3/d3-selection/blob/v1.4.1/README.md#selection_attr)为什么它是小提琴中的一个数值?小提琴似乎正在使用 d3 的 v3,从 v3 到 v4 有许多变化,我们现在在 v5
    • 为了解决这个问题,您会看到,当我在示例中进行顶级绑定时,我实际上为数据添加了一个“ringIndex”属性——这是在顶级绑定中可计算的,但当然,您需要在较低级别将其绘制在正确的位置。有不同的方法可以做到这一点,我选择了我喜欢的路线。然后,您可以在您的填充功能中使用 d.ringIndex。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多