2013-06-01 44 views
1

我從包裝佈局中排列了一些圓,它們從定期更新半徑的數據集中排列。d3包裝佈局圖圈在運動/尺寸轉換後重疊

我開始了該代碼爲氣泡圖表此標準例如:http://bl.ocks.org/mbostock/4063269

enter image description here

每當圓尺寸發生變化,它們的過渡。通常當圓圈長大時,它們會移動以重疊其他圓圈。我不希望他們互相重疊。

我對d3還很新,已經將代碼移到了很多位置,並嘗試了我所能想到的一切,但沒有運氣。

功能makeBubbles通過原始Json(見下文)。

function makeBubbles(root){ 
    var diameter = $(window).width(), 
     diameterh = $(window).height(), 
     format = d3.format(",d"), 
     color = d3.scale.category20(); 

    var bubble = d3.layout.pack() 
     .sort(null) 
     .size([diameter, diameterh]) 
     .value(function(d){return d.value; }) 
     .padding(1.5); 

    var svg = d3.select("svg") 
     .attr("width", diameter) 
     .attr("height", diameterh) 
     .attr("class", "bubble"); 

    var node = svg.selectAll(".node") 
     .data(bubble.nodes(classes(root)).filter(function(d) { return !d.children; }),  function(d){ console.log(d); return d.className; }); 


    node.append("title") 
     .text(function(d) { return d.className + ": " + format(d.value); }); 

    node.append("circle") 
     .style("fill", function(d) { return color(d.packageName); }) 
     .on("click", function(d) { window.location = d.url; }) 
     .attr("r", 0) 
     .transition() 
     .duration(1000) 
     .attr("r", function(d) { return d.r; }); 

    node.transition().duration(1000).attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

    node.enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

    node.exit().transition().duration(200).attr("transform", "scale(0.001)").remove(); 

    node.append("text") 
     .attr("dy", ".3em") 
     .style("text-anchor", "middle") 
     .text(function(d) { return d.className.substring(0, d.r/6); }) 
     .attr("opacity",0) 
     .transition().duration(1000) 
     .attr("opacity",1); 

// Returns a flattened hierarchy containing all leaf nodes under the root. 
    function classes(root) { 
    var classes = []; 

    function recurse(name, node) { 
     if (node.children) node.children.forEach(function(child) { recurse(node.name, child);  }); 
     else classes.push({packageName: name, className: node.name, value: node.size, url: node.url}); 
    } 

    recurse(null, root); 
    return {children: classes}; 
    } 

    d3.select(self.frameElement).style("height", diameterh + "px"); 
} 

數據傳遞看起來是這樣的(如不同的數據集進行更新):

{"name":"bubbles","children":[{"name":"tourism","children":[{"name":"tourism","children":[{"name":"practical","children":[{"name":"ACCOMM","size":13,"url":"#"},{"name":"HIRE","size":2,"url":"#"}]},{"name":"activity","children":[{"name":"EVENT","size":6,"url":"#"},{"name":"TOUR","size":3,"url":"#"}]},{"name":"leisure","children":[{"name":"RESTAURANT","size":168,"url":"#"},{"name":"ATTRACTION","size":8,"url":"#"}]}]}]}]} 
+0

的關鍵,這是處理更新選擇適當的更新時,即你不需要追加新的社交圈,但更新現有的。例如,您可以在[本教程](http://mbostock.github.io/d3/tutorial/circle.html)中找到更多信息。 –

回答

1

我也有類似的問題。

我稍微修改了你的代碼(大部分簡化了),你可以找到here工作示例。

我的方法是不使用轉換。沒有它們,代碼看起來更具可讀性和可維護性。所以,我提出了一個簡單的解決方案,我希望你可以在你的情況下使用它。

標籤。轉型可能不是最好的,但你可以改變它。

在jsfiddle上,它不可能集成json文件,所以數據在javascript裏面。在你的代碼中,你需要處理加載json,但是我的例子中的核心思想可以不加修改地應用。

的主要功能是:

function updateVis() { 

    if (dataSource == 0) 
     pack.value(function(d) { return d.size; }); 
    if (dataSource == 1) 
     pack.value(function(d) { return 100; }); 
    if (dataSource == 2) 
     pack.value(function(d) { return 1 + 
       Math.floor(Math.random()*501); }); 

    var data1 = pack.nodes(data); 

    titles.attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }) 
     .text(function(d) { 
      return (d.children ? "" : d.name + ": " + format(d.value)); 
     }); 

    circles.transition() 
     .duration(5000) 
     .attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }) 
     .attr("r", function(d) { return d.r; }); 

    labels.transition() 
     .duration(5000) 
     .attr("opacity", 0) 
     .attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }) 
     .each("end", function(d){ 
      d3.select(this).text(function(d) { 
        return d.children ? "" : d.name.substring(0, d.r/4); 
       }); 
      d3.select(this).transition() 
       .duration(1000) 
       .attr("opacity", 1); 
     }); 

};