2015-05-06 19 views
0

我想根据其状态为每个节点提供颜色。例如,如果状态为“已完成”,则节点的颜色应为绿色。如果它是'正在等待'状态应该是蓝色等等。根据条件设置节点的颜色

为此我创建了这些css类。类名完全匹配与状态 -

.completed { 
 
    fill: green; 
 
} 
 
.pending { 
 
    fill: blue; 
 
} 
 
.dormant { 
 
    fill: purple; 
 
}

当构造节点,我想申请,其名称与状态

.style("fill", function (d) { return d3.select(this).classed(d.status, true); })

匹配类

但是,这没有任何影响。

下面是完整的代码

\t \t var links = [ 
 
      {source: "Start", target: "Dept Approver", type: "approve", staus: "completed"}, 
 
\t \t {source: "Dept Approver", target: "Amount>20", type: "approve", staus: "completed"}, 
 
\t \t {source: "Amount>20", target: "Div Approver", type: "approve", staus: "completed"}, 
 
\t \t {source: "Amount>20", target: "Section Approver", type: "approve", staus: "completed"}, 
 
\t \t {source: "Amount>20", target: "Dept Approver", type: "reject", staus: "completed"}, 
 
\t \t {source: "Div Approver", target: "End", type: "approve", staus: "dormant"}, 
 
\t \t {source: "Section Approver", target: "End", type: "approve", staus: "pending"} 
 
\t \t ]; 
 
\t \t 
 
\t 
 
\t \t var nodes = {}; 
 

 
\t \t // Compute the distinct nodes from the links. 
 
\t \t links.forEach(function(link) { 
 
\t \t link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); 
 
\t \t link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); 
 
\t \t }); 
 

 
\t \t var width = 960, 
 
\t \t \t height = 500; 
 

 
\t \t var force = d3.layout.force() 
 
\t \t \t .nodes(d3.values(nodes)) 
 
\t \t \t .links(links) 
 
\t \t \t .size([width, height]) 
 
\t \t \t .linkDistance(80) 
 
\t \t \t .charge(-300) 
 
\t \t \t .on("tick", function(d) { 
 
\t \t \t \t path.attr("d", function(d) { 
 
\t \t \t \t \t var dx = d.target.x - d.source.x, 
 
\t \t \t \t \t dy = d.target.y - d.source.y, 
 
\t \t \t \t \t dr = 0; 
 
\t \t \t \t \t return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
 
\t \t \t \t }); 
 
\t \t \t \t circle.attr("transform", function(d) { 
 
\t \t \t \t \t return "translate(" + d.x + "," + d.y + ")"; 
 
\t \t \t \t }); 
 
\t \t \t \t text.attr("transform", function(d) { 
 
\t \t \t \t \t return "translate(" + d.x + "," + d.y + ")"; 
 
\t \t \t \t }); 
 
\t \t \t }) 
 
\t \t \t .start(); 
 

 
\t \t var svg = d3.select("#chart").append("svg") 
 
\t \t \t .attr("width", width) 
 
\t \t \t .attr("height", height); 
 

 
\t \t // Per-type markers, as they don't inherit styles. 
 
\t \t svg.append("defs").selectAll("marker") 
 
\t \t \t .data(["approve", "reject"]) 
 
\t \t .enter().append("marker") 
 
\t \t \t .attr("id", function(d) { return d; }) 
 
\t \t \t .attr("viewBox", "0 -5 10 10") 
 
\t \t \t .attr("refX", 15) 
 
\t \t \t .attr("refY", -1.5) 
 
\t \t \t .attr("markerWidth", 8) 
 
\t \t \t .attr("markerHeight", 8) 
 
\t \t \t .attr("orient", "auto") 
 
\t \t .append("path") 
 
\t \t \t .attr("d", "M0,-5L10,0L0,5"); 
 

 
\t \t var path = svg.append("g").selectAll("path") 
 
\t \t \t .data(force.links()) 
 
\t \t .enter().append("path") 
 
\t \t \t .attr("class", function(d) { return "link " + d.type; }) 
 
\t \t \t .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); 
 

 
\t \t var circle = svg.append("g").selectAll("circle") 
 
\t \t \t .data(force.nodes()) 
 
\t \t .enter().append("circle") 
 
\t \t \t .attr("r", 8) 
 
      .style("fill", function (d) { return d3.select(this).classed(d.status, true); }) 
 
\t \t \t .call(force.drag); 
 

 
\t \t var text = svg.append("g").selectAll("text") 
 
\t \t \t .data(force.nodes()) 
 
\t \t .enter().append("text") 
 
\t \t \t .attr("x", ".40em") 
 
\t \t \t .attr("y", 12) 
 
\t \t \t .text(function(d) { return d.name; }); 
 

 
     var drag = force.drag() 
 
      .on("dragstart", function(d) { 
 
\t \t \t \t \t d3.select(this).classed("fixed", d.fixed = true); 
 
\t \t \t \t });
.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>

能有人帮我纠正吗?

回答

1

您的代码有几个问题。

  1. 您在links在你的例子拼错"status""staus"
  2. 您试图根据节点的状态对节点着色,但由于您提供的节点数据来自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); 
    }) 
    

这给出了下面的输出(完整的小提琴here)。

screenshot where nodes are colored by status

+0

非常感谢您的帮助 – kayasa