user3755529
user3755529

Reputation: 1196

D3.js parseFloat and iterate throught .json

first of all I don't know how to make the type() function go through all the elements of the list in the .JSON file. I get this result:

//0:{x: 0.1, y: 0.966}
//1:{x: 0.3, y: 0.757}
//2:{x: 0.6, y: 0.71}
//x: NaN
//y: NaN

and I thought I would have seen this:

//0:{x: NaN, y: NaN}
//1:{x: NaN, y: NaN}
//2:{x: NaN, y: NaN}

here is the code:

<!-- .JSON file:
[
  {
    "x": 0.1,
    "y": 0.966
  },
  {
    "x": 0.3,
    "y": 0.757
  },
  {
    "x": 0.6,
    "y": 0.71
  }
]
-->

<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>

<script>

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

d3.json("data.json", function (myArrayOfObjects){

render(type(myArrayOfObjects))
console.log(myArrayOfObjects)
});

var scale = d3.scaleLinear();

scale.domain([0,1]);
scale.range([0,250]);

function type(d){
d.x = parseFloat(d.x);
d.y = parseFloat(d.y);
return d;
}

function render(data) {
svg.selectAll("rect").data(data)
.enter().append("rect")
.attr("x", scale(function(d) {return d.x;}))
.attr("y", 0)
.attr("height", scale(function(d) {return d.y;}))
.attr("width",10);
}

</script>

</body>
</html>

Event when I try the following for type function:

function type(d){
d[0].x = parseFloat(d.x);
d[0].y = parseFloat(d.y);
return d;
}

I get this:

//0: {x: NaN, y: NaN}
//1: {x: 0.3, y: 0.757}
//2: {x: 0.6, y: 0.71}

is that because the parseFloat() fucntion is not working? why does it give me NaN and does not translate the strings into floats?

Upvotes: 1

Views: 930

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102198

First of all, there is a misunderstanding about the type function here. An accessor function, a.k.a. row conversion function, is a function that is invoked for each row in a CSV or TSV (or any kind of DSV). That d in the type function is a parameter referring to the row.

The thing is d3.json does not accept a row conversion function, only d3.csv and d3.tsv accept it. The good news is that you don't need one. And the reason is simple: you already have numbers (when using d3.csv or d3.tsv, on the other hand, even if your file has numbers, they are converted to strings).

Let's prove that, this is a simple d3.json using your data, look at the console:

d3.json("https://api.myjson.com/bins/6u80r", function(data) {
  data.forEach(function(d) {
    for (var key in d) {
      console.log("The typeof " + d[key] + " in '" + key + ":" + d[key] + "' is " + typeof d[key])
    }
  })
})
<script src="https://d3js.org/d3.v4.min.js"></script>

Also, you're using your scales incorrectly. Instead of:

.attr("x", scale(function(d) {return d.x;}))

It should be:

.attr("x", function(d) {return scale(d.x);})

Check the demo:

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

var scale = d3.scaleLinear()
  .range([0, 250]);

d3.json("https://api.myjson.com/bins/6u80r", render)

function render(data) {
  svg.selectAll("rect").data(data)
    .enter().append("rect")
    .attr("x", function(d) {
      return scale(d.x);
    })
    .attr("y", 0)
    .attr("height", function(d) {
      return scale(d.y);
    })
    .attr("width", 10);
}
<script src="https://d3js.org/d3.v4.min.js"></script>

Upvotes: 3

Related Questions