markers appear/disappear a few time when toggleing on - angular-google-maps

I am having an issue with the markers directive. I start by loading it but keeping visible = false. then I toggle it on and the clusters appear, disappear and then reappear. this sometime repeats a few times. I tried setting doRebuildAll to false but then they don't appear at all when toggle visible to true. Here is my markup for the directive. I have it in another directive so that I can just keep a list of different kinds of layers:
'<markers models="mylayer.locations" coords="\'location\'" doRebuildAll="true" idKey="\'id\'" doCluster="true" fit="true" options="mylayer.options" click="\'onClick\'">' +
'<windows show="\'showWindow\'" doRebuildAll="false" disableAutoPan="true" data-ng-if="mylayer.options.clickable" ng-cloak>' +
'<div>hello</div>' +
'</windows>' +
'</markers>'
And the object:
var loc = { latitude: item.Latitude, longitude: item.Longitude };
var marker = { location: loc, label: item.Label, id: item.Id, value: item.Value,showWindow:false };
markers.push(marker);
var layer = new markersFactory(5,'Top 1000 Locations by TIV', markers, true, { visible: false });

Turns out the problem happened when updating from version 1.1.0 of angular-google-maps.js to version 1.1.4. Reverted and it works fine now.

Related

AmCharts AmMap - Set starting location for zoom actions

I would like to use the "zoomToMapObject" method based on a selection on a dropdown menu.
For some reason the start zoom location is the middle of the map and not the set the geoPoint.
(The zooming works but the start location make it look a bit weird.)
My current approach looks like this:
const duration = this.chart.zoomToMapObject(selectedPoloygon, this.countryZoom, true).duration;
setTimeout(() => {
this.chart.homeGeoPoint = geoPoint;
this.chart.homeZoomLevel = this.countryZoom;
}, duration);
this.handleCountrySelection(selectedPoloygon);
Somehow even setting the homeGeoPoint / homeZoomLevel doesn't affect next zoom actions.
**UPDATE: Workaround heavy cost (from 1300 nodes to over 9000) **
I examined the problem a step further. It seems the middle point gets set when I push a new mapImageSeries into the map.
My workarround currently is to draw all points on the map and hide them.
Then after I select a country I change the state to visible.
However this approach is very costly. The DOM-Nodes rises from 1300 to ~ 9100.
My other approach with creating them after a country has been selected AND the zoom animation finished was much more
effective. But due to the map starting every time for a center location it is not viable? Or did I do s.th. wrong?
Here is my current code which is not performant:
// map.ts
export class MapComponent implements AfterViewInit, OnDestroy {
imageSeriesMap = {};
// ... standard map initialization ( not in zone of course )
// creating the "MapImages" which is very costly
this.dataService.getCountries().forEach(country => {
const imageSeriesKey = country.id;
const imageSeriesVal = chart.series.push(new am4maps.MapImageSeries()); // takes arround 1-2 ms -> 300 x 2 ~ 500 ms.
const addressForCountry = this.dataService.filterAddressToCountry(country.id); // returns "DE" or "FR" for example.
const imageSeriesTemplate = imageSeriesVal.mapImages.template;
const circle = imageSeriesTemplate.createChild(am4core.Circle);
circle.radius = 4;
circle.fill = am4core.color(this.colorRed);
circle.stroke = am4core.color('#FFFFFF');
circle.strokeWidth = 2;
circle.nonScaling = true;
circle.tooltipText = '{title}';
imageSeriesTemplate.propertyFields.latitude = 'latitude';
imageSeriesTemplate.propertyFields.longitude = 'longitude';
imageSeriesVal.data = addressForCountry.map(address => {
return {
latitude: Number.parseFloat(address.lat),
longitude: Number.parseFloat(address.long),
title: address.company
};
});
imageSeriesVal.visible = false;
this.imageSeriesMap[imageSeriesKey] = imageSeriesVal;
});
// clicking on the map
onSelect(country) {
this.imageSeriesMap[country].visible = true;
setTimeout( () => {
const chartPolygons = <any>this.chart.series.values[0];
const polygon = chartPolygons.getPolygonById(country);
const anim = this.chart.zoomToMapObject(polygon, 1, true, 1000);
anim.events.on('animationended', () => {});
this.handleCountrySelection(polygon);
}, 100);
});
}
handleCountrySelection(polygon: am4maps.MapPolygon) {
if (this.selectedPolygon && this.selectedPolygon !== polygon) {
this.selectedPolygon.isActive = false;
}
polygon.isActive = true;
const geoPoint: IGeoPoint = {
latitude: polygon.latitude,
longitude: polygon.longitude
};
this.chart.homeGeoPoint = geoPoint;
this.chart.homeZoomLevel = this.countryZoom;
this.selectedPolygon = polygon;
}
}
Thanks to your thorough followup I was able to replicate the issue. The problem you were having is triggered by any one of these steps:
dynamically pushing a MapImageSeries to the chart
dynamically creating a MapImage via data (also please note in the pastebind you provided, data expects an array, I had to change that while testing)
In either step, the chart will fully zoom out as if resetting itself. I'm going to look into why this is happening and if it can be changed, so in the meantime let's see if the workaround below will work for you.
If we only use a single MapImageSeries set in advance (I don't particularly see a reason to have multiple MapImageSeries, would one not do?), that eliminates problem 1 from occurring. Asides from data, we can create() MapImages manually via mapImageSeries.mapImages.create(); then assign their latitude and longitude properties manually, too. With that, problem 2 does not occur either, and we seem to be good.
Here's a demo with a modified version of the pastebin:
https://codepen.io/team/amcharts/pen/c460241b0efe9c8f6ab1746f44d666af
The changes are that the MapImageSeries code is taken out of the createMarkers function so it only happens once:
const mapImageSeries = chart.series.push(new am4maps.MapImageSeries());
const imageSeriesTemplate = mapImageSeries.mapImages.template;
const circle = imageSeriesTemplate.createChild(am4core.Circle);
circle.radius = 10;
circle.fill = am4core.color('#ff0000');
circle.stroke = am4core.color('#FFFFFF');
circle.strokeWidth = 2;
circle.nonScaling = true;
circle.tooltipText = 'hi';
In this case, there's no need to pass chart to createMarkers and return it, so I've passed polygon instead just to demo dynamic latitude/longitudes, I also assign our new MapImage to the polygon's data (dataItem.dataContext) so we can refer to it later. Here's the new body of createMarkers:
function createMarkers(polygon) {
console.log('calling createMarkers');
if ( !polygon.dataItem.dataContext.redDot) {
const dataItem = polygon.dataItem;
// Object notation for making a MapImage
const redDot = mapImageSeries.mapImages.create();
// Note the lat/long are direct properties
redDot.id = `reddot-${dataItem.dataContext.id}`;
// attempt to make a marker in the middle of the country (note how this is inaccurate for US since we're getting the center for a rectangle, but it's not a rectangle)
redDot.latitude = dataItem.north - (dataItem.north - dataItem.south)/2;
redDot.longitude = dataItem.west - (dataItem.west - dataItem.east)/2;;
dataItem.dataContext.redDot = redDot;
}
}
There's no need for the animationended event or anything, it just works since there is no longer anything interfering with your code. You should also have your performance back.
Will this work for you?
Original answer prior to question's edits below:
I am unable to replicate the behavior you mentioned. Also, I don't know what this.countryZoom is.
Just using the following in a button handler...
chart.zoomToMapObject(polygon);
...seems to zoom just fine to the country, regardless of the current map position/zoomLevel.
If you need to time something after the zoom animation has ended, the zoomToMapObject returns an Animation, you can use its 'animationended' event, e.g.
const animation = this.chart.zoomToMapObject(selectedPoloygon, this.countryZoom, true);
animation.events.on("animationended", () => {
// ...
});
Here's an example with all that with 2 external <button>s, one for zooming to USA and the other Brazil:
https://codepen.io/team/amcharts/pen/c1d1151803799c3d8f51afed0c6eb61d
Does this help? If not, could you possibly provide a minimal example so we can replicate the issue you're having?

How to remove firefox 36 badge text

Since firefox 36 it is possible to set badge text for a firefox add-on icon:
var { ToggleButton } = require("sdk/ui/button/toggle");
var button = ToggleButton({
id: "my-button1",
label: "my button1",
icon: "./icon-16.png",
onChange: changed,
badge: 0,
badgeColor: "#00AAAA"
});
function changed(state) {
button.badge = state.badge + 1;
if (state.checked) {
button.badgeColor = "#AA00AA";
}
else {
button.badgeColor = "#00AAAA";
}
}
However, it is not clear to me how to remove the badge text. Just setting its color to transparent does not work, since the text is still displayed and the background of the badge has a gradient (which is even in transparent mode visible).
To fully remove the badge text set it to an empty string, i.e. button.badge = "";

Hammer js (v 2.0.4) not working well for an img on Desktop IE 11

I am trying to add swipe and press support to an img using Hammer js version 2.0.4 and I have noticed that it does not work well on Desktop IE11. The gestures are triggered maybe once for every 20 attempts.
Here is a jsfiddle with an example.
http://jsfiddle.net/bhptL6mf/32/
$(function() {
var myImg = document.getElementById("myImg");
var blue = document.getElementById("blue");
var hammerManager = new Hammer.Manager(myImg);
var panRecognizer = new Hammer.Pan({
threshold: 0,
pointers: 0
});
hammerManager.add(panRecognizer);
var swipeRecognizer = new Hammer.Swipe({
threshold: 0,
velocity: 0.01
});
hammerManager.add(swipeRecognizer).recognizeWith(hammerManager.get('pan'));
hammerManager.on('swipe', function(event) {
if (event.type == 'swipe') {
($(blue).text() === "Swiped") ? $(blue).text(" "): $(blue).text("Swiped");
}
});
})
Anyone else seeing this issue and know of a workaround? I am also seeing the same issue when gestures are applied to anchors
Setting img attribute draggable to false will fix this on IE.
Also noticed a similar issue on Desktop Fire Fox and had to set -moz-user-select to none and prevent dragstart event in addition to setting draggable to false to fix it.

Map pans and zooms when opening info window

when I click on a marker the map always re-pans and zooms to the initial state. Not such a big deal for a single marker but if I start with a cluster, zoom in and then click on a marker there is the problem. It zooms out, reclusters and then pops up the window. Anybody come across this issue?
This is what it looks like:
Here is the relevant code:
var loc = { latitude: item.Latitude, longitude: item.Longitude };
var marker = { location: loc, label: item.Label, id: item.Id, value: item.Value,showWindow:false };
markers.push(marker);
marker.onClick = function () {
if ($scope.$$phase || $scope.$root.$$phase) {
this.model.showWindow = true;
} else {
var self = this;
$scope.$apply(function() {
self.model.showWindow = true;
});
}
};
And the markup. This is in another directive that allows me to just keep a list of different layer types:
'<markers models="mylayer.locations" coords="\'location\'" doRebuildAll="true" idKey="\'id\'" doCluster="true" fit="true" options="mylayer.options" click="\'onClick\'">' +
'<windows show="\'showWindow\'" doRebuildAll="false" disableAutoPan="true" data-ng-if="mylayer.options.clickable" ng-cloak>' +
'<div>hello</div>' +
'</windows>' +
'</markers>'
Turns out the problem happened when updating from version 1.1.0 of angular-google-maps.js to version 1.1.4. Reverted and it works fine now.

Bing Maps API v7 Custom HTML pushpins in Firefox not positioned correctly

I've created an app where I use several custom HTML pushpins. Each one of these pushpins has a click event that will call setView on the map to center the map on the selected pin. This works perfectly in all browsers except for Firefox (testing version 22.0).
In Firefox, after the setView animation completes and the map is centered on the pushpin, the pushpin is then offset horizontally, vertically or both by a certain amount of pixels. The amount seems to correspond with amount of pixels the map has moved. If you then drag the map manually with the mouse, upon releasing the mouse button, the pushpin snaps back to its proper place. I've checked the top and left position values of the MapPushpinBase anchor tag in compared it with other browsers and the values differ.
Unfortunately, I cannot post a live example because the product has not yet been publicly released. But see below for the code I'm using.
this.clickHandlers.push(Microsoft.Maps.Events.addHandler(node, 'click', function (e) {
var element = $(e.target._htmlContent);
self.nodeHitboxHandler(element);
}));
Within the nodeHitboxHandler function, the only piece of Bing Map code is this:
this.map.setView({
center: new Microsoft.Maps.Location(panStart.latitude, panStart.longitude),
zoom: this.zoom,
mapTypeId: Microsoft.Maps.MapTypeId[self.mapTypeId]
});
Thanks in advance for any help.
UPDATE:
In order to make things clearer, I've created a simple example that demonstrates the problem. You can see it here: http://ginof.com/tests/bing/
In Firefox, try clicking on the different pushpins and watch the behaviour of the pushpin you've just clicked on after the map finishes panning to its new location. The map works fine in all browsers except Firefox.
Here's the complete JavaScript code for this example:
$(document).ready(function () {
var map = null,
initialCoordinates = {latitude: 40.71435, longitude: -74.00597},
initialPoint = new Microsoft.Maps.Location(initialCoordinates.latitude, initialCoordinates.longitude),
range = {
top: 3,
right: 5,
bottom: 0.01,
left: 5
},
mapOptions = {
credentials:"BING-MAPS-API-KEY",
disableKeyboardInput: true,
disableZooming: true,
enableClickableLogo: false,
enableSearchLogo: false,
showBreadcrumb: false,
showDashboard: false,
showMapTypeSelector: false,
showScalebar: false,
inertiaIntensity: 0.5,
mapTypeId: Microsoft.Maps.MapTypeId.birdseye,
labelOverlay: Microsoft.Maps.LabelOverlay.hidden,
center: initialPoint,
zoom: 14
};
function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), mapOptions);
// Create nodes
map.entities.clear();
var pushpinOptions,
pushpin,
nodeCoordinates;
for (var i = 0; i < 5; i++) {
pushpinOptions = {width: null, height: null, htmlContent: '<div id="node' + i + '" class="node">' + i + '. Custom HTML</div>'};
nodeCoordinates = {latitude: initialCoordinates.latitude + i * 0.005, longitude: initialCoordinates.longitude + i * 0.005};
pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(nodeCoordinates.latitude, nodeCoordinates.longitude), pushpinOptions);
pushpinClick = Microsoft.Maps.Events.addHandler(pushpin, 'click',
(function () {
var nodeId = i,
homeCoordinates = nodeCoordinates;
return function () {
console.log("node " + nodeId + " clicked.");
map.setView({center: new Microsoft.Maps.Location(homeCoordinates.latitude, homeCoordinates.longitude)});
}
})()
);
map.entities.push(pushpin);
}
}
GetMap();
});
Thanks again for any help.
This is a known issue which I was able to reproduce an has been escalated to the development team. Note that the Bing Maps forums are the best place to report these types of issues. You can find a similar thread on this topic here: http://social.msdn.microsoft.com/Forums/en-US/f77e6a80-2e0f-44c3-81cc-edb4c2327016/custom-html-pushpins-in-firefox-not-positioned-correctly

Resources