2016-06-08 13 views
0

Ich baue eine Webanwendung, die eine Liste von Dateinamen erhält und basierend auf dieser Eingabe liest die Dateien, verkettet sie und zeigt die Daten in verschiedenen Diagrammen. Die knifflige Sache hier ist, dass die Dateien ziemlich groß sind, bevor die relevanten Informationen extrahiert werden (~ 6-10mb), und ich nicht genau weiß, wieviele der Benutzer fordert. (Nehmen wir an, dass eine typische Anfrage größer als 3, aber kleiner als 20 ist.)Lesen einer beliebigen Anzahl von csvs mit Javascript/D3

Soweit ich das beurteilen kann, gibt es keine offensichtliche Möglichkeit, eine beliebige Anzahl von Dateien mit d3 einzulesen. Mike Bostock hat eine ähnliche Frage here beantwortet. Das Problem mit diesen Lösungen ist, dass Sie die Anzahl der Dateien im Voraus wissen müssen - ich habe diesen Luxus nicht.

Was würde ich tun möchte, ist eine Art von rekursiven Funktion haben wie:

function concatFiles(fileNameArray) { 
    function recursiveConcat(fileNameArray, concatedFile) { 
     var temp; 
     if (fileNameArray.length === 0) { 
      return concatedFile; 
     } else { 
      d3.csv(fileNameArray.shift(), function(err, csv) { 
       temp = csv; 
      } 
      return recursiveConcat(fileNameArray, concatedFile.concat(temp)); 
     } 
    } 
    return recursiveConcat(fileNameArray, []); 
} 

Das Schöne an dieser Art von Lösung ist, dass ich nicht über eine Variable für jede Datei oder Speicher erstellen müssen Zwischenergebnisse in einem Array. Ich bin mir jedoch nicht sicher, ob dieses Ding gut mit der asynchronen Natur von Javascripts spielen wird (ich bin neu in Javascript). Wie kann ich effektiv zwischen arrayOfFileNames -> concatenatedFile mappen?

Antwort

1

d3-queue scheint für dieses Szenario völlig in Ordnung zu sein. Der folgende Ausschnitt sollte genug sein, um das Laden von einer beliebigen Anzahl von Dateien zu handhaben:

function loadFiles(files) { 

    // Create a new queue to handle the loading of all files. 
    var q = d3.queue(); 

    // Iterate over the array of all files to be loaded. 
    files.forEach(function(f) { 
    // Add a loading task for each file to the queue. 
    q.defer(d3.csv, f) 
    }); 

    // When all loading tasks have finished, you may process the 
    // contents of all files. 
    q.awaitAll(function(error, contents) { 
    // Do your concatenation here. 
    // contents contains an array of the parsed results of all files 
    // console.log(contents); 
    }) 
} 

var filesToLoad = ["file1.csv", "whatever.csv", "another.csv"]; 
loadFiles(filesToLoad);  // load all files in the array 

Beachten Sie, dass dies macht keine Annahmen über die Anzahl der Dateien in dem Array filesToLoad. Sehen Sie sich Plunk für ein funktionierendes Beispiel an.

Verwandte Themen