Rohit Chakraborty
Rohit Chakraborty

Reputation: 83

Coloring the node while performing on-click function

I tried implementing the on-click function in d3. But the coloration of node is not happening as I have expected.

    `var node = svg.selectAll('.node')
        .data(force.nodes())
        .enter().append('circle')
        .attr('class', 'node')
        .on("click", clicked)
        .attr('r', width*0.03);

    function clicked(event, d) {
        if (event.defaultPrevented) return; // dragged

        d3.select(this).transition()
          .attr("fill", "black")
          .attr("r", width * 0.2)
          .transition()
          .attr("r", width*0.03)
`

I tried to implement this code, but the color is not changing from the given color to black(as described in the clicked func.) <style> .node{ fill: blue; stroke: black; stroke-width: 2px; } Here I have described the original color of the node

Here is the whole code snippet

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    .node{
        fill: blue;
        stroke: black;
        stroke-width: 2px;
    }

    .link{
        stroke-width: 2px;
    }
</style>
<body>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script>
        var width = 640,
            height = 480;

        var links = [
            {source: 'Rohit', target: 'Deep'},
            {source: 'Deep', target: 'Deepa'},
            {source: 'Deepa', target: 'Rohit'},
        ];
        var nodes = {};

        //adding to nodes
        links.forEach(function(link){
            link.source = nodes[link.source] ||
                (nodes[link.source] = {name: link.source});

            link.target = nodes[link.target] ||
                (nodes[link.target] = {name: link.target});
        });

        //adding svg to body

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

        var defs = svg.append('defs');

        var gradient = defs
          .append('linearGradient')
          .attr('id', 'svgGradient')
          .attr('x1', '0%')
          .attr('x2', '10%')
          .attr('y1', '0%')
          .attr('y2', '10%');

        gradient
          .append('stop')
          .attr('class', 'start')
          .attr('offset', '0%')
          .attr('start-color', 'red')
          .attr('start-opacity', 1);

        gradient
          .append('stop')
          .attr('class', 'end')
          .attr('offset', '100%')
          .attr('stop-color', 'blue')
          .attr('stop-opacity', 1);

        var force = d3.layout.force()
            .size([width, height])
            .nodes(d3.values(nodes))
            .links(links)
            .on("tick", tick)
            .linkDistance(300)
            .start();

        var link = svg.selectAll('.link')
            .data(links)
            .enter().append('line')
            .attr('class', 'link')
            .attr('stroke', 'url(#svgGradient)');

        var node = svg.selectAll('.node')
            .data(force.nodes())
            .enter().append('circle')
            .attr('class', 'node')
            .on("click", clicked)
            .attr('r', width*0.03);

        function clicked(event, d) {
            if (event.defaultPrevented) return; // dragged

            d3.select(this).transition()
              .attr("fill", "black")
              .attr("r", width * 0.2)
              .transition()
              .attr("r", width*0.03)
              //.attr("fill", d3.schemeCategory10[d.index % 10]);
        }
  

        //define the tick func.
        function tick(e){
            node
                .attr('cx', function(d){
                return d.x;
                })
                .attr('cy', function(d){
                    return d.y;
                })
                .call(force.drag);
            
            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;
                })

        }


    </script>
</body>

Upvotes: 1

Views: 53

Answers (1)

A Haworth
A Haworth

Reputation: 36512

According to at least some documentation (e.g. https://www.d3indepth.com/transitions/) the color of the node is set in CSS using style, and if you use your browser's devtools inspect facility you can see that the blue is indeed set through settings for the class node.

Therefore change that attr to a style.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .node {
    fill: blue;
    stroke: black;
    stroke-width: 2px;
  }
  
  .node.visited {
    fill: red;
  }
  
  .link {
    stroke-width: 2px;
  }
</style>

<body>
  <script src="https://d3js.org/d3.v3.min.js"></script>
  <script>
    var width = 640,
      height = 480;

    var links = [{
        source: 'Rohit',
        target: 'Deep'
      },
      {
        source: 'Deep',
        target: 'Deepa'
      },
      {
        source: 'Deepa',
        target: 'Rohit'
      },
    ];
    var nodes = {};

    //adding to nodes
    links.forEach(function(link) {
      link.source = nodes[link.source] ||
        (nodes[link.source] = {
          name: link.source
        });

      link.target = nodes[link.target] ||
        (nodes[link.target] = {
          name: link.target
        });
    });

    //adding svg to body

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

    var defs = svg.append('defs');

    var gradient = defs
      .append('linearGradient')
      .attr('id', 'svgGradient')
      .attr('x1', '0%')
      .attr('x2', '10%')
      .attr('y1', '0%')
      .attr('y2', '10%');

    gradient
      .append('stop')
      .attr('class', 'start')
      .attr('offset', '0%')
      .attr('start-color', 'red')
      .attr('start-opacity', 1);

    gradient
      .append('stop')
      .attr('class', 'end')
      .attr('offset', '100%')
      .attr('stop-color', 'blue')
      .attr('stop-opacity', 1);

    var force = d3.layout.force()
      .size([width, height])
      .nodes(d3.values(nodes))
      .links(links)
      .on("tick", tick)
      .linkDistance(300)
      .start();

    var link = svg.selectAll('.link')
      .data(links)
      .enter().append('line')
      .attr('class', 'link')
      .attr('stroke', 'url(#svgGradient)');

    var node = svg.selectAll('.node')
      .data(force.nodes())
      .enter().append('circle')
      .attr('class', 'node')
      .on("click", clicked)
      .attr('r', width * 0.03);

    function clicked(event, d) {
      if (event.defaultPrevented) return; // dragged

      d3.select(this).transition()
        .style("fill", "black")
        .attr("r", width * 0.2)
        .transition()
        .attr("r", width * 0.03)
      //.attr("fill", d3.schemeCategory10[d.index % 10]);
    }


    //define the tick func.
    function tick(e) {
      node
        .attr('cx', function(d) {
          return d.x;
        })
        .attr('cy', function(d) {
          return d.y;
        })
        .call(force.drag);

      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;
        })

    }
  </script>
</body>

</html>

Upvotes: 1

Related Questions