I'm encountering some challenges while creating a stacked bar chart in d3.js. The current appearance of my chart is depicted here (developed with D3.js):
https://i.sstatic.net/G6UA6.png
However, I aim to achieve a design similar to this one (crafted using Observable.Plot):
https://i.sstatic.net/Llhtr.png
To address these issues, I need to:
- Ensure that the bars are positioned accurately along the X-axis
- Adjust the height of each bar to reflect the correct data values
- Modify the color of each bar to represent the data effectively
- Determine an appropriate value for the "width" of each bar, considering the dynamic nature of the date range external to this function
If there are concerns regarding the structure of my data, please provide feedback on whether it is correctly stacked by d3.stack();
Initial Data: (some data points have been obscured for simplicity)
https://i.sstatic.net/sXum3.png
The same data after stacking can be viewed here:
https://i.sstatic.net/MHQOm.png
Each array includes:
https://i.sstatic.net/wjPDP.png
This snippet shows my stack function implementation:
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)
Scale Definitions:
// Define time scale for x axis
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]);
// Set maximum value for y axis scale
const yAxisScale_max: any = 10;
// Define linear scale for y axis
const y = d3.scaleLinear().domain([0, yAxisScale_max]).range([HEIGHT, 0]);
Below is the code segment responsible for creating each rectangle element:
const rects = g.selectAll("rects").data(data);
var color = d3.scaleOrdinal(services, d3.schemeCategory10);
svg
.append("g")
.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("fill", function (d: any) {
return color(d.key);
})
.selectAll("rect")
.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 additional details such as the grid information for x and y axes are required, feel free to request them. For brevity, I excluded those specific aspects.