2

I'm trying to achieve something, and I'm not sure how to approach it.

I have a sample data in data.csv file, like this:

State,p1,p2,p3,p4,p5,p6,p7
AL,0.5,0.5,0.5,1,1,1,1,1,1
AK,1,1,1,1,1,1,1,1,1

Right now, each data value is 100. This looks good but if I change value, my bar chart changes, and it needs to be fixed (x axis should always be 0-7) since it represents data for one week in this case.

The reason why I don't want my chart to depend on data is because data will be used only for color representation, not for the width. So, if value is from 80-100, color it green. But I will figure out it later.

I achieved the desired results in Highcharts, but I prefer D3.

I did it using Highcharts here, and I want to get something like this: http://jsfiddle.net/21udsf05/3/

And after I read this answer, I implemented the same code for my case: http://plnkr.co/edit/SgrHixnqnLHcra3Tv65H?p=preview from @mbostock.

I appreciate any help!

Community
  • 1
  • 1
maliRudolf
  • 95
  • 1
  • 1
  • 9
  • I think it is classic problem of data validation. I can put any value i want in the csv file, but the code should decide wheter the value is valid or within range. So you get the data from the csv and then check the value for x axis if it is in range from 1 to 7. If lower then set it to 1, if bigger then set it to 7. If within 1 and 7 that use that value. As simple as that. – Vlad Dec 16 '16 at 17:11
  • Thank you Vlad. I'm still newbie to D3, so I'm not sure where to put the code. What are you saying totally makes sense. That is exactly what I would need. – maliRudolf Dec 16 '16 at 17:21
  • I wrote bunch of if statements withing data.forEach but it looks so ugly. It works though. – maliRudolf Dec 16 '16 at 18:02
  • What is your question? – Gerardo Furtado Dec 17 '16 at 12:36
  • I think I solved it, but it looks rather silly. I wanted visually to represent data value as they are all the same although they aren't. So, if data value is 0.5, represent it on chart as it is 1. If data value is 0.2, represent it as 1. I got that by writing if else statements in csv() callback. – maliRudolf Dec 17 '16 at 15:09
  • Stacked bar charts are challenging. I can't seem to find a way to color each stack depending on data value. Thank you in advance. @GerardoFurtado – maliRudolf Dec 17 '16 at 16:20
  • Thank you @GerardoFurtado. I still need to have them stacked, but I guess I need to learn D3 more to be able to do what you are suggesting. Thanks again! – maliRudolf Dec 17 '16 at 16:45

1 Answers1

1

Here is my solution:

First, since the most important thing here is colouring the bar according to the value, use a threshold scale:

var color = d3.scale.threshold()
    .domain([0.25, 0.75])
    .range(['green', 'yellow', 'red']);

In this example, if the value is less than 0.25, the bar is green, between 0.25 and 0.75, the bar is yellow, and over 0.75 the bar is red. Anyway, this is just an example for you to get the idea, change the domain and the range the way you want.

After that, put the value in your ages array:

data.forEach(function(d) {
    var y0 = 0;
    d.ages = agesDomain.map(function(name) {
        return {
            name: name,
            value: d[name],
            y0: y0,
            y1: y0 += +d[name]
        };
    });
    d.total = d.ages[d.ages.length - 1].y1;
});

Finally, set all the bars to the same width, and colour them by the value:

state.selectAll("rect")
    .data(function(d) {
        return d.ages;
    })
    .enter().append("rect")
    .attr("height", y.rangeBand())
    .attr("x", function(d, i) {
        return x(i);
    })
    .attr("width", x(1))
    .style("fill", function(d) {
        return color(d.value);
    });

Here is your plunker, I changed the data just to make the chart more diverse: http://plnkr.co/edit/fFwTn9m4MedOL06HxbK8?p=preview

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171