JavaScript变量作用域问题:如何用文本输入生成D3图表?
解决D3图表报错“Cannot read property 'links' of undefined”的问题
我一眼就看出问题出在哪了——你把JSON字符串直接当对象用了,而且全局变量的依赖也容易出执行顺序的问题。咱们一步步来修复:
核心问题分析
- JSON字符串未解析:你存在
sessionStorage里的jsontext是字符串格式的JSON,直接赋值给graph后,它还是字符串类型,根本没有links属性,自然会报错。 - 执行顺序/全局变量不可靠:即使你声明了全局
jsontext,如果创建图表的代码在parsequery()执行前就运行,jsontext还是undefined,同样会触发错误。
修复步骤
1. 正确解析JSON字符串
从sessionStorage取出数据后,必须用JSON.parse()把字符串转换成JavaScript对象,这样才能访问graph.links。
2. 避免依赖全局变量,直接从sessionStorage读取
全局变量很容易受代码执行顺序影响,直接从存储中读取并解析是更可靠的方式,还能顺便做空值判断,避免无数据的情况。
修改后的代码示例
保持你的parsequery函数不变(可以去掉多余的jsonstring变量)
function parsequery() { var query = []; var queryoperators = []; var queryterms = []; var jsonnodes = ''; var jsonlinks = ''; // 从文本框输入生成jsonnodes和jsonlinks的逻辑 jsontext = "{\n\t\"nodes\": [" + jsonnodes + "\n\t]," + "\n\n\t\"links\": [" + jsonlinks + "\n\t]\n}"; sessionStorage.setItem("jsontext", jsontext); };
重构创建图表的代码
// 第一步:从sessionStorage获取存储的JSON字符串 var storedJson = sessionStorage.getItem("jsontext"); // 先检查是否有数据,避免无数据时报错 if (!storedJson) { console.error("没有在sessionStorage中找到图表数据,请先执行输入解析!"); return; } // 第二步:将字符串解析为JavaScript对象 var graph = JSON.parse(storedJson); // 第三步:继续D3的图表创建逻辑 var link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) // 别忘了添加enter()来绑定数据到元素(你原来的代码缺了这步) .enter() .append("line") // 这里可以添加样式属性,比如: .attr("stroke", "#ccc") .attr("stroke-width", 1.5);
额外检查点
- 确保
parsequery()函数确实被触发了(比如通过按钮点击事件),否则sessionStorage里不会有数据。 - 虽然你说生成的JSON是有效的,但可以在
parsequery()里加个测试:console.log(JSON.parse(jsontext)),确认解析后的对象结构正确,没有语法错误。
内容的提问来源于stack exchange,提问作者Biffsquiggle
相关产品推荐
相关产品推荐

