2

I have a basic line graph with two lines. When I click a button, one of the two lines will draw on the graph.

I use stroke-dasharray to draw the lines.

Would anyone know how I could add tooltips to my lines? Does using stroke-dasharray make it harder?

Heres my code.

var button=d3.select("#button");

//defines canvas (area in which graph is placed)    
var margin = {top: 30, right: 20, bottom: 50, left: 60},
width = 800 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").parse;

//OUTPUT RANGE
var x = d3.time.scale()
    .range([0, width]);

//OUTPUT RANGE    
var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom")
    .ticks(5);

var yAxis = d3.svg.axis().scale(y)
    .orient("left")
    .ticks(5);

//assigns coordinates for each piece of data    
var valueline = d3.svg.line()
    .interpolate("interpolation")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.close); });

//second line data
var valueline2 = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.open); });

//create area for 'area' below line    
var area = d3.svg.area()
    .x(function(d) { return x(d.date); })
    .y0(height)
    .y1(function(d) { return y(d.close); });    

//creates area to draw graph    
var svg = d3.select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
//groups content    
.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

function make_x_axis() {
    return d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .ticks(5)
}

function make_y_axis() {
    return d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(30)
}

// csv callback function
d3.csv("myData3.csv", function(data) {

    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
        d.open = +d.open;
    });


//INPUT DOMAINS
//.extent() returns min and max values of argument
x.domain(d3.extent(data, function(d) { return d.date; }));
//returns max of whichever set of data is bigger
y.domain([0, d3.max(data, function(d) { return Math.max(d.close, d.open); })]);


 d3.select("#button1").on("click", function(){ 
      var path = svg.append("path")   // Add the valueline path. 
          .attr("class", "line")
          .attr("d", valueline(data))
          .attr("stroke", "steelblue")
          .attr("stroke-width", "5")
          .attr("fill", "none");

  var totalLength = path.node().getTotalLength();

  path
    .attr("stroke-dasharray", totalLength + "30" * 30)
    .attr("stroke-dashoffset", totalLength)
    .transition()
      .duration(2000)
      .ease("linear")
      .attr("stroke-dashoffset", 0);

     })

 d3.select("#button2").on("click", function(){ 
      var path2 = svg.append("path")        // Add the valueline path. 
          .attr("class", "line2")
          .attr("d", valueline2(data))
          .attr("stroke", "steelblue")
          .attr("stroke-width", "5")
          .attr("fill", "none");

  var totalLength = path2.node().getTotalLength();


  path2
    .attr("stroke-dasharray", totalLength + "30" * 30)
    .attr("stroke-dashoffset", totalLength)
    .transition()
      .duration(2000)
      .ease("linear")
      .attr("stroke-dashoffset", 0)
     })       


svg.append("g") // Add the X Axis
    .attr("class", "x axis")
    //moves x axis to bottom of graph
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

//text label for x-axis    
svg.append("text") // text label for the x axis
    .attr("transform", "translate(" + (width / 2) + " ," + (height + margin.bottom - 5 ) + ")")
    .style("text-anchor", "middle")
    .text("Date");

svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
    .call(yAxis);

//text label for y-axis    
svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 0 - margin.left)
    .attr("x",0 - (height / 2))
    //adds extra left padding as original y pos = 0
    .attr("dy", "1em")
    .style("text-anchor", "middle")
    .text("Value");


//adding a title to the graph
svg.append("text")
    .attr("x", (width / 2))
    .attr("y", 0 - (margin.top / 2))
    .attr("text-anchor", "middle")
    .style("font-size", "16px")
    .style("text-decoration", "underline")
    .text("Graph");


//draw x axis grid    
svg.append("g")
    .attr("class", "grid")
    .attr("transform", "translate(0," + height + ")")
    .call(make_x_axis()
    .tickSize(-height, 0, 0)
    .tickFormat("")
)

//draw y axis grid
svg.append("g")
    .attr("class", "grid")
    .call(make_y_axis()
    .tickSize(-width, 0, 0)
    .tickFormat("")
)

});<!--d3.csv close-->​

Thanks in advance!

Daft
  • 10,277
  • 15
  • 63
  • 105

1 Answers1

2

The easiest way to add a tooltip is to append an svg:title element to the elements you want to have a tooltip for. It will be displayed by the browser automatically when you hover over the element. It works for all kinds of elements as well.

So your code would need to look something like

var path = svg.append("path")   // Add the valueline path. 
      .attr("class", "line")
      .attr("d", valueline(data))
      .attr("stroke", "steelblue")
      .attr("stroke-width", "5")
      .attr("fill", "none")
      .append("title").text("whatever");

If you need more sophisticated functionality, you could try for example tipsy, which works in a similar way.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • 2
    I have a same case here but instead of displaying same tooltip throughout line I need to show the value at that point . Ex: In above code instead of "whatever" I want to display X coordinate and Y coordinate values. Can I do it without using tipsy ? If not even tipsy code is accepted. But I wont prefer putting circle at each data point as I have huge data and many lines so, in numbers : 10000 points 4 lines , and for these 40000 circles if I append just to achieve tooltip means .... ! – vajrakumar Feb 15 '13 at 09:06