score:1

Accepted answer

If I understand your question correctly, you want to stack the bars. There are two ways to do it. The first is to do it by hand, as I showed in your other question:

const bars = d3.select('#bars').append('svg').attr('width', 800).attr('height', 200);

var bar1Data = [{
    position: 1,
    label: '70k',
    value: 1000
  },
  {
    position: 2,
    label: '71K - 149K',
    value: 800
  },
];

//sort bars based on value
bar1Data = bar1Data.sort(function(a, b) {
  return d3.descending(a.value, b.value);
})

console.log(d3.sum(bar1Data, d => d.value))

var colorScale = d3.scaleOrdinal()
  .range(["#E8A82B", "#000000"]);

const x = d3.scaleLinear()
  .domain([0, d3.sum(bar1Data, d => d.value)])
  .range([0, 800]);

y = d3.scaleLinear()
  .domain([0, d3.max(bar1Data).value])
  .rangeRound([200])

//Join data to rects

const rects = bars.selectAll('rect')
  .data(bar1Data)

rects
  .attr('width', (d) => {
    return x(d.value)
  })
  .attr('height', 100)
  .attr('x', 20)
  .attr('y', 20)

rects.enter()
  .append('rect')
  .attr('width', (d) => {
    return x(d.value)
  })
  .attr('height', 200)
  .attr('x', function(d, i) {
    // Note that I use `.map` here to take only the `.value` attribute
    // from the data and create an array of numbers. Then I pass it to `x`
    // to be transformed (could also be the other way around if you'd like,
    // so sum(bar1Data.map((e) => x(e.value)), 0, i)
    return x(sum(bar1Data.map((e) => e.value), 0, i));
  })
  .attr('y', 100)
  .style("fill", (d, i) => colorScale(i));

function sum(array, start, end) {
  var total = 0;
  for (var i = start; i < end; i++) total += array[i];
  return total;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="bars"></div>

The second way is to use d3.stack

const bars = d3.select('#bars').append('svg').attr('width', 800).attr('height', 200);
const stack = d3.stack()
  // Each label is a group we want to stack on top of each other
  .keys(['70k', '71K - 149K']);

var bar1Data = [{
  '70k': 1000,
  '71K - 149K': 800,
}, ];

//sort bars based on value
bar1Data = bar1Data.sort(function(a, b) {
  return d3.descending(a.value, b.value);
})

var stackedData = stack(bar1Data);

var colorScale = d3.scaleOrdinal()
  .range(["#E8A82B", "#000000"]);

const x = d3.scaleLinear()
  .domain([0, 1800])
  .range([0, 800]);

// Join data to rects
// In this example I take `0` because you get nested arrays for groups
const rects = bars.selectAll('rect')
  .data(stackedData.map((group) => group[0]))

rects
  .enter()
  .append('rect')
  .attr('width', ([min, max]) => x(max - min))
  .attr('height', 200)
  .attr('x', ([min, _]) => x(min))
  .attr('y', 100)
  .style("fill", (d, i) => colorScale(i));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="bars"></div>


Related Query