2016-12-07 5 views
2

Основываясь на этом tutorial Я создал два графика с двумя метриками каждый. Каждые 5 секунд читается из файла csv, показывающего cpu% user и cpu% system в первом графике и свободной памяти - память, используемая во втором.Обновление графов автоматически в d3.js

Проблема в том, что обновляется только первая строка первого графика. Когда я удаляю пользователя cpu%, он обновляет только систему cpu%. Я также не могу обновить все показатели на обоих графиках своими топорами.

Есть ли здесь явная ошибка? Есть ли какой-нибудь другой учебник, похожий на то, что я пытаюсь сделать в d3.js?

Мой код

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

body { font: 12px Arial;} 

path { 
    stroke: black; 
    stroke-width: 2; 
    fill: none; 
} 

.axis path, 
.axis line { 
    fill: none; 
    stroke: grey; 
    stroke-width: 1; 
    shape-rendering: crispEdges; 
} 


</style> 
<body> 

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

<script> 

// Set the dimensions of the canvas/graph 
var margin = {top: 30, right: 20, bottom: 30, left: 50}, 
    width = 350 - 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); }); 

// Adds the svg canvas 
var chart1 = 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 + ")"); 
var chart2 = 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 + ")"); 

// Get the data 
d3.csv("data.csv", 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; 
    }); 

    var min = d3.min(data, function(d) { return Math.min(d.user, d.system); }); 
    x.domain(d3.extent(data, function(d) { return d.timestamp; })); 
    y.domain([min, d3.max(data, function(d) { return Math.max(d.user, d.system); })]); 

     chart1.append("path") 
     .data([data]) 
     .attr("class", "userLine") 
     .style("stroke", "green") 
     .attr("d", user(data)); 

    chart1.append("path") 
     .data([data]) 
     .attr("class", "systemLine") 
     .style("stroke", "blue") 
     .attr("d", system(data)); 

    // Add the X Axis 
    chart1.append("g") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    // Add the Y Axis 
    chart1.append("g") 
     .call(yAxis); 

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

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

}); 

d3.csv("data.csv", 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; 
    }); 

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

    chart2.append("path") 
     .data([data]) 
     .attr("class", "memFreeLine") 
     .style("stroke", "green") 
     .attr("d", memFree(data)); 

    chart2.append("path") 
     .data([data]) 
     .attr("class", "memUsedLine") 
     .style("stroke", "blue") 
     .attr("d", memUsed(data)); 

    // Add the X Axis 
    chart2.append("g") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    // Add the Y Axis 
    chart2.append("g") 
     .call(yAxis); 

    chart2.append("text") 
    .attr("transform", "translate(" + (width/4) + "," + y(data[0].memFree) + ")") 
    .attr("text-anchor", "start") 
    .style("fill", "green") 
    .text("memFree"); 

    chart2.append("text") 
    .attr("transform", "translate(" + (width/2) + "," + y(data[0].memUsed) + ")") 
    .attr("text-anchor", "start") 
    .style("fill", "blue") 
    .text("memUsed"); 

}); 

setInterval(function() { 
    updateChart1(); 
    updateChart2(); 
}, 5000); 

// ** Update data section (Called from the onclick) 
function updateChart1() { 
    // Get the data again 
    d3.csv("data.csv", 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; 
     }); 

    var min = d3.min(data, function(d) { return Math.min(d.user, d.system); }); 
    x.domain(d3.extent(data, function(d) { return d.timestamp; })); 
    y.domain([min, d3.max(data, function(d) { return Math.max(d.user, d.system); })]); 

    // Select the section we want to apply our changes to 
    var chart1 = d3.select("svg").transition(); 

    // Make the changes 
     chart1.select(".userLine") // change the line 
      .duration(750) 
      .attr("d", user(data)); 
     chart1.select(".systemLine") // change the line 
      .duration(750) 
      .attr("d", system(data)); 

     chart1.select(".x.axis") // change the x axis 
      .duration(750) 
      .call(xAxis); 
     chart1.select(".y.axis") // change the y axis 
      .duration(750) 
      .call(yAxis); 

    }); 
} 

function updateChart2() { 

    // Get the data again 
    d3.csv("data.csv", 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; 
     }); 

     // Scale the range of the data again 
    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); })]); 

    // Select the section we want to apply our changes to 
    var chart2 = d3.select("svg").transition(); 

    // Make the changes 
     chart2.select(".memFreeLine") // change the line 
      .duration(750) 
      .attr("d", memFree(data)); 
     chart2.select(".memUsedLine") // change the line 
      .duration(750) 
      .attr("d", memUsed(data)); 
     chart2.select(".x.axis") // change the x axis 
      .duration(750) 
      .call(xAxis); 
     chart2.select(".y.axis") // change the y axis 
      .duration(750) 
      .call(yAxis); 

    }); 
} 

</script> 
</body> 
+0

Я почти уверен, что это проблема, но прежде чем я напишу ответ, вы можете вставить ** свой ** код? –

+0

Обновлен мой вопрос @GerardoFurtado – jimakos17

ответ

1

Вот проблема: вы выбираете один и тот же элемент внутри обеих ваших updateChart функций:

chart1.select(".line")//class here is "line" 
     .duration(750) 
     .attr("d", user(data)); 
chart1.select(".line")//class here is "line" again! 
     .duration(750) 
     .attr("d", system(data)); 

См? Вы выбираете тот же класс (.line) как для пользователя, так и для системных данных.

Решение:

В начальной живописи, установить различные классы:

chart1.append("path") 
    .data([data]) 
    .attr("class", "userLine")//specific class 
    .style("stroke", "green") 
    .attr("d", user(data)); 

chart1.append("path") 
    .data([data]) 
    .attr("class", "systemLine")//specific class 
    .style("stroke", "blue") 
    .attr("d", system(data)); 

И затем, обновлять каждый из них в отдельности:

chart1.select(".userLine")//selecting different classes... 
     .duration(750) 
     .attr("d", user(data)); 
chart1.select(".systemLine")//selecting different classes... 
     .duration(750) 
     .attr("d", system(data)); 
+0

Я изменил строку на userLine, systemLine, memFreeLine и memUsedLine, и теперь она ничего не обновляет. Даже первая строка первого графика. – jimakos17

+0

Другая ошибка, которую я вижу, - это эта строка, которую вы должны удалить: 'var chart1 = d3.select (" svg "). Transition();' У вас была проблема. На данный момент я больше не могу помочь, если вы не создадите рабочий плункер или не скрипте с данными. –

+0

Я обновил свой код новыми классами. Когда я удалял строку var chart1 = d3.select ("svg"). Transition(); Я получил сообщение об ошибке Uncaught TypeError: chart1.select (...). Продолжительность не является функцией. Спасибо за вашу помощь. Gerardo – jimakos17