-
Notifications
You must be signed in to change notification settings - Fork 0
Tooltip Code Example
Sophie Engle edited this page Apr 8, 2015
·
1 revision
/*
* These are functions that are related to displaying tooltips.
* They require the data and utility helper functions.
*/
function toolHelpers(util, data) {
var main = {};
var tooltip = d3.select("span#tooltip");
var maxWidth = 300;
var drag = d3.behavior.drag().on("drag", function() {
dragPosition(d3.select(this));
});
if (tooltip.empty()) {
tooltip = d3.select("body").append("span");
tooltip.attr("id", "tooltip");
tooltip.attr("class", "blocktip");
tooltip.style("visibility", "hidden");
tooltip.style("position", "absolute");
}
main.hover = function(d) {
d3.select(this).classed("highlight", true);
if (!util.hasClass(d3.select(this), "sticky")) {
updatePosition(tooltip, data.nodeLabel(d));
tooltip.style("visibility", "visible");
}
}
main.exit = function(d) {
d3.select(this).classed("highlight", false);
tooltip.style("visibility", "hidden");
};
main.sticky = function(d) {
tooltip.style("visibility", "hidden");
var selection = d3.select(this);
if (util.hasClass(selection, "sticky")) {
var id = selection.attr("id");
selection.classed("sticky", false);
selection.attr("id", null);
d3.select("span#" + id).remove();
}
else {
var sticky = d3.select("body").append("span");
var sid = Date.now();
sticky.attr("class", "blocktip");
sticky.attr("id", "sticky-" + sid);
sticky.style("position", "absolute");
updatePosition(sticky, data.nodeLabel(d));
sticky.on("dblclick", function() {
var id = d3.select(this).attr("id");
d3.select(this).remove();
var cell = d3.select("#" + id);
cell.classed("sticky", false);
cell.attr("id", null);
});
sticky.call(drag);
selection.classed("sticky", true);
selection.attr("id", "sticky-" + sid);
this.parentNode.appendChild(this);
}
};
main.width = function(arg) {
if (!arguments.length) return maxWidth;
if (arg > 0) {
maxWidth = arg;
}
return main;
};
// Hack required since cannot cause CSS to update width after changing text
function updateText(selection, text) {
if (text == null) {
return null;
}
var temp = d3.select("body")
.append("span")
.classed("blocktip", true)
.attr("visibility", "hidden")
.html(text)
.style("display", "inline-block")
.style("max-width", "fit-content");
var width = temp.node().getBoundingClientRect().width;
temp.remove();
selection.html(text);
return (width > maxWidth) ? maxWidth : width;
}
// Updates position of selected tooltip (not used for sticky drag).
function updatePosition(selection, text) {
var width = updateText(selection, text);
var bbox = selection.node().getBoundingClientRect();
var x = 0;
var y = 0;
var coord = d3.mouse(d3.select("body").node());
// position below right of cursor
x = coord[0] + 20;
y = coord[1] + 5;
// test if should position left of cursor
if (x - window.pageXOffset + bbox.width > window.innerWidth) {
x = coord[0] - bbox.width + 5;
}
// test if should position above cursor
if (y - window.pageYOffset + bbox.height > window.innerHeight) {
y = coord[1] - bbox.height + 10;
}
selection.style("left", "" + x + "px");
selection.style("top", "" + y + "px");
selection.style("width", "" + width + "px");
};
// Updates position of sticky tooltip (being dragged).
function dragPosition(selection) {
var bbox = selection.node().getBoundingClientRect();
var x = 0;
var y = 0;
x = bbox.left + d3.event.dx; // bbox.left is relative to window
y = bbox.top + d3.event.dy; // bbox.top is relative to window
// page offset only greater than 0 if scrolled
// otherwise, no offset is needed
x += (window.pageXOffset > 0) ? window.pageXOffset : 0;
y += (window.pageYOffset > 0) ? window.pageYOffset : 0;
selection.style("left", "" + x + "px");
selection.style("top", "" + y + "px");
};
return main;
}