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

时间:2019-03-18 18:10:39

标签: javascript d3.js

我正在尝试使用数据,进行更新,在D3中输入模式以更新一些数据。我一直在关注这个示例:https://bl.ocks.org/mbostock/3808218

我有两组数据,其中一组具有额外的价值:

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
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");

然后我进行选择并致电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);

我将绿色块更新为蓝色(可以正常工作!):<​​/ p>

// 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");

无论我尝试如何,newItems选择始终是空的。怎么了?

工作示例:

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>

1 个答案:

答案 0 :(得分:4)

您正在输入新的矩形,可以在输入选择中登录.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>

因此,如果您要输入新元素,则将其附加到何处?让我们看一下矩形的位置:

enter image description here

您没有指定想要矩形的位置。输入第一个矩形时,请使用:

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

您输入的元素被创建为svg的子级,在第二个输入循环中,您只需使用d3.selectAll("rect")。您没有指定要在何处输入其他元素,因此该元素已附加到文档中。

要确保在正确的位置输入新元素,只需像输入前两个元素一样先选择父容器即可。

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>