[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>";
}
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>