diff --git a/src/css/worldmap-panel.css b/src/css/worldmap-panel.css
index 94cab8b..70ebaf5 100644
--- a/src/css/worldmap-panel.css
+++ b/src/css/worldmap-panel.css
@@ -6,8 +6,8 @@
   padding: 6px 8px;
   font: 14px/16px Arial, Helvetica, sans-serif;
   background: white;
-  background: rgba(255,255,255,0.8);
-  box-shadow: 0 0 15px rgba(0,0,0,0.2);
+  background: rgba(255, 255, 255, 0.8);
+  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
   border-radius: 5px;
 }
 .info h4 {
@@ -33,10 +33,58 @@
   opacity: 0.7;
 }
 
-.leaflet-top.leaflet-left, .leaflet-bottom.leaflet-left, .leaflet-bottom.leaflet-right {
+.leaflet-top.leaflet-left,
+.leaflet-bottom.leaflet-left,
+.leaflet-bottom.leaflet-right {
   z-index: 1000;
 }
 
-.leaflet-popup-content-wrapper, .leaflet-popup-tip {
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
   color: #d8d9da !important;
 }
+
+.margin-top-8 {
+  margin-top: 8px;
+}
+.tooltip-container {
+  max-height: 100px;
+  overflow: auto;
+  color: #666666;
+}
+
+.info.aggregations.leaflet-control {
+  color: #666666;
+  font-size: 11px;
+  width: 100%;
+}
+.agg-container {
+  max-height: 90px;
+  overflow: auto;
+}
+.agg-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.agg-item > div:first-child {
+  min-width: 70px;
+  display: flex;
+}
+.agg-label {
+  width: 40px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  margin-right: 2px;
+}
+.agg-bar {
+  flex: 1;
+  margin-left: 5px;
+  margin-bottom: 2px;
+}
+
+.agg-bar-progress {
+  background: #0078a8;
+  font-size: 0;
+}
diff --git a/src/css/worldmap.light.css b/src/css/worldmap.light.css
index 2ead013..a97b73d 100644
--- a/src/css/worldmap.light.css
+++ b/src/css/worldmap.light.css
@@ -1,4 +1,3 @@
 .worldmap-popup .leaflet-popup-content-wrapper, .worldmap-popup .leaflet-popup-tip {
   background-color: #ECECEC;
-  color: #000 !important;
 }
diff --git a/src/data_formatter.ts b/src/data_formatter.ts
index 13121f0..065226d 100644
--- a/src/data_formatter.ts
+++ b/src/data_formatter.ts
@@ -22,7 +22,12 @@ export default class DataFormatter {
         }
 
         if (_.isString(lastValue)) {
-          data.push({ key: serie.alias, value: 0, valueFormatted: lastValue, valueRounded: 0 });
+          data.push({
+            key: serie.alias,
+            value: 0,
+            valueFormatted: lastValue,
+            valueRounded: 0
+          });
         } else {
           const dataValue = {
             key: serie.alias,
@@ -31,7 +36,7 @@ export default class DataFormatter {
             locationLongitude: location.longitude,
             value: serie.stats[this.ctrl.panel.valueName],
             valueFormatted: lastValue,
-            valueRounded: 0,
+            valueRounded: 0
           };
 
           if (dataValue.value > highestValue) {
@@ -42,7 +47,10 @@ export default class DataFormatter {
             lowestValue = dataValue.value;
           }
 
-          dataValue.valueRounded = kbn.roundValue(dataValue.value, parseInt(this.ctrl.panel.decimals, 10) || 0);
+          dataValue.valueRounded = kbn.roundValue(
+            dataValue.value,
+            parseInt(this.ctrl.panel.decimals, 10) || 0
+          );
           data.push(dataValue);
         }
       });
@@ -61,10 +69,13 @@ export default class DataFormatter {
       locationLongitude: decodedGeohash.longitude,
       value: value,
       valueFormatted: value,
-      valueRounded: 0,
+      valueRounded: 0
     };
 
-    dataValue.valueRounded = kbn.roundValue(dataValue.value, this.ctrl.panel.decimals || 0);
+    dataValue.valueRounded = kbn.roundValue(
+      dataValue.value,
+      this.ctrl.panel.decimals || 0
+    );
     return dataValue;
   }
 
@@ -93,7 +104,12 @@ export default class DataFormatter {
               : encodedGeohash;
             const value = row[columnNames[this.ctrl.panel.esMetric]];
 
-            const dataValue = this.createDataValue(encodedGeohash, decodedGeohash, locationName, value);
+            const dataValue = this.createDataValue(
+              encodedGeohash,
+              decodedGeohash,
+              locationName,
+              value
+            );
             if (dataValue.value > highestValue) {
               highestValue = dataValue.value;
             }
@@ -117,7 +133,12 @@ export default class DataFormatter {
               : encodedGeohash;
             const value = datapoint[this.ctrl.panel.esMetric];
 
-            const dataValue = this.createDataValue(encodedGeohash, decodedGeohash, locationName, value);
+            const dataValue = this.createDataValue(
+              encodedGeohash,
+              decodedGeohash,
+              locationName,
+              value
+            );
             if (dataValue.value > highestValue) {
               highestValue = dataValue.value;
             }
@@ -169,9 +190,12 @@ export default class DataFormatter {
         let key;
         let longitude;
         let latitude;
+        let metricFieldChoosen: number;
+        let metricFieldNaN;
 
         if (this.ctrl.panel.tableQueryOptions.queryType === 'geohash') {
-          const encodedGeohash = datapoint[this.ctrl.panel.tableQueryOptions.geohashField];
+          const encodedGeohash =
+            datapoint[this.ctrl.panel.tableQueryOptions.geohashField];
           const decodedGeohash = decodeGeoHash(encodedGeohash);
 
           latitude = decodedGeohash.latitude;
@@ -179,20 +203,40 @@ export default class DataFormatter {
           key = encodedGeohash;
         } else {
           latitude = datapoint[this.ctrl.panel.tableQueryOptions.latitudeField];
-          longitude = datapoint[this.ctrl.panel.tableQueryOptions.longitudeField];
+          longitude =
+            datapoint[this.ctrl.panel.tableQueryOptions.longitudeField];
           key = `${latitude}_${longitude}`;
         }
-
+        let locationName;
+        if (this.ctrl.panel.tableQueryOptions.metricField === 'TAS') {
+          locationName =  (datapoint[this.ctrl.panel.tableQueryOptions.labelField] || datapoint["Name"]);
+          if (datapoint["State"] === "ACTIVE"){
+            metricFieldChoosen = 11;
+          }else{
+            metricFieldChoosen = -1;
+          }
+          metricFieldNaN = true;
+        } else {
+          metricFieldChoosen =
+            datapoint[this.ctrl.panel.tableQueryOptions.metricField];
+          metricFieldNaN = false;
+          locationName =  (datapoint[this.ctrl.panel.tableQueryOptions.labelField] || "n/a");
+        }
         const dataValue = {
           key: key,
-          locationName: datapoint[this.ctrl.panel.tableQueryOptions.labelField] || 'n/a',
+          locationName: locationName,
           locationLatitude: latitude,
           locationLongitude: longitude,
-          value: datapoint[this.ctrl.panel.tableQueryOptions.metricField],
-          valueFormatted: datapoint[this.ctrl.panel.tableQueryOptions.metricField],
+          value: metricFieldChoosen || 0,
+          valueFormatted:
+            datapoint[this.ctrl.panel.tableQueryOptions.metricField],
           valueRounded: 0,
+          isMetricFieldNaN: metricFieldNaN
         };
-
+        if (this.ctrl.panel.aggregationLegendField !== '') {
+          dataValue[`agg-${this.ctrl.panel.aggregationLegendField}`] =
+            datapoint[this.ctrl.panel.aggregationLegendField];
+        }
         if (dataValue.value > highestValue) {
           highestValue = dataValue.value;
         }
@@ -201,10 +245,38 @@ export default class DataFormatter {
           lowestValue = dataValue.value;
         }
 
-        dataValue.valueRounded = kbn.roundValue(dataValue.value, this.ctrl.panel.decimals || 0);
-        data.push(dataValue);
+        dataValue.valueRounded = kbn.roundValue(
+          dataValue.value,
+          this.ctrl.panel.decimals || 0
+        );
+        if (latitude && longitude) {
+          data.push(dataValue);
+        }
       });
-
+      // Getting the List of columns from the table row
+      data.columns = Object.keys(tableData[0][0] || []);
+      // Aggregations
+      if (
+        (this.ctrl.panel.aggregationLegendField !== '' &&
+          data.columns.indexOf(this.ctrl.panel.aggregationLegendField) > -1) ||
+        !tableData[0][0]
+      ) {
+        data.aggregations = _.countBy(
+          data,
+          `agg-${this.ctrl.panel.aggregationLegendField}`
+        );
+        data.aggregations.unknown =
+          data.aggregations.Undefined || 0 + data.aggregations[''] || 0;
+        delete data.aggregations.undefined;
+        delete data.aggregations[''];
+        data.aggregationSortedList = Object.keys(data.aggregations).sort(
+          function(a, b) {
+            return data.aggregations[b] - data.aggregations[a];
+          }
+        );
+      } else {
+        data.aggregations = {};
+      }
       data.highestValue = highestValue;
       data.lowestValue = lowestValue;
       data.valueRange = highestValue - lowestValue;
@@ -223,7 +295,7 @@ export default class DataFormatter {
           locationLatitude: point.latitude,
           locationLongitude: point.longitude,
           value: point.value !== undefined ? point.value : 1,
-          valueRounded: 0,
+          valueRounded: 0
         };
         if (dataValue.value > highestValue) {
           highestValue = dataValue.value;
diff --git a/src/partials/editor.html b/src/partials/editor.html
index 63c474e..6720596 100644
--- a/src/partials/editor.html
+++ b/src/partials/editor.html
@@ -1,50 +1,119 @@
-<div class="editor-row">
+<!--//Broadcom has made changes to this file -->
+
+<div class="editor-row" xmlns="http://www.w3.org/1999/html">
   <div class="section gf-form-group">
     <h5 class="section-heading">Map Visual Options</h5>
     <div class="gf-form">
       <label class="gf-form-label width-10">Center</label>
       <div class="gf-form-select-wrapper max-width-10">
-        <select class="input-small gf-form-input" ng-model="ctrl.panel.mapCenter" ng-options="t for t in ['(0°, 0°)', 'North America', 'Europe', 'West Asia', 'SE Asia', 'custom', 'Last GeoHash']"
-          ng-change="ctrl.setNewMapCenter()"></select>
+        <select
+          class="input-small gf-form-input"
+          ng-model="ctrl.panel.mapCenter"
+          ng-options="t for t in ['(0°, 0°)', 'North America', 'Europe', 'West Asia', 'SE Asia', 'custom', 'Last GeoHash']"
+          ng-change="ctrl.setNewMapCenter()"
+        ></select>
       </div>
       <div class="gf-form" ng-show="ctrl.panel.mapCenter === 'custom'">
-        <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.mapCenterLatitude" ng-change="ctrl.setNewMapCenter()"
-          ng-model-onblur />
-        <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.mapCenterLongitude" ng-change="ctrl.setNewMapCenter()"
-          ng-model-onblur />
+        <input
+          type="text"
+          class="input-small gf-form-input width-10"
+          ng-model="ctrl.panel.mapCenterLatitude"
+          ng-change="ctrl.setNewMapCenter()"
+          ng-model-onblur
+        />
+        <input
+          type="text"
+          class="input-small gf-form-input width-10"
+          ng-model="ctrl.panel.mapCenterLongitude"
+          ng-change="ctrl.setNewMapCenter()"
+          ng-model-onblur
+        />
       </div>
     </div>
     <div class="gf-form">
       <label class="gf-form-label width-10">Initial Zoom</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.initialZoom" ng-change="ctrl.setZoom()"
-        placeholder="1" ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.initialZoom"
+        ng-change="ctrl.setZoom()"
+        placeholder="1"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form">
       <label class="gf-form-label width-10">Min Circle Size</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.circleMinSize" ng-change="ctrl.render()"
-        placeholder="2" ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.circleMinSize"
+        ng-change="ctrl.render()"
+        placeholder="2"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form">
       <label class="gf-form-label width-10">Max Circle Size</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.circleMaxSize" ng-change="ctrl.render()"
-        placeholder="30" ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.circleMaxSize"
+        ng-change="ctrl.render()"
+        placeholder="30"
+        ng-model-onblur
+      />
     </div>
-    <gf-form-switch class="gf-form" label="Sticky Labels" label-class="width-10" checked="ctrl.panel.stickyLabels" on-change="ctrl.toggleStickyLabels()">
+    <gf-form-switch
+      class="gf-form"
+      label="Sticky Labels"
+      label-class="width-10"
+      checked="ctrl.panel.stickyLabels"
+      on-change="ctrl.toggleStickyLabels()"
+    >
     </gf-form-switch>
     <div class="gf-form">
       <label class="gf-form-label width-10">Decimals</label>
-      <input type="number" class="input-small gf-form-input width-10" ng-model="ctrl.panel.decimals" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="number"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.decimals"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form">
       <label class="gf-form-label width-10">Unit</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.unitSingular" placeholder="singular form"
-        ng-change="ctrl.render()" ng-model-onblur />
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.unitPlural" placeholder="plural form"
-        ng-change="ctrl.render()" ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.unitSingular"
+        placeholder="singular form"
+        ng-change="ctrl.render()"
+        ng-model-onblur
+      />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.unitPlural"
+        placeholder="plural form"
+        ng-change="ctrl.render()"
+        ng-model-onblur
+      />
     </div>
-    <gf-form-switch class="gf-form" label="Show Legend" label-class="width-10" checked="ctrl.panel.showLegend" on-change="ctrl.toggleLegend()"></gf-form-switch>
-    <gf-form-switch class="gf-form" label="Mouse Wheel Zoom" label-class="width-10" checked="ctrl.panel.mouseWheelZoom" on-change="ctrl.toggleMouseWheelZoom()"></gf-form-switch>
+    <gf-form-switch
+      class="gf-form"
+      label="Show Legend"
+      label-class="width-10"
+      checked="ctrl.panel.showLegend"
+      on-change="ctrl.toggleLegend()"
+    ></gf-form-switch>
+    <gf-form-switch
+      class="gf-form"
+      label="Mouse Wheel Zoom"
+      label-class="width-10"
+      checked="ctrl.panel.mouseWheelZoom"
+      on-change="ctrl.toggleMouseWheelZoom()"
+    ></gf-form-switch>
   </div>
   <div class="section gf-form-group">
     <h5 class="section-heading">Map Data Options</h5>
@@ -52,161 +121,379 @@ <h5 class="section-heading">Map Data Options</h5>
       <div class="gf-form">
         <label class="gf-form-label width-12">Location Data</label>
         <div class="gf-form-select-wrapper max-width-10">
-          <select class="input-small gf-form-input" ng-model="ctrl.panel.locationData" ng-options="t for t in ['countries', 'countries_3letter', 'states', 'probes', 'geohash', 'json endpoint', 'jsonp endpoint', 'json result', 'table']"
-            ng-change="ctrl.changeLocationData()"></select>
+          <select
+            class="input-small gf-form-input"
+            ng-model="ctrl.panel.locationData"
+            ng-options="t for t in ['countries', 'countries_3letter', 'states', 'probes', 'geohash', 'json endpoint', 'jsonp endpoint', 'json result', 'table']"
+            ng-change="ctrl.changeLocationData()"
+          ></select>
         </div>
       </div>
       <div class="gf-form" ng-show="ctrl.panel.locationData !== 'geohash'">
         <label class="gf-form-label width-12">Aggregation</label>
         <div class="gf-form-select-wrapper max-width-10">
-          <select class="input-small gf-form-input" ng-model="ctrl.panel.valueName" ng-options="f for f in ['min','max','avg', 'current', 'total']"
-            ng-change="ctrl.refresh()"></select>
+          <select
+            class="input-small gf-form-input"
+            ng-model="ctrl.panel.valueName"
+            ng-options="f for f in ['min','max','avg', 'current', 'total']"
+            ng-change="ctrl.refresh()"
+          ></select>
         </div>
       </div>
-      <div class="gf-form" ng-show="ctrl.panel.locationData === 'json endpoint'">
+      <div
+        class="gf-form"
+        ng-show="ctrl.panel.locationData === 'json endpoint'"
+      >
         <label class="gf-form-label width-12">Endpoint url</label>
-        <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.jsonUrl" ng-change="ctrl.refresh()" ng-model-onblur
+        <input
+          type="text"
+          class="input-small gf-form-input width-10"
+          ng-model="ctrl.panel.jsonUrl"
+          ng-change="ctrl.refresh()"
+          ng-model-onblur
         />
       </div>
-      <div class="gf-form" ng-show="ctrl.panel.locationData === 'jsonp endpoint'">
+      <div
+        class="gf-form"
+        ng-show="ctrl.panel.locationData === 'jsonp endpoint'"
+      >
         <label class="gf-form-label width-12">Endpoint url</label>
-        <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.jsonpUrl" ng-change="ctrl.refresh()" ng-model-onblur
+        <input
+          type="text"
+          class="input-small gf-form-input width-10"
+          ng-model="ctrl.panel.jsonpUrl"
+          ng-change="ctrl.refresh()"
+          ng-model-onblur
         />
       </div>
-      <div class="gf-form" ng-show="ctrl.panel.locationData === 'jsonp endpoint'">
+      <div
+        class="gf-form"
+        ng-show="ctrl.panel.locationData === 'jsonp endpoint'"
+      >
         <label class="gf-form-label width-12">Jsonp Callback</label>
-        <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.jsonpCallback" ng-change="ctrl.refresh()"
-          ng-model-onblur />
+        <input
+          type="text"
+          class="input-small gf-form-input width-10"
+          ng-model="ctrl.panel.jsonpCallback"
+          ng-change="ctrl.refresh()"
+          ng-model-onblur
+        />
       </div>
     </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.panel.locationData ==='countries'">
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.panel.locationData ==='countries'"
+    >
       <h5>Mapping Between Time Series Query and Worldmap</h5>
-      <p>The query should be formatted as Time Series data. The time series (group by) name should be a 2-letter country code.
-        For example: US for United States or FR for France.</p>
+      <p>
+        The query should be formatted as Time Series data. The time series
+        (group by) name should be a 2-letter country code. For example: US for
+        United States or FR for France.
+      </p>
     </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.panel.locationData ==='countries_3letter'">
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.panel.locationData ==='countries_3letter'"
+    >
       <h5>Mapping Between Time Series Query and Worldmap</h5>
-      <p>The query should be formatted as Time Series data. The time series (group by) name should be a 3-letter country code.
-        For example: USA for United States or FRA for France.</p>
+      <p>
+        The query should be formatted as Time Series data. The time series
+        (group by) name should be a 3-letter country code. For example: USA for
+        United States or FRA for France.
+      </p>
     </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.panel.locationData ==='states'">
-        <h5>Mapping Between Time Series Query and Worldmap</h5>
-        <p>The query should be formatted as Time Series data. The time series (group by) name should be a 2-letter US state code.
-          For example: CA for California.</p>
-      </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.panel.locationData ==='geohash'">
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.panel.locationData ==='states'"
+    >
+      <h5>Mapping Between Time Series Query and Worldmap</h5>
+      <p>
+        The query should be formatted as Time Series data. The time series
+        (group by) name should be a 2-letter US state code. For example: CA for
+        California.
+      </p>
+    </div>
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.panel.locationData ==='geohash'"
+    >
       <h5>Mapping Between Geohash Query and Worldmap</h5>
-      <p>The query should be an Elasticsearch using the Geo Hash Grid feature or a Prometheus query that returns geohashes.</p>
+      <p>
+        The query should be an Elasticsearch using the Geo Hash Grid feature or
+        a Prometheus query that returns geohashes.
+      </p>
       <ul>
         <li>
-          <b>Location Name Field (optional)</b>: enter the name of the Location Name column. Used to label each circle on the
-          map. If it is empty then the geohash value is used as the label.</li>
+          <b>Location Name Field (optional)</b>: enter the name of the Location
+          Name column. Used to label each circle on the map. If it is empty then
+          the geohash value is used as the label.
+        </li>
         <li>
-          <b>geo_point/geohash Field</b>: enter the name of the geo_point/geohash column. This is used to calculate where the
-          circle should be drawn.</li>
+          <b>geo_point/geohash Field</b>: enter the name of the
+          geo_point/geohash column. This is used to calculate where the circle
+          should be drawn.
+        </li>
         <li>
-          <b>Metric Field</b>: enter the name of the metric column. This is used to give the circle a value - this determines
-          how large the circle is.</li>
+          <b>Metric Field</b>: enter the name of the metric column. This is used
+          to give the circle a value - this determines how large the circle is.
+        </li>
       </ul>
     </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.showTableGeohashOptions()">
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.showTableGeohashOptions()"
+    >
       <h5>Mapping Between Table Query and Worldmap</h5>
-      <p>The query should be formatted as Table data and have a geohash column and a numeric metric column.</p>
+      <p>
+        The query should be formatted as Table data and have a geohash column
+        and a numeric metric column.
+      </p>
       <ul>
         <li>
-          <b>Location Name Field (optional)</b>: enter the name of the Location Name column. Used to label each circle on the
-          map. If it is empty then the geohash value is used as the label.</li>
+          <b>Location Name Field (optional)</b>: enter the name of the Location
+          Name column. Used to label each circle on the map. If it is empty then
+          the geohash value is used as the label.
+        </li>
         <li>
-          <b>Geohash Field</b>: enter the name of the geohash column. This is used to calculate where the circle should be drawn.</li>
+          <b>Geohash Field</b>: enter the name of the geohash column. This is
+          used to calculate where the circle should be drawn.
+        </li>
         <li>
-          <b>Metric Field</b>: enter the name of the metric column. This is used to give the circle a value - this determines
-          how large the circle is.</li>
+          <b>Metric Field</b>: enter the name of the metric column. This is used
+          to give the circle a value - this determines how large the circle is.
+        </li>
       </ul>
     </div>
-    <div class="grafana-info-box max-width-28" ng-show="ctrl.showTableCoordinateOptions()">
+    <div
+      class="grafana-info-box max-width-28"
+      ng-show="ctrl.showTableCoordinateOptions()"
+    >
       <h5>Mapping Between Table Query and Worldmap</h5>
-      <p>The query should be formatted as Table data and contain latitude, longitude columns and a numeric metric column.</p>
+      <p>
+        The query should be formatted as Table data and contain latitude,
+        longitude columns and a numeric metric column.
+      </p>
       <ul>
         <li>
-          <b>Location Name Field (optional)</b>: enter the name of the Location Name column. Used to label each circle on the
-          map. If it is empty then the value N/A is used as the label.</li>
+          <b>Location Name Field (optional)</b>: enter the name of the Location
+          Name column. Used to label each circle on the map. If it is empty then
+          the value N/A is used as the label.
+        </li>
         <li>
-          <b>Latitude/Longitude Fields</b>: enter the name of the latitude and longitude columns. These are used to calculate
-          where the circle should be drawn.</li>
+          <b>Latitude/Longitude Fields</b>: enter the name of the latitude and
+          longitude columns. These are used to calculate where the circle should
+          be drawn.
+        </li>
         <li>
-          <b>Metric Field</b>: enter the name of the metric column. This is used to give the circle a value - this determines
-          how large the circle is.</li>
+          <b>Metric Field</b>: enter the name of the metric column. This is used
+          to give the circle a value - this determines how large the circle is.
+          If the selected Datasource is AIOps_Inventory, then specify the value as TAS.
+        </li>
       </ul>
     </div>
-    <h6 ng-show="ctrl.panel.locationData === 'table' || ctrl.panel.locationData === 'geohash'">Field Mapping</h6>
+    <h6
+      ng-show="ctrl.panel.locationData === 'table' || ctrl.panel.locationData === 'geohash'"
+    >
+      Field Mapping
+    </h6>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'table'">
       <label class="gf-form-label width-12">Table Query Format</label>
       <div class="gf-form-select-wrapper max-width-10">
-        <select class="input-small gf-form-input" ng-model="ctrl.panel.tableQueryOptions.queryType" ng-options="t for t in ['geohash', 'coordinates']"
-          ng-change="ctrl.refresh()"></select>
+        <select
+          class="input-small gf-form-input"
+          ng-model="ctrl.panel.tableQueryOptions.queryType"
+          ng-options="t for t in ['geohash', 'coordinates']"
+          ng-change="ctrl.refresh()"
+        ></select>
       </div>
     </div>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'table'">
       <label class="gf-form-label width-12">Location Name Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.tableQueryOptions.labelField" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.tableQueryOptions.labelField"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'table'">
       <label class="gf-form-label width-12">Metric Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.tableQueryOptions.metricField" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.tableQueryOptions.metricField"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.showTableGeohashOptions()">
       <label class="gf-form-label width-12">Geohash Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.tableQueryOptions.geohashField" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.tableQueryOptions.geohashField"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.showTableCoordinateOptions()">
       <label class="gf-form-label width-12">Latitude Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.tableQueryOptions.latitudeField" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.tableQueryOptions.latitudeField"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.showTableCoordinateOptions()">
       <label class="gf-form-label width-12">Longitude Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.tableQueryOptions.longitudeField" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.tableQueryOptions.longitudeField"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'geohash'">
       <label class="gf-form-label width-12">Location Name Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.esLocationName" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.esLocationName"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'geohash'">
       <label class="gf-form-label width-12">geo_point/geohash Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.esGeoPoint" ng-change="ctrl.refresh()"
-        ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.esGeoPoint"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form" ng-show="ctrl.panel.locationData === 'geohash'">
       <label class="gf-form-label width-12">Metric Field</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.esMetric" ng-change="ctrl.refresh()" ng-model-onblur
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.esMetric"
+        ng-change="ctrl.refresh()"
+        ng-model-onblur
       />
     </div>
+    <div ng-show="ctrl.panel.locationData === 'table'">
+      <div class="section gf-form-group">
+        <h5 class="section-heading margin-top-8">
+          Aggregations Legends
+          <tip
+            >When enabled, points that are plotted on the world map are aggregated by the selected <b> Aggregation_Field</b> and the aggregated result is displayed on the chart.
+          </tip>
+        </h5>
+        <gf-form-switch
+          class="gf-form"
+          label="Display Aggregations"
+          label-class="width-12"
+          checked="ctrl.panel.aggregationLegends"
+          on-change="ctrl.toggleAggregations()"
+        >
+        </gf-form-switch>
+        <div class="gf-form">
+          <label class="gf-form-label width-12">Aggregation Field</label>
+          <input
+            type="text"
+            class="input-small gf-form-input width-10"
+            ng-model="ctrl.panel.aggregationLegendField"
+            ng-change="ctrl.refresh()"
+            ng-model-onblur
+          />
+        </div>
+      </div>
+    </div>
+    <div ng-show="ctrl.panel.locationData === 'table'">
+      <div class="section gf-form-group">
+        <h5 class="section-heading margin-top-8">DrillDown</h5>
+        <div class="gf-form">
+          <label class="gf-form-label width-12"
+          >Target<tip>URL of the target where the service is deployed.<br>use ${__locationName} for the target value </br></tip></label
+          >
+          <input
+            type="text"
+            class="input-small gf-form-input width-30"
+            ng-model="ctrl.panel.drilldownTarget"
+            ng-change="ctrl.refresh()"
+            ng-model-onblur
+            placeholder="https://your-grafana-server/d/id/name?var-name=${__locationName}"
+          />
+        </div>
+        <gf-form-switch
+          class="gf-form"
+          label="Open in new tab"
+          label-class="width-12"
+          checked="ctrl.panel.drillDownTab"
+          on-change="ctrl.render()"
+        >
+        </gf-form-switch>
+      </div>
+    </div>
   </div>
 
   <div class="section gf-form-group">
     <h5 class="section-heading">Threshold Options</h5>
     <div class="gf-form">
       <label class="gf-form-label width-10">Thresholds</label>
-      <input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.thresholds" ng-change="ctrl.changeThresholds()"
-        placeholder="0,10" ng-model-onblur />
+      <input
+        type="text"
+        class="input-small gf-form-input width-10"
+        ng-model="ctrl.panel.thresholds"
+        ng-change="ctrl.changeThresholds()"
+        placeholder="0,10"
+        ng-model-onblur
+      />
     </div>
     <div class="gf-form">
       <label class="gf-form-label width-10">Colors</label>
-      <spectrum-picker class="gf-form-input width-3" ng-repeat="color in ctrl.panel.colors track by $index" ng-model="ctrl.panel.colors[$index]"
-        ng-change="ctrl.changeThresholds()"></spectrum-picker>
+      <spectrum-picker
+        class="gf-form-input width-3"
+        ng-repeat="color in ctrl.panel.colors track by $index"
+        ng-model="ctrl.panel.colors[$index]"
+        ng-change="ctrl.changeThresholds()"
+      ></spectrum-picker>
     </div>
   </div>
 
   <div class="section gf-form-group">
     <h5 class="section-heading">Hide series</h5>
-    <gf-form-switch class="gf-form" label="With only nulls" label-class="width-10" checked="ctrl.panel.hideEmpty" on-change="ctrl.render()">
+    <gf-form-switch
+      class="gf-form"
+      label="With only nulls"
+      label-class="width-10"
+      checked="ctrl.panel.hideEmpty"
+      on-change="ctrl.render()"
+    >
     </gf-form-switch>
-    <gf-form-switch class="gf-form" label="With only zeros" label-class="width-10" checked="ctrl.panel.hideZero" on-change="ctrl.render()">
+    <gf-form-switch
+      class="gf-form"
+      label="With only zeros"
+      label-class="width-10"
+      checked="ctrl.panel.hideZero"
+      on-change="ctrl.render()"
+    >
     </gf-form-switch>
   </div>
+  <!-- Regex-->
+	<div class="section gf-form-group">
+		<h5 class="section-heading">Regex</h5>
+		<div class="gf-form">
+		  <label class="gf-form-label width-8">Regex Pattern
+			<tip>Optional, The values in the specified column are filtered and displayed according to this regex. Ex: String: Url|broadcom.com|mirror|location-1 regex: /Url\|(.*?)\|/ Output: broadcom.com</tip>
+		  </label>
+		  <input type="text" class="gf-form-input" ng-model="ctrl.panel.regexPattern" ng-blur="ctrl.render()" placeholder="regex">
+		</div>
+	</div>
 </div>
diff --git a/src/plugin.json b/src/plugin.json
index 1afa70a..8f590d2 100644
--- a/src/plugin.json
+++ b/src/plugin.json
@@ -23,8 +23,8 @@
       {"name": "USA", "path": "images/worldmap-usa.png"},
       {"name": "Light Theme", "path": "images/worldmap-light-theme.png"}
     ],
-    "version": "1.0.1",
-    "updated": "Fri May 15 14:40:24 MDT 2020"
+    "version": "0.2.1",
+    "updated": "2019-08-29"
   },
 
   "dependencies": {
diff --git a/src/worldmap.ts b/src/worldmap.ts
index 341f9a6..0e52a93 100644
--- a/src/worldmap.ts
+++ b/src/worldmap.ts
@@ -4,19 +4,21 @@ import WorldmapCtrl from './worldmap_ctrl';
 
 const tileServers = {
   'CartoDB Positron': {
-    url: 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
+    url:
+      'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
     attribution:
       '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> ' +
       '&copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
-    subdomains: 'abcd',
+    subdomains: 'abcd'
   },
   'CartoDB Dark': {
-    url: 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png',
+    url:
+      'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png',
     attribution:
       '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> ' +
       '&copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
-    subdomains: 'abcd',
-  },
+    subdomains: 'abcd'
+  }
 };
 
 export default class WorldMap {
@@ -26,11 +28,14 @@ export default class WorldMap {
   map: any;
   legend: any;
   circlesLayer: any;
+  aggregations: any;
+  templateSrv: any;
 
-  constructor(ctrl, mapContainer) {
+  constructor(ctrl, mapContainer, templateSrv?) {
     this.ctrl = ctrl;
     this.mapContainer = mapContainer;
     this.circles = [];
+    this.templateSrv = templateSrv;
   }
 
   createMap() {
@@ -42,7 +47,7 @@ export default class WorldMap {
       worldCopyJump: true,
       preferCanvas: true,
       center: mapCenter,
-      zoom: parseInt(this.ctrl.panel.initialZoom, 10) || 1,
+      zoom: parseInt(this.ctrl.panel.initialZoom, 10) || 1
     });
     this.setMouseWheelZoom();
 
@@ -52,7 +57,7 @@ export default class WorldMap {
       subdomains: selectedTileServer.subdomains,
       reuseTiles: true,
       detectRetina: true,
-      attribution: selectedTileServer.attribution,
+      attribution: selectedTileServer.attribution
     }).addTo(this.map);
   }
 
@@ -80,13 +85,63 @@ export default class WorldMap {
           this.ctrl.panel.colors[index + 1] +
           '"></i> ' +
           thresholds[index] +
-          (thresholds[index + 1] ? '&ndash;' + thresholds[index + 1] + '</div>' : '+');
+          (thresholds[index + 1]
+            ? '&ndash;' + thresholds[index + 1] + '</div>'
+            : '+');
       }
       this.legend._div.innerHTML = legendHtml;
     };
     this.legend.addTo(this.map);
   }
 
+  createAggregations() {
+    this.aggregations = (<any>window).L.control({ position: 'bottomright' });
+    this.aggregations.onAdd = () => {
+      this.aggregations._div = (<any>window).L.DomUtil.create(
+        'div',
+        'info aggregations'
+      );
+      this.aggregations.update();
+      return this.aggregations._div;
+    };
+
+    this.aggregations.update = () => {
+      const aggregations = this.ctrl.data.aggregations || {};
+      let aggregationsHtml = '';
+      if (Object.keys(aggregations).length <= 1 && aggregations.unknown === 0) {
+        aggregationsHtml = '<div>No Data Available</div>';
+      } else if (
+        this.ctrl.data.aggregationSortedList &&
+        this.ctrl.data.aggregationSortedList.length &&
+        Object.keys(aggregations).length > 1
+      ) {
+        this.ctrl.data.aggregationSortedList.forEach(agg => {
+          if (aggregations[agg] !== 0) {
+            aggregationsHtml = `${aggregationsHtml}
+          <div class="agg-item">
+            <div>
+              <div class="agg-label" title=${agg}>${agg}</div>
+              <b>${(100 * (aggregations[agg] / this.ctrl.data.length))
+                .toFixed(2)
+                .replace(/[.,]00$/, '')}%</b>
+            </div>
+            <div class="agg-bar">
+              <div class="agg-bar-progress" style="width: ${100 *
+              (aggregations[agg] / this.ctrl.data.length)}%">
+                progress
+              </div>
+            </div>
+          </div>`;
+          }
+        });
+      } else {
+        aggregationsHtml = `Invalid mapping for aggregations`;
+      }
+      this.aggregations._div.innerHTML = `<div class="agg-container">${aggregationsHtml}</div>`;
+    };
+    this.aggregations.addTo(this.map);
+  }
+
   needToRedrawCircles(data) {
     if (this.circles.length === 0 && data.length > 0) {
       return true;
@@ -103,7 +158,10 @@ export default class WorldMap {
 
   filterEmptyAndZeroValues(data) {
     return _.filter(data, o => {
-      return !(this.ctrl.panel.hideEmpty && _.isNil(o.value)) && !(this.ctrl.panel.hideZero && o.value === 0);
+      return (
+        !(this.ctrl.panel.hideEmpty && _.isNil(o.value)) &&
+        !(this.ctrl.panel.hideZero && o.value === 0)
+      );
     });
   }
 
@@ -117,11 +175,17 @@ export default class WorldMap {
 
   drawCircles() {
     const data = this.filterEmptyAndZeroValues(this.ctrl.data);
-    if (this.needToRedrawCircles(data)) {
+    this.clearCircles();
+    this.createCircles(data);
+    /*if (this.needToRedrawCircles(data)) {
       this.clearCircles();
       this.createCircles(data);
     } else {
       this.updateCircles(data);
+    }*/
+    // Update Aggregations
+    if (this.aggregations && this.aggregations !== null) {
+      this.aggregations.update();
     }
   }
 
@@ -131,7 +195,7 @@ export default class WorldMap {
       if (!dataPoint.locationName) {
         return;
       }
-      circles.push(this.createCircle(dataPoint));
+      circles.push(this.createCircle(dataPoint, data));
     });
     this.circlesLayer = this.addCircles(circles);
     this.circles = circles;
@@ -148,66 +212,120 @@ export default class WorldMap {
       });
 
       if (circle) {
+        circle.options.dataset = data;
         circle.setRadius(this.calcCircleSize(dataPoint.value || 0));
         circle.setStyle({
           color: this.getColor(dataPoint.value),
           fillColor: this.getColor(dataPoint.value),
           fillOpacity: 0.5,
-          location: dataPoint.key,
+          location: dataPoint.key
         });
         circle.unbindPopup();
-        this.createPopup(circle, dataPoint.locationName, dataPoint.valueRounded);
+        this.createPopup(
+          circle,
+          dataPoint.locationName,
+          dataPoint.valueRounded,
+          dataPoint.isMetricFieldNaN
+        );
       }
     });
+    if (this.aggregations && this.aggregations !== null) {
+      this.aggregations.update();
+    }
   }
 
-  createCircle(dataPoint) {
-    const circle = (<any>window).L.circleMarker([dataPoint.locationLatitude, dataPoint.locationLongitude], {
-      radius: this.calcCircleSize(dataPoint.value || 0),
-      color: this.getColor(dataPoint.value),
-      fillColor: this.getColor(dataPoint.value),
-      fillOpacity: 0.5,
-      location: dataPoint.key,
-    });
-
-    this.createPopup(circle, dataPoint.locationName, dataPoint.valueRounded);
+  createCircle(dataPoint, dataset?) {
+    const circle = (<any>window).L.circleMarker(
+      [dataPoint.locationLatitude, dataPoint.locationLongitude],
+      {
+        radius: this.calcCircleSize(dataPoint.value || 0),
+        color: this.getColor(dataPoint.value),
+        fillColor: this.getColor(dataPoint.value),
+        fillOpacity: 0.5,
+        location: dataPoint.key,
+        dataset
+      }
+    );
+    this.createPopup(
+      circle,
+      dataPoint.locationName,
+      dataPoint.valueRounded,
+      dataPoint.isMetricFieldNaN
+    );
     return circle;
   }
 
   calcCircleSize(dataPointValue) {
-    const circleMinSize = parseInt(this.ctrl.panel.circleMinSize, 10) || 2;
-    const circleMaxSize = parseInt(this.ctrl.panel.circleMaxSize, 10) || 30;
+    const circleMinSize = parseInt(this.ctrl.panel.circleMinSize, 10) || 10;
+    const circleMaxSize = parseInt(this.ctrl.panel.circleMaxSize, 10) || 10;
 
     if (this.ctrl.data.valueRange === 0) {
       return circleMaxSize;
     }
 
-    const dataFactor = (dataPointValue - this.ctrl.data.lowestValue) / this.ctrl.data.valueRange;
+    const dataFactor =
+      (dataPointValue - this.ctrl.data.lowestValue) / this.ctrl.data.valueRange;
     const circleSizeRange = circleMaxSize - circleMinSize;
 
     return circleSizeRange * dataFactor + circleMinSize;
   }
 
-  createPopup(circle, locationName, value) {
-    const unit = value && value === 1 ? this.ctrl.panel.unitSingular : this.ctrl.panel.unitPlural;
-    const label = (locationName + ': ' + value + ' ' + (unit || '')).trim();
-    circle.bindPopup(label, {
-      offset: (<any>window).L.point(0, -2),
-      className: 'worldmap-popup',
-      closeButton: this.ctrl.panel.stickyLabels,
-    });
+  createPopup(circle, locationName, value, isMetricFieldNaN) {
+    const unit =
+      value && value === 1
+        ? this.ctrl.panel.unitSingular
+        : this.ctrl.panel.unitPlural;
+
+    let formattedLocationList = '';
+    circle.options.dataset
+      .filter(data => data.key === circle.options.location)
+      .forEach(location => {
+        if (
+          this.ctrl.panel.drilldownTarget &&
+          this.ctrl.panel.drilldownTarget !== ''
+        ) {
+          const url = this.ctrl.panel.drilldownTarget
+            ? this.ctrl.panel.drilldownTarget.split('${__locationName}').join(`${location.locationName}`) : '';
+          const hrefUrl = this.templateSrv.replace(url);
+
+          formattedLocationList = `${formattedLocationList}
+            <div>
+            ${`
+            ${
+              this.ctrl.panel.drillDownTab
+                ? `<a href="${hrefUrl}" target="_blank">${location.locationName}</a> `
+                : `<a href="${hrefUrl}">${location.locationName}</a>`
+              }
+            ${!isMetricFieldNaN ? `: ${location.value}` : ''}
+            ${unit ? `(${unit})` : ''}`.trim()}
+            </div>`;
+        } else {
+          formattedLocationList = `${formattedLocationList} <div>
+           ${`${location.locationName} ${
+              !isMetricFieldNaN ? `: ${location.value}` : ''
+              }
+           ${unit ? `(${unit})` : ''}`.trim()}
+           </div>`;
+        }
+        const label = `<div class="tooltip-container">${formattedLocationList}</div>`;
+        circle.bindPopup(label, {
+          offset: (<any>window).L.point(0, -2),
+          className: 'worldmap-popup',
+          closeButton: this.ctrl.panel.stickyLabels
+        });
 
-    circle.on('mouseover', function onMouseOver(evt) {
-      const layer = evt.target;
-      layer.bringToFront();
-      this.openPopup();
-    });
+        circle.on('mouseover', function onMouseOver(evt) {
+          const layer = evt.target;
+          layer.bringToFront();
+          this.openPopup();
+        });
 
-    if (!this.ctrl.panel.stickyLabels) {
-      circle.on('mouseout', function onMouseOut() {
-        circle.closePopup();
+        if (!this.ctrl.panel.stickyLabels) {
+          circle.on('mouseout', function onMouseOut() {
+            circle.closePopup();
+          });
+        }
       });
-    }
   }
 
   getColor(value) {
@@ -224,7 +342,10 @@ export default class WorldMap {
   }
 
   panToMapCenter() {
-    this.map.panTo([parseFloat(this.ctrl.panel.mapCenterLatitude), parseFloat(this.ctrl.panel.mapCenterLongitude)]);
+    this.map.panTo([
+      parseFloat(this.ctrl.panel.mapCenterLatitude),
+      parseFloat(this.ctrl.panel.mapCenterLongitude)
+    ]);
     this.ctrl.mapCenterMoved = false;
   }
 
@@ -233,6 +354,11 @@ export default class WorldMap {
     this.legend = null;
   }
 
+  removeAggregations() {
+    this.aggregations.remove(this.map);
+    this.aggregations = null;
+  }
+
   setMouseWheelZoom() {
     if (!this.ctrl.panel.mouseWheelZoom) {
       this.map.scrollWheelZoom.disable();
@@ -261,6 +387,9 @@ export default class WorldMap {
     if (this.legend) {
       this.removeLegend();
     }
+    if (this.aggregations) {
+      this.removeAggregations();
+    }
     this.map.remove();
   }
 }
diff --git a/src/worldmap_ctrl.ts b/src/worldmap_ctrl.ts
index 4aa746c..e5fe43a 100644
--- a/src/worldmap_ctrl.ts
+++ b/src/worldmap_ctrl.ts
@@ -1,59 +1,61 @@
-import { MetricsPanelCtrl } from "grafana/app/plugins/sdk";
-import TimeSeries from "grafana/app/core/time_series2";
+import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk';
+import TimeSeries from 'grafana/app/core/time_series2';
 import appEvents from 'grafana/app/core/app_events';
 
-import * as _ from "lodash";
-import DataFormatter from "./data_formatter";
-import "./css/worldmap-panel.css";
-import $ from "jquery";
-import "./css/leaflet.css";
-import WorldMap from "./worldmap";
+import * as _ from 'lodash';
+import DataFormatter from './data_formatter';
+import './css/worldmap-panel.css';
+import $ from 'jquery';
+import './css/leaflet.css';
+import WorldMap from './worldmap';
 
 const panelDefaults = {
   maxDataPoints: 1,
-  mapCenter: "(0°, 0°)",
+  mapCenter: '(0°, 0°)',
   mapCenterLatitude: 0,
   mapCenterLongitude: 0,
   initialZoom: 1,
-  valueName: "total",
-  circleMinSize: 2,
-  circleMaxSize: 30,
-  locationData: "countries",
-  thresholds: "0,10",
+  valueName: 'total',
+  circleMinSize: 10,
+  circleMaxSize: 10,
+  locationData: 'table',
+  thresholds: '0,10',
   colors: [
-    "rgba(245, 54, 54, 0.9)",
-    "rgba(237, 129, 40, 0.89)",
-    "rgba(50, 172, 45, 0.97)"
+    'rgba(245, 54, 54, 0.9)',
+    'rgba(237, 129, 40, 0.89)',
+    'rgba(50, 172, 45, 0.97)'
   ],
-  unitSingle: "",
-  unitPlural: "",
+  unitSingle: '',
+  unitPlural: '',
   showLegend: true,
   mouseWheelZoom: false,
-  esMetric: "Count",
+  esMetric: 'Count',
   decimals: 0,
   hideEmpty: false,
   hideZero: false,
   stickyLabels: false,
   tableQueryOptions: {
-    queryType: "geohash",
-    geohashField: "geohash",
-    latitudeField: "latitude",
-    longitudeField: "longitude",
-    metricField: "metric"
-  }
+    queryType: 'coordinates',
+    geohashField: 'geohash',
+    latitudeField: 'latitude',
+    longitudeField: 'longitude',
+    metricField: 'metric'
+  },
+  aggregationLegends: false,
+  aggregationLegendField: ''
 };
 
 const mapCenters = {
-  "(0°, 0°)": { mapCenterLatitude: 0, mapCenterLongitude: 0 },
-  "North America": { mapCenterLatitude: 40, mapCenterLongitude: -100 },
+  '(0°, 0°)': { mapCenterLatitude: 0, mapCenterLongitude: 0 },
+  'North America': { mapCenterLatitude: 40, mapCenterLongitude: -100 },
   Europe: { mapCenterLatitude: 46, mapCenterLongitude: 14 },
-  "West Asia": { mapCenterLatitude: 26, mapCenterLongitude: 53 },
-  "SE Asia": { mapCenterLatitude: 10, mapCenterLongitude: 106 },
-  "Last GeoHash": { mapCenterLatitude: 0, mapCenterLongitude: 0 }
+  'West Asia': { mapCenterLatitude: 26, mapCenterLongitude: 53 },
+  'SE Asia': { mapCenterLatitude: 10, mapCenterLongitude: 106 },
+  'Last GeoHash': { mapCenterLatitude: 0, mapCenterLongitude: 0 }
 };
 
 export default class WorldmapCtrl extends MetricsPanelCtrl {
-  static templateUrl = "partials/module.html";
+  static templateUrl = 'partials/module.html';
 
   dataFormatter: DataFormatter;
   locations: any;
@@ -73,26 +75,26 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
 
     this.dataFormatter = new DataFormatter(this);
 
-    this.events.on("init-edit-mode", this.onInitEditMode.bind(this));
-    this.events.on("data-received", this.onDataReceived.bind(this));
-    this.events.on("panel-teardown", this.onPanelTeardown.bind(this));
-    this.events.on("data-snapshot-load", this.onDataSnapshotLoad.bind(this));
+    this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
+    this.events.on('data-received', this.onDataReceived.bind(this));
+    this.events.on('panel-teardown', this.onPanelTeardown.bind(this));
+    this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));
 
     this.loadLocationDataFromFile();
   }
 
   setMapProvider(contextSrv) {
     this.tileServer = contextSrv.user.lightTheme
-      ? "CartoDB Positron"
-      : "CartoDB Dark";
+      ? 'CartoDB Positron'
+      : 'CartoDB Dark';
     this.setMapSaturationClass();
   }
 
   setMapSaturationClass() {
-    if (this.tileServer === "CartoDB Dark") {
-      this.saturationClass = "map-darken";
+    if (this.tileServer === 'CartoDB Dark') {
+      this.saturationClass = 'map-darken';
     } else {
-      this.saturationClass = "";
+      this.saturationClass = '';
     }
   }
 
@@ -106,23 +108,23 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
       return;
     }
 
-    if (this.panel.locationData === "jsonp endpoint") {
+    if (this.panel.locationData === 'jsonp endpoint') {
       if (!this.panel.jsonpUrl || !this.panel.jsonpCallback) {
         return;
       }
 
       $.ajax({
-        type: "GET",
-        url: this.panel.jsonpUrl + "?callback=?",
-        contentType: "application/json",
+        type: 'GET',
+        url: this.panel.jsonpUrl + '?callback=?',
+        contentType: 'application/json',
         jsonpCallback: this.panel.jsonpCallback,
-        dataType: "jsonp",
+        dataType: 'jsonp',
         success: res => {
           this.locations = res;
           this.render();
         }
       });
-    } else if (this.panel.locationData === "json endpoint") {
+    } else if (this.panel.locationData === 'json endpoint') {
       if (!this.panel.jsonUrl) {
         return;
       }
@@ -131,16 +133,16 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
         this.locations = res;
         this.render();
       });
-    } else if (this.panel.locationData === "table") {
+    } else if (this.panel.locationData === 'table') {
       // .. Do nothing
     } else if (
-      this.panel.locationData !== "geohash" &&
-      this.panel.locationData !== "json result"
+      this.panel.locationData !== 'geohash' &&
+      this.panel.locationData !== 'json result'
     ) {
       $.getJSON(
-        "public/plugins/grafana-worldmap-panel/data/" +
+        'public/plugins/grafana-worldmap-panel/data/' +
           this.panel.locationData +
-          ".json"
+          '.json'
       ).then(this.reloadLocations.bind(this));
     }
   }
@@ -152,15 +154,15 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
 
   showTableGeohashOptions() {
     return (
-      this.panel.locationData === "table" &&
-      this.panel.tableQueryOptions.queryType === "geohash"
+      this.panel.locationData === 'table' &&
+      this.panel.tableQueryOptions.queryType === 'geohash'
     );
   }
 
   showTableCoordinateOptions() {
     return (
-      this.panel.locationData === "table" &&
-      this.panel.tableQueryOptions.queryType === "coordinates"
+      this.panel.locationData === 'table' &&
+      this.panel.tableQueryOptions.queryType === 'coordinates'
     );
   }
 
@@ -171,9 +173,9 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
   }
 
   onInitEditMode() {
-    this.addEditorTab(
-      "Worldmap",
-      "public/plugins/grafana-worldmap-panel/partials/editor.html",
+       this.addEditorTab(
+      'Worldmap',
+      'public/plugins/grafana-worldmap-panel/partials/editor.html',
       2
     );
   }
@@ -190,12 +192,12 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
 
       const data = [];
 
-      if (this.panel.locationData === "geohash") {
+      if (this.panel.locationData === 'geohash') {
         this.dataFormatter.setGeohashValues(dataList, data);
-      } else if (this.panel.locationData === "table") {
+      } else if (this.panel.locationData === 'table') {
         const tableData = dataList.map(DataFormatter.tableHandler.bind(this));
         this.dataFormatter.setTableValues(tableData, data);
-      } else if (this.panel.locationData === "json result") {
+      } else if (this.panel.locationData === 'json result') {
         this.series = dataList;
         this.dataFormatter.setJsonValues(data);
       } else {
@@ -206,13 +208,13 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
 
       this.updateThresholdData();
 
-      if (this.data.length && this.panel.mapCenter === "Last GeoHash") {
+      if (this.data.length && this.panel.mapCenter === 'Last GeoHash') {
         this.centerOnLastGeoHash();
       } else {
         this.render();
       }
     } catch (err) {
-      appEvents.emit('alert-error', ['Data error', err.toString()])
+      appEvents.emit('alert-error', ['Data error', err.toString()]);
     }
   }
 
@@ -239,7 +241,7 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
   }
 
   setNewMapCenter() {
-    if (this.panel.mapCenter !== "custom") {
+    if (this.panel.mapCenter !== 'custom') {
       this.panel.mapCenterLatitude =
         mapCenters[this.panel.mapCenter].mapCenterLatitude;
       this.panel.mapCenterLongitude =
@@ -260,6 +262,12 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
     this.render();
   }
 
+  toggleAggregations() {
+    if (!this.panel.aggregationLegends) {
+      this.map.removeAggregations();
+    }
+    this.render();
+  }
   toggleMouseWheelZoom() {
     this.map.setMouseWheelZoom();
     this.render();
@@ -277,7 +285,7 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
   }
 
   updateThresholdData() {
-    this.data.thresholds = this.panel.thresholds.split(",").map(strValue => {
+    this.data.thresholds = this.panel.thresholds.split(',').map(strValue => {
       return Number(strValue.trim());
     });
     while (_.size(this.panel.colors) > _.size(this.data.thresholds) + 1) {
@@ -286,15 +294,69 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
     }
     while (_.size(this.panel.colors) < _.size(this.data.thresholds) + 1) {
       // not enough colors. add one.
-      const newColor = "rgba(50, 172, 45, 0.97)";
+      const newColor = 'rgba(50, 172, 45, 0.97)';
       this.panel.colors.push(newColor);
     }
   }
+  stringStartsAsRegEx(str: string): boolean {
+    if (!str) {
+      return false;
+    }
+  
+    return str[0] === '/';
+  }
+  
+  stringToJsRegex(str: string): RegExp {
+    if (!this.stringStartsAsRegEx(str)) {
+      return new RegExp(`^${str}$`);
+    }
+  
+    const match = str.match(new RegExp('^/(.*?)/(g?i?m?y?)$'));
+  
+    if (!match) {
+      throw new Error(`'${str}' is not a valid regular expression.`);
+    }
+  
+    return new RegExp(match[1], match[2]);
+  }
+  applyRegexPattern() {
+    let seriesList = this.data;
+    for (let i = 0; i < seriesList.length; i++) {
+      if (!seriesList[i].locName) {
+        seriesList[i].locName = seriesList[i].locationName
+      }
+      if (this.panel.regexPattern !== '' && this.panel.regexPattern !== undefined) {
+        const regexVal = this.stringToJsRegex(this.panel.regexPattern);
+        if (seriesList[i].locName && regexVal.test(seriesList[i].locName.toString())) {
+          const temp = regexVal.exec(seriesList[i].locName.toString());
+          if (!temp) {
+            continue;
+          }
+          let extractedtxt = '';
+          if (temp.length > 1) {
+            temp.slice(1).forEach((value, i) => {
+              if (value) {
+                extractedtxt += extractedtxt.length > 0 ? ' ' + value.toString() : value.toString();
+              }
+            });
+            seriesList[i].locationName = extractedtxt;
+          }
+        }
+        else {
+          seriesList[i].locationName = seriesList[i].locName;
+        }
+      }
+      else {
+        seriesList[i].locationName = seriesList[i].locName;
+      }
+    }
+    this.data = seriesList;
+  }
 
   changeLocationData() {
     this.loadLocationDataFromFile(true);
 
-    if (this.panel.locationData === "geohash") {
+    if (this.panel.locationData === 'geohash') {
       this.render();
     }
   }
@@ -302,12 +364,12 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
   link(scope, elem, attrs, ctrl) {
     let firstRender = true;
 
-    ctrl.events.on("render", () => {
+    ctrl.events.on('render', () => {
       render();
       ctrl.renderingCompleted();
     });
 
-     function render() {
+       function render() {
       if (!ctrl.data) {
         return;
       }
@@ -319,14 +381,16 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
         return;
       }
 
-      const mapContainer = elem.find(".mapcontainer");
+      ctrl.applyRegexPattern();
+
+      const mapContainer = elem.find('.mapcontainer');
 
-      if (mapContainer[0].id.indexOf("{{") > -1) {
+      if (mapContainer[0].id.indexOf('{{') > -1) {
         return;
       }
 
       if (!ctrl.map) {
-        const map = new WorldMap(ctrl, mapContainer[0]);
+        const map = new WorldMap(ctrl, mapContainer[0], ctrl.templateSrv);
         map.createMap();
         ctrl.map = map;
       }
@@ -341,6 +405,10 @@ export default class WorldmapCtrl extends MetricsPanelCtrl {
         ctrl.map.createLegend();
       }
 
+      if (!ctrl.map.aggregations && ctrl.panel.aggregationLegends) {
+        ctrl.map.createAggregations();
+      }
+
       ctrl.map.drawCircles();
     }
   }