Skip to content

Instantly share code, notes, and snippets.

@rmarimon
Created September 3, 2011 17:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmarimon/1191530 to your computer and use it in GitHub Desktop.
Save rmarimon/1191530 to your computer and use it in GitHub Desktop.
Bar Tips
Simple example showing tipsy fork for SVG by Justin Donaldson.
Hover over the different elements to get the corresponding tooltip:
* Bar labels
* Bar values
* Bat itself
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>bar</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="jquery.tipsy.js"></script>
<link rel="stylesheet" href="tipsy.css" type="text/css"/>
<style type="text/css">
#chart {
width: 960px;
height: 320px;
font-size: 12px;
}
#chart .bar {
fill: steelblue;
}
#chart .xaxis {
stroke: black;
}
.tipsy-inner {
text-align: left;
}
.tipsy-inner a {
color: white;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
$('svg title').parent().tipsy({
gravity: 'sw',
html: true,
title: function() { return $(this).find('title').text(); }
});
});
</script>
</head>
<body>
<h1>Bar Tips</h1>
<div id="chart"></div>
<script type="text/javascript">
var w = 960,
h = 320,
m = [ 15, 5, 15, 5 ], // top, right, bottom, left (ala css)
data = [ { l: "Jan", v: 10 }, { l: "Feb", v: 12 }, { l: "Mar", v: 14 }, { l: "Apr", v: 16 } ];
var x = d3.scale.ordinal().domain(d3.range(data.length))
.rangeBands([0, w - m[1] - m[3]], 0.1),
y = d3.scale.linear().domain([0, d3.max(data, function(d) { return d.v; })])
.range([0, h - m[0] - m[2]]);
var vis = d3.select("#chart")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
vis.selectAll("rect.bar")
.data(data)
.enter().append("svg:rect")
.attr("class", "bar")
.attr("x", function(d, i) { return x(i); })
.attr("y", function(d) { return h - m[0] - m[2] - y(d.v); })
.attr("width", x.rangeBand())
.attr("height", function(d) { return y(d.v); })
.append("svg:title")
.text(function(d) { return "Bar: " + d.l + "," + d.v; });
vis.selectAll("text.value")
.data(data)
.enter().append("svg:text")
.attr("class", "value")
.attr("x", function(d, i) { return x(i) + x.rangeBand() / 2; })
.attr("y", function(d) { return h - m[0] - m[2] - y(d.v); })
.attr("dy", -2)
.attr("text-anchor", "middle")
.text(function(d) { return d.v; })
.append("svg:title")
.text(function(d) { return "Bar value: " + d.v; });
vis.selectAll("text.label")
.data(data)
.enter().append("svg:text")
.attr("class", "label")
.attr("x", function(d, i) { return x(i) + x.rangeBand() / 2; })
.attr("y", h - m[0] - m[2] - y(0))
.attr("dy", 12)
.attr("text-anchor", "middle")
.text(function(d) { return d.l; })
.append("svg:title")
.text(function(d) { return "Bar label<br/>" + d.l + "<br/><a href=\"http://www.google.com\">google</a>"; });
vis.append("svg:line")
.attr("class", "xaxis")
.attr("x1", 0)
.attr("x2", w - m[1] - m[3])
.attr("y1", h - m[0] - m[2] - y(0))
.attr("y2", h - m[0] - m[2] - y(0));
</script>
</body>
</html>
(function($) {
$.fn.tipsy = function(options) {
options = $.extend({}, $.fn.tipsy.defaults, options);
return this.each(function() {
var opts = $.fn.tipsy.elementOptions(this, options);
$(this).hover(function() {
$.data(this, 'cancel.tipsy', true);
var tip = $.data(this, 'active.tipsy');
if (!tip) {
tip = $('<div class="tipsy"><div class="tipsy-arrow"></div><div class="tipsy-inner"/></div>');
tip.css({position: 'absolute', zIndex: 100000});
$.data(this, 'active.tipsy', tip);
}
if ($(this).attr('title') || typeof($(this).attr('original-title')) != 'string') {
$(this).attr('original-title', $(this).attr('title') || '').removeAttr('title');
}
var title;
if (typeof opts.title == 'string') {
title = $(this).attr(opts.title == 'title' ? 'original-title' : opts.title);
} else if (typeof opts.title == 'function') {
title = opts.title.call(this);
}
tip.find('.tipsy-inner')[opts.html ? 'html' : 'text'](title || opts.fallback);
var w = this.offsetWidth || 0;
var h = this.offsetHeight || 0;
if (typeof this.getBBox == 'function'){
var bbox = this.getBBox();
w += bbox.width;
h += bbox.height;
}
var pos = $.extend({}, $(this).offset(), {
width: w,
height: h
});
tip.get(0).className = 'tipsy'; // reset classname in case of dynamic gravity
tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
var actualWidth = tip[0].offsetWidth, actualHeight = tip[0].offsetHeight;
var gravity = (typeof opts.gravity == 'function') ? opts.gravity.call(this) : opts.gravity;
switch (gravity.charAt(0)) {
case 'n':
tip.css({top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tipsy-n');
break;
case 's':
tip.css({top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tipsy-s');
break;
case 'e':
tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}).addClass('tipsy-e');
break;
case 'w':
tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}).addClass('tipsy-w');
break;
}
if (opts.fade) {
tip.css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: 0.8});
} else {
tip.css({visibility: 'visible'});
}
}, function() {
$.data(this, 'cancel.tipsy', false);
var self = this;
setTimeout(function() {
if ($.data(this, 'cancel.tipsy')) return;
var tip = $.data(self, 'active.tipsy');
if (opts.fade) {
tip.stop().fadeOut(function() { $(this).remove(); });
} else {
tip.remove();
}
}, 100);
});
});
};
// Overwrite this method to provide options on a per-element basis.
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
// (remember - do not modify 'options' in place!)
$.fn.tipsy.elementOptions = function(ele, options) {
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
};
$.fn.tipsy.defaults = {
fade: false,
fallback: '',
gravity: 'n',
html: false,
title: 'title'
};
$.fn.tipsy.autoNS = function() {
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
};
$.fn.tipsy.autoWE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
};
})(jQuery);
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
.tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
/* Rounded corners */
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
/* Uncomment for shadow */
.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
/* Rules to colour arrows */
.tipsy-arrow-n { border-bottom-color: #000; }
.tipsy-arrow-s { border-top-color: #000; }
.tipsy-arrow-e { border-left-color: #000; }
.tipsy-arrow-w { border-right-color: #000; }
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment