Colin
Colin

Reputation: 940

d3.js Tree - Assign unique color to parents and their children

I am trying to select a branch of my tree and assign each (parent and two levels of children) a unique color. In my example picture below, parent nodes on the right and leafnodes on the left.

My hierarchical data is three levels deep (name:"Specialty" >> name:"Location" >> LeafNode Containing "Provider", "Location", "Specialty"). I'm thinking I need to check each LeafNode object as the path is drawn -

d.source.children.children.children.Specialty == d.source.children.name

but can't put this together to get it to work. As I draw the paths how might I assign a unique color to each branch?

var link = canvas.selectAll(".link")
            .data(links)
            .enter().append("path")
            .attr("d", diagonal)
            .attr("stroke-width", 1)
            .attr("fill", "none")
            .attr("stroke", function(d){
                return  color(d.target.name == d.target.name ? d : "#111" ); //<< huh?
                })

enter image description here

Upvotes: 0

Views: 2253

Answers (1)

user1614080
user1614080

Reputation: 2874

Working with the data structure generated from the tree layout and your code, you can achieve what you're after with some if else statements; you could probably use the ternary operator, but the code would end up being quite terse and not as clear.

Anyway. as I said above you first need to set up a colour scale, which I've done using

d3.scale.category10()

You then need to calculate the the unique categorical variables for the colour scales domain, this could be done for he Speciality variable. The d3.set can do this for you, but first you need to get an array of of the Speciality variables.

var categoryArray = [];

csv.forEach(function(d,i) {
    categoryArray[i] = d.Specialty;
});

colourDomain = d3.set(categoryArray)
    .values();

Pass the unique array of specialities to the colour scale

colours.domain(colourDomain);

Now, all you need to do is set up the anonymous function to set the colour for the paths strokes. This is quite strait forward, and I'll admit not particularity elegant. Your link variable would become:

var link = canvas.selectAll(".link")
            .data(links)
            .enter().append("path")
            .attr("class", "link")
            .attr("stroke", function(d,i) { 
                if (d.source.depth === 1) {
                    return colours(d.source.name);
                } else if (d.source.depth === 2) {
                    return colours(d.source.parent.name);
                } else if (d.source.depth === 3) {
                    return colours(d.source.Specialty);
                } else {
                    return "white";
                }
            })
            .attr("d", diagonal);

Don't forget to remove the stroke attribute for the link class from your css file either.

Oh, this won't give you a unique colour for each category; it repeats the 10 colours in the scale. This might be OK for your application, otherwise setting up a colour scale to give you unique values is easily done in d3.

Upvotes: 1

Related Questions