D3.js和嵌套数据-为什么我的exit()设置为空

时间:2018-11-27 15:05:53

标签: javascript d3.js nested

使用D3.js处理嵌套数据时遇到问题

数据由代表categories的对象数组组成。 每个类别都有多个checkin。 我希望每个category都有一个小节,其中每个checkin都有一个div。我会随着时间处理数据,并依靠D3.js的更新,输入和退出机制将数据正确输出到DOM。

我不明白的地方:

  • 为什么当调用第二次更新时,旧数据没有显示在exit()集中,因此不会被删除?
  • 为什么再次用update()再次调用data1时,尽管提供了数据中的关键功能,条目还是再次追加了?根据我的理解,D3应该认识到这实际上是一次更新,并且本节中已经存在具有相同密钥的数据。

第二个问题可能与第一个有关,但是现在我不确定。

这是一个互动式的bl.ocks.org:https://bl.ocks.org/mattleonowicz/fd975a6d914f90c9934464df57e498c9

下面的相同代码:

<html>
<body>
<div id="app" /> 
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
  const data1 = [
  {
    category: {
      id: 1
    },
    checkins: [
      {
        lat: 1,
        lon: 1
      },
      {
        lat: 2,
        lon: 2
      }
      // ... more objects like this would normally be here
    ]
  }
  // ... more objects like this would normally be here
];
const data2 = [
  {
    category: {
      id: 1
    },
    checkins: [
      {
        lat: 3,
        lon: 3
      },
      {
        lat: 4,
        lon: 4
      }
      // ... more objects like this would normally be here
    ]
  }
  // ... more objects like this would normally be here
];

update(data1);
setTimeout(() => update(data2), 2000);
setTimeout(() => update(data1), 4000);

function update(data) {
  const categoriesData = d3.select('#app')
    .selectAll('section')
    .data(data, d => d.category.id);

  // CATEGORIES EXIT
  categoriesData.exit()
    .remove();

  // CATEGORIES UPDATE + ENTER - bind all categories with their checkins
  const checkinsData = categoriesData.enter()
    .append('section')
    .merge(categoriesData)
    .selectAll('section')
    .data(d => d.checkins, d => `${d.lon},${d.lat}`);

  // CHECKINS UPDATE : nothing, because checkins will only come and go

  // CHECKINS EXIT
  checkinsData.exit()
    .remove();

  // CHECKINS ENTER
  checkinsData.enter()
    .append('div')
    .html(d => `${d.lon},${d.lat}`);
}
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:-2)

您在这里有错字:

  // CATEGORIES UPDATE + ENTER - bind all categories with their checkins
  const checkinsData = categoriesData.enter()
    .append('section')
    .merge(categoriesData)
->  .selectAll('section')
    .data(d => d.checkins, d => `${d.lon},${d.lat}`);

您想在第二个选择中写.selectAll('div')