【问题标题】:Problems parsing CSV into HTML table with d3.js使用 d3.js 将 CSV 解析为 HTML 表时出现问题
【发布时间】:2016-11-19 17:44:28
【问题描述】:

我在 JQuery 和 CSV 解析方面都是新手,我很难做到这一点。

我的 CSV 文件正在由 Javascript 从另一个页面的 HTML 表中生成和下载:

var table = document.getElementById("mytableid").innerHTML;
var data = table.replace(/<thead>/g, '')
.replace(/<\/thead>/g, '') 
.replace(/<tbody>/g, '') 
.replace(/<\/tbody>/g, '')
.replace(/<tr>/g, '') 
.replace(/<\/tr>/g, '\r\n')
.replace(/<th>/g, '') 
.replace(/<\/th>/g, ',')
.replace(/<td>/g, '') 
.replace(/<\/td>/g, ',')
.replace(/\t/g, '');
.replace(/\n/g, '');
var mylink = document.createElement('a');
mylink.download = "mycsvfile.csv";
mylink.href = "data:application/csv," + escape(data);
mylink.click();

下载正确进行。在我要显示该 CSV 下载文件的页面中,我的脚本如下所示:

d3.text("mycsvfile.csv", function(datasetText) {
var parsedCSV = d3.csv.parseRows(datasetText);
var sampleHTML = d3.select("#divid")
.append("table")
.selectAll("tr")    
.data(parsedCSV)
.enter().append("tr")
.selectAll("td")
.data(function(d){return d;})
.enter().append("td")  
.text(function(d){return d;})
}); 

它正确显示了 CSV 表,只是右侧显示了一个空白列(原始文件中不存在),就好像它在每个 tr 中创建了最后一个空白 td。此外,它似乎没有检测到我的 th:它将它们显示为常见的 td。

关于为什么会发生这种情况以及如何解决它有什么想法吗? 提前致谢!

【问题讨论】:

    标签: javascript jquery html csv d3.js


    【解决方案1】:

    这里有一些问题,比如这个:

    此外,它似乎没有检测到我的 th:它将它们显示为普通的 td。

    您的代码中没有任何th。除此之外,链接不正确。

    话虽如此,我认为使用 D3 附加表格的最佳方式是明确定义谁是头部、谁是主体、谁是行以及谁是单元格。

    所以,假设你有这个假数据:

    foo,bar,baz
    21,43,55
    32,77,65
    12,66,42
    42,88,42
    

    第一步,定义组件:

    var body = d3.select("body");
    var table = body.append('table')
    var thead = table.append('thead')
    var tbody = table.append('tbody');
    

    为了打印表格标题,我们使用Object.keys()获取CSV中的标题行:

    var headers = Object.keys(datasetText[0]);
    

    然后我们显示它:

    var head = thead.selectAll('th')
        .data(headers)
        .enter()
        .append('th')
        .text(function (d) { return d; });
    

    现在,对于表的主体,我们创建行:

    var rows = tbody.selectAll('tr')
        .data(datasetText)
        .enter()
        .append('tr');
    

    然后我们使用Object.values() 创建单元格:

    var cells = rows.selectAll('td')
        .data(function (d) {
            return Object.values(d);
        })
        .enter()
        .append('td')
        .text(function (d) { return d; });
    

    请注意Object.values() 无法在 IE、Safari 或 Opera(目前仅 Chrome 和 Firefox)中使用。您可以使用 polyfill 或等效函数,例如 for...in 循环:

        var cells = rows.selectAll('td')
        .data(function(d) {
            var arr = [];
            for (var i in d) {
                arr.push(d[i])
            }
            return arr;
        })
        .enter()
        .append('td')
        .text(function(d) { return d;});
    

    这是 Plunker:https://plnkr.co/edit/kanrGplVfirTgc5Qm2lc?p=preview

    并且,为了避免将 plunker 作为外部链接,这里是使用 SO sn-p 的相同代码(我必须在相应的对象数组中转换 CSV,因为在 SO sn-ps 中加载 CSV 很复杂):

    var datasetText = [{
        foo: 32,
        bar: 43,
        baz: 31
    }, {
        foo: 12,
        bar: 88,
        baz: 11
    }, {
        foo: 33,
        bar: 88,
        baz: 21
    }, {
        foo: 17,
        bar: 33,
        baz: 42
    }];
    
    var body = d3.select("body");
    
    var headers = Object.keys(datasetText[0]);
    
    var table = body.append('table')
    var thead = table.append('thead')
    var tbody = table.append('tbody');
    
    var head = thead.selectAll('th')
        .data(headers)
        .enter()
        .append('th')
        .text(function(d) {
            return d;
        });
    
    var rows = tbody.selectAll('tr')
        .data(datasetText)
        .enter()
        .append('tr');
    
    var cells = rows.selectAll('td')
        .data(function(d) {
            return Object.values(d);
        })
        .enter()
        .append('td')
        .text(function(d) {
            return d;
        });
    .table-fill {
      background: white;
      border-radius:3px;
      border-collapse: collapse;
      height: 320px;
      margin: auto;
      max-width: 600px;
      padding:5px;
      width: 100%;
      box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
      animation: float 5s infinite;
    }
     
    th {
      color:#D5DDE5;;
      background:#1b1e24;
      border-bottom:4px solid #9ea7af;
      border-right: 1px solid #343a45;
      font-size:23px;
      font-weight: 100;
      padding:10px;
      text-align:left;
      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
      vertical-align:middle;
    }
    
    th:first-child {
      border-top-left-radius:3px;
    }
     
    th:last-child {
      border-top-right-radius:3px;
      border-right:none;
    }
      
    tr {
      border-top: 1px solid #C1C3D1;
      border-bottom-: 1px solid #C1C3D1;
      color:#666B85;
      font-size:16px;
      font-weight:normal;
      text-shadow: 0 1px 1px rgba(256, 256, 256, 0.1);
    }
     
    tr:hover td {
      background:#4E5066;
      color:#FFFFFF;
      border-top: 1px solid #22262e;
      border-bottom: 1px solid #22262e;
    }
     
    tr:first-child {
      border-top:none;
    }
    
    tr:last-child {
      border-bottom:none;
    }
     
    tr:nth-child(odd) td {
      background:#EBEBEB;
    }
     
    tr:nth-child(odd):hover td {
      background:#4E5066;
    }
    
    tr:last-child td:first-child {
      border-bottom-left-radius:3px;
    }
     
    tr:last-child td:last-child {
      border-bottom-right-radius:3px;
    }
     
    td {
      background:#FFFFFF;
      padding:10px;
      text-align:left;
      vertical-align:middle;
      font-weight:300;
      font-size:18px;
      text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.1);
      border-right: 1px solid #C1C3D1;
    }
    
    td:last-child {
      border-right: 0px;
    }
    
    th.text-left {
      text-align: left;
    }
    
    th.text-center {
      text-align: center;
    }
    
    th.text-right {
      text-align: right;
    }
    
    td.text-left {
      text-align: left;
    }
    
    td.text-center {
      text-align: center;
    }
    
    td.text-right {
      text-align: right;
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      • 2019-09-04
      • 2015-06-23
      • 1970-01-01
      • 2016-07-04
      • 2019-03-31
      • 1970-01-01
      相关资源
      最近更新 更多