Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data to d3.svg.line()

So,I have a Javascript object like:-

Object {data: Array[39], time: Array[39]}

object.data is an array of values while object.time is an array of javascript's date objects.

I'm trying to plot a line graph in D3. The relevant parts of my code:

    // Line function
    var line = d3.svg.line()
             .x(function(d,i) { return x(d.time); })
             .y(function(d,i) { return y(d.data); });

    // Draw Line
    svg.append("path")
                  .datum([data])
                  .attr("class", "line")
                  .attr("d", line);

The axes are in place like they should be with the data, but the line doesn't show up. I'm guessing I'm not returning the values to the x and y accessors of the line function like the way they should be. Any pointers?

Edit:

function draw(data) {

            // Margins and stuff
            var margin = {top: 20, right: 20, bottom: 20, left: 40};
            var width = 940 - margin.left - margin.right;
            var height = 500 - margin.top - margin.bottom;

            // X and Y axis' data
            var xAxisData = data.time;
            var yAxisData = data.data;

            // Scales
            var x = d3.time.scale().domain(d3.extent(xAxisData)).range([0, width]);
            // var x = d3.scale.linear().domain([100, 500]).range([0, width]);
            var y = d3.scale.linear().domain(d3.extent(yAxisData)).range([height, 0]);

            //Axes
            var xAxis = d3.svg.axis().scale(x).orient("bottom");
            var yAxis = d3.svg.axis().scale(y).orient("left");

            //Base Layer
            var svgContainer = d3.select('#graph').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 + ")");

            // Draw them Axes
            svgContainer.append("g").attr("class","axis bottom").attr("transform", "translate(0," + height + ")").call(xAxis);
            svgContainer.append("g").attr("class","axis left").call(yAxis);

            // Line function
            var line = d3.svg.line()
                .x(function(d,i) { console.log(i); return x(i); })
                .y(function(d,i) { console.log(d); return y(d.data); });

            var lineData = data.time.map(function (_, idx) {
                                console.log(data.data[idx], data.time[idx]);
                                return { data: data.data[idx], time: data.time[idx] };
                            });

            // Draw the Line
            svgContainer.append("path")
                  .datum([lineData])
                  .attr("class", "line")
                  .attr("d", line);

        }
like image 579
Arvind Avatar asked Feb 22 '14 12:02

Arvind


2 Answers

Your data indeed is not a line friendly format, you need to transpose it before the d3.svg.line can interpret it.

var lineData = data.time.map(function (_, idx) {
    return { data: data.data[idx], time: data.time[idx] }; 
});
like image 166
musically_ut Avatar answered Oct 13 '22 00:10

musically_ut


svg.append("path")
    .attr("class","line")
    .attr("d",line(object));

The whole path is a single SVG element, so you can pass it the whole data with the point values.

like image 34
FernOfTheAndes Avatar answered Oct 13 '22 02:10

FernOfTheAndes