最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - d3 JSON multiple line chart - Stack Overflow

programmeradmin1浏览0评论

I'm trying to make a plot with multiple lines on it from a JSON blob that looks like:

{"2007": [{"val":10, "mon":10}, {"val":20, "mon":11}, {"val":40, "mon":12}, ...],
 "2008": [{"val":20, "mon":8}, {"val":20, "mon":9}, {"val":40, "mon":10}, ...],
  ...
 "2012": [{"val":40, "mon":8}, {"val":50, "mon":9}, {"val":60, "mon":10}, ...]
}

The data is basically monthly totals for each year, with some years not having data for some months. I can't figure out exactly how to parse the data in d3 though. I tried various ways such as

var line = d3.svg.line()
 .interpolate("basis")
.x(function(d) { return x(d.mon); })
.y(function(d) { return y(d.val); });

svg.selectAll(".line")
 .data(series)
 .enter().append("path")
 .attr("class", "line")
 .attr("d", line);

But I can't seem to get the data into the SVG line. Any suggestions? Is there a better way to structure the JSON?

I'm trying to make a plot with multiple lines on it from a JSON blob that looks like:

{"2007": [{"val":10, "mon":10}, {"val":20, "mon":11}, {"val":40, "mon":12}, ...],
 "2008": [{"val":20, "mon":8}, {"val":20, "mon":9}, {"val":40, "mon":10}, ...],
  ...
 "2012": [{"val":40, "mon":8}, {"val":50, "mon":9}, {"val":60, "mon":10}, ...]
}

The data is basically monthly totals for each year, with some years not having data for some months. I can't figure out exactly how to parse the data in d3 though. I tried various ways such as

var line = d3.svg.line()
 .interpolate("basis")
.x(function(d) { return x(d.mon); })
.y(function(d) { return y(d.val); });

svg.selectAll(".line")
 .data(series)
 .enter().append("path")
 .attr("class", "line")
 .attr("d", line);

But I can't seem to get the data into the SVG line. Any suggestions? Is there a better way to structure the JSON?

Share Improve this question asked Jan 13, 2013 at 22:08 reptilicusreptilicus 10.4k6 gold badges58 silver badges80 bronze badges 2
  • Where do the multiple lines e in? Are you trying to make one line per year? – nrabinowitz Commented Jan 13, 2013 at 22:14
  • Yup, want one line for each year. – reptilicus Commented Jan 13, 2013 at 22:36
Add a ment  | 

2 Answers 2

Reset to default 4

Here's what worked out in case anyone else runs across this problem. The trick is to pass a function that returns the values in the associative array in the "d" attribute of the path element.

  entries = d3.entries(data);

  var colors = d3.scale.category20()
    .domain(d3.keys(data));

  var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return x(d.month) })
    .y(function(d) { return y(d.value) });

  svg1.selectAll(".line")
    .data(entries)
  .enter().append("path")
    .attr("class", "line")
    // function(d), not just line function 
    .attr("d", function(d){ return  line(d.value); })
    .attr("stroke", function(d) { return colors(d.key) });

Some help from this answer too: Using nested data with javascript D3 problem

My guess is that the biggest problem here is that you're starting with an object, not an array. d3.data takes an array, not an object, so you might need your data set up like:

[
  [{"val":10, "mon":10}, {"val":20, "mon":11}, {"val":40, "mon":12}, ...],
  [{"val":20, "mon":8}, {"val":20, "mon":9}, {"val":40, "mon":10}, ...],
  ...
]

If you need to convert your current data to this format, look at d3.entries, which will give you an array with your key as well as your array of points:

[
  {
    key: "2008",
    value: [{"val":10, "mon":10}, {"val":20, "mon":11}, {"val":40, "mon":12}, ...]
  },
  { 
    key: "2008",
    value: [{"val":20, "mon":8}, {"val":20, "mon":9}, {"val":40, "mon":10}, ...]
  },
  ...
]

See this fiddle for a simple-case version of your graph, using the first data format above: http://jsfiddle/nrabinowitz/kmmyc/

发布评论

评论列表(0)

  1. 暂无评论