Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update d3.js bar chart with new data

I’ve started with the “Let’s make a bar chart I” example here: http://bost.ocks.org/mike/bar/

And I’m having a hard time figuring out how to make the very simple bar chart made with HTML5 elements update with new data. Here is my code:

<!DOCTYPE html>
<html>
  <head>
    <style>
      #work_queues_chart div {
        font-size: 0.5em;
        font-family: sans-serif;

        color: white;
        background-color: steelblue;

        text-align: right;
        padding: 0.5em;
        margin: 0.2em;
      }
    </style>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8" />
    <script type="text/javascript">

      function init() {

        var data = [0, 0, 0, 0, 0, 0];

        /* scale is a function that normalizes a value in data into the range 0-98 */
        var scale = d3.scale.linear()
                      .domain([0, 200])
                      .range([0, 98]);

        var bars = d3.select("#work_queues_chart")
                     .selectAll("div")
                       .data(data)
                     .enter().append("div");

        bars.style("width", function(d) { return scale(d) + "%"; })
        bars.text(function(d) { return d; });

      }

      function update() {

        var data = [4, 8, 15, 16, 23, 42];

        /* http://stackoverflow.com/questions/14958825/dynamically-update-chart-data-in-d3 */
      }

      window.onload = init;

    </script>

  </head>
  <body>
    <div id="work_queues_chart" />
    <button onclick="update()">Update</button>
  </body>
</html>

The question is what do I put into update() to cause the bars to draw with the new data? I tried d3.select("#work_queues_chart").selectAll("div").data(data) with the new data, but I’m unclear on what needs to happen next (or whether that was the right move).

like image 220
Wilfredo Sánchez Vega Avatar asked Feb 26 '14 20:02

Wilfredo Sánchez Vega


People also ask

Which is better D3 or chart JS?

js is a good first choice as it'll require far less effort to create a working chart that includes a legend and hover pop-up. Creating such charts with D3 is a non-trivial undertaking especially when a legend, hover pop-up, series selection, grid lines, animations and responsiveness are required.

Is D3 js still relevant?

The JavaScript ecosystem has completely changed during this time, in terms of libraries, best practices and even language features. Nevertheless, D3 is still here. And it's more popular than ever.

What is D3 js good for?

D3 is a JavaScript library and framework for creating visualizations. D3 creates visualizations by binding the data and graphical elements to the Document Object Model. D3 associates (binding) the data (stuff you want to visualize) with the DOM. This allows the user to manipulate, change or add to the DOM.


2 Answers

I have create a fiddle for you here. It is a simple take on what you had with a few changes, particularly separating the enter, update and exit selections. This should help you start understanding the update process in D3.

// enter selection
bars
    .enter().append("div");

// update selection
bars
    .style("width", function (d) {return scale(d) + "%";})
    .text(function (d) {return d;});

// exit selection
bars
    .exit().remove();
like image 151
FernOfTheAndes Avatar answered Nov 11 '22 23:11

FernOfTheAndes


Accepted answer was answered before d3 version 4 released, but if you use d3v4 you have to make update another way because of (excerpt from changelog):

selection.append no longer merges entering nodes into the update selection; use selection.merge to combine enter and update after a data join.

// enter and update selection
bars
  .enter()
  .append("div")
  .merge(bars) // <== !!!
  .style("width", function (d) {return scale(d) + "%";})
  .text(function (d) {return d;});


// exit selection
bars
  .exit().remove();

Working example in hidden snippet below:

function draw(data) {
    var scale = d3.scaleLinear()
        .domain([0, 50])
        .range([0, 100]);

    var bars = d3.select("#work_queues_chart")
        .selectAll("div")
        .attr("id","work_queues_chart")
        .data(data);
     
    // enter and update selection
    bars
      .enter().append("div")
      .merge(bars)
      .style("width", function (d) {return scale(d) + "%";})
      .text(function (d) {return d;});

    
    // exit selection
    bars
        .exit().remove();
};

function update() {
    var data = [4, 8, 15, 16, 23, 42];
    draw(data);
};

var data = [10, 10, 10, 10, 10, 10];
window.onload = draw(data);

d3.select('#update')
    .on("click",update);
#work_queues_chart div {
    font-size: 0.5em;
    font-family: sans-serif;
    color: white;
    background-color: steelblue;
    text-align: right;
    padding: 0.5em;
    margin: 0.2em;
}
<div id="work_queues_chart" />
<button id="update">Update</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
like image 2
Mikhail Shabrikov Avatar answered Nov 12 '22 00:11

Mikhail Shabrikov