3

I have a chart, http://codepen.io/Siddharth11/pen/LVQmjN

I want to display a popup as I hover over the color codes written on right side in the above chart.

I will be displaying seprete info for each color code.So how can we create a sepeate popup for each color code.

Similar to a morris map : http://codepen.io/andreic/pen/CJoze

or this :http://codepen.io/anon/pen/woJMrX

This question didnot fetch any correct response yet.i tried using a jquery plugin(poshy tip) and tried to solve the issue.yet no luck.I had reposted the question with the progress made.Kindly refer the link for the current situation with the code : jquery plugin to bind data to a tool-tip (poshy tip)

'use strict';

var dataset1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

// let colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd'];
let colors = ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a', '#1a1a1a', '#1a1a1a'];
var weeks = ['January - 2016 ', 'February', 'March', '#fdae61', '#fee08b', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2', '#1a1a1a', '#1a1a1a'];

var width = document.querySelector('.chart-wrapper').offsetWidth,
  height = document.querySelector('.chart-wrapper').offsetHeight,
  minOfWH = Math.min(width, height) / 2,
  initialAnimDelay = 300,
  arcAnimDelay = 150,
  arcAnimDur = 3000,
  secDur = 1000,
  secIndividualdelay = 150;

var radius = undefined;

// calculate minimum of width and height to set chart radius
if (minOfWH > 200) {
  radius = 200;
} else {
  radius = minOfWH;
}

// append svg
var svg = d3.select('.chart-wrapper').append('svg').attr({
  'width': width,
  'height': height,
  'class': 'pieChart'
}).append('g');

svg.attr({
  'transform': 'translate(' + width / 2 + ', ' + height / 2 + ')'
});

// for drawing slices
var arc = d3.svg.arc().outerRadius(radius * 0.6).innerRadius(radius * 0.45);

// for labels and polylines
var outerArc = d3.svg.arc().innerRadius(radius * 0.85).outerRadius(radius * 0.85);

// d3 color generator
// let c10 = d3.scale.category10();

var pie = d3.layout.pie().value(function(d) {
  return d;
});

var draw = function draw() {

  svg.append("g").attr("class", "lines");
  svg.append("g").attr("class", "slices");
  svg.append("g").attr("class", "labels");

  // define slice
  var slice = svg.select('.slices').datum(dataset1).selectAll('path').data(pie);
  slice.enter().append('path').attr({
    'fill': function fill(d, i) {
      return colors[i];
    },
    'd': arc,
    'stroke-width': '25px'
  }).attr('transform', function(d, i) {
    return 'rotate(-180, 0, 0)';
  }).style('opacity', 0).transition().delay(function(d, i) {
    return i * arcAnimDelay + initialAnimDelay;
  }).duration(arcAnimDur).ease('elastic').style('opacity', 1).attr('transform', 'rotate(0,0,0)');

  slice.transition().delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).duration(secDur).attr('stroke-width', '5px');

  var midAngle = function midAngle(d) {
    return d.startAngle + (d.endAngle - d.startAngle) / 2;
  };

  var text = svg.select(".labels").selectAll("text").data(pie(dataset1));

  text.enter().append('text').attr('dy', '0.35em').style("opacity", 0).style('fill', function(d, i) {
    return colors[i];
  }).text(function(d, i) {
    return weeks[i];
  }).attr('transform', function(d) {
    // calculate outerArc centroid for 'this' slice
    var pos = outerArc.centroid(d);
    // define left and right alignment of text labels
    pos[0] = radius * (midAngle(d) < Math.PI ? 1 : -1);
    return 'translate(' + pos + ')';
  }).style('text-anchor', function(d) {
    return midAngle(d) < Math.PI ? "start" : "end";
  }).transition().delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).duration(secDur).style('opacity', 1);

  var polyline = svg.select(".lines").selectAll("polyline").data(pie(dataset1));

  polyline.enter().append("polyline").style("opacity", 0.5).attr('points', function(d) {
    var pos = outerArc.centroid(d);
    pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
    return [arc.centroid(d), arc.centroid(d), arc.centroid(d)];
  }).transition().duration(secDur).delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).attr('points', function(d) {
    var pos = outerArc.centroid(d);
    pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
    return [arc.centroid(d), outerArc.centroid(d), pos];
  });
};

draw();

var button = document.querySelector('button');

var replay = function replay() {

  d3.selectAll('.slices').transition().ease('back').duration(500).delay(0).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
  d3.selectAll('.lines').transition().ease('back').duration(500).delay(100).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
  d3.selectAll('.labels').transition().ease('back').duration(500).delay(200).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();

  setTimeout(draw, 800);
};
body {
  overflow: hidden;
  font-size: 16px;
}
.chart-wrapper {
  width: 100%;
  height: 100%;
  background-color: #0d0d0d;
  position: absolute;
}
path {
  stroke: #0d0d0d;
  /* stroke-width: 5px; */
  cursor: pointer;
  -webkit-transition: fill 250ms;
  transition: fill 250ms;
}
path:hover {
  /* stroke-width: 10px; */
  fill: #fff;
}
text {
  font-size: .8em;
  text-transform: uppercase;
  letter-spacing: .5px;
}
polyline {
  fill: none;
  stroke: #fff;
  stroke-width: 2px;
  stroke-dasharray: 5px;
}
button {
  position: relative;
  top: 20px;
  left: 820px;
  text-transform: uppercase;
  padding: 5px 10px;
  outline: none;
  font-size: 1.2em;
  background-color: transparent;
  color: #fff;
  border: 1px solid #fff;
  letter-spacing: 1px;
  -webkit-transition: all 250ms;
  transition: all 250ms;
}
button:hover {
  background-color: #fff;
  color: #0d0d0d;
  box-shadow: 0 0 2px #fff;
}
button:active {
  opacity: 0.5;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Crazy Pie Chart</title>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">


  <link rel="stylesheet" href="css/style.css">


</head>

<body>
  <div class="chart-wrapper"></div>
  <button onclick='replay()'>Monthly</button>
  <button type="button">Weekly</button>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'></script>

  <script src="js/index.js"></script>

</body>

</html>
Community
  • 1
  • 1
jane
  • 211
  • 9
  • 30

1 Answers1

6

This is probably too broad for SO, but this is how I like to create tooltips without any external library or plugin. It's based on creating a <div>, that we will show/hide using "opacity".

First, set the CSS style for the tooltip, using a div with a class named "tooltip", or any other name:

div.tooltip {   
    position: absolute;         
    /*your other styles here*/;              
}

Then, set a tooltip variable:

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

This div has 0 opacity. Then it's just a matter of showing the tooltip on mouseover or mousemove:

text.on("mousemove", function(d) {
    tooltip.html("Hello, I am<br>a tooltip!")
        .style('top', d3.event.pageY - 6 + 'px')
        .style('left', d3.event.pageX + 10 + 'px')
        .style("opacity", 1);
    }).on("mouseout", function(d) {
        tooltip.style("opacity", 0);
    });

You can use HTML tags to style your text inside the tooltip, making it bold, italic etc.

Here is your CodePen: http://codepen.io/anon/pen/rWyyra?editors=0010

EDIT: Despite this being the correct answer for your specific and particular problem stated in the question, here is a snippet answering your edit (which points to another question):

'use strict';

var dataset = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

// let colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd'];
let colors = ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a', 'white', 'white'];
var months = ['January - 2016', 'February - 2016', 'March - 2016', 'April - 2016', 'May - 2016', 'June - 2016', 'July - 2016', 'August - 2016', 'September - 2016', 'October - 2016', 'November - 2016', 'December - 2016'];
var dataWeeks = ["Week 1: 32<br>Week 2: 54<br>Week 3: 19<br>Week 4: 12","Week 1: 22<br>Week 2: 14<br>Week 3: 12<br>Week 4: 03","Week 1: 35<br>Week 2: 14<br>Week 3: 11<br>Week 4: 23","Week 1: 65<br>Week 2: 53<br>Week 3: 16<br>Week 4: 11","Week 1: 11<br>Week 2: 52<br>Week 3: 22<br>Week 4: 12","Week 1: 09<br>Week 2: 44<br>Week 3: 59<br>Week 4: 87","Week 1: 42<br>Week 2: 76<br>Week 3: 69<br>Week 4: 33","Week 1: 11<br>Week 2: 65<br>Week 3: 69<br>Week 4: 33","Week 1: 99<br>Week 2: 66<br>Week 3: 19<br>Week 4: 84","Week 1: 16<br>Week 2: 66<br>Week 3: 11<br>Week 4: 86","Week 1: 21<br>Week 2: 52<br>Week 3: 12<br>Week 4: 37","Week 1: 90<br>Week 2: 69<br>Week 3: 19<br>Week 4: 17"];

var width = document.querySelector('.chart-wrapper').offsetWidth,
  height = document.querySelector('.chart-wrapper').offsetHeight,
  minOfWH = Math.min(width, height) / 2,
  initialAnimDelay = 300,
  arcAnimDelay = 150,
  arcAnimDur = 3000,
  secDur = 1000,
  secIndividualdelay = 150;

var radius = undefined;

// calculate minimum of width and height to set chart radius
if (minOfWH > 200) {
  radius = 200;
} else {
  radius = minOfWH;
}

// append svg
var svg = d3.select('.chart-wrapper').append('svg').attr({
  'width': width,
  'height': height,
  'class': 'pieChart'
}).append('g');

svg.attr({
  'transform': 'translate(' + width / 2 + ', ' + height / 2 + ')'
});

// for drawing slices
var arc = d3.svg.arc().outerRadius(radius * 0.6).innerRadius(radius * 0.45);

// for labels and polylines
var outerArc = d3.svg.arc().innerRadius(radius * 0.85).outerRadius(radius * 0.85);

// d3 color generator
// let c10 = d3.scale.category10();

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

var pie = d3.layout.pie().value(function(d) {
  return d;
});

var draw = function draw() {

  svg.append("g").attr("class", "lines");
  svg.append("g").attr("class", "slices");
  svg.append("g").attr("class", "labels");

  // define slice
  var slice = svg.select('.slices').datum(dataset).selectAll('path').data(pie);
  slice.enter().append('path').attr({
    'fill': function fill(d, i) {
      return colors[i];
    },
    'd': arc,
    'stroke-width': '25px'
  }).attr('transform', function(d, i) {
    return 'rotate(-180, 0, 0)';
  }).style('opacity', 0).transition().delay(function(d, i) {
    return i * arcAnimDelay + initialAnimDelay;
  }).duration(arcAnimDur).ease('elastic').style('opacity', 1).attr('transform', 'rotate(0,0,0)');

  slice.transition().delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).duration(secDur).attr('stroke-width', '5px');

  var midAngle = function midAngle(d) {
    return d.startAngle + (d.endAngle - d.startAngle) / 2;
  };

  var text = svg.select(".labels").selectAll("text").data(pie(dataset));

  text.enter().append('text').attr('dy', '0.35em').style("opacity", 0).attr("cursor", "default").style('fill', function(d, i) {
    return colors[i];
  }).text(function(d, i) {
    return months[i];
  }).attr('transform', function(d) {
    // calculate outerArc centroid for 'this' slice
    var pos = outerArc.centroid(d);
    // define left and right alignment of text labels
    pos[0] = radius * (midAngle(d) < Math.PI ? 1 : -1);
    return 'translate(' + pos + ')';
  }).style('text-anchor', function(d) {
    return midAngle(d) < Math.PI ? "start" : "end";
  }).transition().delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).duration(secDur).style('opacity', 1);
  
   text.on("mousemove", function(d, i) {
                tooltip.html(dataWeeks[i])
                        .style('top', d3.event.pageY - 6 + 'px')
                        .style('left', d3.event.pageX + 14 + 'px')
                        .style("opacity", 1);
            }).on("mouseout", function(d) {
                tooltip.style("opacity", 0);
            });


  var polyline = svg.select(".lines").selectAll("polyline").data(pie(dataset));

  polyline.enter().append("polyline").style("opacity", 0.5).attr('points', function(d) {
    var pos = outerArc.centroid(d);
    pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
    return [arc.centroid(d), arc.centroid(d), arc.centroid(d)];
  }).transition().duration(secDur).delay(function(d, i) {
    return arcAnimDur + i * secIndividualdelay;
  }).attr('points', function(d) {
    var pos = outerArc.centroid(d);
    pos[0] = radius * 0.95 * (midAngle(d) < Math.PI ? 1 : -1);
    return [arc.centroid(d), outerArc.centroid(d), pos];
  });
};

draw();

var button = document.querySelector('button');

var replay = function replay() {

  d3.selectAll('.slices').transition().ease('back').duration(500).delay(0).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
  d3.selectAll('.lines').transition().ease('back').duration(500).delay(100).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();
  d3.selectAll('.labels').transition().ease('back').duration(500).delay(200).style('opacity', 0).attr('transform', 'translate(0, 250)').remove();

  setTimeout(draw, 800);
};
body {
  overflow: hidden;
  font-size: 16px;
}
.chart-wrapper {
  width: 100%;
  height: 100%;
  background-color: #0d0d0d;
  position: absolute;
}
path {
  stroke: #0d0d0d;
  /* stroke-width: 5px; */
  cursor: pointer;
  -webkit-transition: fill 250ms;
  transition: fill 250ms;
}
path:hover {
  /* stroke-width: 10px; */
  fill: #fff;
}
text {
  font-size: .8em;
  text-transform: uppercase;
  letter-spacing: .5px;
}
polyline {
  fill: none;
  stroke: #fff;
  stroke-width: 2px;
  stroke-dasharray: 5px;
}
button {
  position: absolute;
  top: 20px;
  left: 820px;
  text-transform: uppercase;
  padding: 5px 10px;
  outline: none;
  font-size: .6em;
  background-color: black;
  color: #fff;
  border: 1px solid #fff;
  letter-spacing: 1px;
  -webkit-transition: all 250ms;
  transition: all 250ms;
}
button:hover {
  background-color: #fff;
  color: #0d0d0d;
  box-shadow: 0 0 2px #fff;
}
button:active {
  opacity: 0.5;
}
div.tooltip {
  position: absolute;
  padding: 4px;
  background: white;
  border: 1px solid black;
  border-radius: 2px;
  font-size: 14px;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <title>Crazy Pie Chart</title>
  <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" />

  <!-- Tooltip classes -->

  <link rel="stylesheet" href="http://vadikom.com/demos/poshytip/src/tip-skyblue/tip-skyblue.css" type="text/css" />


 

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">


  <link rel="stylesheet" href="css/style.css">


</head>

<body>

 


  <div class="chart-wrapper"></div>
  <button onclick='replay()'>Replay</button>
  <div class="textt" data-tip="this is the data ."></div>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'></script>

  <script src="js/index.js"></script>

</body>

</html>
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • Thanks a ton. u a genius . looks good .But ,if I want to display separate info for each color code.How do you think can that be achieved ? If any idea,would be glad if you share.Thanks again.God bless... @Gerardo – jane Nov 21 '16 at 12:59
  • You'll have to bind data to the texts. Thus, I reckon the best step for you now is studying some good tutorials on how to bind data using D3. – Gerardo Furtado Nov 21 '16 at 13:05
  • here in this codepen,the bind takes place by calling the color[i] , in the text.So,I will have to create variables for all the color codes. Anyways,thanks for the support. @Gerardo – jane Nov 21 '16 at 13:16
  • 1
    Let me tell u what Iam trying to achieve here.The color codes that u see,in place of that there will be months of the year- January,February,March,.... Now when i hover over the months,I want to display week1,week2,....,week4 for January ,week5,week6,...,week8 for February and so on.I will use php to echo the value of the weekly data like - week1 :23,week2:45,week3:56 ,week4:75 etc....I checked ur code.Can this be achieved.What u think ? Thanks – jane Nov 21 '16 at 13:41
  • 1
    Yes, it can. But, as I told you before, you'll have to study how to bind the data using D3. If you ask a question like this here, people will complain that you want them to "write code for free", and they will be right. That being said, this is an excellent book on D3, and it's free to read online! http://chimera.labs.oreilly.com/books/1230000000345 – Gerardo Furtado Nov 21 '16 at 13:45
  • np,glad that u helped.I will try to solve.Thanks anyways.God bless u. – jane Nov 21 '16 at 13:49
  • @jane I see that you unaccepted my answer. I can only imagine that the code just stopped working suddenly. – Gerardo Furtado Nov 23 '16 at 13:16
  • Sry but I tried to work on ur code further.It was taking me nowhere.The book u recommended,it didnot help either.M still searching a way to solve the issue.I knw its a big ask,but will u kindly show me how to do it fr a month or two.I just need some hint as I am new to d3js. Nevermind.Thanks a lot.God bless – jane Nov 23 '16 at 14:46
  • will using a .csv file with all week info as mentioned in the book help ? – jane Nov 23 '16 at 15:01
  • Yes, it's a way of loading the data and binding it to the SVG elements. – Gerardo Furtado Nov 23 '16 at 15:02
  • i tried doing so,after going through ur document,but no luck.Is thr any other way may be ...Thanks . – jane Nov 23 '16 at 15:14
  • 1
    @jane despite you having unaccepted this answer **twice**, I edited it to answer you once again. However, this is the **last time** I answer a question from you. Good luck. – Gerardo Furtado Nov 24 '16 at 14:49
  • 2
    @GerardoFurtado thanks a lot for the solution.I appreciate it. Thats very kind of you.you people are the reason,this community is what it is.I wont argue or defend.God bless. – jane Nov 25 '16 at 03:59