使用JQuery和在线JSON数据填充JVectorMaps [英] Using JQuery and online JSON data to populate JVectorMaps

查看:106
本文介绍了使用JQuery和在线JSON数据填充JVectorMaps的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JSON数据直接填充JVectorMaps(及其他).大多数常见指标的最新统计信息可通过json在线获得-因此此脚本应使您可以快速,轻松地提取所需的任何数据.我只是还不太了解格式代码,因为我对JQuery& JS.我在被困的地方打了一个问号.

I'm using JSON data to populate JVectorMaps (and others) directly. Up-to-date stats for most common indicators are available via json online - so this script should let you can pluck whatever data that you like quickly and easily. I just haven't quite figured out the formatting code yet as I am very new to JQuery & JS. I put a question mark where I'm stumped.

理想情况下,获取和数据脚本可以采用ind_id变量和标签,以在Vector Map上显示任何指标,而不仅仅是我在此处用作示例的一个GDP(NY.GDP.MKTP.CD)指标./p>

Ideally, the fetch and Data scripts could take an ind_id variable and label that presented any indicator on the Vector Map, and not just the one GDP (NY.GDP.MKTP.CD) indicator I used as an example here.

document.addEventListener('DOMContentLoaded', () => {
    console.log("loaded")
    fetchCountryData()
})

function fetchCountryData () {
    fetch('http://api.worldbank.org/v2/country/all/indicator/NY.GDP.MKTP.CD?format=json&mrv=1&per_page=300)
    // 
    .then(resp => resp.json())
    .then(data => {
        let country.id = data[1]
        let value = data[1]
    create-GDP-Data(country.id,value)
})  
}

function create-GDP-Data(country.id,value){
    let gdpData = ?
}

$('#world-map-gdp').vectorMap({
  map: 'world_mill',
  series: {
    regions: [{
      values: gdpData,
      scale: ['#C8EEFF', '#0071A4'],
      normalizeFunction: 'polynomial'
    }]
  },
  onRegionTipShow: function(e, el, code){
    el.html(el.html()+' (GDP - '+gdpData[code]+')');
  }
});

GDP数据(gdpData)的格式应为:

GDP Data (gdpData) should be formatted as follows:

var gdpData = {
  "AF": 16.63,
  "AL": 11.58,
  "DZ": 158.97,
  ...
};

推荐答案

您知道请求的数据集返回的数据结构与jVectorMap所需的数据结构有所不同.因此,您需要的是从传入数据到后者的重新映射.

You are aware that the requested dataset is returning back a somewhat different data structure as the one needed for jVectorMap. So, what You need is a remapper from the incoming data to the latter.

为使此方法更灵活,我的建议是使用简单的 remapper 函数,您可以在其中传递传入字段的名称,并获取该值.

To make this approach more flexible, my proposal is to use a straightforward remapper function, where You can pass-in the name of the incoming field, and receive back the value for that.

请,请参阅下面我的提案中的评论以获取更多信息:

Please, see the comments inside my proposal below for further information:

演示:动态加载jVectorMap区域数据集

$(function() {
  /* Handler for jQuery .ready() */
  
  function mapper(data, key) { 
    /* Deep search for a key, return the value found. */
    var keys = key.split('.'), value = data[keys.shift()];
    for(var i=0, l=keys.length; i<l; i++) {value = value[keys[i]]}
    return value;
  }     
   
  function showMapValues(schema, map, values, min, max) { 
    var regions = map.series.regions[0];
    /* Reset the scale min & max, allow recomputation. */ 
    regions.params.min = min;
    regions.params.max = max;
    regions.setValues(values.regions);
    map.dataSetName = schema.dataSetName;
    map.dataSetFormat = schema.dataSetFormat; 
  }
  
  function remapData(schema, map, data) { 
    var values = {regions: {}, markers: {}};
    /* Loop over the returned dataset and invoke remap. */
    $.each(data, function(i, item) { 
      var code = mapper(item, schema.countryCodeField),
          value = mapper(item, schema.countryValueField) || 0;
      /* Find out if this is a valid region inside the map. */
      var isRegionCode = typeof map.regions[code] !== 'undefined';
      /* Find out if this is a valid marker inside the map. */
      var isMarkerCode = typeof map.markers[code] !== 'undefined';
      /* Fill two separate datasets for regions & markers. */
      if(isRegionCode) values.regions[code] = value;
      if(isMarkerCode) values.markers[code] = value;
    }); 
    return values;
  }
  
  function fetchAlternateCountryData(schema, map) {
    $.ajax({
      url: schema.alternate,
      dataType: 'json',
      success: function(result) {
        var dataSet = result[schema.dataSetIndex];
        /* Dynamically update the map with the new local data */
        showMapValues(schema, map, remapData(schema, map, dataSet));
      }
    }); 
  }
  
  function fetchCountryData(schema, map) {
    $.ajax({
      url: schema.url,
      dataType: 'json',
      data: schema.params,
      success: function(result) {
        var dataSet = result[schema.dataSetIndex];
        if(dataSet) {
          /* Dynamically update the map with the new remote data */
          showMapValues(schema, map, remapData(schema, map, dataSet));
        } else {
          /* Manage "Invalid value" response */
          fetchAlternateCountryData(schema, map);
        }
      },
      error: function(request, textStatus, errorThrown) { 
        /* Manage some other trappable ajax errors */
        fetchAlternateCountryData(schema, map);
      }
    }); 
  }
  
  var worldMap = new jvm.Map({
    map: 'world_mill_en',
    container: $('#world-map'),
    zoomOnScroll: true,
    regionsSelectable: false,
    backgroundColor: "aliceblue", 
    markers: [], /* Initialize the map with empty markers */
    series: {
      regions: [{
        values: {}, /* Initialize the map with empty region values */
        scale: ['#C8EEFF', '#0071A4'],
        normalizeFunction: 'polynomial'
      }],
      /* Initialize the map with empty marker values */
      markers: [{attribute: 'fill', scale: {}, values: []}]
    }, 
    onRegionTipShow: function(e, el, code){
      var value = worldMap.series.regions[0].values[code],
          formattedValue = new Intl.NumberFormat('en-US', worldMap.dataSetFormat).format(value);
      el.text(el.text() + ' (' + worldMap.dataSetName + ': ' + formattedValue + ')');
    }
  });
      
                                                                                                                       
  /* Define the data type & the location of the relevant fields inside the incoming data */
  var schema = {
      url: 'https://api.worldbank.org/v2/country/all/indicator/NY.GDP.MKTP.CD',
      params: 'format=json&mrv=1&per_page=300',
      alternate: '/ind_MapData',
      dataSetName: 'GDP', 
      dataSetFormat: {style: 'currency', currency: 'USD'}, 
      dataSetIndex: 1, 
      countryCodeField: 'country.id', 
      countryValueField: 'value'
  }; 
      
  fetchCountryData(schema, worldMap);
   
});

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jvectormap@2.0.4/jquery-jvectormap.min.css" type="text/css">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/jvectormap@2.0.4/jquery-jvectormap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/jvectormap@2.0.4/tests/assets/jquery-jvectormap-world-mill-en.js"></script>
</head>

<body>
  <div id="world-map" style="width: 600px; height: 400px"></div>
</body>

</html>

此外:

请注意:jVectorMap中的原始世界地图不包括一些小国,例如新加坡,列支敦士登等.它们太小了,您需要放大很多.此问题的首选解决方案是在其位置放置其他标记.之后,您可以相应地为这些标记设置传入数据.

Please pay attention: the original world map from jVectorMap doesn't include some tiny countries like Singapore, Liechtenstein and so on. They are simply too small, You would need to zoom-in a lot. The preferred solution for this problem is to place additional markers at their location. After that, You can set the incoming data for that markers accordingly.

在这里查看我的答案: jVectorMap-如何动态添加标记

See my answer here: jVectorMap - How to add marker dynamically


顺便说一句,感谢 bjornd 提供的出色jVectorMap.


BTW, thanks to bjornd for the great jVectorMap.

这篇关于使用JQuery和在线JSON数据填充JVectorMaps的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆