I am struggling with Javascript and Leaflet tryind to realize a dashboard.
I am trying to realize a choropleth map following this tutorial.
I need to change dynamically data display on map according to two select menu.
Selects:
<select class="c-select" id="methodSelected" name="methodSelected" required>
</select>
<select class="c-select" id="yearSelected" name="yearSelected" required>
</select>
I am holding changing on selects with
$("#methodSelected").change()
$("#yearSelected").change()
both are declared inside a
$(document).ready(function() {}
In this block I also declare the required variables and functions
var choroplethMap;
var q = d3_queue.queue();
q.defer(d3.json, "final2.geojson");
function ready(GeoJSON) {
...
makePlaceHolderChoroplethMap();
}
makePlaceHolderChoroplethMap is like that
function makePlaceHolderChoroplethMap() {
choroplethMap = L.map('choroplethContainer').setView([51.505, -0.09], 2);
L.tileLayer("url",
{
id: id,
attribution: attribution,
accessToken: accessToken
}
).addTo(choroplethMap);
Now when I will change values with the two select menu I want update map, so I put into $("#yearSelected").change() a call to makeChoroplethMap().
function makeChoroplethMap() {}
Inside this function I put code following tutorial previously linked.
The problem is that when I changed the values with that code I will re-add new layers over others previously added (Geojson, legend and control, as you can see)
So I tryed to leave only binding with data into makeChoroplethMap(),
geojson = L.geoJson(data,
{
style: style,
onEachFeature: onEachFeature
}
).addTo(choroplethMap);
but I recieve an error in info.addTo(choroplethMap); as t is undefined. I think because choroplethMap is not initialized. Map and select work, but controls are not displayed 'cause of error.
For now (I think I breaked something because yesteday worked) also geojson layer overstay over country also if I change values with select (the previously one putted does not go off also I change values).
So my question is: how can re-bind data without re-adding also legend and other control?
Add the legend and the GeoJSON layer once, when you're initializing the map. If you add them in makeChoroplethMap, you'll be re- adding them.
Then, use L.GeoJSON.clearLayers() and the
currently undocumented L.GeoJSON.addData() method to clear/add polygons.
Related
Adding hyperlinks to maps was already addressed here :
amcharts drill-down map countries clickable
But I am wondering what I would need to change if I were to instead add clickable hyperlinks to the states or provinces within the countries in the 'drill down to countries' example?
https://www.amcharts.com/demos/drill-down-to-countries/
For instance, if I were to click on China and view the provinces, how would I assign a URL to its most southern province, Guangxi Zhuang, by using both the methods that you mentioned above?
The ID for that territory is "CN-GX", and can be found in this file :
https://github.com/amcharts/amcharts4-geodata/blob/master/dist/es2015/chinaHigh.js
Thanks for your help!
As indicated in the linked answer, you can set a url propertyField for the PolygonSeries so that it can apply the URL from the data provided to the series. You can combine this with the done event handler in the countrySeries (the drilled down map) to populate the series' data with the desired information based on the loaded geodata url. For example:
countrySeries.mapPolygons.template.propertyFields.url = "url";
countrySeries.geodataSource.events.on("done", function(ev) {
worldSeries.hide();
countrySeries.show();
if (ev.target.url.indexOf('china') != -1) {
countrySeries.data = [{
id: "CN-GX",
url: "https://en.wikipedia.org/wiki/Guangxi"
}];
}
});
Obviously you'll want to make this more robust in your application, but you get the idea.
Demo of your Guangxi scenario
How do I select the list of push pins inside the polygon in bong maps.
In the example below I see the push pins inside the selected polygon get highlighted but is there a code sample that i can see/use where they maybe get a list of push pins details on selection ?
http://bingmapsv8samples.azurewebsites.net/#Select%20Data%20in%20Drawn%20Polygon%20Area
From the source code, it seems to be generated randomly. To get the list
use the variable pinLayer.
var pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(30, map.getBounds(), { color: 'purple' });
pinLayer.add(pushpins);
I have an input in my view:
<label for="map-latitude_input">Latitude {{mapLatitudeInput}}</label>
<input
type="text"
placeholder="00.000"
[(ngModel)]="mapLatitudeInput"
[ngFormControl]="newListingForm.find('mapLatitudeInput')"
id="map-latitude_input"
class="transparent">
and inside my controller I am listening to map drag event from google maps api. On drag I want to update value inside my input and in its associated label. At the moment this looks like this:
//Update coordinates on map drag
map.addListener('drag', (event) => {
this.mapLatitudeInput = map.getCenter().lat();
console.log(this.mapLatitudeInput);
});
Now when I drag a map console keeps outputting correct value as I move it around, however in my view it stays exactly the same. What I also noticed is that if I drag map around and than do some action like select an option in select menu within same form that my input is in, it updates mapLatitudeInput to correct value, i'm not sure why this happens, but thought I'd mention it.
It's perhaps due to ZoneJS. This question could give you some hints: View is not updated on change in Angular2.
From where do you get your map instance. If it's instantiated outside a zone, Angular2 won't be able to detect updates of the mapLatitudeInput attribute.
You could try something like that:
export class MapComponent {
constructor(ngZone:NgZone) {
this.ngZone = ngZone;
}
map.addListener('drag', (event) => {
this.ngZone.run(() =>
this.mapLatitudeInput = map.getCenter().lat();
console.log(this.mapLatitudeInput);
});
});
This question could be also related to your problem: Angular2 child property change not firing update on bound property.
Hope it helps you,
Thierry
I'm having issues setting the visibility of custom Google Maps API v3 overlays. I have a gmaps API page with various overlay, such as polygons, polylines and symbols. Each has an associated text label, made using a custom overlay I adapted from the answer to [this Stack Overflow post][1]
On page load, the actual overlays (polylines, polygons, markers etc - the built in API objects) work correctly. They are displayed based on the default checkbox states. However, the labels are all displayed, regardless if their check box was set by default. If I cycle the checkboxes, everything works correctly.
The overlays are stored as an object called 'overlays' with layout 'description: [polyline, customoverlaylabel]'
Checkbox example code:
<input type="checkbox" id="sun" onclick="refreshCheck('sun')">Sun</input>
This is how I sync whether a display is hidden or visible to the checkbox:
function refreshCheck(overlay) {
var box = document.getElementById(overlay).checked
var lines = overlays[overlay][0]
var text = overlays[overlay][1]
lines.setVisible(box, overlay)
if (box === true) {
text.show()
}
else {
text.hide()
}
}
This code refreshes all the checkmarks, at the end of the javascript head.
var overlayNames = []
for (var k in overlays) overlayNames.push(k)
for (var o in overlayNames) refreshCheck(overlayNames[o])
Here's the hide method of the custom text overlay:
TxtOverlay.prototype.hide = function(){
if (this.div_) {
this.div_.style.visibility = "hidden";
}
}
It's failing the if (this.div_) check, and not doing anything. If I remove the check, it produces an error since this.div_ doesn't exist.
One way to work around it would be to automatically cycle all checkbox states once the page loads (manually doing to solves it). There might be a more fundamental fix. No matter where I attempt to .hide() or .show() a label in my javascript, it doesn't work - it only works when referenced by the checkbox being clicked.
The issue is the moment when you call refreshChecks() .
You assume that the TxtOverlay's already have been added at this time, but that's not the case(that's why the div_'s are still null).
The TXToverlay's (like any object/shape) on a map will be added when the projection of the map is ready.
A possible approach would be:
Instead of using the visible-property of the shapes/markers/etc. to toggle their visibility use the map-property.
The TXTOverlay's are also MVCObject's, you only have to bind the map-property of the TXTOverlay's to the map-property of the related shape.
I know from reading the assoc. Google group that there is not currently an event for clicking a specific point when using the marker map (only regionClick is implemented).
But was reading the docs and noticed the event Select which says:
select Fired when the user clicks a visual entity. To learn what has
been selected, call getSelection(). None
and
setSelection() none Selects the specified chart entities. Cancels any
previous selection. Selectable entities are regions with an assigned
value. A region correlates to a row in the data table (column index is
null). For this chart, only one entity can be selected at a time.
Extended description.
Would I be able to use this to get the entry that was clicked?
Example:
data.addRows([
['Rome', 2761477, 1285.31],
['Milan', 1324110, 181.76],
['Naples', 959574, 117.27],
['Turin', 907563, 130.17],
['Palermo', 655875, 158.9],
['Genoa', 607906, 243.60],
['Bologna', 380181, 140.7],
['Florence', 371282, 102.41]
]);
Somehow get that Milan was clicked? How would I do this? Or am I reading this wrong?
Google API for Geomaps: http://code.google.com/apis/chart/interactive/docs/gallery/geochart.html
Google Group stating there is no click event in Marker mode:
https://groups.google.com/forum/?fromgroups#!topic/google-visualization-api/K8uJoes8ZH0
You need call getSelection function when the select event is called. This function returns an array of objects. Each object have row and column attributes (if any). Use the row and the first column (0) to retrieve the label name (Rome, Milan, ...).
Example (http://jsfiddle.net/VtZQh/):
google.visualization.events.addListener(chart, 'select', function() {
var selection = chart.getSelection()[0];
var label = data.getValue(selection.row, 0);
alert(label);
});
Please refer to documentation to know more about getSelection.