Google charts getting custom tooltips to work with an animation - javascript

Well this is my code, it's broken. I want to have absolute figures appear on mouse over, instead of percentages. Google's guides do not have an example of this with an animation, their examples use data table methods rather than arrays. I think I need to somehow tell Google that I have a third column which is a tooltip, at present it draws it as a bar.
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(init);
function init() {
var rowData1 = [
['key', 'Percentage', 'tooltip'],
['PLUS', 20.9, 3855],
['EDU', 18.4, 3400],
['GEO', 15.6, 2872],
['NO FLAG', 45.2, 8342]
];
var rowData2 = [
['key', 'Percentage', 'tooltip'],
['PLUS', 54.2, 974],
['EDU', 6.7, 120],
['GEO', 39.2, 704],
['NO FLAG', 0.0, 0]
];
// Create and populate the data tables.
var data = [];
data[0] = google.visualization.arrayToDataTable(rowData1);
data[1] = google.visualization.arrayToDataTable(rowData2);
var options = {
// removes the key
legend: {
position: 'none'
},
// puts popup boxes on bar
width: 600,
height: 300,
vAxis: {
title: "vertical axis"
},
hAxis: {
title: "horizontal axis"
},
seriesType: "bars",
series: {
5: {
type: "line"
}
},
animation: {
duration: 1000,
easing: 'out'
},
};
var current = 0;
// Create and draw the visualization.
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
var button = document.getElementById('b1');
function drawChart() {
// Disabling the button while the chart is drawing.
button.disabled = true;
google.visualization.events.addListener(chart, 'ready',
function() {
button.disabled = false;
button.value = 'Switch to ' + (current ? 'Tea' : 'Coffee');
});
options['title'] = 'Monthly ' + (current ? 'Coffee' : 'Tea') + ' Production by Country';
// custom popup box request
chart.draw(data[current], options);
}
drawChart();
button.onclick = function() {
current = 1 - current;
drawChart();
}
}
I've tried converting the array data to DataTables and using
if (current == 0) { chart.draw(dataTable1, options); }
else{ chart.draw(dataTable2, options); }
To select which chart to draw, but this isn't working. And it's less intelligible and inelegant, the dataTables need lots of properties set, so repetition.

need to define tooltip column with object notation...
var rowData1 = [
['key', 'Percentage', {role: 'tooltip'}],
['PLUS', 20.9, 3855],
['EDU', 18.4, 3400],
['GEO', 15.6, 2872],
['NO FLAG', 45.2, 8342]
];
var rowData2 = [
['key', 'Percentage', {role: 'tooltip'}],
['PLUS', 54.2, 974],
['EDU', 6.7, 120],
['GEO', 39.2, 704],
['NO FLAG', 0.0, 0]
];

Change google visualization Combo Chart series option as below:
series: {
0: {
type: "line"
}
}
Every data table column is considered as one series in google visualization Combo Chart.
Here
"Percentage" is line series no is 0
"tooltip" is bar series no is 1
Nothing wrong with google visualization Combo Chart.
After above change you will get below output:

Related

Google Charts not Working When Data Table is Global

I'm working on a small HTML application for my website that does some simulations and plots it to a graph (using Google Charts). All of the data will originate in the JavaScript code on the page (i.e. I'm not trying to pull in data from a database or anything like that). For this reason, I would like to have access to the data table from other functions so the data can be updated when a new simulation is run.
What I'm running into is that if I build a data table (and data view) inside of the drawChart() function, everything works fine. See this jsfiddle or the following code:
//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -.5, 5.7],
[0.1, .4, 8.7],
[0.2, .5, 12]
]);
var forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}
But if I move the code for the creation of the data table and data view outside of the function scope, it doesn't work. See this jsfiddle or the following code:
var sim_data;
var forceDataView;
//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });
sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -0.5, 5.7],
[0.1, 0.4, 8.7],
[0.2, 0.5, 12]
]);
forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}
Both of these examples use the following HTML:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="force_chart_div"></div>
I thought it might have something to do with the execution order of the callback function. But putting it in different spots in the code doesn't seem to change anything. In my full project, I went so far as to add a button that called the drawChart() function just to check, but that didn't help either.
Depending on where I put the callback function call, I'll get a red "Data Table is not Defined" alert showing up where the chart is supposed to be on the webpage. That pretty much tells me what I already suspected, but I don't know how to fix it. Any help would be appreciated. I'm a huge JS noob, by the way, so go easy on me.
your instinct was correct, you must wait on the callback to finish,
before using the google.visualization or google.charts namespaces.
it has to do more with timing, than placement of the code.
instead of using the callback statement, we can use the promise that the load statement returns.
as in the following snippet...
var sim_data;
var forceDataView;
//Google charts stuff
google.charts.load('current', {
packages: ['line', 'corechart']
}).then(function () {
sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");
sim_data.addRows([
[0.0, -0.5, 5.7],
[0.1, 0.4, 8.7],
[0.2, 0.5, 12]
]);
forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);
});
function drawChart() {
var forceChartDiv = document.getElementById('force_chart_div');
var forceChartOptions = {
chart: {title: 'Simulation Results: Force'},
width: 900,
height: 500,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: { axis: 'Total' },
1: { axis: 'Individual' }
},
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
Total: { label: 'Total Force (Newtons)'},
Individual: { label: 'Per-Motor Force (Newtons)'}
}
}
};
var forceChart = new google.charts.Line(forceChartDiv);
forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}

How to display labels inside pie Chart with Chart.Js V2.3

I am trying to show the values of the pie slices inside the pie chart with Chart.JS v2.3
I've tried various ones to see if I could get them to work
Chart.js v2: How to make tooltips always appear on pie chart?
When I try this, the tooltips are still hover over.
Tried this as well and this did not work.
options: {
events: false,
animation: {
duration: 0
},
onAnimationComplete: function () {
var self = this;
var elementsArray = [];
Chart.helpers.each(self.data.datasets, function (dataset, datasetIndex) {
Chart.helpers.each(dataset.metaData, function (element, index) {
var tooltip = new Chart.Tooltip({
_chart: self.chart,
_data: self.data,
_options: self.options,
_active: [element]
}, self);
tooltip.update();
tooltip.transition(Chart.helpers.easingEffects.linear).draw();
}, self);
}, self);
}
},
If I try one of the resolutions that use a plugin service it fails with the following error:
Uncaught TypeError: Cannot read property 'register' of undefined
Here is the full code I'm trying to work with:
var data = {
labels: ["People", "Process", "Technology"],
datasets: [
{
data: [10,20,30],
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}
]
};
// render chart
Chart.pluginService.register({
beforeRender: function(chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function(dataset, i) {
chart.getDatasetMeta(i)
.data.forEach(function(sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options,
_active: [sector]
},
chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function(chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips,
function(tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
var ctx = document.getElementById("pieChart").getContext("2d");
var myPieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: {
showAllTooltips: true
}
});
I'm also trying to avoid having to use chartNEW.js
Also if it matters this is being done in Asp.Net with MVC.

How to display "%" sign on mouse hover in Pie-Chart

I am drawing graph on UI using ChartJS 2.0. And I am able to render a Pie Chart. But I want the mouse-hover to show the data along with a "%" sign. How can I append % So if on mouse hover I am getting Rented: 93 I would like to see Rented: 93 %. Kindly guide me.
Below is what I have now:
var sixthSubViewModel = Backbone.View.extend({
template: _.template($('#myChart6-template').html()),
render: function() {
$(this.el).html(this.template());
var ctx = this.$el.find('#pieChart')[0];
var data = {
datasets: [{
data: this.model.attributes.currMonthOccAvailVac,
backgroundColor: [
"#455C73",
"#BDC3C7",
"#26B99A",
],
label: 'My dataset' // for legend
}],
labels: [
"Rented",
"Vacant",
"Unavailable",
]
};
var pieChart = new Chart(ctx, {
type: 'pie',
data: data
});
},
initialize: function(){
this.render();
}
});
Understanding:
I understand that currently hover takes the label and adds a colon and then adds data to it. So if label = Rented, Data = 93 I will see something like Rented: 93 on mouse-hover. How can I change text of mouse-hover to display Rented: 93%. Below is the image of what I have till now on mouse-hover.
I understand that I need to add one "options" in the pie chart. But I am not sure how to do that. Please help me.
You can edit what is displayed in your tooltip with the callbacks.label method in your chart options, and then simply add a "%" to the default string using :
tooltipItems -- See documentation for more information (scroll up a bit to "Tooltip Item Interface")
data -- Where the datasets and labels are stored.
var ctx = document.getElementById("canvas");
var data = {
datasets: [{
data: [93, 4, 3],
backgroundColor: [
"#455C73",
"#BDC3C7",
"#26B99A",
],
label: 'My dataset' // for legend
}],
labels: [
"Rented",
"Vacant",
"Unavailable",
]
};
var pieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
callbacks: {
label: function(tooltipItems, data) {
return data.labels[tooltipItems.index] +
" : " +
data.datasets[tooltipItems.datasetIndex].data[tooltipItems.index] +
' %';
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.min.js"></script>
<canvas id="canvas" height="150"></canvas>

Chart JS: Donut/Doughnut Chart: Tooltip to be shown always for all the data. All tooltip is not shown when multiple data are with 0 data

I have created a donut chart. I want to display the tooltip always in the donut chart along with the legends.
I have followed this stack overflow question.
Question which explain the tooltip to be shown always
I have followed the answer and created a doughnut chart and tried to show the tooltip always.
it works fine, however it is not showing all the label, esp. when you have multiple data with 0 value.It just overwrite the label.
my label and values are
"Red" -0,
"Green" -0 &
"Yellow"-100
here is shows tooltip for "Yellow-100" and "Green-0", i think it is overwriting on top of "Red-0". How to show tooltip for "Red-0" and "Green-0" both together.
html:
<canvas id="canvas"></canvas>
Javascript:
var ctx = document.getElementById("canvas").getContext("2d");
var data = {
labels: [
"Red",
"Green",
"Yellow"
],
datasets: [
{
data: [0, 0, 100],
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
};
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options,
_active: [sector]
}, chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
})
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
showAllTooltips: true
}
});
here is the link for jsfiddle.
doughnut chart 0 data tooltip is not shown for all
Chart Version : 2.1.0
please help.
you could use the tooltip callbacks in order to check which data is inside and place it on a different position.
For example you could return the red label in the title and the green one in the footer:
callbacks: {
title: function(tooltipItems, data) {
return (HERE YOUR CONDITION FOR FILTERING GREEN OR RED);
},
label: function(tooltipItem, data) {
//remove body, show data only in title
},
footer: function(tooltipItems, data) {
return (HERE YOUR CONDITION FOR FILTERING GREEN OR RED);
}
}

Set Color for Pie Chart using HighChart + JSON data

I am generating a pie chart from data stored in JSON format. I am trying to change color according to the JSON value.
Ex : if value # json[0]['data'][0][0] = "FAILED" //setColor(RED).
I was able to set the color for column stack charts using options.series.color, however when I tried to use this option with pie chart its converting data into series and unable to render the chart on a container.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
function getData(id) {
$.getJSON("pie.php", {
id: id
}, function(json) {
option.series = json;
chart = new Highcharts.chart(options);
});
}
</script>
can we set the color in getData function only before calling 'chart' or do i need to use Highcharts.setOptions() and define the color codes.
The better option is to create series based on your json data. This is how you can do to specify color based on data.
var serie = {
data: []
};
var series = [serie];
jQuery.each(jsonData, function(index, pointData) {
var point = {
name: pointName,
y: pointData.Value,
color: pointData.Value == 'FAILED' ? 'ff0000' : '00ff00',
serverData: pointData
};
serie.data.push(point);
});
chart.series = series;
OR
Have a look at this easier version
JSFiddle
$( document ).ready(function() {
var data = [{
"name": "Tokyo",
"data": 3.0
}, {
"name": "NewYork",
"data": 2.0
}, {
"name": "Berlin",
"data": 3.5
}, {
"name": "London",
"data": 1.5
}];
// Highcharts requires the y option to be set
$.each(data, function (i, point) {
point.y = point.data;
point.color = parseFloat(point.data) > 3 ? '#ff0000' : '#00ff00';
});
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie'
},
series: [{
data: data
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 300px"></div>
we can set highchart custom color by setOption function which is as
Highcharts.setOptions({
colors: ['#F64A16', '#0ECDFD',]
});
It sets color to my pie chart.
Another solution for dynamic 3D color
Actually this customization for theme selection Here it is
3 colors sets to color variable
var colors = Highcharts.getOptions().colors;
$.each(colors, function(i, color) {
colors[i] = {
linearGradient: { x1: 0, y1: 0, x2: 1, y2: 0 },
stops: [
[0, '#0ECDFD'],
[0.3, '#F64A16'],
[1, color]
]
};
});
& assign directly in series
{
type : 'column',
name : 'bug',
data : [],
color : colors,
pointWidth : 28,
}

Categories