2

我肯定对 d3 越来越熟悉了,开始探索过渡和什么不是,并开始真正了解数据是如何组合在一起的。

我正在研究一个具体的例子,一个气泡图,http ://bl.ocks.org/mbostock/4063269 :

在此处输入图像描述

我试图重新利用它来代表人口随时间的增长。这是我的 JSON

{
"name":"Population over Time",
"children":[
    {
    "name": "1790",
    "children": [
        {"locID":"1","name": "New York city, NY", "size": 33131},
        {"locID":"2","name": "Philadelphia city, PA", "size": 28522},
        {"locID":"3","name": "Boston town, MA", "size": 18320},
        {"locID":"4","name": "Charleston city, SC", "size": 16359},
        {"locID":"5","name": "Baltimore town, MD", "size": 13503},
        {"locID":"6","name": "Northern Liberties township, PA", "size": 9913},
        {"locID":"7","name": "Salem town, MA", "size": 7921},
        {"locID":"8","name": "Newport town, RI", "size": 6716},
        {"locID":"9","name": "Providence town, RI", "size": 6380},
        {"locID":"10","name": "Marblehead town, MA", "size": 5661},
        {"locID":"11","name": "Southwark district, PA", "size": 5661},
        {"locID":"12","name": "Gloucester town, MA", "size": 5317},
        {"locID":"13","name": "Newburyport town, MA", "size": 4837},
        {"locID":"14","name": "Portsmouth town, NH", "size": 4720},
        {"locID":"15","name": "Sherburne town (Nantucket), MA", "size": 4620},
        {"locID":"16","name": "Middleborough town, MA", "size": 4526},
        {"locID":"17","name": "New Haven city, CT", "size": 4487},
        {"locID":"18","name": "Richmond city, VA", "size": 3761},
        {"locID":"19","name": "Albany city, NY", "size": 3498},
        {"locID":"20","name": "Norfolk borough, VA", "size": 2959},
        {"locID":"21","name": "Petersburg town, VA", "size": 2828},
        {"locID":"22","name": "Alexandria town, VA", "size": 2748},
        {"locID":"23","name": "Hartford city, CT", "size": 2683},
        {"locID":"24","name": "Hudson city, NY", "size": 2584}
        ]
    },
    {
    "name": "1800",
    "children": [
        {"locID":"1","name": "New York city, NY", "size": 60515},
        {"locID":"2","name": "Philadelphia city, PA", "size": 41220},
        {"locID":"25","name": "Baltimore city, MD", "size": 26514},
        {"locID":"3","name": "Boston town, MA", "size": 24937},
        {"locID":"4","name": "Charleston city, SC", "size": 18824},
        {"locID":"6","name": "Northern Liberties township, PA", "size": 10718},
        {"locID":"11","name": "Southwark district, PA", "size": 9621},
        {"locID":"7","name": "Salem town, MA", "size": 9457},
        {"locID":"9","name": "Providence town, RI", "size": 7614},
        {"locID":"20","name": "Norfolk borough, VA", "size": 6926},
        {"locID":"8","name": "Newport town, RI", "size": 6739},
        {"locID":"13","name": "Newburyport town, MA", "size": 5946},
        {"locID":"18","name": "Richmond city, VA", "size": 5737},
        {"locID":"26","name": "Nantucket town, MA", "size": 5617},
        {"locID":"14","name": "Portsmouth town, NH", "size": 5339},
        {"locID":"12","name": "Gloucester town, MA", "size": 5313},
        {"locID":"27","name": "Schenectady city, NY", "size": 5289},
        {"locID":"19","name": "Albany city, NY", "size": 5289},
        {"locID":"10","name": "Marblehead town, MA", "size": 5211},
        {"locID":"28","name": "New London city, CT", "size": 5150},
        {"locID":"29","name": "Savannah city, GA", "size": 5146},
        {"locID":"30","name": "Alexandria town, DC", "size": 4971},
        {"locID":"16","name": "Middleborough town, MA", "size": 4458},
        {"locID":"31","name": "New Bedford town, MA", "size": 4361},
        {"locID":"32","name": "Lancaster borough, PA", "size": 4292},
        {"locID":"17","name": "New Haven city, CT", "size": 4049},
        {"locID":"33","name": "Portland town, ME", "size": 3704},
        {"locID":"24","name": "Hudson city, NY", "size": 3664},
        {"locID":"23","name": "Hartford city, CT", "size": 3523},
        {"locID":"21","name": "Petersburg town, VA", "size": 3521},
        {"locID":"34","name": "Washington city, DC", "size": 3210},
        {"locID":"35","name": "Georgetown town, DC", "size": 2993},
        {"locID":"36","name": "York borough, PA", "size": 2503}
        ]
    }
    ]
}

没有做很多很酷的事情,我已经能够从每年显示一组特定的数据开始,调整过滤器让我加载它只显示特定的年份,但看起来这是不正确的方式,因为如果我手动将过滤器更改为下一年,那么它只显示 1800 的气泡,但中心有空白区域,好像它仍在尝试加载 1790 气泡。

var node = svg.selectAll(".node")
      .data(bubble.nodes(classes(root))
      .filter(function(d) {
        if(d.depth == 1 && d.packageName == year){
            return d;
        }
        else{
            return null;
        }
      }))
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

我也很难找到一种方法来使用 JS 命令更改该过滤器,以便人们可以在年份之间切换。我怎样才能更好地理解这一点?

4

1 回答 1

2

问题是所有气泡的位置都是在您创建布局时确定的,而不是在您附加所有内容时确定的。如果您只想为 1800 个点创建气泡,则需要在应用布局之前过滤数据。它不是试图加载气泡,但它们是您传递给 bubble.nodes 的数据的一部分。(具体来说,您在类(根)中传递了它们。

您可以通过使用气泡图示例中.filter的函数内部的 javascript 方法来执行此操作。.classes()

这是一个示例,我将其更改为仅显示layout包中的类:

// Returns a flattened hierarchy containing all leaf nodes under the root.
function classes(root) {
  var classes = [];

  function recurse(name, node) {
    if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
    else classes.push({packageName: name, className: node.name, value: node.size});
  }

  recurse(null, root);
  classes = classes.filter(function(thisClass){return thisClass.packageName == 'layout'}) 
  return {children: classes};
}

另请注意,过滤器函数不会返回我想要的元素,它会为每个元素返回一个布尔值,说明我是否想要它。它也不会修改它所使用的数组,因此classes == classes.filter()是必需的。

我在这里建立了一个气泡图示例的工作小提琴

在原始气泡图中,过滤器会删除出现在其他圆圈后面的一些圆圈。

编辑(回答您的问题):

将所有数据存储在一个data对象中。classes您可以使用包含特定年份的内部过滤器的函数的修改版本。(类似于我packageName在示例中过滤到特定的内容)。要更新,请选择所有节点并在其中输入您的新数据,其中包含以下内容:

d3.selectAll('.node').data(bubble.nodes(modifiedClasses(root,year))

请注意,这不会自动更新所有节点,只会更新数据,只会更改底层数据结构。然后,您将使用标准的 d3 进入/退出/更新模式来更改您的可视化。这种结构最好的例子就是这个块。我进一步建议为此使用键控数据,以区分位置。如果你使用

.data(bubble.nodes(modifiedClasses(root,year)),function(d){return d.locID}) 

每个元素将对应一个特定的地方。如果您这样做,而不是删除所有数据点然后重建,您可以删除在新日期不存在的所有位置(具有某些.exit()行为),添加任何新位置(使用.enter()),并更新存在于两年。查看一般更新系列中的下两个块(我在上面链接的块),以获得如何执行此操作的一个很好的示例。如果你能弄明白,你就能很好地掌握 d3 中数据操作的基本工作原理。

于 2013-07-25T21:37:11.627 回答