d3.js 创建新链接之前未清除旧链接

dgsult0t  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(200)

当拖动一个节点时,链接应使用新坐标更新。当前代码不清除旧路径。我使用了join方法,但是group元素没有清理附加的子元素。

svg_arc()

function svg_arc() {
        var svg = d3.select('body')
                .append('svg')
                .attr('width',410)
                .attr('height',500)
                //.style('border','10px solid red')
                .style('background','#ececec')
        
        var g = svg.append('g')
                .attr('stroke','black')
                .attr('stroke-width',1)
                .attr('fill','black')       
        
        var data = [
                {
                        id:"pointA",
                        x:100,
                        y:350,
                        r:6,
                        text:'A'
                },{
                        id:"pointB",
                        x:250,
                        y:50,
                        r:6,
                        text:'B'
                },{
                        id:"pointC",
                        x:400,
                        y:350,
                        r:6,
                        text:'C'
                }
        ]
        var node = g.selectAll('.node')
                .data(data)
                .join('g')
                .attr('class','node')
                .attr('transform',d => `translate(${d.x},${d.y})`)
                .attr("pointer-events", "all")
        
        var circle = node.append('circle')
                .attr('id',d => d.id)
                .attr('cx',0)
                .attr('cy',0)
                .attr('r',d => d.r)
                .attr("pointer-events", "all")

        var text = node.append('text')
                .attr('class','text')
                .text(d => d.text)
                .attr('x',0)
                .attr('y',0)
                .attr('dx',-15)
                .attr('dy',-15)

        node.call(
                d3.drag()
                        .on("start",function(event,d) {
                                d3.select(this).raise().classed("active", true);
                        })                          
                        .on("drag",function(event,d) {
                                
                                d.x += event.dx
                                d.y += event.dy
                                update_links(g,data)
                                d3.select(this).attr('transform',`translate(${d.x},${d.y})`)
                        })
                        .on("end", function dragEnd(event,d) {
                                d3.select(this).classed("active", false);
                        })
        )

        update_links(g,data)
}

function update_links(g,n) {
        var data = [0]//dummy data
        var line = g.selectAll('.lines')
                .data(data)
                .join('g')
                .attr('class','lines')
        
        line.append('path')
                .attr('class','AB')
                .attr('d',['M',n[0].x,n[0].y,'L',n[1].x,n[1].y].join(' '))
                .attr('stroke','black')

        line.append('path')
                .attr('class','BC')
                .attr('d',['M',n[1].x,n[1].y,'L',n[2].x,n[2].y].join(' '))
                .attr('stroke','black')

        line.append('path')
                .attr('class','AC')     
                .attr('d',['M',n[0].x,n[0].y,'Q',n[1].x,n[1].y,n[2].x,n[2].y].join(' '))
                .attr('stroke','black')
                .attr('fill','none')

        line.append('path')
                .attr('class','MID')
                .attr('d',['M',(n[0].x+n[1].x)/2,(n[0].y+n[1].y)/2,'L',(n[1].x+n[2].x)/2,(n[1].y+n[2].y)/2].join(' '))
                .attr('fill','none')
        
}
<script src="https://unpkg.com/d3@7.0.4/dist/d3.min.js"></script>
r3i60tvu

r3i60tvu1#

对组使用join,这是正确的,但是您只是将路径附加到组。换句话说,您需要为路径本身选择输入/更新/退出。
下面是修改后的代码:

svg_arc()

function svg_arc() {
  var svg = d3.select('body')
    .append('svg')
    .attr('width', 410)
    .attr('height', 500)
    //.style('border','10px solid red')
    .style('background', '#ececec')

  var g = svg.append('g')
    .attr('stroke', 'black')
    .attr('stroke-width', 3)
    .attr('fill', 'black')

  var data = [{
    id: "pointA",
    x: 100,
    y: 350,
    r: 6,
    text: 'A'
  }, {
    id: "pointB",
    x: 250,
    y: 50,
    r: 6,
    text: 'B'
  }, {
    id: "pointC",
    x: 400,
    y: 350,
    r: 6,
    text: 'C'
  }]
  var node = g.selectAll('.node')
    .data(data)
    .join('g')
    .attr('class', 'node')
    .attr('transform', d => `translate(${d.x},${d.y})`)
    .attr("pointer-events", "all")

  var circle = node.append('circle')
    .attr('id', d => d.id)
    .attr('cx', 0)
    .attr('cy', 0)
    .attr('r', d => d.r)
    .attr("pointer-events", "all")

  var text = node.append('text')
    .attr('class', 'text')
    .text(d => d.text)
    .attr('x', 0)
    .attr('y', 0)
    .attr('dx', -15)
    .attr('dy', -15)

  node.call(
    d3.drag()
    .on("start", function(event, d) {
      d3.select(this).raise().classed("active", true);
    })
    .on("drag", function(event, d) {

      d.x += event.dx
      d.y += event.dy
      update_links(g, data)
      d3.select(this).attr('transform', `translate(${d.x},${d.y})`)
    })
    .on("end", function dragEnd(event, d) {
      d3.select(this).classed("active", false);
    })
  )

  update_links(g, data)
}

function update_links(g, n) {
  var data = [0] //dummy data
  var group = g.selectAll('.lines')
    .data(data)
    .join('g')
    .attr('class', 'lines');

  const line = group.selectAll(".line")
    .data([0, 1, 2, 3])
    .join("path")
    .attr("class", "line")
    .attr("d", d => d === 0 ? ['M', n[0].x, n[0].y, 'L', n[1].x, n[1].y].join(' ') :
      d === 1 ? ['M', n[1].x, n[1].y, 'L', n[2].x, n[2].y].join(' ') :
      d === 2 ? ['M', n[0].x, n[0].y, 'Q', n[1].x, n[1].y, n[2].x, n[2].y].join(' ') : ['M', (n[0].x + n[1].x) / 2, (n[0].y + n[1].y) / 2, 'L', (n[1].x + n[2].x) / 2, (n[1].y + n[2].y) / 2].join(' '))
    .attr('stroke', 'black')
    .attr('fill', d => d > 1 ? 'none' : null)

}
<script src="https://unpkg.com/d3@7.0.4/dist/d3.min.js"></script>

请记住,这只是为了向您展示为什么您的代码会以这种方式运行。这里仍然有很多很多问题需要解决,从不必要的位到有效地降低性能的模式(例如,在拖动回调中使用join是一个很大的问题),但这超出了这个答案的范围。

相关问题