Search code examples
jqueryjvectormap

Matching two items in two different arrays


I am using Jvectormap and have set an array as "areas" to group country together to be selected, which works. The next step is to give each country on the array its color. So i can define a different color to each country in each array.

UK may be pink in array 1 but green in array 2.

Also how do i assign to a click function:

$("#mp-cyprus-A").click(function(){
    $('#world-map').vectorMap('setSelectedRegions', ['areas[1]']);
});

Code for adding sets of area then add color set for each area:

  //MAP CONTROLS
$(function(){
  var areas = [];
  areas[0] = [];
  areas[2] = ["FR","BG","DK","HR","DE","BA","XK","CH","EE","IS","AL","IT","CZ","GB","IE","ES","ME","MD","RO","RS","MK","SK","SI","UA","SE","AT"];
  areas[2] = ["BE","FR","BG","DK","HR","DE","BA","HU","FI","BY","GR","NL","PT","NO","LV","LT","LU","XK","CH","EE","IS","AL","IT","CZ","GB","IE","ES","ME","MD","RO","RS","MK","SK","SI","UA","SE","AT"];
  areas[3] = ["CA"];
  areas[4] = ["CA"];
  areas[5] = ["CA"];
  areas[6] = ["CA"];

  function selectArea(code){
    var mapObj = $("#world-map").vectorMap("get", "mapObject");
    areas.forEach(function(area) {
      if(area.indexOf(code)>-1) {
        mapObj.setSelectedRegions(area);
        return;
      }
    });
  }

  function clearAll(){
    var mapObj = $("#world-map").vectorMap("get", "mapObject");
    mapObj.clearSelectedRegions();
  }

Part of code that doesnt work: Setting Array for each "areas". And apply it If the correseponding array betwwen "areas" and "areacolor".

   // Area Colors
      var areacolor = [];
        areacolor[0] = [
            {'BE': '#4E7387'},
            {'FR': '#333333'},
            {'BG': '#89AFBF'},
            {'DK': '#817F8E'},
            {'HR': '#344B5E'},
            {'FI': '#344B5E'},
            {'BY': '#344B5E'},
            {'GR': '#344B5E'}
        ]
        areacolor[1] = [
            {'BE': '#4E7387'},
            {'FR': '#333333'},
            {'BG': '#89AFBF'},
            {'DK': '#817F8E'},
            {'HR': '#344B5E'},
            {'FI': '#344B5E'},
            {'BY': '#344B5E'},
            {'GR': '#344B5E'}
        ]
        areacolor[2] = [
            {'BE': '#4E7387'},
            {'FR': '#333333'},
            {'BG': '#89AFBF'},
            {'DK': '#817F8E'},
            {'HR': '#344B5E'},
            {'FI': '#344B5E'},
            {'BY': '#344B5E'},
            {'GR': '#344B5E'}
        ]

        function selectArea(color){
            var mapObj = $("#world-map").vectorMap("get", "mapObject");
            areascolor.forEach(function(color) {
              if(color.indexOf(color)>-1) {
                map.series.regions[0].setValues(areacolor[0]);
                return;
              }

Vector map init:

$('#world-map').vectorMap({
    map: 'world_mill',
    backgroundColor: '#5288F9',
    markersSelectable:'false',
    regionsSelectableOne: 'false',
    regionsSelectable: 'true',
    regionStyle: {
        initial: {
          fill: "lightgrey"
        },
        selected: {
          fill: "darkseagreen"
        }
      },
    onRegionClick: function(e, code){
        clearAll();
        selectArea(code);
        return false;
      }
    });

Apply area filter

    (function () {
      // Collect the rest of the World
      var mapObj = $("#world-map").vectorMap("get", "mapObject");
      var states = areas.join(",");
      for(var code in mapObj.regions) {
        if(mapObj.regions.hasOwnProperty(code)) {
          if(states.indexOf(code) == -1) {
            areas[0].push(code);
          }
        }
      }
    })();

});

UPDATE:

//MAP CONTROLS
var areacolors0  = {
    'BE': '#4E7387',
    'FR': '#333333',
    'BG': '#89AFBF',
    'DK': '#817F8E',
    'HR': '#344B5E',
    'FI': '#344B5E',
    'BY': '#344B5E',
    'GR': '#344B5E'
  };
  var areacolors1 = {
    'BE': '#000000',
    'FR': '#333333',
    'BG': '#000000',
    'DK': '#817F8E',
    'HR': '#000000',
    'FI': '#344B5E',
    'BY': '#344B5E',
    'GR': '#344B5E'
  };
    $('#world-map').vectorMap({
        map: 'world_mill',
        backgroundColor: '#5288F9',
        markersSelectable:'false',
        regionsSelectableOne: 'false',
        regionsSelectable: 'true',
        regionStyle: {
            initial: {
              fill: "lightgrey"
            },
            selected: {
              fill: "darkseagreen"
            }
          },
          onRegionClick: function (event, code) {
            var map = $('#world-map').vectorMap('get', 'mapObject');
            var name = map.getRegionName(code);
            if(name == GR) {
            map.series.regions[0].setValues(areacolors.GR);      
            }
            if(name == CH) {
                map.series.regions[0].setValues(areacolors1.CH);         
                }


       },
});   

Solution

  • Due to the complex nature of your data structure, you need to iterate deeper. So you have:

    Array [
      Array [
        Object {
          key: value
        }
      ]
    ]
    

    So to find the items that match a specific value, you need to iterate the initial array, iterate the array items in each element, and iterate each object in the matrix.

    I prefer to use jQuery $.each(), it's the same idea as .forEach().

    var areacolor = [];
    areacolor[0] = [{
        'BE': '#4E7387'
      },
      {
        'FR': '#333333'
      },
      {
        'BG': '#89AFBF'
      },
      {
        'DK': '#817F8E'
      },
      {
        'HR': '#344B5E'
      },
      {
        'FI': '#344B5E'
      },
      {
        'BY': '#344B5E'
      },
      {
        'GR': '#344B5E'
      }
    ]
    areacolor[1] = [{
        'BE': '#4E7387'
      },
      {
        'FR': '#333333'
      },
      {
        'BG': '#89AFBF'
      },
      {
        'DK': '#817F8E'
      },
      {
        'HR': '#344B5E'
      },
      {
        'FI': '#344B5E'
      },
      {
        'BY': '#344B5E'
      },
      {
        'GR': '#344B5E'
      }
    ]
    areacolor[2] = [{
        'BE': '#4E7387'
      },
      {
        'FR': '#333333'
      },
      {
        'BG': '#89AFBF'
      },
      {
        'DK': '#817F8E'
      },
      {
        'HR': '#344B5E'
      },
      {
        'FI': '#344B5E'
      },
      {
        'BY': '#344B5E'
      },
      {
        'GR': '#344B5E'
      }
    ];
    
    function selectArea(color) {
      //var mapObj = $("#world-map").vectorMap("get", "mapObject");
      $.each(areacolor, function(k, ac) {
        console.log("Examine areacolor[" + k + "]");
        $.each(ac, function(i, area) {
          $.each(area, function(c, clr) {
            if (clr.indexOf(color) === 0) {
              console.log("Color Found: " + c + ", " + clr);
              //map.series.regions[0].setValues(areacolor[0]);
            }
          });
        });
      });
    }
    
    selectArea("#344B5E");
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    The console will show:

    Examine areacolor[0]
    Color Found: HR, #344B5E
    Color Found: FI, #344B5E
    Color Found: BY, #344B5E 
    Color Found: GR, #344B5E
    Examine areacolor[1]
    Color Found: HR, #344B5E
    Color Found: FI, #344B5E
    Color Found: BY, #344B5E
    Color Found: GR, #344B5E
    Examine areacolor[2]
    Color Found: HR, #344B5E
    Color Found: FI, #344B5E
    Color Found: BY, #344B5E
    Color Found: GR, #344B5E
    

    If you're simply assigning a color to a Country Code, it might be better to make a simply object:

    var areacolors = {
      'BE': '#4E7387',
      'FR': '#333333',
      'BG': '#89AFBF',
      'DK': '#817F8E',
      'HR': '#344B5E',
      'FI': '#344B5E',
      'BY': '#344B5E',
      'GR': '#344B5E'
    };
    

    Then, if you know the Country Code, you can simply call it's index:

    map.series.regions[0].setValues(areacolors.GR); // Dot Notation preferred
    

    Or

    map.series.regions[0].setValues(areacolor['GR']);
    

    Or

    var cc = "GR";
    map.series.regions[0].setValues(areacolor[cc]);
    

    I am not familiar with this plugin you're using, so I cannot speak to how to set the proper values, I am just using your example to clarify my point.

    Hope this helps.

    Update 1

    Your updated code appears correct. I would check Console for any alerts or Errors.

    Also consider this:

    var areacolors = {
      'BE': '#000000',
      'FR': '#333333',
      'BG': '#000000',
      'DK': '#817F8E',
      'HR': '#000000',
      'FI': '#344B5E',
      'BY': '#344B5E',
      'GR': '#344B5E'
    };
    

    And then:

    onRegionClick: function (event, code) {
      var map = $('#world-map').vectorMap('get', 'mapObject');
      var name = map.getRegionName(code);
      console.log("Name: " + name + ", Color: " + areacolors[name], map);
      map.series.regions[0].setValues(areacolors[name]);      
    }
    

    It appears all your colors are the same, so I do not see the benefit to multiple data sets. Just use one for all. Also the console.log() function can be very helpful in diagnosing issues.