Adding a Chart inside a C3 Tooltip
You can use the tooltip element that c3 already has. In your contents function call the generateGraph
function (see next step). Pass in the tooltip element available in this.tooltip
in addition to the data.
...
tooltip: {
contents: function (d) {
// this creates a chart inside the tooltips
var content = generateGraph(this.tooltip, d[0], d[1])
// we don't return anything - see .html function below
}
}
...
Your generateGraph
function basically creates a c3 chart in your tooltip element (bindto
supports a d3 element). We do a bit of optimization (if the data is same, the chart is not recreated) and cleanup (when a chart is recreated it is destroyed and removed from the DOM)
function generateGraph(tooltip, data1, data2) {
// if the data is same as before don't regenrate the graph - this avoids flicker
if (tooltip.data1 &&
(tooltip.data1.name === data1.name) && (tooltip.data1.value === data1.value) &&
(tooltip.data2.name === data2.name) && (tooltip.data2.value === data2.value))
return;
tooltip.data1 = data1;
tooltip.data2 = data2;
// remove the existing chart
if (tooltip.chart) {
tooltip.chart = tooltip.chart.destroy();
tooltip.selectAll('*').remove();
}
// create new chart
tooltip.chart = c3.generate({
bindto: tooltip,
size: {
width: 200,
height: 200
},
data: {
columns: [[data1.name, data1.value], [data2.name, data2.value]],
type: 'pie'
}
});
// creating a chart on an element sets its position attribute to relative
// reset it to absolute (the tooltip was absolute originally) for proper positioning
tooltip.style('position', 'absolute');
}
Note that we set the chart size so that it's more like tooltip content instead of a subchart.
The last bit is a bit hacky - since c3 requires that we set a HTML (which we don't want to do) and because we don't have any other callbacks we can easily hitch onto after the content handler, we have to disable the function that c3 uses to set the html content on the tooltip (this will affect only this chart's tooltip) i.e. .tooltip.html
// MONKEY PATCHING (MAY break if library updates change the code that sets tooltip content)
// we override the html function for the tooltip to not do anything (since we've already created the tooltip content inside it)
chart.internal.tooltip.html = function () {
// this needs to return the tooltip - it's used for positioning the tooltip
return chart.internal.tooltip;
}
Fiddle - http://jsfiddle.net/muuqvf1a/
Tooltip Positioning
Instead of using c3's tooltip positioning you could also size and position the tooltip at the bottom of the chart. Just style .c3-tooltip-container
.
Alternatives
Note that c3 also support subcharts (http://c3js.org/reference.html#subchart-show) and data.mouseover
(http://c3js.org/reference.html#data-onmouseover) which could also be a cleaner avenues worth exploring.