Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change tooltip content in c3js

Tags:

I'm working on a timeline display and I have data that I want to show on the tooltip. currently it only shows the value at each time. and I cannot find a way to change it. the example below shows how to change the value's format but not what values are displayed

var chart = c3.generate({ data: {     columns: [         ['data1', 30000, 20000, 10000, 40000, 15000, 250000],         ['data2', 100, 200, 100, 40, 150, 250]     ],     axes: {         data2: 'y2'     } }, axis : {     y : {         tick: {             format: d3.format("s")         }     },     y2: {         show: true,         tick: {             format: d3.format("$")         }     } }, tooltip: {     format: {         title: function (d) { return 'Data ' + d; },         value: function (value, ratio, id) {             var format = id === 'data1' ? d3.format(',') : d3.format('$');             return format(value);         }            //value: d3.format(',') // apply this format to both y and y2     } } }); 

it's taken from http://c3js.org/samples/tooltip_format.html they do admit that there isn't an example for content editing but I couldn't find anything in the reference or forums, but a suggestion to change the code (it's here: https://github.com/masayuki0812/c3/blob/master/c3.js in line 300) and below:

__tooltip_contents = getConfig(['tooltip', 'contents'], function (d, defaultTitleFormat, defaultValueFormat, color) {         var titleFormat = __tooltip_format_title ? __tooltip_format_title : defaultTitleFormat,             nameFormat = __tooltip_format_name ? __tooltip_format_name : function (name) { return name; },             valueFormat = __tooltip_format_value ? __tooltip_format_value : defaultValueFormat,             text, i, title, value, name, bgcolor;         for (i = 0; i < d.length; i++) {             if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }              if (! text) {                 title = titleFormat ? titleFormat(d[i].x) : d[i].x;                 text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");             }              name = nameFormat(d[i].name);             value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);             bgcolor = levelColor ? levelColor(d[i].value) : color(d[i].id);              text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";             text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";             text += "<td class='value'>" + value + "</td>";             text += "</tr>";         }         return text + "</table>";     }) 

did anyone attempted to do so? developed some function to facilitate the process? have any tips on how to do so correctly? I do not know how to change their code in a way I could use more data or data different than the d value the function gets.

like image 494
Adi Avatar asked Jul 15 '14 09:07

Adi


Video Answer


2 Answers

If you use the function getTooltipContent from https://github.com/masayuki0812/c3/blob/master/src/tooltip.js#L27 and add it in the chart declaration, in tooltip.contents, you'll have the same tooltip content that the default one.

You can make changes on this code and customize it as you like. One detail, as CLASS is not defined in the current scope, but it's part chart object, I substituted CLASS for $$.CLASS, maybe you don't even need this Object in your code.

var chart = c3.generate({   /*...*/   tooltip: {       format: {         /*...*/       },       contents: function (d, defaultTitleFormat, defaultValueFormat, color) {           var $$ = this, config = $$.config,               titleFormat = config.tooltip_format_title || defaultTitleFormat,               nameFormat = config.tooltip_format_name || function (name) { return name; },               valueFormat = config.tooltip_format_value || defaultValueFormat,               text, i, title, value, name, bgcolor;           for (i = 0; i < d.length; i++) {               if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }                if (! text) {                   title = titleFormat ? titleFormat(d[i].x) : d[i].x;                   text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");               }                name = nameFormat(d[i].name);               value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);               bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);                text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";               text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";               text += "<td class='value'>" + value + "</td>";               text += "</tr>";           }           return text + "</table>";       }   } }); 
like image 164
supita Avatar answered Nov 15 '22 11:11

supita


If you want to control tooltip render and use default rendering depending on data value you can use something like this:

tooltip: {     contents: function (d, defaultTitleFormat, defaultValueFormat, color) {         if (d[1].value > 0) {             // Use default rendering             return this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color);         } else {             return '<div>Show what you want</div>';         }     },     format: {         /**/     } } 
like image 45
Ivan Avatar answered Nov 15 '22 11:11

Ivan