I would like to show a tooltip by calling it from code. Something like:
tips.fireEvent('show', el);
or
label.fireEvent('mouseover');
The tips are already set and stored on domready and work perfectly on mouseover. MooTools 1.4.5.
What worked was creating a new tip:
var tip_title = el.retrieve('tip:title');
var tip_text = el.retrieve('tip:text');
var tips = new Tips(el, {fixed: true, offset: {x: 0, y: size.y}});
var tip = tips.toElement();
tip.getFirst('div.tip').set('html', '<b>' + tip_title + '</b><br />' + tip_text);
var pos = el.getPosition();
var size = el.getSize();
tip.setStyles({left: pos.x, top: pos.y + size.y});
tips.show(el);
Then, just added a little extra code to detach the additional tip on mouseover.
Related
I have done quite a few searches here and there. None of them give satisfactory answer, all we know is Google Maps API v3 has a limitation, that if the panTo target is more than 1 window height/width of the current center, it will not be smooth.
Still, I want to achieve "somewhat" smoother, not just "jumping" to the target.
Here is my solution (not perfect but I think it's better than jumping):
Calculate distance between current and target locations
Divide into several sections, each section is a little less than one window
panTo each section to achieve "sectional" smooth animation.
It's fine to find out each section target by the following algorithm:
Current is c(x,y)
Target is t(x,y)
Section count is s
Each section is c(x) + (t(x) - c(x)) / s , c(y) + (t(y) - c(y)) / s
Here is the problem: how to calculate the section count?
It should be based on the current zoom level and window size, right?
Ok, I finally come up with some like this and it works (but did not consider the zoom level)
var distance = Math.sqrt(Math.abs(Math.pow(lastLocation.lat() - status.Lat, 2)) + Math.abs(Math.pow(lastLocation.lng() - status.Lng, 2)));
//console.info('last:' + lastLocation.lat() + ',' + lastLocation.lng());
//console.info('new:' + status.Lat + ',' + status.Lng);
//console.info('distance:' + distance);
var smoothFactor = 8.0 / 1440; //hard code for screen size without considering zoom as well...
var factor = $(window).width() * smoothFactor;
smoothPanSections = [];
var sectionCount = Math.ceil(distance / factor);
var sectionLat = (status.Lat - lastLocation.lat()) / sectionCount;
var sectionLng = (status.Lng - lastLocation.lng()) / sectionCount;
for (var i = 1; i <= sectionCount; i++) {
if (i < sectionCount) {
smoothPanSections.push({ Lat: lastLocation.lat() + sectionLat * i, Lng: lastLocation.lng() + sectionLng * i });
}
else
smoothPanSections.push({ Lat: status.Lat, Lng: status.Lng });
}
panStatus();
And the panStatus is:
function panStatus() {
if (smoothPanSections.length > 0) {
var target = smoothPanSections.shift();
//still have more sections
if (smoothPanSections.length > 0) {
google.maps.event.addListenerOnce(map, 'idle', function () {
window.setTimeout(function () {
panStatus();
}, 100);
});
}
var location = new google.maps.LatLng(target.Lat, target.Lng);
map.panTo(location, zoomSize);
}
}
The title kinda says it all, i have a google maps api v3 and everything works fine except for one annoying new feature which i cant seem to fix.
You can show and hide markers by a click of a button which calls togglePOI(), but when i drag a marker and click hide and show again. All the markers appear except for the ones i have been dragging around. So the dragging seems to throw things into chaos. I’ve been have headaches over this one so any help would be greatly appreciated.
I cannot paste all the code in here, but if you want to see some other aspect that you think is causing this just ask and ill put it in.
var latlngs = new google.maps.MVCArray();
Map init etc
Marker creation
google.maps.event.addListener(locationMarker, "drag", function()
{
var index = findMarkerIndex(locationMarker, 1);
if (index >= 0)
{
var nLatLng = locationMarker.getPosition();
latlngs.setAt(index, nLatLng);
var nLat = nLatLng.lat();
var nLng = nLatLng.lng();
var modifiedLocation = {
Latitude: nLat,
Longitude: nLng
};
//SEND OUTPUT TO SELECT BOX
locations[index] = modifiedLocation;
document.getElementById('locations').options[index] = new Option('Num: ' + index + ' Pois: ' + nLat + ' - ' + nLng, data[4] + ',' + nLat + ',' + nLng + ',' + data[5]);
}
});
//FUNCTION CALLED FROM HTML BUTTON
function togglePOI()
{
if(togglePOIBool)
{
for(var i=0;i<markers.length;i++)
{
if (markers[i].category == 1) //ONLY HIDE CAT 1
markers[i].setMap(null);
}
togglePOIBool = false;
$("#togglePOIButton").val('Aan');
}
else
{
for(var i=0;i<markers.length;i++)
{
if (markers[i].category == 1)//ONLY SHOW CAT 1
markers[i].setMap(map);
}
togglePOIBool = true;
$("#togglePOIButton").val('Uit');
}
}
// Returns the index of the marker in the polyline.
function findMarkerIndex(locationMarker, option)
{
var index = -1;
for (var i = 0; i < markers.length; ++i)
{
if (markers[i] == locationMarker)
{
index = i;
break;
}
}
return index;
}
If it's OK for your application, replace setMap's with setVisible(true/false). When I tried this, it solves your problem.
http://jsfiddle.net/F3XbV/
You are not saving that position into markers array, I think it could solve the problem, insert this inside drag event:
markers[index].setPosition(locationMarker.getPosition());
I'm trying to slightly offset cluster icons created by the Google Maps Markerclusterer (V3). Short of modifying the existing code, I can't find a way to do this. Does anybody have an idea?
The Styles object in which you can provide a custom image URL accepts an anchor property, but this is to offset the generated marker item count.
Thanks!
The proper way to do it is to adjust the anchorIcon property like this:
var clusterStyles = [
{
height: 64,
width: 53,
anchorIcon: [20, 140]
},
{
height: 64,
width: 53,
anchorIcon: [20, 140]
},
{
height: 64,
width: 53,
anchorIcon: [20, 140]
}
];
var mcOptions = {
styles: clusterStyles
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
The accepted answer does not work well enough for me - adding transparent space to the icon image can change the way click and hover events behave due to the increased size of the object.
I would use the anchorIcon property except it's only available in Marker Clusterer Plus, not the other Marker Clusterer plugin (which I'm using).
For those that specifically want to use Marker Clusterer - you can override ClusterIcon.prototype.getPosFromLatLng_. The ClusterIcon object is global, so we can modify it at the top-level of any script file without messing with the plugin's source code.
This will anchor the marker to the bottom of the icon:
ClusterIcon.prototype.getPosFromLatLng_ = function (latlng) {
var pos = this.getProjection().fromLatLngToDivPixel(latlng);
pos.x -= parseInt(this.width_ / 2);
pos.y -= parseInt(this.height_);
return pos;
};
I changed the code of marcerclusterer.js to support anchorText parameter by modifying following two functions:
/**
* Sets the icon to the the styles.
*/
ClusterIcon.prototype.useStyle = function() {
var index = Math.max(0, this.sums_.index - 1);
index = Math.min(this.styles_.length - 1, index);
var style = this.styles_[index];
this.url_ = style['url'];
this.height_ = style['height'];
this.width_ = style['width'];
this.textColor_ = style['textColor'];
this.anchor_ = style['anchor'];
this.anchorText_ = style['anchorText']; //added to support anchorText parameter by Frane Poljak, Locastic
this.textSize_ = style['textSize'];
this.backgroundPosition_ = style['backgroundPosition'];
};
/**
* Adding the cluster icon to the dom.
* #ignore
*/
ClusterIcon.prototype.onAdd = function() {
this.div_ = document.createElement('DIV');
if (this.visible_) {
var pos = this.getPosFromLatLng_(this.center_);
this.div_.style.cssText = this.createCss(pos);
////added to support anchorText parameter by Frane Poljak, Locastic
if (typeof this.anchorText_ === 'object' && typeof this.anchorText_[0] === 'number' && typeof this.anchorText_[1] === 'number') {
this.div_.innerHTML = '<span style="position:relative;top:' + String(this.anchorText_[0]) + 'px;left:' + String(this.anchorText_[1]) + 'px;">' + this.sums_.text + '</span>'
} else this.div_.innerHTML = this.sums_.text;
}
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(this.div_);
var that = this;
google.maps.event.addDomListener(this.div_, 'click', function() {
that.triggerClusterClick();
});
};
You could add some transparent space to one side of your cluster icon's PNG, so that the part of the icon which you'd like to be centred is actually also centred in your PNG. This should not increase the weight of your image by more than a few bytes.
anchor / anchorIcon/ anchorText properties didn't work for me...so I made kind of workaround:
I use setCalculator() function to set the cluster text:
https://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/reference.html
when I am setting the cluster text property I am wrapping the value with <span>,
something like this:
markerCluster.setCalculator(function (markers) {
return {
text: '<span class="myClass">' + value+ '</span>',
index: index
};
});
now you can control the cluster label position with ".myClass":
span.myClass{
position: relative;
top: -15px;
.....
}
I had created the script below but the cordinate is not working right. please see my scripts and let me know what is wrong with my scripts.
thanks
/*mcc is the Instance name*/
var myMovieClip:Sprite = new Sprite();
trace("x" + mcc.x + "y" + mcc.y + "width" + mcc.width);
myMovieClip.graphics.lineStyle( 1, 0xFF0000 );
myMovieClip.graphics.drawRect( 0, 0, mcc.width+1, mcc.height+1 );
myMovieClip.graphics.endFill();
myMovieClip.x = -(mcc.x/2);
myMovieClip.y = -(mcc.y/2);
mcc.addChild(myMovieClip);
would need to know more about mcc looks like we're assuming that mcc has the content centered instead of the top right corner of mcc being at [0,0]
Try using the getBounds method instead.
something like this... though I haven't tested it
var bounds:Rectangle = mcc.getBounds(this)
myMovieClip.graphics.drawRect(
bounds.left-border/2, bounds.top-border/2,
bounds.width+border, bounds.height+border
);
myMovieClip.x = (mcc.x);
myMovieClip.y = (mcc.y);
mcc.addChild(myMovieClip);
thank you, it is working now, i used the getBounds and set the myMovieClip.x = (0); . It doesn't make sense but it works good now.
Anyway, the mcc could be anything, event rotate angle too.
var border=1;
var myMovieClip:Sprite = new Sprite();
myMovieClip.graphics.lineStyle( border, 0xFF0000 );
trace("getbound on mcc" + mcc.getBounds(mcc));
trace("parser" + mcc.getBounds(mcc).y)
trace("getbound on this" + mcc.getBounds(this));
trace("Other x " + mcc.x + " y " + mcc.y + " width " + mcc.width+ " height " + mcc.height);
var bounds =mcc.getBounds(mcc)
myMovieClip.graphics.drawRect(bounds.left-border/2, bounds.top/2,bounds.width+border, bounds.height+border);
myMovieClip.graphics.endFill();
myMovieClip.x = (0);
myMovieClip.y = (bounds.y)/2;
mcc.addChild(myMovieClip);
trace("New bound" + mcc.getBounds(mcc));
I am displaying the different marker on the map , the problem is that sometimes (specially when I reset the web server) the map is loaded properly and it even shows the shadow of the points but the markers are not shown/visible on the map.However on the subsequent calls the markers are shown properly (perhaps cached , but not sure). This behavior is consistent in all browsers namely IE 6/7/8 , Chrome , Firfox 3.5.6.
The javascript shown below creates the marker. On the sideline, as markers can be of different sizes, I need to first determine there width and size (other wise they look deformed).
var imgTemp = new Image();
imgTemp.name = "img_" + i.toString();
imgTemp.src = groupMarkerUrl; //url to the actual image
point = new GLatLng(parseFloat(latitude), parseFloat(longitude));
var icon = new GIcon(G_DEFAULT_ICON);
icon.image = groupMarkerUrl;
icon.iconSize = new GSize(imgTemp.width, imgTemp.height); //Width x Height
icon.iconAnchor = new GPoint(14, 15);
icon.infoWindowAnchor = new GPoint(5, 1);
marker = new GMarker(point, icon);
map.setCenter(point, 13);
//build the information box
var htmlContent = "<div style=\"color:#000000\"><span style=\"font-weight:bold;\">" + title + "</span><br/>";
if (address != "") {
htmlContent += address + " ";
}
if (zipcode != "") {
htmlContent += "<br/>" + zipcode + ", ";
}
if (city != "") {
htmlContent += city;
}
if (telephone != "") {
htmlContent += "<br/>Tel : " + telephone;
}
if (fax != "") {
htmlContent += "<br/>Fax : " + fax;
}
htmlContent += "</div>";
map.addOverlay(marker);
markerKeys.push(stamp);
markers[stamp] = marker;
//Add legends with group markers one for each group
if (null == legends[groupId]) {
legends[groupId] = groupMarkerUrl;
var nbsp = document.createTextNode(" ");
var image = document.createElement("img");
image.setAttribute("src", groupMarkerUrl);
image.setAttribute("style", "margin-left:10px !important; border:\"0\";");
pushpinPnlConsole.appendChild(nbsp);
pushpinPnlConsole.appendChild(image);
pushpinPnlConsole.setAttribute("style", "display:block");
}
eval("GEvent.addListener(markers[stamp] , \"click\", function(){markers['" + stamp + "'].openInfoWindowHtml(windowHtmls['" + stamp + "']);});");
windowHtmls[stamp] = htmlContent;
opticianTBody.appendChild(row);
Thanks.
Your problem is that
imgTemp.src = groupMarkerUrl; //url to the actual image
takes some time to complete. Since you use imgTemp.width and imgTemp.height without waiting for the image to load, those values are likely to be zero. The API will plot your icons at zero size.
In browsers other than MSIE, you can omit the icon.iconSize (and not copy the details from G_DEFAULT_ICON as mentioned by mopoke) and the marker will default to the image size if the image has arrived by the time the marker gets displayed. In MSIE, for PNG images, the API uses the AplphaImageLoader which defaults to size zero if a size is not specified.
The workround is to preload your images properly, by placing this code inline, so that it gets executed before the onload event
var imgTemp = new Image();
imgTemp.name = "img_" + i.toString();
imgTemp.src = groupMarkerUrl; //url to the actual image
And placing your icon creation code in an onload function, so that it doesn't get executed until after all the images loaded by the inline code have been completely fetched.
Not sure why you're using G_DEFAULT_ICON in your constructor.
To do a custom icon, use something like:
var icon = new GIcon();
icon.image = groupMarkerUrl;
//...
After you reset the server and you try and load the image referenced in groupMarkerUrl, do you see it correctly?