2012-09-05 24 views
4

到目前爲止,我已經在強制指導圖中使用d3.svg.symbol()來區分不同節點類型。代表一個節點的Svg圖像,在力指向圖中變化的節點尺寸

我現在想通過將節點顯示爲svg圖像來區分不同的節點類型。繼examples之一,我用下面的代碼來顯示圖像節點:

var node = svg.selectAll("image.node").data(json.nodes); 
    var nodeEnter = node.enter().append("svg:g").append("svg:image") 
    .attr("class", "node") 
    .attr("xlink:href", function(d) 
    { 
     switch(d.source) 
     { 
     case "GEXP": return "img/node_gexp.svg"; 
     case "CNVR": return "img/node_cnvr.svg"; 
     case "METH": return "img/node_meth.svg"; 
     case "CLIN": return "img/node_clin.svg"; 
     case "GNAB": return "img/node_gnab.svg"; 
     case "MIRN": return "img/node_mirn.svg"; 
     case "SAMP": return "img/node_samp.svg"; 
     case "RPPA": return "img/node_rppa.svg"; 
     } 
    }) 
    .attr("x", function(d) { return d.px; }) 
    .attr("y", function(d) { return d.py; }) 
    .attr("width", "50") 
    .attr("height", "50") 
    .attr("transform", "translate(-25,-25)") 
    .on("click", function(d) { 
     console.log("nodeclick"); 
     }) 
    .on("mouseover", fade(0.10)) 
    .on("mouseout", fade(default_opacity)) 
    .call(force.drag); 

這並顯示SVG圖像,但我有兩個問題:

1)我要縮放基於節點的尺寸在屬性上。據我瞭解,這可以通過提供的「規模」來完成屬性

transform="scale(something)" 

到合適的位置,喜歡的圖像標籤本身或包含圖像的組:

var node = svg.selectAll("image.node").data(json.nodes); 
    var nodeEnter = node.enter() 
    .append("svg:g") 
    .attr("transform", function(d) 
    { 
     var str = "scale("; 
     if(d.gene_interesting_score && d.gene_interesting_score > 0) 
     { 
      return str + ((d.gene_interesting_score - minScore)/(maxScore - minScore)) + ")"; 
     } 
     return str + 0.7 + ")"; 
    }) 
    .append("svg:image") 
    .... 

因爲它發生時,scale()變換會替換圖像:它們不再位於邊緣的端點上。如何在初始化圖形時適當地調整圖像的大小,最好使控制機制處於單個函數內(例如,使我不必分別控制x,y,寬度和高度)?

2)當圖形放大時,Chrome會模糊圖像,而在Firefox中,圖像仍然很脆(圖片)。如何避免這種模糊現象?

Chrome above, FF below

編輯:基於duopixel的建議,該代碼現在:

var nodeGroup = svg.selectAll("image.node").data(json.nodes).enter() 
    .append("svg:g") 
    .attr("id", function(d) { return d.id; }) 
    .attr("class", "nodeGroup") 
    .call(force.drag); 

    var node = nodeGroup.append("svg:image") 
    .attr("viewBox", "0 0 " + nodeImageW + " " + nodeImageH) 
    .attr("class", "node") 
    .attr("xlink:href", function(d) 
    { 
     switch(d.source) 
     { 
     case "GEXP": return "img/node_gexp.svg"; 
     case "CNVR": return "img/node_cnvr.svg"; 
     case "METH": return "img/node_meth.svg"; 
     case "CLIN": return "img/node_clin.svg"; 
     case "GNAB": return "img/node_gnab.svg"; 
     case "MIRN": return "img/node_mirn.svg"; 
     case "SAMP": return "img/node_samp.svg"; 
     case "RPPA": return "img/node_rppa.svg"; 
     } 
    }) 
    .attr("width", nodeImageW) 
    .attr("height", nodeImageH) 
    .attr("transform", function(d) 
    { 
     var matrix = "matrix("; 
     var scale = 0.7; // sx & sy 
     if(d.gene_interesting_score && d.gene_interesting_score > 0) 
     { 
     scale = ((d.gene_interesting_score - minScore)/(maxScore - minScore)) * 0.5 + 0.25; 
     } 
     //console.log("id=" + d.id + ", score=" + scale); 
     matrix += scale + ",0,0," + scale + "," + (d.x - (scale*nodeImageW/2)) + "," + (d.y - (scale*nodeImageH/2)) + ")"; 
     return matrix; 
    }) 
    // .attr("transform", "translate(-25,-25)") 
    .on("click", function(d) { 
     console.log("nodeclick"); 
     }) 
    .on("mouseover", fade(0.10)) 
    .on("mouseout", fade(node_def_opacity)); 

它解決了問題#1,但不是第二個:選擇

var nodeImageH = 300; 
var nodeImageW = 300; 

生成的svg圖像包含大量的空白空間(通過使用螢火蟲的選擇工具選擇圖像來看)。圖像是在Inkscape中創建的,裁剪爲50x50的畫布大小應該是正確的觀看像素大小。

回答

3

#1您需要設置轉換原點。在SVG這意味着你將不得不使用變換矩陣如下回答:https://stackoverflow.com/a/6714140/524555

#2爲了解決模糊縮放修改svg文件的viewBox, width, height開始大圖像(即<svg viewBox="0 0 300 300" width="300" height="300">

+0

似乎#2不起作用,或者我做錯了什麼,請參閱上面的編輯 – amergin

+1

你不能在'image'元素上分配一個viewBox,你必須深入到實際的svg文件並改變它們的值。在Inkscape中放大圖像(Webkit本質上是將svg文件當作位圖來對待,所以如果你想保持清晰的話,你需要更大的版本)。 – Duopixel