1
votes

I have a plunker here - https://plnkr.co/edit/JSB4FD1yOe6Xvii6FiRn?p=preview

Its a stacked bar chart in an Angular 4 component

I'm having problems with the x domain to create the x axis

At the moment the bars are taking up the width of the whole chart.

private drawChart(data:any){
    this.layersBar = this.layersBarArea.selectAll('.layer')
        .data(data)
        .enter()
        .append('g')
        .classed('layer', true)
        .style('fill', (d:any,i:any)=>{
            return this.colors[i]
        });

    this.x.domain(data.map((d:any)=>{
        //return d.date;
    }));

    this.y.domain([0, +d3.max(this.stackedSeries, function(d:any){
        return d3.max(d, (d:any)=>{
            return d[1]
        })
    })]);

    this.layersBar.selectAll('rect')
        .data((d:any)=>{
            return d;
        })
        .enter()
        .append('rect')
        .attr('y', (d:any)=>{
            return this.y(d[1])
        })
        .attr('x', (d:any, i:any)=>{
            return this.x.date
        })

        .attr('width', this.x.bandwidth())
        .attr('height', (d:any, i:any)=>{
            return this.y(d[0]) - this.y(d[1]);
        })
}
2

2 Answers

1
votes

It's a mystery to me the fact that you're asking why the x domain is not working. You can clearly see that you're not returning anything here:

this.x.domain(data.map((d:any)=>{
    //return d.date;
}));

Which makes the x domain undefined.

You have to return d.date. But, on top of that, you have to change the data: data is the stacked data. Instead of that, you want to use this.data:

this.x.domain(this.data.map((d:any)=>{
    return d.date
}));

Finally, you're setting the x position wrong. It should be:

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

Here is the updated plunker: https://plnkr.co/edit/Itz5wTydyGcohKSlSsX0?p=preview

PS: Your button doesn't work.

-1
votes

The issue is in this code block.

this.layersBar.selectAll('rect')
        .data((d:any)=>{
            return d;
        })
        .enter()
        .append('rect')
        .attr('y', (d:any)=>{
            return this.y(d[1])
        })
        .attr('x', (d:any, i:any)=>{
            return this.x.date
        })

        .attr('width', this.x.bandwidth())
        .attr('height', (d:any, i:any)=>{
            return this.y(d[0]) - this.y(d[1]);
        })

Where you have .attr('width', this.x.bandwidth()) this determines how wide the bars should be. Since I don't know how wide you want them to be you just need to change this.x.bandwith() to something that works for you.