【问题标题】:Create multiple graphs from different files in d3.js从 d3.js 中的不同文件创建多个图形
【发布时间】:2016-12-08 15:19:09
【问题描述】:

我为笔记本电脑的 CPU、内存和 I/O 创建了三个图表,效果很好。我现在正试图包括第二台电脑并显示相应的三个图表。 我已经创建了一个文件名为 var files = ["data1.csv", "data2.csv"] 的数组,并且我正在努力运行两倍的代码以获得六个图表。

 <!DOCTYPE html>
    <meta charset="utf-8">
    <style> /* set the CSS */

    body { font: 14px Arial;}

    path { 
        stroke: black;
        stroke-width: 2;
        fill: none;
    }
    </style>
    <body>

    <!-- load the d3.js library -->    
    <script src="http://d3js.org/d3.v3.min.js"></script>

    <script>

    var files = ["data1.csv", "data2.csv"]

    // Set the dimensions of the canvas / graph
    var margin = {top: 30, right: 20, bottom: 30, left: 50},
        width = 400 - margin.left - margin.right,
        height = 250 - margin.top - margin.bottom;

    // Parse the date / time
    var parseTime = d3.time.format("%d-%m-%Y:%H:%M").parse;

    // Set the ranges
    var x = d3.time.scale().range([0, width]);
    var y = d3.scale.linear().range([height, 0]);

    // Define the axes
    var xAxis = d3.svg.axis().scale(x)
        .orient("bottom").ticks(5);

    var yAxis = d3.svg.axis().scale(y)
        .orient("left").ticks(5);

    // Define the line
    var user = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.user); });

    var system = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.system); });

    var memFree = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.memFree); });

    var memUsed = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.memUsed); });

    var sda = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.sda); });

    var sdb = d3.svg.line()
        .x(function(d) { return x(d.timestamp); })
        .y(function(d) { return y(d.sdb); });   

   var funcs = {};
   for (var l = 0; l < files.length; l++) {
     funcs[l] = function(i) {

      console.log("0"+window["chart" + i*3]);
       window["chart" + i*3]  = d3.select("body")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
          .append("g")
              .attr("transform", 
                    "translate(" + margin.left + "," + margin.top + ")");

       window["chart" + i*3 +1]  = d3.select("body")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
          .append("g")
              .attr("transform", 
                    "translate(" + margin.left + "," + margin.top + ")");

       window["chart" + i*3 +2]  = d3.select("body")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
          .append("g")
              .attr("transform", 
                    "translate(" + margin.left + "," + margin.top + ")");

      console.log("1"+window["chart" + i*3]);



        d3.csv(files[i], function(error, data) {
            data.forEach(function(d) {
                  d.timestamp = parseTime(d.timestamp);
                  d.user = +d.user;
                  d.system = +d.system;
                  d.memFree = +d.memFree;
                  d.memUsed = +d.memUsed;
                  d.sda = +d.sda;
                  d.sdb = +d.sdb;
            });

            console.log("2"+window["chart" + i*3]);
            var min = d3.min(data, function(d) { return Math.min(d.user, d.system); });
            console.log("3"+window["chart" + i*3]);
            x.domain(d3.extent(data, function(d) { return d.timestamp; }));
            console.log("4"+window["chart" + i*3]);
            y.domain([min, d3.max(data, function(d) { return Math.max(d.user, d.system); })]);

          console.log("5"+window["chart" + i*3]);
          window["chart" + i*3].append("path")
              .data([data])
              .attr("class", "userLine")
              .style("stroke", "green")
              .attr("d", user(data));

          window["chart" + i*3].append("path")
              .data([data])
              .attr("class", "systemLine")
              .style("stroke", "blue")
              .attr("d", system(data));

          window["chart" + i*3].append("path")
              .data([data])
              .attr("class", "iowaitLine")
              .style("stroke", "red")
              .attr("d", iowait(data));

          // Add the X Axis
          window["chart" + i*3].append("g")
              .attr("transform", "translate(0," + height + ")")
              .attr("class", window["chart" + i*3]+"xAxis")
              .call(xAxis);

          // Add the Y Axis
          window["chart" + i*3].append("g")
              .attr("class", window["chart" + i*3]+"yAxis")
              .call(yAxis);

          window["chart" + i*3].append("text")
            .attr("transform", "translate(" + (width/4) + "," + y(data[0].user) + ")")
            .attr("text-anchor", "start")
            .style("fill", "green")
            .text("%user");

          window["chart" + i*3].append("text")
            .attr("transform", "translate(" + (width/5) + "," + y(data[0].system) + ")")
            .attr("text-anchor", "start")
            .style("fill", "blue")
            .text("%system");
        });


        d3.csv(files[i], function(error, data) {
            data.forEach(function(d) {
                  d.timestamp = parseTime(d.timestamp);
                  d.user = +d.user;
                  d.system = +d.system;
                  d.memFree = +d.memFree;
                  d.memUsed = +d.memUsed;
                  d.sda = +d.sda;
                  d.sdb = +d.sdb;
            });

            // Scale the range of the data
          var min = d3.min(data, function(d) { return Math.min(d.memFree, d.memUsed); });
          x.domain(d3.extent(data, function(d) { return d.timestamp; }));
          y.domain([min, d3.max(data, function(d) { return Math.max(d.memFree, d.memUsed); })]);

          window["chart" + i*3 +1].append("path")
              .data([data])
              .attr("class", "memFreeLine")
              .style("stroke", "green")
              .attr("d", memFree(data));

          window["chart" + i*3 +1].append("path")
              .data([data])
              .attr("class", "memUsedLine")
              .style("stroke", "blue")
              .attr("d", memUsed(data));

          // Add the X Axis
          window["chart" + i*3 +1].append("g")
              .attr("transform", "translate(0," + height + ")")
              .attr("class", window["chart" + i*3+1]+"xAxis")
              .call(xAxis);

          // Add the Y Axis
          window["chart" + i*3 +1].append("g")
               .attr("class", window["chart" + i*3+1]+"yAxis")
              .call(yAxis);

          window["chart" + i*3 +1].append("text")
            .attr("transform", "translate(" + (width/4) + "," + y(data[0].memFree) + ")")
            .attr("text-anchor", "start")
            .style("fill", "green")
            .text("memFree");

          window["chart" + i*3 +1].append("text")
            .attr("transform", "translate(" + (width/2) + "," + y(data[0].memUsed) + ")")
            .attr("text-anchor", "start")
            .style("fill", "blue")
            .text("memUsed");

        });

        d3.csv(files[i], function(error, data) {
            if (error) throw error;
            data.forEach(function(d) { 
                    d.timestamp = parseTime(d.timestamp);
                    d.user = +d.user;
                    d.system = +d.system;
                    d.memFree = +d.memFree;
                    d.memUsed = +d.memUsed;
                    d.sda = +d.sda;
                    d.sdb = +d.sdb;
                  });

            // Scale the range of the data
            var min = d3.min(data, function(d) { return d.sda, d.sdb; });
            x.domain(d3.extent(data, function(d) { return d.timestamp; }));
            y.domain([min, d3.max(data, function(d) { return Math.max(d.sda, d.sdb); })]);

            window["chart" + i*3 +2].append("path")
                .data([data])
                .attr("class", "sdaLine")
                .style("stroke", "green")
                .attr("d", sda);

            window["chart" + i*3 +2].append("path")
                .data([data])
                .attr("class", "sdbLine")
                .style("stroke", "blue")
                .attr("d", sdb);

            window["chart" + i*3 +2].append("path")
                .data([data])
                .attr("class", "nvme0n1Line")
                .style("stroke", "red")
                .attr("d", nvme0n1);

            // Add the X Axis
            window["chart" + i*3 +2].append("g")
                .attr("transform", "translate(0," + height + ")")
                .attr("class", window["chart" + i*3*2]+"xAxis")
                .call(xAxis);

            // Add the Y Axis
            window["chart" + i*3 +2].append("g")
            .attr("class", window["chart" + i*3+2]+"yAxis")
                .call(yAxis);

            window["chart" + i*3 +2].append("text")
              .attr("transform", "translate(" + (width/2) + "," + y(data[0].sda) + ")")
              .attr("text-anchor", "start")
              .style("fill", "green")
              .text("sda");

             window["chart" + i*3 +2].append("text")
              .attr("transform", "translate(" + (width/2) + "," + y(data[0].sdb) + ")")
              .attr("text-anchor", "start")
              .style("fill", "blue")
              .text("sdb");

          });
     }.bind(this, l);
}


    </script>
    </body>

我最初希望以这种方式获得chart0、chart1、chart2,然后是chart3、chart4、chart5。如果我要添加第三台电脑,我只需要更新数组。不幸的是,它不起作用。

我打印我的 i var 但之后

d3.csv(files[iBound], function(error, data) {

我正在失去它。我试图以这种方式绑定 i (如我在代码中所示),但无法弄清楚。这样,它什么也不做。

基于这个example我也试过了

var funcs = {};
for (var l = 0; l < files.length; l++) {
    funcs[l] = function(j) {

    console.log("0"+window["chart" +  j*3]);
     window["chart" + j*3]  = d3.select("body")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
        .append("g")
            .attr("transform", 
                  "translate(" + margin.left + "," + margin.top + ")");

     window["chart" + j*3 +1]  = d3.select("body")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
        .append("g")
            .attr("transform", 
                  "translate(" + margin.left + "," + margin.top + ")");

     window["chart" + j*3 +2]  = d3.select("body")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
        .append("g")
            .attr("transform", 
                  "translate(" + margin.left + "," + margin.top + ")");

    console.log("1"+window["chart" + i*3]);
 }.bind(this, l);
}

for (var i = 0; i < files.length; i++) {  
  funcs[i]();
    d3.csv(files[i], function(error, data) {
        data.forEach(function(d) {
              d.timestamp = parseTime(d.timestamp);
              d.user = +d.user;
              d.system = +d.system;
              d.iowait = +d.iowait;
              d.memFree = +d.memFree;
              d.memUsed = +d.memUsed;
              d.sda = +d.sda;
              d.sdb = +d.sdb;
              d.nvme0n1 = +d.nvme0n1;
        });


        console.log("2"+window["chart" + i*3]);

但 i 再次变得未定义。有什么帮助吗?

更新 我只有一个带有两行数据的图表,其中包含来自 data1.csv 文件的数据。 我想拥有来自不同文件的数据的相同图表。 这就是我到目前为止所做的。 JSFiddle

【问题讨论】:

  • 我的猜测是您没有针对主图表绘制代码中的每个单独的 SVG。但是,您确实需要添加您的代码,以便我们检查。
  • 谢谢@MatthewWilcoxson 我刚刚添加了我的代码。

标签: javascript csv d3.js graph


【解决方案1】:

您的 i 变量在任何 CSV 加载发生之前的值为 4,因此您需要在执行其余代码时“记住”该值。

查看这些答案以获取更多信息:

我建议将您的代码包装成一个函数并绑定 i 值,例如:

for (var i = 0; i < 3; i++) {
    function(iBound) {
        d3.csv(files[iBound], function(error, data) {
            // etc.
        });
        // etc
    }.bind(this, i); // Bind the value
}

【讨论】:

  • 谢谢@Mathew,但我无法成功。我尝试了您对我的建议并更新了我的问题。
  • 你说得对。绑定函数只是创建一个函数,你仍然需要执行它。在您链接到的示例中,只需添加一个循环来调用每个函数,例如:for (var j = 0; j &lt; files.length; j++) { funcs[j](); }
  • 还有一个提示,您的代码将 funcs 设置为一个对象,但您将其用作数组。我会使用 var funcs = []; 。虽然一个对象确实可以工作,但如果您希望使用特定于数组类型的函数(例如 forEach、push 和 pop),它可能会在未来引起问题
  • 非常感谢您的帮助。我试过你告诉我的,并用 JSFiddle 更新了我的问题。我试图让它尽可能简单以使其工作,但我仍然坚持这一点。
猜你喜欢
  • 1970-01-01
  • 2014-03-20
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 2015-05-10
相关资源
最近更新 更多