Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mouse over event on axis label d3.js javascript

does anyone know if it is possible to have mouse over event on y-axis label? For example, I have a scatter plot below. The labels on y axis are "area1", "area2" and "area3". When user hover the label "area1", a tooltip will popup to show the desciption of area1. I did not see any examples like this before. Anyone know how to do this? Thanks a lot!
I also have a plunker here http://plnkr.co/edit/wLjanxFWIzpxP0cbq6kK?p=preview

<!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Plot</title>
    <style> 
     .axis path,
     .axis line{
        fill: none;
        stroke: #000;
        shape-rendering: crishpEdges;
        }    
    </style>
  </head>
    <h1 style = "text-align:center;">Example</h1>     

 <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>  
    <div id="chart">
    </div>
    <script>

     var data = [
       {x: 5, y: "area1"
        },
       {x: 34, y: "area2"
        },
       {x: 19, y: "area3"
        }
       ];

 data.forEach(function(d){
        d.x = +d.x;
        d.y = d.y;

        return console.log(data);
    })

    var m = {t:30, r:20, b:40, l:45 },
        w = 600 - m.l - m.r,
        h = 500 - m.t - m.b;

    var x = d3.scale.linear()
        .range([0, w])
        .domain([0,d3.max(data, function(d){return d.x})]);

    var y = d3.scale.ordinal()
        .rangeRoundPoints([h-18,0])
        .domain(data.map(function(d){return d.y;}));   

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

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

    var svg = d3.select("#chart")
        .append("svg")
        .attr("width", w + m.l + m.r)
        .attr("height", h + m.t + m.b)
        .style("margin-left", "auto")
        .style("margin-right", "auto")
        .style("display", "block")
        .append("g")
        .attr("transform", "translate(" + m.l + "," + m.t + ")");     

    var circles = svg.selectAll("circle")
       .data(data)
       .enter()
       .append("circle")
       .attr("class", "circles")
       .attr({
        cx: function(d) { return x(d.x); },
        cy: function(d) { return y(d.y); },
        r: 8
      });

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

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

    </script>
  </body>
</html>
like image 680
wsda Avatar asked Dec 01 '15 21:12

wsda


2 Answers

For this first create a tooltip div.

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

Next add style in the CSS for tooltip

div.tooltip {
  position: absolute;
  text-align: center;
  width: 60px;
  height: 28px;
  padding: 2px;
  font: 12px sans-serif;
  background: lightsteelblue;
  border: 0px;
  border-radius: 8px;
  pointer-events: none;
}

For tool tip on y axis select all ticks and mouseover and mouseout listeners to it

yaxis.selectAll(".tick")[0].forEach(function(d1) {
    var data = d3.select(d1).data();//get the data asociated with y axis
    d3.select(d1).on("mouseover", function(d) {
      //on mouse hover show the tooltip
            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
            div .html(data) 
                .style("left", (d3.event.pageX) + "px")     
                .style("top", (d3.event.pageY - 28) + "px");    
            })                  
        .on("mouseout", function(d) {   
          //on mouse out hide the tooltip
            div.transition()        
                .duration(500)      
                .style("opacity", 0);   
        });

  })

Working code here

Hope this helps!

like image 117
Cyril Cherian Avatar answered Oct 04 '22 04:10

Cyril Cherian


There is one more way of adding tool-tips to d3 graphs using svg:title elements.

Each container element or graphics element in an SVG drawing can supply a title description string where the description is text-only. When the current SVG document fragment is rendered as SVG on visual media, title element is not rendered as part of the graphics. However, some user agents may, for example, display the title element as a tooltip.

Edit:

If the tool-tip text is long, you can use \n at certain intervals to split it into multiple lines.

Suppose your data contains description as shown below.

 var data = [{
     x: 5,
     y: "area1",
     desc: 'description 1'
 }, {
     x: 34,
     y: "area2",
     desc: 'description 2'
 }, {
     x: 19,
     y: "area3",
     desc: 'description 3'
 }];

You can add tooltip as shown below.

svg.select(".y.axis")
    .selectAll(".tick")
    .append("svg:title")
    .text(function(d, i) {
        return data[i].desc //Or some other custom decription
    });

var data = [{
       x: 5,
       y: "area1",
       desc: 'description 1 \n Long text 1'
     }, {
       x: 34,
       y: "area2",
       desc: 'description 2 \n Long text 2'
     }, {
       x: 19,
       y: "area3",
       desc: 'description 3 \n Long text 3'
     }];

     data.forEach(function(d) {
       d.x = +d.x;
       d.y = d.y;

       return console.log(data);
     })

     var m = {
         t: 30,
         r: 20,
         b: 40,
         l: 45
       },
       w = 600 - m.l - m.r,
       h = 500 - m.t - m.b;

     var x = d3.scale.linear()
       .range([0, w])
       .domain([0, d3.max(data, function(d) {
         return d.x
       })]);

     var y = d3.scale.ordinal()
       .rangeRoundPoints([h - 18, 0])
       .domain(data.map(function(d) {
         return d.y;
       }));

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

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

     var svg = d3.select("#chart")
       .append("svg")
       .attr("width", w + m.l + m.r)
       .attr("height", h + m.t + m.b)
       .style("margin-left", "auto")
       .style("margin-right", "auto")
       .style("display", "block")
       .append("g")
       .attr("transform", "translate(" + m.l + "," + m.t + ")");

     var circles = svg.selectAll("circle")
       .data(data)
       .enter()
       .append("circle")
       .attr("class", "circles")
       .attr({
         cx: function(d) {
           return x(d.x);
         },
         cy: function(d) {
           return y(d.y);
         },
         r: 8
       });

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

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

     svg.select(".y.axis")
       .selectAll(".tick")
       .append("svg:title")
       .text(function(d, i) {
         return data[i].desc //Or some other custom decription
       });
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crishpEdges;
}
.tooltip-inner {
  white-space:pre-wrap;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<h1 style="text-align:center;">Example</h1> 
<div id="chart">
</div>
like image 32
Gilsha Avatar answered Oct 04 '22 02:10

Gilsha