Gradient Color in a Treemap for D3

Gradient color in a treemap for D3

It sounds like you want a color scale applied to each box in the treemap. This is pretty simple:

var colorScale = d3.scale.linear()
.range(['lightgreen', 'darkgreen']) // or use hex values
.domain([minValue, maxValue]);

Then apply with

.style("fill", function(d) { return colorScale(d.value)});

The hard part here is determining the domain - depending on how your data is structured, you might need to walk the tree to collect it. In the Bostock example, you can get the extent of the data after you've joined it to the elements like this:

d3.extent(d3.selectAll('rect.child').data(), function(d) { return d.value; });

Color gradient in d3 tree map based of another value

Define your scale's domain with your leaves' parent nodes:

color = d3.scaleOrdinal()
.domain(treemap(data).leaves().map(d => {return d.parent.data.name}))
.range(d3.schemeCategory10)

And fill your leaf nodes with the corresponding gradient of color from the range, indexed by data value, applied to the opacity attribute:

.attr("fill", d => { return color(d.parent.data.name) })
.attr("fill-opacity", d => {
let min = d3.min(root.leaves().map(leaf => leaf.data.value))
let max = d3.max(root.leaves().map(leaf => leaf.data.value))
return (d.data.value-min)/(max-min)
})

You get only 3 colors, because you have only 3 parent nodes, but the colors correspond to the those in the docs

See example

EDITED per comment

How to change the colors based on the select value d3.js v4

Ok. I figured the way if anyone would have the same requirement.

First, I created select options and provided values such as, green and blue
Second, using jquery I change grab the value $('#colorChoice').change(function()) inside of the function i select all rect by selectAll('rect') and provide the style .style("fill", function(d){}) whatever color you want can be specified inside of the function and return

D3.js: how to decide both the area and the color of each square by the size of each content in treemap?

To just focus on your original question, how to make fill colours dependent on the data:

What you want is a function to convert a numerical data value (the value associated with the size of your treemap rectangles) into a colour value, in such a way that colours form a smooth transition between two extremes representing the extremes of the data.

The ordinal colour scales don't do this, they're intended to create distinct colour values for contrast.

To create a linear relationship to the data, you'll need a linear scale to convert the data values into an appropriate range for the colour functions, and then you'll need a function to create the actual colour value that varies according to that number.

There are three sets of functions within d3 that create variations on colour:

  • The colour interpolator functions, which are used internally when you specify a transition for a colour property, are initialized with a start colour and an end colour, and return a function that will take values between 0 and 1 and return a colour the appropriate distance between the start and end values.

  • The create colour functions take three numbers as either a RGB, HSL, or L*a*b colour definition, and return the hex value; you can specify any of these numbers with a linear scale to create a scale of colours that vary only one that one dimension (hue, lightness, redness, whatever).

  • The brighter/darker colour functions, which are initialized with one colour value and then can be used to create modifications of it. However, they can only modify the brightness, not the hue.

The colour interpolator functions are much more flexible, so that's what I'd recommend using. There are different versions depending on whether you want the interpolation to vary according to RGB colour space or HSL or L*a*b colour space. I'd recommend using HSL for intuitive transitions that won't ever stray outside of visible colours.

Again, the interpolator function will expect a value between 0 and 1, so you'll need to use a linear scale to convert your data values to that range.

var colourScale = d3.scale.linear()
.domain([0, maxArea])
.range([0,1]);
var colourInterpolator = d3.interpolateHsl("blue", "red")
//colours can be specified as any CSS colour string

function colourFunction(d) {
return colourInterpolator( colourScale( d.area ) );
}

/* and then later */
rect.attr("fill", colourFunction);

If the rectangle's area is equal to the maximum, the scale will convert that to a value of 1, and the colour interpolator will convert that to the final colour of the transition, red. If the area is almost zero, the scale value will be almost zero, and the colour will be almost blue.

Shaded interactive D3 treemap - support for people who are colorblind?

It‘s always fair to have two different characteristics on things that are important to be distinguished. That‘s why links receive different color and underline by default.
I think it‘s a good idea to use hatching as a second characteristic. So you could add e.g.

background-image { repeating-linear-gradient(
55deg,
transparent,
transparent 15px,
rgba(255,255,255,.5) 15px,
rgba(255,255,255,.5) 20px
); }

to your boxes and fiddle around with angle and pixels for different box types.

Could look like this in the end:

Sample Image

Most importantly, please increase font / background contrast! This will help visually impaired more than all hatching…

Hatching was taken from http://lea.verou.me/css3patterns/#diagonal-stripes



Related Topics



Leave a reply



Submit