<rect> attribute height: Expected length "NaN"
Published: 2021-07-18 07:00:55

I have the following data in a `csv` file in my Angular project that also imports the `D3.js` library:

    group,Nitrogen,normal,stress
    banana,12,1,13
    poacee,6,6,33
    sorgho,11,28,12
    triticum,19,6,1

I have created a `stacked-bar` component with the following code in its `html` script:

    <h3>Stacked Bar Chart</h3>
    <figure id="stacked-bar"></figure>

I also have the following code in the typescript file to display the stacked bar:

    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 - Here, soil condition.
        const subgroups = data.slice(1);
        console.log(subgroups);
        
        // List of groups - Value of the first column called group - Shown on the X axis - Here, species.
        const groups = data.map(d => (d.group));
    
        // Create the X-axis band scale.
        const x = d3.scaleBand()
        .domain(groups)
        .range([0, this.width])
        //.domain(data.map(d => d.groups))
        .padding(0.2);
    
        // Draw the X-axis on the DOM.
        this.svg.append("g")
        .attr("transform", "translate(0," + this.height + ")")
        .call(d3.axisBottom(x).tickSizeOuter(0));
        
        // Create the Y-axis band scale.
        const y = d3.scaleLinear()
        .domain([0, 60])
        .range([this.height, 0]);
    
        // Draw the Y-axis on the DOM.
        this.svg.append("g")
        .call(d3.axisLeft(y));
    
        // color palette = one color per subgroup
        const color = d3.scaleOrdinal()
        .domain(subgroups)
        .range(['#e41a1c','#377eb8','#4daf4a']);
    
        // Stack the data per subgroup.
        const stackedData = d3.stack()
        .keys(subgroups)
        (data);
    
        // Create and fill the bars.
        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());
      }
    }

But I only get an empty plot! When I inspect the page, I have this console error:

**<rect> attribute height: Expected length, "NaN"**

It takes me to `attr.js.31` where the line is `else this.setAttribute(name, v)`.

It is actually pointing to `.attr("height", d => y(d[0]) - y(d[1]))`. I don't see anything wrong with this line...

Can somebody please help me with this? I've been stuck in it for a few days now...