如何设置svg的宽度和高度等于其g?

时间:2018-10-19 07:33:58

标签: d3.js svg

我有一个数据图例SVG,我想将此SVG的高度和宽度设置为等于基于数据的g数。但是我该如何实现呢?我的SVG高度和宽度始终不符合我的G。我尝试使用node()。getBBox(),但它仍不能给我正确的高度和宽度。

这是我的代码:

var legend = d3.select(".svgLegend")
                .append('svg')
                .attr("id", "legend")
                .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)')

            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 + ")"; })
            })

传奇数据:

[
   {
      "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"
   }
]

我想要实现的是svg的高度和宽度与itemEnter的高度和宽度完全相同。

2 个答案:

答案 0 :(得分:1)

您可以使用getClientBoundingRect()中的值来设置SVG的宽度和高度:

var bRect = legend.node().getBoundingClientRect() 

svg.attr('width', bRect.width + 10)
   .attr('height', bRect.height)

(为了安全起见,在宽度上增加了10像素)

演示:

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>

答案 1 :(得分:0)

使用getBBox()是个好主意。这就是我要做的。

let bbox = test.getBBox();
//console.log(bbox)
svg.setAttributeNS(null, "viewBox", `${bbox.x} ${bbox.y} ${bbox.width}  ${bbox.height} `)
svg.setAttributeNS(null, "width", bbox.width);
svg.setAttributeNS(null, "height", bbox.height);
<svg id="svg" >
<g id="gtest">

	<path id="test" d="M187.476,214.443c-2.566,11.574-4.541,22.658-7.542,33.456
		c-3.558,12.8-7.14,25.713-12.242,37.938c-10.223,24.495-41.321,29.239-58.824,9.548c-9.592-10.792-11.295-26.9-3.539-40.556
		c11.233-19.778,25.391-37.46,40.447-54.438c1.07-1.207,2.116-2.436,3.893-4.484c-7.212,0.9-13.349,1.988-19.529,2.374
		c-16.283,1.018-32.578,2.21-48.881,2.437c-18.686,0.261-32.846-10.154-37.071-26.055c-6.762-25.449,15.666-48.973,41.418-43.338
		c23.645,5.175,46.447,12.901,68.424,23.051c1.033,0.478,2.083,0.918,3.933,1.731c-0.83-1.947-1.341-3.225-1.911-4.475
		c-9.896-21.701-18.159-43.986-23.192-67.337c-4.587-21.28,8.933-40.56,29.946-43.257c20.134-2.585,38.124,12.991,39.091,34.294
		c1.029,22.682-0.049,45.292-3.58,67.755c-0.17,1.079-0.152,2.188-0.246,3.659c8.05-6.831,15.471-13.737,23.52-19.811
		c11.147-8.412,22.398-16.795,34.27-24.113c18.35-11.312,40.821-4.481,50.028,14.385c9.091,18.628,0.131,40.586-20.065,48.198
		c-11.034,4.158-22.248,7.944-33.594,11.143c-11.321,3.191-22.908,5.438-34.866,8.212c1.189,0.81,2.19,1.504,3.205,2.18
		c18.402,12.261,37.157,24.032,55.101,36.932c14.769,10.616,18.619,29.317,10.675,44.578c-7.537,14.477-25.151,22.136-40.767,17.583
		c-7.583-2.212-14.022-6.469-18.523-12.919c-12.463-17.86-24.638-35.924-36.898-53.925
		C189.24,217.849,188.547,216.357,187.476,214.443z"/>
  
  </g>
  
</svg>

相关问题