For each node, i have a circle which I color with the help of a function ColorType(d)
:
node.append("circle")
.attr("r", 20)
.attr("y", -25)
.style("fill", function(d) { return ColorType(d); })
.style("stroke-width",0.5)
.style("stroke",'black')
.attr("opacity", "1");
My ColorType
function is
function ColorType(d){
for (var i = 0; i < TypesTab.length; i++) {
if (d.type == TypesTab[i].type) { return ColorAction;}
}
}
in the above function, d.type
is the type of my node (see below the json file strucutre). And TypesTab[i].type
is each of my types stored separately in types, checking if the node type is the same as one of the value of the type in types, if so then applies the ColorAction
which colors the node circle.
and here is the ColorAction
code, which is embedded in each color picker container that is appended to each type in types, the list which is inserted to #filterColor
html dom. so each type has a color picker container which is supposed to color its own type only.
$(document).ready(function () {
$.getJSON("databeta.json", function (obj) {
$('#filterColor').data('types', obj.types.map(function (o) {
// console.log(o.type);
return o.type;
})).append(obj.types.map(function (o) {
return '<li>' + o.type + '<input class="color-picker" type="text"/></li>';
}).join(''));
var data = $('#filterColor').data('types'); //stores all types
mynodes = obj.nodes;
console.log("mynodes : ", mynodes); //array of all my nodes
console.log("mynodes : ", mynodes[3].type); //reading the type of the fourth object in the nodes array
$("#filterColor .color-picker").each(function(){
$(this).spectrum({
color: (function (m, s, c) {
return (c ? arguments.callee(m, s, c - 1) : '#') +
s[m.floor(m.random() * s.length)]
})(Math, '0123456789ABCDEF', 5), //generate random initial color for each container
preferredFormat: "rgb",
showInput: true,
showPalette: true,
showAlpha: true,
palette: [["red", "rgba(0, 255, 0, .5)", "rgb(0, 0, 255)"]],
change: function(color) {
MyNode = d3.select("#node").selectAll(".entreprise").select("circle");
MyNode.style("fill", function(d) {
return d3.rgb(color.toHexString())
});
Coloration = d3.rgb(color.toHexString());
}
});
});
});
});
the problem is that when i hardcode the type in the ColorType(d)
function,
if (d.type == "school") { return ColorAction;}
it successfully colors the school typed nodes only. However, if i want to make it dynamic so that it colors the nodes with the type that the color picker is assigned to, it fails, because I can't make the connection with the each
of o.type
. So the question is to pass the each
of o.type
into the ColorAction
and/or ColorType(d)
so that each container only colors the nodes of its own type.
Here is an unsuccessfull attempt, because it doesn't take into consideration the o.type
and reads the type
in types from a global variable (TypesTab
) that holds all type
s in types:
function ColorType(d){
for (var i = 0; i < TypesTab.length; i++) {
if (d.type == TypesTab[i].type) { return ColorAction;}
}
}
The below is the json structure:
{
"nodes": [
{
"type": "school",
"country": "US",
"name": "saint peter's",
"id": 1006
},
{
"type": "univeristy",
"country": "Brazil",
"name": "saint joseph's",
"id": 1007
}
...
],
"links": [
{
"source": 1006,
"target": 1007,
"value": 20
},
...
],
"types": [
{
"type": "school",
"image": "image01"
},
{
"type": "univeristy",
"image": "image02"
},
{
"type": "company",
"image": "image03"
},
...
]
}
This how I would read / import JSON. Inside the for in is basic, so you would need to change that part to suit your needs.
d3.json("data.json", function (error, data) {
console.log(d3.values(data)); // do this as a check
for (var d in data) {
d.nodes = +d.nodes;
d.links = +d.links;
d.types = +d.types;
}
// svg can go here
})