2014-04-12 3 views
5

Ich fand diese snippet in jemand anderes question, die genau das tut, was ich will - ein Liniendiagramm mit eine Dropdown-Box zum Umschalten zwischen mehreren Datasets. Die Sache ist, ich möchte extern von einer PHP-generierten JSON-Datei laden, aber ich bin mir nicht sicher, wie ich das machen kann.d3.js: Laden verschiedener JSON-Datensätze bei Dropdown-Änderung

d3.taos = function (config) { 

    // Margins and graph formatting. 
    var margin = { 
     top: 20, 
     right: 20, 
     bottom: 20, 
     left: 60 }, 

     width = 960 - margin.left - margin.right, 
     height = 400 - margin.top - margin.bottom, 
     x = d3.time.scale(), // different scaling. 
     y = d3.scale.linear(), 
     xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5), 
     yAxis = d3.svg.axis().scale(y).orient("left").ticks(5), 
     line = d3.svg.line(), 
     color = d3.scale.category10(), 
     zoom = d3.behavior.zoom().scaleExtent([0.5, 50]); 


    // The chart itself. 
    var chart = function (selection) { 
     dataset = selection.data()[0]; 

     // Select the svg element, if it exists. 
     var svg = selection.selectAll("svg").data([dataset]) 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom); 

     // Otherwise, create the skeletal chart. 
     var gEnter = svg.enter().append("svg") 
      .append("g") 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     // Rendering both axes. 
     gEnter.append("g").attr("class", "x axis"); 
     gEnter.append("g").attr("class", "y axis"); 

     gEnter.append("defs").append("clipPath") 
      .attr("id", "clip") 
      .append("rect") 
      .attr("id", "clip-rect") 
      .attr("x", "0") 
      .attr("y", "0") 
      .attr("width", width) 
      .attr("height", height); 

     x.range([0, width]) 
      .domain(d3.extent(d3.merge(dataset), function (d) { 
       return d.x; 
      })) 

     y.range([height, 0]) 
      .domain(d3.extent(d3.merge(dataset), function (d) { 
       return d.y; 
      })) 

     var g = svg.select("g"); 

     // Update the x-axis. 
     g.select(".x.axis") 
      .attr("transform", "translate(0," + height + ")") 
      .call(xAxis); 

     // Update the y-axis. 
     g.select(".y.axis") 
      .call(yAxis); 

     // Define lines 
     line = d3.svg.line() 
      .x(function (d) { 
       return x(d.x); 
      }) 
      .y(function (d) { 
       return y(d.y); 
      }) 

     var path = g.selectAll(".line") 
      .data(dataset) 
      .enter().append("path") 
      .style("stroke", function (d, i) { 
       return color(i) 
      }); 

     path.attr("class", "line") 
      .attr("d", line) 
      .attr("clip-path", "url(#clip)"); 

     // Update the clip rectangle 
     g.select("#clip-rect") 
      .attr("width", width) 
      .attr("height", height); 

     // Update the line path. 
     g.selectAll(".line") 
      .attr("d", line); 

     zoom.x(x).y(y) 
      .on("zoom", draw); 

     // Rect for zoom. 
     gEnter.append("rect") 
      .attr("class", "rectzoom") 
      .attr("width", width) 
      .attr("height", height) 
      .call(zoom); 

     function draw() { 
      g.select(".x.axis").call(xAxis); 
      g.select(".y.axis").call(yAxis); 
      g.selectAll("path.line").attr("d", line); 
      //g.select("#clip-rect").attr("width",width).attr("height",height); 
     } 

     /* 
     * Methods 
     */ 

     chart.width = function (w) { 
      if (!arguments.length) return width; 
      width = w; 
      return this; 
     }; 

     chart.height = function (h) { 
      if (!arguments.length) return height; 
      height = h; 
      return this; 
     }; 

     return chart 

    } // chart 

    return chart 

}; // d3.taos 





/* 
* Main 
*/ 

// for json: 


// New instance 
var t = d3.taos(); 

var f = function() {} 



var data = d3.json("api.json?id=1", function(error, data) { 
    if (error) return console.warn(error); 
    // Creation 
    d3.select("svg#chart") 
     .datum(data) 
     .attr("x", function(d) { x(d.x) }) 
     .call(t); 
}); 

// Update 
d3.select("select").on("change", function() { 

    var val = $("select#dataset").val(); 



    val == "dataset1" ? dataset = dataset1 : dataset = dataset2; 

    console.log("Dataset changed: " + val); 

    d3.select("svg#chart") 
     .datum(dataset) 
     .call(t.width(800)); 


}); 

Und der HTML-Code ... Dataset

<select id="dataset"> 
     <option value="1" selected>Dataset 1</option> 
     <option value="2">Dataset 2</option> 
     <option value="3">Dataset 3</option> 
    </select> 

Beispiel JSON zum Beispiel aus api.json?id=1

{ 

     "usability_index": [ 
      {"x": 1397220093000, "y": 7}, 
      {"x": 1397222093000, "y": 21}, 
      {"x": 1397224093000, "y": 13}, 
      {"x": 1397226093000, "y": 23} 
     ] 

} 

Ich erforschte mit d3.json() aber ich bin mir nicht ganz sicher, wie gehen sie dynamisch geladen, wenn z.B. Die Standard-Dataset-Option wird in Dataset 3 von api.json?id=1 in api.json?id=3 geändert.

Ich bin wirklich neu zu d3.js und würde wirklich einige Führung hier schätzen!

+0

Probieren Sie es aus [bl.ock] (http://bl.ocks.org/phil-pedruco/9087479). Sie müssten die 'd3.json (" path/to/url ", Funktion (Fehler, Daten) {// machen Sie einige Liniendiagramm Zeug})' Muster in der Änderungsfunktion. – user1614080

+1

Möchten Sie Ihre Lösung als Antwort posten, falls jemand anderes diese Frage hat? Sie können die Antwort auch akzeptieren. – user1614080

+0

Danke allen! Herausgefunden, dass wiederverwendbare Diagrammbibliotheken wie c3.js oder nvd3.js für dynamische Daten gut sind. Ich habe stattdessen c3.js verwendet. –

Antwort

2

Sie könnten so etwas versuchen, aber stattdessen eine library that makes reusable charts basierend auf d3.js verwenden.

Das Folgende ist ein Beispiel dafür, wie man konnte load data über API-Aufrufe

var chart = c3.generate({ 
    data: { 
     url: 'api.json?id=1', 
     mimeType: 'json' 
    } 
}); 

Beachten Sie, dass c3.js erfordert Ihre JSON im Format haben:

{ 
    "line1": [220, 240, 270, 250, 280], 
    "line2": [180, 150, 300, 70, 120], 
    "line3": [200, 310, 150, 100, 180] 
} 

Daher müssen Sie um Ihre JSON-Daten zu analysieren und neu zu formatieren, bevor Sie sie laden können.

Und fügen Sie Ereignisbehandlungsroutinen an, die Sie auswählen können, um mehr Zeilen in das Zeichen zu regenerieren oder zu laden t.