Google Geomap API change region option onClick() - javascript

This piece of code draws a map with the Google Geomap API
<script type="text/javascript">
google.setOnLoadCallback(drawMap);
function drawMap() {
var data = new google.visualization.DataTable();
data.addColumn('string','iso'); //e.g.: mx
data.addColumn('number','population'); //e.g.: 114
data.addRows([["mx",114],["ec",14],["ve",28]]);
var options = {
region: '005',
width: '511px',
height: '280px',
showLegend: true
};
var geomap = new google.visualization.GeoMap(document.getElementById('map'));
geomap.draw(data,options);
};
</script>
The region that is selected by default is 005 (South America). These are other available regions:
013 - (Central America)
150 - (Europe)
How can I change the region of the already drawn map dinamically? Something like this:
Europe
I know that the map will have to be redrawn, but i'm kind of stuck in the region property modification step. Any ideas will help. Thanks!

If you already have the data, I give you a snippet I use in my own app. Easier to understabd rather than long explanations I guess. Hope it helps.
In my case, I wanted to display numbers by country in the same region.
geomap = new google.visualization.GeoMap(document.getElementById('geo_chart'));
google.visualization.events.addListener( geomap, 'regionClick',
function(e)
{
var dataLocal = new google.visualization.DataTable();
var grouped_cities;
if (e['region'] == "0")
return;
options['colors'] = [0xaacdf8, 0x164177]; //orange colors
options['dataMode'] = 'markers';
options['region'] = e['region'];
options['showZoomOut'] = true;
if ( previous_region != e['region'] )
{
var indexes = dataFull.getFilteredRows([{column: 0, value: e['region']}]);
dataLocal.addRows(indexes.length);
dataLocal.addColumn('string', 'City');
dataLocal.addColumn('number', 'Views');
for ( i=0; i<indexes.length; i++ )
{
dataLocal.setValue(i, 0, dataFull.getValue(indexes[i], 2));
dataLocal.setValue(i, 1, dataFull.getValue(indexes[i], 3));
}
grouped_cities = google.visualization.data.group( dataLocal, [0],[{'column': 1, 'aggregation': google.visualization.data.sum, 'type': 'number'}]);
previous_region = e['region'];
}
geomap.draw(grouped_cities, options);
delete grouped_cities;
delete dataLocal;
}
);

Related

ChartRangeFilter as a zoom function for a google timeline charts that reads data from a dedicated google spreadsheet with dataview

My goal is to integrate this zoom capability provided by Whitehat into my personal timeline project:
JsFiddle 1 - my working timeline
As you can see from the jsfiddle above the code actually works and provides a working timeline:
// Load the Visualization API and the corechart package.
google.charts.load("current", {packages:["timeline"]});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawGID);
function drawGID() {
var query = new google.visualization.Query(
'https://docs.google.com/spreadsheets/d/1gDsiNSKfPdoutSbtzyt8fExliJpzIWQocEArpAQYD_g/gviz/tq?gid=0&sheet=table');
query.setQuery('select A, B, C, D, E, F, G, H, I, J LIMIT 10');
query.send(handleQueryResponse);
} //fine funzione drawGID
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
// Set chart options
var options = {'width':'100%', 'height':'100%'};// fine options
var data = response.getDataTable();
//da qui proviamo dataview
var view = new google.visualization.DataView(data);
view.setColumns([
{ sourceColumn: 1, id: 'materia'},
{ sourceColumn: 2, id: 'evento'},
{ sourceColumn: 5, id: 'start'},
{ sourceColumn: 6, id: 'end'} /*,
{ sourceColumn: 7, id: 'null'},
{ sourceColumn: 8, id: 'scatter'},
{ sourceColumn: 9, id: 'data'}*/
]);
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
chart.draw(view, options);
} //fine funzione handleQueryResponse
The problems start when I try to combine the Whitehat's solution with mine:
here I provide a jsfiddle with a working copy of Whitehat's code in the first place as a reference:
JsFiddle 2 - Whitehat's code ok
then a jsfiddle with my attempt to mix the two codes (not working)
JsFiddle 3 - Whitehat's code mixed to mine (not working)
and in the end a sort of test jsfiddle, where I output data in the form of a data table instead of timeline, to double check that the code was (at least partially) right
JsFiddle 4 - output as data table instead of timeline
And here is the original data base google sheet file
timeline - google sheet
My question of course is: why jsfiddle 3 is not working? thanks
You can use a library like svg-pan-zoom by Andrea Leofreddi to add this capability to your page.
After adding the appropriate resource to your page, you can then add a function to initialize this library with your svg graph.
//...
chart.draw(view, options);
//Initialize the code for svgPanZoom
//Limit Paning so chart doesn't go out of viewport:
var beforePan = function(oldPan, newPan) {
var stopHorizontal = false;
var stopVertical = false;
var gutterWidth = 100;
var gutterHeight = 100;
// Computed variables
var sizes = this.getSizes();
var leftLimit = -((sizes.viewBox.x + sizes.viewBox.width) * sizes.realZoom) + gutterWidth;
var rightLimit = sizes.width - gutterWidth - (sizes.viewBox.x * sizes.realZoom)
var topLimit = -((sizes.viewBox.y + sizes.viewBox.height) * sizes.realZoom) + gutterHeight;
var bottomLimit = sizes.height - gutterHeight - (sizes.viewBox.y * sizes.realZoom);
var customPan = {};
customPan.x = Math.max(leftLimit, Math.min(rightLimit, newPan.x));
customPan.y = Math.max(topLimit, Math.min(bottomLimit, newPan.y));
return customPan
}
var chartSvg = document.querySelector("#timeline > div > div:nth-child(1) > div > svg");
var panZoomSvg = svgPanZoom(chartSvg, {
fit: true,
contain: false,
center: true,
beforePan: beforePan
});
//Resized the chart when the window is resized.
window.onresize = function() {
panZoomSvg.resize();
panZoom.fit();
panZoom.center();
};

How to add clustered markers to a group [Here Maps api]

I want to hide specific markers on checkbox click, that's why i tried to
add these markers to groups. But when i do this iconsGroup.getObjects();
it returns an empty array. What am i doing wrong ?
var iconsGroup = new H.map.Group();
var CUSTOM_THEME = {
getClusterPresentation : function (cluster) {
var randomDataPoint = getRandomDataPoint(cluster),
bubbleContent = getBubbleContent(cluster);
// Get a reference to data object that DataPoint holds
map.setCenter(cluster.getPosition());
data = randomDataPoint.getData();
var marker = new H.map.DomMarker(cluster.getPosition(), {
icon: data.icon,
min: cluster.getMinZoom(),
max: cluster.getMaxZoom()
});
iconsGroup.addObject(marker);
marker.setData(bubbleContent);
marker.addEventListener('tap', onClusterClick);
return marker;
},
getNoisePresentation : function (noisePoint) {
var data = noisePoint.getData();
var noiseMarker = new H.map.DomMarker(noisePoint.getPosition(), {
icon: noisePoint.getData().icon,
min: noisePoint.getMinZoom()
});
noiseMarker.setData(data);
noiseMarker.addEventListener('tap', onMarkerClick);
return noiseMarker;
}
}
var clusterProvider = new H.clustering.Provider(arr, {
clusteringOptions: {
minWeight: 1,
eps: 32
}
});
clusterProvider.setTheme(CUSTOM_THEME);
clusteringProviderArray.push(clusterProvider);
var clusterLayer = new H.map.layer.ObjectLayer(clusterProvider);
map.addLayer(clusterLayer);
clusteringLayerArray.push(clusterLayer);
groupLayers.push(iconsGroup);
I will just use arrays instead of groups

How to limit xAxis label in Chart.Js 1.0.2?

I am trying to plot a twitter streaming ,tweet sentiment score on per minute basis using ChartJs 1.0.2 .The xlables are getting overlapped after sometime. How can i plot the graph for a limited number of xAxis Labels to avoid the overlap. I am using Apache Zeppelin and AngularJs interpreter for the plotting. The code is as follows.
lineChartData = {}; //declare an object
lineChartData.labels = []; //add 'labels' element to object (X axis)
lineChartData.datasets = []; //add 'datasets' array element to object
//FIRST GRAPH: score
var line = 0
y = [];
lineChartData.datasets.push({}); //create a new line dataset
dataset = lineChartData.datasets[line]
dataset.fillColor = "rgba(0, 0, 0, 0)";
dataset.strokeColor = "rgba(75,192,192,0.4)";
dataset.lineColor = "rgba(75,192,192,0.4)";
dataset.label = "Score"
dataset.data = []; // value data
angular.forEach(newValue, function(x) {
y.push(x._3);
if (line === 0)
lineChartData.labels.push(x._2); //adds x axis labels
})
lineChartData.datasets[line].data = y; //send new line data to dataset
//end FIRST GRAPH: score
var options = {
responsive: true,
animation: false,
multiTooltipTemplate: function(dataset) {
//console.log(dataset)
return dataset.datasetLabel+ " : " + dataset.value ;
dataset.strokeColor='red';
} ,
}
ctx = canvas.getContext("2d");
myLineChart = new Chart(ctx).Line(lineChartData, options);
var legend = myLineChart.generateLegend();
$("#legendDiv").html(legend);
//document.getElementById("legendDiv").innerHTML = legend;
})
}
if (window.L) {
initMap();
} else {
console.log('Loading Leaflet library');
var sc = document.createElement('script');
sc.type = 'text/javascript';
sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js';
sc.onload = initMap;
sc.onerror = function(err) { alert(err); }
document.getElementsByTagName('head')[0].appendChild(sc);
}
I can think of following ways.
Get only the data for limited time window to the variable but not get all data.
Group the data to large time point
Example the data for certain interval
BTW, It might be worth to wrap the code which convert to data to visualisation. It will be easier to change to a different chart or use different plot option.
If you don't have strong preference for chart.js, check spark-highcharts to see if it meets your plot needs, or create a similar wrapper to chart.js.

Creating a scatter plot using Plotly.js with multiple Y for common X's

This is the graph that I've created currently.
It looks the way I want it to, but it doesn't behave the way I want it to.
Current Graph
Hello, I am trying to create a scatter plot using Plotly.js, and I am having trouble with markers being buggy (or I just wrote the code in a wrong way).
This is my current code on how I am formatting the data:
var formatData2 = function(antibacData) {
console.log("Data formatting begins now ---------------");
var plotData = {};
var antibiotics = {
neomycin: [],
penicilin: [],
streptomycin: []
};
var gramstain = [];
antibacData.forEach(function(d) {
if (d != null) {
var gramStain;
// Converts gramstain string data to boolean
if (d["Gram Staining "] == "positive") {
gramStain = "rgba(102, 51, 153, 0.7)";
} else {
gramStain = "rgba(255, 47, 47, 0.7)";
}
plotData[d["Bacteria "]] = {
stain : gramStain,
neomycin : d["Neomycin"],
penicilin : d["Penicilin"],
streptomycin : d["Streptomycin "]
};
}
});
var keys = Object.keys(antibiotics);
var bactName = Object.keys(plotData);
console.log(keys);
console.log(bactName);
antibacData.forEach(function(d) {
antibiotics.neomycin.push(d["Neomycin"]);
antibiotics.penicilin.push(d["Penicilin"]);
antibiotics.streptomycin.push(d["Streptomycin "]);
});
console.log(antibiotics);
var name1 = new Array(16).fill('Neomycin');
var name2 = new Array(16).fill('Penicilin');
var name3 = new Array(16).fill('Streptomycin');
var group1 = {
x: name1,
y: antibiotics.neomycin,
name: 'Neomycin',
mode: 'markers',
type: 'scatter',
text: bactName
};
var group2 = {
x: name2,
y: antibiotics.penicilin,
name: 'Penicilin',
mode: 'markers',
type: 'scatter',
text: bactName
};
var group3 = {
x: name3,
y: antibiotics.streptomycin,
name: 'Streptomycin',
mode: 'markers',
type: 'scatter',
text: bactName
};
var resultData = [group1, group2, group3];
console.log("Data formatting ends now -----------------");
return resultData;
}
It's pretty long (sorry about that).
Basically, I created a marker for each bacteria using antibacterials as x-axes, and their MIC as the y-axis.
However, when I plot the data, it doesn't allow me to hover over each marker to display the individual data associated with it. It will only allow me to hover over one marker for each X (or each antibacterial).
Is there a way to fix this? or am I just approaching it in a wrong way.
I think you're missing the hovermode parameter from your layout, but I can't get your code to run so I can't test it. Try adding:
layout = {
hovermode:'closest'
};
Here's an example of the hovermode parameter in use: https://plot.ly/javascript/hover-text-and-formatting/

How to clear chart before adding new data?

I am using the Google Visualization API. A chart is generated based on values from an ajax call function drawchart().
The user then inputs values in textboxes and this point is added on the chart also (function addUserPoint()). function addUserPoint2() is autogenerated and is also added onto the map. The result of adduserpoint and adduserpoint2 have a line between them.
My issue: If the user adds a new point again, the chart adds those values and the previously added points stay on the chart. I want to get rid of the results of adduserpoint and adduserpoint2 before adding a new point. How can I achieve this?
var chartData;
var options2;
function addUserPoint() {
if (chartData.getNumberOfColumns() === 2) {
chartData.addColumn('number', '');
}
var aa= $("#wbtotala").text();
var bb= $("#wbtotalb").text();
chartData.addRow([
parseFloat(bb),
null,
parseFloat(aa)
]);
myLineChart.draw(chartData, options2);
}
function addUserPoint2(){
if (chartData.getNumberOfColumns() === 2) {
chartData.addColumn('number', '');
}
myLineChart.draw(0,0, options2);
var aa2 = fweight;
var bb2= fcg;
chartData.addRow([
parseFloat(bb2),
null,
parseFloat(aa2)
]);
myLineChart.draw(chartData, options2);
}
function drawchart() {
document.getElementById('addPoint').addEventListener('click', addUserPoint, false);
document.getElementById('addPoint').addEventListener('click', addUserPoint2, false);
chartData = new google.visualization.DataTable();
chartData.addColumn('number', 'Sli');
chartData.addColumn('number', 'Weight');
for (var i = 0; i < chartdatax.length; i++) {
chartData.addRow([parseFloat(chartdatax[i]), parseFloat(chartdatay[i])]);
};
options2 = {
height: 500,
hAxis: {
title: 'AB',
gridlines: {
count: 20
}
},
vAxis: {
title: 'CD',
gridlines: {
count: 15
}
},
chartArea: {top:40, width: "70%", height: "75%"},
legend: { position: 'none' },
pointSize: 5
};
myLineChart = new google.visualization.LineChart(document.getElementById('myChart2'));
myLineChart.draw(chartData, options2);
}
Use the Below Command.Here data is the DataTable Variable.
var data = new google.visualization.DataTable();
Set chartData to an empty object in addUserPoint();
function addUserPoint() {
charData = {};
if (chartData.getNumberOfColumns() === 2) {
...
}
}
This makes sure that anytime you add a new Data, it clears the previous data and you have a fresh new dataset ;)

Categories

Resources