学习D3加载外部.json/.csv文件时遇多版本报错求助
解决D3.js加载外部文件及版本兼容问题
让我一步步帮你排查和解决这些问题:
1. D3 v4报错:Uncaught TypeError: canvas.selectAll(...).data(...).enter is not a function
这个问题的核心是D3 v4+的异步回调参数顺序变了。在v4及以后版本中,d3.json的回调函数第一个参数是错误对象,第二个才是请求到的数据,你原来的写法把错误对象当成了数据使用,导致data是undefined,后续链式调用自然出错。
修复后的代码应该是:
d3.json("mydata.json", function(error, data) { // 先处理错误情况 if (error) { console.error("加载JSON失败:", error); return; } // 后续你的可视化代码放在这里 var canvas=d3.select("body") .append("svg") .attr("width", 500) .attr("height", 500); // 绘制矩形部分保持不变 canvas.selectAll("rect") .data(data) .enter() .append("rect") .attr("width", function(d){return d.age*10;}) .attr("height", 50) .attr("fill", "blue") .attr("y", function(d,i){return i * 60}); // 注意这里的text选择器要改成selectAll("text"),否则enter无法正确生成多个文本元素 canvas.selectAll("text") .data(data) .enter() .append("text") .attr("fill", "white") .attr("y", function(d, i){return i * 60 + 30;}) // 调整y值让文本显示在矩形内 .text(function(d) {return d.name;}); });
2. D3 v3报错:Uncaught TypeError: Cannot read property 'length' of null
v3的d3.json回调参数顺序是(data, error),但你的Node.js服务器有个致命问题:不管请求什么资源,都返回index.html的内容。当D3请求mydata.json时,服务器返回的是HTML页面,不是合法的JSON,所以解析后data为null,导致后续操作报错。
3. 加载.csv时的Error: attribute width: Expected length, "NaN"
同样是服务器的问题:请求.csv文件时,服务器依然返回index.html,D3解析HTML内容为CSV自然失败,得到的数据是无效的,计算d.age*10时就会出现NaN。
修复Node.js服务器,支持多文件请求
修改你的app.js,让它根据请求的URL返回对应的文件:
const http = require('http'); const fs = require('fs'); const path = require('path'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { // 处理根路径请求,返回index.html let filePath = req.url === '/' ? './index.html' : `.${req.url}`; // 根据文件后缀设置正确的Content-Type const extname = path.extname(filePath); let contentType = 'text/html'; switch (extname) { case '.json': contentType = 'application/json'; break; case '.csv': contentType = 'text/csv'; break; case '.js': contentType = 'text/javascript'; break; } fs.readFile(filePath, (err, content) => { if (err) { if (err.code === 'ENOENT') { // 文件不存在时返回404 res.writeHead(404, { 'Content-Type': 'text/html' }); res.end('<h1>404 File Not Found</h1>'); } else { // 服务器错误返回500 res.writeHead(500); res.end(`服务器错误: ${err.code}`); } } else { // 文件存在时返回正确内容和类型 res.writeHead(200, { 'Content-Type': contentType }); res.end(content, 'utf-8'); } }); }); server.listen(port, hostname, () => { console.log(`Server started at http://${hostname}:${port}`); });
验证步骤
- 把修改后的
app.js、index.html、mydata.json放在同一目录下 - 运行
node app.js启动服务器 - 访问
http://127.0.0.1:3000,应该能正常显示带有蓝色矩形和白色文本的可视化效果 - 如果测试.csv文件,确保你的CSV格式正确(比如第一行是表头
name,age,后续行是数据),并在代码中使用d3.csv替代d3.json,同时注意回调参数顺序(v4+是error, data)
内容的提问来源于stack exchange,提问作者nganlong
相关产品推荐
相关产品推荐

