Reputation: 173
Hi I am using a large json file in d3, about 75 KB. It seems to work for the 32 data objects but then I get the error in the console Cannot read property 'length' of undefined. It seems like my json is ok since I put it in http://jsonlint.com/ and it validated. I know similar questions have been asked here but I'm new to d3 so don't know how to modify the code. I think it may have something to do with how d3 is getting the data from my json file.
Here is d3 code in its entirety:
function truncate(str, maxLength, suffix) {
if(str.length > maxLength) {
str = str.substring(0, maxLength + 1);
str = str.substring(0, Math.min(str.length, str.lastIndexOf(" ")));
str = str + suffix;
}
return str;
}
var margin = {top: 20, right: 200, bottom: 0, left: 20},
width = 300,
height = 650;
var start_year = 2004,
end_year = 2013;
var c = d3.scale.category20c();
var x = d3.scale.linear()
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("top");
var formatYears = d3.format("0000");
xAxis.tickFormat(formatYears);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("margin-left", margin.left + "px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("data.json", function(error, data) {
if (error) throw error;
x.domain([start_year, end_year]);
var xScale = d3.scale.linear()
.domain([start_year, end_year])
.range([0, width]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + 0 + ")")
.call(xAxis);
console.log(data.length);
var len = data.length;
for (var j = 0; j < len; j++) {
// try{
var g = svg.append("g").attr("class","journal");
var circles = g.selectAll("circle")
.data(data[j]['articles'])
.enter()
.append("circle");
var text = g.selectAll("text")
.data(data[j]['articles'])
.enter()
.append("text");
var rScale = d3.scale.linear()
.domain([0, d3.max(data[j]['articles'], function(d) { return d[1]; })])
.range([2, 9]);
circles
.attr("cx", function(d, i) { return xScale(d[0]); })
.attr("cy", j*20+20)
.attr("r", function(d) { return rScale(d[1]); })
.style("fill", function(d) { return c(j); });
text
.attr("y", j*20+25)
.attr("x",function(d, i) { return xScale(d[0])-5; })
.attr("class","value")
.text(function(d){ return d[1]; })
.style("fill", function(d) { return c(j); })
.style("display","none");
g.append("text")
.attr("y", j*20+25)
.attr("x",width+20)
.attr("class","label")
.text(truncate(data[j]['name'],30,"..."))
.style("fill", function(d) { return c(j); })
.on("mouseover", mouseover)
.on("mouseout", mouseout);
// }
// catch(err){
// console.log(err);
// continue;
// }
};
function mouseover(p) {
var g = d3.select(this).node().parentNode;
d3.select(g).selectAll("circle").style("display","none");
d3.select(g).selectAll("text.value").style("display","block");
}
function mouseout(p) {
var g = d3.select(this).node().parentNode;
d3.select(g).selectAll("circle").style("display","block");
d3.select(g).selectAll("text.value").style("display","none");
}
});
Sample json:
[{"articles":[[2004,25],[2005,25],[2006,26],[2007,31],[2008,20],[2009,26],[2010,19],[2011,18],[2012,24],[2013,17]],"total": 231,"name": " Acta Inf. " },
{"articles":[[2008,1]],"total": 1,"name": " nf. " },
{"articles":[[2005,27],[2006,30],[2007,27],[2008,75],[2009,31],[2010,34],[2011,46],[2012,35],[2013,60]],"total": 365,"name": " Displays " },
{"articles":[[2010,20],[2011,16],[2012,16]],"total": 52,"name": " IJKDB " },
{"articles":[[2004,61],[2005,70],[2006,72],[2007,71],[2008,79],[2009,65],[2010,80],[2011,77],[2012,82],[2013,121]],"total": 778,"name": " Computers in Industry " },
{"articles":[[2010,1]],"total": 1,"name": " rs in Industry " },
{"articles":[[2005,1]],"total": 1,"name": " ry " }, ...
EDIT: no longer getting the error in console, there was something wrong with my JSON..however still not displaying all entries in the visualization, here is my entire JSON file https://api.myjson.com/bins/425wh
EDIT 2: it all displays now! all the data was there but wasn't showing up because the height of the d3 canvas was too small
Upvotes: 1
Views: 747
Reputation: 32327
The problem is in the last entry. The last entry is an array which is in correct it should have be an object, so your dataset has array within array in the last record. You will need to flatten your data set array.
Add this after fetching the data from AJAX.
data = [].concat.apply([], data);//this will flatten all your array within array into a single array of records,
Second problem:
I only see a few that actually show up? for example the Journal with name "Artificial Intelligence in Education" does not appear.
The problem is that the svg height is less and the data to be displayed is more so it cuts off after 30 records.
So have a dynamic height like this:
d3.select("body svg").attr("height",len*20.2);//20.2 is approx height of one element
Now height will depend on the data length that needs to displayed.
I have updated the fiddle accordingly
Working code here.
Upvotes: 1