简体   繁体   中英

D3 SVG doesn't resize responsively

I'm just getting to grips with D3 and wanted to make it resize as you resize the window, I managed to do it through some javascript which is commented out in the below example, but there is a thread here which says that width and height can be left off the SVG element and it will resize responsively without javascript. Sadly this doesn't work for me and I'm testing with IE11 and Firefox latest.

  1. When I leave off width and height it only shows text

      **width="960" height="500"** 
  2. When I uncomment the JS at the bottom it works

  3. When I include width and height the size doesn't change with window size

The snippet is below but doesn't work because I'm using D3 version 4 and JQ version 3.x, the snippet tool only seems to allow earlier versions.

How can I make it resize without the javascript being uncommented?

I'm sure this is something daft and obvious but I've been stuck on it for ages !.. thanks

  $(function () { var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), radius = Math.min(width, height) / 2, g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); var pie = d3.pie() .sort(null) .value(function (d) { return d.population; }); var path = d3.arc() .outerRadius(radius - 10) .innerRadius(0); var label = d3.arc() .outerRadius(radius - 40) .innerRadius(radius - 40); d3.csv("data.csv", function (d) { d.population = +d.population; return d; }, function (error, data) { if (error) throw error; var arc = g.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); arc.append("path") .attr("d", path) .attr("fill", function (d) { return color(d.data.age); }); arc.append("text") .attr("transform", function (d) { return "translate(" + label.centroid(d) + ")"; }) .attr("dy", "0.35em") .text(function (d) { return d.data.age; }); }); // Uncomment this to make it resize with the window width changes //var aspect = width / height, // chart = d3.select('svg'); //d3.select(window) // .on("resize", function () { // var targetWidth = $(window).width(); // chart.attr("width", targetWidth); // chart.attr("height", targetWidth / aspect); // }); }); 
  svg { display: inline-block; position: absolute; top: 0; left: 0; } body { display: inline-block; position: relative; width: 100%; vertical-align: middle; background-color:#ffffe0; } 
 <script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> <svg width="960" height="500" viewBox="0 0 900 600" preserveAspectRatio="xMidYMid meet"></svg> 

data.csv:

age,population
<5,2704659
5-13,4499890
14-17,2159981
18-24,3853788
25-44,14106543
45-64,8819342
=65,612463

When you leave off width and height attributes, you can't expect to read them with svg.attr("width") . What you really want to get is the viewBox property width and height:

    $(function () {
        var svg = d3.select("svg"),
            width = svg.property("viewBox").baseVal.width,
            height = svg.property("viewBox").baseVal.height,
            radius = Math.min(width, height) / 2,
            g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    //...
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM