Amir Rahbaran
Amir Rahbaran

Reputation: 2430

D3.js: Elements don't have any width

I'm trying to append four rectto my svg. I can see them appended in chrome's dev tools. However, they're never rendered because it seems I have an issue with passing on the width value.

Besides, in version 3 of D3 I receive the following error message in the browser:

d3.v3.min.js:1 Error: attribute width: Expected length, "NaN".

There's no error message in version 4.

Here's my code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test</title>
    <script src="https://d3js.org/d3.v3.min.js"></script>
  </head>
  <body>
      <script type="text/javascript">
        var data = [20,3,60,800];

        var width = 500,
            height = 500;

        var widthScale = d3.scale.linear()
                      .domain([0, 80])
                      .range(0, width);

        var svg = d3.select("body")
                  .append("svg")
                  .attr("width", width)
                  .attr("height", height);

        var bars = svg.selectAll("rect")
                    .data(data)
                    .enter()
                      .append("rect")
                      .attr("width", function (d) { return widthScale(d); } )
                      .attr("height", 50)
                      .attr("fill", "steelblue")
                      .attr("y", function (d, i) { return i * 100});
      </script>
  </body>
</html>

The only difference between v3 and v4 is this line (scaleLinear):

var widthScale = d3.scaleLinear().domain([0, 80]).range(0, width);

Any help highly appreciated.

Upvotes: 3

Views: 142

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102218

range has to be an array. The documentation is clear:

linear.range([values]):

If values is specified, sets the scale's output range to the specified array of values

So, instead of:

.range(0, width);

It should be:

.range([0, width]);

If you use .range(0, width) D3 v3.x returns a NaN, and you see in the console:

Error: attribute width: Expected length, "NaN".

However, D3 v4.x returns undefined, and you see no error message in the console.

Here is your working code:

        var data = [20,3,60,800];

        var width = 500,
            height = 500;

        var widthScale = d3.scale.linear()
                      .domain([0, 80])
                      .range([0, width]);

        var svg = d3.select("body")
                  .append("svg")
                  .attr("width", width)
                  .attr("height", height);

        var bars = svg.selectAll("rect")
                    .data(data)
                    .enter()
                      .append("rect")
                      .attr("width", function (d) { return widthScale(d); } )
                      .attr("height", 50)
                      .attr("fill", "steelblue")
                      .attr("y", function (d, i) { return i * 100});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 3

Related Questions