nasıl

2012-08-13 6 views
45

ben kuvvet düzeni kullanarak bir grafik var ekran/tarayıcı boyutuna duyarlı d3.js kuvvet düzeni grafiği yapmak için, ancak sabit bir genişlik w ve yüksekliğini h vardır: Bir svg sonuçlanırnasıl

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      .attr("width", w) 
      .attr("height", h) 

var force = d3.layout.force() 
       .nodes(nodes) 
       .links(links) 
       .charge(-1600) 
       .linkDistance(45) 
       .size([w, h]); 

Ekrandaki veya tarayıcı pencere boyutundaki değişikliklere rağmen ölçeklenmeyen veya azalmayan grafik. Ben tarayıcı penceresi boyutunu ayarlamak zaman hiçbir şey olmuyor olarak

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      .attr("width", w) 
      .attr("height", h) 
      .attr("viewBox", "0, 0, 600, 400") 
      .attr("preserveAspectRatio", "xMidYMid meet"); 

Maalesef bu işe yaramadı: (yani kendisini otomatik boyutlandırır) o duyarlı hale getirmek için, ben viewBox ve preserveAspectRatio özellikleri kullanarak çalıştı. Kuvvet grafiğinin .size([w, h])'un bununla bir ilgisi olup olmadığını merak ediyorum.

Lütfen güç düzeni grafikleriyle viewBox ve preserveAspectRatio özniteliklerinin nasıl kullanılacağı konusunda biraz ışık tutabilirsiniz.

+0

Ayrıca, redraw işlevinizi 'window.onresize' – Wex

+0

'a eklemek isteyebilirsiniz. Bu soru oldukça eskidir, ancak yararlı bulabilenler için, düğümleri sınırlı bir kutuyla sınırlamayı da düşünebilirsiniz. Yeniden boyutlandırıldığında, düğümler ekranda kalır. Örnek: http://bl.ocks.org/mbostock/1129492 – joshfindit

cevap

50

Sorun, .size() kapsamında değil, .attr("width", w) .attr("height", h) numaralı telefondan SVG boyutlarını bildiriyorsunuz. O iki <g> unsurları iç içe ve ekli neden bilmiyorum hariç

var svg = d3.select("#viz").append("svg") 
      .attr("id", "playgraph") 
      //better to keep the viewBox dimensions with variables 
      .attr("viewBox", "0 0 " + w + " " + h) 
      .attr("preserveAspectRatio", "xMidYMid meet"); 

http://jsfiddle.net/aaSjd/

+0

Teşekkürler! Yani şimdi svg resmi yeniden boyutlandırır. Ancak, attr ("width", ...) 've' attr ("height", ...) 'ayarlanmadan, görüntünün genişliği/yüksekliği geçerli tarayıcı penceresinin genişliği/yüksekliğidir. 'ViewBox' ve' preserveAspectRatio' özelliklerini etkilemeden 'svg' öğesinin bu iki boyutunu başka bir yerde ayarlayabilmem mümkün mü? – MLister

+3

' 'başlamanız gerekir. – Duopixel

4

Duopixel, ne gerekli çok yakındır ... Bu iki özellik çıkarın ve doğru yapacağım olay dinleyicileri en dıştaki <g> (aynı zamanda tüm alanın üzerindeki olaylara tepki vermek için her şeyin arkasında görünmez bir dikdörtgen gerektirir).

Dinleyicileri <svg> ürününe eklemek daha kolaydır ve daha sonra yalnızca bir iç <g>'a gereksinim duyarsınız.

var width = 1000, 
    height = 1000; 

var color = d3.scale.category20(); 

var svg = d3.select("body") 
    .append("svg") 
     .attr({ 
     "width": "100%", 
     "height": "100%" 
     }) 
     .attr("viewBox", "0 0 " + width + " " + height) 
     .attr("preserveAspectRatio", "xMidYMid meet") 
     .attr("pointer-events", "all") 
    .call(d3.behavior.zoom().on("zoom", redraw)); 

var vis = svg 
    .append('svg:g'); 

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

function draw_graph(graph) { 
    var force = d3.layout.force() 
     .charge(-120) 
     .linkDistance(30) 
     .nodes(graph.nodes) 
     .links(graph.links) 
     .size([width, height]) 
     .start(); 

    var link = vis.selectAll(".link") 
     .data(graph.links) 
     .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value); }); 

    var node = vis.selectAll(".node") 
     .data(graph.nodes) 
     .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 5) 
     .style("fill", function(d) { return color(d.group); }) 
     .call(force.drag); 

    node.append("title") 
     .text(function(d) { return d.name; }); 

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

draw_graph(data); 
8

Burada gösterilen çözümü: http://bl.ocks.org/mbostock/3355967 benim için iyi çalıştı

İşte benim tam ekran zorla yönettiği örnektir!

window.addEventListener('resize', resize); 

function resize() { 
    var width = window.innerWidth, height = window.innerHeight; 
    svg.attr("width", width).attr("height", height); 
    force.size([width, height]).resume(); 
} 

Tüm çizgilerinizi, düğümlerinizi vb. Ekledikten sonra resize() çalıştırdığınızdan emin olun.