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