Цвет узлов D3 на основе группы, определенной в CSV

1

Мне интересно отображать узлы на 3 разных цветах на основе 3 групп, определенных в файле csv (R = Красный, G = зеленый, B = синий и т.д.). Однако мой код не возвращает 3 разных цвета.

Файл index.html

<!DOCTYPE html>
enter code here'<meta charset="utf-8">
enter code here'<script src="http://d3js.org/d3.v3.js"></script>

 <style>

 path.link {
 fill: none;
 stroke: #666;
 stroke-width: 1.5px;
}

path.link.twofive {
  opacity: 0.25;
}

path.link.fivezero {
  opacity: 0.50;
}

path.link.sevenfive {
  opacity: 0.75;
}

path.link.onezerozero {
  opacity: 1.0;
}

circle {
  fill: #ccc;
  stroke: #fff;
  stroke-width: 1.5px;
}

text {
  fill: #000;
  font: 10px sans-serif;
  pointer-events: none;
}

</style>
<body>
<script>

// get the data
d3.csv("force1.csv", function(error, links) {

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

var width = 960,
    height = 500,
    //color = d3.scale.category20c();

    color = d3.scale.ordinal()
    .domain(["G", "R", "B"])
    .range(["#009933" ,"#FF0000","#0000FD"]);



var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([width, height])
    .linkDistance(60)
    .charge(-300)
    .on("tick", tick)
    .start();

// Set the range
var  v = d3.scale.linear().range([0, 100]);

// Scale the range of the data
v.domain([0, d3.max(links, function(d) { return d.value; })]);

// asign a type per value to encode opacity
links.forEach(function(link) {
    if (v(link.value) <= 25) {
        link.type = "twofive";
    } else if (v(link.value) <= 50 && v(link.value) > 25) {
        link.type = "fivezero";
    } else if (v(link.value) <= 75 && v(link.value) > 50) {
        link.type = "sevenfive";
    } else if (v(link.value) <= 100 && v(link.value) > 75) {
        link.type = "onezerozero";
    }
});



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

// build the arrow.
svg.append("svg:defs").selectAll("marker")
    .data(["end"])      // Different link/path types can be defined here
  .enter().append("svg:marker")    // This section adds in the arrows
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
  .append("svg:path")
    .attr("d", "M0,-5L10,0L0,5");

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

// define the nodes
var node = svg.selectAll(".node")
    .data(force.nodes())
    .enter().append("g")
    .attr("class", "node")
    //.style("fill", function(d) { return color(d.group); })
    .on("click", click)
    .on("dblclick", dblclick)
    .call(force.drag);



// add the nodes
/*node.append("circle")
    .attr("r", 5)
    //.style("fill", function(d) { return color(d.name); });
    .style("fill", function(d) { 
    //if (d.link.group="G")
    //return color(d.green)
    //else if(d.link.group="R")
    return color (d.Red); });*/

//My amendment but style attr is not working
    node.append("circle")
    .attr("r", 5)
    .style("fill", function(d) { return color(d.group); })



// add the text 
node.append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .text(function(d) { return d.name; });


// add the curvy lines
function tick() {
    path.attr("d", function(d) {
        var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy);
        return "M" + 
            d.source.x + "," + 
            d.source.y + "A" + 
            dr + "," + dr + " 0 0,1 " + 
            d.target.x + "," + 
            d.target.y;
    });

    node
        .attr("transform", function(d) { 
            return "translate(" + d.x + "," + d.y + ")"; });
}

// action to take on mouse click
function click() {
    d3.select(this).select("text").transition()
        .duration(750)
        .attr("x", 22)
        .style("stroke", "lightsteelblue")
        .style("stroke-width", ".5px")
        .style("font", "20px sans-serif");
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 16);
}

// action to take on mouse double click
function dblclick() {
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 6);
    d3.select(this).select("text").transition()
        .duration(750)
        .attr("x", 12)
        .style("stroke", "none")
        .style("fill", "black")
        .style("stroke", "none")
        .style("font", "10px sans-serif");
}

});

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

Данные файла force1.csv соответствуют

source,target,value,group
A,B,1.2,G
C,D,1.3,G
B,D,0.2,G
E,A,0.5,G
A,F,0.6,R
G,H,0.5,B
J,A,0.7,R
Теги:
d3.js

1 ответ

0

Несмотря на то, что у вас есть свойство group в исходном массиве links, у вас нет свойства group для узлов.

Решение. Создайте его.

links.forEach(function(link) {
    link.source = nodes[link.source] ||
        (nodes[link.source] = {
            name: link.source,
            group: link.group//create the group property here
        });
    link.target = nodes[link.target] ||
        (nodes[link.target] = {
            name: link.target
        });
    link.value = +link.value;
});

Вот ваш рабочий код:

var links = d3.csv.parse(d3.select("#csv").text())

var nodes = {};

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

var width = 400,
  height = 300,
  //color = d3.scale.category20c();

  color = d3.scale.ordinal()
  .domain(["G", "R", "B"])
  .range(["#009933", "#FF0000", "#0000FD"]);



var force = d3.layout.force()
  .nodes(d3.values(nodes))
  .links(links)
  .size([width, height])
  .linkDistance(60)
  .charge(-300)
  .on("tick", tick)
  .start();

// Set the range
var v = d3.scale.linear().range([0, 100]);

// Scale the range of the data
v.domain([0, d3.max(links, function(d) {
  return d.value;
})]);

// asign a type per value to encode opacity
links.forEach(function(link) {
  if (v(link.value) <= 25) {
    link.type = "twofive";
  } else if (v(link.value) <= 50 && v(link.value) > 25) {
    link.type = "fivezero";
  } else if (v(link.value) <= 75 && v(link.value) > 50) {
    link.type = "sevenfive";
  } else if (v(link.value) <= 100 && v(link.value) > 75) {
    link.type = "onezerozero";
  }
});



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

// build the arrow.
svg.append("svg:defs").selectAll("marker")
  .data(["end"]) // Different link/path types can be defined here
  .enter().append("svg:marker") // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

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

// define the nodes
var node = svg.selectAll(".node")
  .data(force.nodes())
  .enter().append("g")
  .attr("class", "node")
  //.style("fill", function(d) { return color(d.group); })
  .on("click", click)
  .on("dblclick", dblclick)
  .call(force.drag);



// add the nodes
/*node.append("circle")
    .attr("r", 5)
    //.style("fill", function(d) { return color(d.name); });
    .style("fill", function(d) { 
    //if (d.link.group="G")
    //return color(d.green)
    //else if(d.link.group="R")
    return color (d.Red); });*/

//My amendment but style attr is not working
node.append("circle")
  .attr("r", 5)
  .style("fill", function(d) {
    return color(d.group);
  })



// add the text 
node.append("text")
  .attr("x", 12)
  .attr("dy", ".35em")
  .text(function(d) {
    return d.name;
  });


// add the curvy lines
function tick() {
  path.attr("d", function(d) {
    var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = Math.sqrt(dx * dx + dy * dy);
    return "M" +
      d.source.x + "," +
      d.source.y + "A" +
      dr + "," + dr + " 0 0,1 " +
      d.target.x + "," +
      d.target.y;
  });

  node
    .attr("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    });
}

// action to take on mouse click
function click() {
  d3.select(this).select("text").transition()
    .duration(750)
    .attr("x", 22)
    .style("stroke", "lightsteelblue")
    .style("stroke-width", ".5px")
    .style("font", "20px sans-serif");
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 16);
}

// action to take on mouse double click
function dblclick() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 6);
  d3.select(this).select("text").transition()
    .duration(750)
    .attr("x", 12)
    .style("stroke", "none")
    .style("fill", "black")
    .style("stroke", "none")
    .style("font", "10px sans-serif");
}
path.link {
   fill: none;
   stroke: #666;
   stroke-width: 1.5px;
 }
 
 path.link.twofive {
   opacity: 0.25;
 }
 
 path.link.fivezero {
   opacity: 0.50;
 }
 
 path.link.sevenfive {
   opacity: 0.75;
 }
 
 path.link.onezerozero {
   opacity: 1.0;
 }
 
 circle {
   fill: #ccc;
   stroke: #fff;
   stroke-width: 1.5px;
 }
 
 pre {
   display: none;
 }
 
 text {
   fill: #000;
   font: 10px sans-serif;
   pointer-events: none;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<pre id="csv">source,target,value,group
A,B,1.2,G
C,D,1.3,G
B,D,0.2,G
E,A,0.5,G
A,F,0.6,R
G,H,0.5,B
J,A,0.7,R</pre>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню