D3 v.4 - 比较多个数据集的值

时间:2017-09-24 16:55:14

标签: javascript d3.js

(这是一个问题的重新阐述,我没有用足够精确的语言提出问题;我为此道歉。)

我有数据比较问题。 我有两个数据集(这里简化得很多):

var cat = {
    continents: [
        {
            name:"Africa",
            ab:"AF",
            countries: [
                {name:"Egypt",ab:"Eg"},
                {name:"Niger",ab:"Ng"}
            ]
        },
        {
            name:"America",
            ab:"AM",
            countries: [
                {name:"Brasil",ab:"Br"},
                {name:"Canada",ab:"Ca"},
                {name:"United States",ab:"Us"},
                {name:"Venezuela",ab:"Vz"}
            ]
        },
        {
            name:"Asia",
            ab:"AS",
            countries: [...]
        },
        {
            name:"Europe",
            ab:"EU",
            countries: [
                {name:"France",ab:"Fr"},
                {name:"Germany",ab:"Ge"},
                {name:"Greece",ab:"Gr"},
                {name:"Italy",ab:"It"},
                {name:"United Kingdom",ab:"Uk"}
            ]
        },
        {
            name:"Oceania",
            ab:"OC",
            countries: [...]
        }
    ]
},
{...}

var currentNodes = [
   {name:"Japan",continent:"AS",country:"Jp",x:200,y:50},
   {name:"Italy",continent:"EU",country:"It",x:50,y:400},
   {name:"Bologna",continent:"EU",country:"It",x:180,y:100},
   {name:"Florence",continent:"EU",country:"It",x:50,y:200},
   {name:"Germany",continent:"EU",country:"Ge",x:350,y:430},
   {name:"Canada",continent:"AM",country:"Ca",x:180,y:400}
]

我试图为每个大陆(以及在第二阶段,每个国家)检索" ab"如果它们在currentNodes集中存在(如#34; continent"和#34; country")(为了能够更新它们)。

如果我理解正确,以下只返回currentNodes数组中的所有对象:

d3.select('#nav').selectAll('p').data(cat.continents).enter()
    .insert('p').text(function(d) {
        var filteredNodes = currentNodes.filter(function(f) {
            return d.ab == f.continent;
        })
        return filteredNodes;})

- 但我不知道为什么我不能选择相关的值:

d3.select('#nav').selectAll('p').data(cat.continents).enter()
    .insert('p').text(function(d) {
        var filteredNodes = currentNodes.filter(function(f) {
            return d.ab == f.continent;
        })
        return filteredNodes.ab;})

我很乐意找到解决方案,但也要了解我在这里遇到的问题。非常感谢您的帮助 - 宽大!

2 个答案:

答案 0 :(得分:0)

在第二个示例中,您将返回一个对象数组,您希望这些对象只有一个项目。所以你应该使用

return filteredNodes[0].ab

(当然,如果你的数据集没有正确填充,你可能没有匹配或多个匹配,所以可能也想添加一些例外)

答案 1 :(得分:0)

查看您的currentNodes数组。其中没有名为ab的属性。这是cat.continents的属性。

因此,如果我正确理解你想要的东西,你可以在currentNodes数组中映射大陆:

var continentList = currentNodes.map(function(d) {
    return d.continent
}) 

并检查新阵列中是否存在ab

.text(function(d) {
    return continentList.indexOf(d.ab) > -1 ? d.ab : "not in list";
})

在这里,我使用三元运算符和字符串“not in list”来表示错误情况。

以下是演示:

var cat = {
  continents: [{
    name: "Africa",
    ab: "AF",
    countries: [{
      name: "Egypt",
      ab: "Eg"
    }, {
      name: "Niger",
      ab: "Ng"
    }]
  }, {
    name: "America",
    ab: "AM",
    countries: [{
      name: "Brasil",
      ab: "Br"
    }, {
      name: "Canada",
      ab: "Ca"
    }, {
      name: "United States",
      ab: "Us"
    }, {
      name: "Venezuela",
      ab: "Vz"
    }]
  }, {
    name: "Asia",
    ab: "AS",
    countries: [{
      name: "Foo",
      ab: "Fo"
    }, {
      name: "Bar",
      ab: "Ba"
    }]
  }, {
    name: "Europe",
    ab: "EU",
    countries: [{
      name: "France",
      ab: "Fr"
    }, {
      name: "Germany",
      ab: "Ge"
    }, {
      name: "Greece",
      ab: "Gr"
    }, {
      name: "Italy",
      ab: "It"
    }, {
      name: "United Kingdom",
      ab: "Uk"
    }]
  }, {
    name: "Oceania",
    ab: "OC",
    countries: [{
      name: "Foo",
      ab: "Fo"
    }, {
      name: "Bar",
      ab: "Ba"
    }]
  }]
};

var currentNodes = [{
  name: "Japan",
  continent: "AS",
  country: "Jp",
  x: 200,
  y: 50
}, {
  name: "Italy",
  continent: "EU",
  country: "It",
  x: 50,
  y: 400
}, {
  name: "Bologna",
  continent: "EU",
  country: "It",
  x: 180,
  y: 100
}, {
  name: "Florence",
  continent: "EU",
  country: "It",
  x: 50,
  y: 200
}, {
  name: "Germany",
  continent: "EU",
  country: "Ge",
  x: 350,
  y: 430
}, {
  name: "Canada",
  continent: "AM",
  country: "Ca",
  x: 180,
  y: 400
}];

var continentList = currentNodes.map(function(d) {
  return d.continent
})

d3.select("body").selectAll(null)
  .data(cat.continents)
  .enter()
  .append('p')
  .text(function(d) {
    return continentList.indexOf(d.ab) > -1 ? d.ab : "not in list";
  })
<script src="//d3js.org/d3.v4.min.js"></script>

我怀疑你不想向各大洲展示“不在列表中”。在这种情况下,最好的想法是在将数据绑定到元素之前过滤数据数组(在输入选择中)。