You can use the values from getClientBoundingRect()
to set the width and height of your SVG:
var bRect = legend.node().getBoundingClientRect() svg.attr('width', bRect.width + 10) .attr('height', bRect.height)
(adding in an extra 10px to the width for safety)
Demo:
var legendData = [ {"name":"Malaysia","value":350,"percentage":"48.61" }, {"name":"England","value":300,"percentage":"41.67" }, {"name":"China","value":400,"percentage":"55.56" }, {"name":"South Korea","value":600,"percentage":"83.33" }]function safe_name (t) { return t.replace(/\W/g, '_')}function color (d) { var colors = { China: 'deepskyblue','South Korea': 'deeppink', England: 'red', Malaysia: 'goldenrod' } return colors[d]}var svg = d3.select(".svgLegend") .append('svg') .attr("id", "legend")var legend = svg .append('g') .attr("class", "mainGroup") .attr('legend', true) var itemEnter = legend.selectAll('g.legendItem') .data(legendData) .enter() .append('g') .attr('class', function (d) { return 'legendItem '+ safe_name(d.name); }) itemEnter.append('rect') .attr('x', 0) .attr('y', 0) .attr('width', '10') .attr('height', '10') .style('fill', function (d) { return color(d.name); }) .attr('transform', 'translate(10,6)') .attr('class', function (d) { return 'legendRect '+ safe_name(d.name); }) itemEnter.append('text') .attr('x', 0) .attr('y', 0) .attr('class', 'legendText') .text(function (d) { return d.name }) .attr('transform', 'translate(25, 15)') var itemHeight = 25 itemEnter.selectAll("text") .each(function () { var textLength = this.getComputedTextLength(); itemEnter.attr("transform", function (d, i) { return "translate("+ i % 8 * (textLength + 60) +","+ Math.floor(i / 8) * itemHeight +")"; }) }) var bRect = legend.node().getBoundingClientRect() svg.attr('width', bRect.width + 10) .attr('height', bRect.height)
<script src="http://d3js.org/d3.v5.js"></script><div class="svgLegend"></div>