如何将SVG元素的属性传递给D3中的新事件?

时间:2015-10-22 07:51:58

标签: d3.js

我试图返回"类"的值。和"子任务"在D3中单击鼠标时矩形的属性。

var projectRectangles = rectangles.append("rect")
    .attr("id", function(d) { return (d)[7]; })
    .attr("class", function(d) { return (d)[3]; })
    .attr("subtasks", function(d) { return (d)[4]; })
    .on("click", function() {expandTasks(this.id, this.class, this.subtask); });

function expandTasks(task_id, task_subtasks, task_class) { alert(task_id + '/' + task_subtasks + '/' + task_class);};

示例响应:1 / undefined / undefined

它返回 this.id ,但 this.class this.subtasks 总是返回" undefined"。 '类'和'子任务'在属性中显得很好所以为什么它适用于id,而不适用于其他人?

最后,当然,我想知道将这些属性传递给另一个函数的最佳方法。

谢谢, 基思

3 个答案:

答案 0 :(得分:1)

您必须获取类和子任务属性,如点击侦听器中的下面的代码所示。

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

您也可以使用this.className来获取class属性。但由于subtasks是自定义属性,因此您必须使用d3 attr方法或html getAttribute方法。

要将属性从Click侦听器传递给其他一些函数,请尝试下面显示的任何方法。

  

参数d将数据对象绑定到相应的对象   元件。

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

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

答案 1 :(得分:1)

除了解决您当前问题的其他答案之外,请注意,在将数据加入您的选择之前重新映射数据可能是值得的。像

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

将你的(假定的)数组转换为具有可理解键的对象。

然后,您可以将属性分配和处理程序重写为

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

和演示



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>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您访问rect的属性时存在问题。由于您希望在将属性获取到另一个函数方面具有更大的灵活性,我可以提出以下建议:

on事件替换为以下行:

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

你用这个expandTasks方法:

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

基本上,您将g元素传递给expandTasks方法,然后您可以使用d.attr(****)访问元素的任何参数。

希望这有帮助。