Question

I am new to d3.js and am trying to graph three lines on the same plot. I'm reading from a tsv file with four columns: time, x, y, and z. This is accelerometer data. I want to plot the x,y,z columns vs time but can't seem to get it. Any suggestions?

    function graph(){

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

// 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 valueline = d3.svg.line()
    .x(function(d) { return x(d.time); })
    .y(function(d) { return y(d.x); });

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

var     valueline3 = d3.svg.line()
        .x(function(d) { return x(d.time); })
        .y(function(d) { return y(d.z); });

// Adds the svg canvas
var svg = 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.tsv("data/data2.tsv", function(error, data) {
    data.forEach(function(d) {
        d.time = +d.time;
        d.x = +d.x;
                d.y = +d.y;
                d.z = +d.z;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.time; }));
    y.domain([0, d3.max(data, function(d) { return Math.max(d.x, d.y, d.z); })]);

    // Add the valueline path.
    svg.append("path")      // Add the valueline path.
        .attr("class", "line")
        .attr("d", valueline(data));

        svg.append("path")      // Add the valueline path.
        .attr("class", "line")
                .style("stroke", "red")
        .attr("d", valueline2(data));

        svg.append("path")      // Add the valueline path.
        .attr("class", "line")
                .style("stroke", "green")
        .attr("d", valueline3(data));

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

    // Add the Y Axis
    svg.append("g")         // Add the Y Axis
        .attr("class", "y axis")
        .call(yAxis);

});}
Was it helpful?

Solution

You can add each line one at a time to the canvas but it's not very d3 or efficient. It's much better to organise your data in the appropriate way. So the the main issue is the way that the data's been prepared. In the example that Lar's pointed to the data is nested using this block of code:

var series = color.domain().map(function(name) {
    return {
        name: name,
        values: data.map(function(d) {
            return {
                time: d.time,
                score: +d[name]
            };
        })
    };
});

And what this does is to create an array of 3 objects. Each object has a key value pair: name and an array. In each array is another object which contains the time and score information for plotting. It is this last array of object that is passed to the line generator.

I've created a fiddle, here, that's heavily based on the example that Lar's has pointed to and it's commented throughout. The trick at this stage is to inspect the elements and use console.log

Best of luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top