Search code examples
javascriptd3.jstooltip

An Area Chart With Tooltip in D3


I am trying to create an area chart with tooltip using D3.js. I am trying to do something like http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html. I am able to create an area chart successfully but when I try to mix scatter-plot code with it, nothing seems to work. Below is my code

var m = [40,40,40,70],
w = 500 -m[1] - m[3],
h = 300 - m[0] - m[2];

var svg = d3.select('body').append('svg')
.attr('width', w+m[1]+m[3])
.attr('height', h+m[0]+m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");

var div = d3.select("body").append("div")   
.attr("class", "tooltip")               
.style("opacity", 0);

var data = [{
'Wed Jan 23 00:00:00 IST 2013': 3383387
}, {
'Thu Jan 24 00:00:00 IST 2013': 3883387
}, {
'Fri Jan 25 00:00:00 IST 2013': 4383387
}, {
'Sat Jan 26 00:00:00 IST 2013': 2383387
}, {
'Sun Jan 27 00:00:00 IST 2013': 5383387
}, {
'Mon Jan 28 00:00:00 IST 2013': 2283387
}];

var format = d3.time.format("%a %b %d %H:%M:%S IST %Y");

var xscale = d3.time.scale().domain([format.parse(d3.keys(data[0])[0]), format.parse(d3.keys(data[5])[0])]).range([0, w]),
yscale = d3.scale.linear().domain([0, d3.max(data, function (d) {
    return d3.values(d)[0];
})]).range([h, 0]);

var xAxis = d3.svg.axis()
.scale(xscale)
.ticks(d3.time.days, 2)
.orient("bottom");

var yAxis = d3.svg.axis()
.scale(yscale)
.ticks(4)
.orient("left");

var area = d3.svg.area()
.x(function(d) { return xscale(format.parse(d3.keys(d)[0])); })
.y0(h)
.y1(function(d) { return yscale(d3.values(d)[0]); })
.interpolate("basis");

svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis.tickSubdivide(1).tickSize(6));

svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "translate(" + w + ",0)");

svg.append("g")
.append('path')
.attr("class", "area")
.call(area);

svg.selectAll('g.generator')
.data([data])
.enter().append("svg:circle")
.attr("cx",function(d){ return xscale(format.parse(d3.keys(d)[0]));})
.attr("cy", function(d){ return yscale(d3.values(d)[0]);})
.attr("r", function(d){ return 4;});

I've create a jsfiddle also: http://jsfiddle.net/DTs7F/. Can someone please point me in right direction and let me know what's wrong with my approach ? Thanks. Update: Created one more fiddle using slightly different approach. Still not working :-( http://jsfiddle.net/DTs7F/3/


Solution

  • Regarding the scatter-plot:

    Remove the array wrapper around your data (which is already an array)

    change to

    svg.selectAll('g.generator')
      .data( data )  // formerly .data([data])
    

    Regarding the area chart:

    Don't 'call' the area, but rather get the path data for the area, as below:

    svg.append("g").append("path")
      .datum(data)
      .attr("class", "area")
      .attr("d", area);
    

    Instead of

    // Not right
    svg.append("g")
       .append('path')
       .attr("class", "area")
       .call(area);