ekatz
ekatz

Reputation: 1070

Nested JSON: property length of undefined

I'm trying to work with a nested array with a JSON in D3JS and can't figure out why in the world I'm getting a "property length undefined" error at the line which reads:

.attr("d", function(d) { return line(d.points); }).

Here's the JSON:

[
{
    "aspectRatio": 1.247386759581881,
    "closed": 1,
    "xyData": [
        {
            "x0": 0.53078594712060867,
            "x1": 0.95454545454545459,
            "x2": 0.95454545454545459,
            "x3": 0.53078594712060867,
            "x4": 0.53078594712060867,
            "y0": 0.52936622215603868,
            "y1": 0.52936622215603868,
            "y2": 0.13179275296659432,
            "y3": 0.13179275296659432,
            "y4": 0.52936622215603868
        }
    ]
},
{
    "aspectRatio": 1.247386759581881,
    "closed": 1,
    "xyData": [
        {
            "x0": 0.045454545454545435,
            "x1": 0.41126403477001078,
            "x2": 0.41126403477001078,
            "x3": 0.045454545454545435,
            "x4": 0.045454545454545435,
            "y0": 0.86820724703340568,
            "y1": 0.86820724703340568,
            "y2": 0.44804437618547044,
            "y3": 0.44804437618547044,
            "y4": 0.86820724703340568
        }
    ]
}
]

And here's the code:

function loadEss(filename,svgName,mainWidth){
var svgName;
d3.json(filename, function(error, data) {
    data.forEach(function(kv){
        kv.xyData.forEach(function(d) {
            d.points = [];
            aspect=1.5;
            for (var i = 0; d["x"+i] !== "" && (typeof d["x"+i] !== 'undefined'); i++) {
                d.points.push([mainWidth*d["x"+i], mainWidth/aspect*(d["y"+i])]);
            }
            console.log(d.points);
        });
    });

    var margin = {top: 0, right: 0, bottom: 0, left: 0},    
        width = mainWidth - margin.left - margin.right,             
        height = mainWidth/aspect - margin.top - margin.bottom; 

    svgName= d3.select("body")                                  
        .append("svg")                                      
            .attr("width", width + margin.left + margin.right)  
            .attr("height", height + margin.top + margin.bottom)
        .append("g")                                            
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 


    var line = 
    d3.svg.line() 
    .interpolate("linear-closed")
    ;

    svgName.selectAll("path")
        .data(data)
        .enter()
        .append("path")
        ;

    svgName.selectAll("path")
        .attr("d", function(d) { return line(d.points); })  
        .attr("stroke-linecap","round")
        .attr("stroke-linejoin","round")
        ;
});

};

This work is based off of two previous topics: Nested JSON array and D3JS and d3JS: Drawing Line Segments from CSV

Any help would be much appreciated.

Upvotes: 0

Views: 223

Answers (1)

meetamit
meetamit

Reputation: 25157

Here's a jsfiddle

That array of points that you're building is getting stored in the wrong place, so further below d.points is null when you pass it to line(). Instead of d.points you need kv.points:

    kv.xyData.forEach(function(d) {
        kv.points = [];
        aspect=1.5;
        for (var i = 0; d["x"+i] !== "" && (typeof d["x"+i] !== 'undefined'); i++) {
            kv.points.push([mainWidth*d["x"+i], mainWidth/aspect*(d["y"+i])]);
        }
        console.log(kv.points);
    });

Upvotes: 1

Related Questions