我是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)
时出现,但我不明白为什么。
答案 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)