Search code examples
javascriptd3.jscrossfilter

Setting pie chart colors using d3.js


I'm having issues setting pie slice colors using a d3.pieChart. Documentation and examples I've seen use the colors method in combination with an array of hex colors. However, setting this results in my pie chart being colored white (invisible) and every item in the legend becoming black.

I've tried using .colors with an array of five and an array of six colors but the issue persists. Could this be due to some issue with the slicesCap?

Code snippet below, but category10 burns my eyes so any advice on implementing a custom color set would be appreciated!

pie
    .slicesCap(5)
    .legend(dc.legend().gap(3))
    .colors(d3.scale.category10())

Solution

  • Just passing an array of colour values doesn't work because the .colors() function is expecting a color scale like the one created by d3.scale.category10(). Scales are functions which take input data and return a value; in this case, the returned value is one of 10 colours.

    For starters, you could try one of the other d3 built-in colour scales, which don't have as extreme contrast: https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-category20

    If none of those suit, you can make your own scale function with

    var colorScale = d3.scale.ordinal().range([/*array of hex values */]);
    
    pie.colors(colorScale);
    

    You can create the array yourself or use one of the colorBrewer functions.

    If you want to specify particular colours for particular values (instead of just assigning the colours to values in the order they appear) you'll need to (a) specify the domain of the scale as an array of values that matches the order of the range array, and (b) create a helper function that passes in the correct property from your data:

    var colorScale = d3.scale.ordinal().domain(["banana", "cherry", "blueberry"])
                                       .range(["#eeff00", "#ff0022", "#2200ff"]);
    
    pie.colors(function(d){ return colorScale(d.fruitType); });