How do I change symbol type colors on D3js?

1.9k views Asked by At

I want to change colors of the symbol types on my D3 code? I am not sure how to make my var color = d3.scale.linear() work. I am trying to randomize D3 symbol types but want to differentiate them by colors.


<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var w = 1260, //define the canvas
    h = 500,
    nodes = [], //nodes are shapes
    node; //return node..data

var color = d3.scale.linear()
    .domain ([0, h])
    .range ([0, w]);

//creating canvas with svg property
var canvas = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);

//https://github.com/mbostock/d3/wiki/Force-Layout#force
var force = d3.layout.force()
    .nodes(nodes)
    .links([]) //links are between nodes
    .size([w, h]);

force.on("tick", function(d) {
  canvas.selectAll("path")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});

setInterval(function(){

  // Add a new random shape.
  nodes.push({
    type: d3.svg.symbolTypes[~~(Math.random() * d3.svg.symbolTypes.length)], //pushing symbol types
    size: Math.random() * 300 + 100 //randomize size
  });

  // Restart the layout.
  force.start();

  canvas.selectAll("path")
      .data(nodes)
    .enter().append("path")
      .attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
      })
      .attr("d", d3.svg.symbol()
        .size(function(d) { return d.size; })
        .type(function(d) { return d.type; }))
        .style("fill", "#69d3bf")
        .style("stroke", "#253544")
        .style("stroke-width", "1.5px")
        .call(force.drag);
}, 10); //1000 is time 

</script>
1

There are 1 answers

0
VividD On BEST ANSWER

This is your example, just slightly modified to be a runnable code snippet:

var w = 400;
var h = 300;

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

var nodes = [];

//https://github.com/mbostock/d3/wiki/Force-Layout#force
var force = d3.layout.force()
  .nodes(nodes)
  .links([]) //links are between nodes
  .size([w, h]);

force.on("tick", function(d) {
  svg.selectAll("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });
});

setInterval(function() {

  // Add a new random shape.
  nodes.push({
    type: d3.svg.symbolTypes[~~(Math.random() * d3.svg.symbolTypes.length)], //pushing symbol types
    size: Math.random() * 300 + 100 //randomize size
  });

  // Restart the layout.
  force.start();

  svg.selectAll("path")
    .data(nodes)
    .enter().append("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    })
    .attr("d", d3.svg.symbol()
      .size(function(d) {
        return d.size;
      })
      .type(function(d) {
        return d.type;
      }))
    .style("fill", "#69d3bf")
    .style("stroke", "#253544")
    .style("stroke-width", "1.5px")
    .call(force.drag);

}, 3000); //1000 is time
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

enter image description here

Note that there are only six symbols supported.

I am going to present two solutions, to get you started. You can adjust them to suit your needs, and, of course, with the help of documentation.

First solution

Key portions of the code:

.style("fill",  function(d) {
  console.log(d);
  var symbolIndex = 0;
  for(var i=0; i<d3.svg.symbolTypes.length; i++){
    if(d.type == d3.svg.symbolTypes[i])
      symbolIndex=i;
  };
  return color(symbolIndex);
})

color is defined as linear scale from yellow to violet:

var color = d3.scale.linear()
    .domain ([0, d3.svg.symbolTypes.length-1])
    .range (["yellow", "violet"]);

var w = 400;
var h = 300;

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

var nodes = [];
var color = d3.scale.linear()
    .domain ([0, d3.svg.symbolTypes.length-1])
    .range (["yellow", "violet"]);

//https://github.com/mbostock/d3/wiki/Force-Layout#force
var force = d3.layout.force()
  .nodes(nodes)
  .links([]) //links are between nodes
  .size([w, h]);

force.on("tick", function(d) {
  svg.selectAll("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });
});

setInterval(function() {

  // Add a new random shape.
  nodes.push({
    type: d3.svg.symbolTypes[~~(Math.random() * d3.svg.symbolTypes.length)], //pushing symbol types
    size: Math.random() * 300 + 100 //randomize size
  });

  // Restart the layout.
  force.start();

  svg.selectAll("path")
    .data(nodes)
    .enter().append("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    })
    .attr("d", d3.svg.symbol()
      .size(function(d) {
        return d.size;
      })
      .type(function(d) {
        return d.type;
      }))
    .style("fill",  function(d) {
      console.log(d);
      var symbolIndex = 0;
      for(var i=0; i<d3.svg.symbolTypes.length; i++){
        if(d.type == d3.svg.symbolTypes[i])
          symbolIndex=i;
      };
      return color(symbolIndex);
    })
    .style("stroke", "#253544")
    .style("stroke-width", "1.5px")
    .call(force.drag);

}, 3000); //1000 is time
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

enter image description here

Second solution

If you want to explicitly set color for each symbol, you can use this:

var color = d3.scale.linear()
    .domain ([0, 1, 2, 3, 4, 5])
    .range (["red", "blue", "green", "tan", "gray", "orange"]);

var w = 400;
var h = 300;

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

var nodes = [];
var color = d3.scale.linear()
    .domain ([0, 1, 2, 3, 4, 5])
    .range (["red", "blue", "green", "tan", "gray", "orange"]);

//https://github.com/mbostock/d3/wiki/Force-Layout#force
var force = d3.layout.force()
  .nodes(nodes)
  .links([]) //links are between nodes
  .size([w, h]);

force.on("tick", function(d) {
  svg.selectAll("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });
});

setInterval(function() {

  // Add a new random shape.
  nodes.push({
    type: d3.svg.symbolTypes[~~(Math.random() * d3.svg.symbolTypes.length)], //pushing symbol types
    size: Math.random() * 300 + 100 //randomize size
  });

  // Restart the layout.
  force.start();

  svg.selectAll("path")
    .data(nodes)
    .enter().append("path")
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    })
    .attr("d", d3.svg.symbol()
      .size(function(d) {
        return d.size;
      })
      .type(function(d) {
        return d.type;
      }))
    .style("fill",  function(d) {
      console.log(d);
      var symbolIndex = 0;
      for(var i=0; i<d3.svg.symbolTypes.length; i++){
        if(d.type == d3.svg.symbolTypes[i])
          symbolIndex=i;
      };
      return color(symbolIndex);
    })
    .style("stroke", "#253544")
    .style("stroke-width", "1.5px")
    .call(force.drag);

}, 3000); //1000 is time
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

enter image description here