D3 tooltips
by JaelB
HTML
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.6/dc.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.6/dc.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<div id='stack'></div>
<div id='line'></div>
</body>
</html>
CSS
div.tooltip {
position: absolute;
text-align: center;
width: 220px;
height: 125px;
padding: 2px;
font: 12px Arial;
background: white;
border: solid 1px;
border-color: lightgrey;
border-radius: 4px;
pointer-events: none;
}
.toolHead {
padding: 5px;
text-align: left;
font-family: sans-serif;
border-bottom: 2px solid #2196F3;
font-size: 14px;
/* border-bottom: 1px dashed black; */
-webkit-text-fill-color: #2196F3;
}
td {
padding: 5px;
text-align: right;
font-family: sans-serif;
}
JavaScript
var lines = dc.seriesChart('#line');
var stacks = dc.barChart('#stack');
var timeFmt = d3.timeParse('%d-%b-%Y %H:%M');
var numberFormat = d3.format('.2f');
d3.csv('https://raw.githubusercontent.com/JaelB/Generic-DC.js-Chart/master/fiddle3.csv').then(function(data) {
var ndx = crossfilter(data);
var XDimension = ndx.dimension(function(d) {
return d.no;
});
var YDimension = XDimension.group().reduce(
function reduceAdd(p, d) {
++p.count;
p.bottom += +d.bottom;
p.top += +d.top;
p.extra += +d.extra;
p.avg = p.bottom ? (p.top / p.bottom) : 0;
p[d.sub_no] = (p[d.sub_no] || 0) + p.bottom ? (p.top / p.bottom) : 0;
return p;
},
function reduceRemove(p, d) {
--p.count;
p.bottom -= +d.bottom;
p.top -= +d.top;
p.extra -= +d.extra;
p.avg = p.bottom ? (p.top / p.bottom) : 0;
p[d.sub_no] = (p[d.sub_no] || 0) - p.bottom ? (p.top / p.bottom) : 0;
return p;
},
function reduceInitial() {
return {
count: 0,
bottom: 0,
top: 0,
extra: 0,
avg: 0
};
});
var dateDimension = ndx.dimension(function(d) {
return [timeFmt(d.date), d.no, d.sub_no, d.type, +d.top, +d.bottom];
});
var lineGroup = dateDimension.group().reduceSum(function(d) {
if (d.type == 'X' || d.type == 'Y')
return +d.extra;
else return null;
});
var dummy = ndx.dimension(function(d) {
return timeFmt(d.date);
});
var startDate = timeFmt(dummy.bottom(1)[0].date);
var endDate = timeFmt(dummy.top(1)[0].date);
function sel_stack(sub) {
return function(dataItem) {
return dataItem.value[sub];
};
}
function remove_empty_bins(source_group) {
return {
all: function() {
return source_group.all().filter(function(d) {
return d.value != 0;
});
}
};
}
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
...