Google pie chart attempts to draw before API finish loading - javascript

I am having some problem with Google chart. Here is the codes for my pie chart:
EDITED PORTION
function displayExistHospital(){
queryTask = new esri.tasks.QueryTask(overlayURLs["moh_hospital_WSA2"] + "/10");
query = new esri.tasks.Query();
query.returnGeometry = false;
query.where = "1=1";
query.outFields = ["*"];
queryTask.execute(query, getExistHospitalData);
document.getElementById("tabsLabel").style.display = "block";
document.getElementById("tabsLabel3").innerHTML = "Age > 60";
document.getElementById("tabsLabel2").innerHTML = "SCPR";
document.getElementById("tabsLabel1").innerHTML = "Total Pop";
}
google.load("visualization", "1", {packages:["corechart"], callback: displayExistHospital});
var arrList = [];
function getExistHospitalData(results){
arrList = [];
var features = results.features;
dojo.forEach(features, function(feature){
var tempArr = [];
var total_SCPR = feature.attributes.SUM_SUM_TOTAL_SCPR;
var total_NR = feature.attributes.SUM_SUM_TOTAL_NR;
var time = feature.attributes.FIRST_E_BREAK;
tempArr.push(time,total_SCPR,total_NR);
arrList.push(tempArr);
});
displayExistHospitalGraph(arrList);
}
function displayExistHospitalGraph(arrListData){
var total_ten = parseInt(arrListData[0][1]) + parseInt(arrListData[0][2]);
var total_tentoFifteen = arrListData[1][1] + arrListData[1][2];
var total_fifteenTwenty = arrListData[2][1] + arrListData[2][2];
var total_greaterTwenty = arrListData[3][1] + arrListData[3][2];
var ppl_num = total_ten + total_tentoFifteen;
var total_pop = total_ten + total_tentoFifteen + total_fifteenTwenty + total_greaterTwenty;
var dataOne = google.visualization.arrayToDataTable([
['Population', 'Percentage'],
['<10 mins' +getPercentageInString(total_ten,total_pop) , total_ten],
['10 - 15 mins' +getPercentageInString(total_tentoFifteen,total_pop), total_tentoFifteen],
['15 - 20 mins' +getPercentageInString(total_fifteenTwenty,total_pop), total_fifteenTwenty],
['>20 mins' +getPercentageInString(total_greaterTwenty,total_pop) , total_greaterTwenty],
]);
var percentage = (((total_ten / total_pop) + (total_tentoFifteen / total_pop)) * 100).toFixed(1);
var title = "Total Population ("+total_pop.toLocaleString()+") Catchment By Drive-Time(Existing)";
var optionsOne = {
chartArea: {
width: 350,
height: 200,
top: 20,
left: 10
},
fontName: 'Arial',
fontSize: getFontSize(),
isStacked:false,
title: title,
width: 400,
height: 200,
sliceVisibilityThreshold: 0,
colors:['#004CA8','#437DC4','#96B8E0','#FFFFFF']
};
document.getElementById('hospitalBoxContent').innerHTML= "</br><p ><span style='font-size:2em; color:#00297A; font-family:ArialVerdana; font-weight:bold;'>"+percentage+"% ("+ppl_num.toLocaleString()+")</span > of residents stay within <span style='font-size:2em; color:#00297A; font-family:ArialVerdana; font-weight:bold;'>15-min</span> drive-time to a public hospital </p><br/>";
var chart = new google.visualization.PieChart(document.getElementById('displayHospitalGraph'));
chart.draw(dataOne, optionsOne);
}
The chart works but somehow the percentage on the pie chart was cut off as the picture shown below:
I wonder is there any way to adjust the percentage for example, shift it nearer to the centre so that it won't cut off? I know the reason is because the chart was trying to draw before the API finish loading because this will only occur for the first load. After switching a few charts, the percentage label will be placed nicely inside the chart.
Credits to #asgallant and #Yoann as they helped me to spot the error but after added the codes, it still does not solve.
Thanks in advance.

Please change the last color #FFFFFF to any other color #FFFFFF this color is same as background

Some elements are cut off in you screenshot.
for the title, you need to increase top in optionsOne.chartArea (and height)
for the legend, increase width or reduce left in optionsOne.chartArea
the last pie item is set up on white colors:['#004CA8','#437DC4','#96B8E0','#FFFFFF'], change the font-colour or the last colour to avoid white on white
EDIT :
I created a http://jsfiddle.net/X24Sy/3/ with your code, I cannot reproduce your issue. Do you have any CSS for your container?
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart(){
var total_ten=15,total_tentoFifteen=35,total_fifteenTwenty=50,total_greaterTwenty=10;
var ppl_num = total_ten + total_tentoFifteen;
var total_pop = total_ten + total_tentoFifteen + total_fifteenTwenty + total_greaterTwenty;
var dataOne = google.visualization.arrayToDataTable([
['Population', 'Percentage'],
['<10 mins' +getPercentageInString(total_ten,total_pop) , total_ten],
['10 - 15 mins' +getPercentageInString(total_tentoFifteen,total_pop), total_tentoFifteen],
['15 - 20 mins' +getPercentageInString(total_fifteenTwenty,total_pop), total_fifteenTwenty],
['>20 mins' +getPercentageInString(total_greaterTwenty,total_pop) , total_greaterTwenty],
]);
var percentage = (((total_ten / total_pop) + (total_tentoFifteen / total_pop)) * 100).toFixed(1);
var title = "Total Population ("+total_pop.toLocaleString()+") Catchment By Drive-Time(Existing)";
var optionsOne = {
chartArea: {
width: 350,
height: 200,
top: 20,
left: 10
},
fontName: 'Arial',
fontSize: 12,
legend: { alignment: 'center', textStyle: { fontSize: 12} },
// pieSliceText: 'none', //label - > show the name on the pie
tooltip: {
trigger: 'focus'// focus -> tooltip will be displayed when the user hovers over an element.
// none -> tooltip is not displayed
},
isStacked:false,
title: title,
width: 350,
height: 200,
sliceVisibilityThreshold: 0,
colors:['#004CA8','#437DC4','#96B8E0','#FFFFFF']
};
var chart = new google.visualization.PieChart($('#displayHospitalGraph')[0]);
chart.draw(dataOne, optionsOne);
}

The problem is in this:
function getExistHospitalData(results){
arrList = [];
var features = results.features;
dojo.forEach(features, function(feature){
var tempArr = [];
var total_SCPR = feature.attributes.SUM_SUM_TOTAL_SCPR;
var total_NR = feature.attributes.SUM_SUM_TOTAL_NR;
var time = feature.attributes.FIRST_E_BREAK;
tempArr.push(time,total_SCPR,total_NR);
arrList.push(tempArr);
});
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(displayExistHospitalGraph(arrList));
}
First, you want to call google.load outside of any other functions. Second, this line:
google.setOnLoadCallback(displayExistHospitalGraph(arrList));
calls your displayExistHospitalGraph function with arrList as an argument, and passes it's return value (null) to google.setOnLoadCallback. This means that your drawing function is being executed immediately, not in the callback. Try this approach instead:
function getExistHospitalData(results){
arrList = [];
var features = results.features;
dojo.forEach(features, function(feature){
var tempArr = [];
var total_SCPR = feature.attributes.SUM_SUM_TOTAL_SCPR;
var total_NR = feature.attributes.SUM_SUM_TOTAL_NR;
var time = feature.attributes.FIRST_E_BREAK;
tempArr.push(time,total_SCPR,total_NR);
arrList.push(tempArr);
});
displayExistHospitalGraph(arrList);
}
function init () {
// get "results" and feed them to getExistHospitalData
getExistHospitalData(results);
}
google.load("visualization", "1", {packages:["corechart"], callback: init});

Related

GEE Animation, print thumbnail black

The following code is conceived to create a thumbnail image of landsat 7 images:
// Feature Collection
var aoi = geometry
print(aoi);
Map.addLayer(aoi);
var centroid = aoi.centroid(1)
print(centroid);
var coors = centroid.coordinates().getInfo()
var x = coors[0]
var y = coors[1];
Map.setCenter(x, y, 10);
// Elaborating the dates
// Getting Temperatures for Every Month
var period = ['-01-01', '-12-01'];
var years = [['1999', '2000'],
['2000', '2001'],
['2001', '2002'],
['2002', '2003'],
['2003', '2004'],
['2004', '2005'],
['2005', '2006'],
['2006', '2007'],
['2007', '2008'],
['2008', '2009'],
['2009', '2010'],
['2010', '2011'],
['2011', '2012'],
['2012', '2013'],
['2013', '2014'],
];
var add_period = function(year){
var start_date = period[0];
var end_date = period[1];
return [year[0] + start_date, year[1] + end_date];
};
var concatenate_year_with_periods = function(years, period){
return years.map(add_period);
};
var Dates = concatenate_year_with_periods(years, period);
/**********************************************************************
Landsat 7
***********************************************************************/
var visualization = {
bands: ['B4', 'B3', 'B2'],
min: 0.0,
max: 0.3,
};
var visualization_ = {
bands: ['B4_median', 'B3_median', 'B2_median'],
min: 0.0,
max: 0.3,
gamma: [0.95, 1.1, 1]
};
// Applies scaling factors.
var cloudMaskL7 = function(image) {
var qa = image.select('BQA');
var cloud = qa.bitwiseAnd(1 << 4)
.and(qa.bitwiseAnd(1 << 6))
.or(qa.bitwiseAnd(1 << 8));
var mask2 = image.mask().reduce(ee.Reducer.min());
return image
//.select(['B3', 'B4'], ['Red', 'NIR'])
.updateMask(cloud.not()).updateMask(mask2)
.set('system:time_start', image.get('system:time_start'));
};
var dataset = ee.ImageCollection('LANDSAT/LE07/C01/T1_TOA')
.filterDate('1999-01-01', '2020-12-31')
.filterBounds(aoi)
//.map(applyScaleFactors)
.map(cloudMaskL7)
.map(function(image){return image.clip(aoi)});
// Creating composites using median pixel value
var median_yearly_landsat_7 = function(start, end){
var dataset_ = dataset.filter(ee.Filter.date(start, end));
var median_yearly = dataset_.reduce(ee.Reducer.median());
return median_yearly;
};
var composite_name_list_l7 = ee.List([]);
var apply_monthly_composite = function(date_list){
var start = date_list[0];
var end = date_list[1];
var output_name = start + "TO" + end + "_LANSAT_7";
var composite = median_yearly_landsat_7(start, end);
composite_name_list_l7 = composite_name_list_l7.add([composite, output_name]);
Map.addLayer(composite, visualization_, output_name, false);
Export.image.toDrive({
image: composite,
description: output_name,
fileFormat: 'GeoTIFF',
crs : 'EPSG:4326',
folder : 'LANDSAT_LST_LAS_LOMAS',
region: aoi
});
return 0;
};
Dates.map(apply_monthly_composite);
/******************************************************************
// Animation gif
// Create RGB visualization images for use as animation frames.
/******************************************************************/
var text = require('users/gena/packages:text');
var annotated_collection_list = ee.List([])
var annotations = [
{position: 'left', offset: '0.25%', margin: '0.25%', property: 'label', scale: 1.5} //large scale because image if of the whole world. Use smaller scale otherwise
];
var create_annotated_collection = function(image_and_id) {
var img = image_and_id[0];
var image_id = image_and_id[1];
console.log(img);
console.log(image_id);
var img_out = img.visualize(visualization_)
.clip(aoi)//.paint(municipalities, 'FF0000', 2)
.set({'label': image_id});
Map.addLayer(img_out);
var annotated = text.annotateImage(img_out, {}, Bayern, annotations);
annotated_collection.add(annotated);
return 0;
};
var municipalities_geom = geometry;
var n = composite_name_list_l7.size().getInfo();
print(n);
for (var i = 0; i < n; i++) {
var img_info = ee.List(composite_name_list_l7.get(i));
print(img_info);
var img = ee.Image(img_info.get(0));
var img_id = ee.String(img_info.get(1));
var year = ee.String(ee.List(img_id.split("-").get(0)));
var month = ee.String(ee.List(img_id.split("-").get(1)));
var img_id_ = year.getInfo() + "_" + month.getInfo();
var img_out = img.visualize(visualization_)
.set({'label': img_id_});
var annotated = text.annotateImage(img_out, {}, municipalities_geom, annotations);
Map.addLayer(annotated);
var annotated_collection_list = annotated_collection_list.add(annotated)
}
var annotated_col = ee.ImageCollection(annotated_collection_list)
// Define GIF visualization parameters.
var gifParams = {
'region': geometry,
'dimensions': 254,
'crs': 'EPSG:32632',
'framesPerSecond': 1
};
// Print the GIF URL to the console.
print(annotated_col.getVideoThumbURL(gifParams));
// Render the GIF animation in the console.
print(ui.Thumbnail(annotated_col, gifParams));
However, this thumbnail appears black, but the images I load into the map project, are in the color visualization parameters that I need.
The geometry parameter is a Polygon I drew using the drawing tool. The coordinates are below:
Coordinates: List (1 element)
0: List (5 elements)
0: [-82.35277628512759,8.432445555054713]
1: [-82.314667459444,8.432445555054713]
2: [-82.314667459444,8.460632259476993]
3: [-82.35277628512759,8.460632259476993]
4: [-82.35277628512759,8.432445555054713]
Could someone tell my why the thumbnail appears black?

How to create a JavaScript stacked, semi-circle gauge chart with customized line widths?

I would like to be able to plot two or three values on one stacked gauge chart, similar to the following, with a light green, on top of another blue and a main thick value:
I have seen examples of these lines being separated, which would also do.
The first two need not be superimposed, but would be nice.
In looking at https://github.com/pguso/jquery-plugin-circliful, I can create multiple values on a chart but only in full-circle, not half-circle.
In the following JSFiddle, https://jsfiddle.net/0c8qaqaj/41/
<section class="container">
<h3>Circliful</h3>
<div class="row">
<div class="col-lg-4">
<div id="test-circle"></div>
</div> </div>
</section>
<script>
$( document ).ready(function() { // 6,32 5,38 2,34
$("#test-circle").circliful({
animation: 1,
animationStep: 5,
foregroundBorderWidth: 7,
backgroundBorderWidth: 7,
percent: 99,
textSize: 28,
textStyle: 'font-size: 12px;',
textColor: '#666',
multiPercentage: 1,
//halfCircle: 1,
halfCircle: false,
percentages: [
{'percent': 10, 'color': '#3180B8', 'title': 'Gryffindor' },
{'percent': 30, 'color': '#4ADBEA', 'title': 'Ravenclaw' },
{'percent': 50, 'color': '#49EBA8', 'title': 'Hufflepuff' },
{'percent': 70, 'color': '#FFCA35', 'title': 'Slytherin' }
],
multiPercentageLegend: 1,
replacePercentageByText: '',
backgroundColor: '#eee',
icon: 'f0d0',
iconPosition: 'middle',
iconColor: '#273B4E'
});
});
</script>
Setting 'halfCircle: true', only draws one value. Obviously not what I'm looking for.
The library does have a sample with two values, although I'm not sure how to replicate this example and whether or not it would work in halfcircle or if I can create an array to stack these values.
In another test, using AMCharts, I was able to create a semi-circle, stacked gauge chart.
A few issues:
I am unable to change the chart line widths manually. They seem to be proportional to the larger of the chart's height or width setting.
Setting width: 350:
I cannot change the white-space/padding above/below the charts. This one is fixable using css position: relative; left: -150; or whatever works. I don't really want to have to do this for anything around sides (top, bottom, etc.)
The charts do not display in a '' tag. To get in-line charts, I am using table cells.
Here is the JSFiddle for it.
I managed to locate a closer example of what I'm looking for in Chart.JS
The issue remains that I still am unable achieve exactly what I'm looking for as once again, the line sizing seems to be directly proportional to the container. You can see this by resizing the window.
The question/problem: I am m looking for a library that gives me the ability to customize the line widths in semi-circular gauge/doughnut charts and not be auto-constrained to the chart's dimensions.
Any recommendations on another library that would give me what I'm looking for please?
There is more than one way to do it with amCharts 4, here is one:
am4core.useTheme(am4themes_animated);
var chart = am4core.create("chartdiv", am4charts.GaugeChart);
chart.innerRadius = am4core.percent(80);
var colorSet = new am4core.ColorSet();
var axis = chart.xAxes.push(new am4charts.ValueAxis());
axis.min = 0;
axis.max = 100;
axis.renderer.innerRadius = 10
axis.strictMinMax = true;
axis.renderer.labels.template.disabled = true;
axis.renderer.ticks.template.disabled = true;
axis.renderer.grid.template.disabled = true;
var range0 = axis.axisRanges.create();
range0.value = 0;
range0.endValue = 60;
range0.axisFill.fillOpacity = 1;
range0.axisFill.fill = colorSet.getIndex(0);
range0.grid.disabled = true;
var range1 = axis.axisRanges.create();
range1.value = 60;
range1.endValue = 100;
range1.axisFill.fillOpacity = 1;
range1.axisFill.fill = am4core.color("#DADADA");
range1.grid.disabled = true;
var axis2 = chart.xAxes.push(new am4charts.ValueAxis());
axis2.min = 0;
axis2.max = 100;
axis2.strictMinMax = true;
axis2.renderer.labels.template.disabled = true;
axis2.renderer.ticks.template.disabled = true;
axis2.renderer.grid.template.disabled = true;
var range2 = axis2.axisRanges.create();
range2.value = 0;
range2.endValue = 90;
range2.axisFill.fillOpacity = 1;
range2.axisFill.fill = colorSet.getIndex(3);
range2.axisFill.radius = am4core.percent(105);
range2.axisFill.innerRadius = am4core.percent(100); // set it to >100 if you'd like to have some gap between fills
range2.grid.disabled = true;
var range3 = axis2.axisRanges.create();
range3.value = 90;
range3.endValue = 100;
range3.axisFill.fillOpacity = 0.5;
range3.axisFill.fill = am4core.color("#DADADA");
range3.axisFill.radius = am4core.percent(105);
range3.axisFill.innerRadius = am4core.percent(100); // set it to >100 if you'd like to have some gap between fills
range3.grid.disabled = true;
var label = chart.radarContainer.createChild(am4core.Label);
label.isMeasured = false;
label.fontSize = 45;
label.x = am4core.percent(50);
label.y = am4core.percent(100);
label.horizontalCenter = "middle";
label.verticalCenter = "bottom";
label.text = "50%";
And this is a result: https://codepen.io/team/amcharts/pen/qgxyZK

Adding annotations to Google candlestick chart (Posted solution triggers TypeError)

I am trying to add some annotations to a Google Candlestick chart. I noticed someone had already asked this same question (Adding annotations to Google Candlestick chart). The user Aperçu replied with a detailed solution to extend the chart and add annotations since the chart doesn't have any such feature built in. However, when I try this solution I get an error "TypeError: document.querySelectorAll(...)[0] is undefined"
Here is my code:
chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
// attempt to use Aperçu's solution
const bars = document.querySelectorAll('#chart_div svg > g:nth-child(5) > g')[0].lastChild.children // this triggers a TypeError
for (var i = 0 ; i < bars.length ; i++) {
const bar = bars[i]
const { top, left, width } = bar.getBoundingClientRect()
const hint = document.createElement('div')
hint.style.top = top + 'px'
hint.style.left = left + width + 5 + 'px'
hint.classList.add('hint')
hint.innerText = rawData.filter(t => t[1])[i][0]
document.getElementById('chart_div').append(hint)
}
I want the chart to show the last piece of data next to the bars (i.e. "foo1", "foo2", etc)
each candle or bar will be represented by a <rect> element
we can use the rise and fall colors to separate the bars from other <rect> elements in the chart
there will be the same number of bars as rows in the data table
once we find the first bar, we can use rowIndex of zero to pull values from the data
we need to find the value of the rise / fall, to know where to place the annotation
then use chart methods to find the location for the annotation
getChartLayoutInterface() - Returns an object containing information about the onscreen placement of the chart and its elements.
getYLocation(position, optional_axis_index) - Returns the screen y-coordinate of position relative to the chart's container.
see following working snippet
two annotations are added
one for the difference in rise and fall
and the other for the value in the column with annotation role
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.CandlestickChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var annotation;
var bars;
var chartLayout;
var formatNumber;
var positionY;
var positionX;
var rowBalance;
var rowBottom;
var rowIndex;
var rowTop;
var rowValue;
var rowWidth;
chartLayout = chart.getChartLayoutInterface();
rowIndex = 0;
formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0'
});
bars = container.getElementsByTagName('rect');
for (var i = 0; i < bars.length; i++) {
switch (bars[i].getAttribute('fill')) {
case '#a52714':
case '#0f9d58':
rowWidth = parseFloat(bars[i].getAttribute('width'));
if (rowWidth > 2) {
rowBottom = data.getValue(rowIndex, 1);
rowTop = data.getValue(rowIndex, 3);
rowValue = rowTop - rowBottom;
rowBalance = Math.max(rowBottom, rowTop);
positionY = chartLayout.getYLocation(rowBalance) - 6;
positionX = parseFloat(bars[i].getAttribute('x'));
// row value
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = formatNumber.formatValue(rowValue);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY);
annotation.setAttribute('font-weight', 'bold');
// annotation column
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = data.getValue(rowIndex, 5);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY - 18);
annotation.setAttribute('font-weight', 'bold');
rowIndex++;
}
break;
}
}
});
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google Charts Get maximum scale

I'm trying to make an all positive bubble chart have quadrants by drawing the quadrants using the baseline property like so:
var dataT = google.visualization.arrayToDataTable(.....);
var options = {
hAxis: {title: 'h axis',baseline:100},
vAxis: {title: 'v axis',baseline:20},
...}
var chart = new google.visualization.BubbleChart(...);
chart.draw(dataT,options);
Except the graph will keep changing depending on the query so the baselines will not be the same for all the graphs. I would like to be able to get the max axis value and divide it by 2 to set the baselines right in the middle of each axis.
Example:
var options = {
hAxis: {title: 'h axis',baseline:max_h_axis/2},
vAxis: {title: 'v axis',baseline:max_v_axis/2},
...
Is there any way of knowing the max axis values of the graph before drawing the graph?
the getColumnRange method works for this...
Returns the minimal and maximal values of values in a specified column. The returned object has properties min and max. If the range has no values, min and max will contain null.
you can also use this information to produce your own axis tick marks.
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['X', 'Y'],
[8, 120],
[4, 155],
[11, 140],
[4, 205],
[3, 35],
[6, 78]
]);
var ticksX = [];
var ticksY = [];
var numberOfTicks = 10;
var rangeX = data.getColumnRange(0);
var rangeY = data.getColumnRange(1);
var stepX = Math.ceil((rangeX.max - rangeX.min) / numberOfTicks);
for (var i = rangeX.min - stepX; i <= rangeX.max + stepX; i = i + stepX) {
ticksX.push(i);
}
var stepY = Math.ceil((rangeY.max - rangeY.min) / numberOfTicks);
for (var i = rangeY.min - stepY; i <= rangeY.max + stepY; i = i + stepY) {
ticksY.push(i);
}
var baseX = Math.ceil((rangeX.max - rangeX.min) / 2) + rangeX.min;
var baseY = Math.ceil((rangeY.max - rangeY.min) / 2) + rangeY.min;
var options = {
hAxis: {
title: 'h axis',
baseline: baseX,
ticks: ticksX
},
vAxis: {
title: 'v axis',
baseline: baseY,
ticks: ticksY
},
legend: 'none',
height: 600,
width: 600
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Trouble creating google gauge chart dynamically

I am having some issues dynamically creating code for Google Gauge visualization. My main problem is that I am trying to build the javascript based on what is returned in some JSON to build multiple gauge panels for a temp monitoring dashboard. Here is my current code:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
//Get php data about sensor into json array for javasript processing
var gauges = <?php echo json_encode($sensor_data);?>;
google.load("visualization", "1", {packages:["gauge"]});
google.setOnLoadCallback(drawChart);
for (var i = 0, len = gauges.length; i < len; ++i) {
var gauge = gauges[i];
var currentTemp = gauge.value;
var chartID = "chart_div_" + gauge.sensor_id;
var gMin = gauge.config_min_temp;
var gMax = gauge.config_max_temp;
var lLimit = gauge.limits_low;
var hLimit = gauge.limits_high;
//calculate major tick increments
var increment = (parseFloat(gMax) - parseFloat(gMin))/4;
var tick0 = gMin;
var tick1 = parseFloat(gMin) + parseFloat(increment);
var tick2 = parseFloat(tick1) + parseFloat(increment);
var tick3 = parseFloat(tick2) + parseFloat(increment);
var tick4 = gMax;
var Ticks = [tick0, tick1, tick2, tick3, tick4];
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Temp', 0]
]);
var options = {
width: 220, height: 220,
redFrom: hLimit, redTo: gMax,
yellowFrom: gMin, yellowTo: lLimit,
greenFrom: gMin, greenTo: gMax,
minorTicks: 5,
majorTicks: Ticks,
min: gMin,
max: gMax,
redColor: '#ff0000',
yellowColor: '#ff0000',
greenColor: '#00cc00'
};
var chart = new google.visualization.Gauge(document.getElementById(chartID));
data.setValue(0, 1, currentTemp);
chart.draw(data, options);
}
}
</script>
My issue is that I cannot create an array of the data object. I need to reference that object inside the for loop. I have googled this issue until I am at my wits end and cannot come up with a good way to do this. I am wide open for suggestions. Thanks in advance.
Your code as-is will create a single drawChart function and then overwrite it, which I am fairly certain is not your intention. This code will loop over your gauges array and draw a Gauge for each element in the array:
function drawChart() {
for (var i = 0, len = gauges.length; i < len; ++i) {
var gauge = gauges[i];
var currentTemp = gauge.value;
var chartID = "chart_div_" + gauge.sensor_id;
var gMin = gauge.config_min_temp;
var gMax = gauge.config_max_temp;
var lLimit = gauge.limits_low;
var hLimit = gauge.limits_high;
//calculate major tick increments
var increment = (parseFloat(gMax) - parseFloat(gMin))/4;
var tick0 = gMin;
var tick1 = parseFloat(gMin) + parseFloat(increment);
var tick2 = parseFloat(tick1) + parseFloat(increment);
var tick3 = parseFloat(tick2) + parseFloat(increment);
var tick4 = gMax;
var Ticks = [tick0, tick1, tick2, tick3, tick4];
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Temp', currentTemp]
]);
var options = {
width: 220, height: 220,
redFrom: hLimit, redTo: gMax,
yellowFrom: gMin, yellowTo: lLimit,
greenFrom: gMin, greenTo: gMax,
minorTicks: 5,
majorTicks: Ticks,
min: gMin,
max: gMax,
redColor: '#ff0000',
yellowColor: '#ff0000',
greenColor: '#00cc00'
};
var chart = new google.visualization.Gauge(document.getElementById(chartID));
data.setValue(0, 1, currentTemp);
chart.draw(data, options);
}
}
Is that what you are looking to accomplish?

Categories