javascript - d3 元素未在反应中显示
问题描述
我正在使用对 d3js 做出反应,但由于某种原因,d3 容器 div 没有呈现。我怀疑在选择本地 div 时某些事情没有正确完成,但我不知道是什么。
index.html 和 index.js 文件只是简单的样板代码,唯一的修改是在下面发布的 App.jsx 文件中
import React from "react";
import * as d3 from "d3";
function App() {
const data = [
{ name: "A", score: 70 },
{ name: "B", score: 90 },
{ name: "C", score: 50 }
];
const width = 800;
const height = 800;
const margin = { top: 50, bottom: 50, left: 50, right: 50 };
const svg = d3
.select("#container")
.append("svg")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.attr("viewbox", [0, 0, width, height]);
const x = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.padding(0.1);
const y = d3
.scaleLinear()
.domain([0, 100])
.range([height - margin.bottom, margin.top]);
svg
.append("g")
.attr("fill", "royalblue")
.selectAll("rect")
.data(data.sort((a, b) => d3.descending(a.score, b.score)))
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", (d) => y(d.score))
.attr("width", x.bandwidth())
.attr("height", (d) => y(0) - y(d.score));
svg.node();
return (
<div>
<h1>Chart</h1>
<div id="container"></div>
</div>
);
}
export default App;
解决方案
想想你的代码运行时的世界状态:
- 该
App
组件在页面加载时呈现。 - 我们打电话
d3.select('#container')
,但没有任何反应。页面上没有具有该 ID 的 div,因为我们还没有走到那一步。 - D3 操作继续进行,可能不会引发错误,因为根据设计,D3 允许您对空选择进行操作。
- 我们返回一个 JSX 值来描述我们希望 React 渲染的 DOM。在我们返回这个后不久,元素被渲染到页面中。
- 现在我们有了
#container
元素,但我们的选择代码不会重新运行,因为没有任何东西会触发组件重新渲染。
您可能会考虑使用回调 ref - 这是一个最小的示例:
const doD3Stuff = (element) => {
const width = 800;
const height = 800;
const margin = { top: 50, bottom: 50, left: 50, right: 50 };
const svg = d3
// the select method can accept an actual element instead of a selector
.select(element)
.append("svg");
// etc.
};
const App = () => {
return (
<div>
<h1>Chart</h1>
<div id="container" ref={doD3Stuff} />
</div>
);
};
这是一个起点,但当然它不会涉及当数据更改并且您想要重绘、动画等时会发生什么。
React 和 D3可以很好地协同工作。但即使只使用其中一个,理解执行模型也很好——代码何时运行,何时不运行。将它们一起使用时,具有这种理解水平更为重要,否则会发生您难以进行故障排除的事情。
推荐阅读
- python - 循环字符串以扩展特定字符 Pyhton
- python - 使用 importlib 加载已编译的模块
- c - 如何避免使用 io.popen 从 lua 打开的子进程阻塞 C 线程?
- swift - Alamofire URLRequestConvertible 全局标头
- excel - 电子表格 - 我试图找到两列中前 n 个数字的总和
- python - 如何解决python中的字符串表达式?
- c# - 如何在 Puppeteer Sharp 中实现插件隐身?
- python - 如何从python中的URL读取(.RDS)文件?
- r - dplyr 中的排名函数
- c - 致命错误:glib.h:使用 vscode 和 mingw 时没有这样的文件或目录