Angular项目中使用D3.js在SVG内绘制圆形无法显示如何解决?
问题原因
- 生命周期调用错误:
ngOnInit执行时组件视图尚未完成渲染,此时通过d3选择DOM元素大概率无法匹配到目标节点,绘图逻辑实际未执行,所有DOM操作类逻辑都应该放到ngAfterViewInit生命周期中执行。 - 缩放绑定逻辑错误:
- 你在
ngAfterViewInit中重新选中SVG根元素绑定缩放事件后,额外追加了一个空的g元素,没有复用之前的绘图容器;且你将zoom事件返回的transform直接应用到了SVG根元素上,SVG根元素本身不支持transform属性,该属性只能作用于SVG内部的容器元素。 ngAfterViewInit中定义的let svg是局部变量,和组件类的this.svg属性完全无关,导致绘图容器和缩放控制逻辑完全脱节。
- 你在
- 坐标计算偏差:绘图g容器已经设置了
translate(50,50)的初始偏移,再基于body的宽高计算圆心坐标,很容易导致圆形被挤出可视区域。
修复方案
修改TS代码
svg: any; margin = 50; width = 350 - (this.margin * 2); height = 300 - (this.margin * 2); ngOnInit(): void {} ngAfterViewInit() { this.createSvg(); // 绑定缩放事件,变换作用到绘图容器上 d3.select("svg") .call(d3.zoom().on("zoom", (event) => { this.svg.attr("transform", event.transform); })) this.createCircle(); } createSvg(): void { this.svg = d3 .select("figure#zoom-pan") .append("svg") .attr("width", "100%") .attr("height", "100%") .append("g") .attr("transform", "translate(" + this.margin + "," + this.margin + ")"); } createCircle(): void { this.svg .append("circle") // 基于预设宽高计算圆心,保证在可视区内 .attr("cx", this.width / 2) .attr("cy", this.height / 2) .attr("r", 50) .style("fill", "#B8DEE6") }
修改CSS代码(避免层级遮挡)
.center { display: flex; justify-content: center; } h3.center { position: relative; z-index: 10; } figure#zoom-pan { margin: 0; position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1; }
内容的提问来源于stack exchange,提问作者user11658838
相关产品推荐
相关产品推荐

