D3分级统计图更新问题:点击按钮切换CSV数据无响应求助
解决D3.js按钮切换CSV更新地图无变化的问题
嘿,我看了你的代码,问题主要出在没有把新CSV的数据重新关联到地图的GeoJSON属性里,还有一些小的语法和逻辑问题,我帮你梳理一下并修正:
核心问题分析
- 你的切换函数里只是重复设置了填充颜色,但没有把新CSV的数据更新到地图要素的
properties.value里,所以用的还是初始加载的旧数据 - 没有根据新CSV的数据更新颜色比例尺
color的domain,新数据的数值范围可能和原来的不一样,颜色映射会出错 - 存在语法错误:
d3.select("option1")缺少id选择器#,而且这行代码没有实际作用;viewManagers函数末尾多了一个多余的}); - 重复代码太多,应该把数据合并和地图更新的逻辑抽成复用函数,避免冗余
修正后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>D3: Setting path fills dynamically to generate a choropleth</title> <h1>Relation between Managers and Tertiary Education </h1> <div id="option1"> <input type="button" value="Education" onclick="viewEducation()" /> </div> <div id="option2"> <input type="button" value="Managers" onclick="viewManagers()" /> </div> <script type="text/javascript" src="d3.js"></script> <style type="text/css"> /* No style rules here yet */ </style> </head> <body> <script type="text/javascript"> //Width and height var w = 1000; var h = 600; var path = d3.geoPath() .projection(d3.geoMercator() .center([151,-33.5]) .scale(17000) .translate([w/2,h/2])); //Define quantize scale to sort data values into buckets of color var color = d3.scaleQuantize() .range(["rgb(237,248,233)","rgb(200,235,198)", "rgb(186,228,179)","rgb(146,208,140)", "rgb(116,196,118)", "rgb(88,178,100)", "rgb(49,163,84)", "rgb(20,130,60)", "rgb(0,109,44)"]); //Create SVG element var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); // 存储GeoJSON数据,方便后续切换时复用 var geoJsonData; // 初始化加载地图和初始数据 d3.json("australia_adm2.json", function(json) { geoJsonData = json; // 先加载Manager数据作为初始显示 loadCsvData("ManagerPercentage.csv"); }); // 复用函数:加载CSV并更新地图 function loadCsvData(csvPath) { d3.csv(csvPath, function(d) { d.value = parseFloat(d.value); return d; }, function(data) { // 更新颜色比例尺的domain为当前CSV的数值范围 color.domain([ d3.min(data, function(d) { return d.value; }), d3.max(data, function(d) { return d.value; }) ]); // 把新CSV的数据合并到GeoJSON的properties里 for (var i = 0; i < data.length; i++) { var dataState = data[i].state; var dataValue = parseFloat(data[i].value); for (var j = 0; j < geoJsonData.features.length; j++) { var jsonState = geoJsonData.features[j].properties.sa4_name11; if (dataState == jsonState) { geoJsonData.features[j].properties.value = dataValue; break; } } } // 更新地图的填充颜色 svg.selectAll("path") .data(geoJsonData.features) .style("fill", function(d) { var value = d.properties.value; if (value) { return color(value); } else { return "#ccc"; } }); }); } // 切换到教育数据 function viewEducation () { loadCsvData("EducationPercentage.csv"); } // 切换到管理者数据 function viewManagers () { loadCsvData("ManagerPercentage.csv"); } </script> </body> </html>
关键修改点说明
- 把GeoJSON数据存储在全局变量
geoJsonData里,避免每次切换都重新加载JSON文件,提升性能 - 抽取出
loadCsvData复用函数,把加载CSV、更新比例尺domain、合并数据到GeoJSON、更新地图颜色的逻辑都放在这里,避免重复代码 - 修复了语法错误:移除了无用的
d3.select("option1"),删掉了viewManagers里多余的闭合括号 - 切换函数现在只需要调用复用函数并传入对应的CSV路径即可,逻辑清晰
- 确保每次切换时,都会把新CSV的数据重新关联到地图要素的属性中,并且更新颜色比例尺的范围,这样颜色映射才会准确
内容的提问来源于stack exchange,提问作者Jgreensie
相关产品推荐
相关产品推荐

