0

How do I highlight an elliptical arc drawn, on mouseover and display tooltip on the same using d3.js?

sjaikumar
  • 49
  • 5
  • That's a different one Jai, Please find my d3-tip answer below, if you need more details, please let me know exactly what is your requirement. – BHUVANESH MOHANKUMAR Nov 19 '16 at 00:47
  • Thank you Bhuvanesh for your response. The situation is that I have a world map with 3 different locations displayed which I am connecting using two elliptical arcs. Now, there are going to be many such arcs that are going to be connected from different locations displayed on the map. My intention is that when the user hovers over any portion of the arc -a tooltip will pop out displaying descriptive information that I want it too and additionally if possible it must be highlighted. I have implemented tooltips before using Tipsy.js, however I could not get it to work for this. – sjaikumar Nov 19 '16 at 01:02

2 Answers2

0
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
    <style>
        body { font: 10px sans-serif; }

        .d3-tip {
            background: rgba(0, 0, 0, 0.8);
            border-radius: 2px;
            color: #fff;
            font-weight: bold;
            line-height: 1;
            padding: 12px;
        }
    </style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

    var w = window.innerWidth,
        h = window.innerHeight,
        margin = { top: 40, right: 20, bottom: 20, left: 40 };

    var svg = d3.select("body").append("svg").attr({
        width: w,
        height: h
    });

    var dataset = [
        { toolTip: "one", d: "M 50 200 a 100 50 0 1 1 250 50" },
        { toolTip: "two", d: "M 400 100 a 100 50 30 1 1 250 50" },
        { toolTip: "three", d: "M 400 300 a 100 50 45 1 1 250 50" },
        { toolTip: "four", d: "M 750 200 a 100 50 135 1 1 250 50" }
    ];

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([-10, 0])
        .html(function(d) {
            return "<strong>Elipse:</strong> <span style='color:red'>" + d.toolTip + "</span>";
        });

    svg.selectAll("g")
        .data(dataset)
        .enter()
        .append("g")
        .attr("stroke-width", 3)
        .attr("stroke", "black")
        .attr("fill", "none")
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide)
        .append("path")
        .attr("d", function(d) { return d.d })
        .on('mouseover', highLight)
        .on('mouseout', unHighLight);

        svg.call(tip);

    function highLight(){
       var foo = d3.select(this);
       foo.attr("stroke","red");
   }

    function unHighLight(){
        var foo = d3.select(this);
        foo.attr("stroke","black");
    }

</script>
</body>
</html>

view block here

Damian
  • 74
  • 5
  • Damian, I cannot thank you enough for your answer. I was able to successfully implement it in my code. The only question I have now is how I can highlight the elliptical arc that the user chooses to hover over. My intention is to highlight it so that it stands out from the other arcs on the screen only when the user hovers over that arc. The tooltip would also be displayed at the same time. Thank You once again :) – sjaikumar Nov 19 '16 at 04:48
  • @sjaikumar - I made it work by adding mouse events to the "g" and changing the mouse events for the "path" to call a function. See the edited code above or click on the [block link](http://bl.ocks.org/damianak1/c0baa4ac91f8e2c338857877b228710c) to see it live (you may need to clear the browser cache to see the updated code). – Damian Nov 19 '16 at 06:58
  • 1
    Thank You @Damian this worked but I ran into a problem of triggering two mouse events simultaneously. In other words, I was only able to see the tooltip or the highlight and both did not appear together. To overcome this, I made use of namespacing in this manner - . .on("mouseover.tip", tip.show).on("mouseover.highlight", highlight); – sjaikumar Nov 19 '16 at 14:13
  • @sjaikumar - great! I am glad you got it resolved and thanks for sharing your final fix. – Damian Nov 19 '16 at 18:08
-1

Using d3-tip to add tooltips to a d3 bar chart

Index.html:

    Using d3-tip to add tooltips to a d3 bar chart.
<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: orange;
}

.bar:hover {
  fill: orangered ;
}

.x.axis path {
  display: none;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(".0%");

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

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

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

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(formatPercent);

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
  })

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

svg.call(tip);

d3.tsv("data.tsv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

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

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Frequency");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function(d) { return height - y(d.frequency); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)

});

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

</script>

Data.tsv

letter frequency A .08167 B .01492 C .02780 D .04253 E .12702 F .02288 G .02022 H .06094 I .06973 J .00153 K .00747 L .04025 M .02517 N .06749 O .07507 P .01929 Q .00098 R .05987 S .06333 T .09056 U .02758 V .01037 W .02465 X .00150 Y .01971 Z .00074

Reference:

BHUVANESH MOHANKUMAR
  • 2,747
  • 1
  • 33
  • 33