Changing the colors of each of the Stacked Bar chart with different Color in D3

This involved the assignment of different colors to each bars of the stacked bar charts as currently there is only single color in all the four bars and colors are changing in the stacked one but I am trying to assign different colors to all the four bars as well the stacked value.

Here is the code

    var margin = {
            top: 20,
            right: 160,
            bottom: 35,
            left: 30
          };

          var width = 960 - margin.left - margin.right,
            height = 600 - margin.top - margin.bottom;

          var svg = d3.select("body")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


          /* Data in strings like it would be if imported from a csv */

          var data = [{
              year: "A",
              redDelicious: "10",
              mcintosh: "5",
              oranges: "19"
            }, {
              year: "B",
              redDelicious: "12",
              mcintosh: "0",
              oranges: "15"
            }, {
              year: "C",
              redDelicious: "05",
              mcintosh: "0",
              oranges: "28"
            }, {
              year: "D",
              redDelicious: "14",
              mcintosh: "0",
              oranges: "12"
            },

          ];
          $("#btn").on("click", function(){
            d3.selectAll("svg > g > g").remove();
            data[1].mcintosh = (Number(data[1].mcintosh) + 1).toString();
            console.log(1,data);
            update();
          });
          update();
    function update(){
          var orangeData = data.map(function(d) {
            return {
              year: d.year,
              oranges: +d.oranges
            }
          });
          console.log(orangeData)



          // Transpose the data into layers
          var dataset = d3.layout.stack()(["redDelicious", "mcintosh"].map(function(skillset) {
            return data.map(function(d) {
              return {
                x: d.year,
                y: +d[skillset]
              };
            });
          }));
          console.log(dataset)

          // Set x, y and colors
          var x = d3.scale.ordinal()
            .domain(dataset[0].map(function(d) {
              return d.x;
            }))
            .rangeRoundBands([10, width - 10], 0.02);

          var y = d3.scale.linear()
            .domain([0, d3.max(dataset, function(d) {
              return d3.max(d, function(d) {
                return d.y0 + d.y;
              });
            })])
            .range([height, 0]);

          var colors = ["#b33040", "#d9d574"];
           var backcolors = ["red", "blue","green","pink"];


          // Define and draw axes
          var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left")
            .ticks(5)
            .tickSize(-width, 0, 0)
            .tickFormat(function(d) {
              return d
            });

          var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");
          //  .tickFormat(d3.time.format("%Y"));

          svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);

          svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

            // Creating the Average Bar for the Semester
            svg.selectAll(".bar1").data(orangeData).enter().append("g")
            .attr("class", "bar1").append("rect")
            .attr("x", function(d) {
              return x(d.year) ; // center it
            })
            .attr("width", x.rangeBand()) // make it slimmer
            .attr("y", function(d) {
              return y(d.oranges);
            })
            .attr("height", function(d) {
              return height - y(d.oranges);
            });



          // Create groups for each series, rects for each segment in Stacked Bar 
          var groups = svg.selectAll("g.cost")
            .data(dataset)
            .enter().append("g")
            .attr("class", "cost")
            .style("fill", function(d, i) {
              return colors[i];
            });

          var rect = groups.selectAll("rect")
            .data(function(d) {
              return d;
            })
            .enter()
            .append("rect")
            .attr("x", function(d) {
              return x(d.x)  + 20 ;
            })
            .attr("y", function(d) {
              return y(d.y0 + d.y);
            })
            .attr("height", function(d) {
              return y(d.y0) - y(d.y0 + d.y);
            })
            .attr("width", x.rangeBand() -40 );
            }

Here is the working fiddle

Answers:

Answer

First, set your colours array:

var colors = ['#7fc97f','#beaed4','#fdc086','#ffff99','#386cb0','#f0027f','#bf5b17','#666666'];

Then, in your rectangles (not in your groups), set the fill of each bar using the parent's index:

.attr("fill", function(d, i, j) {
      return colors[(j*4)+i];
 });

Here, the magic number "4" is the number of groups. Change it accordingly (if you create more bars).

Here is your fiddle: https://fiddle.jshell.net/747beqqc/

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.