I want to draw multiple real time lines using JSON files. I am basically retrieving the JSON file from a website, getting the time data (duration in seconds), converting them into minutes and pushing them into the data array. This code checks the JSON file for every second.
I want to add as many line as possible. For example, I want to add the average of the elements in data array (average duration) and plot it on the same plane. I tried to add another "line" and "path" variable, however I wasn't able to plot it at the same time.
The data array is an empty array with 44 elements in the beginning, and everytime the code checks the JSON file it replaces those zeroes with the retrieved duration data.
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();
});
}
};
First, I included another another data array (data2) to push 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 the line that uses the points of 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 needed to select both of those lines to update them (You can write a function to do the same thing for these steps instead of 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 thing for transition and data shift as well
// 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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With