HighMaps with drilledDown - javascript

I am using highmaps in my application with drilledown enabled, it works fine for the sample data given for usa.
But it does not work with the data for srilanka. what could be the issue?
Here is my code:
$('#container').highcharts('Map', {
chart : {
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
mapKey = 'countries/lk/' + e.point.drilldown + '-all',
// Handle error, the timeout is cleared on success
fail = setTimeout(function () {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function () {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function () {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function (i) {
this.value = i;
console.log(i);
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, { text: e.point.name });
},
drillup: function () {
this.setTitle(null, { text: 'Sri Lanka' });
}
}
}
JSFiddle Link

The drilldown data doesn't exist in the Highmaps Map Collection for Sri Lanka. If you scroll down the page you can see that at the moment the only countries with data below country level (e.g. admin2 level) are Canada, Germany, France, Netherlands, Norway, USA.
When you click a district the fiddle is trying to retrieve data from a corresponding URL:
mapKey = 'countries/lk/' + e.point.drilldown + '-all',
and for Sri Lanka it is failing because the JS file for each district does not exist.
There is more info in the Highmaps docs about creating maps:
Highmaps loads its maps from GeoJSON, an open standard for description
of geographic features. Most GIS software supports this format as
export from for instance Shapefile or KML export. Read more in the API
reference and see the live demo.
There are three basic sources for your map:
Use our Map collection. Read the tutorial article on the map
collection to get started.
Find an SVG map online and convert it using
our (experimental) online converter.
Create your own map from scratch
using an SVG editor, then convert them online. Read our tutorial on
Custom maps for Highmaps.
and about the Highmaps Maps Collection:
For your convenience, Highmaps offers a free collection of maps,
optimized for use with Highmaps. For common maps, it saves you the
trouble of finding or drawing suitable SVG or GeoJSON maps.
For Admin2, we have only compiled selected countries, and these maps
are created from national files with their own license which is
specified on the SVG map and in the other format files as meta data.
If you miss your country, please contact us and we'll try to find a
suitable shapefile and generate more maps.

Related

Finding Zoom level from ArcGIS WebMap

I am loading a Webmap made with ArcGIS online into a simple viewer app. I want the position and zoom level to match the original.
I can get the center from map.portalItem.extent, but how do I find the zoom?
app.map=new WebMap({ portalItem: { id: myId }});
app.map.load().then(function() {
app.center[0]=app.map.portalItem.extent.center.longitude;
app.center[1]=app.map.portalItem.extent.center.latitude;
app.zoom=???
});
...
app.mapView.when(function() { app.activeView.goTo({ center:app.center, zoom: app.zoom }) });
The extent is stored in the WebMap (not the zoom level) - but that's ok because the goTo() function you're using takes many different inputs, including an extent. So just change your code to something like this:
app.map=new WebMap({ portalItem: { id: myId }});
app.map.load().then(function() {
app.extent=app.map.portalItem.extent;
});
...
app.mapView.when(function() { app.activeView.goTo(app.extent) });

Display data from JSON on hover of SVG path?

I am working on a SVG map of the US and I would like to display a small info window pointing to each state when you hover over it that shows the population, similar to the info windows on Google Maps. Unfortunately I'm not very good with JSON so I'm stuck at this point.
Currently I have the SVG map of the US up and the fill color changes on hover via CSS. I have a sample group of JSON data and wondering how I can incorporate it into my map so that it displays the population on hover.
Here's an example of the JSON data:
[
{
"id":"AL",
"population":"253045"
},
{
"id":"AR",
"population":"1529923"
},
{
"id":"AZ",
"population":"352416t"
}
]
There's quite a bit of HTML due to the SVG paths, so I won't paste that here, but you can see what I have so far on this JSFiddle
To get info about the hovered state, first put your info in an array, so it can be accessed:
var info = [
{
"id":"AL",
"population":"253045"
},
{
"id":"AR",
"population":"1529923"
},
{
"id":"AZ",
"population":"352416t"
}
]
Then you can get info from your array by filtering it by the id key using filter:
info.filter(function(state) {return state.id === currState});
Here is an example where you get the population of the hovered state:
$('path').hover(function() {
var currState = $(this).attr('id');
var currStateInfo = info.filter(function(x) {return x.id == currState});
if (currInfo[0])
console.log(currInfo[0].population);
});
Here is a working example: https://jsfiddle.net/4tasLo6k/

OnClick in an angular-openlayers-directive marker

Thats it I want to create an onclick event on my marker, I'm using angular-openlayers-directive.
So far I've been able to make some markers show up, but I'm unable to get them after a click event.
I would like to perform some actions with these markers custom properties like name, remarks, etc. But it seems too hard to achieve this with openlayers 3.
<openlayers ol-center="ven" height="100vh">
<ol-layer ol-layer-properties="wms">
<ol-marker ng-repeat="marker in markers"
lat="marker.lat"
lon="marker.lon"
></ol-marker>
</ol-layer>
</openlayers>
So how could I handle an onclick event on these markers and get all their info, or a reference to the javascript object "marker" itself.
I wasn't sure if you wanted to have the click on the popover or the marker itself. Below there are instructions for both. Use the Plunker link at the bottom to see a working demo of both options.
To Register Click on Marker Popover:
If you take a look at the directive, you can see that the marker template uses ng-transclude, so you can do the following:
Markup:
<ol-marker ol-marker-properties="santiago" >
<p ng-click="showDetails(santiago)">Santiago de Compostela</p>
</ol-marker>
In your controller:
$scope.showDetails = function(id) {
alert('lat: '+ id.lat+', '+'lon: '+id.lon);
};
Here I'm passing in the marker object to the showDetails function. When you click the popover label for Santiago de Compostela in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
To Register Click on the Marker:
You can add an onClick property to the marker object as follows:
In your controller:
finisterre: {
lat: 42.907800500000000000,
lon: -9.265031499999964000,
label: {
show: false,
},
onClick: function (event, properties) {
console.log(properties);
alert('lat: '+ properties.lat+', '+'lon: '+properties.lon);
}
}
When you click the marker associated with finisterre in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
NOTE:
I could only get this to work though under the following conditions:
The marker object must have a label property defined
The show property of the label must be set to false.
The ol-marker html element must have some transcluded content OR the message property must be set in the marker label object.
I was able to use CSS to prevent the popover from displaying as you can see in the demo, but it seems a little hacky. If you want the popover to display on click as well, you're all set, just remove the css hidden class I added and add your pop-over html.
Plunker Demo
I just got this working today as it happens. What I am doing for now is adding the properties to my markers once I get them from mongo.
function addMarkerProperties ()
// needed to enable click events on a marker!
// Have a label property defined for the marker.
// Have the show property of the label set to false.
// Have some transcluded content in the marker.
{
for (var i = $scope.markers.length - 1; i >= 0; i--) {
$scope.markers[i].onClick = function (event, properties) { console.log('Clicked a marker'); console.log(this); console.log(properties); };
$scope.markers[i].label = {
// Note: Duplication of data here # message. Fix this later.
"message": $scope.markers[i].name,
"show": false,
"showOnMouseOver": false
};
};
}
Once the markers have all the properties they need. It just sort of works but I do have a bug to iron out as well where the marker titles repeat above the map for.... reasons.
As you click the markers the words disappear.
With the latest release (April 6 2016) of the angular-openlayers-directive library (correct) ngClick-handling seems to be implemented. After a bit of searching I came up with the following solution:
The HTML (simplified):
<html ng-controller="mapController">
<openlayers width="100%" height="400px">
<ol-marker ng-repeat="marker in markers" ol-marker-properties="marker" ng-click="showDetails(marker)"></ol-marker>
</openlayers>
</html>
The Angular Javascript for the map controller (expects that your API endpoint called '/api/markerlist' returns a list of JSON objects with the fields: 'latitude', 'longitude'):
$scope.markers = [];
$scope.initializeMarkers = function() {
var markerList = $http.get("yoursite/api/markerlist")
.succes( function(result) {
angular.forEach(result, function(value, key) {
$scope.markers.push({
lat: value.latitude,
lon: value.longitude,
label: {
message: "Your message",
show: false,
showOnMouseOver: false
}
});
});
}
function showDetails(marker) {
alert('Clicked a marker on the map');
console.log(marker);
}
Finally, be sure that you have included the angular-openlayer-directive CSS, so the messages for the labels are not visible.

JVector Map onRegionClick Event

So in JVector map I need a function that has each region linked to a URL. So if you click on South Africa it will take you to a page with information about South Africa. I know to start with onRegionClick: function () but where to go from there is a mystery to me.
Well, as the documentation says:
onRegionClick
Callback function which will be called when the user
clicks the region path. Region code will be passed to the callback as
argument.
So each time a region is clicked, the region's code is passed to the handler. Then if the code is all you need on your next page, you could just pass that as is in the query string.
onRegionClick: function (event, code) {
window.location.href = "yourpage?regionCode=" + code
},
If you need the actual name of the region instead of the code, there is a handy getRegionName method that you could use.
var regionName = map.getRegionName(code);
You can Use this html body
<div class="map_jvector"></div>
and the javascript
<script>
$('.map_jvector').vectorMap({
map: 'africa',
backgroundColor: '#ffffff',
onRegionClick:function(event, code){
var name = (code);
window.location.replace("http://your url address/"+code+"");
},
series: {
regions: [{
values: gdpData,
scale: ['#003471','#009eef', '#0076a3','#0d004c','#f26522','#9e0039'],
normalizeFunction: 'polynomial'
}]
},
onRegionTipShow: function(e, el, code){
el.html(el.html());
}
});
</script>
Change link "your url address" to your link address & the "+code+" is region of JVector Map, if you click on the map province area, it will be to link the region.

Data from json file for use with CHAPS timeline

I'm trying to use the CHAP links library timeline (http://almende.github.io/chap-links-library/timeline.html).
Example17 is using JSON, but it's in the html file itself. I'd like to use an external JSON file sitting on the web server instead.
Here's my example.json:
{"timeline":[
{
"start":"2013,7,26",
"end":"2013,7,26",
"content": "Bleah1"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah2"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah3"
},
{
"start":"2013,7,26",
"end":"2013,8,2",
"content": "Bleah4"
}
]}
I added this:
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
And here's the modified function:
// Called when the Visualization API is loaded.
function drawVisualization() {
// Create a JSON data table
$.getJSON('example.json', function(jsondata) {
data = jsondata.timeline;
});
// specify options
var options = {
'width': '100%',
'height': '300px',
'editable': true, // enable dragging and editing events
'style': 'box'
};
// Instantiate our timeline object.
timeline = new links.Timeline(document.getElementById('mytimeline'));
function onRangeChanged(properties) {
document.getElementById('info').innerHTML += 'rangechanged ' +
properties.start + ' - ' + properties.end + '<br>';
}
// attach an event listener using the links events handler
links.events.addListener(timeline, 'rangechanged', onRangeChanged);
// Draw our timeline with the created data and options
timeline.draw(data, options);
}
Anyone who can tell me what I'm doing wrong gets a cookie! :-)
Update: I should specify that it's rendering the timeline div correctly, I'm just getting no data showing up.
Your start and end dates need to be parsed as Date objects for use in the timeline
I stumbled on this post as I was implementing similar functionality.
In version 2.6.1 of timeline.js, around line 3439 where the function links.Timeline.Item is declared, you'll notice a comment relating to implementing parseJSONDate.
/* TODO: use parseJSONDate as soon as it is tested and working (in two directions)
this.start = links.Timeline.parseJSONDate(data.start);
this.end = links.Timeline.parseJSONDate(data.end);
*/
I enabled the suggested code and it all works!* (go to the parseJSONDate function to see which formats are accepted)
*(works insofar as dates appear on the timeline.. I'm not using therefore not testing any selection/removal features, images, or anything like that..)

Categories