3

I'm trying to draw a simple graph which gets its data from a json feed. The json feed looks like this:

[{"date":"2013-09-06","count":158},{"date":"2013-09-07","count":107},{"date":"2013-09-08","count":124},{"date":"2013-09-05","count":9},{"date":"2013-09-04","count":4},{"date":"2013-09-03","count":6},{"date":"2013-09-02","count":6},{"date":"2013-09-01","count":1}]

This is an example of the type of graph that I expect with the code below:

d3 graph

The JavaScript looks like this:

var margin = {top: 10, right: 10, bottom: 100, left: 400},
    width  = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var parseDate = d3.time.format("%Y-%m-%d").parse;

var x = d3.time.scale().range([0, width]),
    y = d3.scale.linear().range([height, 0]);

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

var brush = d3.svg.brush().on("brush", brushed);

var area = d3.svg.area()
    .interpolate("monotone")
    .x(function(d) { return x(d.date); })
    .y0(height)
    .y1(function(d) { return y(d.count); });

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);

svg.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height);

var focus = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json('http://path/to/feed.json', function (data) {
    data.forEach(function(d) {
      d.date = parseDate(d.date);
    });

  x.domain(d3.extent(data.map(function(d) { return d.date; })));
  y.domain([0, d3.max(data.map(function(d) { return d.count; }))]);

  focus.append("path")
       .datum(data)
       .attr("clip-path", "url(#clip)")
       .attr("d", area);

  focus.append("g")
       .attr("class", "x axis")
       .attr("transform", "translate(0," + height + ")")
       .call(xAxis);

  focus.append("g")
       .attr("class", "y axis")
       .call(yAxis);
  });

  function brushed() {
    x.domain(brush.empty() ? x2.domain() : brush.extent());
    focus.select("path").attr("d", area);
    focus.select(".x.axis").call(xAxis);
  }

Update:

Got the graph to draw after fixing the bug Scott Cameron pointed out but it looks like this:

broken graph

Looks like the date parsing is acting up.

1
  • Can you try to describe what's going on? Is nothing displaying at all? You may not be loading the data. Commented Sep 8, 2013 at 13:47

2 Answers 2

2

Your JSON blob is out of order with time. If you sort your data points in correct time order, you'll get the correct graph.

http://vida.io/documents/ZkoBevX2ZGD8pCxZu

Sign up to request clarification or add additional context in comments.

2 Comments

Yes that's so obvious now! Thank you. Any idea why the x-axis splits the dates and times into separate points? Even on your link.
It because there isn't enough data point to cover the entire x axis. I added a couple more points. Check the link again.
1

The y1 accessor on your area object is looking for d.price but it looks like there is no such property in your feed.

.y1(function(d) { return y(d.price); });

Should this be returning y(d.count)?

2 Comments

Spotted that as well. Ok so the graph works, but it's still weird. Slowly getting there... See updated question.
Updated the JSON feed to reflect the exact one I'm consuming.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.