简体   繁体   中英

D3JS: Multi-Nested JSON data

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM