如何在D3中为SVG分组元素设置唯一ID
问题根源
单次调用.append('g')添加单个元素时,D3索引参数i的取值由当前操作的选择集长度决定,你每次仅添加1个分组,i永远为0,因此生成的ID重复。
实现方案
提供两种实现方式,可根据你的实际场景选择:
方案1:手动维护索引(固定2个标题+2个图表场景)
直接定义计数变量控制ID后缀,修改后代码如下:
if (this.pieDatasets.length != undefined && this.pieDatasets.length > 0) { let captionCount = 0, chartCount = 0; let outerSvg = d3.select("figure#pie") .append("svg") .attr("id", "outerSVG") .attr("width", "100%") .attr("height", "100%") // 第一个标题 let svgCaption1 = d3.select("#outerSVG") .append("g") .attr("id", "svgCaption" + captionCount++) .append("text") .style("font", "18px sans-serif") .attr("dy", "29px") .text(valueColumnLabels); // 第二个标题,自行调整dy偏移避免重叠 let svgCaption2 = d3.select("#outerSVG") .append("g") .attr("id", "svgCaption" + captionCount++) .append("text") .style("font", "18px sans-serif") .attr("dy", "69px") .text(/* 第二个标题的文本 */); let svgBox = d3.select("#outerSVG") .append("g") .attr("id", "svgBox") .attr("width", "100%") .attr("height", "100%"); box.style.setProperty("width", "50%"); // 第一个图表 var svg1 = d3.select("#svgBox") .append("g") .attr("id", 'svgChart' + chartCount++) .attr("class", 'chart-font') .attr("viewBox", '0 0 ' + width + ' ' + height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // 第二个图表,自行调整transform偏移避免重叠 var svg2 = d3.select("#svgBox") .append("g") .attr("id", 'svgChart' + chartCount++) .attr("class", 'chart-font') .attr("viewBox", '0 0 ' + width + ' ' + height) .append("g") .attr("transform", "translate(" + (width / 2 + 300) + "," + height / 2 + ")"); }
方案2:数据绑定批量生成(动态数量场景)
如果后续可能扩展标题、图表数量,用D3数据绑定的方式自动分配索引更合理:
if (this.pieDatasets.length != undefined && this.pieDatasets.length > 0) { let outerSvg = d3.select("figure#pie") .append("svg") .attr("id", "outerSVG") .attr("width", "100%") .attr("height", "100%") // 批量生成标题,captionList替换为你的标题文本数组 const captionList = [valueColumnLabels, 第二个标题文本]; outerSvg.selectAll('g.svg-caption') .data(captionList) .join('g') .attr('class', 'svg-caption') .attr('id', (d, i) => 'svgCaption' + i) .append('text') .style("font", "18px sans-serif") .attr("dy", (d, i) => 29 + i * 40 + "px") .text(d => d); let svgBox = d3.select("#outerSVG") .append("g") .attr("id", "svgBox") .attr("width", "100%") .attr("height", "100%"); box.style.setProperty("width", "50%"); // 批量生成图表,chartData替换为你的图表配置数组 const chartData = [{}, {}]; svgBox.selectAll('g.svg-chart') .data(chartData) .join('g') .attr('class', 'svg-chart chart-font') .attr('id', (d, i) => 'svgChart' + i) .attr("viewBox", '0 0 ' + width + ' ' + height) .append("g") .attr("transform", (d, i) => "translate(" + (width / 2 + i * 300) + "," + height / 2 + ")"); }
内容的提问来源于stack exchange,提问作者Zehke
相关产品推荐
相关产品推荐

