Including Your Own Custom Components

[ezcol_2third]


Custom Components

The map allows you to inject your remote JavaScript and HTML/CSS into the AdvancedInfoWindow, or into another target of the DOM. By developing a custom component, refered to as a “Card”, you can code basically whatever and however you want, with the following beneifts including but not limited to:

  • Get a live reference to the map
  • Get a live reference to the currently selected layer in the AdvancedInfoWindow
  • Get notified when things happen, like when the map moves or when a layer was selected, etc.
  • Can target any DOM element on the page
  • Easy coding strategy to reduce HTML conflicts/ensure uniqueness
  • Your HTML and JS gets injected into a target DIV, granting you tons of flexibility with virtually no imposed restrictions.

Reduce chance of conflicts

DOM Objects

To reduce DOM conflicts, the map will randomize any HTML element id’s you specify and a mechanism is provided (domObjByRandField) within
your card, to access the randomized id’s using their hard-coded key names. Refer to the “caByCountyChart” field, in the ColumnChartCard
example below to see a practical example of this in use.

CSS namespacing

To reduce CSS conflicts, namespace your CSS using a unique naming convention, like “com_companyname_cardname_stylename”.

Card Features by Inheritance

By inheriting from the centigon.ui.Card class, the following functionality will be added to your component class,
effectively passing a reference of the map in as well as notifying your custom component when certain map and/or AdvancedInfoWindow actions
occur. Everything aside from “getHtml” is optional to implement. Otherwise, just pick and choose the functions you want to implement/override and
code for whatever’s needed. addEventListeners is called after your HTML has been added to the DOM. It’s there where you can add
button click event listeners for your HTML elements, using jQuery, for example.

Below is a stubbed list of functionality you inherit from the card class. Just for reference purposes only.

 

centigon.ui.Card = function(){
	
	this.options = {};
	this.uid = this._domUtil.getRandomDivId();
	this.controlIdToRandomId = {};
	this.cMap;
	this.layer;
}

centigon.ui.Card.prototype.getHtml = function(callback){
	
	
	/*SYNC SAMPLE
	return "<div>Hello</div>";
	*/
	
	/*ASYNC SAMPLE
	$.ajax({
		url: "whateverurl.txt",
		dataType: "text",
		success: function(content){
			callback(content);
		},
		error: function(xhr, status, error){
			alert("Could not load remote Card html due to: " + error);
		}
	});
	*/
}

centigon.ui.Card.prototype.addEventListeners = function(){

}

centigon.ui.Card.prototype.updateView = function(){

}

centigon.ui.Card.prototype.viewportChanged = function(){

}

centigon.ui.Card.prototype.aiwLayerChanged = function(){
	
}

centigon.ui.Card.prototype.layerSelected = function(){

}

centigon.ui.Card.prototype.add = function(){

}

centigon.ui.Card.prototype.remove = function(){

}

centigon.ui.Card.prototype.show = function(){

}

centigon.ui.Card.prototype.hide = function(){

}

centigon.ui.Card.prototype.domObj = function(id){
	
}

centigon.ui.Card.prototype.domObjByRandField = function(fieldName){
	
	return this._domUtil.getDomObjectById(this.controlIdToRandomId[fieldName]);
}

centigon.ui.Card.prototype.getMyDiv = function(){
	
}

centigon.ui.Card.prototype.getDomObjByClassNameUnderMyDiv = function(className){
	
}

Hello World

Map Code

 

cMap = new centigon.locationIntelligence.MapView();
				
var aiwOpts = new centigon.ui.AdvancedInfoWindowOptions();

var cardOpts = new centigon.ui.CardOptions();
cardOpts.className = "HelloWorld";
cardOpts.classUrl = "myserver.com/..HelloWorld.js";
cardOpts.category = "Summary";
cardOpts.title = "Hello World";
cardOpts.getHtmlIsAsync = false;

advInfWinOptions.opts.cardOpts.push(cardOpts);

cMap.setAdvancedInfowindowOptions(aiwOpts);

HelloWorld.js Code

 

function HelloWorld(){

	centigon.ui.Card.call(this);
}

HelloWorld.constructor = centigon.ui.Card;
HelloWorld.prototype = new centigon.ui.Card();

HelloWorld.prototype.getHtml = function(gotHtml){

	return "<div>Hello World!</div&gt";
}

Highcharts – Outside of Map DOM

Map Code

 

cMap = new centigon.locationIntelligence.MapView();
				
var aiwOpts = new centigon.ui.AdvancedInfoWindowOptions();

var cardOpts = new centigon.ui.CardOptions();
cardOpts.className = "ColumnChartCard";
cardOpts.classUrl = "myserver.com/..ColumnChartCard.js";
cardOpts.category = "Store Charts";
cardOpts.title = arguments[3];
cardOpts.iconUrl = "menu_chart@1x.png";
cardOpts.iconSelectedUrl = "menu_chart@1x.png";
cardOpts.getHtmlIsAsync = true;

advInfWinOptions.opts.cardOpts.push(cardOpts);

cMap.setAdvancedInfowindowOptions(aiwOpts);

ColumnChartCard.js Code

 

function ColumnChartCard(){

	centigon.ui.Card.call(this);
		
	this.contentUrl = "//myserver.com/..ColumnChartCardMarkup.txt";
	
	this.controlIdToRandomId = {
		caByCountyChart: this._domUtil.getRandomDivId(),
		countyByStoreChart: this._domUtil.getRandomDivId()
	};
}

ColumnChartCard.constructor = centigon.ui.Card;
ColumnChartCard.prototype = new centigon.ui.Card();

ColumnChartCard.prototype.getHtml = function(gotHtml){

	this.getRemoteContent({url: this.contentUrl, success: gotHtml});
}

ColumnChartCard.prototype.addEventListeners = function(){
	
	this.updateView();
}

ColumnChartCard.prototype.viewportChanged = function(){

	this.updateView();
}

ColumnChartCard.prototype.aiwLayerChanged = function(){
	
	this.updateView();
}

ColumnChartCard.prototype.layerSelected = function(){
	
	this.updateView();
}

ColumnChartCard.prototype.updateView = function(){
	
	this.domObjByRandField("caByCountyChart").hide();
	this.domObjByRandField("countyByStoreChart").hide();
	
	if(this.layer.positionInMapDataProvider === countyLayerIx){
		this.domObjByRandField("caByCountyChart").show();
	}
	else{
		this.domObjByRandField("countyByStoreChart").show();
	}
	
	this.updateCharts();
}

ColumnChartCard.prototype.updateCharts = function(){
	
	this.buildCountyChart();
	this.buildStoreChart();
}

ColumnChartCard.prototype.buildCountyChart = function(){
	
	var colVals = [];
	var xAxisLabels = [];
	var allCountyXAxisLabels = [];
	
	var countyLayer = this.cMap.getLayerAt(countyLayerIx);
	if(!countyLayer){
		return;
	}

	var chartTitle = "CA Revenue by County";
	colVals = countyLayer.getValues();
	xAxisLabels = countyLayer.getLabels();

	var arrObjsToSort = [];
	for(var l0=0;l0<colVals.length;l0++){

		arrObjsToSort.push({value: colVals[l0], label: xAxisLabels[l0]});
		allCountyXAxisLabels[l0] = xAxisLabels[l0].substring(0,12) + "...";
	}

	//sort the data
	var sortedObjs = uf.getCollIterator(arrObjsToSort);
	sortedObjs = uf.getCollIterator(sortedObjs.getSortedArrayObjsByFieldAscending("value"));
	colVals = sortedObjs.getColumnFromObjsByField("value");
	xAxisLabels = sortedObjs.getColumnFromObjsByField("label");

	for(var l=0;l<xAxisLabels.length;l++){
		xAxisLabels[l] = xAxisLabels[l].substring(0,12) + "...";
	}

	var clickHandler = function(data){
		selectedCountyName = cMap.labels()[countyLayerIx][allCountyXAxisLabels.indexOf(data.category)];
		drillToCounty(allCountyXAxisLabels.indexOf(data.category));
		enableGetDirections();
		lastSelectedChartCountyName = selectedCountyName;
	}
	
	this.renderNewColumnChart({divId:"caByCountyChart", 
						title:chartTitle, subtitle:"(click a county column to drill to it)", 
						vals:colVals, lbls:xAxisLabels, clickHandler:clickHandler});
}

ColumnChartCard.prototype.buildStoreChart = function(){
	
	var allStoreXAxisLabels = [];

	var lastSelectedChartCountyName = "";

	var colVals = [];
	var xAxisLabels = [];

	var storesLyr = cMap.getLayerAt(storeLayerIx);
	if(!storesLyr){return;}

	storesLyr.restrictCalcsToViewport = true;
	storesLyr.restrictCalcsToVisible = true;

	var chartTitle = selectedCountyName + " County Revenue by Store";
	colVals = storesLyr.getValues();
	xAxisLabels = storesLyr.getLabels();

	var arrObjsToSort = [];
	for(var l0=0;l0<colVals.length;l0++){

		arrObjsToSort.push({value: colVals[l0], label: xAxisLabels[l0]});
	}

	//sort the data
	var sortedObjs = uf.getCollIterator(arrObjsToSort);
	sortedObjs = uf.getCollIterator(sortedObjs.getSortedArrayObjsByFieldAscending("value"));
	colVals = sortedObjs.getColumnFromObjsByField("value");
	xAxisLabels = sortedObjs.getColumnFromObjsByField("label");

	//trim x-axis labels
	for(var l=0;l<xAxisLabels.length;l++){
		xAxisLabels[l] = xAxisLabels[l].substring(0,12) + "...";
	}

	storesLyr.restrictCalcsToViewport = false;
	storesLyr.restrictCalcsToVisible = false;
	allStoreXAxisLabels = storesLyr.getLabels();

	//store all trimmed labels for index matching purposes on chart column select
	for(var l2=0;l2<allStoreXAxisLabels.length;l2++){
		allStoreXAxisLabels[l2] = allStoreXAxisLabels[l2].substring(0,12) + "...";
	}
	
	var that = this;
	var clickHandler = function(data){

		that.panZoomToStore(allStoreXAxisLabels.indexOf(data.category));
	}
	
	this.renderNewColumnChart({divId:"countyByStoreChart", 
								title:chartTitle, subtitle:"(click a store column to go to it)", 
								vals:colVals, lbls:xAxisLabels, clickHandler:clickHandler});
}

ColumnChartCard.prototype.panZoomToStore = function(strChldIx){
	
	this.cMap.panZoomTo(cMap.getLayerAt(storeLayerIx).getCleansedLayerLocation(strChldIx).toCsvLatLon());
	this.cMap.zoomLevel(cMap.getZoomLevel()-2);
}

ColumnChartCard.prototype.renderNewColumnChart = function(opts){
	
	var strUtil = this._utilFactory.getStringUtil();
	Highcharts.setOptions({
		chart: {
			style: {
				fontFamily: 'arial'
			}
		}
	});
	
	this.domObjByRandField(opts.divId).highcharts({

		chart: {
			zoomType: 'xy'
		},
		title: {
			text: opts.title
		},
		subtitle: {
			text: opts.subtitle
		},
		xAxis: [{
			categories: opts.lbls,
			labels: {
				staggerLines: 1,
				rotation: 90
			}
		}],
		yAxis: [{ // Primary yAxis
			labels: {
				formatter: function () {
					return strUtil.getFormattedAbbreviatedDisplayValue(this.value);
				},
				style: {
					color: Highcharts.getOptions().colors[1]
				}
			},
			title: {
				text: 'Revenue',
				style: {
					color: Highcharts.getOptions().colors[1]
				}
			}
		}],
		tooltip: {
			shared: true
		},
		legend: {
			enabled:false
		},
		plotOptions: {
			series: {
				cursor: 'pointer',
				point: {
					events: {
						click: function () {
							opts.clickHandler(this);
						}
					}
				}
			}/*,
			column: {
				colorByPoint: true
			}*/
		},
		//colors: clrs,
		series: [{
			name: "Revenue",
			type: 'column',
			yAxis: 0,
			data: opts.vals,
			tooltip: {
				valueSuffix: ''
			}
		}]
	});	
}
	
})()

ColumnChartCardMarkup.txt Content

 

<div style="
    
    position: fixed;
    left: 372px;
    bottom: 10px;
    width: 636px;
    height: 270px;
    ">

	Store Charts

	<div style="height:100%;width: 100%;background-color:#ffffff;position: absolute;bottom:0px;">
		<div class="colChart" id="caByCountyChart"></div>
		<div class="colChart" id="countyByStoreChart" style="display:none"></div>
	</div>

</div>


<style type="text/css">

</style>
[/ezcol_2third] [ezcol_1third_end] [post-content id=7776] [/ezcol_1third_end]