nvd3 piechart.js - How to edit the tooltip? - javascript

I'm using nvd3's piechart.js component to generate a piechart on my site. The provided .js file includes several var's, as follows:
var margin = {top: 30, right: 20, bottom: 20, left: 20}
, width = null
, height = null
, showLegend = true
, color = nv.utils.defaultColor()
, tooltips = true
, tooltip = function(key, y, e, graph) {
return '<h3>' + key + '</h3>' +
'<p>' + y + '</p>'
}
, noData = "No Data Available."
, dispatch = d3.dispatch('tooltipShow', 'tooltipHide')
;
In my in-line js, I've been able to override some of those variables, like this (overriding showLegend and margin):
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.showLabels(false)
.showLegend(false)
.margin({top: 10, right: 0, bottom: 0, left: 0})
.donut(true);
I've tried overwriting the tooltip in the same way:
.tooltip(function(key, y, e, graph) { return 'Some String' })
but when I do that, my piechart does not display at all. Why can't I overwrite the tooltip here? Is there another way I can do so? I'd really rather not have to edit piechart.js itself at all; I need to keep that file generic for use in multiple widgets.
And while we're at it, is there some way I can make the entire tooltip into a clickable link?

Just override in this way it will work definitely
function tooltipContent(key, y, e, graph) {
return '<h3>' + key + '</h3>' +'<p>' + y + '</p>' ;
}
Or
tooltipContent(function(key, y, e, graph) { return 'Some String' })

I have just got the same problem, with nvd3 1.8.1, and this is the solution I've found.
Without the option useInteractiveGuideline you could simply declare your tooltip generating function in chart.tooltip.contentGenerator(function (d){ YOUR_FUNCTION_HERE}):
The argument d is given by nvd3 when calling the tooltip, and it has three properties :
value: the x-axis value for the cursor position
index: the index in chart's datum corresponding to the the cursor position
series: an array containing, for each item in the chart :
key: the legend key for that item
value: the y-axis value for that item at the cursor position
color: the legend color for that item
So here you have an example:
chart.tooltip.contentGenerator(function (d) {
var html = "<h2>"+d.value+"</h2> <ul>";
d.series.forEach(function(elem){
html += "<li><h3 style='color:"+elem.color+"'>"
+elem.key+"</h3> : <b>"+elem.value+"</b></li>";
})
html += "</ul>"
return html;
})
Important note
When the option useInteractiveGuideline is used, the chart.tooltip object isn't used to generate the tooltip, you must instead use the chart.interactiveLayer.tooltip, i.e.:
this.chart.interactiveLayer.tooltip.contentGenerator(function (d) { ... })
I hope the answer is useful for you, even if late.

Customized tooltip can not exist with "useInteractiveGuideline".

If you happen to use the Angular NVD3 wrapper, the way to set the custom message is through chart options, simply:
$scope.options = {
chart: {
...
tooltip: {
contentGenerator: function(d) {
return d.series[0].key + ' ' + d.series[0].value;
}
},
...
}
};

To add to previous answers, sometimes you want to use the data of the series and not only of x and y. For instance when
data = {'values': [{'month': 1, 'count': 2}, ...], 'key': 'test' }
For those situations, use
.tooltip(function(key, x, y, e, graph) {
var d = e.series.values[e.pointIndex];
return '<h3>' + e.series.key + '</h3><p>' + d.month.toString() + ...;
});
e.series is the particular series the mouse is hovering, e.pointIndex is the index on the values of the series. Here e.series.key == key, but I used to empathise what is e.series.

my_chart = nv.models.multiBarChart()
.tooltip(function(key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
'<p>' + y + ' on ' + x + '</p>';
});

I think you're missing the 'x' parameter in your tooltip function. The format of the function call is:
function(key, x, y, e, graph)

var chart = nv.models.multiBarChart();
chart.tooltip.contentGenerator(function (obj) {
return JSON.stringify("<b>HOHO</b>")
})
This worked for me...

chart:{
interactive:true,
tooltips: true,
tooltip: {
contentGenerator: function (d) {
return '<h3>PUT YOUR DATA HERE E.g. d.data.name</h3>'
}
}
Thank You and Best Regards
Abhay Patidar

Related

Expose additional data based on xAxis element click - Highcharts.js

I'm facing some difficulties while trying to implement 'xAxis clickable' column chart. I'm trying to expose additional Pie charts below my column chart, based on user click on one of the element in xAxis.
The way the first graph is build:
function chartBuilder(data) {
if (data.length === 0) {
return null;
}
var categories = [];
var uniqData = [
{name : 'Fatal', data:[], color:'black', stack: 'fatal'},
{name : 'Critical', data:[], color:'red', stack: 'critical'},
];
_.each(data, function (item) {
categories = categories.concat(item.site);
var fatalValue = {};
fatalValue[item.site] = parseFloat(item.fatal || 0);
uniqData[0].data = uniqData[0].data.concat(fatalValue);
var criticalValue = {};
criticalValue[item.site] = parseFloat(item.critical || 0);
uniqData[1].data = uniqData[1].data.concat(criticalValue);
});
var chartConfig = util.basicConfigChart(categories, uniqData);
chartConfig.yAxis.title = {
text: 'Num Of Events'
};
chartConfig.xAxis.labels = {
formatter: function() {
var ret = this.value,
len = ret.length;
if (len > 10) {
ret = '<strong>' + ret.slice(0,ret.indexOf('_')) + '<br/>' + ret.slice(ret.indexOf('_') + 1, len) + '</strong>';
}
if (len > 25) {
ret = ret.slice(0,25) + '...';
}
return '<strong>' + ret + '</strong>';
},
useHTML: true
};
chartConfig.options.tooltip = {
formatter : function () {
return '<strong>' + this.series.name + '</strong>:' + this.point.y + '<br>Total: ' + this.point.total;
}
};
return chartConfig;
}
So basically, what I need is a way to determine which element in xAxis was clicked, and expose below pie charts with data relevant to this element.
If I understand you correctly, you want to add a click event on the xAxis columns. This can be done using a click event
events: {
click: function (event) {
alert(
'x index: ' + event.point.x + ', \n' +
'series.index: ' + event.point.series.index
);
}
}
This event can be added to a specific series, or to the plotOptions to affect all series.
The code above, will make an alert that shows the relevant indexes.
Working example: https://jsfiddle.net/ewolden/xr17pen6/6/
API on click event: https://api.highcharts.com/highcharts/series.column.events.click

Highcharts passing variable to tooltip

Hi I am trying to pass a variable to my tooltip using setData.
Here is a piece of my code explaining how I am setting the chart data, this code doesn't pass the sensorValue to my tooltip yet:
nitrogenDioxide = [];
$.each(data['NO2'], function(key, value) {
nitrogenDioxide.push([value.ts * 1000, value.rating]);
});
chart_2_1.series[0].setData(nitrogenDioxide);
chart_2_1.series[0].update({name:'Nitrogen Dioxide'}, true);
Here is the code I used to create my tooltip:
tooltip: {
shared: true,
useHTML: true,
formatter: function () {
var tooltipcontent = '<b>' + moment.unix((this.points[0].key / 1000)).format("DD/MM/YYYY HH:mm"); + '</b>';
tooltipcontent += '<table style="width:100%">';
$.each(this.points, function () {
console.log(this);
tooltipcontent += '<tr><td>' + this.y.toLocaleString() + '</td></tr>';
tooltipcontent += '<tr><td>' + sensorValue + '</td></tr>';
});
tooltipcontent += '</table>';
return tooltipcontent;
}
}
As you can see I have a variable called sensorValue in my tooltip. In the foreach loop I have a rating value (y-axis) and a sensor value. I want to pass that sensor value to me tooltip.
I have seen multiple ways of doing this online but none of them set the data the way I do, they do it like so:
new Highcharts.Chart( {
...,
series: [ {
name: 'Foo',
data: [
{
y : 3,
myData : 'firstPoint'
},
{
y : 7,
myData : 'secondPoint'
},
{
y : 1,
myData : 'thirdPoint'
}
]
} ]
} );
I have tried something like this but didn't know how to call this extra value in the tooltip:
nitrogenDioxide = [];
$.each(data['NO2'], function(key, value) {
nitrogenDioxide.push([value.ts * 1000, value.rating, value.value]);
});
In the above code I have pushed the sensor value into the nitrogenDioxide[] array.
I have tried my best to explain what I am trying to do, in my head the explanation makes sense but if it doesnt to you please let me know. Thank you in advance for any help.
I hope I understood correctly what is your issue and the demo posted below will be helpful for you.
When an array with an additional value is passed (sensorValue in your case) it can be retrieved inside formatter using this approach:
get hovered point index: this.point.index
use the point index to get additional value from this.series.userOptions.data array
Code:
Highcharts.chart('container', {
tooltip: {
formatter: function() {
var point = this.point,
series = this.series,
pointIndex = point.index,
text,
additionalValue;
text = '<span style="color:' +
this.color + '">\u25CF</span> ' +
series.name +
': <b>' +
this.y +
'</b><br/>';
additionalValue =
series.userOptions.data[pointIndex][2];
text += '<br> Additional value: ' +
additionalValue;
return text;
}
},
series: [{
data: [
[1, 2, 'aaa'], // 'aaa' is an additional value
[2, 5, 'bbb'],
[3, 9, 'ccc']
]
}],
});
Demo:
https://jsfiddle.net/BlackLabel/3g6om1fw/1/

How to add images to the tooltip NVD3 in r

I have a dataframe that I have managed to create a great chart from and I'm pretty pleased with the result.
However, I would like to add a specific image that is relevant to a point when the user hovers over it. As this is all done on one computer I imagine the file reference will be kept as part of the dataframe and then somehow the tooltip will read the file reference and then display an image preview. This is probably all in javascript but I'm not really sure how to do it or if this is the best method
Here is my dataframe (without filenames referencing images:
TTypedAll2<-structure(list(V1 = c(6L, 13L, 8L, 11L, 6L), TissueType = c("GC","Co","BE", "Tu", "Tu"), Sample = c("SL.Tum_TB05_00.fq.gz", "S.Tum_TB06.fq.gz", "S.Tum_T573.fq.gz", "Tum_TB0578.fq.gz", "TumTB0106.fq.gz"),Samplenum = 1:5), .Names = c("V1", "TissueType", "Sample", "Samplenum"), row.names = c("SL.Tum_TB05_00.fq.gz", "S.Tum_TB06.fq.gz", "S.Tum_T573.fq.gz", "Tum_TB0578.fq.gz", "TumTB0106.fq.gz"), class = "data.frame")
and the code for the plot:
TTypedAll2$Sample<-as.character(TTypedAll2$Sample)
TTypedAll2$Samplenum<-1:nrow(TTypedAll2)
d3chart<-nPlot(V1~Samplenum, group='TissueType', data=TTypedAll2,type="scatterChart")
d3chart$chart(tooltipContent = "#! function(key, x, y, e){
return '' + e.point.Sample
} !#")
d3chart
require(rCharts)
n1 <- nPlot(mpg ~ wt, group = 'gear', data = mtcars, type = 'scatterChart')
n1$chart(tooltipContent = "#! function(key, x, y){
return 'x: ' + x + ' y: ' + y
} !#")
Update
I changed the code that was provided so that I added the full image path I am interested in to my dataframe and then tried this:
d3chart<-nPlot(V1~Samplenum, group='TissueType', data=TTypedAll2,type="scatterChart")
d3chart$chart(tooltipContent = "#! function(item, x, y, e){
return '' + e.point.Sample + '<img src=' + e.point.img + '>'
} !#")
d3chart
No errors but all I get is a question mark instead of the image
Update
OK I think Im getting there but probably have a problem with double quotes. This is what I have so far but it doesnt display the image and I think its because the file path has to be in double quotes but I cant figure out how to do this
d3chart<-nPlot(V1~Samplenum, group='TissueType', data=TTypedAll2,type="scatterChart")
d3chart$chart(tooltipContent = "#! function(item, x, y, e,z){
return '' + e.point.Sample + '<img src=file:///Users/cer.png' + '>'
} !#")
d3chart
I'm not familiar with your R setup, this JavaScript code will change the tooltip to display an image:
nv.addGraph(function() {
var chart = nv.models.scatterChart();
chart.xDomain( [ 0, 10 ] ).yDomain( [ 0, 10 ] );
chart.tooltipContent(function(key, x, y, z, e) {
return '<img class="style-your-image" src="' + e.point.img + '">';
});
var myData = [
{
key: 'Group 1',
values: [
{ x: 3, y: 5, size: 5, shape: 'circle', img: '/static/img/img_1.jpg' }, // image on local server
{ x: 7, y: 5, size: 5, shape: 'circle', img: 'http://placehold.it/150x150' } // Web image
]
}
]
d3.select('#chart svg').datum(myData).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});

Change value on legend in dc.js

I built a pie chart with dc.js, with the following:
var chart = dc.pieChart(selector, this.chartGroup)
.width(200).height(200)
.dimension(this.dimension)
.group(this.group)
...
.legend(dc.legend().x(10).y(255).gap(5).horizontal(true))
chart.render()
Is there a way to format the labels on the legend with something like the following:
function (d) {
return d.key + ': ' + d.value;
}
The last answer seems partially true. I would suggest the following:
.legend(dc.legend().x(100).y(400).itemHeight(13).gap(5).autoItemWidth(true).legendText(function (d) {
return d.name + " " + Math.round((d.data / totalPrice) * 100) + "%"
}));
Where d.name is the actual label you will see in the legend.
d.data is the actual value.
I also needed to add (%) to the pieChart legend for several graphs. I ended up modifying a copy of the legend.js from dc.js-2.0.0-beta.5\src and include that in my pages.
See http://jsfiddle.net/za8ksj45/36/ for working example
The first ~260 lines is the modified legend.js that can be put in a separate file.
(I don't have a place I could serve it from so I had to include the file content).
The main modification starts at line ~88
itemEnter.append('text')
.text(function(d) {
var legendText = d.name;
if (_showPercent) {
var groupTotal = d.chart.group().all().reduce(function(a, v){ return a + v.value; }, 0);
//legendText = legendText + " (" + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%)";
//legendText = legendText + " = " + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%";
legendText = legendText + " - " + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%";
}
return legendText;
})
.attr('x', _itemHeight + LABEL_GAP)
.attr('y', function () {
return _itemHeight / 2 + (this.clientHeight ? this.clientHeight : 13) / 2 - 2;
});
The modification consists of two new methods for legend()
.displayPercent (default=false to keep original behavior the same)
.percentDecimals (default=1)
The hardest part to figure out was the following line:
var groupTotal = d.chart.group().all().reduce(function(a, v){ return a + v.value; }, 0);
It calculates the grand total for the current filtered group that is driving the pieChart which can be used to calculate the percentage.
I played with a couple different string to show percentage. It should probably be replaced with a string like this: - (%%) where %% gets replaced with the actual percentage. That way you can customize it for each legend without having to touch the code.
Works great for a bunch of pieCharts I used so far. I wanted to share this on stackoverflow since I have gotten so much help from this site myself. If this is useful, I can expand it a bit and submit it for inclusion in some future release.
Now you can simply use the .legendText() method in the dc.legend() object!
In your particular case, the solution would be:
var chart = dc.pieChart(selector, this.chartGroup)
.width(200).height(200)
.dimension(this.dimension)
.group(this.group)
...
.legend(dc.legend().x(10).y(255).gap(5).horizontal(true).legendText(function(d) {
return d.key + ': ' + d.value;
}))
chart.render();
This method is defined here.

Customize tooltip in Highcharts.js?

I have the following question:
How can I customize the chart tooltip using Highcharts.js
library?
any help is appreciated.
If you want to customize the tooltip of your highcharts.js chart, you can do it defining a formatter
for the tooltip property of your chart_object, like this:
var chart_object = {
(...)
tooltip: {
formatter: function() {
return '<span>' + 'My HTML ' + this.x + '</span> : <b>' + this.y + '</b>';
}
},
(...)
}
You will use the chart_object later to initialize your Highcharts chart:
var chart = new Highcharts.Chart(chart_object );
I hope it helps.

Categories

Resources