This sample application demonstrates the clustering of spot objects on a map. Initially the spots are unclustered. When clicking the toggle button the objects are grouped together depending on their location. The number in the cluster object indicates the amount of objects clustered together. If you click on a cluster object a popover will open and show the list of all objects' tooltips. You can zoom in and out and see how the clustering changes depending on the zoom level. When you move the mouse over a cluster you can see the underlying area of the involved spots.
We start placing a GeoMap
control on the view with a spot aggregation. The properties of the spots are listed in json-file: index, geo location, tooltip and status. Status is defined as CustomData
, which is a map with a key - value pair. The Spots aggregation needs a customProperties
property which points to it.
<vbm:GeoMap id='vbi' width="100%" height="100%" initialZoom='6' initialPosition="9.3;52;0"> <vbm:vos> <vbm:Spots customProperties="{= ['status']}" items="{/spots}"> <vbm:items> <vbm:Spot position='{A1}' tooltip='{A2}' type='Success'> <vbm:customData> <core:CustomData key='status' value='{status}' /> </vbm:customData> </vbm:Spot> </vbm:items> </vbm:Spots> </vbm:vos> </vbm:GeoMap>
{ "spots": [ {"VB:ix":"0","A1":"9.22622;52.47909;0","A2": "LTL001001", "status":"good"}, {"VB:ix":"1","A1":"11.01954;53.38237;0","A2": "LTL001002", "status":"good"} ... ] }
onInit: function() { this.oVBI = null; this.oCurrentClustering = null; var oController = this; var oModel = new sap.ui.model.json.JSONModel(); oModel.setSizeLimit(99999); $.getJSON("media/clusterUnclustered.json", function(data) { oModel.setData(data); oController.oData = data; }); this.getView().setModel(oModel); this.oVBI = this.getView().byId("vbi"); }
In function onInit
we do some initialization for controller variables.
Then we create a JSONModel
, get the data from the json file and assign it to the view.
The model will serve as data source for our spots
.
Note that we need to extend the size limit for the model because we specify more than 100 spot items.
onToggleCluster: function(e) { var bCluster = e.getParameter("pressed"); if (bCluster) { if (!this.oCurrentClustering) { this.oCurrentClustering = new sap.ui.vbm.ClusterTree({ rule: "status=good", click: this.onClickCluster.bind(this), vizTemplate: new sap.ui.vbm.Cluster({ type: "Success", icon: 'sap-icon://shipping-status' }) }); } this.oVBI.addCluster(this.oCurrentClustering); e.getSource().setText("Cluster off"); } else { this.oVBI.removeCluster(this.oCurrentClustering); e.getSource().setText("Cluster on"); } }
The function onToggleCluster
turns the clustering mode on or off depending on the toggle button press state.
The clustering aggregation object is created when it is called for the first time. In our sample we define a ClusterTree object
.
The rule defines which items will be clustered. The click event is bound to an onClickCluster
method.
The vizTemplate
is the aggregation we use to define a control that serves as a visualization template for our cluster.
In our sample we specify the Cluster
control with the properties semantic type and an icon to show.
Finally our GeoMap
control adds or removes the clustering object.
onClickCluster: function( evt ){ var oTarget = evt.getParameter("instance").getItem(); var ident = evt.getParameter("instance").getKey(); var type = sap.ui.vbm.ClusterInfoType.ContainedVOs; var info = this.oVBI.getInfoForCluster(ident, type); var cluster = []; for (var j = 0; j < info.length; j++) { var spot = this.oVBI.getVoByInternalId(info[j]); if (spot) { cluster.push({name: spot.getTooltip()}); } } var oClusterModel = new sap.ui.model.json.JSONModel(); oClusterModel.setSizeLimit(99999); oClusterModel.setData({"cluster":cluster}); var oPopover = new sap.m.Popover({ title: "Cluster Details", placement:"Right", content: new sap.m.List({ items:{ path: "/cluster", template: new sap.m.StandardListItem({ title: '{name}', icon: 'sap-icon://shipping-status' }) } })}); oPopover.setModel(oClusterModel); .... }
The function onClickCluster
shows some detail information on a cluster object when it is clicked.
To get this information we need to call method getInfoForCluster
on our GeoMap control.
First parameter identifies the cluster itself, second parameter specifies the type of information needed.
The returned info is an array of internal IDs, and to get the spots out of them we use the method getVoByInternalId
.
The spots' tooltips are assembled in an array and set as data into a new model.
We define a popover with a list of items to show it.
The list gets a single list item element assigned to the items aggregation - acting as a template for the aggregation binding. The attribute 'title' of the template object are bound to model attribute 'name'.