Custom Popup Style and Grafana Integration

5 min read

Grafana integration

Author: Marko Polovina, Frontend Developer at GIS Cloud

 
Info popup is one of our standard UI components to visualize feature data. By default, the component is available in any GIS Cloud application. But sometimes, we want to customize popups to adjust the style or to integrate with other apps. In that case, we can use API to achieve that.
 
Before we start, look at our developer’s site and GIS Cloud JavaScript API documentation
 

About the data

 
For our example, we use storm data from the NOAA. The original raw dataset contains the following:
 

 
Every event has a location, so it’s easy to display the dataset on a map.
 
storm data
 
We will focus on a few columns to create an informative portal with clean info popup:
 

 

Let’s start coding!

 
It’s time to set up your Map Portal app. To be able to do so, you will need first to upload data and create a map in GIS Cloud Map Editor. Then, go to the App builder application and build your map portal using created maps.
 
If you need additional instructions on how to create your own Map Portal, take a look at this example or contact us directly.
 
When your Map Portal is up, your map is populated with data, and you are done with the initial portal customization and branding, it’s time to start coding.
 
Get data from layer
 


giscloud.features.byLayer(, {
   geometry: "wkt"
}).done(function(features) {
   console.log(features);
   // ...
});

 

Create points on the map

 


features.forEach(function(feature) {
   var pointGraphic = {
       color: new giscloud.Color(0, 0, 0, 100),
       fill: feature.data.DEATHS && feature.data.DEATHS !== "0" ? new giscloud.Color.fromHex("e6312e") : new giscloud.Color.fromHex("3a2ee6"),
       size: 8,
       border: 2,
       shape: "circle"
   };
   var pointStyle = new giscloud.GraphicStyle(pointGraphic);
   var point = new giscloud.GraphicFeature(giscloud.geometry.fromOGC(feature.geometry), pointStyle);
   giscloud.ui.map.graphic.add(point);
   // ...
});

 

Add animation to red points

 


if (feature.data.DEATHS && feature.data.DEATHS !== "0") {
   $(".leaflet-marker-pane .leaflet-marker-icon:last-child").addClass("animated-icon");
}


.leaflet-marker-icon.animated-icon {
   animation: highlight 2s linear infinite;
}
@keyframes highlight {
   0% {
       width: 8px;
       height: 8px;
       opacity: 0.3;
   }
   50% {
       opacity: 1.0;
   }
   70% {
       border: 1px solid rgba(230, 49, 46, 0.5);
   }
   100% {
       width: 18px;
       height: 18px;
       opacity: 0.3;
       border: 1px solid rgba(230, 49, 46, 0.2);
   }
}

 

Enable info popup on point click

 


point.bind("click", function() {
   gcapp.selo.showRecordInfo(this.feature, false, giscloud.geometry.fromOGC(this.feature.geometry));
});

 

Change info popup values before render

 


gcapp.selo.addEvent("beforeshowrecordinfo", processPopupDataBeforeRender);
 
function processPopupDataBeforeRender(evt) {
   $.each(evt.tabledata, function(fieldIndex, item) {
       switch(item.fieldName) {
           case "event_type":
               // change column name from 'event_type' to 'EVENT TYPE'
               item.name = "EVENT TYPE";
               break;
           case "TIME":
               // change TIME column format from 830 to 8:30
               item.value = item.value.substr(0, item.value.length - 2) + ":" + item.value.substr(item.value.length - 2);
               break;
           case "DEATHS":
               // add red color to column value if value bigger then 0
               if (item.value !== "0") {
                   item.value = "" + item.value + "";
               }
               break;
           case "INJURIES":
               // add red color to column value if value bigger than 0
               if (item.value !== "0") {
                   item.value = "" + item.value + "";
               }
               break;
           case "EVENT NARRATIVE":
               // change column value to link with onclick event
               if (item.value && item.value !== " ") {
                   activeInfo.eventNarrative = item.value;
                   item.value = 'View';
               } else {
                   item.value = "NONE";
               }
               break;
           case "EPISODE NARRATIVE":
               // change column value to link with onclick event
               if (item.value && item.value !== " ") {
                   activeInfo.episodeNarrative = item.value;
                   item.value = 'View';
               } else {
                   item.value = "NONE";
               }
               break;
           case "DAMAGE PROPERTY":
               // load Grafana chart
               item.value = '<iframe src="https://nagios1.cld.gcld.io:3002/d-solo/lrdGEid4z/storm-data?orgId=3&from=1668656457358&to=1668678057358&panelId=2" width="300" height="120" frameborder="0"> 
DAMAGE = ' + item.value + '$'; break; } }); }

 

FINAL RESULT

 
This blog post showed you how to create a custom portal to visualize lightning strike events and get a decision-making tool. Take a look at the final result: Map Storm Data 2007 – Example
 
storm data
 
You can find our last development blog post here.
 
Also, don’t hesitate to contact us if you have any questions, comments, or ideas for a new development example. And if you need any help with development, take a look at our Services page.
 
Happy coding!
 

Follow GIS Cloud 

Terms of use & Privacy policy  © GIS Cloud Ltd