javascript - 拖动一个矩形并附加到相应的组

标签 javascript d3.js drag-and-drop

我正在尝试拖动石灰矩形并附加到我删除的相应组。

我有多个组,因为我无法使用 <g>直接引用。 我不知道是否需要克隆或者可以使用相同的矩形。

但是,我不知道谁是下降的目标,因为矩形第一组总是改变大小。

举个例子:

<svg id="graph" height="310" width="600" style="border: 1px solid #000;"></svg>

<!-- scripts -->
<script src="//d3js.org/d3.v4.min.js"></script>
<script>

    /* create svg & container */
  var svg = d3.select('svg').attr('focusable', false);
  var container = svg.append('g').attr('id', 'container');
  var use = svg.append('use').attr('xlink:href', '#action');
  
  /* create groups */
  var groupOne = container.append('g').attr('class', 'group').attr('transform', 'matrix(1,0,0,1, 0, 0)');
  var groupTwo = container.append('g').attr('class', 'group').attr('y', 160).attr('transform', 'matrix(1,0,0,1, 0, 160)');
  var groupThree = container.append('g').attr('class', 'group').attr('y', 160).attr('transform', 'matrix(1,0,0,1, 170, 0)');
  
  
  /* create group content  */
  var bgGroupOne = groupOne.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'red');
    
  var txtGroupOne = groupOne.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 1');
    
    var bgGroupTwo = groupTwo.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'blue');
    
 var txtGroupTwo = groupTwo.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 2');
  
  var bgGroupThree = groupThree.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'violet');
    
 var txtGroupThree = groupThree.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 3');
    
  
  var draggableElement = groupOne.append('rect')
    .attr('height', 70)
    .attr('width', 70)
    .attr('x', 40)
    .attr('y', 70)
    .attr('stroke', 'black')
    .attr('stroke-width', 2)
    .attr('fill', 'lime')
    .attr('cursor', 'move')
    .attr('id', 'action')
    .call(
        d3.drag()
        .on('start', onDragStart)
        .on('drag', onDragged)
        .on('end', onDragEnd)
    );
  
  
  /* drag functions */
  function onDragStart() {
    d3.select(this).classed("active", true);
  }
  
  function onDragged(d) {
    return d3.select(this).attr('x', d3.event.x).attr('y', d3.event.y);
  }

  function onDragEnd() {
    
  }
  
  
</script>

最佳答案

首先,将可拖动的矩形移出组1。如果该组随着矩形的移动而调整大小,它将始终位于组1中。之后,您可以对拖动事件来确定您所在的组:

<svg id="graph" height="310" width="600" style="border: 1px solid #000;"></svg>

<!-- scripts -->
<script src="//d3js.org/d3.v4.min.js"></script>
<script>

    /* create svg & container */
  var svg = d3.select('svg').attr('focusable', false);
  var container = svg.append('g').attr('id', 'container');
  var use = svg.append('use').attr('xlink:href', '#action');
  
  /* create groups */
  var groupOne = container.append('g').attr('class', 'group').attr('transform', 'matrix(1,0,0,1, 0, 0)');
  var groupTwo = container.append('g').attr('class', 'group').attr('y', 160).attr('transform', 'matrix(1,0,0,1, 0, 160)');
  var groupThree = container.append('g').attr('class', 'group').attr('y', 160).attr('transform', 'matrix(1,0,0,1, 170, 0)');
  
  
  /* create group content  */
  var bgGroupOne = groupOne.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'red');
    
  var txtGroupOne = groupOne.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 1');
    
    var bgGroupTwo = groupTwo.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'blue');
    
 var txtGroupTwo = groupTwo.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 2');
  
  var bgGroupThree = groupThree.append('rect')
    .attr('height', '150')
    .attr('width', '150')
    .attr('fill', 'violet');
    
 var txtGroupThree = groupThree.append('text')
    .attr('y', 20)
    .attr('x', 10)
    .attr('font-size', "12")
    .attr('fill', "#FFF")
    .text('Group 3');
    
  
  var draggableElement = container.append('rect')
    .attr('height', 70)
    .attr('width', 70)
    .attr('x', 40)
    .attr('y', 70)
    .attr('stroke', 'black')
    .attr('stroke-width', 2)
    .attr('fill', 'lime')
    .attr('cursor', 'move')
    .attr('id', 'action')
    .call(
        d3.drag()
        .on('start', onDragStart)
        .on('drag', onDragged)
        .on('end', onDragEnd)
    );
  
  
  /* drag functions */
  function onDragStart() {
    d3.select(this).classed("active", true);
  }
  
  let inG;
  function onDragged(d) {
    let r1 = this.getBoundingClientRect();
    inG = [groupOne,groupTwo,groupThree].find( (g) => {
      g.select('text').attr('fill','white');
      let r2 = g.node().getBoundingClientRect();
      return contains(r2, r1);
    });
    if (inG){
      inG.select('text').attr('fill','steelblue');
    }
    return d3.select(this).attr('x', d3.event.x).attr('y', d3.event.y);
  }

  function onDragEnd() {
    if (inG){
      console.log('dropped in ' + inG.select('text').text()) ;
    }
  }

function contains(a, b) {
    return !(
        b.left < a.left ||
        b.top < a.top ||
        b.right > a.right ||
        b.bottom > a.bottom
    );
}
  
  
</script>

关于javascript - 拖动一个矩形并附加到相应的组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67205664/

相关文章:

javascript - AngularJS如何根据指定参数过滤JSON数据

javascript - dc.js - 在一组中一起渲染两个对象(一个图表 - 渲染,一个形状 - 不渲染)?

java - 如何在我自己的应用程序中获得拖动到 bin 的主屏幕行为?

javascript - jQuery UI 拖放 : clone not dropping

javascript - InnerHTML 属性追加而不是替换数据

javascript - 附加到 Backbone/Marionette 中的当前路线?

javascript - Drupal 7 + D3 - 在页面中嵌入循环包可视化

javascript - d3 转换在页面加载时开始,而不是在模态弹出窗口加载时开始

jquery - 在 Jquery/HTML 上实现拖放功能

javascript - 在 amCharts 中将图表导出为图像时如何显示加载程序?