【问题标题】:D3 change elements based on two different datasets?D3 根据两个不同的数据集更改元素?
【发布时间】:2014-01-24 02:20:38
【问题描述】:

我是 d3 新手,也不是 javascript 专家。我发现了类似的问题,但没有一个是我正在寻找的。 我有两个 csv 文件,一个带有看起来像这样的学校数据 id、姓名、经度、纬度

另一个csv有网络数据

idnetId(这是连接的其他学校id)、hits(这基本上是两者之间有多少连接学校)

我将学校数据绑定到地图上的圆圈。我想要做的是点击一下,找到每个连接的学校,并根据他们有多少连接在地图上转换他们的圈子。

我假设这需要一系列 for 循环,但我不确定最好的方法。 目前,跳过所有地图创建的东西,我有这个:

    var currData = [];

 d3.csv("network.csv", function(networkData){
    d3.csv("schoolData.csv", function(data) {

             //create the circles

             var circle = svg.selectAll("circle")
     //bind the data
                    .data(data)
                    .enter()
                    .append("circle")
                    .attr("cx", function(d) {
                        return projection([d.lon, d.lat])[0];
                    })
                    .attr("cy", function(d) {
                        return projection([d.lon, d.lat])[1];
                    })

                //initial style of circles (will move this into a class eventually)
                    .attr("r", 5)
                    .style("fill", "orange")
                    .style("opacity", 0.75)



            //on click 
                    .on("click", function (d) {


            for (i = 0; i<= networkData.length; i++) {
                    if(d.id == networkData[i].id) {  
                    currData.push({"netId": networkData[i].netId,
                                    "hits": networkData[i].hits}
                        )}
                    };

如果我在 for 循环中将它记录到控制台,这将返回 netId 并命中,但我似乎无法在 for 循环之外访问 currData。我不确定为什么。 我也不确定获取每个后续​​ netId 并将它们链接回绑定到圆形元素的学校数据的最佳方法。我是否让这变得比必要的更复杂? D3 有简单的方法吗?

当在地图上点击一个圆圈时,我需要找到所选学校在网络中的学校 id,然后根据点击次数在地图上更改他们的圆圈。非常喜欢this

数据如下:

School Data: 

id,school,lon,lat
1,UC Berkeley,-122.250502,37.872855
2,UC Los Angeles,-118.445227,34.06886
3,Cal State Los Angeles,-118.168266,34.068232
4,University of Southern California,-118.2866414,34.021801

Network Data:

id,netId,hits
193,220,1
193,229,5
193,226,1
193,49,1
124,226,11
124,201,1
278,175,7
341,227,1
341,310,2
341,135,1
101,201,1

【问题讨论】:

  • 定义“点击一下,找到每个连接的学校,并根据他们有多少连接在地图上转换他们的圈子。”并给出两个数据集的示例作为上下文。
  • 如果你能准备一个 jsfiddle 或类似的东西也会有所帮助。
  • 我已编辑添加数据示例并希望澄清。让我知道它是否需要更多。我看看能不能弄个小提琴。

标签: javascript csv d3.js


【解决方案1】:

如果您希望能够根据数据属性选择元素,最简单的方法是根据该数据为元素指定类名。例如,您的所有学校元素都可以根据数据中的 id、“s-1”、“s-203”等来创建一个班级。

然后,当您从网络数据表中找到在一行中引用的 id 时,很容易选择相应的元素并根据需要进行更改。

这是一个例子。我使用 Array.forEach() 而不是 for 循环,但这与您的想法相似。我不太确定您是如何使用过滤后的数据数组的,以及为什么它不适合您,但希望这能让您开始:

http://fiddle.jshell.net/V5DCx/

但是,与其在每次点击时扫描网络数据,不如预先处理数据并将其包含在学校的数据对象中。您可以使用d3.nest 根据 id 将网络数据分组为子数组,然后对学校数组进行一次排序,将正确的网络子数组附加到学校数据,然后再将学校数据附加到您的 d3 图形。然后它将在您的function(d) 事件处理程序中等待。

【讨论】:

  • 这正是我想要的。谢谢!像魅力一样工作。
  • 您建议使用 d3.nest 将数据包含在对象中。我认为这对标签、附加和退出很有用,但我不知道如何使用 .nest 对数据进行分组。你对那个 .nest 代码有什么建议吗?我应该使用地图功能根据 id 对网络数据进行分组吗?
  • 您使用d3.nest() 函数,首先设置它的关键访问函数,然后调用它的entries 方法。 Specs hereTutorial here。排序实际上更麻烦,因为嵌套会将您的键转换为字符串(因此排序顺序可能不同)。在将嵌套网络分配给这个小提琴中的学校数据对象时,我跳过了它,只是扫描了数组:fiddle.jshell.net/V5DCx/1 效率不高,但你只做一次。
  • 如果您愿意,您可以创建两个不同的网络阵列嵌套版本——一个用于传出网络,一个用于传入网络。您所更改的只是嵌套键功能。
  • 非常感谢。我看到你在小提琴中做了什么,这是有道理的,但是当我将它添加到我的代码中时,nestedData 返回未定义,因此无法读取值。我不确定我做错了什么......虽然它可能与数据加载有关。我把我的代码放在这里:jsfiddle.net/UtHGv。我真的很感激帮助!我正在慢慢掌握 d3 的窍门。 :)
猜你喜欢
  • 1970-01-01
  • 2021-11-04
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多