Theming and Customizing of Ignite UI jQuery Map Control

[Infragistics] Mihail Mateev / Monday, January 12, 2015

Ignite UI Map Control (igMap) is very easy to use widget providing  strong mapping functionalities

The underlying rendering engine of the Ignite UI Map (igMap) is the same as the Data Chart, so in addition to a wide variety of tile sources, you can also bind & render thousands to millions of data points on the map.  Bing, CloudMade, OpenStreet, ESRI Shape Files and custom tiles are supported.

This blog is focused mainly about how to style igMap, how to change the visualization  of some  the most popular Map series ( Geographic Symbol, Geographic Shape, Geographic Contour series), how to customize the symbol marker templates, tooltips and more useful examples.

Map series’ colors are controlled by options and depend on the particular series type used. For example, the Geographic Symbol and Geographic Shape series support markers, while the rest of the map series have other visual representation like polylines and contour lines or employ colored regions which depend on map data. That is the reason to have different code for different series. It is not possible for one article to cover everything and mentioned practices cover some of the most often seen cases.

Theming:

Infragistics offers the following themes you can include:

  • Infragistics Theme
  • Infragistics 2012 Theme
  • Metro Theme
  • iOS Theme
  • Bootstrap Themes:
    • Default
    • Superhero
    • Yeti
    • Flatly

Before to start:

To support styles and themes for any of Infragistics components don’t forget to add required resources to support Infragistics Ignite UI Map.

Include the Infragistics theme file and  structure file in the code.

 

The following code snippet includes the Infragistics theme and structure files in your file:

In HTML:

 

<link href="{IG Resources root}/css/themes/infragistics/infragistics.theme.css" 
     rel="stylesheet" type="text/css" />
<link href="{IG Resources root}/css/structure/infragistics.css" 
     rel="stylesheet" type="text/css" />

 

The example demonstrates usage of infragistics theme , but the same approach can be used for all available themes.

In ASPX:

 

<%@ Import Namespace="Infragistics.Web.Mvc" %>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<link href="<%= Url.Content("{IG Resources root}/css/themes/infragistics/infragistics.theme.css ") %>” 
     rel="stylesheet" type="text/css" />
<link href="{IG Resources root}/css/structure/infragistics.css" 
     rel="stylesheet" type="text/css" />

 

The whole list of required resources to use igMap is available below:

 

<script src="http://igniteui.com/js/modernizr.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<script src="http://cdn-na.infragistics.com/igniteui/latest/js/infragistics.core.js"></script>
<script src="http://cdn-na.infragistics.com/igniteui/latest/js/infragistics.dv.js"></script>
<script src="http://igniteui.com/js/map-helper.js"></script>
<link href="http://cdn-na.infragistics.com/igniteui/latest/css/themes/infragistics/infragistics.theme.css" rel="stylesheet"></link>
<link href="http://cdn-na.infragistics.com/igniteui/latest/css/structure/infragistics.css" rel="stylesheet"></link>

 

For loading the resources with the Loader, use the following code to include the igLoader script in the page:

If you are using Infragistics loader you need to set cssPath and scriptPath options, which is relative to the page that instantiates the loader.

<script type="text/javascript">
    $.ig.loader({
        scriptPath: "/Scripts/ig/",
        cssPath: "/Content/ig/",
        resources: "igMap"
    });
</script>

If you need to use predefined themes you need to add also the specified theme:

<script type="text/javascript">
    $.ig.loader({
        scriptPath: "/Scripts/ig/",
        cssPath: "/Content/ig/",
        resources: "igMap",
	theme: "metro"
    });
</script>

Ignite UI Map has no many styling points, so if you add series without specific styling these series will take default styling – not a styling related to the specified theme.

For example if you have Geographic Shape series or Geographic Symbol Series you will have default styling for these elements:

Geographic Shape series default styling

Geographic Symbol series default styling:

 

There are some elements affected from theming:

 

Overview Plus Detail panel   , getting the currently displayed area on the map, is one of the elements where theming effect is available:

$("#map").igMap({
	width: "100%",
	verticalZoomable: true,
	horizontalZoomable: true,
	overviewPlusDetailPaneVisibility: "visible",
	series: [{
		//add series definitions
	}],
	//add additional properties
});

Overview detail panel s affected from predefined themes

 

Overview Panel:

Infragistics theme:

 

Metro theme:

 

No styling:

 

Styling Ignite UI Map elements:

Map styling options reference summary

The igMap control is predominantly a graphic-content control and has properties and styling options to manage all visual aspects of the control.

With individual options you can define:

  • Map series outline and fill color
  • Marker outline and fill color for a particular series
  • Palette of colors for a geographic scatter area or contour line series
  • Custom functions to calculate style for individual shapes in geographic shapes series
  • The background content provider and, optionally, the imagery set to be used from the provider
  • The background color to be displayed until all map tiles are loaded from the provider


When set, the map properties have precedence over style classes in CSS files. These properties provide for programmatically changing the look of maps at run-time

More information about the igMap styling details could be found here:

Styling Geographic Shape series:

Providing Custom Logic for the Shape Style

There are many applications for geographic shapes maps with custom colors for individual shapes. These can be political maps showing different map regions, demographic maps showing population or population density, or financial maps showing different key performance indicators for different regions.

The igMap control allows, for the Geographic Shapes Series, a function to be specified which applies custom logic to select proper fill and outline color for individual shapes. It is called before each shape is drawn on the map and is passed the data bound to the shape.

Color selection logic.

The custom color selection logic in the example works based on a palette of colors and a range of values. It calculates interval of values based on the range size and the number of available colors in the palette. After that, whenever the logic is invoked with a concrete value for a map shape, it calculates to which interval the value belongs and returns the corresponding color from the palette.

The following code defines a variable colorPicker and assigns it with a ColorPickerByIndex object initialized with 100 000 and 500 000 000 as minimum and maximum values.

 

function ColorPickerByIndex(min, max) {
    //  Initialize internal state
    var brushes = ["#d9c616", "#d96f17", "#d1150c"];
    var interval = (max - min) / (brushes.length - 1);
    //  Returns a color from the brushes array depending on the input value
    this.getColorByIndex = function (val) {
        var index = Math.round(val / interval);
        if (index < 0) {
            index = 0;
        } else if (index > (brushes.length - 1)) {
            index = brushes.length - 1;
        }
        return brushes[index];
    };
}

 

The following code in JavaScript defines a shapeStyleSelector and assigns a color selection object to it. The selectStyle member of the color selection object points to an anonymous function which receives an argument called shape with all data bound to the shape. The anonymous function gets the POP_COUNTRY field from the data and invokes the colorPicker object’s getColorByIndex() method with the country population to get the proper fill color for the shape.

 

var colorPicker = new ColorPickerByIndex(100000, 500000000);

$("#map").igMap({
	width: "700px",
	height: "500px",
	windowRect: { left: 0.1, top: 0.1, height: 0.7, width: 0.7 },
	overviewPlusDetailPaneVisibility: "visible",
	overviewPlusDetailPaneBackgroundImageUri: "http://igniteui.com/images/samples/maps/world.png",
	series: [{
		type: "geographicShape",
		name: "worldCountries",
		markerType: "none",
		shapeMemberPath: "points",
		shapeDataSource: 'http://igniteui.com/data-files/shapes/world_countries_reg.shp',
		databaseSource: 'http://igniteui.com/data-files/shapes/world_countries_reg.dbf',
		opacity: 0.8,
		outlineThickness: 1,
		shapeStyleSelector: {
			selectStyle: function (s, o) {
				var pop = s.fields.item("POP2005");
				var popInt = parseInt(pop);
				var colString = colorPicker.getColorByIndex(popInt);
				return {
					fill: colString,
					stroke: "gray"
				};
			}
		}
	}],

});

 

The styled map will be like this one shown below:

Alternative methods:

alternative functions for generating color based on a data value:

Linear relation between the value and the color:

 

var getColorValue = function (val) {
	var ratio = val / 1338299500.0;
	var col = 255.0 * ratio;
	var colString = "rgba(0,50," + Math.round(col) + ",0.45)";
	return colString;
};


$("#map").igMap("option", "series", [{
		name: "series1",
		type: "geographicShape",
		markerType: "none",
		shapeMemberPath: "points",
		shapeDataSource: 'http://igniteui.com/data-files/shapes/world_countries_reg.shp',
		databaseSource: 'http://igniteui.com/data-files/shapes/world_countries_reg.dbf',
		shapeStyleSelector: {
		selectStyle: function (s, o) {
			var pop = s.fields.item("POP2005");
			var popInt = parseInt(pop);
			var colString = getColorValue(popInt); 
			return {
				fill: colString,
				stroke: "gray"
			};
		}

	}]                               
);

 

 

Logarithmic relation between the value and the color:

 

var getLogColorValue = function (val) {
	var ratio = Math.log(val) / Math.log(1338299500.0);
	var col = 255.0 * ratio;
	var colString = "rgba(0,50," + Math.round(col) + ",0.45)";
	return colString;
};

 

 

 

Styling Geographic Contour series

The fill scale palette is a set of colors from which the control chooses when plotting contour lines. The contour line delineates regions on the map where the values associated to the triangles differ between two ranges. The data member is designated by the valueMemberPath option. The whole range of values in the file is divided by the number of colors in the palette provided and an index of ranges is calculated for each color. A color is selected depending on which range the value belongs to. An optional minimumValue and maximumValue options can narrow the range of values for triangles which are colored.

A fillscale snippet:

 

fillScale: {
	type: "value",
	brushes: [
		"#3300CC", "#4775FF", "#0099CC", "#00CC99",
		"#33CC00", "#99CC00", "#CC9900", "#FFC20A", "#CC3300"]
}

 

 

The snippet below demonstrates how to bind pre-triangulated files (.ITF) to the igMap control and configure a geographic contour line series.

 

$("#map").igMap({
	width: "700px",
	height: "500px",
	overviewPlusDetailPaneVisibility: "visible",
	overviewPlusDetailPaneBackgroundImageUri: "http://igniteui.com/images/samples/maps/world.png",
	series: [{
		type: "geographicContourLine",
		name: "precipitation",
		fillScale: {
			type: "value",
			brushes: [
				"#3300CC", "#4775FF", "#0099CC", "#00CC99",
				"#33CC00", "#99CC00", "#CC9900", "#FFC20A", "#CC3300"]
		},
		triangleVertexMemberPath1: "v1",
		triangleVertexMemberPath2: "v2",
		triangleVertexMemberPath3: "v3",
		longitudeMemberPath: "pointX",
		latitudeMemberPath: "pointY",
		valueMemberPath: "value",
		triangulationDataSource: "http://igniteui.com/data-files/shapes/nws_precip_2011091820.itf",

	}]
});

 

 

The picture below shows how the map looks with the fill scale from the snippet above.

 

Create custom markers for Geographic Symbol series

The geographic symbol series of the igMap plots the markers for the geographic points specified by the data in your application.

With the help of the custom marker feature you can draw your own markers to convey information to the user in a different way.

The markerTemplate option gets or sets the MarkerTemplate for the current series object. The provided object should have properties called render and optionally measure.

 

$("#map").igMap({
	width: "700px",
	height: "500px",
	overviewPlusDetailPaneVisibility: "visible",
	overviewPlusDetailPaneBackgroundImageUri: "http://igniteui.com/images/samples/maps/world.png",
	windowRect: { left: 0.4, top: 0.2, height: 0.6, width: 0.6 },
	backgroundContent: {
		type: "openStreet"
	},
	series: [
		{
			type: "geographicSymbol",
			name: "igOffices",
			dataSource: igOffices,
			latitudeMemberPath: "Latitude",
			longitudeMemberPath: "Longitude",
			showTooltip: true,
			tooltipTemplate: "customTooltip",
			markerCollisionAvoidance: "fade",
			//  Defines marker template rendering function
			markerTemplate: {
				measure: function (measureInfo) {
					measureInfo.width = 10;
					measureInfo.height = 10;
				},
				render: function (renderInfo) {
					createMarker(renderInfo);
				}
			}
		}
	],

});

 

Function createMarker is responsible for the marker visualization:

 

function createMarker(renderInfo) {
	var ctx = renderInfo.context;
	var x = renderInfo.xPosition;
	var y = renderInfo.yPosition;
	var size = 10;
	var heightHalf = size / 2.0;
	var widthHalf = size / 2.0;

	if (renderInfo.isHitTestRender) {
		//  This is called for tooltip hit test only
		//  Rough marker rectangle size calculation
		ctx.fillStyle = renderInfo.data.actualItemBrush().fill();
		ctx.fillRect(x - widthHalf, y - heightHalf, size, size);
	} else {
		var data = renderInfo.data;
		var name = data.item()["Name"];
		var type = data.item()["ID"];
		//  Draw text
		ctx.textBaseline = "top";
		ctx.font = '8pt Verdana';
		ctx.fillStyle = "black";
		ctx.textBaseline = "middle";
		wrapText(ctx, name, x + 3, y + 6, 80, 12);

		//  Draw marker
		ctx.beginPath();
		ctx.arc(x, y, 4, 0, 2 * Math.PI, false);
		if (type == "Marketing")
			ctx.fillStyle = "#2372D1";
		else if (type == "Support")
			ctx.fillStyle = "#4d4949";
		else if (type == "Development Lab")
			ctx.fillStyle = "#d13521";
		else
			ctx.fillStyle = "#36a815";

		ctx.fill();
		ctx.lineWidth = 1;
		ctx.strokeStyle = "black";
		ctx.stroke();
	}
}

 

The sample below demonstrates final result using sample database and marker template, described above:

 

 

Setting custom color to Ignite UI  Map series:

The sample is focused on Geographic Shape series. Often seen case is to highlight one or set of specified polygons, adding it in a new series.

The image below demonstrates a dashboard with a highlighted selection on the map

A series color need to ne specified:

For this case a colorPicker component is used:

 

//Cerate a color picker
 $('#color1').colorPicker();

selectedColor = $('#color1')[0].value;

 $('#color1').change(function () {
		{electedColor = $('#color1')[0].value;
  //more code
 });

 

 

 

 

$("#map").igMap("option", "series", [{
	name: "series1",
	type: "geographicShape",
	markerType: "none",
	dataSource: shapeData,
	shapeMemberPath: "Points",
	shapeStyle: {
		fill: selectedColor,
		stroke: "black",
		thickness: 8.0
	}
}]                               

);

 

 

Map tooltips

The snippet below demonstrates a tooltip template that displays city and country name, and geographic coordinates is assigned to the series and displayed when the mouse pointer hovers over the city marker on the map.

 

$(function () {
	$("#map").igMap({
		width: "700px",
		height: "500px",
		windowRect: { left: 0.1, top: 0.1, height: 0.7, width: 0.7 },
		backgroundContent: {
			type: "openStreet"
		},
		series: [{
			type: "geographicSymbol",
			name: "worldCities",
			dataSource: data,
			latitudeMemberPath: "Latitude",
			longitudeMemberPath: "Longitude",
			markerType: "automatic",
			showTooltip: true,
			tooltipTemplate: "customTooltip"
		}],
		
	});
});

 

<script id="customTooltip" type="text/x-jquery-tmpl">
	<table id="customTable" >
		<tr><th colspan="2">${item.Name}, ${item.Country}</th></tr>
		<tr>
			<td>Latitude:</td>
			<td>${item.Latitude}</td>
		</tr>
		<tr>
			<td>Longitude:</td>
			<td>${item.Longitude}</td>
		</tr>
	</table>
</script>

 

The samples above shows how you can set styling for different igMap series and important map elements like markers and tooltips. This post is a brief overview of the main Ignite UI Map styling cases.

Click on this image to get a fully support trial version of Infragistics Ignite UI controls:

http://www.igniteui.com/

Follow news from Infragistics for more information about new Infragistics products.

As always, you can follow us on Twitter @Infragistics and stay in touch on Facebook, Google+ and  LinkedIn!