change the colour of google pie chart slice based on mysql value - google-visualization

I currently have 2 charts on a page that are populated using MYSQL and 1 of them a bar chart the other a pie chart
I have successfully managed to change the colours of the bars based on mysql but dont seem to be able to use the same code to change the pie chart colours the outcome i get would be that the whole chart turn the largest slice's colour e.g. for the data in the table below the whole chart would turn RED as its the largest slice
the data string comes out as below:
|---------------------|------------------|
| location | beacon |
|---------------------|------------------|
| RED | 34 |
|---------------------|------------------|
| Blue | 34 |
|---------------------|------------------|
| Green | 34 |
|---------------------|------------------|
| RED | 34 |
|---------------------|------------------|
| Yellow | 34 |
|---------------------|------------------|
so the charts desired outcome would be 4 slices red,blue,green,yellow
the issue im having is because the chart is populated by mysql i cant define the colours manually as the way that the sections come out can differ every time the chart loads.
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart()
{
var data = google.visualization.arrayToDataTable([
['location', 'count'],
<?php
$connect = mysqli_connect("localhost", "user", "password", "test");
if(isset($_POST['but_search'])){
$fromDate = $_POST['fromDate'];
$endDate = $_POST['endDate'];
if(!empty($fromDate) && !empty($endDate)){
$emp_query .= " and date_of_join
between '".$fromDate."' and '".$endDate."' ";
}
}
$query = "SELECT location,count(location) as customer_count FROM test.filter where date between '".$fromDate."' and '".$endDate."' group by location ";
$result = mysqli_query($connect, $query);
while($row = mysqli_fetch_array($result))
{
echo "['".$row["location"]."', ".$row["count"]."],";
}
?>
]);
for (var i = 0; i < data.getNumberOfRows(); i++) {
var colors = [];
colors.push(data.getValue(i, 0));
var options = {
title: 'Zone Statistics',
is3D:false,
pieHole: 0.4,
colors: colors,
textStyle:{color: 'black'},
legend:{position: 'none'},
chartArea: {width: 550, height: 300},
legend: 'labeled',
pieSliceText: 'none',
backgroundColor: '#E4E4E4',
};
var chart = new google.visualization.PieChart(document.getElementById('pie'));
chart.draw(data, options);
};
}
</script>

This question is about 2 years old but still unanswered. Let me provide a possible solution to your problem.
Google has option slices: to customize slice color and font color as well. There can be used array of all slices to customize them all or use index of the slice to customize individual slice.
slices: [{color: 'black'}, {}, {}, {color: 'red'}]
or
slices: {0: {color: 'black'}, 3: {color: 'red'}}
This can be used to change colors dynamically if colors are passed as variables.
Here is the google reference page for slice colors. Piechart

Related

How to show the complete number on the Y-axis in Google Chart?

I am using Google Chart to display a bar chart. Please see the screen shot below. Problem is, the highest number on the y-axis is always getting chopped off. In the screenshot, the highest number is supposed to be 55; but, as you can see, only the lower portion of 55 is showing. I have tried changing the height of my div and changing the height of the chart. They didn't solve the problem. I have also tried changing the max value of the y-axis but that does not solve the problem in the sense that the highest number would get chopped off (for example, for the chart in my screen shot, if I were to change the max value to 60, it is true that 55 would show completely but 60 would be chopped off).
How can I show the complete number on the highest value on y-axis in Google Charts?
google.charts.load('current', {packages: ['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.arrayToDataTable([
["", ""],
["Col_1", <?php echo $col1Count; ?>],
["Col_2", <?php echo $col2Count; ?>],
["Col_3", <?php echo $col3Count; ?>],
["Col_4", <?php echo $col4Count; ?>]
]);
var options = {
width: 720,
height: 550,
legend: { position: 'none' },
vAxis: {
viewWindow: {
min: 5,
max: 55
},
ticks: [5,10,15,20,25,30,35,40,45,50,55]
}
};
// Instantiate and draw the chart.
var chart = new google.charts.Bar(document.getElementById('myChart'));
chart.draw(data, google.charts.Bar.convertOptions(options));
google.visualization.events.addListener(chart, 'ready', function () {
html2canvas(document.getElementById('myChart')).then(function(canvas) {
// console.log(canvas.toDataURL('image/png'));
//document.getElementById('myChart').appendChild(canvas);
jQuery.ajax({
type: 'POST',
url: 'https://myURL.com/saveimage.php',
data: {
// send image string as data
imgstr: canvas.toDataURL('image/png')
},
success: function(response) {
alert(response);
}
});
});
});
}
The material Bar chart has far fewer options than the classic charts. I suspect that if you add a title, even if it is just a space character, that will reserve enough space above the chart to show the topmost axis tick label without truncation.

Google Visualization X Axis is overlapped

I am drawing Charts Using google.visualization API .
The User can select a value from DropDown in Front End and clicks on Go , it fetches data from backend .
Sometimes the data that fetched is more and sometimes less
When the Data is more , the x-axis being overlapped
Please see this fiddle
http://jsfiddle.net/7wYP2/462/
This is my code
google.load('visualization', '1', {packages: ['corechart']});
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([["strike_pr","CE","PE"],["5500",1875,2025],["6000",61500,104775],["6100",450,13725],["6500",35400,421800],["6600",150,121950],["6700",600,770925],["6800",13650,370425],["6900",33375,586650],["7000",744375,1122075],["7100",229200,355875],["7200",199800,689850],["7300",461550,244425],["7400",442950,439125],["7500",835350,484725],["7600",459000,82800],["7700",482250,48000],["7800",893250,11550],["7900",1215600,13500],["8000",741150,93525],["8100",242325,6150],["8200",326175,1500],["8300",365850,75],["8500",104850,2925],["9000",13050,11775]]);
var options = {
title:"OPTION INDEX distribution",
width: 800,
height: 400,
bar: {groupWidth: "95%"},
legend: { position: "none" },
is3D:true,
"vAxis":{"title":"Open Interest"},
"hAxis":{"title":"Strike Price"},
};
// Create and draw the visualization.
new google.visualization.ColumnChart(document.getElementById('visualization')).
draw(data, options);
}
google.setOnLoadCallback(drawVisualization);
Could you please let me know how to resolve this issue ??

Google Chart: Showing bars wrongly

I am currently working on Google Bar Chart-Dual-X and it is working nice.
Issue:
The bar is showing wrongly.For an example: Suppose I want to show Obtained Marks and Total Marks.But Issue is Google Chart shows Obtained Marks Bar bigger than the Total Mark(which is not true at all). You can see below pic :
As you can see in the pic that Chap 6,7,8 is having Obtained Mark Bar is bigger than the Total Mark Bar.
Code
<script type="text/javascript">
google.load("visualization", "1.1", {packages:["bar"]});
google.setOnLoadCallback(drawStuff);
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Subject', 'Obtained Marks', 'Total Marks'],
<?php
$i=1;
foreach($sql_get_marks_results as $sql_get_marks_result){
echo "['".$sql_get_marks_result->meta_subject."', ".$sql_get_marks_result->obtained_marks.", ".$sql_get_marks_result->total_marks."]";
if($i != count($sql_get_marks_results)){echo ",";}
$i++;
}
?>
]);
var options = {
width: 900,
chart: {
title: 'Markesheet',
subtitle: 'distance on the left, brightness on the right'
},
bars: 'horizontal', // Required for Material Bar Charts.
series: {
0: { axis: 'obtained' }, // Bind series 0 to an axis named 'distance'.
1: { axis: 'total' } // Bind series 1 to an axis named 'brightness'.
},
axes: {
x: {
obtained: {label: 'Obtained'}, // Bottom x-axis.
total: {side: 'top', label: 'Total'} // Top x-axis.
}
}
};
var chart = new google.charts.Bar(document.getElementById('dual_x_div'));
chart.draw(data, options);
};
</script>
Is anyone here who came across similar problem or anyone can help me out in this ?
Tell me if you want more detail about this.
The display shown in your screen shots is correct.
The "total marks" (red) dataset follows the bottom x-axis.
And the "Obtained" (blue) dataset follows the top x-axis.
I think that the scale (inferred by your data range) of your two X-axis is quite close. And because of this it's easy to confuse them.
Dual x-axis charts are good for complementary datasets with values in very different ranges as in the example given in the documentation.
In your case you'd be better of using a simple (single axis) bar chart to avoid that kind of confusion.

Multiple baselines with dual y-axis Google Chart

I'm using the Google Visualization API for a simple sales chart that has two series, number of sales and sales value, that I'm showing on a column chart with two vetical axes. The sales value can be negative, such as for returns, but this is causing the graph to show two different baselines. The zero baseline for number of sales is in line with the lowest sales value figure. Here's an example of the code with some sample data:
google.load('visualization', '1.0', { 'packages': ['corechart'] });
google.setOnLoadCallback(drawSalesChart);
function drawSalesChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Order Source');
dataTable.addColumn('number', 'Num Sales');
dataTable.addColumn('number', 'Sales Value');
dataTable.addRows([
['Web (Order)', 300, 31000],
['Call Centre (Order)', 700, 61000],
['Call Centre (Return)', 50, -4100],
['Call Centre (Exchange)', 10, 800]
]);
var options = {
title: 'Sales by Order Source',
hAxis: { title: 'Order Source' },
series: {
0: { targetAxisIndex: 0 },
1: { targetAxisIndex: 1 },
},
vAxes: {
0: { title: 'Num Sales' },
1: { title: 'Sales Value' }
}
};
new google.visualization.ColumnChart(
document.getElementById('livesales-chart-container')).draw(dataTable, options);
}
I've been through the API documentation as there's information on setting the baseline but there doesn't seem to be a way to tie the zero of each vAxis to the same point. I've tried searching Google and StackOverflow and there are similar questions but I can't see that anyone has had this problem.
How can I, or even can I, show a single baseline at zero for both series?
From a visualization perspective, it may be a lot better to create two separate charts on top of each other since the data provided is very different both in scope and in what it is explaining.
<!--
You are free to copy and use this sample in accordance with the terms of the
Apache license (http://www.apache.org/licenses/LICENSE-2.0.html)
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>
Google Visualization API Sample
</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});
</script>
<script type="text/javascript">
function drawSalesChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'Order Source');
dataTable.addColumn('number', 'Num Sales');
dataTable.addColumn('number', 'Sales Value');
dataTable.addRows([
['Web (Order)', 300, 31000],
['Call Centre (Order)', 700, 61000],
['Call Centre (Return)', 50, -4100],
['Call Centre (Exchange)', 10, 800]
]);
var dataView1 = new google.visualization.DataView(dataTable);
dataView1.setColumns([0,1]);
var dataView2 = new google.visualization.DataView(dataTable);
dataView2.setColumns([0,2]);
var options1 = {
title: 'Sales by Order Source',
hAxis: { title: 'Order Source' },
vAxis: { title: 'Num Sales' }
};
var options2 = {
title: null,
hAxis: { title: null, textPosition: 'none' },
vAxis: { title: 'Sales Value' }
};
new google.visualization.ColumnChart(
document.getElementById('chart1')).draw(dataView1, options1);
new google.visualization.ColumnChart(
document.getElementById('chart2')).draw(dataView2, options2);
}
google.setOnLoadCallback(drawSalesChart);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="chart1" style="width: 600px; height: 300px;"></div>
<div id="chart2" style="width: 600px; height: 100px;"></div>
</body>
</html>
Of course, this would need some prettying-up to make the graphs line up properly, and to make the colors work as you'd like, but this way you can focus on the main data you want to show, while keeping the other info nearby as a reference.
If you are insistent on doing them on the same graph, you will need to write a function to be able to calculate where the grid lines should lie (or figure out how Google does it, but I couldn't find it on a web search).
To figure out what the max/min values should be on a graph, an "easy" way is to take the difference between the minimum and maximum values, count the number of grid lines you will have (default for google is 5), round up to the nearest significant digit of your biggest number, and use those as your grid line dividers.
e.g. Taking your first column: 300, 700, 50, 10
Max Value: 700
Min Value: 10
Exponent: LEN(Max)-1 = 2 = 10^2, nearest 100
Grid Lines: 5 - 1 = 4 (assuming you want the bottom value to serve as the floor at the same rounding, you need 4 more iterations to go over the top value)
Difference Between Max and Min: 690
Required Interval: 690 / 4 = 172.5
Rounded up to the nearest 100: 200
Min Value: FLOOR(Min,200) = 0
Max Value: CEILING(Max,200) = 800
Grid Line 1: 0
Grid Line 2: 200
Grid Line 3: 400
Grid Line 4: 600
Grid Line 5: 800
Note, this matches what your chart shows. However, it won't work for negative values because the math gets a bit more complicated.
First you need to figure out the ratio of negative values to the total difference in min and max values.
e.g. Given your Column 2 data: 31000, 61000, -4100, 800
Min Value: -4100
Max Value: 61000
Difference: 65100
Negative Ratio: 6.3%
So 6.3% of your range is in the negative portion. Given 5 grid lines, that means that one grid line will need to be below 0, and you only have 4 grid lines for the positive portion. Since the negative portion is smaller than the positive portion, the positive portion will determine the grid line spacings.
So now you have 4 grid lines to cover the positive portion (0 - 61000), which means you have 3 segments from 0 to reach 61000.
That means 61000 / 3, rounded up to 4 significant digits, or 30,000.
That makes your gridlines:
-30,000
0
30,000
60,000
90,000
Coincidentally, this is what you got in your chart.
Now that you know the second series has 1 negative gridline, you'd have to readjust your first series to match the second one. So instead of having 5 gridlines (0 and 4 above), you now have 1 negative gridline, 1 0, and then 3 above zero that need to reach 700. So you take the 700 positive value you have, divide by 3, for 233.333.
Round that up to the nearest 100, and you get 300.
So your first chart max/min would be readjusted to -300, and 900 for the following gridlines:
-300
0
300
600
900
This will set the same baseline.
That will solve your problem -- all you need to do is code that logic in to Javascript! Let us know if you do it, I'm sure someone else will have the same issue down the line.

How to show an Empty Google Chart when there is no data?

Consider drawing a column chart and I don't get any data from the data source, How do we draw an empty chart instead of showing up a red colored default message saying "Table has no columns"?
What I do is initialize my chart with 1 column and 1 data point (set to 0). Then whenever data gets added I check if there is only 1 column and that it is the dummy column, then I remove it. I also hide the legend to begin so that it doesn't appear with the dummy column, then I add it when the new column gets added.
Here is some sample code you can plug in to the Google Visualization Playground that does what I am talking about. You should see the empty chart for 2 seconds, then data will get added and the columns will appear.
var data, options, chart;
function drawVisualization() {
data = google.visualization.arrayToDataTable([
['Time', 'dummy'],
['', 0],
]);
options = {
title:"My Chart",
width:600, height:400,
hAxis: {title: "Time"},
legend : {position: 'none'}
};
// Create and draw the visualization.
chart = new google.visualization.ColumnChart(document.getElementById('visualization'));
chart.draw(data,options);
setTimeout('addData("12:00",10)',2000);
setTimeout('addData("12:10",20)',3000);
}
function addData(x,y) {
if(data.getColumnLabel(1) == 'dummy') {
data.addColumn('number', 'Your Values', 'col_id');
data.removeColumn(1);
options.legend = {position: 'right'};
}
data.addRow([x,y]);
chart.draw(data,options);
}​
A even better solution for this problem might be to use a annotation column instead of a data column as shown below. With this solution you do not need to use any setTimeout or custom function to remove or hide your column. Give it a try by pasting the given code below into Google Code Playground.
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['', { role: 'annotation' }],
['', '']
]);
var ac = new google.visualization.ColumnChart(document.getElementById('visualization'));
ac.draw(data, {
title : 'Just a title...',
width: 600,
height: 400
});
}
​
The way I did this was by disabling the pie slices, turning off tooltips, stuffing in a pretend value and making it gray. I'm sure there are more clever ways to do this, but this worked for me where the other methods didn't.
The only drawback is that it sets both items in the legend to gray as well. I think you could perhaps just add a third item, and make it invisible on the legend only. I liked this way though.
function drawChart() {
// Define the chart to be drawn.
data = new google.visualization.DataTable();
data.addColumn({type: 'string', label: 'Result'});
data.addColumn({type: 'number', label: 'Count'});
data.addRows([
['Value A', 0],
['Value B', 0]
]);
var opt_pieslicetext = null;
var opt_tooltip_trigger = null;
var opt_color = null;
if (data.getValue(1,1) == 0 && data.getValue(0,1) == 0) {
opt_pieslicetext='none';
opt_tooltip_trigger='none'
data.setCell(1,1,.1);
opt_color= ['#D3D3D3'];
}
chart = new google.visualization.PieChart(document.getElementById('mydiv'));
chart.draw(data, {sliceVisibilityThreshold:0, pieSliceText: opt_pieslicetext, tooltip: { trigger: opt_tooltip_trigger }, colors: opt_color } );
}