0

I am creating a stacked bar chart in d3.js, and I am having a few problems. My chart looks like this (created in D3.js):

enter image description here

but it should look something like this (created with Observable.Plot):

enter image description here

How can I change my code to:

  1. Show the bars on the X axis in the correct location
  2. change the height of each bar to be accurate
  3. change the color of each bar to accurately show the proper data
  4. What can i put as the "width" of each bar since the width is dynamic (the date range can change externally to this function)

If my data is not structured correctly, please let me know. I'm not sure if it is getting stacked correctly by d3.stack();

Initial Data: (unnecessary data points are blacked out for simplicity)

enter image description here

This is the same data after stacking:

enter image description here

with each array having:

enter image description here

This is my stack function:

    const stack: any = d3
      .stack()
      .keys(services) // string[]
      .value((x) => x.count); // count is a number

    var data = stack(props.data);

    console.log(props.data); // initial data array (as shown)
    console.log(data); // data array after stacking (as shown)

Scales:

    // x axis time scale
    const xAxisScale_min: Date = d3.min(props.data.map((i) => i.createdDate))!;
    const xAxisScale_max: Date = d3.max(props.data.map((i) => i.createdDate))!;
    const x = d3
      .scaleTime()
      .domain([xAxisScale_min, xAxisScale_max])
      .range([0, WIDTH]);

const yAxisScale_max: any = 10;
// y axis scale
const y = d3.scaleLinear().domain([0, yAxisScale_max]).range([HEIGHT, 0]);

And this is the code creating each rect

const rects = g.selectAll("rects").data(data);

    var color = d3.scaleOrdinal(services, d3.schemeCategory10);

    svg
      .append("g")
      .selectAll("g")
      // Enter in the stack data = loop key per key = group per group
      .data(data)
      .enter()
      .append("g")
      .attr("fill", function (d: any) {
        return color(d.key);
      })
      .selectAll("rect")
      // enter a second time = loop subgroup per subgroup to add all rectangles
      .data(function (d): any {
        return d;
      })
      .enter()
      .append("rect")
      .attr("x", function (d: any) {
        return x(new Date(d.data.createdDate));
      })
      .attr("y", function (d: any) {
        return y(d[1]);
      })
      .attr("height", function (d: any) {
        return y(d[0]) - y(d[1]);
      })
      .attr("width", WIDTH / props.data.length);

If you need the x and y axes grid information I can show that too, but I omitted it for simplicity.

Adam
  • 21
  • 3

1 Answers1

0

If anyone has this same problem, the issue is due to my data not being formatted correctly. I had a key of "service" and a value of the actual name of the service. Instead, I changed each object to have a "key" of the actual name of the service, and a value of the "count".

After changing my data, the chart started showing properly.

Adam
  • 21
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 31 '22 at 07:11