Introduction to the jQuery Map

Jordan Tsankov / Wednesday, September 12, 2012

Infragistics NetAdvantage jQuery Map

Hey people ! This post , along with four more will try to shed light on the latest addition to the range of Infragistics jQuery controls – the jQuery Map. Albeit in a CTP stage , you can expect to squeeze a lot of use out of this widget. This blog post will focus on the basics of the control and how to use it in your applications and the rest of the topics will be centered on specific features.

Setting the map up

Of course , the first thing you should add to your project is add a reference to the jQuery library. You can use the CDN-hosted jQuery .js file which  you will need to put this inside your page header. In there , you should also include a jQueryUI.js reference and a Modernizr reference. Modernizr should be included in your Visual Studio project and as for jQueryUI , you can get yourself a custom build at jQueryUI.

Finally , you will also need to reference our resource loader.

With these files referenced , your header should have these lines of code:

   1: <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
   2: <script type="text/javascript" src="Scripts/jquery-ui-1.8.11.js">
   3: <script type="text/javascript" src="Scripts/modernizr-2.0.6-development-only.js">
   4: <script type="text/javascript" src="Scripts/js/infragistics.loader.js">

Your next step would be using the resource loader to get all the map-specific files loaded up. In case you’re new to NetAdvantage 12.1 , here’s a quick run-down on using the resource loader:

   1: $.ig.loader({
   2:     scriptPath: '{Resources root}/js/',
   3:     cssPath: '{Resources root}/css/',
   4:     resources: '*' // replace the star with desired controls
   5: });
   6:  
   7: // here's an example
   8: $.ig.loader({
   9:     scriptPath: '/Scripts/js/',
  10:     cssPath: '/Content/css/',
  11:     resources: 'igMap'
  12: });

After following these steps , you have completed the setup phase and can move on to…

Rendering a map

Let’s do it baby steps – here are the bare-bones of getting a map on your web page. I will explain the important map options as well.

   1: $.ig.loader(function () {
   2:     $("#map").igMap({
   3:         width: "100%",
   4:         crosshairVisibility: "visible",
   5:         verticalZoomable: true,
   6:         horizontalZoomable: true,
   7:         overviewPlusDetailPaneVisibility: "visible",
   8:         panModifier: "control",
   9:         backgroundContent: {
  10:             type: "openStreet"
  11:         },
  12:         windowResponse: "immediate"
  13:     });
  14: });

The most important option in the lines above is the backgroundContent one – it specifies which map service do you want your widget to work with. Currently , you may choose between openStreet , bing and cloudMade. I have chosen to use OpenStreet in this example because it requires no registration – unlike Bing or CloudMade.

Another useful option is the panModifier – it establishes a key which will switch the mouse drag mode. Instead of panning the map , you will be presented with a selection-like rectangle which lets you define an area to zoom in on.

Here’s a snippet of the resulting map:

As you can see , the map is fine and dandy but it is blank. In order to add an overlay that contains some locations , we will need to explore one more option – series. Within the object scope of this option , you can provide a series of points to be plotted on the map.

Spicing it up

If you only wanted to display an empty map , then you are all set. Yet I believe most of you would want to have some data on there , so let’s get down to describing series. The simplest scenario is having a single set of locations on one map – this is illustrated in the snippet below:

   1: var europeCapitals = [
   2: { "Name": "Copenhagen", "Latitude": 55.676111, "Longitude": 12.56833 },
   3: { "Name": "London", "Latitude": 51.507222, "Longitude": -0.1275 },
   4: { "Name": "Paris", "Latitude": 48.8567, "Longitude": 2.3508 },
   5: { "Name": "Madrid", "Latitude": 40.4, "Longitude": -3.683333 }];
   6:  
   7: $.ig.loader(function () {
   8:     $("#map").igMap({
   9:         width: "100%",
  10:         crosshairVisibility: "visible",
  11:         verticalZoomable: true,
  12:         horizontalZoomable: true,
  13:         overviewPlusDetailPaneVisibility: "visible",
  14:         panModifier: "control",
  15:         backgroundContent: {
  16:             type: "openStreet"
  17:         },
  18:         series: [{
  19:             type: "geographicSymbol",
  20:             name: "capitals",
  21:             dataSource: europeCapitals,
  22:             latitudeMemberPath: "Latitude",
  23:             longitudeMemberPath: "Longitude",
  24:             markerType: "automatic",
  25:             markerBrush: "#FF0000",
  26:             markerOutline: "#00FF00"
  27:         }],
  28:         windowResponse: "immediate
  29:     });
  30: });

The code above has the locations of four different capital cities , which are fed to the map on line 21. Lines 22 and 23 define the names of which properties within your data source hold latitude and longitude information. markerType is something that would be better left off as automatic – it tells the map what types of symbols to put for every entry in the data source – valid options are circle , triangle , square , pyramid , diamond , pentagon , hexagon , tetragram , pentagram and hexagram. These come in handy when you have more extra series you wish to plot – I’ll demonstrate that in a second.

Now , here is what the code above will leave you with:

Again , this is only a snippet of the entire world map – the point was to show you that the locations we’ve described are clearly marked on their respective places. They , however , bear no information to the place they represent unless you decide to actually zoom in on them. A very simple solution to this ( for now , as there will be a blog post regarding another way of handling this issue ) is to use one of the provided events and handle clicks on the series symbols.

 

This last snippet will show how to include a second series to the map and how to use one of the provided events for the widget to relay information back to the user. Of course , I will try to elaborate on things right after the snippet.

   1: var europeCapitals = [
   2: { "Name": "Copenhagen", "Lat": 55.676111, "Lon": 12.56833 },
   3: { "Name": "London", "Lat": 51.507222, "Lon": -0.1275 },
   4: { "Name": "Paris", "Lat": 48.8567, "Lon": 2.3508 },
   5: { "Name": "Madrid", "Lat": 40.4, "Lon": -3.683333 }
   6: ];
   7:  
   8: var igOffices = [
   9: { "Name": "Infragistics Europe", "Country": "England", "Latitude": 51.53554, "Longitude": -0.45306 },
  10: { "Name": "Infragistics Bulgaria Development Lab", "Country": "Bulgaria", "Latitude": 42.641262, "Longitude": 23.334461 }
  11: ];
  12:  
  13: $.ig.loader(function () {
  14:     $("#map").igMap({
  15:         width: "100%",
  16:         crosshairVisibility: "visible",
  17:         verticalZoomable: true,
  18:         horizontalZoomable: true,
  19:         overviewPlusDetailPaneVisibility: "visible",
  20:         panModifier: "control",
  21:         backgroundContent: {
  22:             type: "openStreet"
  23:         },
  24:         series: [{
  25:             type: "geographicSymbol",
  26:             name: "capitals",
  27:             dataSource: europeCapitals,
  28:             latitudeMemberPath: "Lat",
  29:             longitudeMemberPath: "Lon",
  30:             markerType: "automatic",
  31:             markerBrush: "#FF0000",
  32:             markerOutline: "#00FF00"
  33:         },
  34:         {
  35:             type: "geographicSymbol",
  36:             name: "igOffices",
  37:             dataSource: igOffices,
  38:             latitudeMemberPath: "Latitude",
  39:             longitudeMemberPath: "Longitude",
  40:             markerType: "automatic",
  41:             markerBrush: "#000000",
  42:             markerOutline: "#00FFFF"
  43:         }],
  44:         windowResponse: "immediate",
  45:         seriesMouseLeftButtonUp: function (evt, ui) {
  46:             alert(ui.item.Name);
  47:         }
  48:     });
  49: });

First off , we get a second data source – the company’s office locations in Europe. Then , lines 34 to 43 describe the second series – we’ve given it a different name and a different data source , as well as different brush colors. Lines 45 to 47 describe the event handler discussed earlier. ui.item represents the series item that triggered the event , that’s why we directly display its Name attribute; other accessible properties of the ui object are ui.series , ui.positionX , ui.positionY , ui.actualItemBrush / ui.actualSeriesBrush.

Here you have it , both series displayed on the map. You can see how the control handles marker types automatically – the second series we’ve added got assigned the triangle symbol.

Finally , let’s get through something that some of you probably noticed but couldn’t figure the meaning of. Both of the series objects I have defined up there have a name property defined , which is seemingly useless – it does not show up anywhere and does not really affect the map itself in any way. This , however , lets you address the series through methods that the map widget has , such as the addItem one. Here’s a small example of how to add a new European capital to the existing series:

   1: $("#btn").click(function () {
   2:     $("#map").igMap("addItem", { "Name": "Stockholm", "Lat": 59.329444, "Lon": 18.068611 }, "capitals");
   3: });

You can also use insertItem and removeItem. These three methods automatically notify the widget that the data source has been updated.

   1: .igMap( "insertItem", item:object, index:number, targetName:string );
   2: .igMap( "removeItem", index:number, targetName:string );

And if you update your data sources in run-time ( and not using the two methods above ) , here’s how to trigger notifies that you’ve either inserted or removed an item:

   1: .igMap( "notifyInsertItem", dataSource:object, index:number, newItem:object );
   2: .igMap( "notifyRemoveItem", dataSource:object, index:number, oldItem:object );

 

Conclusion

I hope this introductory post has helped you grasp the basics of our Infragistics jQuery Map and has motivated you to start toying with it so you can see for yourself the amount of flexibility it offers.

imap.zip