In my Angular project, I have a csv
file containing data that is imported along with the D3.js
library:
group,Nitrogen,normal,stress
banana,12,1,13
poacee,6,6,33
sorgho,11,28,12
triticum,19,6,1
The TypeScript file includes code for displaying a stacked bar chart:
import { Component, OnInit } from '@angular/core';
import * as d3 from 'd3';
@Component({
selector: 'app-stacked-bar',
templateUrl: './stacked-bar.component.html',
styleUrls: ['./stacked-bar.component.css']
})
export class StackedBarComponent implements OnInit {
data = [
{"group": "banana", "Nitrogen": "12", "normal": "1", "stress": "13"},
{"group": "poacee", "Nitrogen": "6", "normal": "6", "stress": "33"},
{"group": "sorgho", "Nitrogen": "11", "normal": "28", "stress": "12"},
{"group": "triticum", "Nitrogen": "19", "normal": "6", "stress": "1"}
];
svg: any;
margin = 50;
width = 750 - (this.margin * 2);
height = 400 - (this.margin * 2);
ngOnInit(): void {
this.createSvg();
this.drawBars(this.data);
}
createSvg(): void {
this.svg = d3.select("figure#stacked-bar")
.append("svg")
.attr("width", this.width + (this.margin * 2))
.attr("height", this.height + (this.margin * 2))
.append("g")
.attr("transform", "translate(" + this.margin + "," + this.margin + ")");
}
drawBars(data): void {
// List of subgroups - Header of the csv file.
// Replace line below with ['Nitrogen', 'normal', 'stress'] to resolve issue
const subgroups = data.columns.slice(1);
const groups = data.map(d => (d.group));
const x = d3.scaleBand()
.domain(groups)
.range([0, this.width])
.padding(0.2);
this.svg.append("g")
.attr("transform", "translate(0," + this.height + ")")
.call(d3.axisBottom(x).tickSizeOuter(0));
const y = d3.scaleLinear()
.domain([0, 60])
.range([this.height, 0]);
this.svg.append("g")
.call(d3.axisLeft(y));
const color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#e41a1c','#377eb8','#4daf4a']);
const stackedData = d3.stack()
.keys(subgroups)
(data);
this.svg.append("g")
.selectAll("g")
.data(stackedData)
.join("g")
.attr("fill", d => color(d.key))
.selectAll("rect")
.data(d => d)
.join("rect")
.attr("x", d => x(d.data.group))
.attr("y", d => y(d[1]))
.attr("height", d => y(d[0]) - y(d[1]))
.attr("width", x.bandwidth());
}
}
However, the plot appears empty, and upon inspecting the page, a console error displays:
TypeError: Cannot read property 'slice' of undefined
This error arises due to ambiguity in data
, preventing the use of the slice
method. A quick fix involves replacing subgroups
with ['Nitrogen', 'normal', 'stress']
. After making this adjustment, the chart renders successfully!
If anyone can provide assistance on this matter, it would be greatly appreciated.
p.s. For reference, here is how the chart should look: