Javascript 如何使用d3画布渲染器将鼠标事件添加到强制定向图?

Javascript 如何使用d3画布渲染器将鼠标事件添加到强制定向图?,javascript,events,d3.js,click,mouse,Javascript,Events,D3.js,Click,Mouse,所有其他示例都有带有svg.append()的鼠标事件。。。。我不知道在画布渲染器中从何处“输入”以获取圆弧,并以v4样式添加.on('click',function(){})。我想单击以获取d的值。在本例中,我在哪里添加处理程序?我理解这个例子下面的老方法 可能是这样的工作d3.选择(画布).调用(d3.鼠标()).打开(“单击”,…) 链接到 老路 var node = svg.append("g") .attr("class", "nodes") .selectAll("circle")

所有其他示例都有带有svg.append()的鼠标事件。。。。我不知道在画布渲染器中从何处“输入”以获取圆弧,并以v4样式添加
.on('click',function(){})
。我想单击以获取
d
的值。在本例中,我在哪里添加处理程序?我理解这个例子下面的老方法

可能是这样的工作<代码>d3.选择(画布).调用(d3.鼠标()).打开(“单击”,…)

链接到

老路

var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
  .attr("r", 8)
  .attr("fill", function(d) { return color(d.group); })
  .on("click", togglenode)
  .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

在D3 v4.x中,添加单击事件的方式与v3.x中的方式基本相同:

selection.on("click", function(d){
    //do whatever you want with the datum
});
您的问题不是v3对v4,这不是您共享的代码中的问题。该代码的问题在于,它使用HTML画布而不是SVG来呈现dataviz

与SVG不同,canvas没有元素的节点树。您不能“选择某个内容”并向其添加事件处理程序

将画布视为光栅图像,如BMP或JPEG。您可以在单击的x和y位置上找到,甚至可以找到该像素的颜色,但无法选择给定的节点元素,因为画布没有


例如,选中此项查看在使用HTML画布时用户单击的圆圈有多复杂。

在D3 v4.x中,添加单击事件的方式与在v3.x中几乎相同:

selection.on("click", function(d){
    //do whatever you want with the datum
});
您的问题不是v3对v4,这不是您共享的代码中的问题。该代码的问题在于,它使用HTML画布而不是SVG来呈现dataviz

与SVG不同,canvas没有元素的节点树。您不能“选择某个内容”并向其添加事件处理程序

将画布视为光栅图像,如BMP或JPEG。您可以在单击的x和y位置上找到,甚至可以找到该像素的颜色,但无法选择给定的节点元素,因为画布没有


例如,选中此项查看在使用HTML画布时用户单击的圆圈有多复杂。

因为我使用了画布渲染器,所以我只是作弊并使用了示例中已经存在的d3 dragstart事件。也许有一种方法可以做到这一点,我想知道

        d3.select(canvas)
        .call(d3.drag()
            .container(canvas)
            .subject(dragsubject)
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

function dragstarted(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
            d3.event.subject.fx = d3.event.subject.x;
            d3.event.subject.fy = d3.event.subject.y;
            //broadcast the selection to parent
            emitter.emit( d3.event.subject );
        }

因为我使用了画布渲染器,所以我只是欺骗并使用了示例中已经存在的d3 dragstart事件。也许有一种方法可以做到这一点,我想知道

        d3.select(canvas)
        .call(d3.drag()
            .container(canvas)
            .subject(dragsubject)
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

function dragstarted(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
            d3.event.subject.fx = d3.event.subject.x;
            d3.event.subject.fy = d3.event.subject.y;
            //broadcast the selection to parent
            emitter.emit( d3.event.subject );
        }

双击扩展了FlavorScape的hack

        d3.select(canvas)
        .call(d3.drag()
            .container(canvas)
            .subject(dragsubject)
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));
        var clickDate = new Date();
        var difference_ms;
        function dragstarted(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
            d3.event.subject.fx = d3.event.subject.x;
            d3.event.subject.fy = d3.event.subject.y;
            difference_ms = (new Date()).getTime() - clickDate.getTime();
            clickDate = new Date();
            //if clicks less than 200ms apart (double click)
            if(difference_ms < 200)
                console.log( d3.event.subject );
        }
d3.选择(画布)
.call(d3.drag()
.容器(帆布)
.主题(dragsubject)
.on(“开始”,拖动开始)
.打开(“拖动”,拖动)
。在(“结束”,dragended));
var clickDate=新日期();
var差分;
函数dragstarted(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d3.event.subject.fx=d3.event.subject.x;
d3.event.subject.fy=d3.event.subject.y;
差异_ms=(新日期()).getTime()-单击日期.getTime();
单击日期=新日期();
//如果单击间隔小于200ms(双击)
如果(差值小于200)
console.log(d3.event.subject);
}

双击扩展了FlavorScape的破解功能

        d3.select(canvas)
        .call(d3.drag()
            .container(canvas)
            .subject(dragsubject)
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));
        var clickDate = new Date();
        var difference_ms;
        function dragstarted(d) {
            if (!d3.event.active) simulation.alphaTarget(0.3).restart();
            d3.event.subject.fx = d3.event.subject.x;
            d3.event.subject.fy = d3.event.subject.y;
            difference_ms = (new Date()).getTime() - clickDate.getTime();
            clickDate = new Date();
            //if clicks less than 200ms apart (double click)
            if(difference_ms < 200)
                console.log( d3.event.subject );
        }
d3.选择(画布)
.call(d3.drag()
.容器(帆布)
.主题(dragsubject)
.on(“开始”,拖动开始)
.打开(“拖动”,拖动)
。在(“结束”,dragended));
var clickDate=新日期();
var差分;
函数dragstarted(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d3.event.subject.fx=d3.event.subject.x;
d3.event.subject.fy=d3.event.subject.y;
差异_ms=(新日期()).getTime()-单击日期.getTime();
单击日期=新日期();
//如果单击间隔小于200ms(双击)
如果(差值小于200)
console.log(d3.event.subject);
}

肯定有一种正确的方法可以使用canvas来执行d3.mouse()之类的操作吗?最后,我在画布上使用了从d3.drag()开始拖动的模块。我可以想象它只是将全局鼠标坐标转换为画布的坐标空间。肯定有一种正确的方式可以使用画布来执行d3.mouse()或其他操作吗?最后,我在画布上使用了从d3.drag()开始拖动的模块。我可以想象它只是将全局鼠标坐标转换为画布的坐标空间。