diff --git a/README.md b/README.md
index 1fab8a4bdcd6cea7ab0c832056a0828b577f2119..53111b12e3ff679ce0336081e6a87c18cb5e64e6 100644
--- a/README.md
+++ b/README.md
@@ -14,11 +14,19 @@ Author: Barend Köbben - <a href="mailto:b.j.kobben@utwente.nl">b.j.kobben@utwen
 
 ##Changelist:
 
+### version 0.9.0 [September 2016]
+*   now using v4 of the D3 library
+*   now all map symbolisations use d3.scale
+*   now using standard version of d3-legend (by Susie Lu: http://d3-legend.susielu.com), 
+    legend height calculation moved to makeLegend() in NatAtlas.js
+
+### version 0.8.5 [January 2016]
+*   supports CBS REST Open Data (using OData3 json output) in DataLoader().attributes
+
 ### version 0.8 [December 2015]:
 *   got rid of all use of eval(): e.g. eval("d." + FK) => d[FK]
-*   first attempts at breaking up in more js files, with proper classing:
-*   Messages.js
-*   dataloader.js
+*   first attempts at breaking up: re-useable js files, as proper classes: 
+    Messages.js + DataLoader.js
 
 ### 0.7 [August 2015]:
 *   Implementation of mapCompare tools
diff --git a/css/natatlas.css b/css/natatlas.css
index fd46fd4900fb1341e3b2512b84ab934e6a2ca89f..676bfb62048fce78c0027b357760b7aae9c51ee5 100644
--- a/css/natatlas.css
+++ b/css/natatlas.css
@@ -48,7 +48,7 @@ h4 {
     position: absolute;
     left: 640px;
     top: 5px;
-    width: 300px;
+    width: 120px;
     height: 20px;
     padding: 4px;
     overflow: hidden;
@@ -124,19 +124,6 @@ h4 {
     border: 1px solid #cccccc;
     background: #ccddf2;
 }
-#compareGraphDiv {
-    position: absolute;
-    left: 640px;
-    top: 5px;
-    width: 500px;
-    height: 590px;
-    padding: 2px;
-    overflow: hidden;
-    z-index: 2;
-    border: 1px solid #cccccc;
-    background: #ffffff;
-    display: inline;
-}
 #compareMapDiv {
     position: absolute;
     left: 770px;
diff --git a/data/metaData.json b/data/metaData.json
index 9ff0e97d7534863c85d83477ad5f6fdadbb04b8b..ea7c773b1cdd1f5a44892dc1da117b7b07523708 100644
--- a/data/metaData.json
+++ b/data/metaData.json
@@ -3,10 +3,10 @@
     "Nationale Atlas van Nederland",
     "National Atlas of The Netherlands"
   ],
-  "atlasVersion": "0.7",
+  "atlasVersion": "0.9",
   "atlasCopyright": [
-    "©2011-15: Stichting Wetenschappelijke Atlas Nederland",
-    "©2011-15: Foundation Scientific Atlas of the Netherlands"
+    "©2016: Stichting Wetenschappelijke Atlas Nederland",
+    "©2016: Foundation Scientific Atlas of the Netherlands"
   ],
   "atlasLanguages": [
     "Nederlands",
@@ -26,7 +26,7 @@
         "Municipalities of the Netherlands, generalised from the Base Registration Cartography of the Kadaster. "
       ],
       "date": "2011",
-      "FK_attrib": "GM_CODE",
+      "FKattrib": "GM_CODE",
       "source": [
         "Kadaster",
         "Kadaster"
@@ -46,7 +46,7 @@
         "Provinces of the Netherlands, aggegrated from municipal borders. "
       ],
       "date": "2011",
-      "FK_attrib": "prov_code",
+      "FKattrib": "prov_code",
       "source": [
         "Kadaster",
         "Kadaster"
@@ -66,7 +66,7 @@
         "Municipalities of the Netherlands, generalised from the Base Registration Cartography of the Kadaster. "
       ],
       "date": "2013",
-      "FK_attrib": "GM_CODE",
+      "FKattrib": "GM_CODE",
       "source": [
         "Kadaster",
         "Kadaster"
@@ -86,7 +86,7 @@
         "Natura 2000-areas consist of a combination of 77 Bird Protection areas and 142 EC Habitat Regulation areas as well as the protected nature conservation areas within."
       ],
       "date": "2012",
-      "FK_attrib": "id",
+      "FKattrib": "id",
       "source": [
         "Helpdesk PDOK",
         "Helpdesk PDOK"
@@ -105,7 +105,7 @@
         "Statistical key numbers municipality (selected from StatLine)"
       ],
       "date": "2011",
-      "FK_attrib": "GM_CODE",
+      "FKattrib": "GM_CODE",
       "source": [
         "Centraal Bureau voor de Statistiek",
         "Statistics Netherlands"
@@ -122,7 +122,7 @@
         "Statistical key numbers province (selected from StatLine)"
       ],
       "date": "2011",
-      "FK_attrib": "prov_code",
+      "FKattrib": "prov_code",
       "source": [
         "Centraal Bureau voor de Statistiek",
         "Statistics Netherlands"
@@ -139,7 +139,7 @@
         "Statistical key numbers municipality (selected from StatLine)"
       ],
       "date": "2013",
-      "FK_attrib": "GM_CODE",
+      "FKattrib": "GM_CODE",
       "source": [
         "Centraal Bureau voor de Statistiek",
         "Statistics Netherlands"
@@ -159,7 +159,7 @@
         "Natura 2000-areas consist of a combination of 77 Bird Protection areas and 142 EC Habitat Regulation areas as well as the protected nature conservation areas within."
       ],
       "date": "2012",
-      "FK_attrib": "id",
+      "FKattrib": "id",
       "source": [
         "Helpdesk PDOK",
         "Helpdesk PDOK"
@@ -179,7 +179,7 @@
         "Selected economic data from StatLine."
       ],
       "date": "2012",
-      "FK_attrib": "prov_code",
+      "FKattrib": "prov_code",
       "source": [
         "CBS StatLine",
         "CBS StatLine"
@@ -199,7 +199,7 @@
         "Selected economic data from StatLine."
       ],
       "date": "2013",
-      "FK_attrib": "GM_CODE",
+      "FKattrib": "GM_CODE",
       "source": [
         "CBS StatLine",
         "CBS StatLine"
@@ -219,7 +219,7 @@
         "Natura2000 Protected Areas"
       ],
       "date": "2012",
-      "FK_attrib": "id",
+      "FKattrib": "id",
       "source": [
         "Helpdesk PDOK",
         "Helpdesk PDOK"
@@ -228,6 +228,40 @@
       "serviceURL": "./data/natura2000/geoandattribs.geojson",
       "serviceTypeName": "",
       "serviceOutputFormat": "geojson"
+    },
+    {
+      "name": "CBSGemeenten 2014 live",
+      "description": [
+        "Statistische kerncijfers gemeente (live feed uit CBS OData)",
+        "Statistical key numbers municipality (live feed from CBS OData)"
+      ],
+      "date": "2014",
+      "FKattrib": "WijkenEnBuurten",
+      "source": [
+        "Centraal Bureau voor de Statistiek",
+        "Statistics Netherlands"
+      ],
+      "serviceType": "REST",
+      "serviceURL": "http://opendata.cbs.nl/ODataAPI/odata/82931NED/TypedDataSet?&$filter=(startswith(WijkenEnBuurten,%20%27GM%27)%20eq%20true)&$select=WijkenEnBuurten,Gemeentenaam_1,AantalInwoners_4",
+      "serviceTypeName": "",
+      "serviceOutputFormat": "odata"
+    },
+    {
+      "name": "CBSGemeenten 2014 offline",
+      "description": [
+        "Statistische kerncijfers gemeente (download uit CBS OData)",
+        "Statistical key numbers municipality (from CBS OData)"
+      ],
+      "date": "2014",
+      "FKattrib": "WijkenEnBuurten",
+      "source": [
+        "Centraal Bureau voor de Statistiek",
+        "Statistics Netherlands"
+      ],
+      "serviceType": "localfile",
+      "serviceURL": "./data/gemeenten/TypedDataSet.json",
+      "serviceTypeName": "",
+      "serviceOutputFormat": "odata"
     }
   ],
   "mapgroups": [
@@ -272,6 +306,22 @@
                   "FK": "GM_CODE",
                   "attrib": "AANT_INW",
                   "label": "GM_NAAM"
+                },
+                {
+                  "date": "2014 online",
+                  "geo_data": 2,
+                  "attrib_data": 7,
+                  "FK": "GM_CODE",
+                  "attrib": "AantalInwoners_4",
+                  "label": "Gemeentenaam_1"
+                },
+                {
+                  "date": "2014 offline",
+                  "geo_data": 2,
+                  "attrib_data": 8,
+                  "FK": "GM_CODE",
+                  "attrib": "AantalInwoners_4",
+                  "label": "Gemeentenaam_1"
                 }
               ]
             },
diff --git a/data/old/metaData_en.json b/data/old/metaData_en.json
deleted file mode 100644
index b6f58bb023ce42b400931090375d4829b5f7b401..0000000000000000000000000000000000000000
--- a/data/old/metaData_en.json
+++ /dev/null
@@ -1,307 +0,0 @@
-{
-  "atlasName": "National Atlas of The Netherlands",
-  "atlasVersion": "0.5",
-  "atlasCopyright": "copyright 2011-15: Stichting Wetenschappelijke Atlas Nederland",
-  "baseMapDataURL": "./data/basemap/data.geojson",
-  "baseMapClassAttr": "name",
-  "mapgroups": [
-    {
-      "groupnum": "0",
-      "groupname": "Statistic Core Data per Municipality",
-      "groupDescription": "Municipal data consists of the geometry of all municipalities of The Netherlands wit a number of core statistics as attributes. The municipal borders are generalised from the Base Registration Cartography of the Kadaster. ",
-      "date": "2011",
-      "defaultLabelAttribute": "GM_NAAM",
-      "source": "Source: Statistics Netherlands (CBS)",
-      "//serviceType": "WFS",
-      "//serviceVersion": "1.1.0",
-      "//serviceURL": "http://geoserver.itc.nl/geoserver/wfs?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/gemeenten/data.geojson",
-      "serviceTypeName": "natatlas%3AWijkenBuurten2011%3AGemeenten_2011",
-      "serviceOutputFormat": "json",
-      "mapsubjects": [
-        {
-          "attrib": "GM_CODE",
-          "data_unit": "",
-          "name": "Municipality code",
-          "maptype": "area_colour"
-        },
-        {
-          "attrib": "GM_NAAM",
-          "data_unit": "",
-          "name": "Municipality name",
-          "maptype": "area_label"
-        },
-        {
-          "attrib": "AANT_INW",
-          "data_unit": " inhabitants",
-          "name": "Number of inhabitants",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "AANT_MAN",
-          "data_unit": " male inhabitants",
-          "name": "Number of Males",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "AANT_VROUW",
-          "data_unit": " female inhabitants",
-          "name": "Number of Females",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "P_00_14_JR",
-          "data_unit": "% of total population",
-          "name": "% 0-14",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_15_24_JR",
-          "data_unit": "% of total population",
-          "name": "% age 15-24",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_25_44_JR",
-          "data_unit": "% of total population",
-          "name": "% age 25-44",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_45_64_JR",
-          "data_unit": "% of total population",
-          "name": "% age 45-64",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_65_EO_JR",
-          "data_unit": "% of total population",
-          "name": "% age 65 and older",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "AANTAL_HH",
-          "data_unit": " households",
-          "name": "Number of households",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "BEV_DICHTH",
-          "data_unit": " inhabitants per km2",
-          "name": "Population density",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_EENP_HH",
-          "data_unit": "% of households",
-          "name": "% one person households",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_HH_Z_K",
-          "data_unit": "% of households",
-          "name": "% households without children",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_HH_M_K",
-          "data_unit": "% of households",
-          "name": "% households with children",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "GEM_HH_GR",
-          "data_unit": " persons",
-          "name": "Average household size",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_WEST_AL",
-          "data_unit": "% of total population",
-          "name": "% western foreigners",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_N_W_AL",
-          "data_unit": "% of total population",
-          "name": "% non-western foreigners",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_MAROKKO",
-          "data_unit": "% of total population",
-          "name": "% Moroccons",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_ANT_ARU",
-          "data_unit": "% of total population",
-          "name": "% Antilians and Arubans",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_SURINAM",
-          "data_unit": "% of total population",
-          "name": "% Surinams",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_TURKIJE",
-          "data_unit": "% of total population",
-          "name": "% Turks",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_OVER_NW",
-          "data_unit": "% of total population",
-          "name": "% other non-western foreigners",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "OPP_TOT",
-          "data_unit": " ha.",
-          "name": "Area total",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "OPP_LAND",
-          "data_unit": " ha.",
-          "name": "Area land",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "OPP_WATER",
-          "data_unit": " ha.",
-          "name": "Area water",
-          "maptype": "point_size"
-        }
-      ]
-    },
-    {
-      "groupnum": "1",
-      "groupname": "Statistic Core Data per Province",
-      "groupDescription": "Provincial data aggregated from municipal data. The provincial borders are a union of the municipal borders as supplied by Kadaster.",
-      "date": "2011",
-      "defaultLabelAttribute": "prov_name",
-      "source": "Source: Statistics Netherlands (CBS)",
-      "//serviceType": "WFS",
-      "//serviceVersion": "1.1.0",
-      "//serviceURL": "http://geoserver.itc.nl/natatlas/spatialaggregator?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/provincies/data.geojson",
-      "serviceTypeName": "gemeenten2provincies",
-      "serviceOutputFormat": "json",
-      "mapsubjects": [
-        {
-          "attrib": "id",
-          "data_unit": "",
-          "name": "Provincial code",
-          "maptype": "area_colour",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "min"
-        },
-        {
-          "attrib": "prov_name",
-          "data_unit": "",
-          "name": "Provincial name",
-          "maptype": "area_label",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "sum"
-        },
-        {
-          "attrib": "aant_inw",
-          "data_unit": " inhabitants",
-          "name": "Population",
-          "maptype": "point_size",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "round_avg"
-        },
-        {
-          "attrib": "aantal_hh",
-          "data_unit": " households",
-          "name": "Number of households",
-          "maptype": "point_size",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "sum"
-        },
-        {
-          "attrib": "bev_dichth",
-          "data_unit": " inhabitants per km2",
-          "name": "Population density",
-          "maptype": "area_value",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "round_avg"
-        },
-        {
-          "attrib": "gem_hh_gr",
-          "data_unit": " persons",
-          "name": "Average household size",
-          "maptype": "area_value",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "avg"
-        },
-        {
-          "attrib": "p_west_al",
-          "data_unit": "%",
-          "name": "% western foreigners",
-          "maptype": "area_value",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "round_avg"
-        },
-        {
-          "attrib": "p_n_w_al",
-          "data_unit": "%",
-          "name": "% non-western foreigners",
-          "maptype": "area_value",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "round_avg"
-        },
-        {
-          "attrib": "opp_tot",
-          "data_unit": " ha.",
-          "name": "Total area",
-          "maptype": "point_size",
-          "spatial_aggregation" : "union",
-          "attribute_aggregation": "sum"
-        }
-      ]
-    },
-    {
-      "groupnum": "2",
-      "groupname": "Natura2000 Protected Areas",
-      "groupDescription": "Natura 2000-areas consist of a combination of 77 Bird Protection areas and 142 EC Habitat Regulation areas as well as the protected nature conservation areas within. ",
-      "date": "2012",
-      "defaultLabelAttribute": "naam_n2k",
-      "source": "Source: Helpdesk PDOK",
-      "//serviceType": "WFS",
-      "//serviceURL": "http://geodata.nationaalgeoregister.nl/natura2000/wfs?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/natura2000/data.geojson",
-      "serviceTypeName": "natura2000:natura2000",
-      "serviceOutputFormat": "json",
-      "serviceVersion": "1.1.0",
-      "mapsubjects": [
-        {
-          "attrib": "naam_n2k",
-          "data_unit": "",
-          "name": "Name protected area",
-          "maptype": "area_label"
-        },
-        {
-          "attrib": "status",
-          "data_unit": "",
-          "name": "Status protected area",
-          "maptype": "area_colour"
-        },
-        {
-          "attrib": "area",
-          "data_unit": " m2",
-          "name": "Size protected area",
-          "maptype": "point_size",
-          "bgColor": "#ffffff"
-        }
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/data/old/metaData_nl.json b/data/old/metaData_nl.json
deleted file mode 100644
index f6a91176062c1b93daf28de25d4d6d2275928035..0000000000000000000000000000000000000000
--- a/data/old/metaData_nl.json
+++ /dev/null
@@ -1,301 +0,0 @@
-{
-  "atlasName": "Nationale Atlas van Nederland",
-  "atlasVersion": "0.5",
-  "atlasCopyright": "copyright 2011-15: Stichting Wetenschappelijke Atlas Nederland",
-  "baseMapDataURL": "./data/basemap/data.geojson",
-  "baseMapClassAttr": "name",
-  "mapgroups": [
-    {
-      "groupnum": "0",
-      "groupname": "Statistische Kerncijfers per Gemeente",
-      "groupDescription": "Gemeentedata bevat gegeneraliseerde geometrie van alle gemeenten in Nederland met als attribuut een aantal statistische kerncijfers. De gemeentegrens is afkomstig uit de Basis Registratie Kartografie van het Kadaster. ",
-      "date": "2011",
-      "defaultLabelAttribute": "GM_NAAM",
-      "source": "Bron: Centraal Bureau voor de Statistiek (CBS)",
-      "//serviceType": "WFS",
-      "//serviceVersion": "1.1.0",
-      "//serviceURL": "http://geoserver.itc.nl/geoserver/wfs?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/gemeenten/data.geojson",
-      "serviceTypeName": "natatlas%3AWijkenBuurten2011%3AGemeenten_2011",
-      "serviceOutputFormat": "json",
-      "mapsubjects": [
-        {
-          "attrib": "GM_CODE",
-          "data_unit": "",
-          "name": "Gemeente code",
-          "maptype": "area_colour"
-        },
-        {
-          "attrib": "GM_NAAM",
-          "data_unit": "",
-          "name": "Gemeente naam",
-          "maptype": "area_label"
-        },
-        {
-          "attrib": "AANT_INW",
-          "data_unit": " inwoners",
-          "name": "Aantal inwoners",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "AANT_MAN",
-          "data_unit": " mannelijke inwoners",
-          "name": "Aantal mannen",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "AANT_VROUW",
-          "data_unit": " vrouwelijke inwoners",
-          "name": "Aantal vrouwen",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "P_00_14_JR",
-          "data_unit": "% van totale bevolking",
-          "name": "% 0-14 jaar",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_15_24_JR",
-          "data_unit": "% van totale bevolking",
-          "name": "% 15-24 jaar",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_25_44_JR",
-          "data_unit": "% van totale bevolking",
-          "name": "% 25-44 jaar",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_45_64_JR",
-          "data_unit": "% van totale bevolking",
-          "name": "% 45-64 jaar",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_65_EO_JR",
-          "data_unit": "% van totale bevolking",
-          "name": "% 65 jaar en ouder",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "AANTAL_HH",
-          "data_unit": " huishoudens",
-          "name": "Aantal huishoudens",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "BEV_DICHTH",
-          "data_unit": " inwoners per km2",
-          "name": "Bevolkingsdichtheid",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_EENP_HH",
-          "data_unit": "% van de huishoudens",
-          "name": "% eenpersoons-huishoudens",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_HH_Z_K",
-          "data_unit": "% van de huishoudens",
-          "name": "% huishoudens zonder kinderen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_HH_M_K",
-          "data_unit": "% van de huishoudens",
-          "name": "% huishoudens met kinderen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "GEM_HH_GR",
-          "data_unit": " personen",
-          "name": "Gemiddelde huishoudensgrootte",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_WEST_AL",
-          "data_unit": "% van totale bevolking",
-          "name": "% westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_N_W_AL",
-          "data_unit": "% van totale bevolking",
-          "name": "% niet-westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_MAROKKO",
-          "data_unit": "% van totale bevolking",
-          "name": "% Marokkanen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_ANT_ARU",
-          "data_unit": "%",
-          "name": "% Antilianen en Arubanen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_SURINAM",
-          "data_unit": "% van totale bevolking",
-          "name": "% Surinamers",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_TURKIJE",
-          "data_unit": "% van totale bevolking",
-          "name": "% Turken",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "P_OVER_NW",
-          "data_unit": "% van totale bevolking",
-          "name": "% overige niet-westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "OPP_TOT",
-          "data_unit": " ha.",
-          "name": "Oppervlakte totaal",
-          "maptype": "point_size"
-        }
-      ]
-    },
-    {
-      "groupnum": "1",
-      "groupname": "Statistische Kerncijfers per Provincie",
-      "groupDescription": "Provinciale data geaggregeerd uit de gemeentedata van alle gemeenten in Nederland. De attributen zijn een aantal statistische kerncijfers. De provinciegrens is geaggregeerd uit de gemeentegrenzen.",
-      "date": "2011",
-      "defaultLabelAttribute": "prov_name",
-      "source": "Bron; Centraal Bureau voor de Statistiek (CBS)",
-      "//serviceType": "WFS",
-      "//serviceVersion": "1.1.0",
-      "//serviceURL": "http://geoserver.itc.nl/natatlas/spatialaggregator?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/provincies/data.geojson",
-      "serviceTypeName": "gemeenten2provincies",
-      "serviceOutputFormat": "json",
-      "mapsubjects": [
-        {
-          "attrib": "prov_name",
-          "data_unit": "",
-          "name": "Provincienaam",
-          "maptype": "area_label"
-        },
-        {
-          "attrib": "aant_inw",
-          "data_unit": " inwoners",
-          "name": "Aantal inwoners",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "aantal_hh",
-          "data_unit": " huishoudens",
-          "name": "Aantal huishoudens",
-          "maptype": "point_size"
-        },
-        {
-          "attrib": "bev_dichth",
-          "data_unit": " inwoners per km2",
-          "name": "Bevolkingsdichtheid",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "gem_hh_gr",
-          "data_unit": " personen",
-          "name": "Gemiddelde huishoudensgrootte",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_west_al",
-          "data_unit": "% van totale bevolking",
-          "name": "% westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_n_w_al",
-          "data_unit": "% van totale bevolking",
-          "name": "% niet-westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_marokko",
-          "data_unit": "% van totale bevolking",
-          "name": "% Marokkanen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_ant_aru",
-          "data_unit": "%",
-          "name": "% Antilianen en Arubanen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_surinam",
-          "data_unit": "% van totale bevolking",
-          "name": "% Surinamers",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_turkije",
-          "data_unit": "% van totale bevolking",
-          "name": "% Turken",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "p_over_nw",
-          "data_unit": "% van totale bevolking",
-          "name": "% overige niet-westerse allochtonen",
-          "maptype": "area_value"
-        },
-        {
-          "attrib": "opp_tot",
-          "data_unit": " ha.",
-          "name": "Oppervlakte totaal",
-          "maptype": "point_size"
-        }
-      ]
-    },
-    {
-      "groupnum": "2",
-      "groupname": "Natura2000 Beschermde Gebieden",
-      "groupDescription": "Natura 2000-gebieden zijn een samenvoeging van 77 Vogelrichtlijngebieden en 142 EU Habitat richtlijngebieden en de daarin gelegen beschermde natuurmonumenten. ",
-      "date": "2012",
-      "defaultLabelAttribute": "naam_n2k",
-      "source": "Bron: Helpdesk PDOK",
-      "//serviceType": "WFS",
-      "//serviceURL": "http://geodata.nationaalgeoregister.nl/natura2000/wfs?",
-      "serviceType": "localfile",
-      "serviceURL": "./data/natura2000/data.geojson",
-      "serviceTypeName": "natura2000:natura2000",
-      "serviceOutputFormat": "json",
-      "serviceVersion": "1.1.0",
-      "mapsubjects": [
-        {
-          "attrib": "naam_n2k",
-          "data_unit": "",
-          "name": "Naam beschermd gebied",
-          "maptype": "area_label"
-        },
-        {
-          "attrib": "status",
-          "data_unit": "",
-          "name": "Status beschermd gebied",
-          "maptype": "area_colour"
-        },
-        {
-          "attrib": "area",
-          "data_unit": " m2",
-          "name": "Oppervlakte beschermd gebied",
-          "maptype": "point_size",
-          "bgColor": "#ffffff"
-        }
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/index.html b/index.html
index 207e8809f9ae44d809672c2c071634886acde500..6340949a3637f52da13d2f0c9c550d51ee389c1b 100644
--- a/index.html
+++ b/index.html
@@ -2,10 +2,10 @@
 <meta charset="utf-8">
 <head>
 
-    <title>Nationale Atlas [0.8]</title>
+    <title>Nationale Atlas</title>
 
-    <script src="./js/d3.v3.min.js"></script>
-    <script src="./js/d3-legend-bjk.js"></script>
+    <script src="./js/d3.v4.min.js"></script>
+    <script src="./js/d3-legend.min.js"></script>
     <script src="./js/colorbrewer.js"></script>
     <script src="./js/topojson.min.js"></script>
     <script src="./js/jenks.js"></script>
@@ -19,7 +19,7 @@
 
 </head>
 
-<!-- init with language = 0 = Nederlands -->
+<!-- init NatAtlas.js with language = 0 = Nederlands -->
 <body id="mainWindow" onload="init(0)">
 <div id="chooserDiv">
     <input id="makeMapBtn" type="button" onclick="showMapGroups(MD)" value="KIES ONDERWERP">
@@ -37,7 +37,7 @@
     </p>
 </div>
 <div id="compareDiv">
-    <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="VERGELIJK MET KAART">
+    <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="VERGELIJK MET...">
     <p>Thema:<br>
     <div id="cGroup"></div>
     </p>
diff --git a/index_en.html b/index_en.html
index a51691aa157f2b8e96bfd4f6c53ef52102d51e76..9d4f20a2e210b393521bc076884ecc9da4e4834a 100644
--- a/index_en.html
+++ b/index_en.html
@@ -2,10 +2,10 @@
 <meta charset="utf-8">
 <head>
 
-    <title>National Atlas [0.8]</title>
+    <title>National Atlas</title>
 
-    <script src="./js/d3.v3.min.js"></script>
-    <script src="./js/d3-legend-bjk.js"></script>
+    <script src="./js/d3.v4.min.js"></script>
+    <script src="./js/d3-legend.min.js"></script>
     <script src="./js/colorbrewer.js"></script>
     <script src="./js/topojson.min.js"></script>
     <script src="./js/jenks.js"></script>
@@ -17,7 +17,7 @@
 
 </head>
 
-<!-- init with language = 1 = english -->
+<!-- init NatAtlas.js with language = 1 = english -->
 <body id="mainWindow" onload="init(1)">
 <div id="chooserDiv">
   <input  id="makeMapBtn" type="button" onclick="showMapGroups()" value="CHOOSE SUBJECT" >
@@ -36,7 +36,7 @@
     </p>
 </div>
 <div id="compareDiv">
-    <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="COMPARE WITH MAP">
+    <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="COMPARE WITH...">
     <p>Theme:<br>
     </p>
     <div id="cGroup"></div>
@@ -47,8 +47,8 @@
     </p>
     <div id="cUnit"></div>
     <p>Date:<br>
-    </p>
     <div id="cDate"></div>
+    </p>
 </div>
 <div id="mainMapDiv"></div>
 <div id="compareMapDiv"></div>
diff --git a/js/DataLoader.js b/js/DataLoader.js
index 80918c9fa7efde0df4dcb0717397554df9edfb25..87b2fb7761cafe250f68280d3607d6fcc5ef0abd 100644
--- a/js/DataLoader.js
+++ b/js/DataLoader.js
@@ -17,15 +17,20 @@
  *
  * Depends on Messages.js for error reporting!
  *
- * @version 1.0 [November 2015]
+ * @version 1.1 [December 2015]
+ *
+ * added CBS REST Open Data (using OData3 json output) to DataLoader().attributes
+ *
+ * version 1.0 [November 2015]
+ *
  * first version supports
- * geoData: geojson, topojson
- * attribData: geojson, topojson, csv
+ * geometries: geojson, topojson
+ * attributes: geojson, topojson, csv
  *
  */
 
 
-DataLoader = function () {
+function DataLoader() {
     var loadedCallback = null;
     var toload = {};
     var dataLoaded = {};
@@ -61,7 +66,27 @@ DataLoader = function () {
         },
         attributes: function (name, dataFormat, url, FK) {
             toload[name] = url;
-            if (dataFormat == "geojson") {
+            if (dataFormat == "odata") {
+                d3.json(url, function (error, d) {
+                    if (error != undefined) showError(error, url);
+                    //create a map using FK as key:
+                    var attribData = d3.map();
+                    d.value.forEach(function (f) {
+                        var FKval = f[FK];
+                        var valuesObj = f;
+                        if (FKval == undefined || valuesObj == undefined) {
+                            Messages.setMessage(["Geen geldige FK. Check metadata!\nFK=" + FK + "; FKval=" + FKval,
+                                "No valid FK. Check metadata!\n(FK=" + FK + "; FKval=" + FKval], Messages.errorMsg);
+                        }
+                        if (typeof(FKval) == "string") FKval = FKval.trimRight();
+                        for (var aValueObj in valuesObj)  { //trim extra whitespace of string values:
+                            if (typeof(valuesObj[aValueObj]) == "string") valuesObj[aValueObj] = valuesObj[aValueObj].trimRight();
+                        };
+                        attribData.set(FKval, valuesObj);
+                    });
+                    return loaded(name, attribData);
+                });
+            } else if (dataFormat == "geojson") {
                 d3.json(url, function (error, d) {
                     if (error != undefined) showError(error, url);
                     //create a map using FK as key:
@@ -82,7 +107,6 @@ DataLoader = function () {
                     if (error != undefined) showError(error, url);
                     //create a map using FK as key:
                     var attribData = d3.map();
-                    DEBUG1 = topojson.feature(d, d.objects.geo).features;
                     topojson.feature(d, d.objects.geo).features.forEach(function (f) {
                         var FKval =  f.properties[FK];
                         var valuesObj =  f.properties;
@@ -127,10 +151,13 @@ DataLoader = function () {
 ;
 
 function showError(error, url) {
-    if (error.status == undefined) { // it's not XMLHTTPrequest error}
+    if (error.status == undefined) { // it's not an XMLHTTPrequest error}
         theError = error.name + ": " + error.message;
+    } else if (error.status == 0) {
+        theError = "HTTP " + error.status + " -- " + "Internet disconnected?";
+
     } else {
-        theError = "HTTP " + error.status + "--" + error.statusText;
+        theError = "HTTP " + error.status + " -- " + error.statusText;
     }
     Messages.setMessage(["ACHTERGRONDKAART LADEN MISLUKT!\nURL= " + url + ";\nError: " + theError,
         "ERROR LOADING BACKGROUND MAP!\nURL= " + url + ";\nError: " + theError], Messages.errorMsg);
diff --git a/js/NatAtlas.js b/js/NatAtlas.js
index f32cecda90767d04cc46d897f3eefeceb37b05e7..3964e7314f19e357bf02841c48115cff7f8b97c2 100644
--- a/js/NatAtlas.js
+++ b/js/NatAtlas.js
@@ -6,30 +6,33 @@
  *
  * @author Barend Köbben - b.j.kobben@utwente.nl
  *
- * @version 0.8 [December 2015]
- * -- see ChangeList in README.md
+ * @version 0.9 [October 2016]
+ *
+ *
+ * other changes/versions: see ChangeList in README.md
  */
 
 
-var DEBUG,DEBUG1;
+var DEBUG,DEBUG1; // temp globals for debugging
 
 
 // metadata as bootstrap, all other necessary data is in there:
-var METADATA_URL;
-METADATA_URL = "./data/metaData.json";
+var METADATA_URL = "./data/metaData.json";
 var MD; //global MetaDataObject
 
-// global vars:
-var VIEWER_VERSION = "0.8";
+// global constants:
+var VIEWER_VERSION = "0.9";
 var debugOn = true; //activates debugging message window
 var NL = 0, EN = 1;
-// For now mapDiv fixed to 550x650 (here and in CSS style)
+var typeNum = 0, typeStr = 1;
+
+// For now mapDiv fixed to 500x590 (here AND in CSS style)
 // TODO: Make rescalable (responsive?)
 var mapDivHeight = 590, mapDivWidth = 500;
 var mapVis = 0, graphVis = 1;
 var numClasses = 5;
-var minCircleSize = 0;
-var maxCircleSize = 20;
+var defaultMinCircleSize = 0;
+var defaultMaxCircleSize = 25;
 var curLang;
 var mainMap, mainMapBG, compareMap, compareMapBG;
 var map_dims = {map_scale: 0.0, y_offset: 0.0, x_offset: 0.0};
@@ -37,22 +40,18 @@ var mainLegendDiv, compareLegendDiv, compareDiv, compareToolsDiv,
     compareMapDiv, compareToolsDiv, messageDiv;
 var geo_path;
 var tooltip;
-var xSliderElem;
-var oSliderElem;
-var wSliderElem;
-var bCheckElem;
-var xScale = d3.scale.linear()
+var xSliderElem, oSliderElem, wSliderElem, bCheckElem;
+var xScale = d3.scaleLinear()
     .range([135, 770])
     .domain([0, 1]);
-var oScale = d3.scale.linear()
+var oScale = d3.scaleLinear()
     .range([0, 1])
     .domain([0, 100]);
-var wScale = d3.scale.linear()
+var wScale = d3.scaleLinear()
     .range([0, 500])
     .domain([0, 100]);
 
 
-
 /**
  * INITIALISATION FUNCTION
  *
@@ -147,7 +146,7 @@ function init(language) {
 
                 // initiate d3 geo path stream for handling geometric data
                 // use AffineTransformation function to override default d3 projection mechanism
-                geo_path = d3.geo.path()
+                geo_path = d3.geoPath()
                     .projection(new AffineTransformation(map_dims.map_scale, 0, 0, -(map_dims.map_scale),
                         map_dims.x_offset, map_dims.y_offset))
                 ;
@@ -176,7 +175,7 @@ function init(language) {
 
 /**
  * Implements Affine transformation as a pseudo d3 projection,
- * overriding standard d3.geo.projection.stream, because we do
+ * overriding standard d3.geoProjection.stream, because we do
  * NOT want projection from latlon to cartesian and resampling,
  * but instead translate & scale RD coordinates into screen coordinates
  *
@@ -222,7 +221,6 @@ function AffineTransformation(a, b, c, d, tx, ty) {
  * from MD = the global metadata object for maps
  */
 function showMapGroups() {
-
     hideCompareMap() ;
     //fold open div:
     d3.select("#chooserDiv")
@@ -235,6 +233,7 @@ function showMapGroups() {
     d3.select("#mSubject").selectAll("input").remove();
     d3.select("#mUnit").selectAll("input").remove();
     d3.select("#mDate").selectAll("input").remove();
+    d3.select("#mType").selectAll("input").remove();
     var mapGroupsList = d3.select("#mGroup");
     for (i = 0; i < MD.mapgroups.length; i++) {
         mapGroupsList.append("input")
@@ -246,7 +245,6 @@ function showMapGroups() {
 }
 
 function showMapSubjects(mapGroup) {
-
     //clean up open menus:
     d3.select("#mSubject").selectAll("input").remove();
     d3.select("#mUnit").selectAll("input").remove();
@@ -262,7 +260,6 @@ function showMapSubjects(mapGroup) {
 }
 
 function showMapUnits(mapGroup, mapSubject) {
-
     //clean up open menus:
     d3.select("#mUnit").selectAll("input").remove();
     d3.select("#mDate").selectAll("input").remove();
@@ -277,7 +274,6 @@ function showMapUnits(mapGroup, mapSubject) {
 }
 
 function showMapDates(mapGroup, mapSubject, mapUnit) {
-
     //clean up open menus:
     d3.select("#mDate").selectAll("input").remove();
     var mapDatesList = d3.select("#mDate");
@@ -285,20 +281,19 @@ function showMapDates(mapGroup, mapSubject, mapUnit) {
         mapDatesList.append("input")
             .attr("type", "button")
             .attr("value", MD.mapgroups[mapGroup].mapsubjects[mapSubject].mapunits[mapUnit].mapdates[i].date)
-            .attr("onclick", "createMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");")
+            .attr("onclick", "createMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ", mainMap" + ");")
         ;
     }
 }
 
 
-
 /**
  * Create comparemap menus
  * from MD = the global metadata object for maps to compare
- * [TODO: for now the same as the main MD]
+ * for now the same as the main MD
+ * [TODO: make dependent on MainMap]
  */
 function showCompareGroups() {
-
     showCompareMap() ;
     //fold open div:
     d3.select("#compareDiv")
@@ -311,6 +306,7 @@ function showCompareGroups() {
     d3.select("#cSubject").selectAll("input").remove();
     d3.select("#cUnit").selectAll("input").remove();
     d3.select("#cDate").selectAll("input").remove();
+    d3.select("#cType").selectAll("input").remove();
     var mapGroupsList = d3.select("#cGroup");
     for (i = 0; i < MD.mapgroups.length; i++) {
         mapGroupsList.append("input")
@@ -322,7 +318,6 @@ function showCompareGroups() {
 }
 
 function showCompareSubjects(mapGroup) {
-
     //clean up open menus:
     d3.select("#cSubject").selectAll("input").remove();
     d3.select("#cUnit").selectAll("input").remove();
@@ -338,7 +333,6 @@ function showCompareSubjects(mapGroup) {
 }
 
 function showCompareUnits(mapGroup, mapSubject) {
-
     //clean up open menus:
     d3.select("#cUnit").selectAll("input").remove();
     d3.select("#cDate").selectAll("input").remove();
@@ -353,7 +347,6 @@ function showCompareUnits(mapGroup, mapSubject) {
 }
 
 function showCompareDates(mapGroup, mapSubject, mapUnit) {
-
     //clean up open menus:
     d3.select("#cDate").selectAll("input").remove();
     var mapDatesList = d3.select("#cDate");
@@ -361,7 +354,7 @@ function showCompareDates(mapGroup, mapSubject, mapUnit) {
         mapDatesList.append("input")
             .attr("type", "button")
             .attr("value", MD.mapgroups[mapGroup].mapsubjects[mapSubject].mapunits[mapUnit].mapdates[i].date)
-            .attr("onclick", "createCompareMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");")
+            .attr("onclick", "createMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ", compareMap" + ");")
         ;
     }
 }
@@ -376,7 +369,7 @@ function showCompareDates(mapGroup, mapSubject, mapUnit) {
  */
 function createBackgroundMap(mapLayer, theFormat, URL, theClassAttr) {
     Messages.setMessage(["ACHTERGRONDKAART LADEN...", "LOADING BACKGROUND MAP..."], Messages.showMsg);
-    Messages.setMessage(["", mapLayer[0][0].id + ": " + URL], Messages.debugMsg);
+    Messages.setMessage(["", mapLayer.attr("id") + "; URL=" + URL], Messages.debugMsg);
     DataLoader()
         .geometries('BGMap', theFormat, URL)
         .onload(function (dataLoaded) {
@@ -400,14 +393,25 @@ function createBackgroundMap(mapLayer, theFormat, URL, theClassAttr) {
  *
 // * */
 
-function createMap(mapgroup, mapsubject, mapunit, mapdate) {
+function createMap(mapgroup, mapsubject, mapunit, mapdate, mapLayer) {
+
+    if (mapLayer == mainMap) {
+        //fold down chooserDiv:
+        d3.select("#chooserDiv")
+            .transition().duration(250)
+            .style("width", "120px")
+            .style("height", "20px")
+        ;
+    } else { //mapLayer == compareMap
+        //fold down compareDiv:
+        d3.select("#compareDiv")
+            .transition().duration(250)
+            .style("width", "120px")
+            .style("height", "20px")
+        ;
+        showCompareMap();
+    }
 
-    //fold down chooserDiv:
-    d3.select("#chooserDiv")
-        .transition().duration(250)
-        .style("width", "120px")
-        .style("height", "20px")
-    ;
     var geoData = undefined; // empty data layer
     var attribData = undefined; // empty attrib layer
 
@@ -430,10 +434,11 @@ function createMap(mapgroup, mapsubject, mapunit, mapdate) {
 
         try {
             var geoMD = MD.geo_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].geo_data];
+            var geoFK = geoMD.FKattrib;
             var geoURL = geoMD.serviceURL;
             var attribMD = MD.attrib_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].attrib_data];
+            var atrribFK = attribMD.FKattrib;
             var attribURL = attribMD.serviceURL;
-            var FK = MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].FK;
         } catch (e) {
             console.log(e);
         }
@@ -443,14 +448,14 @@ function createMap(mapgroup, mapsubject, mapunit, mapdate) {
 
         DataLoader()
             .geometries('geoData', geoMD.serviceOutputFormat, geoURL)
-            .attributes('attribData', attribMD.serviceOutputFormat, attribURL, FK)
+            .attributes('attribData', attribMD.serviceOutputFormat, attribURL, atrribFK)
             .onload(function (dataLoaded) {
 
                 Messages.setMessage(["Data geladen.", "Data loaded."], Messages.hideMsg);
-                createMapPlaceholders(dataLoaded.geoData, mainMap);
-                symboliseMap(dataLoaded.attribData, FK, mainMap, mapgroup, mapsubject, mapunit, mapdate);
+                createMapPlaceholders(dataLoaded.geoData, mapLayer);
+                symboliseMap(dataLoaded.attribData, atrribFK, mapLayer, mapgroup, mapsubject, mapunit, mapdate);
                 Messages.setMessage(["Kaart gemaakt.", "Created map."], Messages.hideMsg);
-                showCompareBtn();
+                if (mapLayer == mainMap) showCompareBtn();
 
                 }
             );
@@ -459,71 +464,6 @@ function createMap(mapgroup, mapsubject, mapunit, mapdate) {
 
 } // endfunction createMap()
 
-/**
- * trigger mapmaking according to mapgroup/etc chosen in menu
- *
- * */
-function createCompareMap(mapgroup, mapsubject, mapunit, mapdate) {
-
-    //fold down compareDiv:
-    d3.select("#compareDiv")
-        .transition().duration(250)
-        .style("width", "120px")
-        .style("height", "20px")
-    ;
-    showCompareMap();
-
-    var geoData = undefined; // empty data layer
-    var attribData = undefined; // empty attrib layer
-
-    if (mapgroup == -1 || mapsubject == -1 || mapunit == -1 || mapdate == -1
-        || MD.mapgroups[mapgroup] == undefined
-        || MD.mapgroups[mapgroup].mapsubjects[mapsubject] == undefined
-        || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit] == undefined
-        || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate] == undefined) {
-        Messages.setMessage(
-            ["Geen metadata voor kaart [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]",
-                "No metadata for map [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]"
-            ], Messages.errorMsg);
-
-        return;
-    } else {
-
-        Messages.setMessage(["KAART MAKEN [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]...",
-                "CREATING MAP [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]..."],
-            Messages.showMsg);
-
-        try {
-            var geoMD = MD.geo_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].geo_data];
-            var geoURL = geoMD.serviceURL;
-            var attribMD = MD.attrib_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].attrib_data];
-            var attribURL = attribMD.serviceURL;
-            var FK = MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].FK;
-        } catch (e) {
-            console.log(e);
-        }
-
-        Messages.setMessage(["", "Loading geodata; URL=" + geoURL], Messages.debugMsg);
-        Messages.setMessage(["", "Loading attribute data; URL=" + attribURL], Messages.debugMsg);
-
-        DataLoader()
-            .geometries('geoData', geoMD.serviceOutputFormat, geoURL)
-            .attributes('attribData', attribMD.serviceOutputFormat, attribURL, FK)
-            .onload(function (dataLoaded) {
-
-                    Messages.setMessage(["Data geladen.", "Data loaded."], Messages.hideMsg);
-                    createMapPlaceholders(dataLoaded.geoData, compareMap);
-                    symboliseMap(dataLoaded.attribData, FK, compareMap, mapgroup, mapsubject, mapunit, mapdate);
-                    Messages.setMessage(["Kaart gemaakt.", "Created map."], Messages.hideMsg);
-                    showCompareBtn();
-
-                }
-            );
-
-    } //if-else
-
-} // endfunction createCompareMap()
-
 
 function showCompareBtn() {
     compareDiv.style("display", "inline");
@@ -577,7 +517,7 @@ function createMapPlaceholders(geoData, mapLayer) {
             return y = Math.round(geo_path.centroid(d)[1]);
         }) // transform the supplied json geo path centroid Y to svg "cy"
         .attr("class", "defaultCircles")  // add default style (from css)
-        .attr("r", 0)    // add radius , start with r = 0
+        .attr("r", 0)    // init radius r = 0
         .on("mousemove", function () {
             toolTipMove(d3.event)
         })
@@ -651,13 +591,10 @@ function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, m
             .on("mouseenter", function (d) {
                 toolTipShow(infoTextFromData(d, attribData, tooltipLabel, mapAttrib, mapFK, mapUnit));
             })
-            .transition().ease("bounce").duration(2000)
-            .attr("r", function (d) {
-                var theVal = getAttribValue(d, attribData, mapAttrib, mapFK);
-                var theRadius = (Math.sqrt(theVal) / Math.PI) * dataStats.dCircleRatio;
-                if (theRadius < 0) theRadius = 0;
-                return theRadius;
-            })  // change radius with result from function
+            .transition().ease(d3.easeBounceOut).duration(2000)
+            .attr("r", function (d) { // change radius based on value
+                return dataStats.dClass2Size(+getAttribValue(d, attribData, mapAttrib, mapFK, typeNum));
+            })
         ;
 
 // *** CHOROPLETH MAPS ****
@@ -681,7 +618,7 @@ function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, m
             .attr("class", "classedPolygons") //to avoid being treated as background!
             .style("fill", function (d) {
                 // fill with result from classify function
-                return dataStats.dClass2Value(+getAttribValue(d, attribData, mapAttrib, mapFK));
+                return dataStats.dClass2Value(+getAttribValue(d, attribData, mapAttrib, mapFK, typeNum));
             })
         ;
 
@@ -707,12 +644,12 @@ function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, m
                 toolTipShow(infoTextFromData(d, attribData, tooltipLabel, mapAttrib, mapFK, mapUnit));
             })
             .text(function (d) {
-                return getAttribValue(d, attribData, mapAttrib, mapFK);
+                return getAttribValue(d, attribData, mapAttrib, mapFK, typeStr);
             })
         ;
 
         // *** CHOROCHROMATIC MAPS ****
-    } else if (mapType == "area_colour") { // simple label map:
+    } else if (mapType == "area_colour") { // simple nominal map:
         dataStats = makeStats(attribData, mapAttrib, mapType, mapClassification);
         // shrink circles :
         mapLayer.selectAll("circle")   // select again all the current circle nodes
@@ -731,7 +668,7 @@ function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, m
             .transition().duration(1500)
             .attr("class", "classedPolygons") //to avoid being treated as background!
             .style("fill", function (d) {
-                return dataStats.dClass2Colour(getAttribValue(d, attribData, mapAttrib, mapFK));
+                return dataStats.dClass2Colour(getAttribValue(d, attribData, mapAttrib, mapFK, typeStr));
             })  // fill with result from classify function
         ;
 
@@ -749,19 +686,6 @@ function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, m
     }
 }
 
-function getAttribValue(d, attribData, mapAttrib, mapFK) {
-    var FKval = undefined;
-    var attribValue = undefined;
-    try {
-        FKval = d.properties[mapFK];
-        attribValue = attribData.get(FKval)[mapAttrib];
-    } catch (e) {
-        Messages.setMessage(["Fout in data!\nFK=" + FKval + "; attribuut=" + mapAttrib + "; waarde=" + attribValue,
-        "Error retrieving data!\n(FK=" + FKval + "; attribute=" + mapAttrib + "; value=" + attribValue], Messages.errorMsg);
-    }
-    return attribValue;
-}
-
 /**
  * update legendDiv according to mapgroup/map chosen in menu
  *
@@ -790,6 +714,9 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
             .attr("height", "100%")
         ;
 
+    var legSymWidth = 20;
+    var legSymHeight = 15;
+    var legPadding = 2;
 
     // *** PROPORTIONAL POINT MAPS ****
     if (mapType == "point_size") {
@@ -798,18 +725,17 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
             .attr("class", "mySizeLegend")
             .attr("transform", "translate(20,20)")
         ;
-        var linearSize = d3.scale.linear().domain([0, dataStats.dMax]).range([0, maxCircleSize]);
-        //var linearSize = d3.scale.linear().domain([0,100]).range([10, 20]);
 
-        var mySizeLegend = d3.legend.size()
-                .scale(linearSize)
+        var mySizeLegend = d3.legendSize()
                 .labelFormat(d3.format(mapClassification.format))
                 .shape('circle')
-                .shapePadding(2)
+                .shapePadding(legPadding)
                 .labelOffset(1)
-                .cells(4)
+                .cells([dataStats.dMin, (dataStats.dMax /2), dataStats.dMax])
                 .orient('vertical')
+                .scale(dataStats.dClass2Size)
             ;
+
         legendSVG.select(".mySizeLegend")
             .call(mySizeLegend)
         ;
@@ -822,7 +748,9 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
         }
         legendSVG.selectAll("circle").style("fill", myCol);
 
-        legendSVG.style("height", mySizeLegend.legendHeight());
+        // numclasses in legend = mySizeLegend.cells = 3
+        var legendHeight = ((defaultMaxCircleSize*2 + legPadding) * mySizeLegend.cells().length);
+        legendSVG.style("height", legendHeight);
 
         // *** CHOROPLETH MAPS ****
     } else if (mapType == "area_value") { // choropleth map:
@@ -832,10 +760,13 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
             .attr("class", "myColorLegend")
             .attr("transform", "translate(0,0)")
         ;
-        var myColorLegend = d3.legend.color()
+
+        var myColorLegend = d3.legendColor()
                 .labelFormat(d3.format(mapClassification.format))
                 .labelDelimiter("–")
-                .shapeWidth(20)
+                .shapeWidth(legSymWidth)
+                .shapeHeight(legSymHeight)
+                .shapePadding(legPadding)
                 .useClass(false)
                 .orient('vertical')
                 .scale(dataStats.dClass2Value)
@@ -843,7 +774,9 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
         legendSVG.select(".myColorLegend")
             .call(myColorLegend)
         ;
-        legendSVG.style("height", myColorLegend.legendHeight());
+        // numclasses in legend = scale domain - 1
+        var legendHeight = ((legSymHeight + legPadding) * (dataStats.dClass2Value.domain().length - 1));
+        legendSVG.style("height", legendHeight);
 
         // *** LABEL MAPS ****
     } else if (mapType == "area_label") { // simple label map:
@@ -854,19 +787,23 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType
     } else if (mapType == "area_colour") { // simple label map:
 
         legendSVG.append("g")
-            .attr("class", "myLegend")
+            .attr("class", "myColorLegend")
             .attr("transform", "translate(0,0)")
         ;
-        var legend = d3.legend.color()
+        var myColorLegend = d3.legendColor()
                 .labelFormat(d3.format(".0f"))
-                .shapeWidth(20)
+                .shapeWidth(legSymWidth)
+                .shapeHeight(legSymHeight)
+                .shapePadding(legPadding)
                 .useClass(false)
                 .scale(dataStats.dClass2Colour)
             ;
-        legendSVG.select(".myLegend")
-            .call(legend)
+        legendSVG.select(".myColorLegend")
+            .call(myColorLegend)
         ;
-        legendSVG.style("height", legend.legendHeight());
+        // numclasses in legend = scale domain
+        var legendHeight = ((legSymHeight + legPadding) * (dataStats.dClass2Colour.domain().length));
+        legendSVG.style("height", legendHeight);
 
     } else {
         Messages.setMessage(
@@ -904,67 +841,87 @@ function toolTipShow(theText) {
 function infoTextFromData(d, attribData, labelAttrib, mapAttrib, mapFK, mapUnit) {
     var theText = "";
     if (labelAttrib != mapAttrib) {
-        theText += getAttribValue(d, attribData, labelAttrib, mapFK) + ": "
+        theText += getAttribValue(d, attribData, labelAttrib, mapFK, typeStr) + ": "
     }
-    theText += getAttribValue(d, attribData, mapAttrib, mapFK) + " " + mapUnit;
+    theText += getAttribValue(d, attribData, mapAttrib, mapFK, typeStr) + " " + mapUnit;
     return theText;
 }
 
+function getAttribValue(d, attribData, theAttrib, theFK, asType) {
+    var FKval = undefined;
+    var attribValue = undefined;
+    try {
+        FKval = d.properties[theFK];
+        attribValue = attribData.get(FKval)[theAttrib];
+    } catch (e) {
+        Messages.setMessage(["Kan attribuut [" + theAttrib + "] niet vinden voor deze kaarteenheid [key=" + FKval + "]",
+            "Error retrieving attribute [" + theAttrib + "] for this map unit [key=" + FKval + "]"], Messages.errorMsg);
+        if (asType == typeNum) {attribValue = 0} else {attribValue = "[no data]"};
+    }
+    if (asType == typeNum) {return Number(attribValue); } else {return attribValue};
+    ;
+}
 
 function makeStats(attribData, attrib, mapType, mapClassification) {
 
-    var myStats = {
-        dValues: undefined, dMin: undefined, dMax: undefined, dCircleRatio: undefined,
-        dClasses: undefined, dClass2Value: undefined, dClass2Colour: undefined
+    var dataStats = {
+        dValues: undefined, dMin: undefined, dMax: undefined, dClasses: undefined,
+        dClass2Size: undefined, dClass2Value: undefined, dClass2Colour: undefined
     };
 
     var numFeatures = attribData.size();
-    myStats.dValues = new Array(numFeatures);
-    var i = 0;
+    dataStats.dValues = new Array(numFeatures);
     var errorStr = "";
-    attribData.forEach(function (k, v) {
+    var dataKeys = attribData.keys();
+
+    for (i=0; i < dataKeys.length; i++) {
+        //console.log(attribData.get(dataKeys[i])[attrib]);
         if (mapType == "point_size" || mapType == "area_value") {
-            myStats.dValues[i] = + v[attrib]; //+ to force numerical
-            if (myStats.dValues[i] == undefined || isNaN(myStats.dValues[i])) {
-                errorStr = "Maptype=" + mapType + "; data=" + myStats.dValues[i];
+            dataStats.dValues[i] = + attribData.get(dataKeys[i])[attrib]; //+ to force numerical
+            if (dataStats.dValues[i] == undefined || isNaN(dataStats.dValues[i])) {
+                errorStr = "Maptype=" + mapType + "; data=" + dataStats.dValues[i];
             }
         } else { //area_label or area_colour
-            myStats.dValues[i] = v[attrib];
-            if (myStats.dValues[i] == undefined) {
-                errorStr = "Maptype=" + mapType + "; data=" + myStats.dValues[i];
+            dataStats.dValues[i] = attribData.get(dataKeys[i])[attrib];
+            if (dataStats.dValues[i] == undefined) {
+                errorStr = "Maptype=" + mapType + "; data=" + dataStats.dValues[i];
             }
         }
-        i++;
-    });
+    }
     if (errorStr != "") {
         Messages.setMessage(["ONGELDIGE DATA VOOR DIT MAPTYPE!\n" + errorStr,
             "INVALID DATA FOR THIS MAPTYPE!\n" + errorStr], Messages.errorMsg);
-        console.log(myStats.dValues);
+        console.log(dataStats.dValues);
     }
-
-    var clStr = "type=" + mapClassification.type + "; numclasses=" + mapClassification.numclasses + "; classes="
+    var clStr = "1: type=" + mapClassification.type + "; numclasses=" + mapClassification.numclasses + "; classes="
         + mapClassification.classes + "; colours=" + mapClassification.colours + "; format=" + mapClassification.format;
     console.log(clStr);
 
     // *** PROPORTIONAL POINT MAPS ****
     if (mapType == "point_size") {
-        myStats.dMin = d3.min(myStats.dValues);
+        dataStats.dMin = d3.min(dataStats.dValues);
         //TODO: less crappy solution for NoData vals:
-        if (myStats.dMin <= -99999997) { // is NoData
-            myStats.dMin = 0
+        if (dataStats.dMin <= -99999997) { // is NoData
+            dataStats.dMin = 0
         }
-        myStats.dMax = d3.max(myStats.dValues);
-        // a ratio between values and circles radius for (proportional) ratio maps:
-        myStats.dCircleRatio = maxCircleSize / (Math.sqrt(myStats.dMax) / Math.PI );
+        dataStats.dMax = d3.max(dataStats.dValues);
+        // the ratio between values and circle radius for proportional symbols:
+        var val2RadiusRatio = defaultMaxCircleSize / (Math.sqrt(dataStats.dMax) / Math.PI );
+        dataStats.dClass2Size =  d3.scaleLinear()
+            .domain([dataStats.dMin, dataStats.dMax])
+            .range([(Math.sqrt(dataStats.dMin) / Math.PI) * val2RadiusRatio,
+                (Math.sqrt(dataStats.dMax) / Math.PI) * val2RadiusRatio])
+        ;
+
 
         // *** CHOROPLETH MAPS ****
     } else if (mapType == "area_value") { // choropleth map:
-        myStats.dMin = d3.min(myStats.dValues);
+        dataStats.dMin = d3.min(dataStats.dValues);
         //TODO: less crappy solution for NoData vals:
-        if (myStats.dMin <= -99999997) { // is NoData
-            myStats.dMin = 0
+        if (dataStats.dMin <= -99999997) { // is NoData
+            dataStats.dMin = 0
         }
-        myStats.dMax = d3.max(myStats.dValues);
+        dataStats.dMax = d3.max(dataStats.dValues);
         if (mapClassification.numclasses == undefined) {
             mapClassification.numclasses = 5;
         }
@@ -972,26 +929,26 @@ function makeStats(attribData, attrib, mapType, mapClassification) {
             InvalidClassMessage(clStr + "\nInvalid numclasses (<3 or >11).");
         }
         if (mapClassification.type == "jenks") { //use jenks.js to calculate Jenks Natural breaks
-            myStats.dClasses = jenks(myStats.dValues, mapClassification.numclasses);
+            dataStats.dClasses = jenks(dataStats.dValues, mapClassification.numclasses);
         } else if (mapClassification.type == "manual") { // use manual
             if (mapClassification.classes == undefined) {
                 InvalidClassMessage(clStr + "\nClasses array needed for manual classification.");
             }
             if (mapClassification.classes[0] == "dMin") {
-                mapClassification.classes[0] = myStats.dMin;
+                mapClassification.classes[0] = dataStats.dMin;
             }
             if (mapClassification.classes[mapClassification.classes.length - 1] == "dMax") {
-                mapClassification.classes[mapClassification.classes.length - 1] = myStats.dMax;
+                mapClassification.classes[mapClassification.classes.length - 1] = dataStats.dMax;
             }
             //check manual classes
-            if (mapClassification.classes[0] > myStats.dMin) {
+            if (mapClassification.classes[0] > dataStats.dMin) {
                 InvalidClassMessage(clStr + "\nData min < lowest class.");
-            } else if (mapClassification.classes[mapClassification.classes.length - 1] < myStats.dMax) {
+            } else if (mapClassification.classes[mapClassification.classes.length - 1] < dataStats.dMax) {
                 InvalidClassMessage(clStr + "\nData max > highest class.");
             } else if (mapClassification.classes.length - 1 != mapClassification.numclasses) {
                 InvalidClassMessage(clStr + "\nClasses array length does not match number of classes.");
             } else { // all correct
-                myStats.dClasses = mapClassification.classes;
+                dataStats.dClasses = mapClassification.classes;
             }
 
         } else {
@@ -1003,31 +960,33 @@ function makeStats(attribData, attrib, mapType, mapClassification) {
         } catch (e) {
             InvalidClassMessage(clStr + "\n'" + mapClassification.colours + "' is not a valid ColorBrewer name.");
         }
-        myStats.dClass2Value = d3.scale.quantile()
-            .domain(myStats.dClasses) // use jenks or manual classes (see above)
+        dataStats.dClass2Value = d3.scaleQuantile()
+            .domain(dataStats.dClasses) // use jenks or manual classes (see above)
             .range(CBrange)
         ;
 
+
         // *** LABEL MAPS ****
     } else if (mapType == "area_label") { // simple label map:
 
         // *** CHOROCHROMATIC MAPS ****
-    } else if (mapType == "area_colour") { // simple label map:
+    } else if (mapType == "area_colour") { // chorochromatic map:
 
         // an ordinal scale for (chorochromatic) nominal maps
+        // set numclasses to max number of colours to effectively use (limited to 25)
         if (mapClassification.numclasses == undefined) {
             mapClassification.numclasses = 25; //25 is max for scale MaxColours
         }
         if (mapClassification.numclasses < 3 || mapClassification.numclasses > 25) {
-            InvalidClassMessage(clStr + "\nInvalid numclasses (<3 or >24).");
+            InvalidClassMessage(clStr + "\nInvalid numclasses (<3 or >25).");
         }
         try {
             var CBrange = colorbrewer[mapClassification.colours][mapClassification.numclasses];
         } catch (e) {
             InvalidClassMessage(clStr + "\n'" + mapClassification.colours + "' not valid ColorBrewer name, or no. of classes not available.");
         }
-        myStats.dClass2Colour = d3.scale.ordinal() // make a classes array using d3 ordinal
-            .range(CBrange)
+        dataStats.dClass2Colour = d3.scaleOrdinal() // make a classes array using d3 ordinal
+            .range(CBrange);
 
     } else {
         Messages.setMessage(
@@ -1035,13 +994,13 @@ function makeStats(attribData, attrib, mapType, mapClassification) {
     }
 
     Messages.setMessage(["", "Calculated map statistics."], Messages.debugMsg);
-    //if (debugOn) console.log(myStats);
-    return myStats;
+    if (debugOn) console.log(dataStats);
+    return dataStats;
 }
 
-function InvalidClassMessage(Str) {
-    Messages.setMessage(["ONGELDIGE CLASSIFICATIE!\n" + Str,
-        "INVALID CLASSIFICATION!\n" + Str], Messages.errorMsg);
+function InvalidClassMessage(typeStr) {
+    Messages.setMessage(["ONGELDIGE CLASSIFICATIE!\n" + typeStr,
+        "INVALID CLASSIFICATION!\n" + typeStr], Messages.errorMsg);
 }
 
 
diff --git a/js/d3-legend-bjk.js b/js/d3-legend-bjk.js
deleted file mode 100644
index 8f0ead102a22d96cd48961b1c46287ae8f6fc0a3..0000000000000000000000000000000000000000
--- a/js/d3-legend-bjk.js
+++ /dev/null
@@ -1,750 +0,0 @@
-(function e(t, n, r) {
-    function s(o, u) {
-        if (!n[o]) {
-            if (!t[o]) {
-                var a = typeof require == "function" && require;
-                if (!u && a)return a(o, !0);
-                if (i)return i(o, !0);
-                var f = new Error("Cannot find module '" + o + "'");
-                throw f.code = "MODULE_NOT_FOUND", f
-            }
-            var l = n[o] = {exports: {}};
-            t[o][0].call(l.exports, function (e) {
-                var n = t[o][1][e];
-                return s(n ? n : e)
-            }, l, l.exports, e, t, n, r)
-        }
-        return n[o].exports
-    }
-
-    var i = typeof require == "function" && require;
-    for (var o = 0; o < r.length; o++)s(r[o]);
-    return s
-})({
-    1: [function (require, module, exports) {
-        var helper = require('./legend');
-
-        //BJK: addition/changed
-        // legend.legendHeight() returns total height, for SVG height determination
-        // Barend Köbben b.j.kobben@utwente.nl 10 Aug 2015
-
-        module.exports = function () {
-
-//*** legend.color ***//
-//        alert("color");
-
-            var scale = d3.scale.linear(),
-                shape = "rect",
-                shapeWidth = 15,
-                shapeHeight = 15,
-                shapeRadius = 10,
-                shapePadding = 2,
-                cells = [5],
-                labels = [],
-                useClass = false,
-                labelFormat = d3.format(".01f"),
-                labelOffset = 10,
-                labelAlign = "middle",
-                labelDelimiter = "to",
-                orient = "vertical",
-                path,
-                legendDispatcher = d3.dispatch("cellover", "cellout", "cellclick"),
-            //BJK addition/change
-                legendHeight = 0
-                ;
-
-            function legend(svg) {
-
-                var type = helper.d3_calcType(scale, cells, labels, labelFormat, labelDelimiter);
-
-                var cell = svg.selectAll(".cell").data(type.data),
-                    cellEnter = cell.enter().append("g", ".cell").attr("class", "cell").style("opacity", 1e-6);
-                shapeEnter = cellEnter.append(shape).attr("class", "swatch"),
-                    shapes = cell.select("g.cell " + shape);
-
-                //add event handlers
-                helper.d3_addEvents(cellEnter, legendDispatcher);
-
-                cell.exit().transition().style("opacity", 0).remove();
-
-                helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path);
-
-                helper.d3_addText(svg, cellEnter, type.labels)
-
-                // sets placement
-                var text = cell.select("text"),
-                    shapeSize = shapes[0].map(function (d) {
-                        return d.getBBox();
-                    });
-
-                //sets scale
-                //everything is fill except for line which is stroke,
-                if (!useClass) {
-                    if (shape == "line") {
-                        shapes.style("stroke", type.feature);
-                    } else {
-                        shapes.style("fill", type.feature);
-                    }
-                } else {
-                    shapes.attr("class", function (d) {
-                        return "swatch " + type.feature(d);
-                    });
-                }
-
-                var cellTrans,
-                    textTrans,
-                    textAlign = (labelAlign == "start") ? 0 : (labelAlign == "middle") ? 0.5 : 1;
-
-                //positions cells and text
-                if (orient === "vertical") {
-                    cellTrans = function (d, i) {
-                        // addition by BJK
-                        legendHeight = (i + 1) * (shapeSize[i].height + shapePadding);
-                        return "translate(0, " + (i * (shapeSize[i].height + shapePadding)) + ")";
-                    };
-                    textTrans = function (d, i) {
-                        return "translate(" + (shapeSize[i].width + shapeSize[i].x +
-                            labelOffset) + "," + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
-                    };
-
-                } else if (orient === "horizontal") {
-                    cellTrans = function (d, i) {
-                        // addition by BJK
-                        legendHeight = (2) * shapeSize[i].height + shapePadding + 8;
-                        return "translate(" + (i * (shapeSize[i].width + shapePadding)) + ",0)";
-                    }
-                    textTrans = function (d, i) {
-                        return "translate(" + (shapeSize[i].width * textAlign + shapeSize[i].x) +
-                            "," + (shapeSize[i].height + shapeSize[i].y + labelOffset + 8) + ")";
-                    };
-                }
-
-                helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
-                cell.transition().style("opacity", 1);
-
-            }
-
-
-            legend.scale = function (_) {
-                if (!arguments.length) return legend;
-                scale = _;
-                return legend;
-            };
-
-            legend.cells = function (_) {
-                if (!arguments.length) return legend;
-                if (_.length > 1 || _ >= 2) {
-                    cells = _;
-                }
-                return legend;
-            };
-
-            legend.shape = function (_, d) {
-                if (!arguments.length) return legend;
-                if (_ == "rect" || _ == "circle" || _ == "line" || (_ == "path" && (typeof d === 'string'))) {
-                    shape = _;
-                    path = d;
-                }
-                return legend;
-            };
-
-            legend.shapeWidth = function (_) {
-                if (!arguments.length) return legend;
-                shapeWidth = +_;
-                return legend;
-            };
-
-            legend.shapeHeight = function (_) {
-                if (!arguments.length) return legend;
-                shapeHeight = +_;
-                return legend;
-            };
-
-            legend.shapeRadius = function (_) {
-                if (!arguments.length) return legend;
-                shapeRadius = +_;
-                return legend;
-            };
-
-            legend.shapePadding = function (_) {
-                if (!arguments.length) return legend;
-                shapePadding = +_;
-                return legend;
-            };
-
-            legend.labels = function (_) {
-                if (!arguments.length) return legend;
-                labels = _;
-                return legend;
-            };
-
-            legend.labelAlign = function (_) {
-                if (!arguments.length) return legend;
-                if (_ == "start" || _ == "end" || _ == "middle") {
-                    labelAlign = _;
-                }
-                return legend;
-            };
-
-            legend.labelFormat = function (_) {
-                if (!arguments.length) return legend;
-                labelFormat = _;
-                return legend;
-            };
-
-            legend.labelOffset = function (_) {
-                if (!arguments.length) return legend;
-                labelOffset = +_;
-                return legend;
-            };
-
-            legend.labelDelimiter = function (_) {
-                if (!arguments.length) return legend;
-                labelDelimiter = _;
-                return legend;
-            };
-
-            //BJK addition/change:
-            legend.legendHeight = function () {
-                return legendHeight;
-            };
-
-            legend.useClass = function (_) {
-                if (!arguments.length) return legend;
-                if (_ === true || _ === false) {
-                    useClass = _;
-                }
-                return legend;
-            };
-
-            legend.orient = function (_) {
-                if (!arguments.length) return legend;
-                _ = _.toLowerCase();
-                if (_ == "horizontal" || _ == "vertical") {
-                    orient = _;
-                }
-                return legend;
-            };
-
-            d3.rebind(legend, legendDispatcher, "on");
-
-            return legend;
-
-        };
-
-
-    }, {"./legend": 2}], 2: [function (require, module, exports) {
-        module.exports = {
-
-
-            d3_identity: function (d) {
-                return d;
-            },
-
-            d3_mergeLabels: function (gen, labels) {
-
-                if (labels.length === 0) return gen;
-
-                gen = (gen) ? gen : [];
-
-                var i = labels.length;
-                for (; i < gen.length; i++) {
-                    labels.push(gen[i]);
-                }
-                return labels;
-            },
-
-            d3_linearLegend: function (scale, cells, labelFormat) {
-                var data = [];
-
-                if (cells.length > 1) {
-                    data = cells;
-
-                } else {
-                    var domain = scale.domain(),
-                        increment = (domain[domain.length - 1] - domain[0]) / (cells - 1),
-                        i = 0;
-
-                    for (; i < cells; i++) {
-                        data.push(labelFormat(domain[0] + i * increment));
-                    }
-                }
-
-                return {
-                    data: data,
-                    labels: data,
-                    feature: function (d) {
-                        return scale(d);
-                    }
-                };
-            },
-
-            d3_quantLegend: function (scale, labelFormat, labelDelimiter) {
-                var labels = scale.range().map(function (d) {
-                    var invert = scale.invertExtent(d),
-                        a = labelFormat(invert[0]),
-                        b = labelFormat(invert[1]);
-
-                    // if (( (a) && (a.isNan()) && b){
-                    //   console.log("in initial statement")
-                    return labelFormat(invert[0]) + " " + labelDelimiter + " " + labelFormat(invert[1]);
-                    // } else if (a || b) {
-                    //   console.log('in else statement')
-                    //   return (a) ? a : b;
-                    // }
-
-                });
-
-                return {
-                    data: scale.range(),
-                    labels: labels,
-                    feature: this.d3_identity
-                };
-            },
-
-            d3_ordinalLegend: function (scale) {
-                return {
-                    data: scale.domain(),
-                    labels: scale.domain(),
-                    feature: function (d) {
-                        return scale(d);
-                    }
-                };
-            },
-
-            d3_drawShapes: function (shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) {
-                if (shape === "rect") {
-                    shapes.attr("height", shapeHeight).attr("width", shapeWidth);
-
-                } else if (shape === "circle") {
-                    shapes.attr("r", shapeRadius)//.attr("cx", shapeRadius).attr("cy", shapeRadius);
-
-                } else if (shape === "line") {
-                    shapes.attr("x1", 0).attr("x2", shapeWidth).attr("y1", 0).attr("y2", 0);
-
-                } else if (shape === "path") {
-                    shapes.attr("d", path);
-                }
-            },
-
-            d3_addText: function (svg, enter, labels) {
-                enter.append("text").attr("class", "label");
-                svg.selectAll("g.cell text").data(labels).text(this.d3_identity);
-            },
-
-            d3_calcType: function (scale, cells, labels, labelFormat, labelDelimiter) {
-                var type = scale.ticks ?
-                    this.d3_linearLegend(scale, cells, labelFormat) : scale.invertExtent ?
-                    this.d3_quantLegend(scale, labelFormat, labelDelimiter) : this.d3_ordinalLegend(scale);
-
-                type.labels = this.d3_mergeLabels(type.labels, labels);
-
-                return type;
-            },
-
-            d3_placement: function (orient, cell, cellTrans, text, textTrans, labelAlign) {
-                cell.attr("transform", cellTrans);
-                text.attr("transform", textTrans);
-                if (orient === "horizontal") {
-                    text.style("text-anchor", labelAlign);
-                }
-            },
-
-            d3_addEvents: function (cells, dispatcher) {
-                var _ = this;
-
-                cells.on("mouseover.legend", function (d) {
-                    _.d3_cellOver(dispatcher, d, this);
-                })
-                    .on("mouseout.legend", function (d) {
-                        _.d3_cellOut(dispatcher, d, this);
-                    })
-                    .on("click.legend", function (d) {
-                        _.d3_cellClick(dispatcher, d, this);
-                    });
-            },
-
-            d3_cellOver: function (cellDispatcher, d, obj) {
-                cellDispatcher.cellover.call(obj, d);
-            },
-
-            d3_cellOut: function (cellDispatcher, d, obj) {
-                cellDispatcher.cellout.call(obj, d);
-            },
-
-            d3_cellClick: function (cellDispatcher, d, obj) {
-                cellDispatcher.cellclick.call(obj, d);
-            }
-
-        }
-
-    }, {}], 3: [function (require, module, exports) {
-        var helper = require('./legend');
-
-        module.exports = function () {
-
-//*** legend.size ***//
-//        alert("size");
-
-            var scale = d3.scale.linear(),
-                shape = "rect",
-                shapeWidth = 15,
-                shapePadding = 2,
-                cells = [5],
-                labels = [],
-                useStroke = false,
-                labelFormat = d3.format(".01f"),
-                labelOffset = 10,
-                labelAlign = "middle",
-                labelDelimiter = "to",
-                orient = "vertical",
-                path,
-                legendDispatcher = d3.dispatch("cellover", "cellout", "cellclick"),
-            //BJK addition/change
-                legendHeight = 0
-                ;
-
-            function legend(svg) {
-
-                var type = helper.d3_calcType(scale, cells, labels, labelFormat, labelDelimiter);
-
-                var cell = svg.selectAll(".cell").data(type.data),
-                    cellEnter = cell.enter().append("g", ".cell").attr("class", "cell").style("opacity", 1e-6);
-                shapeEnter = cellEnter.append(shape).attr("class", "swatch"),
-                    shapes = cell.select("g.cell " + shape);
-
-                //add event handlers
-                helper.d3_addEvents(cellEnter, legendDispatcher);
-
-                cell.exit().transition().style("opacity", 0).remove();
-
-                //creates shape
-                if (shape === "line") {
-                    helper.d3_drawShapes(shape, shapes, 0, shapeWidth);
-                    shapes.attr("stroke-width", type.feature);
-                } else {
-                    helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path);
-                }
-
-                helper.d3_addText(svg, cellEnter, type.labels)
-
-                //sets placement
-                var text = cell.select("text"),
-                    shapeSize = shapes[0].map(
-                        function (d, i) {
-                            var bbox = d.getBBox()
-                            var stroke = scale(type.data[i]);
-
-                            if (shape === "line" && orient === "horizontal") {
-                                bbox.height = bbox.height + stroke;
-                            } else if (shape === "line" && orient === "vertical") {
-                                bbox.width = bbox.width;
-                            }
-
-                            return bbox;
-                        });
-
-                var maxH = d3.max(shapeSize, function (d) {
-                        return d.height + d.y;
-                    }),
-                    maxW = d3.max(shapeSize, function (d) {
-                        return d.width + d.x;
-                    });
-
-                var cellTrans,
-                    textTrans,
-                    textAlign = (labelAlign == "start") ? 0 : (labelAlign == "middle") ? 0.5 : 1;
-
-                //positions cells and text
-                if (orient === "vertical") {
-
-                    cellTrans = function (d, i) {
-                        var height = d3.sum(shapeSize.slice(0, i + 1), function (d) {
-                            return d.height;
-                        });
-                        // addition by BJK:
-                        legendHeight = (height + i * shapePadding) + 50;
-                        return "translate(0, " + (height + i * shapePadding) + ")";
-                    };
-
-                    textTrans = function (d, i) {
-                        return "translate(" + (maxW + labelOffset) + "," +
-                            (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
-                    };
-
-                } else if (orient === "horizontal") {
-                    cellTrans = function (d, i) {
-                        var width = d3.sum(shapeSize.slice(0, i + 1), function (d) {
-                            return d.width;
-                        });
-                        // addition by BJK:
-                        legendHeight = d3.sum(shapeSize.slice(0, i + 1), function (d) {
-                            return d.height;
-                        });
-                        return "translate(" + (width + i * shapePadding) + ",0)";
-                    };
-
-                    textTrans = function (d, i) {
-                        return "translate(" + (shapeSize[i].width * textAlign + shapeSize[i].x) + "," +
-                            (maxH + labelOffset ) + ")";
-                    };
-                }
-
-                helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
-                cell.transition().style("opacity", 1);
-
-            }
-
-            legend.scale = function (_) {
-                if (!arguments.length) return legend;
-                scale = _;
-                return legend;
-            };
-
-            legend.cells = function (_) {
-                if (!arguments.length) return legend;
-                if (_.length > 1 || _ >= 2) {
-                    cells = _;
-                }
-                return legend;
-            };
-
-
-            legend.shape = function (_, d) {
-                if (!arguments.length) return legend;
-                if (_ == "rect" || _ == "circle" || _ == "line") {
-                    shape = _;
-                    path = d;
-                }
-                return legend;
-            };
-
-            legend.shapeWidth = function (_) {
-                if (!arguments.length) return legend;
-                shapeWidth = +_;
-                return legend;
-            };
-
-            legend.shapePadding = function (_) {
-                if (!arguments.length) return legend;
-                shapePadding = +_;
-                return legend;
-            };
-
-            legend.labels = function (_) {
-                if (!arguments.length) return legend;
-                labels = _;
-                return legend;
-            };
-
-            legend.labelAlign = function (_) {
-                if (!arguments.length) return legend;
-                if (_ == "start" || _ == "end" || _ == "middle") {
-                    labelAlign = _;
-                }
-                return legend;
-            };
-
-            legend.labelFormat = function (_) {
-                if (!arguments.length) return legend;
-                labelFormat = _;
-                return legend;
-            };
-
-            legend.labelOffset = function (_) {
-                if (!arguments.length) return legend;
-                labelOffset = +_;
-                return legend;
-            };
-
-            legend.labelDelimiter = function (_) {
-                if (!arguments.length) return legend;
-                labelDelimiter = _;
-                return legend;
-            };
-
-            //BJK addition/change:
-            legend.legendHeight = function () {
-                return legendHeight;
-            };
-
-            legend.orient = function (_) {
-                if (!arguments.length) return legend;
-                _ = _.toLowerCase();
-                if (_ == "horizontal" || _ == "vertical") {
-                    orient = _;
-                }
-                return legend;
-            };
-
-            d3.rebind(legend, legendDispatcher, "on");
-
-            return legend;
-
-        };
-
-
-    }, {"./legend": 2}], 4: [function (require, module, exports) {
-        var helper = require('./legend');
-
-//*** legend.symbol ***//
-//    alert("symbol");
-
-        module.exports = function () {
-
-            var scale = d3.scale.linear(),
-                shape = "path",
-                shapeWidth = 15,
-                shapeHeight = 15,
-                shapeRadius = 10,
-                shapePadding = 5,
-                cells = [5],
-                labels = [],
-                useClass = false,
-                labelFormat = d3.format(".01f"),
-                labelAlign = "middle",
-                labelOffset = 10,
-                labelDelimiter = "to",
-                orient = "vertical",
-                legendDispatcher = d3.dispatch("cellover", "cellout", "cellclick"),
-            //BJK addition/change
-                legendHeight = 40
-                ;
-
-            function legend(svg) {
-
-                var type = helper.d3_calcType(scale, cells, labels, labelFormat, labelDelimiter);
-
-                var cell = svg.selectAll(".cell").data(type.data),
-                    cellEnter = cell.enter().append("g", ".cell").attr("class", "cell").style("opacity", 1e-6);
-                shapeEnter = cellEnter.append(shape).attr("class", "swatch"),
-                    shapes = cell.select("g.cell " + shape);
-
-                //add event handlers
-                helper.d3_addEvents(cellEnter, legendDispatcher);
-
-                //remove old shapes
-                cell.exit().transition().style("opacity", 0).remove();
-
-                helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature);
-                helper.d3_addText(svg, cellEnter, type.labels)
-
-                // sets placement
-                var text = cell.select("text"),
-                    shapeSize = shapes[0].map(function (d) {
-                        return d.getBBox();
-                    });
-
-                var maxH = d3.max(shapeSize, function (d) {
-                        return d.height;
-                    }),
-                    maxW = d3.max(shapeSize, function (d) {
-                        return d.width;
-                    });
-
-                var cellTrans,
-                    textTrans,
-                    textAlign = (labelAlign == "start") ? 0 : (labelAlign == "middle") ? 0.5 : 1;
-
-                //positions cells and text
-                if (orient === "vertical") {
-                    cellTrans = function (d, i) {
-                        return "translate(0, " + (i * (maxH + shapePadding)) + ")";
-                    };
-                    textTrans = function (d, i) {
-                        return "translate(" + (maxW + labelOffset) + "," +
-                            (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ")";
-                    };
-
-                } else if (orient === "horizontal") {
-                    cellTrans = function (d, i) {
-                        return "translate(" + (i * (maxW + shapePadding)) + ",0)";
-                    };
-                    textTrans = function (d, i) {
-                        return "translate(" + (shapeSize[i].width * textAlign + shapeSize[i].x) + "," +
-                            (maxH + labelOffset ) + ")";
-                    };
-                }
-
-                helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign);
-                cell.transition().style("opacity", 1);
-
-            }
-
-
-            legend.scale = function (_) {
-                if (!arguments.length) return legend;
-                scale = _;
-                return legend;
-            };
-
-            legend.cells = function (_) {
-                if (!arguments.length) return legend;
-                if (_.length > 1 || _ >= 2) {
-                    cells = _;
-                }
-                return legend;
-            };
-
-            legend.shapePadding = function (_) {
-                if (!arguments.length) return legend;
-                shapePadding = +_;
-                return legend;
-            };
-
-            legend.labels = function (_) {
-                if (!arguments.length) return legend;
-                labels = _;
-                return legend;
-            };
-
-            legend.labelAlign = function (_) {
-                if (!arguments.length) return legend;
-                if (_ == "start" || _ == "end" || _ == "middle") {
-                    labelAlign = _;
-                }
-                return legend;
-            };
-
-            legend.labelFormat = function (_) {
-                if (!arguments.length) return legend;
-                labelFormat = _;
-                return legend;
-            };
-
-            legend.labelOffset = function (_) {
-                if (!arguments.length) return legend;
-                labelOffset = +_;
-                return legend;
-            };
-
-            legend.labelDelimiter = function (_) {
-                if (!arguments.length) return legend;
-                labelDelimiter = _;
-                return legend;
-            };
-
-            legend.orient = function (_) {
-                if (!arguments.length) return legend;
-                _ = _.toLowerCase();
-                if (_ == "horizontal" || _ == "vertical") {
-                    orient = _;
-                }
-                return legend;
-            };
-
-            d3.rebind(legend, legendDispatcher, "on");
-
-            return legend;
-
-        };
-
-
-    }, {"./legend": 2}], 5: [function (require, module, exports) {
-        d3.legend = {
-            color: require('./color'),
-            size: require('./size'),
-            symbol: require('./symbol')
-        };
-    }, {"./color": 1, "./size": 3, "./symbol": 4}]
-}, {}, [5]);
diff --git a/js/jenks.js b/js/jenks.js
index 551fbc403b61b631218be1c27f77639e517b8f85..4d9a7c43b6bc4f9f4004a9c55f8d6d3a75fdf03c 100644
--- a/js/jenks.js
+++ b/js/jenks.js
@@ -2,7 +2,7 @@
 //
 // Implementations: [1](http://danieljlewis.org/files/2010/06/Jenks.pdf) (python),
 // [2](https://github.com/vvoovv/djeo-jenks/blob/master/main.js) (buggy),
-// [3](https://github.com/simogeo/geostats/blob/master/lib/geostats.js#L407) (works)
+// [3](https://github.com/simogeo/geostats/blob/master/lib/geostats.js#L4
 function jenks(data, n_classes) {
 
     // Compute the matrices required for Jenks breaks. These matrices