How to make a d3 pie chart responsive?

Viewed 2522

I have a PIE chart. And it works okay but I can't make it work to be responsive and resizable . I need it to be compatible for a mobile browser and Ipad etc.

  <html>
    <head></head>
    <body>
    <div id="pie"></div>
    <button id="addData"> Add Data </button>

    <script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
    <script   src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>

    <script src="https://raw.githubusercontent.com/benkeen/d3pie/0.2.1/d3pie/d3pie.min.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
        var data = [
              { label: "1", value: 1 },
              { label: "2", value: 4 },
              { label: "3", value: 3 }
            ];

            var pie = new d3pie("pie", {
              data: {
                content: data
              }
            });


    </script>
    </body>
    </html> 

I tried to wrap it to bootstrap but this doesn't make it fully resizable

How can I make it resizable depending on mobile device or desktop ?

(PS: I'm using an example from here https://dzone.com/articles/d3js-pie-charts-made-super-easy-d3pie)

2 Answers

You can use the size setting to scale the chart, and some CSS to center. Finally an resize event to update everything when the screen size changes.

var data = [
  { label: "1", value: 1 },
  { label: "2", value: 4 },
  { label: "3", value: 3 }
];

var pie;

var update = function () {
  if (pie) pie.destroy();
  var size = Math.min(innerHeight, innerWidth);
  var opt =  {
    data: {
      content: data
    },
    size: {
      canvasHeight: size,
      canvasWidth: size,
    }
  };
  pie = new d3pie("pie", opt);
};

update();

window.addEventListener('resize', update)
#pie > svg {
  margin: 0 auto;
  display: block;
}
<div id="pie"></div>

<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>

<script src="https://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/d3pie@0.2.1/d3pie/d3pie.min.js"></script>

<script src="https://d3js.org/d3.v4.min.js"></script>

destroying the chart is not exactly "responsive". the code-snippet only scales in "full page" mode (because the embed has fixed dimensions); but it scales dynamically, as it should be. there still may be space for improvement.

var chart, svg, width, height;
var data = [
  { label: "1", value: 1 },
  { label: "2", value: 4 },
  { label: "3", value: 3 }
];

$(function() {
  chart = new d3pie("#container", {data: {content: data}});
  svg = d3.select("#container > svg");
});

$(window).on('resize', function() {
    width = $(window).width();
    height = $(window).height();
    svg
      .attr("width", '100%')
      .attr("height", '100%')
      .attr('viewBox','0 0 ' + height + ' ' + width)
      .attr('preserveAspectRatio', 'xMinYMin')
      .append("g")
      .attr("transform", "translate(" + height + "," + width + ")");
});
html, body {margin: 0; height: 100%; overflow: hidden;}
div#container > svg {min-height: 200px;}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="//cdn.jsdelivr.net/npm/d3pie@0.2.1/d3pie/d3pie.min.js"></script>
<div id="container"></div>

Related