【问题标题】:D3 - Appending SVG based on JSON DataD3 - 基于 JSON 数据附加 SVG
【发布时间】:2017-09-12 06:33:03
【问题描述】:

在我附加的fiddle 中,您将找到一个可变数据集,它是一个 JSON 对象,其中包含一个包含三个不同 JSON 对象的嵌套数组。下面的代码旨在为每个对象在画布上附加一个圆形元素。 x 位置基于 JSON 中的一个字段,单击圆圈后,会在控制台中打印另一个字段(您会注意到此 JSON 数据是从 Twitter API 中提取的推文)。

但是,当您运行此代码时,只会显示一个圆圈:

canvas.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "node")
      .attr("cx", (d.Followers)/20)
      .attr("cy", 200)
      .attr("r", 30)
      .attr("fill", "#42f459")
      .attr("stroke", "black")
      .attr("stroke-width", 2.5)
      .on("mouseover", mouseOn)
        .on("mouseout", mouseOff)
      .on('mousedown.log', function (d) {
        console.log(d.Tweet);
      });

如何更改此代码以显示所有数据的圆圈,而不是仅显示一个圆圈?单击它并查看打印的内容似乎表明它只是为数据集中的最后一个 JSON 对象附加了一个圆圈。

您可以提供的任何提示将不胜感激。我觉得这是由于缺乏对 data() 和 enter() 在 D3 上下文中的实际含义的理解,因为我是新手。提前非常感谢!

【问题讨论】:

    标签: javascript json d3.js svg


    【解决方案1】:

    试试这样:

     data.forEach(function (d) {
            d.Favourites = d.Favourites;
            d.Default = d["Has Default Profile Image"];  
            d.Followers = d["Number of followers"];
            d.Timestamp = d.Timestamp;
            d.Tweet = d.Tweet;
            d.Url = d["Tweet URL"]
            d.Description = d["User Description"];
            d.Location = d["User Location"];
            d.Verified = d["User Verified"];
            d.Retweets = d.Retweets;
            d.Username = d.Username;
     });
    
           canvas.selectAll("circle")
              .data(data)
              .enter()
              .append("circle")
              .attr("class", "node")
              .attr("cx", function(d){return d.Followers/20})
              .attr("cy", 200)
              .attr("r", 30)
              .attr("fill", "#42f459")
              .attr("stroke", "black")
              .attr("stroke-width", 2.5)
              .on("mouseover", mouseOn)
                .on("mouseout", mouseOff)
              .on('mousedown.log', function (d) {
                console.log(d.Tweet);
              });
    
              function mouseOn(d, i) {
                d3.select(this).attr({
                  fill: "#42f4ee"
                });
              }
    
              function mouseOff(d, i) {
                d3.select(this).attr({
                  fill: "#42f459"
                });
              }
    

    工作示例here。首先,您需要设置数据,一旦数据准备好,然后遍历每个项目并绘制圆圈。

    【讨论】:

    • 非常感谢约翰!我感谢您的帮助。所以我现在知道你必须先设置数据。你必须为此使用 ForEach 吗?如果您想一次显示 n 个圆圈怎么办?当您第二次调用 function(d) 时,是否会替换已经存在的数据?我想我有点不确定这个 d 代表什么。
    • 这部分本质上是for循环,输入后的所有内容都是针对数组中的每个对象完成的。 canvas.selectAll("circle") .data(data) .enter() ----- 为每个对象做一些事情 --------- function(d) 将当前对象传递给一个函数,该函数您可以使用它来询问对象并根据其属性返回值。
    • 我明白了,谢谢。最后一个问题(抱歉):假设我只想为前 n 个 JSON 对象创建圆圈。这是否涉及用以下内容替换 ForEach 块? - for (var i = 0; i
    • 您需要在将数据数组传递给 d3 之前对其进行操作。创建一个新的数据数组,var dataSubset = data.slice(0, 3);。这将返回前 3 个对象。然后使用 dataSubset,例如.data(数据子集)。在此处查看有关切片的更多信息w3schools.com/jsref/jsref_slice_array.asp。
    猜你喜欢
    • 1970-01-01
    • 2014-03-10
    • 2017-12-09
    • 2015-07-25
    • 1970-01-01
    • 2014-01-05
    • 2015-06-13
    • 2017-06-17
    相关资源
    最近更新 更多