2017-03-13 3 views
1

나는 휴대 전화에 몇 가지 요소 (예 : 원)를 표시하는 안드로이드 (apache cordova 사용)에서 d3.js를 사용하여 시각화를 만들려고합니다. 화면과 요소 사이에 링크 (예 : 줄)를 만들 가능성이 있습니다.d3.js 하나의 요소에서 다른 요소로 선을 만들기 위해 길게 누르기

  1. 터치를하고
  2. 릴리스

새로운 링크가 이제 2 사이에 형성되어야하는 두 번째 요소로 시작 요소에

  • 을 누른 상태에서 드래그 :

    가 작동하는 방법 집단. 마우스 이벤트를 사용하여 상대적으로 쉽게이 작업을 수행 할 수 있지만 터치 지원을 사용하여 동일한 작업을 수행하는 데 어려움이 있습니다.

    이것은 내가 직면 한 문제를 보여주는 최소 예입니다. 이 예에서

    touchend 이벤트가 항상 touchstart과 같은 요소에 실행되고 내가 상단에있는 요소를 얻을 수있는 방법을 찾을 수 없습니다

    var width = 350, 
     
        height = 600, 
     
        colors = d3.scale.category10(); 
     
    
     
    var nodeData = 
     
        [ 
     
         { id: 1, x: 50, y: 50 }, 
     
         { id: 2, x: 200, y: 50 }, 
     
         { id: 3, x: 125, y: 150 } 
     
        ]; 
     
    
     
    var svg = d3.select('body') 
     
        .append('svg') 
     
        .attr('width', width) 
     
        .attr('height', height); 
     
    
     
    
     
    var node = svg.selectAll('g') 
     
        .data(nodeData) 
     
        .enter() 
     
        .append('g'); 
     
    
     
    node.append('circle') 
     
        .attr('cx', function (d) { return d.x; }) 
     
        .attr('cy', function (d) { return d.y; }) 
     
        .attr('r', 30) 
     
        .attr('fill', 'red') 
     
        .on('touchstart', function (node) { 
     
        }) 
     
        .on('touchend', function (node) { 
     
        }); 
     
    
     
    node.append('text') 
     
        .attr('fill', 'white') 
     
        .attr('x', function (d) { return d.x; }) 
     
        .attr('y', function (d) { return d.y; }) 
     
        .text(function (d) { return d.id; });
    <script src="https://d3js.org/d3.v3.min.js"></script>
    하는 터치의 작업이 종료되었습니다.

    d3.js를 사용하기 시작 했으므로 도움을 받으실 수 있습니다.

    건배

  • 답변

    2

    당신은 히트 (충돌) 감지를 사용하도록 전환 할 수 있습니다 : 이동 이벤트가 원을 "명중"

    svg.on('touchmove', function() { 
        var p = d3.touches(this)[0]; 
    
        endNode = undefined; 
        cs.each(function(d) { 
        var self = d3.select(this), 
         x = d.x - p[0], 
         y = d.y - p[1], 
         l = Math.sqrt(x * x + y * y), 
         r = 30; 
    
        if (l < r) { 
         endNode = d; 
        } 
        }); 
    }); 
    

    경우, 말단 노드가 정의됩니다.

    <!DOCTYPE html> 
     
    <html> 
     
    
     
    <head> 
     
        <script src="https://d3js.org/d3.v4.min.js"></script> 
     
    </head> 
     
    
     
    <body> 
     
        <script> 
     
        var width = 350, 
     
         height = 600; 
     
        //colors = d3.scale.category10(); 
     
    
     
        var nodeData = [{ 
     
         id: 1, 
     
         x: 50, 
     
         y: 50 
     
        }, { 
     
         id: 2, 
     
         x: 200, 
     
         y: 50 
     
        }, { 
     
         id: 3, 
     
         x: 125, 
     
         y: 150 
     
        }]; 
     
    
     
        var startNode, endNode; 
     
    
     
        var svg = d3.select('body') 
     
         .append('svg') 
     
         .attr('width', width) 
     
         .attr('height', height); 
     
    
     
        svg.on('touchmove', function() { 
     
         var p = d3.touches(this)[0]; 
     
         
     
         endNode = undefined; 
     
         cs.each(function(d) { 
     
         var self = d3.select(this), 
     
          x = d.x - p[0], 
     
          y = d.y - p[1], 
     
          l = Math.sqrt(x * x + y * y), 
     
          r = 30; 
     
    
     
         if (l < r) { 
     
          endNode = d; 
     
         } 
     
         }); 
     
        }); 
     
        svg.on('touchend', function(){ 
     
         if (startNode && endNode){ 
     
         svg.append("path") 
     
          .style("fill", "none") 
     
          .style("stroke", "black") 
     
          .attr("d", "M" + startNode.x + "," + startNode.y + "L" + endNode.x + "," + endNode.y); 
     
         } 
     
         startNode = undefined; 
     
         endNode = undefined; 
     
         cs.attr("fill", "red"); 
     
        }) 
     
    
     
        var node = svg.selectAll('g') 
     
         .data(nodeData) 
     
         .enter() 
     
         .append('g'); 
     
    
     
        var cs = node.append('circle') 
     
         .attr('cx', function(d) { 
     
         return d.x; 
     
         }) 
     
         .attr('cy', function(d) { 
     
         return d.y; 
     
         }) 
     
         .attr('r', 30) 
     
         .attr('fill', 'red') 
     
         .on('touchstart', function(d) { 
     
         startNode = d; 
     
         }); 
     
    
     
        node.append('text') 
     
         .attr('fill', 'white') 
     
         .attr('x', function(d) { 
     
         return d.x; 
     
         }) 
     
         .attr('y', function(d) { 
     
         return d.y; 
     
         }) 
     
         .text(function(d) { 
     
         return d.id; 
     
         }); 
     
        </script> 
     
    </body> 
     
    
     
    </html>

    : 코드를 실행

    svg.on('touchend', function(){ 
        if (startNode && endNode){ 
        svg.append("path") 
         .style("fill", "none") 
         .style("stroke", "black") 
         .attr("d", "M" + startNode.x + "," + startNode.y + "L" + endNode.x + "," + endNode.y); 
        } 
        startNode = undefined; 
        endNode = undefined; 
    }); 
    

    :

    는 그런 다음 touchend 이벤트에서, 우리는 시작 원에 중단 확인