Skip to content
Snippets Groups Projects
Commit 38eb1c33 authored by Allen Gilliland's avatar Allen Gilliland
Browse files

Merge pull request #481 from metabase/tooltips

Tooltips
parents 12d525fc 708bdccc
Branches
Tags
No related merge requests found
......@@ -27,6 +27,7 @@
"angularytics": "0.3.0",
"crossfilter": "1.3.11",
"d3": "3.5.3",
"d3-tip": "^0.6.7",
"dc": "2.0.0-beta.1",
"fixed-data-table": "0.2.0",
"jquery": "2.1.4",
......
......@@ -8,6 +8,9 @@ import d3 from 'd3';
import dc from 'dc';
import moment from 'moment';
import tip from 'd3-tip';
tip(d3);
// ---------------------------------------- TODO - Maybe. Lots of these things never worked in the first place. ----------------------------------------
// IMPORTANT
// - 'titles' (tooltips)
......@@ -358,12 +361,49 @@ function applyChartColors(dcjsChart, card) {
return dcjsChart.ordinalColors([chartColor].concat(colorList));
}
function applyChartTooltips(dcjsChart, card) {
// set the title (tooltip) function for points / bars on the chart
console.log('tip tip tip');
return dcjsChart.title(function(d) {
var commasFormatter = d3.format(",.0f");
return d.key + ": " + commasFormatter(d.value);
function applyChartTooltips(dcjsChart, card, cols) {
dcjsChart.renderlet(function(chart) {
// Remove old tooltips which are sometimes not removed due to chart being rerendered while tip is visible
// We should only ever have one tooltip on screen, right?
Array.prototype.forEach.call(document.querySelectorAll('.ChartTooltip'), (t) => t.parentNode.removeChild(t));
var valueFormatter = d3.format(',.0f');
var tip = d3.tip()
.attr('class', 'ChartTooltip')
.direction('n')
.offset([-10, 0])
.html(function(d) {
return (
'<div><span class="ChartTooltip-key">' + cols[0].name + '</span> <span class="ChartTooltip-value">' + d.data.key + '</span></div>' +
'<div><span class="ChartTooltip-key">' + cols[1].name + '</span> <span class="ChartTooltip-value">' + valueFormatter(d.data.value) + '</span></div>'
);
});
chart.selectAll('rect.bar,circle.dot,g.pie-slice path,circle.bubble,g.row rect')
.call(tip)
.on('mouseover.tip', function(x) {
tip.show.apply(tip, arguments);
if (card.display === "pie") {
var arc = d3.svg.arc()
.outerRadius(chart.radius()).innerRadius(x.innerRadius)
.padAngle(x.padAngle).startAngle(x.startAngle).endAngle(x.endAngle);
var centroid = arc.centroid();
var pieRect = this.parentNode.parentNode.getBoundingClientRect();
var pieCenter = [pieRect.left + chart.radius(), pieRect.top + chart.radius()];
var tooltip = d3.select('.ChartTooltip');
var tooltipRect = tooltip[0][0].getBoundingClientRect();
var tooltipOffset = [-tooltipRect.width / 2, -tooltipRect.height - 20];
tooltip.style({
top: pieCenter[1] + tooltipOffset[1] + centroid[1] + "px",
left: pieCenter[0] + tooltipOffset[0] + centroid[0] + "px",
"pointer-events": "none" // d3-tip forces "pointer-events: all" which cases flickering when the tooltip is under the cursor
});
}
})
.on('mouseleave.tip', tip.hide);
chart.selectAll('title').remove();
});
}
......@@ -763,6 +803,9 @@ export var CardRenderer = {
return d.key + ': ' + d.value + ' (' + percent + '%)';
});
applyChartTooltips(chart, card, result.cols);
chart.render();
},
......@@ -824,7 +867,7 @@ export var CardRenderer = {
// TODO: if we are multi-series this could be split axis
applyChartYAxis(chart, card, result.cols, data, MIN_PIXELS_PER_TICK.y);
applyChartTooltips(chart, card);
applyChartTooltips(chart, card, result.cols);
applyChartColors(chart, card);
// if the chart supports 'brushing' (brush-based range filter), disable this since it intercepts mouse hovers which means we can't see tooltips
......@@ -901,7 +944,7 @@ export var CardRenderer = {
// TODO: if we are multi-series this could be split axis
applyChartYAxis(chart, card, result.cols, data, MIN_PIXELS_PER_TICK.y);
applyChartTooltips(chart, card);
applyChartTooltips(chart, card, result.cols);
applyChartColors(chart, card);
// if the chart supports 'brushing' (brush-based range filter), disable this since it intercepts mouse hovers which means we can't see tooltips
......
/* based on https://rawgit.com/Caged/d3-tip/master/examples/example-styles.css */
.ChartTooltip {
width: 200px;
line-height: 1;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
pointer-events: none;
border-radius: 4px;
}
/* Creates a small triangle extender for the tooltip */
.ChartTooltip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
position: absolute;
pointer-events: none;
}
/* Northward tooltips */
.ChartTooltip.n:after {
content: "\25BC";
margin: -1px 0 0 0;
top: 100%;
left: 0;
text-align: center;
}
/* Eastward tooltips */
.ChartTooltip.e:after {
content: "\25C0";
margin: -4px 0 0 0;
top: 50%;
left: -8px;
}
/* Southward tooltips */
.ChartTooltip.s:after {
content: "\25B2";
margin: 0 0 1px 0;
top: -8px;
left: 0;
text-align: center;
}
/* Westward tooltips */
.ChartTooltip.w:after {
content: "\25B6";
margin: -4px 0 0 -1px;
top: 50%;
left: 100%;
}
.ChartTooltip-key {
font-weight: bold;
}
.ChartTooltip-key:after {
content: ":";
}
......@@ -98,6 +98,7 @@ module.exports = {
'd3': __dirname + '/node_modules/d3/d3.min.js',
'crossfilter': __dirname + '/node_modules/crossfilter/index.js',
'dc': __dirname + '/node_modules/dc/dc.js',
'd3-tip': __dirname + '/node_modules/d3-tip/index.js'
}
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment