代码之家  ›  专栏  ›  技术社区  ›  Ilan Aizelman WS

只使用.csv文件中的两列构造多个条形图

  •  2
  • Ilan Aizelman WS  · 技术社区  · 6 年前

    我正试图通过使用.csv列数据(见下图)来实现这一点。我指的是用交易成本和零售价表示一个条形图。X轴是汽车类型,Y轴的增量为5000。目前,我的代码通过使用for循环遍历所有列,从而构建包含所有列的条形图来显示所有列。(见下图三) 在试图编辑for循环以只遍历前3列之后,图表上没有任何更改,我也不知道为什么,我想知道我做错了什么。

    注: 我不想删除/更改任何.csv文件数据。

    我想达到的目标是:

    enter image description here 我的.csv文件数据:

    enter image description here

    到目前为止我所取得的成就:

    enter image description here

    代码:

    <!DOCTYPE html>
    <style>
    .axis .domain {
      display: none;
    }
    </style>
    <svg width="960" height="500"></svg>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
    var svg = d3.select("svg"),
        margin = {top: 20, right: 20, bottom: 30, left: 40},
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom,
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    var x0 = d3.scaleBand()
        .rangeRound([0, width])
        .paddingInner(0.1);
    var x1 = d3.scaleBand()
        .padding(0.05);
    var y = d3.scaleLinear()
        .rangeRound([height, 0]);
    var z = d3.scaleOrdinal()
        .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
    d3.csv("carsAggregated.csv", function(d, i, columns) {
      for (var i = 1, n = columns.length; i < n; ++i) d[columns[i]] = +d[columns[i]];
      return d;
    }, function(error, data) {
      if (error) throw error;
      var keys = data.columns.slice(1);
      x0.domain(data.map(function(d) { return d.CarType; }));
      x1.domain(keys).rangeRound([0, x0.bandwidth()]);
      y.domain([0, d3.max(data, function(d) { return d3.max(keys, function(key) { return d[key]; }); })]).nice();
      g.append("g")
        .selectAll("g")
        .data(data)
        .enter().append("g")
          .attr("transform", function(d) { return "translate(" + x0(d.CarType) + ",0)"; })
        .selectAll("rect")
        .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
        .enter().append("rect")
          .attr("x", function(d) { return x1(d.key); })
          .attr("y", function(d) { return y(d.value); })
          .attr("width", x1.bandwidth())
          .attr("height", function(d) { return height - y(d.value); })
          .attr("fill", function(d) { return z(d.key); });
      g.append("g")
          .attr("class", "axis")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x0));
      g.append("g")
          .attr("class", "axis")
          .call(d3.axisLeft(y).ticks(null, "s"))
        .append("text")
          .attr("x", 2)
          .attr("y", y(y.ticks().pop()) + 0.5)
          .attr("dy", "0.32em")
          .attr("fill", "#000")
          .attr("font-weight", "bold")
          .attr("text-anchor", "start")
          .text("USD Dollars ($)");
      var legend = g.append("g")
          .attr("font-family", "sans-serif")
          .attr("font-size", 10)
          .attr("text-anchor", "end")
        .selectAll("g")
        .data(keys.slice().reverse())
        .enter().append("g")
          .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
      legend.append("rect")
          .attr("x", width - 19)
          .attr("width", 19)
          .attr("height", 19)
          .attr("fill", z);
      legend.append("text")
          .attr("x", width - 24)
          .attr("y", 9.5)
          .attr("dy", "0.32em")
          .text(function(d) { return d; });
    });
    </script>
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Andrew Reid    6 年前

    此行:

    var keys = data.columns.slice(1);
    

    这将从csv中提取标题名称(删除第一个是另一个轴-汽车类型)。这些键用于在图表中创建不同的系列(此处: .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); }) )

    如果我们只需要前两个数据列(除去汽车类型后),我们可以使用:

    var keys = data.columns.slice(1).slice(0,2);
    

    这将获取除第一个标题(汽车类型)以外的所有标题,然后除去前两个剩余列以外的所有内容。

    当然,我们可以缩短这个过程(谢谢 Gerardo ,使用一次切片:

    var keys = data.columns.slice(1,3); 
    

    不管怎样, keys 仍然是一个包含两列的数组,因此我们可以正常继续。 Here's 一个基本的模型,其中有一些仓促制造的假数字、假车型和一些专栏。