Skip to content

Instantly share code, notes, and snippets.

@artzub
Forked from milroc/index.html
Last active September 28, 2017 06:35
Show Gist options
  • Save artzub/5062548 to your computer and use it in GitHub Desktop.
Save artzub/5062548 to your computer and use it in GitHub Desktop.
Tooltip as a d3 helper
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="./tooltip.js"></script>
</head>
<body>
<div class="viz"></div>
<script type="text/javascript">
var sampleSVG = d3.select(".viz")
.append("svg")
.attr("width", 600)
.attr("height", 100);
var data = [];
for (var i = 0; i < 100; i++) data.push(i);
sampleSVG.selectAll("circle")
.data(data)
.enter().append("circle")
.style("stroke", "gray")
.style("fill", "aliceblue")
.attr("r", 40)
.attr("cx", function(d, i){return i*100 + 50;})
.attr("cy", 50)
.call(d3.helper.tooltip()
.attr("class", function(d, i) { return d + " " + i + " A"; })
.attr("d", "b")
.padding(8, 8)
.text(function(d, i){return "value: "+d;}));
</script>
</body>
</html>
d3.helper = {};
d3.helper.tooltip = function(){
var tooltipDiv,
body = d3.select('body'),
attrs = [],
text = "",
styles = [],
_w, _h, _p = {x: 16, y: 16};
function tooltip(selection) {
function doText(d, i) {
// Crop text arbitrarily
tooltipDiv.html(
typeof text === "function"
? text(d, i)
: typeof text != "undefined" || typeof text != null
? text
: ''
);
}
function mover(d, i) {
var key, name, value;
// Clean up lost tooltips
body.selectAll('div.tooltip').remove();
// Append tooltip
tooltipDiv = body.append('div');
for (key in attrs) {
if (!attrs.hasOwnProperty(key))
continue;
name = attrs[key][0];
if (typeof attrs[key][1] === "function") {
value = attrs[key][1](d, i);
} else value = attrs[key][1];
if (name === "class") value += " tooltip";
tooltipDiv.attr(name, value);
}
for (key in styles) {
if (!styles.hasOwnProperty(key))
continue;
name = styles[key][0];
if (typeof attrs[key][1] === "function") {
value = styles[key][1](d, i);
} else value = styles[key][1];
tooltipDiv.style(name, value);
}
tooltipDiv.style('position', 'absolute')
.style('z-index', 1001);
mm(d, i);
doText(d, i);
}
function mm(d, i) {
// Move tooltip
var absoluteMousePos = d3.mouse(body.node());
tooltipDiv
.style('left', (absoluteMousePos[0] > _w/2
? absoluteMousePos[0] - tooltipDiv.node().clientWidth - _p.x
: absoluteMousePos[0] + _p.x) + 'px')
.style('top', (absoluteMousePos[1] > _h/2
? absoluteMousePos[1] - tooltipDiv.node().clientHeight - _p.y
: absoluteMousePos[1] + _p.y) + 'px');
//doText(d, i);
}
function mout(d, i){
// Remove tooltip
tooltipDiv.remove();
}
selection
.on("mouseover", mover)
.on('mousemove', mm)
.on("mouseout", mout);
}
tooltip.attr = function(name, value) {
attrs.push(arguments);
return this;
};
tooltip.text = function(value) {
text = value;
return this;
};
tooltip.style = function(name, value) {
styles.push(arguments);
return this;
};
tooltip.spaceWidth = function(value) {
if (!value) return _w;
_w = +value;
return this;
};
tooltip.spaceHeight = function(value) {
if (!value) return _h;
_h = +value;
return this;
};
/**
* @params x or x,y {Number}
*/
tooltip.padding = function() {
if (!arguments.length) return _p;
switch(arguments.length) {
case 1: _p = {x : parseInt(p), y : parseInt(p)}; break;
case 2: _p = {x : parseInt(arguments[0]), y : parseInt(arguments[1])}; break;
}
return this;
}
return tooltip;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment