Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple way to color bar chart #200

Closed
textplusdata opened this issue Jun 15, 2013 · 17 comments
Closed

Simple way to color bar chart #200

textplusdata opened this issue Jun 15, 2013 · 17 comments
Labels

Comments

@textplusdata
Copy link

Hi.
I'm trying to color a stacked bar chart, and I've looked at some other complicated solutions, but I need something simple!

I am trying this which seems to be a hotch-potch of code. I've tried the selectAll with about every combination: rect.bar, rect.stack, g.rect.bar etc.

.renderlet(function(chart){
       chart.selectAll("g.rect.stack").attr("fill", function(d){
            if(d.key == "a) Free")   
         return "green-bar";
    else if(d.key == "b) Partly Free")
         return "yellow-bar";
     else if(d.key == "c) Not Free")
         return "red-bar"; 
        });})

Anyone help me get over this?

@textplusdata
Copy link
Author

Hi,

I ended up solving this using the css way. Here it is summarised for anyone else trying to do it:

(Assumes trying to show stacks for three categories by year, totalling their "value", by year "yearDimension")

var category1sum = yearDimension.group().reduceSum(function(d){return d.category=="category1"?d.value:0;});
var category2sum = yearDimension.group().reduceSum(function(d){return d.category=="category2"?d.value:0;});
var category3sum = yearDimension.group().reduceSum(function(d){return d.category=="category3"?d.value:0;});

This means that it creates a bunch of zero values in a stack so that stack0 always remains the same colour, even if there are no values in that stack (the bottom stack would normally default to stack0, even if that botom stack was category1 rather than category2
Then for the chart I did this:

.dimension(yearDimension)
                    .group(category1Sum)
                    .stack(category2Sum)
                    .stack(category3Sum)

And then in the css, this, where stack0 = category1, stack1= category2 and stack2=category3

.dc-chart rect.stack0 {
    fill: green;
    stroke: none;
}

.dc-chart rect.stack1 {
    fill: yellow;
    stroke: none;
}

.dc-chart rect.stack2 {
    fill: red;
    stroke: none;
}

If anyone would care to share an easier way to do it direct within dc.js I' be keen to hear it!

@NickQiZhu
Copy link
Contributor

The renderlet solution should work however you need to set the fill to color instead of css class:

.renderlet(function(chart){
       chart.selectAll("g.rect.stack").attr("fill", function(d){
            if(d.key == "a) Free")   
         return "green";
    else if(d.key == "b) Partly Free")
         return "yellow";
     else if(d.key == "c) Not Free")
         return "red"; 
        });})

Also make sure remove fill setting in your css class since in some browser the css class take precedence over fill attribute.

@claud-alex
Copy link

In case anyone still runs into something like this, Nick's solution works fine for me but only operating on the chart selection with "style" rather than "attr", i.e. chart.selectAll("g.rect.stack").style("fill", etc.
No idea why, but it solved issue for me.

@rajeshr6r
Copy link

rajeshr6r commented Apr 29, 2016

I was able to create multi-series bar chart with a twist of the renderlet technique explained above .

renderlet(function (chart) {
                        chart.selectAll('rect.bar').each(function(d){                           
                        d3.select(this).attr("fill",                            
                        (function(d){
                            var colorcode ="grey"
                                                 if(d.x[1] === "Zone1")   
                                                    colorcode ="#ff7373";
                                            else if(d.x[1] === "Zone2")
                                                    colorcode ="#b0e0e6";
                                            else if(d.x[1] === "Zone3")
                                                    colorcode ="#c0c0c0";
                                            else if(d.x[1] === "Zone4")
                                                    colorcode ="#003366";
                                            else if(d.x[1] === "Zone5")
                                                    colorcode ="#ffa500";
                                            else if(d.x[1] === "Zone6")
                                                    colorcode ="#468499";
                                            else if(d.x[1] === "Zone7")
                                                    colorcode ="#660066";   
                                                return colorcode;

                                   }))
                        }); 

            });

Note : I was using a dimension with 2 values for the series .

Thanks to all comments and feel free to use this. I think with some development over this technique could yield us a multi-bar chart within the dc.charts library .

@ozermm
Copy link

ozermm commented May 27, 2016

Thank you @rajeshr6r for this great contribution. For some reason, it did not work for me. Do you have a working example? Thanks.

@rajeshr6r
Copy link

Hi

I do Hv one . Will share as soon as I get to my laptop . I'm hoping you are us dc 2.0

Sent from my iPhone

On 28-May-2016, at 12:45 AM, ozermm [email protected] wrote:

Thank you @rajeshr6r for this great contribution. For some reason, it did not work for me. Do you have a working example? Thanks.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@gordonwoodhull
Copy link
Contributor

Note there are also a couple of PRs for grouped bar charts, if that's the intended purpose. Would appreciate some reviews of them. #1043 #984

@ozermm
Copy link

ozermm commented Jun 3, 2016

Thank you @gordonwoodhull!

@ozermm
Copy link

ozermm commented Jun 3, 2016

Hi again Rajesh,

I will be very happy if you can share you working bar chart example.

Thanks,

Murat

From: Rajesh Rajamani [mailto:[email protected]]
Sent: Friday, May 27, 2016 9:48 PM
To: dc-js/dc.js
Cc: ozermm; Comment
Subject: Re: [dc-js/dc.js] Simple way to color bar chart (#200)

Hi

I do Hv one . Will share as soon as I get to my laptop . I'm hoping you are us dc 2.0

Sent from my iPhone

On 28-May-2016, at 12:45 AM, ozermm [email protected] wrote:

Thank you @rajeshr6r for this great contribution. For some reason, it did not work for me. Do you have a working example? Thanks.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub #200 (comment) , or mute the thread https://github.com/notifications/unsubscribe/ASiVRCultKLNWF32GVfHrJTDiuRa7m7tks5qF57AgaJpZM4AvNfo . https://github.com/notifications/beacon/ASiVRDvdddTQ8E7fq4oRXEAheLBhYjedks5qF57AgaJpZM4AvNfo.gif

@nitinsurana
Copy link

nitinsurana commented Jun 24, 2016

The renderlet solution does not work for me. Tried with both .attr & .style. The callback function never gets called.
I'm using dc 2.0.0-beta.30

@nitinsurana
Copy link

The below works instead :

chart.selectAll("g rect").style("fill", function (d) {
  if (d.layer === "Advanced")
   return "green";  //return "#898989";

@nitinsurana
Copy link

nitinsurana commented Jun 24, 2016

renderlet solution creates a flickering effect. Still working to figure out how to change legend colors.
Is there any way to use colorAccessor to set the stacked bar color ?

@gordonwoodhull
Copy link
Contributor

Use pretransition instead of renderlet to avoid the flicker.

@nitinsurana
Copy link

nitinsurana commented Jun 24, 2016

Thanks @gordonwoodhull , works like a charm.

Anyone looking, here's the no flickering solution with bar color, legend color on pretransition.

var colorMap = {
                "Adv": "#006837",
                "Pro": "#a6d96a",
                "Basic": "#fee08b"
            };


.on('pretransition', function (chart) {
                    chart.selectAll("g rect").style("fill", function (d) {
                        return colorMap[d.layer];
                    });
                    chart.selectAll('g.dc-legend-item rect').style('fill', function (d) {
                        return colorMap[d.name];
                    });
                });

@nitinsurana
Copy link

nitinsurana commented Jun 24, 2016

With pretransition or renderlet coloring the layers - the filtering (clicking on bar) doesn't dim all the other unselected bars.

@nitinsurana
Copy link

nitinsurana commented Jun 24, 2016

Here's the solution for clicking on a bar not dimming the other unselected stackedbars.

chart.selectAll("g rect").style("fill", function (d) {
                        return colorMap[d.layer];
                    });
                    chart.selectAll('g.dc-legend-item rect').style('fill', function (d) {
                        return colorMap[d.name];
                    });
                    chart.selectAll("g rect.deselected").style("fill", function (d) {
                        return '#ccc';
                    });

@rassemdev
Copy link

@nitinsurana what is chart.selectAll('g.dc-legend-item rect') for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants