Create a map of Canada and USA with Datamaps in a single page - datamaps

I am using Datamaps to create a map of Canada and USA. I saw the tutorial and/or examples in its website and I saw a "USA map only" example. And I did that:
<script>
var addUSA = new Datamap({
scope: 'usa',
element: document.getElementById('usa-map'),
geographyConfig: {
highlightOnHover: false,
borderColor: '#006298',
borderWidth: 0.8,
popupTemplate: function(geography, data) {
return "<div class='hoverinfo'><strong>" + data.info + "</strong></div>";
}
},
dataUrl: 'data.json',
dataType: 'json',
data: {},
fills: {
defaultFill: '#FFFFFF'
}
});
addUSA.labels();
</script>
So I assume that you can also create a "Canada map only". But the problem is, I don't know how to combine two countries.
I aim for labels, the hover-info and json that's why I'm using Datamaps.

So I've found this URL entitled Custom Map Data in Datamaps by Mark DiMarco and I used and tried copying what he had done. On that link, he created a map of Afghanistan which was not included in his main examples on Datamaps website. But instead of one country, we will combine two countries custom map using Datamaps. This is an experiment I've made but I hope this will be the answer to your problem
First, he created a custom topo json for Afghanistan. He published a tutorial on how to create custom map data but I think I don't have an access 'cause I'm getting 404 or he took it down. Going back, the code he used for that custom topo json can also be found in his other works located at "More Versions" link in Datamaps website. You just need to look for the country/ies you need to make a custom topo json. On your end, look for datamaps.afg.js and datamaps.usa.js; and get the json.
I only have 1 reputation and I am limit with two URLs. Just visit this GitHub site where I put those two custom topo json for Canada and USA.
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Canada and USA</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://rawgithub.com/markmarkoh/datamaps/master/dist/datamaps.none.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<!-- CANADA -->
<h1>CANADA</h1>
<div id="canada"></div>
<!-- USA -->
<h1>USA</h1>
<div id="usa"></div>
</body>
</html>
CSS
#canada {
border: 1px solid #000000;
height: 450px;
width: 400px;
}
#usa {
border: 2px solid #EDA552;
height: 400px;
width: 500px;
}
JQUERY
$(function() {
var canadaMap = new Datamap({
element: document.getElementById('canada'),
geographyConfig: {
dataUrl: 'canada.topo.json'
},
scope: 'canada',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-95, 71])
.scale(200)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
var USAmap = new Datamap({
element: document.getElementById('usa'),
geographyConfig: {
dataUrl: 'usa.topo.json'
},
scope: 'usa',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-120, 54])
.scale(250)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
});
Working code here => JS FIDDLE

Related

COG on Google Cloud Storage - error using OpenLayers without NodeJS

I'm playing with OpenLayers to display COG files uploaded on GCS.
Using the NodeJS, an index.html and a main.js files, then building with Parcel (or others), everything works fine.
When I tried to skip using NodeJS, coding an HTML files with the CDN imports, and the inline JavaScript, it looks like OpenLayers is not able to retrieve all the needed dependencies. In particular in the network request/response, I have:
Request URL: https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.1/build/231.ol.js
Request Method: GET
Status Code: 403
Remote Address: 151.101.241.229:443
Referrer Policy: strict-origin-when-cross-origin
and if I try to hit directly the URL in the Browser:
https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.1/build/231.ol.js
I got:
Package size exceeded the configured limit of 50 MB. Try https://github.com/openlayers/openlayers.github.io/tree/master/en/v6.14.1/build/231.ol.js instead.
Why?
Below the content of the HTML file I stored on GCS (layer styling omitted),
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>COG on Google Cloud Storage</title>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.14.0/css/ol.css">
<style>
html, body {
margin: 0;
height: 100%;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var cogSource = new ol.source.GeoTIFF (
{
normalize: true,
sources: [
{
url: 'https://storage.googleapis.com/fao-gismgr-cache/TEST/L1_AETI_21.tif',
min: -9999,
max: 16000
}
],
transition: 0
}
);
var cogLayer = new ol.layer.WebGLTile (
{
source: cogSource
}
);
var cogView = new ol.View (
{
projection: 'EPSG:4326',
minZoom: 0,
maxZoom: 12,
center: [0,0],
zoom: 4
}
);
var map = new ol.Map({
target: 'map',
maxTilesLoading: 32,
layers: [cogLayer],
view: cogView
});
</script>
</body>
</html>
The COG and HTML file are on a public GCS bucket.
To test, I use Chrome with web-security disabled (CORS policies)
open -na Google\ Chrome --args --user-data-dir=/tmp/temporary-chrome-profile-dir --disable-web-security --disable-site-isolation-trials
Could you help me?
Thanks in advance,
Davide
Thanks #Mike, I was having the same problem and tried your solution both with local and remote files and it worked without any problem.
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.12.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.12.0/css/ol.css">

Is it possible to highlight some states of US and some states of Canada in GeoChart?

Region 1
Region 2
I am trying to add map on a location page and I want to select some states from US and Canada in different regions when user hovers on a specific part of the map. Basically a map of North and South America(Brazil and Argentina) with different regions.
In the following code I attempted to highlight 2 US states and 1 Canada state. But I get "Requested map does not exist" error when I try to highlight states on a continent.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
'packages': ['geochart'],
'mapsApiKey': 'AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY'
});
google.charts.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['State', 'Offices'],
['New Jersey', 2],
['Alabama', 3],
['Toronto', 1]
]);
var options = {
region: '019', // Americas Continent
colorAxis: {
colors: ['#00853f', 'black', '#e31b23']
},
backgroundColor: '#81d4fa',
datalessRegionColor: 'gray',
defaultColor: '#f5f5f5',
resolution: 'provinces'
};
var chart = new google.visualization.GeoChart(document.getElementById('geochart-colors'));
chart.draw(data, options);
};
</script>
</head>
<body>
<div id="geochart-colors" style="width: 100%; height: 100%;"></div>
</body>
</html>
Is it possible to do so? How can I achieve something like the image attached?
I would really appreciate your time and help. Thank you!

Google Chart not showing info from google sheet unless sheet is accessed

I have a bunch of sheets that I'm using to store the marks of my students for a couple of my classes. On my website, I am using HTML and Google's Query Language to pull info from the sheets (2 columns...the students numbers of each student and their mark). If I've edited the spreadsheet on any given day, the chart shows up properly, but if I have not edited it that day then it shows incorrect values for their marks or old values for their marks. I think it's something to do with the sheets, but I can't be sure.
Here's the HTML code from my site:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", '1', {packages:['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var query = new google.visualization.Query(
'https://docs.google.com/spreadsheet/ccc?key=14mPTcYYraMyuBnEFSJW74ZQ3xjWSSOuDqoxB2VrvAvw&tq=select%20D%2C%20E%20where%20D%3C%3E%22Avatar%22%20order%20by%20E%20desc%20label%20E%20%22Experience%20Points%22');
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var chart = new google.visualization.ColumnChart(document.getElementById('columnchart'));
var options = {'title':'Experience Points',
'width':'927',
'height':'510',
'chartArea': {'left':'50', 'width':'90%'},
legend: { position: 'top', maxLines: 2 },
hAxis: {showTextEvery: 1, slantedText: true, slantedTextAngle: 90, viewWindow:{max:33}},
bar:{groupWidth: '60%'},
isStacked: true};
chart.draw(data, options);
}
</script>
<title>Data from a Spreadsheet</title>
</head>
<body>
<span id='columnchart'></span>
</body>
</html>
Any ideas? By the way, the sheet is set so that anyone on the internet can find and view.

How do you draw a line between two points in google geo chart?

I want to draw a line between two points (zip codes in this case) on map using googles geochart function. Is that possible? For example, I would like to have a line drawn between zip 07206 and 78746 below:
<html>
<head>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load('visualization', '1', { 'packages': ['geochart'] });
google.setOnLoadCallback(drawMarkersMap);
function drawMarkersMap() {
var data = google.visualization.arrayToDataTable([
['Region', 'Total'],
['07206', 500],
['78746', 250],
['90040', 1000],
]);
var options = {
sizeAxis: { minValue: 0, maxValue: 100 },
region: 'US', // United States
resolution: 'provinces',
displayMode: 'markers',
colorAxis: { colors: ['#e7711c', '#4374e0'] } // orange to blue
};
var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));
chart.draw(data, options);
};
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
VectorWorkz GeoChart allows you to draw lines between two points, it enables animation for the lines and also you can customize the look and feel of the connection lines. It is briefly illustrated in this online sample(Click on "Flight Routes" in the left menu).
I had a need for this just recently. Fairly simple solution is to draw 0px points (markers) on the map and then do a jQuery loop through the points and create a element with the x1 / y1 values of the first point, the x2/y2 values of the second point, etc.

showing all fields in a Dojo Data Grid with dojo.store.JsonRest

I have a Dojo Data Grid for displaying contact information that is showing values for only two columns: "model" and "pk". The other columns are blank, probably because the JSON response from the server puts the other name/value pairs inside of "fields":
[{"pk": 1, "model": "accounting.contacts", "fields": {"mail_name": "Andy", "city": "Grand Rapids", "zip": "49546", "country": "US", "state": "MI"}}]
What is the best way to get all my fields to show up in the grid?
Here's the relevant view in Django:
def contacts(request):
json_serializer = serializers.get_serializer("json")()
json_contacts = json_serializer.serialize(Contacts.objects.all(), ensure_ascii=False)
return HttpResponse(json_contacts, mimetype="application/json")
And here's my Dojo page:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"
data-dojo-config="isDebug: true,parseOnLoad: true">
</script>
<script type="text/javascript">
dojo.require("dojo.store.JsonRest");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ObjectStore");
dojo.ready(function(){
objectStore = new dojo.store.JsonRest({target:"/contacts/"});
//alert(objectStore);
dataStore = new dojo.data.ObjectStore({objectStore: objectStore});
//alert(dataStore);
layoutGridContacts = [{
field: 'mail_name',
name: 'Name',
width: '200px'
},
{
field: 'model',
name: 'DB Table',
width: '100px'
...
}];
gridContacts = new dojox.grid.DataGrid({
query: {
name: '*'
},
store: dataStore,
clientSort: true,
structure: layoutGridContacts
}, dojo.byId("containerGridContacts"));
gridContacts.startup();
});
</script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css" />
<style type="text/css">
#import "http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/grid/resources/Grid.css";
#import "http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/grid/resources/claroGrid.css";
.dojoxGrid table {margin: 0; } html, body { width: 100%; height: 100%;
margin: 0;}
</style>
</head>
<body class="claro">
<div id="containerGridContacts" style="width: 100%, height: 100%;">
</div>
</body>
Thanks.
This is really a question of, "How do I interact with a javascript object?" Given the JSON in your question, and assuming you assigned it to the variable obj, you could access mail_name with obj[0]['fields']['mail_name'] or using dot notation, obj[0].fields.mail_name. I haven't used Dojo, but I'd wager you just need to set fields.mail_name as the field in layoutGridContacts.
I was able to get the server to produce a JSON response that does not contain nested objects, so the Dojo Store was able to use it. To do this I changed my view to:
def contacts(request):
all_contacts = list(iter(Contacts.objects.values()))
json_contacts = simplejson.dumps(all_contacts)
return HttpResponse(json_contacts, mimetype="application/json")
Use "fields." in front of your field identifier to access the properties inside fields:
layoutGridContacts = [{
field: 'fields.mail_name',
name: 'Name',
width: '200px'
},
...
You can use formatter method to retrieve the data. For your example it will be something like below
{name:"Name",
field: "fields",
width: "20%",
cellStyles:"background-color:#e3690b;",
formatter: function(field){
if(!field){return;}
return field.mail_name;
}
}