How to create a pie chart visualization in d3.js, typing the input manually and with smooth transitions

Tags: , ,



I am trying to use D3.js to create a pie chart with 3 pie slices. I would like to input the values with the keyboard and the transition when updating the values (when clicking the button) should be smooth, that’s why I use merge() and transition().

In oder words, what I am trying to do is to adapt the code from this given example: https://www.d3-graph-gallery.com/graph/pie_changeData.html

the difference would be that I would like to be able to input the values manually instead of having them in the code (it is fine that it is always 3 pie slices).

For some reason I cannot really adapt the code. Thanks in advance.

// set the dimensions and margins of the graph
var width = 450
height = 450
margin = 40

// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin

// append the svg object to the div called 'my_dataviz'
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// set the color scale
var color = d3.scaleOrdinal()
  .domain(["a", "b", "c", "d"])
  .range(d3.schemeDark2);

// A function that create / update the plot for a given variable:
function update() {

  var data = d3.selectAll('.fuel').nodes();

  var pie = d3.pie() //we create this variable, for the values to be readeable in the console
    .value(function(d) {
      return d.innerHTML;
    })(data);

  var u = svg.selectAll("path")
    .data(pie)

  // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
  u.enter()
    .append('path')
    .merge(u)
    .transition()
    .duration(5000)
    .attr('d', d3.arc()
      .innerRadius(0)
      .outerRadius(radius)
    )
    .attr('fill', function(d) {
      return (color(d.data.key))
    })
    .attr("stroke", "white")
    .style("stroke-width", "2px")
    .style("opacity", 1)
}
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Color scale -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>


<!-- Create 3 cells for the input -->

<td>
  <input type="number" class="fuel" style="text-align:center">
</td>
<td>
  <input type="number" class="fuel" style="text-align:center">
</td>
<td>
  <input type="number" class="fuel" style="text-align:center">
</td>

<!-- Add  button -->
<button onclick="update(data)">Update</button>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

Answer

To access the values in the input boxes, use this.value, not this.innerHtml, where this points to the relevant DOM node:

// set the dimensions and margins of the graph
var width = 450
height = 450
margin = 40

// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin

// append the svg object to the div called 'my_dataviz'
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// set the color scale
var color = d3.scaleOrdinal()
  .domain(["a", "b", "c", "d"])
  .range(d3.schemeDark2);

// A function that create / update the plot for a given variable:
function update() {

  var data = [];
  d3.selectAll('.fuel').each(function() {
    data.push(+this.value || 0);
  });

  var pie = d3.pie()
    (data);

  var u = svg.selectAll("path")
    .data(pie)

  // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
  u.enter()
    .append('path') 
    .merge(u)
    .transition()
    .duration(5000)
    .attr('d', d3.arc()
      .innerRadius(0)
      .outerRadius(radius)
    )
    .attr('fill', function(d) {
      return (color(d.data.key))
    })
    .attr("stroke", "white")
    .style("stroke-width", "2px")
    .style("opacity", 1)
}
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Color scale -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>


<!-- Create 3 cells for the input -->

<td>
  <input type="number" class="fuel" style="text-align:center">
</td>
<td>
  <input type="number" class="fuel" style="text-align:center">
</td>
<td>
  <input type="number" class="fuel" style="text-align:center">
</td>

<!-- Add  button -->
<button onclick="update()">Update</button>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>


Source: stackoverflow