Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing D3 SVG object within on click event

Tags:

onclick

svg

d3.js

I am working on a bubble graph and I have attached an on click event to each of the circles. When clicking on a circle, the bubble graph will be replaced with a new graph representing a more detailed information.

Here is part of the code:

svg.selectAll("circle")
               .data(dataset)
               .enter()
               .append("circle")
               .attr("cx", function(d) {
                    return scaleX(d[2]);
               })
               .attr("cy", function(d) {
                    return scaleY(100 - d[1]);
               })
               .attr("r", function(d) {
                    return d[1];
               })
               .attr("fill", "#4eb157")
               .attr("stroke", "#00c4d4")
               .attr("stroke-width", function(d) {

                    return d[1]*(1-d[2]/100)*1.5;

               })
               .on("click", function ()
                                    {


                                       svg.selectAll("circle")
                                       .data(new_dataset)
                                       .enter()
                                       .append("circle")
                                       .attr("cx", function(d) {
                                            return scaleX(d[2]);
                                       })
                                       .attr("cy", function(d) {
                                            return scaleY(100 - d[1]);
                                       })
                                       .attr("r", function(d) {
                                            return d[1];
                                       })
                                       .attr("fill", "#4eb157")
                                       .attr("stroke", "#00c4d4")
                                       .attr("stroke-width", function(d) {

                                            return d[1]*(1-d[2]/100)*1.5;

                                        });             


                                    svg.selectAll("text")
                                       .data(new_dataset)
                                       .enter()
                                       .append("text")
                                       .text(function(d) {
                                            return d[0];
                                       })
                                       .attr("x", function(d) {
                                            return scaleX(d[2]);
                                       })
                                       .attr("y", function(d) {
                                            return scaleY(100 - d[1]);
                                       })
                                       .attr("font-family", "sans-serif")
                                       .attr("font-size", "11px")
                                       .attr("fill", "red");
                                    });

The problem comes when I click on the circle, the whole graph disappears, but no new graph is visualized. I figured out that during the execution of the on click function, the svg object has changed from its initial state and in particular some of the properties such as baseURI, clientHeight, clientWidth etc are not set anymore even though they were when initially creating the svg object. Here is the code with which I am creating the svg object:

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

My question is why is the new graph not appearing? Is this because of the changed properties of the svg object? What should I change in the on click function in order to make the new graph visualize successfully?

Thanks!

like image 1000
Andreev Avatar asked Nov 27 '12 17:11

Andreev


1 Answers

The problem is that in the onclick event you are selecting all the circles under the svg element and joining them with new_dataset. You probably want to select another set of circle elements and join new_dataset to this group of circles. One way to do that is to create two groups under svg, one for the original set, and other for the circles of new_dataset, another solution is to assign different classes to different groups of circles and narrow each selection using the class.

In the following links you can find a clearer explanation about the joining mechanism:

  • D3 Tutorial - Scott Murray
  • Thinking with Joins - Mike Bostok
like image 126
Pablo Navarro Avatar answered Oct 12 '22 23:10

Pablo Navarro