【问题标题】:Adding multiple objects to svg and adding drag behaviour issue将多个对象添加到 svg 并添加拖动行为问题
【发布时间】:2015-12-16 18:47:17
【问题描述】:

我对 SVG 和 d3 库完全陌生。我需要向 svg 添加动态添加 5 个圆圈,其中都包含可拖动的事件处理程序。我已经编写了用于添加单个圆圈并向其添加可拖动行为的代码,并且工作正常。现在我在 for 循环中尝试同样的事情以添加 5 个圆圈。它显示所有圆圈,但是当我拖动一个特定的圆圈并将其放在某个位置时,它会停留在那里,当我触摸另一个圆圈时,旧圆圈会从我们放置的位置消失并出现在我们接下来开始的新圆圈上。请查看下面提到的代码。对此的任何帮助将不胜感激。

   function addCircles()
    {    
    var box = d3.select(".box");  

         for(var i = 0;i<5;i++)
         {

            var drag = d3.behavior.drag()  
                 .on('dragstart', function() { console.log("dragstart"); circle.style('fill', 'red'); })
                 .on('drag', function() { console.log("drag X - " + d3.event.x + " Y - " + d3.event.y); circle.attr('cx', d3.event.x)
                                                .attr('cy', d3.event.y); })
                 .on('dragend', function() {    console.log("dragend - " + d3.event.x); 
                                                circle.style('fill', 'green');  }); 

var circle = box.selectAll('.draggableCircle'+i)  
                    .data([{ x: i*15, y: i*15, r: 10 }])
                    .enter()
                    .append('svg:circle')
                    .attr('class', 'draggableCircle'+i)
                    .attr('cx', function(d) { return d.x; })
                    .attr('cy', function(d) { return d.y; })
                    .attr('r', function(d) { return d.r; })
                    .call(drag)
                    .style('fill', 'green');


         } 
    } 

我在 chrome 中调试代码后检查,发现没有检测到 dragEnd 的位置。

【问题讨论】:

  • 你想把 JSFiddle 放在一起,这样我们就可以玩代码了吗?
  • 没有得到你的问题。能否请您详细说明。
  • 把你的代码放在这里:jsfiddle.net 这样我们就可以编辑、保存并向你展示工作示例,如果可能的话。只需确保您在左栏中引用 D3,在单独的窗口中引用 html javascript 和 css,按保存,将 URL 复制到此处,我们将查看 :)
  • 请查看以下链接并尝试将每个绿色圆圈逐个拖动。 jsfiddle.net/ta2ek6zj/1

标签: javascript html d3.js svg


【解决方案1】:

你的小提琴没用,所以我不得不用提供的代码自己做:http://jsfiddle.net/Qh9X5/6932/

首先创建数据,然后根据该数据绘制圆圈,而不是一次性完成。

var nodeData = [];

     for(var i = 1;i<15;i++) //change the value 15 to however many circles you want
     {      

        nodeData.push({
           x:i*15,
           y:i*15,
           r:10
        })    

     }

然后使用这些数据创建圈子:

 var circle = box.selectAll('.draggableCircle'+i)  
                    //.data([{ x: i*15, y: i*15, r: 10 }])
                    .data(nodeData)
                    .enter()
                    .append('svg:circle')
                    .attr('class', function(d,i){
                    return 'draggableCircle'+i; //changed this to use i in the loop 
                                              //through the nodes not i in the for loop
                    })
                    .attr('cx', function(d) { return d.x; })
                    .attr('cy', function(d) { return d.y; })
                    .attr('r', function(d) { return d.r; })
                    .style('fill', 'green')
                    .call(drag)

你的拖动也没有正确完成。你有这条线:

circle.attr('cx', d3.event.x).attr('cy', d3.event.y);

您不希望这样,因为您要遍历每个圆圈并在所有圆圈中调用阻力。您只想像这样在您“拖动”的元素上调用它:

function dragmove(d, i) //-updates the co-ordinates 
{
    d.x += d3.event.dx;
    d.y += d3.event.dy; 


    d3.select(this).attr("transform", function(d,i)
    {
        return "translate(" + [ d.x,d.y ] + ")";
    });    
}

我认为这就是我为使其正常工作所做的所有更改。

附带说明,使用 JSFiddle,您必须在左侧包含 D3 库,否则它将无法工作。此外,在 html 中调用您的“drawCircles()”函数时,您必须更改小提琴的加载,否则它将无法找到该函数。此外,综上所述,如果您要在问题中再次使用 JSFiddle,请确保在向 SO 用户发送链接之前它可以正常工作。

EDIT

我添加了这条线以获得正确的加载圆位置:

circle.attr("transform", function(d){
          return "translate(" + [ d.x,d.y ] + ")";
          })

现在拖动效果很好 :)) 希望这会有所帮助

【讨论】:

  • 注意在提供的小提琴中,当你开始拖动时,节点会跳转,我现在就解决这个问题
  • 我浏览了那个特定的链接,并注意到当我们尝试拖动圆圈时,会自动更改位置并向下放置位置。 .你能检查一下并提供必要的帮助吗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 1970-01-01
  • 2018-07-06
  • 2021-07-14
  • 2020-05-11
  • 1970-01-01
相关资源
最近更新 更多