[英]Gradient along links in D3 Sankey diagram
@VividD:剛剛看到你的評論,但無論如何我還是完成了。 在你自己想出來之前,請隨意忽略這一點,但我想確保我知道如何去做。 另外,這是一個非常常見的問題,非常適合參考。
需要提醒的人閱讀這之后,它只會工作,因為路徑幾乎是直線,所以線性漸變的外觀半體面-路徑行程設置漸變不與路徑漸變曲線!
在初始化中,在SVG中創建<defs>
(definitions)元素並將選擇保存到變量:
var defs = svg.append("defs");
定義一個函數,該函數將從鏈接數據對象為漸變創建唯一的 id。 為函數確定節點顏色的名稱也是一個好主意:
function getGradID(d){return "linkGrad-" + d.source.name + d.target.name;} function nodeColor(d) { return d.color = color(d.name.replace(/ .*/, ""));}
在<defs>
創建<linearGradient>
對象的選擇並將其連接到鏈接數據,然后根據源和目標數據對象設置停止偏移和線坐標。
對於您的示例,如果您只是使所有漸變水平,它可能看起來很好。 因為這是方便的默認我認為我們所要做的就是告訴漸變以適應它繪制的路徑的大小:
var grads = defs.selectAll("linearGradient") .data(graph.links, getLinkID); grads.enter().append("linearGradient") .attr("id", getGradID) .attr("gradientUnits", "objectBoundingBox"); //stretch to fit grads.html("") //erase any existing <stop> elements on update .append("stop") .attr("offset", "0%") .attr("stop-color", function(d){ return nodeColor( (d.source.x <= d.target.x)? d.source: d.target) }); grads.append("stop") .attr("offset", "100%") .attr("stop-color", function(d){ return nodeColor( (d.source.x > d.target.x)? d.source: d.target) });
不幸的是,當路徑是完全直線時,其邊界框不存在(無論筆划寬度有多寬), 最終結果是漸變不會被繪制 。
所以我不得不切換到更一般的模式,其中漸變位置和沿源和目標之間的線成角度:
grads.enter().append("linearGradient") .attr("id", getGradID) .attr("gradientUnits", "userSpaceOnUse"); grads.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;}); /* and the stops set as before */
當然,現在漸變是基於坐標系而不是基於路徑的長度定義的,你必須在節點移動時更新那些坐標,所以我必須將這些定位語句包裝在我可以調用的函數中在dragmove()
函數中。
最后,在創建鏈接路徑時,將其填充設置為CSS url()
函數,引用從數據派生的相應唯一漸變id(使用預定義的實用程序函數):
link.style("stroke", function(d){ return "url(#" + getGradID(d) + ")"; })
還有瞧!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.