到目前爲止,我已經在強制指導圖中使用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中,圖像仍然很脆(圖片)。如何避免這種模糊現象?
編輯:基於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的畫布大小應該是正確的觀看像素大小。
似乎#2不起作用,或者我做錯了什麼,請參閱上面的編輯 – amergin
你不能在'image'元素上分配一個viewBox,你必須深入到實際的svg文件並改變它們的值。在Inkscape中放大圖像(Webkit本質上是將svg文件當作位圖來對待,所以如果你想保持清晰的話,你需要更大的版本)。 – Duopixel