Tooltip component for d3.compose.
xxxxxxxxxx
<link rel="stylesheet" type="text/css" href="https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose.css">
<style>
.chart {width: 465px; height: 480px; float: left; margin: 10px; font-family: sans-serif;}
.chart + .chart {margin-left: 0;}
.tooltip {
margin: 0;
padding: 5px;
font-size: 12px;
border: solid 1px #666;
background-color: #fff;
}
.tooltip:before {
border-left: solid transparent 5px;
border-right: solid transparent 5px;
border-top: solid #666 5px;
bottom: -4.5px;
content: " ";
height: 0;
left: 50%;
margin-left: -5px;
position: absolute;
width: 0;
}
.tooltip:after {
border-left: solid transparent 5px;
border-right: solid transparent 5px;
border-top: solid #fff 5px;
bottom: -3px;
content: " ";
height: 0;
left: 50%;
margin-left: -5px;
position: absolute;
width: 0;
}
</style>
<div id="lines" class="chart"></div>
<div id="bars" class="chart"></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3.chart/0.2.1/d3.chart.min.js"></script>
<script src="https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose-all.js"></script>
<script>
var Overlay = d3c.Overlay;
Overlay.extend('Tooltip', {
initialize: function(options) {
Overlay.prototype.initialize.call(this, options);
this.p = this.base.append('p').attr('class', 'tooltip');
this.points = {};
this.on('attach', function() {
this.container.on('mouseenter:point', function(point) {
this.points[point.key] = point;
this.render();
}.bind(this));
this.container.on('mouseleave:point', function(point) {
delete this.points[point.key];
this.render();
}.bind(this));
});
},
render: function() {
if (!Object.keys(this.points).length) {
this.hide();
return;
}
var closest;
for (var key in this.points) {
var point = this.points[key];
if (!closest || point.distance < closest.distance) {
closest = this.points[key];
}
}
this.p.text('(' + closest.d.x + ', ' + closest.d.y + ')');
var x = closest.meta.x;
var y = closest.meta.y;
var tooltipHeight = 4.5;
this.show();
this.position({
chart: {
x: x - (this.width() / 2),
y: y - tooltipHeight - this.height()
}
});
}
});
function createChart(type, data) {
var xScale = {data: data, key: 'x'};
var yScale = {domain: [0, 100]};
if (type == 'bars') {
xScale.type = 'ordinal';
xScale.adjacent = true;
}
var charts = [
d3c[type]({data: data, xScale: xScale, yScale: yScale})
];
var xAxis = d3c.axis({scale: xScale});
var yAxis = d3c.axis({scale: yScale});
var tooltip = {type: 'Tooltip'};
return [
[yAxis, d3c.layered(charts)],
xAxis,
tooltip
];
}
// Lines chart
var lines = d3.select('#lines').chart('Compose', function(data) {
return createChart('lines', data);
}).width(465).height(480).margins({top: 35, right: 40});
// Bars chart
var bars = d3.select('#bars').chart('Compose', function(data) {
return createChart('bars', data);
}).width(465).height(480).margins({top: 35, right: 40});
// Draw
var data = [
{
key: 'series-1',
values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(function(x, i) {
return {x: x, y: x * x, key: '1-' + i};
})
},
{
key: 'series-2',
values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(function(x, i) {
return {x: x, y: x * 10, key: '2-' + i};
})
}
];
lines.draw(data);
bars.draw(data);
</script>
https://d3js.org/d3.v3.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3.chart/0.2.1/d3.chart.min.js
https://npmcdn.com/d3.compose@0.15.13/dist/d3.compose-all.js