2015-12-31 87 views
3

我改編了Christopher Manning's force-directed graph on a sphere。我想讓圖形平靜下來,然後旋轉球體而不改變圖形中各點之間的關係。相反,當我拖動時,它似乎拖動圖形,而不是旋轉球體。拖動圖形將激活強制啓動。如果我關掉force.start()沒有什麼變化。d3.js強制定向圖球體

var svg = d3.select("#cluster").append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .call(d3.behavior.drag() 
     .origin(function() { var r = projection.rotate(); return {x: 2 * r[0], y: -2 * r[1]}; }) 
     .on("drag", function() { force.start(); var r = [d3.event.x/2, -d3.event.y/2, projection.rotate()[2]]; t0 = Date.now(); origin = r; projection.rotate(r); })) 

http://bl.ocks.org/mbostock/3795040,我發現我可以旋轉格線,但隨後我所有的鏈路和節點的消失。

var path = d3.geo.path() 
    .projection(projection); 

var λ = d3.scale.linear() 
    .domain([0, width]) 
    .range([-180, 180]); 

var φ = d3.scale.linear() 
    .domain([0, height]) 
    .range([90, -90]); 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

svg.on("mousemove", function() { 
    var p = d3.mouse(this); 
    projection.rotate([λ(p[0]), φ(p[1])]); 
    svg.selectAll("path").attr("d", path); 
}); 

鏈路和節點會添加類似這樣的:

var link = svg.selectAll("path.link") 
     .data(graph.links) 
     .enter().append("path").attr("class", "link") 
     .attr ("stroke-width", function(d){return d.value/3}); 

    var node = svg.selectAll("path.node") 
     .data(graph.nodes) 
     .enter() 
     .append("g") 
     .attr("class", "gnode") 
     .attr("text-anchor", "middle") 

     .append("path").attr("class", "node") 
     .style("fill", function(d) { return d.color; }) 
     .style("stroke", function(d) { return d3.rgb(fill(d.group)).darker(); }) 

我想什麼來完成:當圖形落戶到的位置,我想用拖動手勢旋轉與球節點和鏈接。

我該如何做到這一點?

回答

0

這可能沿一個軸

var rotateScale = d3.scale.linear().domain([0, width]).range([-180,180]);//width of SVG 

d3.select("svg").on("mousedown",startRotating).on("mouseup",stopRotating); 

function startRotating() { 
    d3.select("svg").on("mousemove",function() { 
     var p = d3.mouse(this); 
     projection.rotate([rotateScale(p[0]),0]); 
    }); 
} 
function stopRotating() { 
    d3.select("svg").on("mousemove",null); 
} 
2

這可以通過調整對svgdrag事件,這是你的第一個片段定義註冊的處理程序進行旋轉。這需要兩次編輯:

  1. 擺脫force.start(),因爲您不想在拖動時重新啓動力量。
  2. 投影更新後觸發節點和鏈接的渲染,可以通過調用tick()輕鬆完成。如果力量沒有被步驟1停用,這將被重複調用,因爲該函數被註冊爲力佈局的事件處理程序。現在,你已經停用了部隊,你必須明確地稱呼它。

重新格式化代碼如下:

.on("drag", function() { 
    //force.start();  // 1. Don't restart the force. 
    var r = [d3.event.x/2, -d3.event.y/2, projection.rotate()[2]]; 
    t0 = Date.now(); 
    origin = r; 
    projection.rotate(r); 
    tick();    // 2. Trigger the rendering after adjusting the projection. 
})) 

看一看這個working example

+0

謝謝,這個例子正是我正在尋找的。我的快速應用你的建議並沒有解決問題,但這個例子顯然有效。我會再研究一下,這應該可以解決我的問題。謝謝。 – user1430965

+0

這就像一個魅力。需要包含您示例中的tick函數。再次感謝你! – user1430965