Google chart api Line chart: Units don't match points - google-visualization

I have a Google chart api Line chart where the horizontal axis units don't match the corresponding points on the chart. See the image.
I have used those options that makes sure that the h axis don't use decimal numbers:
hAxis: { title: 'some title', format: '#' }
I have used no other relevant options, and haven't found any options in the documentation that seems to could solve the issue..
Update:
Code to generate the chart:
var options = { title: '<%# Strings.GameStatisticsView_GameProgressChart %>', hAxis: { title: '<%# Strings.ScoreBoard_RoundNr %>', format: '#' }, vAxis: { title: '<%# Strings.Common_Points %>' }, backgroundColor: { fill: 'transparent' }, elementId: 'GameProgressChart', column1: 'Round Nr' };
drawLineChart(response.d.Data, options);
...
drawLineChart: function (data, options) {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', options.column1);
for (var j = 0; j < data.key.length; j++) {
dataTable.addColumn('number', data.key[j]);
}
dataTable.addRows(data.value.length);
for (var i = 0; i < data.value.length; i++) {
dataTable.setValue(i, 0, data.value[i].key);
for (var k = 0; k < data.key.length; k++) {
dataTable.setValue(i, k+1, data.value[i].value[k]);
}
}
var chart = new google.visualization.LineChart(document.getElementById(options.elementId));
chart.draw(dataTable, options);
},
Solution from comments:
The steps in your x axis can't be hardcoded but you can hardcode how many gridlines to have, see link.

I doubt you are still in need of an answer for this, but should anyone be in the same situation..
format: '#' forces the value format to 1 digit, so your 3 in the example is most likely around 3.3 but you only see the integer part because of the formatting applied.

Related

In bar chartjs report zero values are skipped so bars are invalid

I have stacked bar (Chart.js Version: 2.7.2 ) with 2 values of vote type(correct / not correct).
It works ok except cases when there are some data on correct votes and no data on non correct votes. And vice versa
To salve this problem I added some check on server and for nonexisting values I add rows in 0 value in count field, so set of data looks like
Please pay attention that for voteItemUsersResultsNoneCorrect array row with id":4,"vote_name":"Which fictional city is the home of Batman ?"},
field count has 0 value. Looking at resulting bar chart I see that 0 value was skipped and value FROM NEXT row was used to build the chart, so all next bars
are invalid.
{"error_code":0,"message":"",
"voteItemUsersResultsCorrect":{"0":
{"count":9,"id":12,"vote_name":"According to the old proverb, to which European capital city do all roads lead ?"},"1":
{"count":6,"id":13,"vote_name":"On which mountain did Moses receive the Ten Commandments ?"},"2":
{"count":10,"id":9,"vote_name":"Traditionally, how many Wonders of the World are there ?"},"3":
{"count":6,"id":10,"vote_name":"What is the name of the fairy in Peter Pan ?"},"4":
{"count":12,"id":8,"vote_name":"Which crime-fighting cartoon dog has the initals \u201cS.D.\u201d on his collar ?"},"5":
{"count":16,"id":4,"vote_name":"Which fictional city is the home of Batman ?"},"6":
{"count":5,"id":14,"vote_name":"Which is the tallest mammal?"},"7":
{"count":8,"id":11,"vote_name":"Which planet is the closest to Earth ?"},"10":
{"count":0,"id":2,"vote_name":"Who Framed Roger Rabbit ?"},"8":
{"count":8,"id":15,"vote_name":"Who directed the movie Jaws?"},"9":
{"count":8,"id":5,"vote_name":"Who was known as the Maid of Orleans ?"}},
"voteItemUsersResultsNoneCorrect":{"0":
{"count":22,"id":12,"vote_name":"According to the old proverb, to which European capital city do all roads lead ?"},"1":
{"count":25,"id":13,"vote_name":"On which mountain did Moses receive the Ten Commandments ?"},"2":
{"count":21,"id":9,"vote_name":"Traditionally, how many Wonders of the World are there ?"},"3":
{"count":25,"id":10,"vote_name":"What is the name of the fairy in Peter Pan ?"},"4":
{"count":19,"id":8,"vote_name":"Which crime-fighting cartoon dog has the initals \u201cS.D.\u201d on his collar ?"},"10":
{"count":0,"id":4,"vote_name":"Which fictional city is the home of Batman ?"},"5":
{"count":26,"id":14,"vote_name":"Which is the tallest mammal?"},"6":
{"count":23,"id":11,"vote_name":"Which planet is the closest to Earth ?"},"8":
{"count":27,"id":2,"vote_name":"Who Framed Roger Rabbit ?"},"7":
{"count":23,"id":15,"vote_name":"Who directed the movie Jaws?"},"9":
{"count":23,"id":5,"vote_name":"Who was known as the Maid of Orleans ?"}
}
}
I show fully retrieving of data and setting bar options,
At first I have to set values for 3 arrays monthsXCoordItems, voteNamelabels, voteValuesCorrect and created bar chart on them .
$.ajax({
url: href,
type: "POST",
dataType: "json",
data: dataArray,
}).done(function (response) {
if (response.error_code == 0) {
this.this_voteItemUsersResultsCorrect = response.voteItemUsersResultsCorrect
this.this_voteItemUsersResultsNoneCorrect = response.voteItemUsersResultsNoneCorrect
for (var key_index in response.voteItemUsersResultsCorrect) {
if (response.voteItemUsersResultsCorrect.hasOwnProperty(key_index)) {
var dataRow= response.voteItemUsersResultsCorrect[key_index];
monthsXCoordItems.push(dataRow.vote_name);
voteNamelabels.push(dataRow.vote_name);
voteValuesCorrect.push(dataRow.count);
}
}
for (var key_index in response.voteItemUsersResultsNoneCorrect) {
if (response.voteItemUsersResultsNoneCorrect.hasOwnProperty(key_index)) {
var dataRow= response.voteItemUsersResultsNoneCorrect[key_index];
voteValuesNoneCorrect.push(dataRow.count);
}
}
var barCanvas = document.getElementById("canvasVoteNames");
$("#div_canvasVoteNames").css("display","block")
var barCanvasContext = barCanvas.getContext('2d');
var numberWithCommas = function (x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
var self = this;
if (window.chartObject != undefined) { // clear existing instance
window.chartObject.destroy();
}
window.chartObject = new Chart(barCanvasContext, {
type: 'bar', // http://www.chartjs.org/docs/latest/charts/bar.html
data: {
labels: monthsXCoordItems,
datasets: [{
label: 'Correct Votes',
data: voteValuesCorrect,
}, {
label: 'Incorrect Votes',
data: voteValuesNoneCorrect,
}
]
},
options: { // options of Report By Vote Names
animation: {
duration: 10,
},
scales: { // options for x and y scales
xAxes: [{
stacked: true,
gridLines: {
display: true,
// offsetGridLines: true,
},
// barThickness: 70,
}],
yAxes: [{
stacked: true,
ticks: {
callback: function (value) {
if (Math.floor(value) === value) {
return value;
}
},
},
}],
}, // scales: { // options for x and y scales
legend: {display: true}
}, // options: { // options of Report By Vote Names
plugins: [{
beforeInit: function (chart) {
chart.data.labels.forEach(function (value, index, array) {
var a = [];
a.push(value.slice(0, this_column_width));
var i = 1;
while (value.length > (i * this_column_width)) {
a.push(value.slice(i * this_column_width, (i + 1) * this_column_width));
i++;
}
array[index] = a;
})
}
}]
});
barCanvas.onclick = function (e) {
var slice = window.chartObject.getElementAtEvent(e);
if (!slice.length) return; // return if not clicked on slice
var label = slice[0]._model.label;
if (label.length > 1) { // that is an array - we need to convert it to string
var label_text = ''
for (var key in label) {
if (label.hasOwnProperty(key)) {
label_text = label_text + label[key]
}
}
label = label_text
}
self.this_voteItemUsersResultsCorrect.forEach(function (data) {
if (label == data.vote_name) {
backendReports.showVoteNamesReportDetailsByVoteId(data.id, data.vote_name)
return;
}
});
} // barCanvas.onclick = function(e) {
}
if (response.error_code > 0) {
alertMsg(response.message, 'Reports error!', 'OK', 'fa fa-file-chart-pie')
}
});
Are some ideas how to fix this error ?
MODIFIED BLOCK # 2 :
I uploaded that chart online: please open
http://votes.nilov-sergey-demo-apps.tk/admin/report_votes_by_vote_names
there is creditials provided and by default page with all data will be opened, but value for
"Which fictional city is the home of Batman " ivalid as it has 0 value for noncorrect stack : https://imgur.com/a/hGfYLog
You can see valid results with 0 value if select the only vote from voyes filter selection : https://imgur.com/a/seshsFp
?
Thanks!
there is count: 13, id: 4 and count: 22, id: 2 ...
which means, your script is confusing Batman with Roger Rabbit.
there might be further values wrong; it only gets the most obvious with 0 values.
better merge the arrays on the server-side, to have them readily consumable for the chart; this would permit easier index assignment - and it would also speed up the run-time of the JS. less complexity is commonly easier the handle than useless complexity (as it is with client-side merging of the arrays).

ChartJS tooltip label for pie cart being cut

I am trying to add tooltip in my chart, however some of them the label are being cut.
Hier is my code
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
title: {
display: true,
text: title,
fontSize: 36
},
tooltips: {
bodyFontSize: 22,
callbacks: {
label: function (tooltipItem, data) {
var number = data.datasets[0].data[tooltipItem.index];
var label = data.labels[tooltipItem.index];
var sum = data.datasets[0].data.reduce(function (a, b) { return a + b; }, 0);
var percentage = getPercent(number, sum);
return label + " " + Math.round(percentage) + " %";
}
}
}
}
Can anyone help me to make the label rendered properly? Many thanks
Regards
I would say your tooltip is going off the edge of your canvas, have a look at this jsfiddle for an example. Or see sample code at the end.
Or, without seeing the full code, I might assume that your 2014 chart is overlapping the 2015 chart. Maybe fixed with a z-index in CSS, but then the opposite effect with the other chart may happen?
Same code from jsfiddle:
<div style='width: 300px;'>
<canvas id='chart'></canvas>
</div>
var ctx = document.getElementById('chart');
var chart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["I am a really really really really really really really really really really really reallyreally really really really really really long label so long I might go off the chart"],
datasets: [{
data: [5],
}]
},
options: {
legend: {
display: false
},
maintainAspectRatio: false,
title: {
display: false,
fontSize: 16
}
}
});

Google halfdonut pie chart: is it possible to set total percentage?

I made half a donut chart with Google charts and I have a problem that the sum of visible percentage is equal to 50%. Is there any possible solution ?
Image of my chart
you can override the text displayed on the slice by using the following config option...
pieSliceText: 'value'
then in the data, set the formatted value of the cells to the correct percentage...
var data = [
['Task', 'Hours'],
// use formatted values
['A', {v: 19.2, f: '38.4%'}],
['B', {v: 30.8, f: '61.6%'}],
[null, 50]
];
the following working snippet uses the same approach,
but calculates the correct percentages,
rather than hard-coding...
google.charts.load('current', {
callback: function () {
var data = [
['Task', 'Hours'],
['A', 19.2],
['B', 30.8],
[null, 50.0]
];
var total = 0;
for (var i = 1; i < data.length; i++) {
if (data[i][0] !== null) {
total += data[i][1];
}
}
var numberFormat = new google.visualization.NumberFormat({
pattern: '#,##0.0',
suffix: '%'
});
var dataTable = google.visualization.arrayToDataTable(data);
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
if (dataTable.getValue(i, 0) !== null) {
dataTable.setFormattedValue(i, 1, numberFormat.formatValue(((dataTable.getValue(i, 1) / total) * 100)));
}
}
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
var options = {
height: 400,
chartArea: {
top: 24
},
colors: ['#8BC34A', '#64B5F6'],
legend: 'none',
pieHole: 0.4,
pieStartAngle: 270,
pieSliceText: 'value',
slices: {
2: {
color: 'transparent'
}
},
theme: 'maximized',
width: 400
};
chart.draw(dataTable, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Can the colors of bars in a bar chart be varied based on their value?

Using chart.js 2, can the colors of the bars in a bar-cart be varied based on their value?
For example, if the scale is 0 - 100, columns with 50% and above could be green, while 0-49% could be red.
As far as I know there is no configuration or callback for each individual point being drawn. The best way I can think of to do this would be to create a function that would modify your chart config/data object. This isn't the most elegant way to deal with the problem, but it would work.
The Fix
Pass your chart config/data object to a function that will add the background color.
Main Point of the example is function AddBackgroundColors(chartConfig)
Example:
function AddBackgroundColors(chartConfig) {
var min = 1; // Min value
var max = 100; // Max value
var datasets;
var dataset;
var value;
var range = (max - min);
var percentage;
var backgroundColor;
// Make sure the data exists
if (chartConfig &&
chartConfig.data &&
chartConfig.data.datasets) {
// Loop through all the datasets
datasets = chartConfig.data.datasets;
for (var i = 0; i < datasets.length; i++) {
// Get the values percentage for the value range
dataset = datasets[i];
value = dataset.data[0];
percentage = value / range * 100;
// Change the background color for this dataset based on its percentage
if (percentage > 100) {
// > 100%
backgroundColor = '#0000ff';
} else if (percentage >= 50) {
// 50% - 100%
backgroundColor = '#00ff00';
} else {
// < 50%
backgroundColor = '#ff0000';
}
dataset.backgroundColor = backgroundColor;
}
}
// Return the chart config object with the new background colors
return chartConfig;
}
var chartConfig = {
type: 'bar',
data: {
labels: ["percentage"],
datasets: [{
label: '100%',
data: [100]
}, {
label: '50%',
data: [50]
}, {
label: '49%',
data: [49]
}, {
label: '5%',
data: [5]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
chartConfig = AddBackgroundColors(chartConfig);
var myChart = new Chart(ctx, chartConfig);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.2/Chart.bundle.min.js"></script>
<canvas id="canvas" width="400" height="200"></canvas>
In Chart.js 2 it is possible to set multiple colors with an array.
So you can define the backgroundColor as an array of color strings, matching the datasets data.
var myChart = new Chart(ctx, {
datasets: [{
label: 'Votes',
data: [1, 2, 3],
// Make the first bar red, the second one green and the last one blue
backgroundColor: ['#f00', '#0f0', '#00f']
}]
});
You can easily generate an array based on the values in data:
function getColorArray(data, threshold, colorLow, colorHigh) {
var colors = [];
for(var i = 0; i < data.length; i++) {
if(data[i] > threshold) {
colors.push(colorHigh);
} else {
colors.push(colorLow);
}
}
return colors;
}
See this fiddle for a working demo

Google Chart - Centering Annotations

I simply want to "center" the annotation in the bars in this chart. You can see how the data appear at the end of the bar. Can that percentage be centered in the bar?
Try as I might, I cannot figure it out. I found a block of code that was described as a hack, but it would have to be customized for each chart. I use this code to generates lots and lots of charts. Any help would be wildy appreciated!
function drawVisualizationstack(qid,cdata, w,h,l,cw,pos,stacked,questioncase) {
pos='top';
var data = new google.visualization.DataTable();
var e;
for (var k=0;k<cdata.length;k++) {
e=cdata[k];
if (e[0]=='column') {
if (e[2]=="tooltip") {
data.addColumn({type:'string',role:'tooltip','p':{'html':true}});
//data.addColumn({type: 'string', role: 'annotation','p':{'html':true}});
}
else if (e[2]=="annotation") {
data.addColumn({type: 'string', role: 'annotation', p: {html: true}});
}
else {
if (e[2]=="All") e['2']="All";
data.addColumn(e[1],e[2]);
}
}
else {
if (e==="" || e===undefined) {mclog('UNDEFINED DATA ROW FOR ' + qid);}
else {
data.addRow(e);
}
}
}
h=h*.75;
var chartHeight=h-65;
var options = {
width:500,
height:h,
isStacked:true,
chartArea:{height:chartHeight,left:l,width:cw},
backgroundColor:'transparent',
bar:{groupWidth:'80%'},
tooltip: {isHtml:true},
legend:{position:'none'},
hAxis: {title: 'Percentage',minValue:0,maxValue:100},
hAxis: {textPosition: 'none',ticks: [0]},
colors: ['#5d5d5d', '#002e32', '#0e1a40', '#364940', '#a9b861', '#404000', '#504000', '#604000', '#003070', '#687000'] //set default colors for charts
}}},
true,italic: true,color: '#871b47',auraColor: '#d799ae',opacity: 0.8}}
}
var chart = new google.visualization.BarChart(document.getElementById('questchart_'+qid));
jQuery("base").attr('href',document.location);
chart.draw(data,options);
}