ASP.net google charts - asp.net

I am having difficulties to get google charts to work in ASP.NET Core MVC. When using the example from google it works fine (Source: https://developers.google.com/chart/interactive/docs/gallery/columnchart):
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
</head>
<body>
<div id="columnchart_material" style="width: 800px; height: 500px;"></div>
</body>
</html>
My problem is that my data has different lengths in columns, thus sticking to the example above I have sometimes ['Year', 'Sales'] or ['Year', 'Sales', 'Expenses'] and I am trying to make this plot dynamic.
I am using Viewbag to pass around my data, thus I have made available my model with:
#{
dataModel.ChartPlotData = ViewBag.ChartPlotData as ChartPlotData
}
I have defined a class holding my data:
public class ChartPlotData
{
public List<List<object>> Data;
public ChartPlotData() { Data = new List<List<object>>(); }
}
The data is filled via:
private ChartPlotData MockData()
{
var retVal = new ChartPlotData();
var line = new List<object>();
line.Add("Time");
line.Add("Test");
retVal.Data.Add(line);
line = new List<object>();
line.Add("0:05");
line.Add(0);
retVal.Data.Add(line);
line = new List<object>();
line.Add("0:10");
line.Add(1);
retVal.Data.Add(line);
return retVal;
}
Now I was trying to change the part in the plot data as:
var data = google.visualization.arrayToDataTable( #dataModel.ChartPlotData.Data )
It did not work. Next, I extended my class as:
public object[][] DataArray
{
get
{
var tmpLst = new List<object[]>();
foreach (var lstObj in Data)
{
tmpLst.Add(lstObj.ToArray());
}
return tmpLst.ToArray();
}
}
Still no luck. I tried various other things by instantiating the data as
var data = new google.visualization.DataTable();
then tried adding columns and setting cells like
// Add columns
data.addColumn('string', 'Employee Name');
data.addColumn('date', 'Start Date');
// Add empty rows
data.addRows(6);
data.setCell(0, 0, 'Mike');
data.setCell(0, 1, {v:new Date(2008,1,28), f:'February 28, 2008'});
data.setCell(1, 0, 'Bob');
data.setCell(1, 1, new Date(2007, 5, 1));
data.setCell(2, 0, 'Alice');
data.setCell(2, 1, new Date(2006, 7, 16));
data.setCell(3, 0, 'Frank');
but somehow I can not get it to work. Any help would be highly appreciated.
Edit:
I tried this:
var data = google.visualization.arrayToDataTable([
#for (var i = 0; i < 1; i++)
{
<text> ['Time','Test'],['00:00',0],['00:05',1] </text>
}
]);
It works. But when I replace it with a string containing the list, it stops working:
var data = google.visualization.arrayToDataTable([
#for (var i = 0; i < 1; i++)
{
<text> #dataModel.dataAsString </text>
}
]);
I can now narrow it down to the following problem. This works fine:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', { 'packages': ['bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable(
#for (var i = 0; i < 1; i++)
{
<text> [['Time', 'Test'], ['0:00', 0], ['0:05', 1]] </text>
}
);
var options = {
chart: {
title: 'Title',
subtitle: 'Some subtitle'
}
};
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
</head>
<body>
<div id="columnchart_material" style="width: 800px; height: 500px;"></div>
</body>
</html>
If I define a variable within my datamodel that includes exactly this string and replace
var data = google.visualization.arrayToDataTable(
#for (var i = 0; i < 1; i++)
{
<text> #dataModel.MyDataAsString </text>
}
);
it stops working.

I solved the problem. First, I created a field in html like
<p id="demo"></p>
Then in the java script one can use this to get the representation of the data:
var tmpData = google.visualization.arrayToDataTable([['Time', 'Test',], ['0:00', 1], ['0:05', 0.5]]);
document.getElementById("demo").innerHTML = tmpData.toJSON();
I then created a data class in C# that can generate this structure:
{"cols":[{"label":"Time","type":"string"},{"label":"Test","type":"number"}],"rows":[{"c":[{"v":"0:00"},{"v":1}]},{"c":[{"v":"0:05"},{"v":0.5}]}]}
Setting the value of the field using a variable
<p id="field">#StringRepresentation</p>
and then:
tmpJason = document.getElementById("field").innerHTML;
var data = new google.visualization.DataTable(tmpJason);

Related

Unable to draw a Curved Polyline using Here Maps JS Api

Unable to Draw a curved polyline using Here Maps JS API.
Trying to add the logic based on my previous findings.
It throws an error "Uncaught TypeError: arc.GreatCircle is not a constructor"
Any Suggestions on how to fix this ?
My Earlier Querstion
Here is my working JSFiddle which is trying to draw a curve to multiple spots.
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
defaultLayers.vector.normal.map,{
center: {lat:52, lng:5},
zoom: 5,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
var npoints = 100,
offset = 20;
// Now use the map as required...
//addPolylineToMap(map);
// Berlin -> Chicago0
add([52.51607,13.37699],[41.88425,-87.63245], { style: { strokeColor : "#00FF00", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Tokyo -> san Francisco
add([35.68019,139.81194],[37.77712,-122.41964], {style: { strokeColor: "rgba(0,0,255,0.7)", lineWidth: 15, lineDash: [1], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Melbourne
add([52.51607,13.37699],[-37.81753,144.96715], { style: { strokeColor : "rgba(255,0,255,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Paris -> Paris -> London
add([52.51607,13.37699],[48.85721, 2.34144], { style: { strokeColor : "rgba(0,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
add([48.85721, 2.34144],[51.50643,-0.12721], { style: { strokeColor : "rgba(255,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
function add(s,e,options) {
var arc = {};
arc.Coord = Coord;
arc.Arc = Arc;
arc.GreatCircle = GreatCircle;
var start_ll = new H.geo.Point(s[0],s[1]),
end_ll = new H.geo.Point(e[0],e[1]),
start_coord = {x: start_ll.lng, y:start_ll.lat},
end_coord = {x:end_ll.lng, y:end_ll.lat};
description = ''+s[0]+','+s[1]+'=>'+e[0]+','+e[1]+'',
gc0 = new arc.GreatCircle(start_coord,end_coord, {'name': 'line', 'color':'#ff7200','description':description}),
line0 = gc0.Arc(npoints,{offset:offset}),
strip = line0.strip();
map.addObject(new H.map.Polyline(strip, options));
}
var D2R = Math.PI / 180;
var R2D = 180 / Math.PI;
var Coord = function(lon, lat) {
this.lon = lon;
this.lat = lat;
this.x = D2R * lon;
this.y = D2R * lat;
};
Coord.prototype.view = function() {
return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
};
Coord.prototype.antipode = function() {
var anti_lat = -1 * this.lat;
var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
return new Coord(anti_lon, anti_lat);
};
var LineString = function() {
this.coords = [];
this.length = 0;
};
LineString.prototype.move_to = function(coord) {
this.length++;
this.coords.push(coord);
};
var Arc = function(properties) {
this.properties = properties || {};
this.geometries = [];
};
Arc.prototype.json = function() {
if (this.geometries.length <= 0) {
return { 'geometry': { 'type': 'LineString', 'coordinates': null }, 'type': 'Feature', 'properties': this.properties };
} else if (this.geometries.length == 1) {
return { 'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords }, 'type': 'Feature', 'properties': this.properties };
} else {
var multiline = [];
for (var i = 0; i < this.geometries.length; i++) {
multiline.push(this.geometries[i].coords);
}
return { 'geometry': { 'type': 'MultiLineString', 'coordinates': multiline }, 'type': 'Feature', 'properties': this.properties };
}
};
Arc.prototype.strip = function() {
var s = H.geo.Strip ? new H.geo.Strip() : new H.geo.LineString();
for (var i = 0; i < this.geometries.length; i++) {
if (this.geometries[i].coords.lenght !== 0) {
var coords = this.geometries[i].coords;
for (var j = 0; j < coords.length; j++) {
var p = new H.geo.Point(coords[j][1], coords[j][0]);
s.pushPoint(p);
}
}
}
return s;
}
var GreatCircle = function(start, end, properties) {
if (!start || start.x === undefined || start.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
if (!end || end.x === undefined || end.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
this.start = new Coord(start.x, start.y);
this.end = new Coord(end.x, end.y);
this.properties = properties || {};
var w = this.start.x - this.end.x;
var h = this.start.y - this.end.y;
var z = Math.pow(Math.sin(h / 2.0), 2) + Math.cos(this.start.y) * Math.cos(this.end.y) * Math.pow(Math.sin(w / 2.0), 2);
this.g = 2.0 * Math.asin(Math.sqrt(z));
if (this.g == Math.PI) {
throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
} else if (isNaN(this.g)) {
throw new Error('could not calculate great circle between ' + start + ' and ' + end);
}
};
#map {
width: 95%;
height: 450px;
background: grey;
}
<script src="https://heremaps.github.io/maps-api-for-javascript-examples/test-credentials.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Polyline on the Map</title>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="../template.css" />
<script type="text/javascript" src='../test-credentials.js'></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
</head>
<body id="markers-on-the-map">
<div id="map"></div>
<script type="text/javascript" src='demo.js'></script>
</body>
</html>
this is simple: the var GreatCircle is not defined yet but program code invoke GreatCircle
We moved some parts of code through each together
but any way there is error GreatCircle doesn't have 'arc' property defined.
there is this module https://demo.support.here.com/javascripts/examples/v31/geodesic-polyline.js
but you needs Bézier curve: https://en.wikipedia.org/wiki/B%C3%A9zier_curve
I found some implementation on this https://habr.com/ru/post/163073/ - (but in russian) - there a curve consists from lines based on 100 points (step 0.01)
flow = getBezierCurve(new Array(arr[0], arr[1], arr[2], arr[3]), 0.01);
drawLines(ctx, flow, 10);
In JS API wasn't implemented functionality of like Bézier curve
but search in google on "bezier curve javascript example code" - if you get points of curve you can use in JS API map.screenToGeo every point and plot it on the map

Google Earth Network Link with Fusion Heat Map

So I have created a heat map in Fusion Tables, obtained a API key and copied the code into the link in Google Earth Network Link add. I did not get the resulting heat map to populate in Google Earth. I've set the sharing to Public and Unlisted but neither bears any fruit. Can anyone tell me what steps I am missing to get the heat map to populate in Google Earth?
Here is my obtained code (XXX'd out my API key)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"></meta>
<title>Copy of Heat Map - Google Fusion Tables</title>
<style type="text/css">
html, body, #googft-mapCanvas {
height: 300px;
margin: 0;
padding: 0;
width: 500px;
}
</style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?v=3&libraries=visualization"></script>
<script type="text/javascript">
if (window.location.protocol == "file:") {
alert('This script only works when loaded from a web server,' +
' not from a file on your computer.');
}
function ftOnLoadClientApi() {
gapi.client.setApiKey('XxxXxxXxxxXx');
}
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=ftOnLoadClientApi">
</script>
<script type="text/javascript">
var map;
function loadApi() {
gapi.client.load('fusiontables', 'v1', initialize);
}
function initialize() {
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '100%' : '500px';
mapDiv.style.height = isMobile ? '100%' : '300px';
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(28.070831120253633, -82.434892289917),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var query = 'select col2, col1 from 1-6pqmYvsmKGwt9IZcpIxFUmyYwmumoMAtMrE8pMe limit 1000';
var request = gapi.client.fusiontables.query.sqlGet({ sql: query });
request.execute(function(response) {
onDataFetched(response);
});
}
function onDataFetched(response) {
if (response.error) {
alert('Unable to fetch data. ' + response.error.message +
' (' + response.error.code + ')');
} else {
drawHeatmap(extractLocations(response.rows));
}
}
function extractLocations(rows) {
var locations = [];
for (var i = 0; i < rows.length; ++i) {
var row = rows[i];
if (row[0]) {
var lat = row[0];
var lng = row[1];
if (lat && lng && !isNaN(lat) && !isNaN(lng)) {
var latLng = new google.maps.LatLng(lat, lng);
locations.push(latLng);
}
}
}
return locations;
}
function drawHeatmap(locations) {
var heatmap = new google.maps.visualization.HeatmapLayer({
dissipating: true,
gradient: [
'rgba(102,255,0,0)',
'rgba(147,255,0,1)',
'rgba(193,255,0,1)',
'rgba(238,255,0,1)',
'rgba(244,227,0,1)',
'rgba(244,227,0,1)',
'rgba(249,198,0,1)',
'rgba(255,170,0,1)',
'rgba(255,113,0,1)',
'rgba(255,57,0,1)',
'rgba(255,0,0,1)'
],
opacity: 0.49,
radius: 20,
data: locations
});
heatmap.setMap(map);
}
google.maps.event.addDomListener(window, 'load', loadApi);
</script>
</head>
<body>
<div id="googft-mapCanvas"></div>
</body>
</html>

Google Charts : change region color on click

I'm working on a map using Google Charts.
When someone clicks on a region every region change opacity while the clicked one keeps the original color.
It's exactly like this but for regions:
https://developers.google.com/chart/interactive/docs/gallery/columnchart#creating-material-column-charts
Do you guys know where to begin ? I can retrieve the current item selected, it's easy... but now I have to retrieve every item but the selected one and change the color of them.
Thanks in advance.
using the colorAxis config option,
assign a higher number to the selected region
reset the remaining regions back to zero
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Country', 'Popularity'],
['England', 0],
['Wales', 0],
['Scotland', 0],
['Ireland', 0],
]);
var options = {
colorAxis: {
minValue: 0,
colors: ['#FFEBEE', '#B71C1C']
},
region: 'GB',
resolution: 'provinces'
};
var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));
google.visualization.events.addListener(chart, 'select', function () {
for (var i = 0; i < data.getNumberOfRows(); i++) {
if (i === chart.getSelection()[0].row) {
data.setValue(i, 1, 100);
} else {
data.setValue(i, 1, 0);
}
}
chart.draw(data, options);
});
chart.draw(data, options);
},
packages:['geochart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://www.google.com/jsapi"></script>
<div id="chart_div"></div>

fusion table with sidebar - error in query

I tried to make a map with a sidebar by using a fusion table. I adapted the codes I found on stackoverflows.com but I see an error message : Error in query: Could not parse query.
What is wrong ? The codes are as below:
<!DOCTYPE html>
<html>
<head>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map {
margin: 0;
padding: 0;
height: 100%;
}
</style>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<!--Load the AJAX API-->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" >
var tableId = "1zELV0V48On-5c8aqKM_PD2cMQtfy4hByyR5o8sQ";
google.load('visualization', '1', {'packages':['table']});
var map;
var markers = [];
var infoWindow = new google.maps.InfoWindow();
function initialize() {
var istanbul = new google.maps.LatLng(41.049, 28.991);
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: istanbul,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var FTlayer = new google.maps.FusionTablesLayer({query:{from:tableId}, map:map});
var queryStr = "SELECT hotels, location, phone, url FROM "+tableId+" ORDER BY hotels";
document.getElementById('info').innerHTML += queryStr +"<br>";
var queryText = encodeURIComponent(queryStr);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
query.send(getData);
}
function getData(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var dt = response.getDataTable();
var side_html = '<table style="border-collapse: collapse" border="1" \
cellpadding="5"> \
<thead> \
<tr style="background-color:#e0e0e0"> \
<th>Hotels</th> \
</tr> \
</thead> \
<tbody>';
document.getElementById('info').innerHTML += "rows="+dt.getNumberOfRows()+"<br>";
for (var i = 0; i < dt.getNumberOfRows(); i++) {
var location = dt.getValue(i,1);
var phone = dt.getValue(i,2);
var hotels = dt.getValue(i,0);
var url = dt.getValue(i,3);
var pt = new google.maps.LatLng(lat, lng);
var html = "<strong>" + hotels + "</strong><br />";
side_html += '<tr> \
<td>' + hotels + '</td> \
</tr>';
createMarker(pt, html);
}
side_html += '</tbody> \
</table>';
document.getElementById("side_bar").innerHTML = side_html;
}
function createMarker(point,info) {
var iconURL = 'tools/pinred.png'; var iconSize = new google.maps.Size(29,60);
var iconOrigin = new google.maps.Point(0,0); var iconAnchor = new google.maps.Point(15,60);
var myIcon = new google.maps.MarkerImage(iconURL, iconSize, iconOrigin, iconAnchor);
var shadowURL = 'tools/pinred.png'; var shadowSize = new google.maps.Size(63, 60);
var shadowOrigin = new google.maps.Point(0, 0); var shadowAnchor = new google.maps.Point(15, 60);
var myShadow = new google.maps.MarkerImage(shadowURL, shadowSize, shadowOrigin, shadowAnchor);
var iconShape = [18,0,20,1,22,2,23,3,24,4,25,5,26,6,27,7,27,8,28,9,28,10,28,11,28,12,28,13,28,14,28,15,28,16,28,17,28,18,28,19,27,20,27,21,26,22,26,23,25,24,24,25,23,26,21,27,20,28,16,29,21,31,21,32,21,33,21,34,21,35,20,36,20,37,20,38,19,39,19,40,19,41,18,42,18,43,18,44,18,45,17,46,17,47,17,48,17,49,16,50,16,51,16,52,15,53,15,54,15,55,14,56,14,57,14,58,14,59,13,59,13,58,13,57,13,56,12,55,12,54,12,53,12,52,11,51,11,50,11,49,11,48,11,47,10,46,10,45,10,44,10,43,9,42,9,41,9,40,9,39,9,38,8,37,8,36,8,35,8,34,8,33,7,32,7,31,12,29,9,28,7,27,6,26,4,25,3,24,3,23,2,22,1,21,1,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,1,9,1,8,2,7,2,6,3,5,4,4,5,3,6,2,8,1,10,0,18,0];
var myMarkerShape = {
coord: iconShape,
type: 'poly'
};
var myMarkerOpts = {
position: point,
map: map,
icon: myIcon,
shadow: myShadow,
shape: myMarkerShape
};
var marker = new google.maps.Marker(myMarkerOpts);
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infoWindow.close();
infoWindow.setContent(info);
infoWindow.open(map,marker);
});
}
function myclick(num) {
google.maps.event.trigger(markers[num], "click");
}
</script>
<body onload="initialize();">
<table border="1"><tr><td>
<div id="map_canvas" style="width:600px;height:500px;"></div>
</td><td>
<div id="side_bar" style="width:200px;height:300px; overflow: auto;"></div>
</td></tr></table>
<div id="info"></div>
</body>
</html>
Your query is wrong, you are querying for:
var queryStr = "SELECT hotels, location, phone, url FROM "+tableId+" ORDER BY hotels";
The columns in your table have different names (the first character is upper case).
This works for me:
var queryStr = "SELECT Hotels, Location, Phone, Url FROM "+tableId+" ORDER BY Hotels";
But then you will have other problems as your locations don't have coordinates (lat and lng are undefined), you will need to geocode them externally and add a column or two for the geographic coordinates for this to work (you can try geocoding the location on click, but that is not the best way to do it).
proof of concept for geocoding on click - issue: some of the addresses geocode to different locations than are in the FusionTable or don't geocode at all.
The phone number is null because in your table you have that column defined to be of type number, but it contains text.
proof of concept using lat/lng columns in (a copy of) your new table (changed the "phone" column from number to text).

How to utilize google map MarkerCluster to catch Polygon rather than marker ?

everyone!
How to utilize google map MarkerCluster to catch Polygon rather than Marker ?
My program has about 20,000 markers on Google Map, and it becomes very slow when the data is loading into the map. Then I use JS code to draw one polygon as the replacement of marker. It would run faster. Maybe the PNG image loading for markers exercises negative influence on speed.
Finally, I read this article
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/examples.html
The function 'MarkerCluster' is great. However, it can be only used on the aspect of Google Marker.
var markerClusterer = new MarkerClusterer(map, **markerArray**)
So is there some solution for putting polygon into this cluster mechanism ?
Any help would be greatly appreciated !
I tentatively made an example.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
<style>
html, body, #map_canvas {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript'>
var mapCanvas;
function initalize() {
// Creating a map
var mapDiv = document.getElementById("map_canvas");
mapCanvas = new google.maps.Map(mapDiv, {
mapTypeId : google.maps.MapTypeId.ROADMAP
});
// Generate bunch of path data
var sw = new google.maps.LatLng(-19.448292, -152.012329);
var ne = new google.maps.LatLng(76.150236, 58.925171);
var bounds = new google.maps.LatLngBounds(sw, ne);
mapCanvas.setCenter(bounds.getCenter());
mapCanvas.setZoom(3);
var baseLat, baseLng, category, json = [], path;
for (var i = 0; i < 100; i++) {
baseLat = Math.random() * (ne.lat() - sw.lat()) + sw.lat();
baseLng = Math.random() * (ne.lng() - sw.lng()) + sw.lng();
path = [
new google.maps.LatLng(baseLat, baseLng),
new google.maps.LatLng(baseLat + 1, baseLng + 1),
new google.maps.LatLng(baseLat, baseLng + 2)
];
json.push(path);
}
var bounds, polyList = [];
for (var i = 0, length = json.length; i < length; i++) {
var polyline = createPolygon(json[i]);
polyList.push(polyline);
}
var clusterer = new MarkerClusterer(mapCanvas, polyList);
}
function createPolygon(path) {
var polygon = new google.maps.Polygon({
path : path,
strokeOpacity : 1,
strokeColor : "red"
});
var lastPath = null,
lastCenter = null;
polygon.getPosition = function() {
var path = this.getPath();
if (lastPath == path) {
return lastCenter;
}
lastPath = path;
var bounds = new google.maps.LatLngBounds();
path.forEach(function(latlng, i) {
bounds.extend(latlng);
});
lastCenter = bounds.getCenter()
return lastCenter;
};
return polygon;
}
google.maps.event.addDomListener(window, "load", initalize);
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>

Resources