4

enter image description here

I am using D3 api for a graph where a couple of nodes are forming from a parent node i want to color the nodes of the whole graph in a manner that each parent node has a fixed color and the child nodes has different color i.e a root node always have red color and the left child is blue and the right one is green and if only one child is there it is green .I am using this api ,,

<!DOCTYPE html>
<html>
 <head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?1.27.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.27.1"></script>
    <style type="text/css">

 line.link {
  stroke: #ccc;
}

circle.node {
 fill: #000;
 stroke: #fff;
 stroke-width: 1.5px;
}

    </style>
  </head>
  <body>
    <script type="text/javascript">

   var w = 960,
  h = 500,
  r = d3.scale.sqrt().domain([0, 20000]).range([0, 20]);

 var force = d3.layout.force()
.gravity(.01)
.charge(-120)
.linkDistance(60)
.size([w, h]);

var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);

d3.xml("flare.xml", "application/xml", function(xml) {
  var nodes = self.nodes = d3.select(xml).selectAll("*")[0],
    links = self.links = nodes.slice(1).map(function(d) {
      return {source: d, target: d.parentNode};
     });

  force
  .nodes(nodes)
  .links(links)
  .start();

  var link = svg.selectAll("line.link")
  .data(links)
.enter().append("svg:line")
  .attr("class", "link")
  .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; });

  var node = svg.selectAll("circle.node")
  .data(nodes)
  .enter().append("svg:circle")
  .attr("class", "node")
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("r", function(d) { return r(d.textContent) || 5; })
  .call(force.drag);

    force.on("tick", function() {
    nodes[0].x = w / 2;
    nodes[0].y = h / 2;

   link.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; });

      node.attr("cx", function(d) { return d.x; })
     .attr("cy", function(d) { return d.y; });
     });
    });

    </script>
  </body>
 </html>

can anyone help me

VividD
  • 10,456
  • 6
  • 64
  • 111
lucifer
  • 2,297
  • 18
  • 58
  • 100

1 Answers1

5

SVG has its own CSS properties, one of which being fill. It sets the fill color of an SVG element.

Here is how you use it with D3:

var node = svg.selectAll("circle.node")
  .data(nodes)
  .enter().append("svg:circle")
  .style("fill", function (d) { return '#1f77b4'; })
  .attr("class", "node")
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("r", function(d) { return r(d.textContent) || 5; })
  .call(force.drag);

Here the color value (#1f77b4) will be the same for all nodes. If you want to color your nodes with a specific algorithm, D3 ships with predefined categorical color scales.

Edit: Here is a related SO question. One of its answers has a good custom ordinal color scale example.

Community
  • 1
  • 1
Thibaud Colas
  • 1,248
  • 1
  • 16
  • 24
  • thanks for your answer it is working i get all nodes in blue color..if i want to add custom color in nodes i will have to put a condition write? – lucifer Dec 08 '13 at 04:01
  • Yes. You have to decide how each node will be colored by changing the return value in `.style("fill", function (d) { return '#1f77b4'; })`. You could directly put the color in your XML file, or map colors to values of attributes already in your XML (see [example](http://stackoverflow.com/questions/13006712/d3js-fill-color/13013162#13013162)). – Thibaud Colas Dec 08 '13 at 04:21
  • i can not change the data here or can not use an XML file i have to put a condition that will decide which node is root and which is child – lucifer Dec 08 '13 at 05:06
  • var nodes = svg.selectAll("circle.node") .data(force.nodes()) .enter().append("circle") .attr("class", "node") .attr("r", 8) //.style("fill", function(d,i) { return d3.scale.category20(i); }) .style("fill",function(d,i){ return d3.scale.category20(i); }) .call(force.drag); i am doing this can you help from here?? – lucifer Dec 08 '13 at 17:40
  • 1
    That's the way to go, but `d3.scale.category20(i)` won't work. It should be `d3.scale.category20()(i)`, because `d3.scale.category20()` returns the scale function. – Thibaud Colas Dec 08 '13 at 17:43
  • thanks for your help it worked fine ,,can you help a little about this arrowheads??? – lucifer Dec 09 '13 at 08:59
  • You are using SVG lines for the edges, so [this thread](http://stackoverflow.com/questions/12680166/how-to-use-an-arrow-marker-on-an-svg-line-element) may help you. Good luck. – Thibaud Colas Dec 09 '13 at 12:18