2016-01-13 135 views
0

SO上有類似的問題,但我根本不知道如何在我的情況下使用它。我正在嘗試將縮放/平移功能添加到力圖。我對D3.js的瞭解是基本的,請原諒我愚蠢的問題。D3.js - 強制關係圖。如何添加縮放和平移

這是從這個website原來fiddle

fiddle是我嘗試添加變焦能力。

我加入這個代碼:

var zoom = d3.behavior.zoom() 
     .scaleExtent([1, 10]) 
     .on("zoom", zoomed); 

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


function zoomed() { 
     container.attr("transform", "translate(" + d3.event.translate + 
    ")scale(" + d3.event.scale + ")"); 
    } 

    function dragstarted(d) { 
     d3.event.sourceEvent.stopPropagation(); 

     d3.select(this).classed("dragging", true); 
     force.start(); 
    } 

    function dragged(d) { 

     d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = 
    d3.event.y); 

    } 

    function dragended(d) { 

     d3.select(this).classed("dragging", false); 
    } 

而且什麼也沒有發生,代碼的作品,但縮放和平移沒有。我錯過了什麼?

+0

的[?有沒有一種方法可以放大到一個D3力佈局圖](可能的複製http://stackoverflow.com/questions/7871425/is-there-a-方式到放大到一個d3力佈局圖) –

+0

你有看看這個演示http://bl.ocks.org/mbostock/6123708?網上有很多可縮放的d3力圖的例子... –

回答

3

您需要一組附加到使用.append您的SVG( 'SVG:G');聲明你的SVG後。不幸的是,當它具有子元素時,不能直接將變換應用於svg元素(因爲它們還需要縮放)。

您可以在這裏的行動看到它 - http://jsfiddle.net/s7aLv276/ < - 新版本

//Append a SVG to the body of the html page. Assign this SVG as an object to svg 
    var svg = d3.select('body').append("svg") 
     .attr("width", width) 
     .attr("height", height) 
     .call(zoom) 
     .append('svg:g'); // <- Add your group so you can transform all elements together 

整個代碼:

//Constants for the SVG 
var width = 500, 
    height = 500; 

//Set up the colour scale 
var color = d3.scale.category20(); 

//Set up the force layout 
var force = d3.layout.force() 
    .charge(-120) 
    .linkDistance(80) 
    .size([width, height]); 

var zoom = d3.behavior.zoom() 
    .scaleExtent([1, 10]) 
    .on("zoom", zoomed); 

//Append a SVG to the body of the html page. Assign this SVG as an object to svg 
var svg = d3.select('body').append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .call(zoom) 
    .append('svg:g'); 


//Read the data from the mis element 
var mis = document.getElementById('mis').innerHTML; 
graph = JSON.parse(mis); 

force.drag().on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); }); 

//Creates the graph data structure out of the json data 
force.nodes(graph.nodes) 
    .links(graph.links) 
    .start(); 


//Create all the line svgs but without locations yet 
var link = svg.selectAll(".link") 
    .data(graph.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("marker-end", "url(#suit)") //Added 
; 

//Do the same with the circles for the nodes - no 
var node = svg.selectAll(".node") 
    .data(graph.nodes) 
    .enter().append("circle") 
    .attr("class", "node") 
    .attr("r", 8) 
    .style("fill", function(d) { 
    return color(d.group); 
    }) 
    .call(force.drag); 

function zoomed() { 
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 
} 

function dragstarted(d) { 
    d3.event.sourceEvent.stopPropagation(); 

    d3.select(this).classed("dragging", true); 
    force.start(); 
} 

function dragged(d) { 

    d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y); 

} 

function dragended(d) { 

    d3.select(this).classed("dragging", false); 
} 

//Now we are giving the SVGs co-ordinates - the force layout is generating the co-ordinates which this code is using to update the attributes of the SVG elements 
force.on("tick", function() { 
    link.attr("x1", function(d) { 
     return d.source.x; 
    }) 
    .attr("y1", function(d) { 
     return d.source.y; 
    }) 
    .attr("x2", function(d) { 
     return d.target.x; 
    }) 
    .attr("y2", function(d) { 
     return d.target.y; 
    }); 

    node.attr("cx", function(d) { 
     return d.x; 
    }) 
    .attr("cy", function(d) { 
     return d.y; 
    }); 
}); 

//---Insert------- 
svg.append("defs").selectAll("marker") 
    .data(["suit", "licensing", "resolved"]) 
    .enter().append("marker") 
    .attr("id", function(d) { 
    return d; 
    }) 
    .attr("viewBox", "0 -5 10 10") 
    .attr("refX", 25) 
    .attr("refY", 0) 
    .attr("markerWidth", 6) 
    .attr("markerHeight", 6) 
    .attr("orient", "auto") 
    .append("path") 
    .attr("d", "M0,-5L10,0L0,5 L10,0 L0, -5") 
    .style("stroke", "#4679BD") 
    .style("opacity", "0.6"); 
//---End Insert--- 

*更新到節點添加平移/縮放*

看起來我們沒有在Force對象上附加拖動處理程序。我已經添加了以下行:

force.drag().on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); }); 

圖表應該讓你現在拖動單個節點,以及平移和縮放整個圖形。

看到它在行動 - http://jsfiddle.net/s7aLv276/

+1

這就是它的縮放和平移:)。但由於某種原因,將節點拖到新位置現在已連接到縮放。在我能夠抓住節點並把它放到新的位置之前,現在當我嘗試去做它時,它就會平移。你可以看看嗎? –

+1

啊,我明白了。我已經更新了小提琴,所以你現在可以平移和放大圖形和單個節點(見上面的答案) - http://jsfiddle.net/s7aLv276/ – Garbit