stkubr
stkubr

Reputation: 391

D3.js redraw graph on button click

How to redraw the D3.js graph on button click? I'm getting data from my Python Flask server as json from http://127.0.0.1:5000/json. Here is my poor attempt:

var height = 1000;
var width = 1000;
var color = d3.scale.category10();
var force = d3.layout.force()
    .linkDistance(120)
    //.linkStrength(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var url = "http://127.0.0.1:5000/json";
function drawGraph(data){

    force
        .nodes(data.graph.nodes)
        .start();

    var node = svg.selectAll(".node")
        .data(data.graph.nodes)
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", 5)
        .style("fill", function (d) {
            return color(d.group);
        })
        .call(force.drag);

    force.on("tick", function () {
        link.attr("x1", function (d) {return d.source.x;})
            .attr("y1", function (d) {return d.source.y;})
            .attr("x2", function (d) {return d.target.x;})
            .attr("y2", function (d) {return d.target.y;});

        node.attr("cx", function (d) {return d.x;})
            .attr("cy", function (d) {return d.y;});
    });
}

// This initial load works 
d3.json(url, drawGraph);

// The refresh does not
function refreshGraph() {
    d3.json(url, drawGraph);
}

html:

<!DOCTYPE html>
<html>
  <head>
    <title>Force-Directed Layout</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <link type="text/css" rel="stylesheet" href="force.css"/>
  </head>
  <body>
    <div id="option">
    <input name="updateButton"
           type="button"
           value="Update"
           onclick="refreshGraph()" />
    </div>
    <div id="chart"></div>
    <script type="text/javascript" src="force.js"></script>
  </body>
</html>

Upvotes: 0

Views: 1311

Answers (1)

Yaroslav Sergienko
Yaroslav Sergienko

Reputation: 720

Perhaps the problem arises, because you assign var node to .enter() section of selection. So, when you update your graph, this section is empty, so during force.on("tick", ...) you update nothing.

I suggest to rewrite

var node = svg.selectAll(".node")
    .data(data.graph.nodes)
    .enter().append("circle")
    .attr("class", "node")
    .attr("r", 5)
    .style("fill", function (d) {
        return color(d.group);
    })
    .call(force.drag);

to

var node = svg.selectAll(".node")
    .data(data.graph.nodes)

node.enter().append("circle")
    .attr("class", "node")
    .attr("r", 5)
    .style("fill", function (d) {
        return color(d.group);
    })
    // .call(force.drag);

Upvotes: 2

Related Questions