Tooltip html google charts - javascript

I have a tooltip setting as below in JS
function createDashboard4() {
var json_results = getData('http://localhost:9999/countcarbytype')
data_results = []
var Header = ['car Type', 'count', 'region',{'type': 'string', 'role': 'tooltip', 'p': {'html': true}}];
data_results.push(Header)
for (var i = 0; i < json_results.length; i++) {
var value = json_results[i];
var URL = ""+value["imageURL"][0]
data_results.push([value["_id"]["title"], value["countofcars"], value["_id"]["region"]],createCustomHTMLContent(URL,value["_id"]["title"], value["countofcars"], value["_id"]["region"]))
}
console.log(data_results)
var data = google.visualization.arrayToDataTable(data_results);
// Define a StringFilter control for the 'Name' column
var stringFilter = new google.visualization.ControlWrapper({
'controlType': 'StringFilter',
'containerId': 'control4',
'options': {
'filterColumnLabel': 'region'
}
});
// Define a table visualization
var table = new google.visualization.ChartWrapper({
'chartType': 'BarChart',
'containerId': 'chart4',
'options': { 'height': 400, 'width': 500, 'title': 'Count of cars by Model Type', 'legend': 'none','tooltip': { isHtml: true } },
'view': { 'columns': [0, 1] }
});
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard')).
// Configure the string filter to affect the table contents
bind(stringFilter, table).
// Draw the dashboard
draw(data);
return stringFilter;
}
google.setOnLoadCallback(drawVisualization);
I did an implementation of createCustomHTMLContent
function createCustomHTMLContent(imageURL, title, totalCount, region) {
return '<div style="padding:5px 5px 5px 5px;">' +
'<img src="' + imageURL + '" style="width:75px;height:50px"><br/>' +
'<table class="medals_layout">' + '<tr>' +
'<td><img src="https://upload.wikimedia.org/wikipedia/commons/1/15/Gold_medal.svg" style="width:25px;height:25px"/></td>' +
'<td><b>' + title + '</b></td>' + '</tr>' + '<tr>' +
'<td><img src="https://upload.wikimedia.org/wikipedia/commons/1/15/Gold_medal.svg" style="width:25px;height:25px"/></td>' +
'<td><b>' + totalCount + '</b></td>' + '</tr>' + '<tr>' +
'<td><img src="https://upload.wikimedia.org/wikipedia/commons/5/52/Bronze_medal.svg" style="width:25px;height:25px"/></td>' +
'<td><b>' + region + '</b></td>' + '</tr>' + '</table>' + '</div>';
}
However its giving me an error Uncaught Error: Row 0 has 3 columns, but must have 4. I am sure i already followed the procedure to add in a HTML tool tip.
What did i do wrong?
EDIT 1:
Sample data:
[{"_id":{"title":"Mercedes Benz C Class 220 CDI Elegance AT (2009) in Mumbai","region":"Mumbai"},"countofcars":2,"imageURL":["https://imguct3.aeplcdn.com/img/340x192/lis/201807/1405424_71524_1_1530437796289.jpeg?v=27","https://imguct3.aeplcdn.com/img/340x192/lis/201807/1405424_71524_1_1530437796289.jpeg?v=27"]},{"_id":{"title":"Mercedes Benz C Class 220 CDI Sport (2012) in Coimbatore","region":"Coimbatore"},"countofcars":2,"imageURL":["https://imguct3.aeplcdn.com/img/340x192/lis/201806/1402641_71493_1_1530177529608.jpeg?v=27","https://imguct3.aeplcdn.com/img/340x192/lis/201806/1402641_71493_1_1530177529608.jpeg?v=27"]}

closing bracket of the array is out of place...
change this...
data_results.push([value["_id"]["title"], value["countofcars"], value["_id"]["region"]],createCustomHTMLContent(URL,value["_id"]["title"], value["countofcars"], value["_id"]["region"]))
to this...
data_results.push([value["_id"]["title"], value["countofcars"], value["_id"]["region"],createCustomHTMLContent(URL,value["_id"]["title"], value["countofcars"], value["_id"]["region"])]);
EDIT
also need to add the tooltip column to the chart view...
change...
'view': { 'columns': [0, 1] }
to...
'view': { 'columns': [0, 1, 3] }

Related

Why does my HighStock data drop off when I zoom out?

I have a JsFiddle here:
http://jsfiddle.net/hh3ocm4t/
In the initial view, the tooltip shows daily volume.
The tooltip formatter code is as follows:
formatter: function() {
var result = '<b>' + Highcharts.dateFormat('%A, %b %e, %Y', this.x) + '</b>';
for (var i = 0; i < this.points.length; i++) {
var datum = this.points[i];
console.log(datum);
result += '<br />Original price: $' + datum.point.high.toFixed(2);
result += '<br />Dropped price: $' + datum.point.low.toFixed(2);
result += '<br />Daily volume: ' + datum.point.name;
}
return result;
}
But when I click 'all' the daily volume becomes undefined.
How do I get my daily volume to appear when I click 'All'?
By default data grouping is enabled in Highstock. The solution here is disabling it:
series: [{
name: 'Temperatures',
data: data,
dataGrouping: {
enabled: false
}
}]
Live demo: http://jsfiddle.net/kkulig/yu1ybnje/
Docs reference: https://www.highcharts.com/docs/advanced-chart-features/data-grouping
API reference: https://api.highcharts.com/highstock/plotOptions.series.dataGrouping

On 'click' not firing/finding Datatable child row to open up

Here's all the code.
#model IEnumerable<Arb.Models.Fixture>
#{
ViewBag.Title = "Fixtures";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table id="fixtures" class="table table-bordered table-hover">
<thead>
<tr>
<th></th>
<th>Fixture</th>
<th>Date/Time</th>
<th>Market</th>
<th>Selection</th>
<th>Bookie</th>
<th>Coupon</th>
<th>Back</th>
<th>Lay</th>
<th>Size</th>
<th>Percent</th>
</tr>
</thead>
<tbody></tbody>
</table>
#section scripts
{
<style type="text/css" class="init">
td.details-control {
background: url('http://next.datatables.net/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('http://next.datatables.net/examples/resources/details_close.png') no-repeat center center;
}
</style>
<script>
/* Formatting function for row details - modify as you need */
function format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Full name:</td>' +
'<td>' + d.name + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extension number:</td>' +
'<td>' + d.extn + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extra info:</td>' +
'<td>And any further details here (images etc)...</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function () {
var fixtureTable = $('#fixtures').DataTable({
ajax: {
url: "/api/fixtures",
dataSrc: ""
},
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
data: "eventName",
render: function (data, type, fixture) {
return "<a href='/fixtures/edit/" + fixture.id + "'>" + fixture.eventName + "</a>";
}
},
{
data: 'eventDateTime',
render: function (data, type, row) {
var d = new Date(data);
return d.getDate() + '-' + ('0' + d.getMonth()).slice(-2) + ' ' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2);
}
},
{ data: 'marketName' },
{ data: 'selectionName' },
{ data: 'bookmakerName' },
{ data: 'couponName' },
{
data: 'backOdds',
render: $.fn.dataTable.render.number(',', '.', 2)
},
{
data: 'exchangeType.layOdds',
render: $.fn.dataTable.render.number(',', '.', 2)
},
{
data: 'exchangeType.size',
render: $.fn.dataTable.render.number('', '.', 0, '£')
},
{
data: null,
render: function (data, type, row) {
return Math.round((row.backOdds / row.exchangeType.layOdds) * 100 - 100) + '%';
}
}
],
"order": [[1, 'asc']]
});
setInterval(function () {
fixtureTable.ajax.reload(null, false); // user paging is not reset on reload
var currentTime = new Date().toLocaleTimeString('en-GB', {
hour: "numeric",
minute: "numeric",
second: "numeric"
});
var currentDate = new Date();
var datetime = "Last Updated: " + currentDate.getDate() + "/" + (currentDate.getMonth() + 1)
+ "/" + currentDate.getFullYear() + " " + currentTime;
$("#UpdateTime").text(datetime);
}, 10000);
// Add event listener for opening and closing details
$('#fixtures tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
});
</script>
}
One thing I have noticed is that sometimes but not always it is showing "selector td.details-control is already specified earlier". But when I look for any earlier definitions including global searching or commenting out code - the error still appears.
IDK, if this is a red herring, but, it's not getting the child row somehow.
This is what I am trying to achieve https://datatables.net/examples/api/row_details.html
I see that following could be mistakes:
with ajax update - you tbody will be recreated, so your event will not work (try to use $('#fixtures').on('click', 'tbody td.details-control', ...
var row = table.row(tr); - should be var row = fixtureTable.row(tr);

Highchart tooltip customization

I am using highcharts and i would like to customize tooltip.
My tooltip should show the reqName and reqVersion,but currently the tooltip is showing all the values of the 'tipValue' array.
When i hover over the column it shows me tooltip on each column as (1.1,1.0,1.2,1.2)
where as I would like the tooltip to show version
1.1 for column tpReq
1.0 for column opReq
1.2 for column Rex
1.2 for column tpReq
My xVaue is an array of ['tpReq','opReq','Rex','tpReq']
My yValue is an array of [5,8,5,1]
My tipValue is an array of ['1.1','1.0','1.2','1.2']
Here is my function to draw the highcharts
function drawchar(myXAxis,myYAxis,myTooltip)
{
var xValue = JSON.parse(XAxis);
var yValue = JSON.parse(YAxis);
var tipValue = JSON.parse(myTooltip);
var reqTypeChart = new HighCharts.Chart ({
...
...
xAxis: {
categories: xValue,
title: { 'My Requests'
text: null
},
},
....
series: [{
name: 'Status',
data: yValue
}],
legend: { enabled: false },
tooltip: {
formatter: function () {
return '<b>' + this.xValue + '</b><br/>' +
'IssueCount: ' + Highcharts.numberFormat(this.yValue, 0) + '</b><br/>' +
'AppVersion: ' + tipValue ;
}
...
});
}
Try this.
function drawchar(myXAxis, myYAxis, myTooltip) {
var xValue = JSON.parse(myXAxis);
var yValue = JSON.parse(myYAxis);
var tipValue = JSON.parse(myTooltip);
var data = [];
$.each(xValue, function (index, val) {
var tempObj = {
x: val,
y: yValue[index],
tipValue: tipValue[index]
}
data.push(tempObj);
});
// **UPDATED **
data.sort(function(a, b){
if(a.x < b.x) return -1;
if(a.x > b.x) return 1; return 0;
})
var reqTypeChart = new HighCharts.Chart({
xAxis: {
title: {
text: 'My Requests'
}
},
series: [
{
name: 'Status',
data: data
}
],
legend: {
enabled: false
},
tooltip: {
formatter: function () {
return '<b>' + this.point.x + '</b><br/>' +
'IssueCount: ' + Highcharts.numberFormat(this.point.y, 0) + '</b><br/>' +
'AppVersion: ' + this.point.tipValue;
}
}
});
}
Combine all three values into one array of objects and set that array as data source in series of highchart api. You'll get passed object inside formatter method of tooltip wrapped into this.point object.
I managed to solve this problem by changing the tooltip formater. So first find the index of xValue and find the corresponding tooltip value from tipValue array.
formatter: function () {
var index = xValue.indexOf(this.xValue);
var tip = tipValue[index];
return '<b>' + this.xValue + '</b><br/>' +
'IssueCount: ' + Highcharts.numberFormat(this.yValue, 0) + '</b><br/>' +
'AppVersion: ' + tip ;

Highstock - How can i display the open, high, low, close in the line or area charts tooltip

I'm trying to display the open, high, low, close in the line or area chart's tooltip. Right now, the data for the line and the area charts is being sent in a JSON array which looks like this
{timestamp, close}
Now for OHLC or candlestick charts this JSON changes to
{timestamp,open, high, low, close}
I've tried this method which only works for OHLC and candlestick.
tooltip: {
valueDecimals: 2,
useHTML: true,
formatter: function() {
/*
* tooltip formatter function
*
*/
var d = new Date(this.x);
var s = '';
if (chartGlobalOptions.range.indexOf("m") >= 0) {
s += '<b>' + Highcharts.dateFormat('%b %e, %Y', this.x) + '</b><br />';
} else {
s += '<b>' + Highcharts.dateFormat('%b %e, %Y [%H:%M]', this.x) + '</b><br />';
}
$.each(this.points, function(i, point) {
if (point.series.name.indexOf("Volume") >= 0) {
/*
* if the series is volume, then don't show the decimals
*
*/
s += '<b><span style = "color:' + point.series.color + ';">' + point.series.name + ' </span>' + ' : ' + Highcharts.numberFormat(point.y, 0) + '</b><br />';
} else if (point.series.type == 'candlestick' || point.series.type == 'ohlc') {
s += '<b><span style = "color:' + point.series.color + ';">' + point.series.name + ' : ' + Highcharts.numberFormat(point.point.close, 3) + '</b><br />';
s += '<span style ="color:' + point.series.color + ';">Open</span>: ' + point.point.open +
'<br/><span style ="color:' + point.series.color + ';">High</span>: ' + point.point.high +
'<br/><span style ="color:' + point.series.color + ';">Low</span>: ' + point.point.low +
'<br/><span style ="color:' + point.series.color + ';">Close</span>: ' + point.point.close + '<br/>';
}
else {
s += '<b><span style = "color:' + point.series.color + ';">' + point.series.name + ' </span>' + ' : ' + Highcharts.numberFormat(point.y, 3) + '</b><br />';
}
});
return s;
},
shared: true
},
What modifications are needed to be done in order to display ohlc values in the tooltip of the line chart ? I've been trying to find a solution for quite some time without any success.
Thanks,
Maxx
EDIT
Here is the series option that i'm setting
series: [{
type: chartGlobalOptions.chartTypes.name,
name: $('#symbol-name').text(),
data: data.prices,
id: 'Price Axes',
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: data.volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits,
approximation: 'close'
}
}]
And here is the data that i'm getting from the server.
{"prices":[{"x":1387377184000,"y":1.05,"high":1.06,"low":1.05,"open":1.06,"close":1.05},{"x":1387377509000,"y":1.04,"high":1.06,"low":1.04,"open":1.05,"close":1.04},{"x":1387378295000,"y":1.04,"high":1.04,"low":1.04,"open":1.04,"close":1.04},{"x":1387379370000,"y":1.04,"high":1.04,"low":1.04,"open":1.04,"close":1.04},{"x":1387380217000,"y":1.04,"high":1.04,"low":1.04,"open":1.04,"close":1.04},{"x":1387381181000,"y":1.04,"high":1.04,"low":1.04,"open":1.04,"close":1.04},{"x":1387381324000,"y":1.03,"high":1.03,"low":1.03,"open":1.03,"close":1.03},{"x":1387382146000,"y":1.03,"high":1.03,"low":1.03,"open":1.03,"close":1.03},{"x":1387383229000,"y":1.03,"high":1.03,"low":1.03,"open":1.03,"close":1.03}],
"volume":[[1387377184000,0],[1387377509000,35600],[1387378295000,0],[1387379370000,25300],[1387380217000,0],[1387381181000,0],[1387381324000,4500],[1387382146000,1700],[1387383229000,4000],[1387383788000,2600],[1387384004000,1000],[1387384218000,2900],[1387385045000,0],[1387385840000,10000],[1387386013000,100],[1387386627000,6200],[1387386981000,0],[1387387439000,2500],[1387387728000,2500],[1387387950000,0],[1387388920000,0],[1387389210000,500],[1387389890000,15500],[1387390124000,400],[1387390988000,11900],[1387391264000,4900],[1387391832000,0],[1387392803000,0],[1387393369000,6200],[1387393774000,200],[1387394744000,0],[1387395716000,0],[1387395904000,2800],[1387396334000,15000],[1387396689000,0],[1387397664000,0],[1387398328000,12300],[1387398706000,7000],[1387400379000,13000],[1387463638000,0],[1387464573000,46200],[1387465371000,4000],[1387465588000,0],[1387465948000,33000],[1387466607000,0],[1387466883000,11400],[1387468648000,13500],[1387470272000,12800],[1387470693000,0],[1387471718000,0],[1387472674000,0],[1387472742000,0],[1387473768000,100],[1387474795000,0],[1387475319000,29500],[1387475698000,99100],[1387475822000,14400],[1387476297000,3400]]}
Here is how i'm setting the data in the server
$this->price[] = array (
$eachRow[ "timestamp" ] * 1000 ,
$eachRow[ "close" ] * 1 ,
$eachRow[ "high" ] * 1 ,
$eachRow[ "low" ] * 1 ,
$eachRow[ "open" ] * 1 ,
$eachRow[ "close" ] * 1
) ;
return json_encode ( array (
"prices" => $this->resultArray[ "prices" ] ,
"volume" => $this->resultArray[ "volume" ] ));
And i do a var data = JSON.parse(data); at the very beginning just after i get the values from the server. Please let me know what is wrong with my program. I mean if i hardcode the same values directly in the data object i get the correct result.
You need to add that info to your points, for example:
series: [{
//type : 'ohlc',
name: 'AAPL Stock Price',
data: [{
x: 1367884800000,
y: 100,
high: 150,
low: 90,
close: 120,
open: 100
}, {
x: 1367984800000,
y: 120,
high: 170,
low: 120,
close: 160,
open: 120
}, {
x: 1368084800000,
y: 160,
high: 160,
low: 90,
close: 120,
open: 160
}]
}]
jsFiddle demo: http://jsfiddle.net/UTsT4/
Note: when you will have a lot of points, and dataGrouping will be used, point info (opten/high/low/close) will be lost. So that will only work with disabled dataGrouping.

How to get multiple series data in tooltip highcharts?

I want to display multiple series Data in tooltip on every column
tooltip: {
formatter: function() {
return '<span style="color:#D31B22;font-weight:bold;">' +this.series.name +': '+ this.y +'<br/>'+
'<b style="color:#D31B22;font-weight:bold;">'+this.x +'</b><span>';
}
},
and Data
series: [{
showInLegend: false,
name: 'Total Click',
data: [3000,200,50,4000],
color: '#9D9D9D'
}, {
showInLegend: false,
name: 'Total View',
data: [100,2000,3000,4000],
color: '#D8D8D8'
}]
I am using like this but in tool tip only one series data is showing at a time.
I want to display Data like this (Total View:100 and Total Click:3000 )
please try using this code
updated DEMO
tooltip: {
formatter: function() {
var s = [];
$.each(this.points, function(i, point) {
s.push('<span style="color:#D31B22;font-weight:bold;">'+ point.series.name +' : '+
point.y +'<span>');
});
return s.join(' and ');
},
shared: true
},
You need to use shared parameter http://api.highcharts.com/highcharts#tooltip.shared and then in formater iterate on each point.
If anybody looking for scatterplot, here is solution to show shared tooltip.
formatter: function(args) {
var this_point_index = this.series.data.indexOf( this.point );
var this_series_index = this.series.index;
var that_series_index = this.series.index == 0 ? 1 : 0; // assuming 2 series
var that_series = args.chart.series[that_series_index];
var that_point = that_series.data[this_point_index];
return 'Client: ' + this.point.name +
'<br/>Client Health: ' + this.x +
'<br/>' + this.series.name + ' Bandwidth: ' + this.y + 'Kbps' +
'<br/>' + that_series.name + ' Bandwidth: ' + that_point.y + 'Kbps';
}
Jsfiddle link to Solution

Categories