34

I am trying to use NVD3 http://nvd3.org/livecode/#codemirrorNav a pie chart. But i want to change the default color. How do i change the color. i am not able to do it.

user2315392
  • 343
  • 1
  • 3
  • 4

7 Answers7

50

If you want to use specific color for pie

chart.color(function(d){
    return d.data.color
});

Then, organize your data as:

[
  {
    key: "Cumulative Return",
    values: [
      { 
        "label": "One",
        "value" : 29.765957771107,
        "color" : "#8c564b"
      } ,
      { 
        "label": "Three",
        "value" : 32.807804682612,
        "color" : "#e377c2"
      } 
    ]
  }
]
Christopher Chiche
  • 14,409
  • 9
  • 55
  • 94
nicky
  • 3,581
  • 7
  • 33
  • 41
  • 1
    Great tip, saved me quite some time. Thank you. – Javier Constanzo Dec 20 '13 at 19:04
  • 1
    This is the best answer, it utilized d3 functionality and because in my particular case, the color values are stored on a database, so I can't hard code them on my js file like in Christopher's answer. – svarog Apr 14 '15 at 12:48
44

You can add colors by passing an array to the 'color()' option. So just add:

.color(['blue', 'green', 'yellow'])

If you want to use these colors for 3 elements.

Note: if you have more than 3 elements, then some colors will be used multiple times.

Christopher Chiche
  • 14,409
  • 9
  • 55
  • 94
27

To use your own colours you will have to override the existing colours, I prefer not to tinker around with the original code.

So this is what I did.

    var myColors = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"];
    d3.scale.myColors = function() {
        return d3.scale.ordinal().range(myColors);
    };

    nv.addGraph(function() {
      var chart = nv.models.pieChart()
          .x(function(d) { return d.label })
          .y(function(d) { return d.value })
          .showLabels(true).color(d3.scale.myColors().range());

        d3.select("#chart svg")
            .datum(data)
          .transition().duration(1200)
            .call(chart);

      return chart;
    });

All I did was add .color(d3.scale.myColors().range())


UPDATE :

Check answer by Christopher Chiche, for the perfect solution.

.color(['blue', 'green', 'yellow'])

Hope this helps.

shabeer90
  • 5,051
  • 3
  • 44
  • 64
  • i am using this, but i have a problem, when i change the metrics of the chart and redraw it (with new colors, i have a function that computes colors based on the label), the chart draws wrong colors. when i click to show/hide some values, sometimes are redrawn like they should be, sometimes are redrawn wrong. Do you have some idea why that is so?this happens only on pie charts. – Nikola Aug 29 '13 at 07:51
  • I'll try my best to explain this, say for example you have 5 categories at load, the chart takes the first 5 colours of the array. So your clour 1 will always be assigned to the first element of the data. This may not the the best way, but try having an array and map the color against the pies, so you can use the onclick functions on the ledgend and get which elements are active and which are not, its returns an array with the positions, you can use that to filter out what colours you need to be pass when you redraw the chart. – shabeer90 Aug 29 '13 at 20:33
  • no no the problem is that i want to do smth else, for example i a set of data with different fields in it for ex. (ip, country, and some more), when i show the ip metric (i have 4 different ips) i group the data, create the colors for the pie and render it. when i change from ip metric to country, i again aggregate the data ( i get 10 different countries) i create the colors for them, and then redraw the pie, at first render its ok, it takes the new colors (these colors have nothing to do with the colors of the ip pie), but when i hide or show parts of the pie, colors from the ip pie are shown – Nikola Aug 30 '13 at 07:27
  • I don't understand why you are creating a `d3.scale` instead of just use the original array as the argument for the colors method. – Paulo Scardine Oct 21 '13 at 18:37
  • @PauloScardine - I agree with you, when I replied to this, I did not have much knowledge, Christopher Chiche has the perfect answer. I have upvoted his answer. Will update mine. – shabeer90 Oct 22 '13 at 07:29
0

Here is a note that got me, I was setting chart.color inside of nv.addGraph, this was not working correctly and would instead use the defaults. I then set it outside of this and it worked fine.

Chris Stephens
  • 2,106
  • 2
  • 16
  • 21
0

I use .color(function(d) {return [d.value > 0 ? 'blue' : 'red']}); to make it change color depending on data value.

Hope this help someone.

Manh Tai
  • 156
  • 1
  • 6
0

Here is the Typescript solution which is similar to the JS version. Let's say you want a Top 10 of your results with 10 different colors :

Here i'll give you the example that work for my PieChart or MultiBarChart

  • Create a global array of color like colors = ["#D9D9D9", "#4B11A6", ....];
  • The data has to be formatted in an Object : myGraph { key: "Title", values : { streams to push }}
  • Then when creating your data table just push the color for each stream :

let stream = {}; let data = []; let i=0;

dataTable.forEach((period) => {
    stream = { 'label': period.key, 'value': period.value, 'color': this.colors[i] };

if(period.value !== 0) {
 data.push(stream);}
 i++;
});
this.myGraph = data;

The if condition is just there to prevent empty piece in the graph

0

I have used below concept to add custom color:

// for define variable of custom colors 
var colors = ["red", "green", "blue"];
...
chart {
    color: function(d,i){
        return (d.data && d.data.color) || colors[i % colors.length]
    }
}

For dynamic color based on JSON Data just add New json obj color such as below concept..

// or set custom colors directly in the data
data = [{
        key: "One",
        y: 5,
        color: "yellow"
    },{
        key: "Two",
        y: 2,
        color: "gray"
    },{
        key: "Three",
        y: 9
    },
     ...
];
SantoshK
  • 1,531
  • 13
  • 20