d3.js 将D3代码转换为Vue 3-单元格未添加到行,而是添加到HTML

h43kikqp  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(131)

我找到了迈克·博斯托克的adjacency matrix visualizationGitHub version,使用的是《悲惨世界》中的数据。
我把它转换成了Vue3代码,但由于这是我的第一个项目,我可能犯了一些错误。应该添加到每行的单元格被添加到了主HTML中,可视化没有出现(黑屏)。
以下是Vue3格式的转换可视化的在线版本:https://codesandbox.io/s/sweet-gould-dejiuj?file=/src/components/Miserables.vue:33765-33857

vfwfrxfs

vfwfrxfs1#

这是因为方法roww()的上下文不是正确的上下文。
使用以下代码创建一行:

const row = this.svg
  .selectAll(".row")
  .data(this.matrix)
  .enter()
  .append("g")
  .attr("class", "row")
  .attr("transform", (d, i) => `translate(0,${this.x(i)})`)
  .each(this.roww);

最后一行为选择的每个节点调用this.roww,但该函数的上下文(this.roww内的this关键字)以某种方式硬编码到其所属的对象,因此它没有接收到正确的上下文,该上下文应该是与DOM相关的实际节点对象。
为了解决这个问题,你需要使用一个用function关键字创建的常规函数(不是箭头函数,原因和上面一样),这样它就可以传递正确的上下文,尽管因为你的函数精确地依赖于它的“父”上下文(另一个this),你将不得不在外部作用域中设置一个引用它的变量,这样它就可以在函数中被读取:

// ...

const that = this;

function fillrow (row) {
  // eslint-disable-next-line no-unused-vars
  const cell = d3.select(this).selectAll(".cell")
    .data(row.filter((d) => d.z))
    .enter()
    .append("rect")
    .attr("class", "cell")
    .attr("x", (d) => that.x(d.x))
    .attr("width", that.x.bandwidth())
    .attr("height", that.x.bandwidth())
    .style("fill-opacity", (d) => that.z(d.z))
    .style("fill", (d) =>
      that.get_nodes[d.x].group === that.get_nodes[d.y].group
        ? that.c(that.get_nodes[d.x].group)
        : null
    )
    .on("mouseover", that.mouseover)
    .on("mouseout", that.mouseout);
}

const row = this.svg
  .selectAll(".row")
  .data(this.matrix)
  .enter()
  .append("g")
  .attr("class", "row")
  .attr("transform", (d, i) => `translate(0,${this.x(i)})`)
  .each(fillrow);

// ...

相关问题