Marsel Gray
Marsel Gray

Reputation: 33

d3 height function returns NaN

I am new to d3.js and I am receiving an error of : Error: attribute height: Expected length, "NaN" when I attempt to run the following code:

I know the error is occurring at

   .attr('height', function(d){
        return (d * 5);
    })

but I can not seem to resolve it. Any help is appreciated.

var data = [];

for(let i = 0; i < 20; i++){
    // let num = Math.floor( Math.random() * 50 );
    let num = d3.randomUniform(1, 50);
    data.push(num);
}
// create svg element
var chartWidth = 800;
var chartHeight = 400;
var barPadding = 5;

var svg = d3.select('#chart')
            .append('svg')
            .attr('width', chartWidth)
            .attr('height', chartHeight);

// bind data and create bars
svg.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr('x', function(d, i){
        return i * (chartWidth / data.length);
    })
    .attr('y', 0)
    .attr('width', (chartWidth / data.length - barPadding))
    .attr('height', function(d){
        return (d * 5);
    })
    .attr('fill', '#7ED26D');

Upvotes: 1

Views: 111

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38211

If we look at the documentation for d3.randomUniform we see that it "Returns a function for generating random numbers with a uniform distribution." If we log d in your height function, we see d is a function. This is because we are taking the function returned by d3.randomUniform and adding it to the array in your for loop.

So, we just need to execute that function:

let num = d3.randomUniform(1, 50)();

But there is a better way, as we don't need to create this function each iteration of the loop. Instead, we could use:

let num = d3.randomUniform(1, 50);
for(let i = 0; i < 20; i++){
    data.push(num());
}

var data = [];


let num = d3.randomUniform(1, 50);
for(let i = 0; i < 20; i++){
    data.push(num());
}
// create svg element
var chartWidth = 800;
var chartHeight = 400;
var barPadding = 5;

var svg = d3.select('#chart')
            .append('svg')
            .attr('width', chartWidth)
            .attr('height', chartHeight);

// bind data and create bars
svg.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr('x', function(d, i){
        return i * (chartWidth / data.length);
    })
    .attr('y', 0)
    .attr('width', (chartWidth / data.length - barPadding))
    .attr('height', function(d){
        return (d * 5);
    })
    .attr('fill', '#7ED26D');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart">

Upvotes: 4

Related Questions