使用 D3.js 解析上传的 CSV 文件

Posted

技术标签:

【中文标题】使用 D3.js 解析上传的 CSV 文件【英文标题】:Parse Uploaded CSV file using D3.js 【发布时间】:2016-07-04 21:54:57 【问题描述】:

我是 d3.js 的新手,所以我知道这对某些人来说可能是一个愚蠢的问题,所以请多多包涵。我正在尝试解析用户上传的 csv 文件并在控制台中打印它的输出。当我提供 CSV 文件的绝对路径时,我能够解析 CSV 文件,但是当我尝试对文件上传功能执行相同操作时,我在控制台中没有得到任何输出..

工作 Javascript 代码..

    var dataset = [];
    d3.csv("sample.csv", function(data) 
    dataset = data.map(function(d)  return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; );
    console.log(dataset[0]);
    console.log(dataset.length);
    ); 

控制台输出...

["Men's ***s Ghost 8 Running Shoe Black/High Risk Red/Silver Size 11.5 M US", "Shoes", "B00QH1KYV6", "$120.00 "]
 8

新的 HTML 代码..

    <input type="file" id="csvfile" name="uploadCSV"/>
    <br/>
    <button onclick="howdy()">submit</button>

修改后的 Javascript 代码(不工作)..

    var myfile = $("#csvfile").prop('files')[0];
    var reader = new FileReader();

    reader.onload = function(e) 
    var text = reader.result;
    

    reader.readAsDataURL(myfile);

     var dataset = [];
    d3.csv(reader.result , function(data) 
    dataset = data.map(function(d)  return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; );
    console.log(dataset[0]);
    console.log(dataset.length);
    )

由于没有关于如何处理用户上传的 CSV 文件的官方文档,我无法弄清楚我哪里出错了。有没有办法可以使用 html5 文件阅读器?请帮忙。。

【问题讨论】:

问题是$("#csvfile")[0].files这行没有给你文件的内容。您需要先将文件上传到服务器,并返回上传文件的 URL。然后,您需要更新客户端代码(javascript)以使用上传的文件 URL,而不仅仅是文件上传输入的内容 我们不能使用 HTML5 文件阅读器 API 来做到这一点吗?? 是的,您可以使用 html5 Fie Reader API 我编辑了上面的代码以使用文件阅读器获取 url,但我仍然没有在控制台中获得任何输出。你能看看我上面编辑的代码,告诉我哪里出错了吗? 请看developer.mozilla.org/en-US/docs/Web/API/FileReader/…你需要访问onload回调中的数据。您设置了 text 变量,但您从未使用过它。当文件内容可用时,您可能必须在回调中调用d3.csv() 【参考方案1】:

您很接近,但您不需要也不能在 reader.result 上调用 d3.csvd3.csv 进行异步 AJAX 调用以从服务器检索 CSV 文件。您已经有了文件内容并且只想解析,所以使用d3.csv.parse。

完整的工作示例:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
  <input type="file" onchange="loadFile()" />

  <script>
    var reader = new FileReader();  
    
    function loadFile()       
      var file = document.querySelector('input[type=file]').files[0];      
      reader.addEventListener("load", parseFile, false);
      if (file) 
        reader.readAsText(file);
            
    
    
    function parseFile()
      var doesColumnExist = false;
      var data = d3.csv.parse(reader.result, function(d)
        doesColumnExist = d.hasOwnProperty("someColumn");
        return d;   
      );
      console.log(doesColumnExist);
    
  </script>
</body>

</html>

【讨论】:

有没有办法在 parseFile() 函数中检查 CSV 文件中是否存在某些列??【参考方案2】:

这是给d3-csv@3

<!-- https://www.jsdelivr.com/package/npm/d3-dsv -->
<script src="https://cdn.jsdelivr.net/npm/d3-dsv@3.0.1/dist/d3-dsv.min.js" integrity="sha256-IrzYc2a3nTkfvgAyowm/WKmIGdVCMCcccPtz+Y2y6VI=" crossorigin="anonymous"></script>
<input type="file" accept=".csv">
<button>test button</button>

<script>
const testData = `owner,repo,"branch name"
foo,demo,master
boo,"js awesome",sha1123456
`
document.querySelector(`input`).onchange = async e => 
  const input = e.target
  const file = input.files[0]
  const reader = new FileReader()
  reader.readAsText(new Blob(
    [file],
    "type": file.type
  ))
  const fileContent = await new Promise(resolve => 
    reader.onloadend = (event) => 
      resolve(event.target.result)
    
  )
  const csvData = d3.csvParse(fileContent)
  console.log(csvData)


document.querySelector(`button`).onclick = e => 
  const csvData =  d3.csvParse(testData)
  console.log(csvData)

</script>

下面的链接可以帮助你了解csvParse的实现

csv.js : csv, tsv(tab) 依赖于 dsv.js dsv.js

如果您只加载 CSV,则不要导入整个 JS。 (而不是d3-csv.js

https://cdn.jsdelivr.net/npm/d3@7.0.1/dist/d3.min.js

https://cdn.jsdelivr.net/npm/d3-dsv@3.0.1/dist/d3-dsv.min.js

【讨论】:

以上是关于使用 D3.js 解析上传的 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 d3.js 从 .csv 导入数据

D3.js 中的array_replace?

如何保存在 d3.js 脚本中构建的 JSON 数据

D3.js csv到html表

如何在php中上传和解析CSV文件

如何通过D3.js中的JSON文件解析按键对对象进行排序[重复]