0

This question focuses on calling nested data in a JSON within d3JS. As a follow up to this question answered by @meetamit, I'm now adding another tier to the nested JSON and am having trouble with the script (JS Fiddle Here):

var svgName;
var mainWidth=300;
data=[
{
    "params": [
        {
            "strokeWeight": 1.3,
            "xyData": [
                {
                    "x0": 0.34827403080754826,
                    "x1": 0.60600737245405589,
                    "x2": 0.72278004152764297,
                    "x3": 0.46504669988113501,
                    "x4": 0.34827403080754826,
                    "y0": 0.41161457968694481,
                    "y1": 0.60527707639332184,
                    "y2": 0.36347025679680034,
                    "y3": 0.16980776009042353,
                    "y4": 0.41161457968694481
                }
            ]
        },
        {
            "strokeWeight": 6.3,
            "xyData": [
                {
                    "x0": 0.19665357021794935,
                    "x1": 0.41914132668202908,
                    "x2": 0.54254880649843318,
                    "x3": 0.32006105003435364,
                    "x4": 0.19665357021794935,
                    "y0": 0.39756094992379476,
                    "y1": 0.56473968639682104,
                    "y2": 0.30919384295958852,
                    "y3": 0.14201510648656224,
                    "y4": 0.39756094992379476
                }
            ]
        }
    ],
    "view": "view0"
}
];

    data.forEach(function(qx){  
        qx.points=[];  //this makes two curves merged into one curve.  I want two separate rectangles       
        qx.params.forEach(function(kv){
            aspect=1.5;
            // qx.points=[]; //this makes one curve
            kv.xyData.forEach(function(d) {             
                for (var i = 0; d["x"+i] !== "" && (typeof d["x"+i] !== 'undefined'); i++) {
                    qx.points.push([mainWidth*d["x"+i], mainWidth/aspect*(d["y"+i])]);
                }
            });
        });
    });
    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() 
    ;

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

    svgName.selectAll("path")
        .attr("d", function(d) { return line(d.points); })  
        .style("stroke-width", function(d){return d.strokeWeight;})  //this isn't working.
        .style("fill","none")
        .attr("stroke-linecap","round")
        .attr("stroke-linejoin","round")
        ;

Now I must be missing something obvious here, but I'm having trouble getting the two xyData to read as different curves with the code below. The stroke-width also doesn't work to reference data. What's happening with the curves is clear: the two list are merged into one list and this creates a continuous path instead of two separate ones. I'm not sure how to fix the stroke-width issue, so I'd appreciate any help.

1 Answer 1

1

I haven't dug too deeply into the structure, but the problem appears to be that, at the top level, you only have one item in your array. Since your paths (or path, as it happens to be) is appended at svgName.selectAll("path").data(data).enter().append("path"), you are going to generate one path for each element in data, which is a one element array.

If you want to generate one path for each element in params, you shoud use svgName.selectAll("path").data(data.params), since this has the correct number of elements, or use newData = data.params.map(mappingFunction) to create an appropriate array from data.params, and then use that as your data.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your help, there's a bit more detail that I've figured out. I needed to remove the brackets which made the one element array and add data.params to the line method and the forEach method. Updated JSFIDDLE here: jsfiddle.net/B4qAQ/1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.