Real-time drawing of multiple lines

I want to draw multiple lines in real time using JSON files. I basically extract the JSON file from the website, getting the time data (duration in seconds), converting it into minutes and pushing it into a data array. This code checks the JSON file every second.

I want to add as many lines as possible. For example, I want to add the average value of the elements in the data array (average duration) and build it on one plane. I tried to add another variable called "string" and "path", but I was not able to build it at the same time.

The data array is an empty array with 44 elements at the beginning, and each time the code checks the JSON file, it replaces these zeros with data obtained with preservation of duration.

Here is my code to draw only one line.

function graph() { var n = 43, duration = 1000, now = new Date(Date.now() - duration), count = 0, data = d3.range(n).map(function() { return 0; }); var margin = {top: 10, right: 20, bottom: 30, left: 60}, width = 1200 - margin.left-margin.right, height = 460 - margin.top - margin.bottom; var x = d3.time.scale() .domain([now - (n - 2) * duration, now - duration]) .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var line = d3.svg.line() .interpolate("basis") .x(function(d, i) { return x(now - (n - 1 - i) * duration); }) .y(function(d, i) { return y(d); }); var line2 = d3.svg.line() .interpolate("basis") .x(function(d, i) { return x(now - (n - 1 - i) * duration); }) .y(function(d, i) { return y(d); }); var svg = d3.select("body").append("p").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .style("margin-left", -margin.left + "px") .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); var axis = svg.append("g") .attr("class", "x axis") .attr("transform", "translate( "+margin.left+"," + height + ")") .call(x.axis = d3.svg.axis().scale(x).orient("bottom")); var yaxis = svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + margin.left + ",0)") .call(y.axis = d3.svg.axis().scale(y).orient("left")); d3.select(".y.axis") .append("text") .text("Travel Time (min)") .attr("text-anchor", "middle") .attr("transform","rotate( -90, 200, 0)") .attr("y",-250); var path = svg.append("g") .attr("clip-path", "url(#clip)") .attr("transform", "translate(" + margin.left + ",0)") .append("path") .data([data]) .attr("class", "line"); tick(); function tick() { d3.json("route.json",function(barzo){ var tempdata = barzo.route; var len = tempdata.realTime; var lastdata = parseInt(len)/60; //this is the time variable I use. // update the domains now = new Date(); x.domain([now - (n - 2) * duration, now - duration]); y.domain([0, d3.max(data)+5]); // push the time into the data data.push(count); count = lastdata; // redraw the line svg.select(".line") .attr("d", line) .attr("transform", null); // slide the x-axis left axis.transition() .duration(duration) .ease("linear") .call(x.axis); yaxis.transition() .duration(duration/10) .ease("linear") .call(y.axis); // slide the line left path.transition() .duration(duration) .ease("linear") .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")") .each("end", tick); // pop the old data point off the front data.shift(); }); } }; 
+6
source share
1 answer

First, I included another data array (data2) to direct the new data points for the new path:

  var n = 43, duration = 1000, now = new Date(Date.now() - duration), count = 0, data = d3.range(n).map(function() { return 0; }); data2 = d3.range(n).map(function() { return 0; }); 

Then I defined another path for a row that uses the points of the data2 array.

 var path2 = svg.append("g") .attr("clip-path", "url(#clip)") .attr("transform", "translate(" + margin.left + ",0)") .append("path") .data([data2]) .attr("class", "line2") 

In the tick function, I had to select both of these lines to update them (you can write a function to do the same for these steps, rather than repeating the same code twice).

  // redraw the line svg.select(".line") .attr("d", line) .attr("transform", null); svg.select(".line2") .attr("d", line2) .attr("transform", null); 

The same goes for data transition and shift

  // slide the line left path.transition() .duration(duration) .ease("linear") .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")"); path2.transition() .duration(duration) .ease("linear") .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")") .each("end", tick); // pop the old data point off the front data.shift(); data2.shift(); 
+3
source

All Articles