I have a Leaflet map with polygons, you can click on each polygon to select them and there is an info window "L.control" that shows the values for the selected polygon. As you continue click on polygons the info window add values for each selected and you get total values for all selected polygons. All this is fine but I need to get down to more detailed sum for specific properties like the example below of regions. If ten polygons are selected I want to differentiate the total amount for regions with properties "REGION SOUTH" and "REGION NORTH" as well as the total of all.
This is the code I'm using, to sum the totals of different properties is no problem but how do you sum for defined properties?
How and where can I add a kind of filter solution that sum only the properties I want?
$.each(statesData.features, function(index, feature) {
var name = `${feature.properties.ZIPCODE} ${feature.properties.Name} ( ${feature.properties.average_time} - ${feature.properties.CITY})`
placenames.push(name);
zipcodes[name] = feature.properties.ZIPCODE;
time = feature.properties.average_time
});
etc....
// Now get the totals of selected polygons
var detailshow = function() {
var result = ''
var total = 0
var total1 = 0
var total2 = 0
var total3 = 0
var total4 = 0
for (var i = 0; i < featuresSelected.length; i++) {
var properties = featuresSelected[i].feature.properties
result +=
`
${properties.CITY}<br>
Zipcode: ${properties.ZIPCODE}
<a href="#" onclick=dellayer(${properties.ZIPCODE})>Delete</a>
<hr>`;
total += properties.amount, // sum amount for all regions
total1 += properties.average_time, // in seconds
total2 += properties.distance,
total3 += properties.amount, // amount for Region South only
total4 += properties.amount, // amount for Region North only
// Convert seconds to timeformat
var convertTime = function (input, separator) {
var pad = function(input) {return input < 10 ? "0" + input : input;};
return [
pad(Math.floor(input / 3600)),
pad(Math.floor(input % 3600 / 60)),
pad(Math.floor(input % 60)),
].join(typeof separator !== 'undefined' ? separator : ':' );
}
var resultTime = convertTime(total1);
}
return {
result: result,
total: total,
resultTime: resultTime,
total2: total2
total3: total3
total4: total4
};
}
detailsselected.update = function(arrayselected) {
var details = detailshow()
this._div.innerHTML =
'<b>Zipcodes</b><br>' +
'Total time: <b>' + details.resultTime + ' hh:mm:ss</b><br>' +
'Total amount: <b>' + details.total + ' st</b><br>' +
'Region South amount: <b>' + details.total3 + ' st</b><br>' +
'Region North amount: <b>' + details.total4 + ' st</b><br>' +
'Distance: <b>' + details.total2.toFixed(1) + ' km</b><br>';
$('#suma', window.parent.document).val(details.resultTime, details.total, details.total2, details.total3, details.total4);
};
detailsselected.addTo(map);
FeatureSelected:
function checkExistsLayers(feature) {
var result = false
for (var i = 0; i < featuresSelected.length; i++) {
if (featuresSelected[i].ZIPCODE == feature.properties.ZIPCODE) {
result = true;
break;
}
};
return result
}
This is part of the json file structure:
var statesData = new L.LayerGroup;
var statesData = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"ZIPCODE":12345,"CITY":"LONDON","REGION":"REGION SOUTH","amount":1088,"average_time":26150,"distance":2.2},"geometry":{"type":"MultiPolygon","coordinates":...
I did try the following but that did not work...
function filt_north (feature){
if (feature.properties.REGION === 'REGION NORTH' )
return true;
}
total4 += filt_north.(properties.amount), // amount for Region North only
The filt_north function you wrote looks good, just add a filt_south filter to get the south region and do:
let filteredResults = featuresSelected.filter(
result => filt_north(result.feature) || filt_south(result.feature)
);
for (let result of filteredResults) {
var properties = result.feature.properties;
...
Tried your solution, seems it breaks the code and totals is not added up at all = stopped working. I did this, should it be done in a different way?
Filter function:
function filt_south (feature){
if (feature.properties.REGION === 'REGION SOUTH')
return true;
}
function filt_north (feature){
if (feature.properties.REGION === 'REGION NORTH')
return true;
}
Then changed to this (I must be doing something wrong here):
// Now get the totals of selected polygons
var detailshow = function() {
var result = ''
var total = 0
var total1 = 0
var total2 = 0
var total3 = 0
var total4 = 0
let filteredResults = featuresSelected.filter(
result => filt_south(result.feature) || filt_north(result.feature)
);
for (let result of filteredResults) {
var properties = result.feature.properties;
for (var i = 0; i < featuresSelected.length; i++) {
var properties = featuresSelected[i].feature.properties
result +=
`
${properties.CITY}<br>
Zipcode: ${properties.ZIPCODE}
<a href="#" onclick=dellayer(${properties.ZIPCODE})>Delete</a>
<hr>`;
total += properties.amount, // sum amount for all regions
total1 += properties.average_time,
total2 += properties.distance,
total3 += filt_south (properties.amount), // amount for Region South only
total4 += filt_north (properties.amount) // amount for Region North only
// Convert seconds to timeformat
var convertTime = function (input, separator) {
var pad = function(input) {return input < 10 ? "0" + input : input;};
return [
pad(Math.floor(input / 3600)),
pad(Math.floor(input % 3600 / 60)),
pad(Math.floor(input % 60)),
].join(typeof separator !== 'undefined' ? separator : ':' );
}
var resultTime = convertTime(total1);
}
}
return {
result: result,
total: total,
resultTime: resultTime,
total2: total2
total3: total3
total4: total4
};
}
detailsselected.update = function(arrayselected) {
var details = detailshow()
this._div.innerHTML =
'<b>Zipcodes</b><br>' +
'Total time: <b>' + details.resultTime + ' hh:mm:ss</b><br>' +
'Total amount: <b>' + details.total + ' st</b><br>' +
'Region South amount: <b>' + details.total3 + ' st</b><br>' +
'Region North amount: <b>' + details.total4 + ' st</b><br>' +
'Distance: <b>' + details.total2.toFixed(1) + ' km</b><br>';
$('#suma', window.parent.document).val(details.resultTime, details.total, details.total2, details.total3, details.total4);
};
detailsselected.addTo(map)
Here is the link to what i'm trying to do. I want to flip the blue bars to face to opposite way on the male side then I will fill in the female side as normal. This will create a tornado chart. I've been working on this for hours and I cant figure it out. I'm using Raphael JS.
http://math.mercyhurst.edu/~cmihna/DataViz/Butterfly.html
Just finished up reviewing your website's source code. No need for transforms, or anything of the such. Just some simple math added to your graph generating for-loop.
Your Code below
ind = 0
for (var key in gender) { // loop over all possible gender
for ( var i = 0; i < people.length; i++ ) { // loop over people
if (people[i][key] != 0) {
var barmale = paper.rect((w+leftPadding-rightPadding)/2,topPadding + vs*0 + i*vs, people[i][key],vs)
barmale.attr({'fill': '#0000A0', 'stroke-width':1})
var barfemale = paper.rect((w+leftPadding-rightPadding)/2, topPadding + vs*0 + i*vs, people2[i][key],-vs)
barfemale.attr({'fill': '#FFC0CB', 'stroke-width':1})
barmale.scale(1,-1)
//var dp = paper.circle(leftPadding + ind*hs + 0.5*hs, topPadding + vs*0.5 + i*vs, people[i][key])
//dp.attr({ 'fill': colors[ind] })
barmale.id = people[i][key] + " " + gender[key] + " people in this age range"
barmale.hover(hoverStart, hoverEnd)
barfemale.id = people[i][key] + " " + gender[key] + " people in this age range"
barfemale.hover(hoverStart, hoverEnd)
}
}
ind++
My Code Below
ind = 0
for (var key in gender) { // loop over all possible gender
for ( var i = 0; i < people.length; i++ ) { // loop over people
if (people[i][key] != 0) {
var barmale = paper.rect((w+leftPadding-rightPadding)/2 - people[i][key],topPadding + vs*0 + i*vs, people[i][key],vs)
barmale.attr({'fill': '#0000A0', 'stroke-width':1})
var barfemale = paper.rect((w+leftPadding-rightPadding)/2, topPadding + vs*0 + i*vs, people2[i][key],vs)
barfemale.attr({'fill': '#FFC0CB', 'stroke-width':1})
barmale.scale(1,-1)
//var dp = paper.circle(leftPadding + ind*hs + 0.5*hs, topPadding + vs*0.5 + i*vs, people[i][key])
//dp.attr({ 'fill': colors[ind] })
barmale.id = people[i][key] + " " + gender[key] + " people in this age range"
barmale.hover(hoverStart, hoverEnd)
barfemale.id = people2[i][key] + " " + gender[key] + " people in this age range"
barfemale.hover(hoverStart, hoverEnd)
}
}
ind++
You can see that I am subtracting the value of the Males from the placement on the graph. This causes the offset to "flip". Then, I modified the code a bit more the bring the female graph into the picture and properly label it.
Please let me know if any questions.
Proof below
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.
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>";
}
}
});
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: {
/**/
}
}
In my case i had to add the day for the date value(x axis) in tool tip. Finally i came came up with the below solution
References for js and css
https://code.jquery.com/jquery-3.2.1.js
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js
https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js
https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css
function toDate(dateStr)
{
var numbers = dateStr.match(/\d+/g);
return new Date(numbers[0], numbers[1]-1, numbers[2]);
}
function GetMonthFromString(month)
{
var months = {'Jan' : '01','Feb' : '02','Mar':'03','Apr':'04',
'May':'05','Jun':'06','Jul':'07','Aug':'08','Sep':'09',
'Oct':'10','Nov':'11','Dec':'12'};
return months[month];
}
function GetFullDayName(formatteddate)
{
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
var dayofdate = weekday[formatteddate.getDay()];
return dayofdate;
}
//Chart Data for x-axis, OnHours and AvgHours
function CollectChartData()
{
var xData = new Array();
var onHoursData = new Array();
var averageHoursData = new Array();
var instanceOccuringDatesArray = ["2017-04-20","2017-04-21","2017-04-22","2017-04-23","2017-04-24","2017-04-25","2017-04-26","2017-04-27","2017-04-28","2017-04-29","2017-04-30","2017-05-01","2017-05-02","2017-05-03","2017-05-04","2017-05-05","2017-05-06","2017-05-07","2017-05-08","2017-05-09","2017-05-10","2017-05-11","2017-05-12","2017-05-13","2017-05-14","2017-05-15","2017-05-16","2017-05-17","2017-05-18","2017-05-19","2017-05-20"];
var engineOnHoursArray = ["4.01","14.38","0.10","0.12","0.01","0.24","0.03","6.56","0.15","0.00","1.15","0.00","1.21","2.06","8.55","1.41","0.03","1.42","0.00","3.35","0.02","3.44","0.05","5.41","4.06","0.02","0.04","7.26","1.02","5.09","0.00"];
var avgUtilizationArray = ["2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29"];
xData.push('x');
onHoursData.push('OnHours');
averageHoursData.push('Project Average');
for(var index=0;index<instanceOccuringDatesArray.length;index++)
{
xData.push(instanceOccuringDatesArray[index]);
}
for(var index=0;index<engineOnHoursArray.length;index++)
{
onHoursData.push(engineOnHoursArray[index]);
}
for(var index=0;index<avgUtilizationArray.length;index++)
{
averageHoursData.push(avgUtilizationArray[index]);
}
var Data = [xData, onHoursData, averageHoursData];
return Data;
}
function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config, CLASS = $$.CLASS,
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;
// You can access all of data like this:
//$$.data.targets;
for (i = 0; i < d.length; i++) {
if (! text) {
title = titleFormat ? titleFormat(d[i].x) : d[i].x;
var arr = title.split(" ");
var datestr = new Date().getFullYear().toString() + "-"+ GetMonthFromString(arr[1]) + "-"+ arr[0];
var formatteddate = toDate(datestr);
var dayname = GetFullDayName(formatteddate);
title = title + " (" + dayname + ")";
text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
name = nameFormat(d[i].name);
var initialvalue = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
if (initialvalue.toString().indexOf('.') > -1)
{
var arrval = initialvalue.toString().split(".");
value = arrval[0] + "h " + arrval[1] + "m";
}
else
{
value = initialvalue + "h " + "00m";
}
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>";
}
$(document).ready(function () {
var Data = CollectChartData();
var chart = c3.generate({
data: {
x: 'x',
columns: Data
},
axis: {
x: {
type: 'timeseries',
tick: {
rotate: 75,
//format: '%d-%m-%Y'
format: '%d %b'
}
},
y : {
tick : {
format: function (y) {
if (y < 0) {
}
return y;
}
},
min : 0,
padding : {
bottom : 0
}
}
},
tooltip: {
contents: tooltip_contents
}
});
});
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css" rel="stylesheet" />
<div id="chart"></div>
When we have a stacked bar chart and we would like to show "Total" in the tooltip (but not in the chart as a bar/stack) this can come handy.
C3 charts use a array to store the data for tooltips and before the tooltips are displayed we are adding totals (or anyother data as per our requirement). By doing this though the totals is not available as a stack it is shown in the tooltip.
function key_for_sum(arr) {
return arr.value; //value is the key
};
function sum(prev, next) {
return prev + next;
}
var totals_object = {};
totals_object.x = d[0]['x'];
totals_object.value = d.map(key_for_sum).reduce(sum);
totals_object.name = 'total';
totals_object.index = d[0]['index'];
totals_object.id = 'total';
d.push(totals_object);
Above code has been added to ensure that total is available in
C3.js Stacked Bar chart's tooltip
var chart = c3.generate({
/*...*/
tooltip: {
format: {
/*...*/
},
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
function key_for_sum(arr) {
return arr.value; //value is the key
}
function sum(prev, next) {
return prev + next;
}
var totals_object = {};
totals_object.x = d[0]['x'];
totals_object.value = d.map(key_for_sum).reduce(sum);// sum func
totals_object.name = 'total';//total will be shown in tooltip
totals_object.index = d[0]['index'];
totals_object.id = 'total';//c3 will use this
d.push(totals_object);
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>";
}
}
Adding additional content or non-numerical data into the chart tooltips can be done.
This builds on #supita's excellent answer http://stackoverflow.com/a/25750639/1003746.
Its possible to insert additional metadata about each line into the classes parameter when generating/updating the chart. These can then be added as rows to the tooltip.
This doesn't seem to affect the chart - unless you are using the data.classes feature.
data: {
classes: {
data1: [{prop1: 10, prop2: 20}, {prop1: 30, prop2: 40}],
data2: [{prop1: 50, prop2: 60}'{prop1: 70, prop2: 80}]
}
}
To pick up the metadata in the config.
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
const $$ = this;
const config = $$.config;
const meta = config.data_classes;
...
for (i = 0; i < d.length; i++) {
if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
if (! text) {
...
}
const line = d[0].id;
const properties = meta.classes[line];
const property = properties? properties[i] : null;
Then add the following rows to the table to show the new properties.
if (property ) {
text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>PROP1</td>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + property.prop1 + "</td>";
text += "</tr>";
text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>PROP2</td>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" +
property.prop2+ " cm/s</td>";
If anybody cares, here is a ClojureScript version of the above algorithm (e.g. supita's answer), slightly simplified (without support for config). (This is probably nothing the OP asked for, but as of now there are so few resources on the net on this topic that most people might wind up here.)
:tooltip {
:contents
(fn [d default-title-format default-value-format color]
(this-as this
(let [this-CLASS (js->clj (.-CLASS this) :keywordize-keys true)
tooltip-name-class (:tooltipName this-CLASS)
rows (js->clj d :keywordize-keys true)
title-row (->> (first rows) (#(str "<table class='" (:tooltip this-CLASS)
"'><tr><th colspan='2'>"
(default-title-format (:x %)) "</th></tr>")))
data-rows (->> rows
(map #(str "<tr class='" tooltip-name-class "--" (:id %) "'>"
"<td class='name'><span style='background-color:"
(color (:id %)) "'></span>" (:name %) "</td>"
"<td class='value'>" (default-value-format (:value %)) "</td>"
"</tr>")))]
(str title-row (string/join data-rows) "</table>"))))}
Your question is about changing the content of the tooltip in c3js.
The tooltip has 3 variables
+----------------+
| title |
+----------------+
| name | value |
+----------------+
Plus, you want to add 'name' from an additional variable, other than those used in 'column'.
tooltip: {
format: {
title(x, index) { return ''; },
name(name, ratio, id, index) { return lst[index + 1]; },
value(value, ratio, id, index) { return value; }
}
},
this worked for me, feel free to play around with the arguments, to get what you need.
I faced a problem which is related tooltip position and style for c3 before. in order to arrange tooltip in c3 freely, my suggestion is manipulating tooltip with d3.
// internal = chart.internal()
const mousePos = d3.mouse(internal.svg.node()); // find mouse position
const clientX = mousePos[0]; //for x
const clientY = mousePos[1]; //for y
const tooltip = d3.select("#tooltip"); //select tooltip div (apply your style)
tooltip.style("display", "initial"); //show tooltip
tooltip.style("left", clientX - mouseOffSet.X + "px"); // set position
tooltip.style("top", clientY - mouseOffSet.Y + "px"); // set position
tooltip.html("<span>" + content + "</span>");
// you can arrange all content and style whatever you want
<div
id="tooltip"
className="your-style"
style={{ display: "none", position: "absolute" }}
/>
Good luck!!