jyonkheel
jyonkheel

Reputation: 463

button ouside d3.js svg to select and modify d3.js elements

I have svg graph generated via d3.js, and click events attached to DOM generated by d3.js works, but a precreated DOM outside d3.js simply does not fire the event

//d3.js generated DOM
var marker = layer.selectAll("svg")
                .data(data)
                .each(transform) // update existing markers
                .enter().append("svg")
                .each(transform)
                .attr("class", function (d) {
                    return d[12] === "Region" ? "marker region" : "marker";
                });

//pre-created DOM
var btn = d3.select('#vslCur_btn0');

//method i'd like to trigger on click
var hideAct = function(){
                console.log("trying to hide"+marker.size());
                marker.filter(function (d) {
                    return d[12] === "Region";
                }).style("width", function (d) {
                    console.log('attr lulz:' + d3.select(this).style('width'));
                    return d3.select(this).style('width') === '70px' ? '0px' : '70px';
                });                
        };  

marker.on("click", hideAct);//works when clicked displays "trying to hide295" or the number of svg
btn.on("click", hideAct);//does not work but displays "trying to hide0" on console

Obviously #vslCur_btn0 exists outside the svg. In case selectAll("svg") bothers you there are multiple absolute position svgs within a div which serves as some sort of canvas (google maps), #vslCur_btn0 exists outside of that canvas and is some sort of control panel. the questions is

  1. Why d3js treats #vslCur_btn0 as outside scope
  2. How to override this scope problem and make it work on 'outsider' DOM

Upvotes: 0

Views: 667

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

click events attached to DOM generated by d3.js work, but a precreated DOM outside d3.js simply does not fire the event.

This is wrong, it does fire. The problem here seems to be the use of this.

In your hideAct function, you are using this to change the style of a given svg element. The problem is, when you click the button, this is the button itself, not the SVG element.

Here is a fiddle demo, that calls a function on click to log the radius of the circle: https://jsfiddle.net/gerardofurtado/42yLuhfb/

I'm using the same pattern in your code:

circles.on("click", test);//clicking on the SVG element
d3.select("#btn").on("click", test);//clicking on the HTML button

Click the circle first, and after that click the button, comparing the results. Pay attention to the console, it logs this and the r. For the button, the r result is, of course, null

PS: I'd rather use SO snippet instead of an external link (JSfiddle), but unfortunately SO snippet is freezing when we try to console.log this.

Upvotes: 2

Related Questions