score:3

Accepted answer

You have to get the class and subtasks attributes as shown in below code inside the click listener.

d3.select(this).attr("class");
d3.select(this).attr("subtasks");

You may also use this.className to get the class attribute. But since subtasks is a custom attribute, you will have to get it use the d3 attr method or html getAttribute method.

To pass the attributes to some other functions from click listener, try any of the methods shown below.

The parameter d gives the data object binded to the corresponding element.

.on("click", function(d) {
    expandTasks(d[7],d[3],d[4]); 
});

or

.on("click", function(d) {
    var id = d3.select(this).attr("id"); // or this.id
    var className = d3.select(this).attr("class");// or this.className
    var subtasks = d3.select(this).attr("subtasks"); // or this.getAttribute("subtasks");
    expandTasks(id,className,subtasks); 
});

score:0

There is an issue in how you access the attributes of your rect. As you want to have more flexibility in getting the attributes to another function, may I propose the following:

Replace your on event with the following line:

.on("click", function() {expandTasks(d3.select(this)); });

And you expandTasks method with this one:

function expandTasks(d) { 
   alert(d.attr("id") + '/' + d.attr("class") + '/' + d.attr("subtasks"));
};

Essentially you are passing the g element to the expandTasks method, and then you can access any parameter of the element using d.attr(****).

Hope this helps.

score:1

In addition to the other answers that solve your immediate problem, note that it could be worth it to remap your data prior to joining it to your selection. Something like

var rectangles = pad
                 .selectAll("rect")
                 .data(data.map(function(d) {
                        return {
                            id: d[7],
                            classname: d[3],
                            subtask: d[4]
                        };
                  }));

where your transform your (presumed) arrays into objects with understandable keys.

You could then rewrite your attributes assignments and your handler as

var projectRectangles = rectangles.append("rect")
        .attr("id", function(d) { return d.id; })
        .attr("class", function(d) { return d.classname; })
        .on("click", function(d) {
            expandTasks(d.id, d.classname, d.subtask);
        });

And a demo

var data = [
    [null, null, null, 'class1', 'subtasks1', null, null, 'id1'],
    [null, null, null, 'class2', 'subtasks2', null, null, 'id2']
];

var expandTasks = function() {
    alert(Array.prototype.join.call(arguments, ' '))
};

var pad = d3.select('body').append('svg').append("g");
var rectangles = pad.selectAll("rect")
                    .data(data.map(function(d) {
                            return {
                                id: d[7],
                                classname: d[3],
                                subtask: d[4]
                            };
                    }))


var projectRectangles = rectangles.enter().append("rect")
    .attr('x',function(d, i) {return i*100;})
    .attr('y',0)
    .attr('width',100).attr('height',100)
        .attr("class", function(d) { return d.classname; })
        .on("click", function(d) {
            expandTasks(d.id, d.classname, d.subtask);
        });
svg {background-color: beige; width:200px; height:100px}
.class1 {fill: red}
.class2 {fill: green}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


Related Query

More Query from same tag