Multi series chart (D3) with missing values

charts, d3.js, javascript

Solution

I could solve it, but I'm not sure if I can handle data updates this way with transitions. I changed the data format a bit and am drawing each line separately now:

http://jsfiddle.net/G5z4N/3/

var data = [
    {
        name: "x1",
        color: "green",
        data: [
            [1, 0.8],
            [2, 0.9],
            [3, 0.9],
            [5, 0.8],
            [6, 0.9]
        ]
    },
    {
        name: "x2",
        color: "red",
        data: [
            [3, 1.2],
            [4, 1.1],
            [5, 1.1],
            [6, 1.2],
            [7, 1.3]
        ]
    },
    {
        name: "x3",
        color: "blue",
        data: [
            [1, 0.7],
            [2, 0.7],
            [3, 0.7],
            [4, 0.7],
            [5, 2.7],
            [6, 2.6],
            [7, 0.8]
        ]
    },
];

var margin = [20, 20, 20, 20];
var w = 400 - margin[1] - margin[3];
var h = 300 - margin[0] - margin[2];

var x = d3.time.scale().range([0, w]);
var y = d3.scale.linear().range([h, 0]);
var lineFunction = d3.svg.line()
    .x(function(d) { return x(d[0]); })
    .y(function(d) { return y(d[1]); });

graph = d3.select('#line')
    .append("svg:svg")
        .attr("class", "line-graph")
        .attr("width", w + margin[1] + margin[3])
        .attr("height", h + margin[0] + margin[2])  
    .append("svg:g")
        .attr("transform", "translate(" + margin[3] + "," + margin[0] + ")");

x.domain([
    d3.min(data, function(c) { return d3.min(c.data, function(v) { return v[0]; }); }),
    d3.max(data, function(c) { return d3.max(c.data, function(v) { return v[0]; }); })
]);

y.domain([
    d3.min(data, function(c) { return d3.min(c.data, function(v) {  return +v[1]; }); }),
    d3.max(data, function(c) { return d3.max(c.data, function(v) { return +v[1]; }); })
]);

var linesGroup = graph
    .append("svg:g")
        .attr("class", "lines");

var linedata;
for (var i in data) {
    linedata = data[i];
    linesGroup
        .append("path")
            .attr("d", lineFunction(linedata.data))
            .attr("class", "line")
            .attr("fill", "none")
            .attr("stroke", function(d, i) {
                console.log(linedata.color);
                return linedata.color;
            });
};

Problem

I want to create a multi series line chart with D3 based on this example. My problem is, that some of the values are missing: ``` y x1 x2 x3 1 0.8 0.7 2 0.9 0.7 3 0.9 1.2 0.7 4 1.1 0.7 5 0.8 1.1 2.7 6 0.9 1.2 2.6 7 1.3 0.8 ``` I want to get the following chart: Missing points at the beginnig or end should be left out. I could achieve that with ``` d3.svg.line().defined(function (d) { return d.value; } ``` But if some points are missing within a line, the line shouldn't be interrupted. With the code above the green line (x1) stops at y=3 and continues at y=5. But I want to have those points connected. Without the usage of `line().defined()`, all missing points were handled as if their value was `0`. Here is the code, I used to find a way to implement that feature: http://jsfiddle.net/G5z4N/2/ I think it is no solution for me to substitute the missing points in the data array before passing it to my charts function, because I have to show the values in a legend and in tooltips and I cannot show calculated values here. So for example if I move with the mouse over y=4, there should appear `x1:-- x2:1.1 x3:0.8` in the legend (x1 does not have any value here). Also the (real) points should be displayed as circles. I also don't want to have two data tables in the memory (one with the real measurement data and a second with the augmented data for the chart lines).

Original source