Permalink
Browse files

This revision adds the functionality to place (html) pins on countrie…

…s. In addition to that, it adds zoomIn, zoomOut methods which can be called to zoom in or out of the map. It adds three events, bound to map's container. The details are as follows.

Added events:
_______________
"drag": When the map is dragged, map.container triggers this event.
"zoomIn": When the map is zoomed in, map.container triggers this event.
"zoomOut": When the map is zoomed out, map.container triggers this event.

Added parameters:
_________________
"pins": JSON which specifies the pins to be placed on the map.
Example:
{
	"pk" : "pk_pin_metadata",
	"ru" : "ru_pin_metadata",
	...
}

There are two modes for placing pins:
"pinMode":
	1) "content" (default)
	2) "id"

If the pin mode is "content" (or not specified) then the parameter "pins" contains the html content to be placed in place of the pin.
Example:
{
	"pk" : "\u003cimg src=\"images/pin.png\" /\u003e", //serialized <img src="images/pin.png" /> tag
	...
}

If the pin mode is "id" then the parameter "pins" contains the "id" attribute of the html (DOM) object to be placed as pin.
Example:
{
	"pk" : "pin_pk_id",
	"ru" : "pin_for_russia",
	...
}
...
...
</script>
<div style="display:none">
	<img id="pin_pk_id" src="images/pin.png" />
	<div id="pin_for_russia">...</div>
</div>

The parameters "pins" and "pinMode" can be specified at the time of initialization:
jQuery(document).ready(function() {
	jQuery('#vmap').vectorMap({
		map: 'world_en',
		pins: {"ru":"\u003ca href=\"#\"\u003epin_ru\u003c/a\u003e", "pk":"\u003ca href=\"#\"\u003epin_pk\u003c/a\u003e"},
		pinMode: 'content'
	});
});

To add pins later, use placePins method (explained in the methods list).

Note:
_____
1) The pin is placed at the center of the bounding box of related country. So depending on the shape of the country's map, the pin might not land on the country itself :(. For instance the pin for 'US' lands in the center of the united states and the state of alaska, and it is not ACTUALLY on the land of 'US'. It is rather placed in the ocean between them :P.
2) If the "pinMode" is set as "id", then the html DOM element having the given id is NOT COPIED to the desired position, it IS MOVED. This means that the element will be removed from it's original position and will be added to the desired location on the map.

Methods (functions):
____________________
zoomIn(): It has the same effect as clicking on the zoom in button.
Usage:
jQuery('#vmap').vectorMap('zoomIn');

zoomOut(): It has the same effect as clicking on the zoom out button.
Usage:
jQuery('#vmap').vectorMap('zoomOut');

//Methods related to pinning
getPinId(cc): Returns the html attribute "id" of the pin belonging to the country whose country code is provided in "cc". This method does not check if the pin physically exists.
Usage:
var pinId = jQuery('#vmap').vectorMap('getPinId', 'pk');

placePins(pins, pinMode): This method is provided to place pins after the initialization of the map. The parameters "pins" and "pinMode" are explained earlier.
Usage:
jQuery('#vmap').vectorMap('placePins', pins[, pinMode]);
If pinMode is unspecified, it is considered as "content".
Note: Only one pin can be placed at a time on one country. So if a pin is placed on a country already having a pin, the older pin will be removed.

positionPins(): To position the pins to their proper places (center of the bounding box of their respective country). This method is called automatically upon placing the pins, dragging, or zooming in/out.
Usage: (Not so usable though)
jQuery('#vmap').vectorMap('positionPins');

getPin(cc): Returns a string containing the html of the pin placed on the country whose country code was specified in "cc".
Usage:
var pinContent = jQuery('#vmap').vectorMap('getPin', 'pk');

getPins(): Returns a json STRING containing html strings of all the pins associated with the respective country codes.
Example: {"ru":"\u003ca href=\"#\"\u003epin_ru\u003c/a\u003e", "pk":"\u003ca href=\"#\"\u003epin_pk\u003c/a\u003e"}
Usage:
var pins = jQuery('#vmap').vectorMap('getPins');

removePin(cc): Removes the pin from the country whose country code is specified in "cc".
Usage:
jQuery('#vmap').vectorMap('removePin', 'pk');

removePins(): Removes all the pins from the map.
Usage:
jQuery('#vmap').vectorMap('removePins');

Variables (properties):
_______________________
pinHandlers: (bool)
Usage:
It is false by default. When the pins are placed for the first time, it is set to true. It performs as a check to make sure the pins are being placed for the first time. If so, the plugin binds the method "positionPins()" with the events "drag", "zoomIn", and "zoomOut". This makes sure that the event listener is assigned only once.
Note: Not to be messed with externally.

__________________________________________________________________________________________________________________
  • Loading branch information...
1 parent 76b1874 commit 54ea46e3289c7b138b8fcf5200783b8ebabced70 @adeelnawaz adeelnawaz committed Feb 15, 2013
View
173 jqvmap/jquery.vmap.js
@@ -510,6 +510,18 @@
}
this.bindZoomButtons();
+
+ if(params.pins) {
+ /*if(params.pinMode) {
+ if(params.pinMode != "id" && params.pinMode != "content") {
+ params.pinMode = "content";
+ }
+ } else {
+ params.pinMode = "content";
+ }*/
+ this.pinHandlers = false;
+ this.placePins(params.pins, params.pinMode);
+ }
WorldMap.mapIndex++;
};
@@ -734,6 +746,8 @@
if (self.isMovingTimeout) {
clearTimeout(self.isMovingTimeout);
}
+
+ self.container.trigger('drag');
}
return false;
@@ -761,37 +775,52 @@
bindZoomButtons: function () {
var map = this;
+ this.container.find('.jqvmap-zoomin').click(function(){
+ map.zoomIn();
+ });
+ this.container.find('.jqvmap-zoomout').click(function(){
+ map.zoomOut();
+ });
+ },
+
+ zoomIn: function () {
+ var map = this;
var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
- this.container.find('.jqvmap-zoomin').click(function () {
- if (map.zoomCurStep < map.zoomMaxStep) {
- var curTransX = map.transX;
- var curTransY = map.transY;
- var curScale = map.scale;
+ if (map.zoomCurStep < map.zoomMaxStep) {
+ var curTransX = map.transX;
+ var curTransY = map.transY;
+ var curScale = map.scale;
- map.transX -= (map.width / map.scale - map.width / (map.scale * map.zoomStep)) / 2;
- map.transY -= (map.height / map.scale - map.height / (map.scale * map.zoomStep)) / 2;
- map.setScale(map.scale * map.zoomStep);
- map.zoomCurStep++;
+ map.transX -= (map.width / map.scale - map.width / (map.scale * map.zoomStep)) / 2;
+ map.transY -= (map.height / map.scale - map.height / (map.scale * map.zoomStep)) / 2;
+ map.setScale(map.scale * map.zoomStep);
+ map.zoomCurStep++;
- jQuery('#zoomSlider').css('top', parseInt(jQuery('#zoomSlider').css('top'), 10) - sliderDelta);
- }
- });
+ jQuery('#zoomSlider').css('top', parseInt(jQuery('#zoomSlider').css('top'), 10) - sliderDelta);
+
+ map.container.trigger("zoomIn");
+ }
+ },
+
+ zoomOut: function () {
+ var map = this;
+ var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
- this.container.find('.jqvmap-zoomout').click(function () {
- if (map.zoomCurStep > 1) {
- var curTransX = map.transX;
- var curTransY = map.transY;
- var curScale = map.scale;
+ if (map.zoomCurStep > 1) {
+ var curTransX = map.transX;
+ var curTransY = map.transY;
+ var curScale = map.scale;
- map.transX += (map.width / (map.scale / map.zoomStep) - map.width / map.scale) / 2;
- map.transY += (map.height / (map.scale / map.zoomStep) - map.height / map.scale) / 2;
- map.setScale(map.scale / map.zoomStep);
- map.zoomCurStep--;
+ map.transX += (map.width / (map.scale / map.zoomStep) - map.width / map.scale) / 2;
+ map.transY += (map.height / (map.scale / map.zoomStep) - map.height / map.scale) / 2;
+ map.setScale(map.scale / map.zoomStep);
+ map.zoomCurStep--;
- jQuery('#zoomSlider').css('top', parseInt(jQuery('#zoomSlider').css('top'), 10) + sliderDelta);
- }
- });
+ jQuery('#zoomSlider').css('top', parseInt(jQuery('#zoomSlider').css('top'), 10) + sliderDelta);
+
+ map.container.trigger("zoomOut");
+ }
},
setScale: function (scale) {
@@ -801,7 +830,101 @@
getCountryId: function (cc) {
return 'jqvmap' + this.index + '_' + cc;
- }
+ },
+
+ getPinId: function (cc) {
+ return this.getCountryId(cc)+'_pin';
+ },
+
+ placePins: function(pins, pinMode){
+ var map = this;
+
+ if(!pinMode || (pinMode != "content" && pinMode != "id")) {
+ pinMode = "content";
+ }
+
+ if(pinMode == "content") {//treat pin as content
+ jQuery.each(pins, function(index, pin){
+ if(jQuery('#'+map.getCountryId(index)).length == 0){
+ return;
+ }
+ //mapData.pathes[code].name
+ var pinIndex = map.getPinId(index);
+ if(jQuery('#'+pinIndex).length > 0){
+ jQuery('#'+pinIndex).remove();
+ }
+ map.container.append('<div id="' + pinIndex + '" for="'+index+'" class="jqvmap_pin" style="position:absolute">' + pin + '</div>');
+ });
+ } else { //treat pin as id of an html content
+ jQuery.each(pins, function(index, pin){
+ if(jQuery('#'+map.getCountryId(index)).length == 0){
+ return;
+ }
+ var pinIndex = map.getPinId(index);
+ if(jQuery('#'+pinIndex).length > 0){
+ jQuery('#'+pinIndex).remove();
+ }
+ map.container.append('<div id="' + pinIndex + '" for="'+index+'" class="jqvmap_pin" style="position:absolute"></div>');
+ jQuery('#'+pinIndex).append(jQuery('#'+pin));
+ });
+ }
+
+ this.positionPins();
+ if(!this.pinHandlers){
+ this.pinHandlers = true;//do only once
+ var positionFix = function(){
+ map.positionPins();
+ };
+ this.container.bind('zoomIn', positionFix)
+ .bind('zoomOut', positionFix)
+ .bind('drag', positionFix);
+ }
+ },
+
+ positionPins: function(){
+ var map = this;
+ var pins = this.container.find('.jqvmap_pin');
+ jQuery.each(pins, function(index, pinObj){
+ pinObj = jQuery(pinObj);
+ var countryId = map.getCountryId(pinObj.attr('for'));
+ var countryObj = jQuery('#' + countryId);
+
+ var bbox = document.getElementById(countryId).getBBox();
+ var position = countryObj.position();
+
+ var scale = map.scale;
+
+ var left = position.left + (bbox.width / 2) * scale - pinObj.width() / 2,
+ top = position.top + (bbox.height / 2) * scale - pinObj.height() / 2;
+
+ pinObj.css('left',left).css('top',top);
+ });
+ },
+
+ getPin: function(cc){
+ var pinObj = jQuery('#'+this.getPinId(cc));
+ return pinObj.html();
+ },
+
+ getPins: function(){
+ var pins = this.container.find('.jqvmap_pin');
+ var ret = new Object();
+ jQuery.each(pins, function(index, pinObj){
+ pinObj = jQuery(pinObj);
+ var cc = pinObj.attr('for');
+ var pinContent = pinObj.html();
+ eval("ret." + cc + "=pinContent");
+ });
+ return JSON.stringify(ret);
+ },
+
+ removePin: function(cc) {
+ jQuery('#'+this.getPinId(cc)).remove();
+ },
+
+ removePins: function(){
+ this.container.find('.jqvmap_pin').remove();
+ }
};
WorldMap.xlink = "http://www.w3.org/1999/xlink";
View
BIN samples/images/background.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN samples/images/flag.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN samples/images/globe.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN samples/images/thumb.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN samples/images/tip.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
211 samples/pins.html
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>JQVMap - World Map</title>
+
+ <link href="../jqvmap/jqvmap.css" media="screen" rel="stylesheet" type="text/css" />
+
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
+ <script src="../jqvmap/jquery.vmap.js" type="text/javascript"></script>
+ <script src="../jqvmap/maps/jquery.vmap.world.js" type="text/javascript"></script>
+
+ <script type="text/javascript">
+ var pins = {'ru' : "\u003ca target=\"_blank\" href=\"http://www.google.com.ru\"\u003epin_ru\u003c/a\u003e", 'pk' : "\u003ca target=\"_blank\" href=\"http://www.google.com.pk\"\u003epin_pk\u003c/a\u003e"};
+
+ jQuery(document).ready(function() {
+ jQuery('#vmap').vectorMap({
+ map: 'world_en',
+ backgroundColor: '#333333',
+ color: '#ffffff',
+ hoverOpacity: 0.7,
+ selectedColor: '#666666',
+ enableZoom: true,
+ showTooltip: true,
+ scaleColors: ['#C8EEFF', '#006491'],
+ normalizeFunction: 'polynomial',
+ pins: {"ru":"\u003ca href=\"#\"\u003epin_ru\u003c/a\u003e", "pk":"\u003ca href=\"#\"\u003epin_pk\u003c/a\u003e"}
+ //,pinMode: 'content'
+ });
+ });
+ function placePin(id){
+ var cc = jQuery("#"+id+' input[name=cc]').val();
+ if(cc == ''){
+ alert('Insert a country code first');
+ return;
+ }
+ var pin = jQuery("#"+id+' .pin-td').html();
+ if(jQuery.trim(pin) == ''){
+ alert('Pin has been moved');
+ return;
+ }
+
+ var pins = new Object();
+ eval("pins." + cc + "=pin");
+
+ jQuery('#vmap').vectorMap('placePins', pins, 'content');
+ }
+ function movePin(id){
+ var cc = jQuery("#"+id+' input[name=cc]').val();
+ if(cc == ''){
+ alert('Insert a country code first');
+ return;
+ }
+ var pin = jQuery("#"+id+' .pin-td').html();
+ if(jQuery.trim(pin) == ''){
+ alert('Pin has been moved');
+ return;
+ }
+ pin = id+'_content';
+
+ var pins = new Object();
+ eval("pins." + cc + "=pin");
+
+ jQuery('#vmap').vectorMap('placePins', pins, 'id');
+ }
+ function removePin(){
+ var cc = jQuery('#remove input[name=cc]').val();
+ if(cc == ''){
+ alert('Insert a country code first');
+ return;
+ }
+ jQuery('#vmap').vectorMap('removePin', cc);
+ }
+ function removeAllPins(){
+ jQuery('#vmap').vectorMap('removePins');
+ }
+ </script>
+ <style>
+ *{
+ margin: 0;
+ padding: 0;
+ }
+ #overlay {
+ position: relative;
+ overflow: hidden;
+ }
+ #overlay div {
+ position: absolute;
+ z-index: 1;
+ }
+ .jqvmap-zoomin,
+ .jqvmap-zoomout {
+ z-index: 1;
+ }
+ </style>
+ <style>
+ *{
+ margin: 0;
+ padding: 0;
+ }
+ .pin {
+ background: url(images/tip.png) no-repeat;
+ width: 9px;
+ height: 5px;
+ position: absolute;
+ cursor: pointer;
+ }
+ .pin .pin_content {
+ background: url("images/background.png") repeat scroll 0 0 transparent;
+ border-radius: 5px 5px 5px 5px;
+ bottom: 50px;
+ height: 50px;
+ position: relative;
+ right: 15px;
+ width: 100px;
+ }
+ .pin .pin_content div{
+ float: left;
+ height: 30px;
+ width: 35px;
+ padding: 10px 5px;
+ text-align: center;
+ }
+ .pin .pin_content div span {
+ color: #EA4E41;
+ font-size: 20px;
+ font-weight: bold;
+ line-height: 18px;
+ }
+ .pin .pin_content div span.small {
+ font-size: 12px;
+ }
+ .pin .pin_content .thumb{
+ width: 45px;
+ }
+ .pin .pin_content .thumb img{
+ max-width: 45px;
+ max-height: 30px;
+ }
+ #rightcol {
+ position: absolute;
+ right: 230px;
+ top: 0;
+ }
+ table, tr, td {
+ border: 1px solid #aaaaaa;
+ }
+ .pin-td {
+ height: 65px;
+ padding: 20px;
+ width: 70px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="vmap" style="width: 600px; height: 400px;"></div>
+ <div id="rightcol">
+ <table>
+ <tr id="pin1">
+ <td class="pin-td">
+ <div id="pin1_content" class="pin">
+ <div class="pin_content">
+ <div>
+ <span>09</span>
+ <span class="small">new</span>
+ </div>
+ <div class="thumb">
+ <img src="images/thumb.jpg"/>
+ </div>
+ </div>
+ </div>
+ </td>
+ <td>
+ <input type="text" name="cc" placeholder="Country code"/><br/>
+ <input type="button" onClick="placePin('pin1')" value="Copy"/>
+ <input type="button" onClick="movePin('pin1')" value="Move"/>
+ </td>
+ </tr>
+ <tr id="pin2">
+ <td class="pin-td">
+ <img id="pin2_content" src="images/globe.png"/>
+ </td>
+ <td>
+ <input type="text" name="cc" placeholder="Country code"/><br/>
+ <input type="button" onClick="placePin('pin2')" value="Copy"/>
+ <input type="button" onClick="movePin('pin2')" value="Move"/>
+ </td>
+ </tr>
+ <tr id="pin3">
+ <td class="pin-td">
+ <img id="pin3_content" src="images/flag.png"/>
+ </td>
+ <td>
+ <input type="text" name="cc" placeholder="Country code"/><br/>
+ <input type="button" onClick="placePin('pin3')" value="Copy"/>
+ <input type="button" onClick="movePin('pin3')" value="Move"/>
+ </td>
+ </tr>
+ <tr id="remove">
+ <td class="pin-td">
+ <input type="text" name="cc" placeholder="Country code"/><br/>
+ <input type="button" onClick="removePin()" value="Remove"/>
+ </td>
+ <td>
+ <input type="button" onClick="removeAllPins()" value="Remove"/>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </body>
+</html>

0 comments on commit 54ea46e

Please sign in to comment.