浏览代码

[search] More on maps

Enrico Berti 11 年之前
父节点
当前提交
d48a3e7

+ 4 - 0
apps/search/src/search/templates/search2.mako

@@ -592,6 +592,9 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
 
 <script src="/search/static/js/search.ko.js" type="text/javascript" charset="utf-8"></script>
 
+<script src="/static/js/hue.geo.js"></script>
+<script src="/static/js/hue.colors.js"></script>
+
 <script src="/static/ext/js/d3.v3.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/nv.d3.min.js" type="text/javascript" charset="utf-8"></script>
 <link href="/static/ext/css/nv.d3.min.css" rel="stylesheet">
@@ -665,6 +668,7 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
     top: 70px;
     position: fixed;
     width: 100%;
+    z-index: 1000;
   }
 
   .row-header {

+ 83 - 3
apps/search/static/js/charts.ko.js

@@ -92,11 +92,91 @@ ko.bindingHandlers.lineChart = {
 
 ko.bindingHandlers.mapChart = {
   init: function (element, valueAccessor) {
-    $(element).height($(element).width()/2.5);
+    $(element).height($(element).width()/2.23);
     $(element).css("position", "relative");
     var _options = valueAccessor();
-    var basic = new Datamap({
-      element: element
+    var _data = _options.transformer(_options.data);
+    var _maxWeight = 0;
+    $(_data).each(function(cnt, item){
+      if (item.value > _maxWeight) _maxWeight = item.value;
+    });
+
+    var _chunk = _maxWeight / _data.length;
+
+    var _mapdata = {};
+    var _fills = {};
+    var _noncountries = [];
+    if (_options.isScale){
+      _fills["defaultFill"] = HueColors.LIGHT_BLUE;
+      var _colors = HueColors.scale(HueColors.LIGHT_BLUE, HueColors.DARK_BLUE, _data.length);
+      $(_colors).each(function(cnt, item){
+        _fills["fill_" + cnt] = item;
+      });
+      $(_data).each(function(cnt, item){
+        var _country = HueGeo.getCountryFromName(item.label);
+        if (_country != null){
+          _mapdata[_country.alpha3] = {
+            fillKey: "fill_" + Math.floor(item.value/_chunk)
+          }
+        }
+        else {
+          _noncountries.push(item);
+        }
+      });
+    }
+    else {
+      _fills["defaultFill"] = HueColors.BLUE;
+      _fills["selected"] = HueColors.DARK_BLUE;
+      $(_data).each(function(cnt, item){
+        var _country = HueGeo.getCountryFromName(item.label);
+        if (_country != null){
+          _mapdata[_country.alpha3] = {
+            fillKey: "selected"
+          }
+        }
+        else {
+          _noncountries.push(item);
+        }
+      });
+    }
+
+    var _map = new Datamap({
+      element: element,
+      fills: _fills,
+      scope: 'world',
+      data: _mapdata,
+      done: function(datamap) {
+
+        datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
+          _options.onClick(geography);
+        });
+
+        var _bubbles = [];
+      $(_noncountries).each(function(cnt, item){
+          HueGeo.getCityCoordinates(item.label, function(lat, lng){
+              _bubbles.push({
+                fillKey: "selected",
+                label: item.label,
+                radius: 4,
+                latitude: lat,
+                longitude: lng
+              });
+              _map.bubbles(_bubbles, {
+                popupTemplate: function(geo, data) {
+                  return '<div class="hoverinfo"><strong>'  + data.label + '</strong></div>'
+                }
+              });
+          });
+      });
+      },
+      geographyConfig: {
+        hideAntarctica: true,
+        borderWidth: 1,
+        borderColor: HueColors.DARK_BLUE,
+        highlightOnHover: true,
+        highlightFillColor: HueColors.DARK_BLUE,
+        highlightBorderColor: HueColors.DARK_BLUE
+      }
     });
     _options.onComplete();
   },

+ 55 - 0
desktop/core/static/js/hue.colors.js

@@ -0,0 +1,55 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var HueColors = {
+  hexToR: function (h) {
+    return parseInt((this.cutHex(h)).substring(0, 2), 16)
+  },
+  hexToG: function (h) {
+    return parseInt((this.cutHex(h)).substring(2, 4), 16)
+  },
+  hexToB: function (h) {
+    return parseInt((this.cutHex(h)).substring(4, 6), 16)
+  },
+  cutHex: function (h) {
+    return (h.charAt(0) == "#") ? h.substring(1, 7) : h
+  },
+  decToHex: function (i) {
+    return (i + 0x100).toString(16).substr(-2).toUpperCase();
+  },
+  scale: function (from, to, bands) {
+    var _fromRGB = [this.hexToR(from), this.hexToG(from), this.hexToB(from)],
+      _toRGB = [this.hexToR(to), this.hexToG(to), this.hexToB(to)],
+      _i,
+      _delta = [],
+      _bands = [];
+
+    for (_i = 0; _i < 4; _i++) {
+      _delta[_i] = (_fromRGB[_i] - _toRGB[_i]) / (bands + 1);
+    }
+
+    for (_i = 0; _i < bands; _i++) {
+      var r = Math.round(_fromRGB[0] - _delta[0] * _i);
+      var g = Math.round(_fromRGB[1] - _delta[1] * _i);
+      var b = Math.round(_fromRGB[2] - _delta[2] * _i);
+      _bands.push("#" + this.decToHex(r) + this.decToHex(g) + this.decToHex(b));
+    }
+    return _bands;
+  },
+  LIGHT_BLUE: "#f7fbff",
+  BLUE: "#c7d2e1",
+  DARK_BLUE: "#08306b"
+};

+ 2 - 0
desktop/core/static/js/hue.geo.js

@@ -272,6 +272,7 @@ var HueGeo = {
         return this.ISO_3166[i];
       }
     }
+    return null;
   },
   getCountryFromCode: function (code) {
     for (var i = 0; i < this.ISO_3166.length; i++) {
@@ -279,6 +280,7 @@ var HueGeo = {
         return this.ISO_3166[i];
       }
     }
+    return null;
   },
   getCity: function (city, callback) {
     var api = new NominatimAPI();