TypeError:this.setAttribute不是函数

时间:2019-08-01 19:03:39

标签: reactjs d3.js

我是d3和reactjs的新手。我正在尝试使用以下Rect.js componenet制作条形图

我尝试在// enter-update之前进行调试,但无济于事。

import React, { Component } from 'react'
import * as d3 from 'd3';

const dataset = [14, 68, 24500, 430, 19, 1000, 5555];
const width = 600;
const height = 400;



export default class Rect extends Component {
constructor(props) {
  super(props);
}

componentWillMount() {

}

componentDidMount() {
  this.renderRect();
}

componentDidUpdate() {
  this.renderRect();

}

renderRect() {
  this.container = d3.select(this.refs.container);


  // draw refs rectangle
  this.rects = this.container.selectAll("bar")
                            .data(dataset)
                            .enter();
  // exit
  this.rects.exit().remove();

  // enter-update
  this.rects = this.rects.enter()
                         .append("rect")
                         .merge(this.rects)
                         .attr("y", d => 24500 - d)
}

  render() {
    return (
      <svg ref="container" width={width} height={height}>

      </svg>
    )
  }
}

错误消息为TypeError: this.setAttribute is not a function;调试时,我发现错误仅在attr之后链接了merge(this.rects)时出现,但我不明白为什么。

setAttribute error message

1 个答案:

答案 0 :(得分:2)

以下是该问题的一个最小示例:

var rect = container.selectAll("rect")
  .data([1,2,3])
  .enter();   // return a selection of entered placeholders

var merge = rect.enter() // return a selection of entered placeholders
  .append("rect") // return a selection of appended nodes
  .merge(rect)    // merge appended nodes with entered placeholders.
  .attr("someAttribute",0); // set an attribute for both appended nodes and entered placeholders.

问题很简单:合并的选区不是您想的那样。

选择rect是由.enter()创建的占位符节点的选择-不是DOM中的实际节点。他们有几种方法,但是没有用于设置属性的方法。这就是上面的代码或您的代码将产生错误的原因:this.setAttribute is not a function,因为setAttribute不是输入的占位符的方法(请参见源here)。

相反,我们只删除第一个.enter()语句。这也将导致您想要的行为,因为我们可能不希望rect成为回车选择,因为我们确实会在此之后退出并进行更新。相反,我们希望rect是现有rect元素的选择,而不是占位符。修改上面的内容,我们就可以考虑得到的更改:

var rect = container.selectAll("rect")
  .data([1,2,3])

rect.enter().append("rect").merge(rect)...

rect.exit()....

或使用您的代码:

  // draw refs rectangle
  this.rects = this.container.selectAll("bar")
      .data(dataset)
      // No enter here

  // exit
  this.rects.exit().remove();

  // enter-update
  this.rects = this.rects.enter()
    .append("rect")
    .merge(this.rects)
    .attr("y", d => 24500 - d)