2017-03-13 25 views
1

我試圖創建一個可視化使用d3.js在android(使用apache cordova),我在手機上顯示一些元素(例如圈子)的屏幕,並有可能在元素之間創建鏈接(例如行)。d3.js觸摸並保持創建從一個元素到另一個線

如何它應該工作:

  1. 觸摸和
  2. 拖動按住開始元素上發佈

一個新的鏈接現在應該在2之間形成

  • 第二個元素元素。我可以使用鼠標事件相對輕鬆地實現此功能,但是在使用觸摸支持實現相同功能時遇到困難。

    這是顯示我面臨的問題的最小示例。

    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>

    在這個例子中touchend事件總是相同的元件上執行如touchstart,我無法找到一種方法,以獲得在頂部的元件,其在觸摸的操作已結束。

    我剛開始使用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; 
        } 
        }); 
    }); 
    

    如果移動事件「擊中」了一圈,終端節點將被定義。

    然後在你的touchend事件中,檢查我們開始和停在一個圓圈:

    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; 
    }); 
    

    運行代碼:

    <!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>

    相關問題