ttmt
ttmt

Reputation: 4984

Stacked bar chart, color bars

I have a codepen here - https://codepen.io/anon/pen/xpBqxG?editors=1010

I'm doing some simple changes to my starter data and then creating a stacked bar chart.

I'm currently coloring each bar the same color but there should be two colors, one for each key in the stacked chart. Each bar should be spilt into two colors.

How do I color each section of the bar the same color.

.style('fill', (d, i) => {
    return colors[i];
});

Upvotes: 1

Views: 162

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

Apply the style to the groups, not to the rectangles:

let layers = layersArea.selectAll('.layer')
    .data(stackedSeries)
    .enter()
    .append('g')
    .attr('class', 'layer')
    .style('fill', (d, i) => {
        return colors[i];
    });

Here is your code with that change only:

let keys = [];

let dataToStack = [];
let totalData = [];

let legendKeys = ['usedInf', 'newInf'];

let w = 800;
let h = 450;

let margin = {
  top: 30,
  bottom: 40,
  left: 50,
  right: 20,
};

let width = w - margin.left - margin.right;
let height = h - margin.top - margin.bottom;

let colors = ['#FF9A00', '#FFEBB6', '#FFC400', '#B4EDA0', '#FF4436'];

let data = [{
  "one": 10,
  "two": 12,
  "three": 18,
  "four": 22,
  "five": 30,
  "six": 44,
  "seven": 25,
  "date": "2015-05-31T00:00:00"
}, {
  "one": 30,
  "two": 42,
  "three": 38,
  "four": 62,
  "five": 90,
  "six": 144,
  "seven": 95,
  "date": "2015-06-30T00:00:00"
}, {
  "one": 30,
  "two": 92,
  "three": 18,
  "four": 100,
  "five": 120,
  "six": 10,
  "seven": 110,
  "date": "2015-07-31T00:00:00"
}, ];

for (let i = 0; i < data.length; i++) {
  dataToStack.push({
    date: data[i]['date'].toString(),
    usedInf: data[i]['one'] + data[i]['two'] + data[i]['three'],
    newInf: data[i]['four'] + data[i]['five'] + data[i]['six']
  });
  totalData.push({
    date: data[i]['date'].toString(),
    total: data[i]['seven']
  });
}

let stack = d3.stack()
  .keys(legendKeys);

let stackedSeries = stack(dataToStack);


let x = d3.scaleBand()
  .domain(dataToStack.map(function(d) {
    return d.date;
  }))
  .rangeRound([0, width])
  .padding(0.05);

let y = d3.scaleLinear()
  .domain([0, d3.max(stackedSeries, function(d) {
    return d3.max(d, (d) => {
      return d[1];
    })
  })])
  .range([height, 0]);

let svg = d3.select('.chart').append('svg')
  .attr('class', 'chart')
  .attr('width', w)
  .attr('height', h);

let chart = svg.append('g')
  .classed('graph', true)
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

let layersArea = chart.append('g')
  .attr('class', 'layers');

let layers = layersArea.selectAll('.layer').data(stackedSeries)
  .enter()
  .append('g')
  .attr('class', 'layer')
  .style('fill', (d, i) => {

    return colors[i];
  });

layers.selectAll('rect')
  .data((d) => {
    return d
  })

  .enter()
  .append('rect')

  .attr('height', (d, i) => {
    return y(d[0]) - y(d[1]);
  })

  .attr('y', (d) => {
    return y(d[1]);
  })

  .attr('x', (d, i) => {
    return x(d.data.date)
  })

  .attr('width', x.bandwidth());

chart.append('g')
  .classed('x axis', true)
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x));

chart.append('g')
  .classed('y axis', true)
  .call(d3.axisLeft(y)
    .ticks(10));
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>

Upvotes: 1

Related Questions