0

I have created three charts for cpu, memory and i/o for my laptop and it works well. I'm now trying to include a second pc and display the according three charts. I've created an array with the filenames var files = ["data1.csv", "data2.csv"] and I'm struggling to run twice the code that I have in order to have six graphs.

 <!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>

I expected that in this way initially I would have chart0, chart1, chart2 and then chart3, chart4, chart5. In case I would add third pc I sould just update the array. Unfortunately, it doesn't work.

I print my i var but after

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

I'm loosing it. I tried to bind i in this way (as I show in my code) but couldn't figure it out. In that way it does nothing.

Based on this example I also tried

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]);

but the i becomes again undefined. Any help please?

UPDATE I have only one chart with two lines with data from a data1.csv file. I'd like to have the same chart with data from a different file. That's what I've done so far. JSFiddle

jimakos17
  • 905
  • 4
  • 14
  • 33

1 Answers1

0

You i variable has the value of 4 before any of you CSV loads can occur so you'll need to "remember" that value when executing the rest of the code.

Checkout these answers for more information:

I'd suggest wrapping your code into a function and binding the i value, for instance:

for (var i = 0; i < 3; i++) {
    function(iBound) {
        d3.csv(files[iBound], function(error, data) {
            // etc.
        });
        // etc
    }.bind(this, i); // Bind the value
}
Community
  • 1
  • 1
Matthew Wilcoxson
  • 3,432
  • 1
  • 43
  • 48
  • Thank you @Mathew but I couldn't make it work. I tried what you suggested to me and updated my question. – jimakos17 Dec 09 '16 at 20:17
  • You are amlost right. The bind function just *creates* a function, you still have to execute it. As in the example you link to, just add a loop to call each function, e.g.: ```for (var j = 0; j < files.length; j++) { funcs[j](); }``` – Matthew Wilcoxson Dec 10 '16 at 14:29
  • One more tip, your code sets funcs to an object but you are using it like an array. I would use ```var funcs = [];``` . While an object does work it may cause problems in the future if you expect functions specific to the array type (such as forEach, push and pop) – Matthew Wilcoxson Dec 10 '16 at 14:40
  • thank you very much for your help. I tried what you told me and updated my question with JSFiddle. I tried to make it as simple as I can to make it work but I'm still stuck on this. – jimakos17 Dec 10 '16 at 16:40