[英]Set color of nodes based on condition
我想根據其狀態為每個節點提供一種顏色。 例如,如果狀態為“完成”,則節點的顏色應為綠色。 如果是“待定”,則狀態應為藍色,依此類推。
為此,我創建了這些CSS類。 類名與狀態完全匹配-
.completed { fill: green; } .pending { fill: blue; } .dormant { fill: purple; }
在構造節點時,我試圖應用其名稱與狀態匹配的類
.style("fill", function (d) { return d3.select(this).classed(d.status, true); })
但是,這沒有任何影響。
下面是完整的代碼
var links = [ {source: "Start", target: "Dept Approver", type: "approve", staus: "completed"}, {source: "Dept Approver", target: "Amount>20", type: "approve", staus: "completed"}, {source: "Amount>20", target: "Div Approver", type: "approve", staus: "completed"}, {source: "Amount>20", target: "Section Approver", type: "approve", staus: "completed"}, {source: "Amount>20", target: "Dept Approver", type: "reject", staus: "completed"}, {source: "Div Approver", target: "End", type: "approve", staus: "dormant"}, {source: "Section Approver", target: "End", type: "approve", staus: "pending"} ]; var nodes = {}; // Compute the distinct nodes from the links. links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); }); var width = 960, height = 500; var force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([width, height]) .linkDistance(80) .charge(-300) .on("tick", function(d) { path.attr("d", function(d) { var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = 0; return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; }); circle.attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); text.attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); }) .start(); var svg = d3.select("#chart").append("svg") .attr("width", width) .attr("height", height); // Per-type markers, as they don't inherit styles. svg.append("defs").selectAll("marker") .data(["approve", "reject"]) .enter().append("marker") .attr("id", function(d) { return d; }) .attr("viewBox", "0 -5 10 10") .attr("refX", 15) .attr("refY", -1.5) .attr("markerWidth", 8) .attr("markerHeight", 8) .attr("orient", "auto") .append("path") .attr("d", "M0,-5L10,0L0,5"); var path = svg.append("g").selectAll("path") .data(force.links()) .enter().append("path") .attr("class", function(d) { return "link " + d.type; }) .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); var circle = svg.append("g").selectAll("circle") .data(force.nodes()) .enter().append("circle") .attr("r", 8) .style("fill", function (d) { return d3.select(this).classed(d.status, true); }) .call(force.drag); var text = svg.append("g").selectAll("text") .data(force.nodes()) .enter().append("text") .attr("x", ".40em") .attr("y", 12) .text(function(d) { return d.name; }); var drag = force.drag() .on("dragstart", function(d) { d3.select(this).classed("fixed", d.fixed = true); });
.link { fill: none; stroke: #666; stroke-width: 1.5px; } #licensing { fill: green; } .link.licensing { stroke: green; } .link.reject { stroke-dasharray: 0,2 1; stroke: red; } circle { fill: #ccc; stroke: #333; stroke-width: 1.5px; } text { font: 11px sans-serif; pointer-events: none; text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; } .fixed { /* fill: #00B2EE; */ } .completed { fill: green; } .pending { fill: blue; } .dormant { fill: purple; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <body> <div id="chart"></div> </body>
有人可以幫我糾正這個問題嗎?
您的代碼存在一些問題。
"status"
為"staus"
的links
在你的榜樣。 您正在嘗試根據節點的狀態為節點着色,但是由於要從force.nodes()
提供節點數據, force.nodes()
會丟失status
。 (此外,每個link
都有一個status
,而不是一個node
。)解決此問題的一種方法是分別存儲每個節點的狀態:
var nodes = {}, nodeToStatus = {}; // Compute the distinct nodes and node status from the links. links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); nodeToStatus[link.source.name] = link.status; <---- unclear which status nodeToStatus[link.target.name] = link.status; <---- to use per node });
然后使用它為節點着色:
.style("fill", function (d) { return d3.select(this).classed(nodeToStatus[d.name], true); })
這給出下面的輸出( 在此處完成Fiddle)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.