[英]Unable to use d3 with react
I wanted to display a d3 graphics inside a modal window created using react-bootstrap.我想在使用 react-bootstrap 创建的模态 window 中显示 d3 图形。 First I tried displaying d3 circle directly inside (non-modal)
div
element.首先,我尝试直接在(非模态)
div
元素内显示 d3 圆圈。 I tried it as follows:我尝试如下:
import "./styles.css";
import React from "react";
import * as d3 from "d3";
export default class App extends React.Component {
testRef = React.createRef();
constructor(props) {
super(props);
this.changeText = this.changeText.bind(this);
}
async changeText() {
let svg = d3
.select(this.testRef.current)
.append("svg")
.attr("width", 200)
.attr("height", 200);
// Add the path using this helper function
svg
.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 50)
.attr("stroke", "black")
.attr("fill", "#69a3b2");
// this.testRef.current.innerHtml = "Test123";
}
render() {
return (
<>
<div className="App">
<div ref={this.testRef} />
<button onClick={this.changeText}> Draw circle inside div </button>
</div>
</>
);
}
}
And its working as can be seen in this codesandbox :它的工作可以在这个代码框中看到:
Now I tried to add d3 circle to modal popup created using react-bootstrap as shown below:现在我尝试将 d3 circle 添加到使用 react-bootstrap 创建的模式弹出窗口中,如下所示:
import React from "react";
import ReactDOM from "react-dom";
import Modal from "react-bootstrap/Modal";
import Button from "react-bootstrap/Button";
import ButtonToolbar from "react-bootstrap/ButtonToolbar";
import * as d3 from "d3";
import "./styles.css";
class App extends React.Component {
constructor(...args) {
super(...args);
this.state = { modalShow: false };
}
testRef = React.createRef();
showD3 = () => {
this.setState({ modalShow: true });
// console.log(this.testRef.current);
let svg = d3
.select(this.testRef.current)
.append("svg")
.attr("width", 200)
.attr("height", 200);
// Add the path using this helper function
svg
.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 50)
.attr("stroke", "black")
.attr("fill", "#69a3b2");
};
render() {
let modalClose = () => this.setState({ modalShow: false });
return (
<>
<ButtonToolbar>
<Button variant="primary" onClick={this.showD3}>
Launch vertically centered modal
</Button>
</ButtonToolbar>
<Modal show={this.state.modalShow} onHide={modalClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
D3 in React
<div ref={this.testRef}></div>
</Modal.Body>
</Modal>
</>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
However this doesnt work as can be seen in this codesandbox :但是,这不起作用,可以在此代码框中看到:
It does show the modal dialog, but without D3 circle.它确实显示了模态对话框,但没有 D3 圆圈。 Why is this so?
为什么会这样?
I realized that we have to handle rendering in component life cycle methods.我意识到我们必须在组件生命周期方法中处理渲染。 In this case in
componentDidMount
method.在这种情况下,在
componentDidMount
方法中。 We have to just manipulate the state in the click event.我们只需要在点击事件中操作 state。 I was able to do this with class components as follows:
我能够使用 class 组件执行此操作,如下所示:
import React from "react";
import ReactDOM from "react-dom";
import Modal from "react-bootstrap/Modal";
import Button from "react-bootstrap/Button";
import ButtonToolbar from "react-bootstrap/ButtonToolbar";
import * as d3 from "d3";
import "./styles.css";
class App extends React.Component {
constructor(...args) {
super(...args);
let _color = "#" + Math.floor(Math.random() * 16777215).toString(16);
this.state = { modalShow: false, color: _color, showChart: false };
}
chart = React.createRef();
componentDidUpdate() {
if (this.state.modalShow) {
this.renderChart();
}
}
renderChart() {
let svg = d3
.select(this.chart.current)
.append("svg")
.attr("width", 200)
.attr("height", 200);
svg
.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 50)
.attr("stroke", "black")
.attr("fill", this.state.color);
}
changeChartState() {
let _color = "#" + Math.floor(Math.random() * 16777215).toString(16);
this.setState({ color: _color });
}
showD3 = () => {
this.setState({ modalShow: true });
this.changeChartState();
};
render() {
let modalClose = () => this.setState({ modalShow: false });
return (
<>
<ButtonToolbar>
<Button variant="primary" onClick={this.showD3}>
Launch vertically centered modal
</Button>
</ButtonToolbar>
<Modal show={this.state.modalShow} onHide={modalClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
D3 in React
<div ref={this.chart}></div>
</Modal.Body>
</Modal>
</>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.