D3地图缩放功能报错:d3.behavior未定义问题求助
解决D3.js中
d3.behavior is undefined的缩放功能问题 兄弟,你这个报错太典型了——D3.js版本不兼容!d3.behavior.zoom是D3 v3及更早版本的写法,而你现在用的应该是v4或更高版本,这些版本里已经把缩放模块改成了d3.zoom(),旧写法自然会提示undefined,连带地图也因为代码报错加载失败了。
我帮你把代码改成适配v4+版本的写法,一步步来:
1. 替换缩放对象的创建
把原来的d3.behavior.zoom()改成d3.zoom(),scaleExtent的用法保留,但事件绑定逻辑要调整:
// 旧写法(v3) // var zoom = d3.behavior.zoom() // .scaleExtent([1, 8]) // .on("zoom", zoomed); // 新写法(v4+) var zoom = d3.zoom() .scaleExtent([1, 8]) .on("zoom", zoomed);
2. 调整SVG结构,明确缩放容器
你原来的代码把zoom绑定在了g元素上,这不对——zoom应该绑定在最外层的svg元素上,同时要把地图元素的容器g单独存为变量,方便后续缩放变换:
var svg = d3.select("#map") .classed("svg-cont", true) .append("svg") .attr("preserveAspectRatio", "xMinYMin meet") .attr("viewBox", "0 0 560 350") .classed("svg-content-responsive", true); // 单独创建地图容器g,后续缩放的就是这个元素 var g = svg.append("g"); // 把zoom绑定到svg上,而不是g svg.call(zoom);
注意:v4+里不再需要
call(zoom.event)来初始化缩放,去掉这行就行。
3. 修改zoomed函数的变换逻辑
v4+里不再用d3.event.translate和d3.event.scale,而是通过d3.event.transform来获取完整的变换信息,直接用它来更新g的transform属性:
function zoomed() { // 旧写法(v3) // g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); // 新写法(v4+) g.attr("transform", d3.event.transform); }
修改后的完整代码示例
var projection = d3.geoMercator() .translate([width / 2, height / 2]) .scale((width - 1) / 2 / Math.PI); var zoom = d3.zoom() .scaleExtent([1, 8]) .on("zoom", zoomed); var path = d3.geoPath().projection(projection); var svg = d3.select("#map") .classed("svg-cont", true) .append("svg") .attr("preserveAspectRatio", "xMinYMin meet") .attr("viewBox", "0 0 560 350") .classed("svg-content-responsive", true); var g = svg.append("g"); svg.call(zoom); // 这里记得添加你的地图路径绘制代码,比如: // g.selectAll("path") // .data(geoData.features) // .enter() // .append("path") // .attr("d", path); function zoomed() { g.attr("transform", d3.event.transform); }
最后提醒你一下:刚学D3一定要先确认自己用的版本!v3和v4+的API差异非常大,建议直接从v7(当前稳定版)的官方文档入手,避免踩这种版本坑~
内容的提问来源于stack exchange,提问作者abaporu
相关产品推荐
相关产品推荐

