d3 Error: Unable to retrieve the length property of an undefined value

I am currently working with a large JSON file in d3, approximately 75 KB in size. It seems to be functioning properly for the first 32 data objects, but then an error appears in the console stating 'Cannot read property 'length' of undefined'. Despite this, when I validated my JSON using http://jsonlint.com/, it showed that the JSON is formatted correctly. While I see similar questions on this topic, I am new to d3 and unsure how to make modifications to the code. It seems like the issue may be related to how d3 is retrieving data from my JSON file.
Here is the full code for d3:

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: The console error has been resolved, it was an issue with my JSON formatting. However, not all entries are being displayed in the visualization. Here is the link to my complete JSON file:

EDIT 2: All the data is now being displayed! The data was present but was not visible due to the insufficient height of the d3 canvas.

Answer №1

The issue lies in the final entry of your dataset. Instead of being an object, the last entry is an array, resulting in an array within an array in the last record. To resolve this, you will need to flatten your dataset array.

After fetching the data from AJAX, add the following code:

data = [].concat.apply([], data);//this will flatten all arrays within arrays into a single record array,

Update

Second concern:

Only a few entries are visible? For instance, the Journal named "Artificial Intelligence in Education" is missing.

The issue is that the height of the svg is insufficient for the amount of data to be displayed, causing it to cut off after 30 records.

To address this, adjust the height dynamically like this:

d3.select("body svg").attr("height",len*20.2);//20.2 is the approximate height of one element

Now, the height will be based on the length of the data to be displayed.

The fiddle has been updated accordingly

See the updated code here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

display Ajax Response in dropdown selection

My task involves selecting multiple tests and dates. Upon clicking submit, the names of laboratories associated with the selected tests are loaded into a select option. Using Ajax script: $('[name=submits]').click(function(e) { e.preventDef ...

What is the best way to parse JSON data in a Struts 2.0 web service

When working in a servlet, I typically use the JSONObject json = (JSONObject)new JSONParser().parse(jb.toString()); code snippet to get a JSON object and JSONObject result=new JSONObject();response.getWriter().write(result.toString()); to post a JSON obj ...

Converting a PHP multidimensional array to JavaScript

I'm facing an issue with printing data from a PHP array in a JavaScript function. The current setup is not producing the desired outcome. Here's how the data is being processed in PHP: $daten = array(); $anzahl = array(); $leads = array(); if ($ ...

What steps do I need to take to extract the date and month from a single datepicker using the code below?

<div class="col-md-3 pull-left" style="padding:9px"> <input type="text" id="datepicker" class="form-control"> </div> The HTML and C ...

Troubles with importing/resolving components in Vue 3

Just starting out with Vue and following tutorials to learn. I've created a component called Header.vue and attempted to import it into App.vue. This is the setup: code structure Here is App.vue: <template> <Header /> </template&g ...

"Exploring the possibilities of integrating the Twitter API with

Currently, I am attempting to access my most recent tweet from Twitter using https://github.com/jdub/node-twitter I am interested in setting a variable, modifying that variable within a function, and then utilizing it again outside of said function. Is th ...

Remove background image when input form field is in focus

I am currently experimenting with the following approach: $('input').on('click focusin', function() { $('.required').hide(); }); However, it appears that this logic is not functioning as intended. Here is an ...

css rules are not applied if the element is dynamically added using javascript

I'm encountering an issue with my code that inserts icons into a div with the ID of "editor". When I try to add a <select> element to the div with the ID of "drug_tool", the CSS styling rules for it are being ignored. How can I resolve this prob ...

Guide on importing a JS file into the main JS file using Three.js

I'm fairly new to Threejs and I am trying to organize my code by putting some of my threejs code in a separate JS file and then using it in my main.js file. Here is a simplified version of what I am trying to do: main.js import * as THREE from &ap ...

I possess an item, but unfortunately, I am only able to save the first object from this possession

I have an object, but I can only save the first item from this object. Interface: export interface PhotoToCreate { albumName: string; albumTitle: string; ImageNameO : string; imageNameT : string; } Component import { Component, OnI ...

The JSON file containing API data is stored within the _next folder, making it easily accessible to anyone without the need for security measures or a login in the Next

When accessing the protected user Listing page, we utilize SSR to call the api and retrieve all user records which are then rendered. However, if one were to check the Network tab in Chrome or Firefox, a JSON file containing all user data is generated and ...

Connection issue occurred with Mongodb server causing failure to establish a connection

I encountered an error where my application was unable to connect to mongo after running "nodemon index.js": { MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: getaddrinfo ENOTFOUND localhost localhost: ...

Node.js Express: Invalid attempt to modify headers after they have already been sent

I have been working on reading a growing file in nodejs and have implemented the following code in my app.js file. app.post('/readfile',function (req,res) { var fullfilename = req.body.filepath+"\\"+req.body.filename; var bi ...

Leveraging icons with Bootstrap 4.5

I am currently exploring how to incorporate Bootstrap 4.5 icons using CSS. Do you have any examples of code that could guide me on how to achieve this? I am specifically interested in understanding the required CSS declarations that would allow me to use t ...

Attempting to use Selenium in JavaScript to download a file with a new element called 'TransitionRejection'

I am looking to streamline the process of downloading multiple files from a website. To achieve this, I navigate through several pages to obtain the file IDs using selenium and a perl script. Since selenium does not have a built-in download function and u ...

Implementing Conditional Inclusion of Attributes in Active Model Serializer in RailsDiscover the best way to include attributes

In my Rails 4 API project, I am utilizing Active Model Serializers. I've been grappling with how to incorporate the auth_token attribute into my JSON response only when a user logs in through sessions#create. Despite referring to the AMS documentation ...

Looping through ng-repeats, extracting checked checkbox values in Angular

I am currently dealing with multiple nested ng-repeats in my project, and the third level down consists of a group of checkboxes. Initially, I receive an array of options for these checkboxes, which I handle with the following code snippet: <div class= ...

Tips for retrieving nested properties from a JSON Array object in Azure KQL dynamically

I am facing a challenge in retrieving all data disks available on a VM from Azure Resource Graph Query. While I can retrieve a specific data disk by specifying the index (e.g. properties.storageProfile.dataDisks[0].name for the first disk), I am unsure h ...

Nodejs controller unable to successfully pass variables to the view

I'm facing an issue with passing a variable from a controller to a view in Nodejs. Currently, I am using Express for my routing: app.get('/search/:id', function(req,res){ searchController.findByName(req, res); // console.log(res); ...

The Splitter remains inactive until a peculiar series of actions is taken

Trying to troubleshoot this issue with a library called Split.js, which can be found here: https://github.com/nathancahill/Split.js I've encountered an interesting problem where I have to disable the height CSS property of my container, move the spli ...