Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 multi-series line chart from pivoted JSON

Tags:

d3.js

There is a great example of a multi-series line chart here http://bl.ocks.org/mbostock/3884955 and if the tsv data were laid out I'm sure it would look something like this:

[
  {
    "date": "20111001",
    "New York": "63.4",
    "San Francisco": "62.7",
    "Austin": "72.2"
  },
  {
    "date": "20111002",
    "New York": "58.0",
    "San Francisco": "59.9",
    "Austin": "67.7"
  },
  {
    "date": "20111003",
    "New York": "53.3",
    "San Francisco": "59.1",
    "Austin": "69.4"
  }
]

The issue I have is that I may not always know the keys, cities in this case, and would not want a solution that stores the cities in the key.

If my data looked like this:

[
    {
        "City": "New York",
        "Data": [
            {
                "Date": "20111001",
                "Value": "63.4"
            },
            {
                "Date": "20111002",
                "Value": "58.0"
            },
            {
                "Date": "20111003",
                "Value": "53.3"
            }
        ]
    },
    {
        "City": "San Francisco",
        "Data": [
            {
                "Date": "20111001",
                "Value": "62.7"
            },
            {
                "Date": "20111002",
                "Value": "59.9"
            },
            {
                "Date": "20111003",
                "Value": "59.1"
            }
        ]
    },
    {
        "City": "Austin",
        "Data": [
            {
                "Date": "20111001",
                "Value": "72.2"
            },
            {
                "Date": "20111002",
                "Value": "67.7"
            },
            {
                "Date": "20111003",
                "Value": "69.4"
            }
        ]
    }
]

Is there a way to map my data to the first format OR what would I need to change in the code to get the same multi-series line chart?

Here is a jsfiddle http://jsfiddle.net/p8S7p/

like image 421
greenafrican Avatar asked Nov 16 '13 08:11

greenafrican


1 Answers

The date in the example, is actually transformed somewhat to look like the data you have:

var cities = color.domain().map(function(name) {
  return {
    name: name,
    values: data.map(function(d) {
      return {date: d.date, temperature: +d[name]};
    })
  };
});

The difference is that this data contains only arrays of arrays while your format contains array of objects, where each object contains the array inside the object as obj.Data.

It is easy to make the changes to make the demo run Demo.

The primary problem was how to calculate the min/max of the Date and Value for the scales:

In the original example:

x.domain(d3.extent(data, function (d) {
    return d.date;
}));

y.domain([
d3.min(cities, function (c) {
    return d3.min(c.values, function (v) {
        return v.temperature;
    });
}),
d3.max(cities, function (c) {
    return d3.max(c.values, function (v) {
        return v.temperature;
    });
})]);

For the changed format:

var minX = d3.min(data, function (kv) { return d3.min(kv.Data, function (d) { return d.Date; }) });
var maxX = d3.max(data, function (kv) { return d3.max(kv.Data, function (d) { return d.Date; }) });
var minY = d3.min(data, function (kv) { return d3.min(kv.Data, function (d) { return d.Value; }) });
var maxY = d3.max(data, function (kv) { return d3.max(kv.Data, function (d) { return d.Value; }) });

x.domain([minX, maxX]);
y.domain([minY, maxY]);
like image 83
musically_ut Avatar answered Sep 24 '22 03:09

musically_ut