简体   繁体   English

D3:数据更新“输入”选择为空

[英]D3: data update “enter” selection is empty

I'm trying to use the data, update, enter pattern in D3 to update some data. 我正在尝试使用数据,更新,在D3中输入模式来更新一些数据。 I've been following this example: https://bl.ocks.org/mbostock/3808218 我一直在关注这个示例: https : //bl.ocks.org/mbostock/3808218

I've got two sets of data, one with an extra value: 我有两组数据,其中一组具有额外的价值:

const data = [
  {
    weekId: "w-1",
    start: 100
  },
  {
    weekId: "w-2",
    start: 200
  }
];

const updatedData = [
  {
    weekId: "w-1",
    start: 100
  },
  {
    weekId: "w-2",
    start: 200
  },
  {
    weekId: "w-3",
    start: 300
  }
];

Some code that creates a set of green blocks 一些代码创建了一组绿色块

// Create initial data
this.visualisation
  .selectAll()
  .data(data, d => d.weekId)
  .enter()
  .append("rect")
  .attr("class", "spline-group")
  .attr("x", w => w.start)
  .attr("y", 20)
  .attr("width", 22)
  .attr("height", 22)
  .attr("fill", "green");

I then do a selection and call data : 然后,我进行选择并调用data

// https://bl.ocks.org/mbostock/3808218
// DATA JOIN
// Join new data with old elements, if any.
const dataGroups = d3
  .selectAll("rect.spline-group")
  .data(updatedData, d => d.weekId);

I update the green blocks to blue (Works fine!): 我将绿色块更新为蓝色(很好!):

// UPDATE
// Update old elements as needed.
dataGroups.attr("fill", "blue");

Here's where I have a problem, I enter on the new data to try append the new rect (white this time so I can see it's new): 这是我遇到的问题,我输入新数据以尝试附加新的rect(这次是白色,所以我可以看到它是新的):

// ENTER
// Create new elements as needed.
const newItems = dataGroups
  .enter()
  .append("rect")
  .attr("class", "spline-group")
  .attr("x", w => w.start)
  .attr("y", 30)
  .attr("width", 20)
  .attr("height", 20)
  .attr("fill", "white");

That newItems selection is always empty, whatever I seem to try. 无论我尝试什么,该newItems选择始终为空。 What's going wrong? 怎么了

Working example: 工作示例:

 const data = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 } ]; const updatedData = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 }, { weekId: "w-3", start: 300 } ]; // Create initial data d3.select("svg") .selectAll() .data(data, d => d.weekId) .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 20) .attr("width", 22) .attr("height", 22) .attr("fill", "green"); // https://bl.ocks.org/mbostock/3808218 // DATA JOIN // Join new data with old elements, if any. const dataGroups = d3 .selectAll("rect.spline-group") .data(updatedData, d => d.weekId); // UPDATE // Update old elements as needed. dataGroups.attr("fill", "blue"); // ENTER // Create new elements as needed. const newItems = dataGroups .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 30) .attr("width", 20) .attr("height", 20) .attr("fill", "white"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg> </svg> 

You are entering the new rectangle, you can log .size() on the enter selection and see one element is added: 您正在输入新的矩形,可以在输入选择中记录.size()并看到已添加一个元素:

 const data = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 } ]; const updatedData = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 }, { weekId: "w-3", start: 300 } ]; // Create initial data d3.select("svg") .selectAll() .data(data, d => d.weekId) .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 20) .attr("width", 22) .attr("height", 22) .attr("fill", "green"); // https://bl.ocks.org/mbostock/3808218 // DATA JOIN // Join new data with old elements, if any. const dataGroups = d3 .selectAll("rect.spline-group") .data(updatedData, d => d.weekId); // UPDATE // Update old elements as needed. dataGroups.attr("fill", "blue"); // ENTER // Create new elements as needed. const newItems = dataGroups .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 30) .attr("width", 20) .attr("height", 20) .attr("fill", "white"); console.log("new items: " + newItems.size()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg> </svg> 

So if you are entering the new element, to where are you appending it? 因此,如果您要输入新元素,则将其附加到何处? Let's look at where your rectangle is: 让我们看一下矩形的位置:

在此处输入图片说明

You did not specify where you wanted the rectangle. 您未指定想要矩形的位置。 When entering the first rectangles you use: 输入第一个矩形时,请使用:

d3.select("svg").selectAll("rect")

And your entered elements are created as children of the svg, on the second enter cycle, you simply use d3.selectAll("rect") . 输入的元素将作为svg的子级创建,在第二个输入循环中,您只需使用d3.selectAll("rect") You didn't specify where you wanted to enter the additional element, so it was appended to the document. 您没有指定要在何处输入其他元素,因此该元素已附加到文档中。

To make sure your enter new elements at the right place, just select the parent container first, as you did when entering the first two elements: 要确保在正确的位置输入新元素,只需像输入前两个元素时一样先选择父容器即可:

const dataGroups = d3.select("svg") // select SVG
    .selectAll("rect.spline-group") // then select all rects.
    .data(updatedData, d => d.weekId);

dataGroups.attr("fill", "blue");

const newItems = dataGroups
   .enter()
   .append("rect")

 const data = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 } ]; const updatedData = [ { weekId: "w-1", start: 100 }, { weekId: "w-2", start: 200 }, { weekId: "w-3", start: 300 } ]; // Create initial data d3.select("svg") .selectAll() .data(data, d => d.weekId) .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 20) .attr("width", 22) .attr("height", 22) .attr("fill", "green"); // https://bl.ocks.org/mbostock/3808218 // DATA JOIN // Join new data with old elements, if any. const dataGroups = d3.select("svg") .selectAll("rect.spline-group") .data(updatedData, d => d.weekId); // UPDATE // Update old elements as needed. dataGroups.attr("fill", "blue"); // ENTER // Create new elements as needed. const newItems = dataGroups .enter() .append("rect") .attr("class", "spline-group") .attr("x", w => w.start) .attr("y", 30) .attr("width", 20) .attr("height", 20) .attr("fill", "crimson"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg width="500"> </svg> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM