diff --git a/README.md b/README.md index a59a6bd627d1664a047d3ebc7f5bf0a3775b09f9..b39cf9a416e1709905f931b4496367c24006d6e5 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,35 @@ NatAtlas Viewer is a HTML5/SVG webapplication using the D3 Javascript API to create National Atlas webmapping in the framework of the Dutch National GeoData Infrastructure. NatAtlas Viewer is currently only tested fully on recent Chrome and FireFox browsers. - -Check out running tests on <http://geoserver.itc.nl/NatAtlas/NatAtlasViewer/> +Check out stable test versions on <http://kartoweb.itc.nl/NatAtlas/NatAtlasViewer/> (not always the latest version, that one is always in this GitHub)... + +National Atlas Viewer is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. +see http://creativecommons.org/licenses/by-nc-sa/3.0/ + +Author: Barend Köbben - <a href="mailto:b.j.kobben@utwente.nl">b.j.kobben@utwente.nl</a> -- +<a href="kartoweb.itc.nl/kobben">kartoweb.itc.nl/kobben</a> + +##Changelist: + +### 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 + +### 0.7 [August 2015]: +* Implementation of mapCompare tools +* added Jenks algorithm for classification (from GeoStats.js : + https://github.com/simogeo/geostats/blob/master/lib/geostats.js) + +### 0.6 [August 2015]: +* Started using a Changelist ;-) +* First attempt at new MapChooser +* repaired circles sizes to use Math.PI +* use object for dataStats +* Changed metadata to one file with several languages +* moved common styles to natatlas.css +* cleaned up all: clear distinction globals/locals/attributes +* more error checking in metadata loading +* added legends (based on d3.legend by Susie Lu: http://d3-legend.susielu.com) diff --git a/index.html b/index.html index b44fb313b81069fadcaeb2ecdc46ac7d2f74bfc9..207e8809f9ae44d809672c2c071634886acde500 100644 --- a/index.html +++ b/index.html @@ -2,13 +2,15 @@ <meta charset="utf-8"> <head> - <title>Nationale Atlas [0.7]</title> + <title>Nationale Atlas [0.8]</title> <script src="./js/d3.v3.min.js"></script> <script src="./js/d3-legend-bjk.js"></script> <script src="./js/colorbrewer.js"></script> <script src="./js/topojson.min.js"></script> <script src="./js/jenks.js"></script> + <script src="./js/Messages.js"></script> + <script src="./js/DataLoader.js"></script> <script src="./js/NatAtlas.js"></script> <link href='./css/natatlas.css' rel='stylesheet' type='text/css'/> @@ -20,7 +22,7 @@ <!-- init with language = 0 = Nederlands --> <body id="mainWindow" onload="init(0)"> <div id="chooserDiv"> - <input id="makeMapBtn" type="button" onclick="showMapGroups(MD)" value="KIES KAART..."> + <input id="makeMapBtn" type="button" onclick="showMapGroups(MD)" value="KIES ONDERWERP"> <p>Thema:<br> <div id="mGroup"></div> </p> @@ -35,7 +37,7 @@ </p> </div> <div id="compareDiv"> - <input id="cMapBtn" type="button" onclick="showCompareGroups(MD)" value="VERGELIJK MET..."> + <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="VERGELIJK MET KAART"> <p>Thema:<br> <div id="cGroup"></div> </p> @@ -51,7 +53,7 @@ </div> <div id="mainMapDiv"></div> <div id="compareMapDiv"></div> -<div id="mainLegendDiv"></div> +<div id="mainLegendDiv"><a href="index_en.html">English version</a></div> <div id="compareLegendDiv"></div> <div id="compareToolsDiv"> <table> diff --git a/index_en.html b/index_en.html index 51bb0b36c53cc4a21287f00654131c3b813a6725..a51691aa157f2b8e96bfd4f6c53ef52102d51e76 100644 --- a/index_en.html +++ b/index_en.html @@ -2,57 +2,57 @@ <meta charset="utf-8"> <head> - <title>National Atlas [0.7]</title> + <title>National Atlas [0.8]</title> <script src="./js/d3.v3.min.js"></script> <script src="./js/d3-legend-bjk.js"></script> <script src="./js/colorbrewer.js"></script> <script src="./js/topojson.min.js"></script> <script src="./js/jenks.js"></script> + <script src="./js/Messages.js"></script> + <script src="./js/DataLoader.js"></script> <script src="./js/NatAtlas.js"></script> <link href='./css/natatlas.css' rel='stylesheet' type='text/css'/> - <style> - - </style> </head> -<!-- init with language = 0 = Nederlands --> +<!-- init with language = 1 = english --> <body id="mainWindow" onload="init(1)"> <div id="chooserDiv"> - <input id="makeMapBtn" type="button" onclick="showMapGroups(MD)" value="CHOOSE MAP..." > + <input id="makeMapBtn" type="button" onclick="showMapGroups()" value="CHOOSE SUBJECT" > <p>Theme:<br> - <div id="mGroup"></div> </p> + <div id="mGroup"></div> <p>Subject:<br> + </p> <div id="mSubject"></div> </p> <p>Map Unit:<br> - <div id="mUnit"></div> </p> + <div id="mUnit"></div> <p>Date:<br> <div id="mDate"></div> </p> </div> <div id="compareDiv"> - <input id="cMapBtn" type="button" onclick="showCompareGroups(MD)" value="COMPARE WITH..."> + <input id="cMapBtn" type="button" onclick="showCompareGroups()" value="COMPARE WITH MAP"> <p>Theme:<br> - <div id="cGroup"></div> </p> + <div id="cGroup"></div> <p>Subject:<br> - <div id="cSubject"></div> </p> + <div id="cSubject"></div> <p>Map Unit:<br> - <div id="cUnit"></div> </p> + <div id="cUnit"></div> <p>Date:<br> - <div id="cDate"></div> </p> + <div id="cDate"></div> </div> <div id="mainMapDiv"></div> <div id="compareMapDiv"></div> -<div id="mainLegendDiv"></div> +<div id="mainLegendDiv"><a href="index.html">Nederlandse versie</a></div> <div id="compareLegendDiv"></div> <div id="compareToolsDiv"> <table> @@ -62,7 +62,7 @@ oninput="xSlider()"/></td> <td><input id="oSlider" type="range" disabled="disabled" min="0" max="100" step="1" value="100" oninput="oSlider()"/></td> - <td><input id="wSlider" type="range" min="0" max="100" step="1" value="100" + <td><input id="wSlider" type="range" disabled="disabled" min="0" max="100" step="1" value="100" oninput="wSlider()"/></td> <td><input id="bCheck" type="checkbox" checked onchange="bCheck()">Show</td> </tr> diff --git a/js/DataLoader.js b/js/DataLoader.js new file mode 100644 index 0000000000000000000000000000000000000000..80918c9fa7efde0df4dcb0717397554df9edfb25 --- /dev/null +++ b/js/DataLoader.js @@ -0,0 +1,138 @@ +/** + * DataLoader.js: + * + * Data Loader for attribute and geodata for the NatAtlas project + * + * Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. + * see http://creativecommons.org/licenses/by-nc-sa/3.0/ + * + * @author Barend Köbben - b.j.kobben@utwente.nl + * Basic structure based on Mike Bostock's D3 example DataLoader + * + * loads data from various formats and returns in unified format + * geoData => returned as array of n objects, each having a GeoJson geometry and a + * properties object = nested list of attribute key-value pairs + * attribData => returned as d3.map of objects with key = FK, + * value = nested list of attribute key-value pairs + * + * Depends on Messages.js for error reporting! + * + * @version 1.0 [November 2015] + * first version supports + * geoData: geojson, topojson + * attribData: geojson, topojson, csv + * + */ + + +DataLoader = function () { + var loadedCallback = null; + var toload = {}; + var dataLoaded = {}; + var loaded = function (name, d) { + delete toload[name]; + dataLoaded[name] = d; + return notifyIfAll(); + }; + var notifyIfAll = function () { + if ((loadedCallback != null) && d3.keys(toload).length === 0) { + loadedCallback(dataLoaded); + } + }; + var loader = { + geometries: function (name, dataFormat, url) { + toload[name] = url; + if (dataFormat == "geojson") { + d3.json(url, function (error, d) { + if (error != undefined) showError(error, url); + return loaded(name, d.features); + }); + } else if (dataFormat == "topojson") { + d3.json(url, function (error, d) { + if (error != undefined) showError(error, url); + return loaded(name, topojson.feature(d, d.objects.geo).features); + }); + } else { + Messages.setMessage(["DataLoader: Ongeldig formaat [dataFormat = " + dataFormat + "]", + "DataLoader: Invalid format [dataFormat = " + dataFormat + "]"], Messages.errorMsg); + return false; + } + return loader; + }, + attributes: function (name, dataFormat, url, FK) { + toload[name] = url; + if (dataFormat == "geojson") { + d3.json(url, function (error, d) { + if (error != undefined) showError(error, url); + //create a map using FK as key: + var attribData = d3.map(); + d.features.forEach(function (f) { + var FKval = f.properties[FK]; + var valuesObj = f.properties; + 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); + } + attribData.set(FKval, valuesObj); + }); + return loaded(name, attribData); + }); + } else if (dataFormat == "topojson") { + d3.json(url, function (error, d) { + 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; + 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); + } + attribData.set(FKval, valuesObj); + }); + return loaded(name, attribData); + }); + } else if (dataFormat == "csv") { + d3.csv(url, function (error, d) { + if (error != undefined) showError(error, url); + //create a map using FK as key: + var attribData = d3.map(); + d.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); + } + attribData.set(FKval, valuesObj); + }); + return loaded(name, attribData); + }); + } else { + Messages.setMessage(["DataLoader: Ongeldig formaat [dataFormat = " + dataFormat + "]", + "DataLoader: Invalid format [dataFormat = " + dataFormat + "]"], Messages.errorMsg); + return false; + } + return loader; + }, + onload: function (callback) { + loadedCallback = callback; + notifyIfAll(); + } + }; + return loader; +} +; + +function showError(error, url) { + if (error.status == undefined) { // it's not XMLHTTPrequest error} + theError = error.name + ": " + error.message; + } else { + 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); + return; +} \ No newline at end of file diff --git a/js/Messages.js b/js/Messages.js new file mode 100644 index 0000000000000000000000000000000000000000..003812f373acff7cd001eaccaab940bcf0373189 --- /dev/null +++ b/js/Messages.js @@ -0,0 +1,56 @@ +/** + * Messages.js: + * * Bi-lingual messaging system used for messages as well as errors and debug info + * + * part of the National Atlas Viewer system + * + * Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. + * see http://creativecommons.org/licenses/by-nc-sa/3.0/ + * + * @author Barend Köbben - b.j.kobben@utwente.nl + * + * @version 1.0 [October 2015] + * part of attempts at creating parts of NatAtlasViewer as seperate classes + * re-implementation of existing Message function + * + */ + +Messages = { + + MsgDiv: null, + + init: function(div, language) { + Messages.MsgDiv = div; + Messages.curLang = language; + Messages.NL = 0, Messages.EN = 1; + Messages.errorMsg = 0, Messages.showMsg = 1, Messages.hideMsg = 2, Messages.debugMsg = 3; + //alert("inited !"); + } + + , + + setMessage: function (messageStrs, messageType) { + //first some checking and if necessary repairing: + if (messageStrs.length == 0) { + //no message: + messageStrs[0] = messageStrs[1] = "No message supplied to SetMessage!"; + } else if ((messageStrs.length == 1)) { + //message in only one language, copy to other language: + messageStrs[1] = messageStrs[0]; + } + if (messageType == Messages.showMsg) { //log message and display message box + Messages.MsgDiv.innerHTML = messageStrs[Messages.curLang]; + Messages.MsgDiv.style.display = "inline" + } else if (messageType == Messages.hideMsg) { //log message and hide messagebox + Messages.MsgDiv.innerHTML = messageStrs[Messages.curLang]; + Messages.MsgDiv.style.display = "none" + } else if (messageType == Messages.errorMsg) { //display Javascript alert + alert(messageStrs[Messages.curLang]); + } + if (debugOn) { // all messageTypes are logged in console: + // debug messages only in english + console.log(messageStrs[Messages.EN]); + } + } + +} diff --git a/js/NatAtlas.js b/js/NatAtlas.js index 090ffdb9ec0e8cbe83d8441529902f1431696622..f32cecda90767d04cc46d897f3eefeceb37b05e7 100644 --- a/js/NatAtlas.js +++ b/js/NatAtlas.js @@ -6,45 +6,35 @@ * * @author Barend Köbben - b.j.kobben@utwente.nl * - * @version 0.7.0 [August 2015] - * - Implementation of mapCompare tools - * - * earlier: 0.6.0 [August 2015] - * - First attempt at new MapChooser - * - repaired circles sizes to use Math.PI - * - use object for dataStats - * - Changed metadata to one file with several languages - * - moved common styles to natatlas.css - * - cleaned up all: clear distinction globals/locals/attributes - * - more error checking in metadata loading - * - added legends (based on d3.legend by Susie Lu: d3-legend.susielu.com) - * + * @version 0.8 [December 2015] + * -- see ChangeList in README.md */ + +var DEBUG,DEBUG1; + + // metadata as bootstrap, all other necessary data is in there: var METADATA_URL; METADATA_URL = "./data/metaData.json"; var MD; //global MetaDataObject -// global varants: -var VIEWER_VERSION = "0.6"; +// global vars: +var VIEWER_VERSION = "0.8"; var debugOn = true; //activates debugging message window var NL = 0, EN = 1; -var errorMsg = 0, showMsg = 1, hideMsg = 2, debugMsg = 3; // For now mapDiv fixed to 550x650 (here and in CSS style) // TODO: Make rescalable (responsive?) var mapDivHeight = 590, mapDivWidth = 500; - -// global vars: +var mapVis = 0, graphVis = 1; var numClasses = 5; var minCircleSize = 0; var maxCircleSize = 20; -var mapgroup = -1, mapsubject = -1, - mapunit = -1, mapdate = -1; var curLang; var mainMap, mainMapBG, compareMap, compareMapBG; var map_dims = {map_scale: 0.0, y_offset: 0.0, x_offset: 0.0}; -var mainLegendDiv, compareLegendDiv, compareDiv, compareToolsDiv,messageDiv; +var mainLegendDiv, compareLegendDiv, compareDiv, compareToolsDiv, + compareMapDiv, compareToolsDiv, messageDiv; var geo_path; var tooltip; var xSliderElem; @@ -62,7 +52,6 @@ var wScale = d3.scale.linear() .domain([0, 100]); -var DEBUG; /** * INITIALISATION FUNCTION @@ -84,7 +73,12 @@ function init(language) { alert("Invalid startup language in initialisation [" + language + "]") } MD = undefined; + + messageDiv = document.getElementById("messageDiv"); + Messages.init(messageDiv,curLang); + + mainLegendDiv = d3.select("#mainLegendDiv"); compareLegendDiv = d3.select("#compareLegendDiv"); compareDiv = d3.select("#compareDiv"); @@ -107,10 +101,10 @@ function init(language) { } else { theError = "HTTP " + error.status + "--" + error.statusText; } - setMessage([ + Messages.setMessage([ "BOOTSTRAP MISLUKT: Laden MetaData mislukt\nURL= " + metadataURL + "\n" + theError, "BOOTSTRAP FAILED: Error loading MetaData\nURL= " + metadataURL + "\n" + theError - ], errorMsg); + ], Messages.errorMsg); } else { MD = json; //make global // use RD projection limits to calculate scale and bounds needed for @@ -160,8 +154,9 @@ function init(language) { // load background maps from basemap data and render it // using the attrib baseMapClassAttr as a class name - createBackgroundMap(mainMapBG, MD.baseMapDataURL, MD.baseMapClassAttr); - createBackgroundMap(compareMapBG, MD.baseMapDataURL, MD.baseMapClassAttr); + createBackgroundMap(mainMapBG, MD.baseMapDataFormat, MD.baseMapDataURL, MD.baseMapClassAttr); + createBackgroundMap(compareMapBG, MD.baseMapDataFormat, MD.baseMapDataURL, MD.baseMapClassAttr); + } }); @@ -222,38 +217,6 @@ function AffineTransformation(a, b, c, d, tx, ty) { }; } - -/** - * Bi-lingual messaging system used for messages as well as errors and debug info - * - * @param messageStrs : array of messages [0=NL,1=EN] - * @param messageType : var defining messageType (errorMsg,showMsg,hideMsg,debugMsg) - */ -function setMessage(messageStrs, messageType) { - //first some checking and if necessary repairing: - if (messageStrs.length == 0) { - //no message: - messageStrs[0] = messageStrs[1] = "No message supplied to SetMessage!"; - } else if ((messageStrs.length == 1)) { - //only one language supplied, copy to other language: - messageStrs[1] = messageStrs[0]; - } - if (messageType == showMsg) { //log message and display message box - messageDiv.innerHTML = messageStrs[curLang]; - messageDiv.style.display = "inline" - } else if (messageType == hideMsg) { //log message and hide messagebox - messageDiv.innerHTML = messageStrs[curLang]; - messageDiv.style.display = "none" - } else if (messageType == errorMsg) { //display Javascript alert - alert(messageStrs[curLang]); - } - if (debugOn) { // all messageTypes are logged in console: - // debug messages only in english - console.log(messageStrs[EN]); - } -} - - /** * Create map menus * from MD = the global metadata object for maps @@ -322,13 +285,17 @@ 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", "chooseMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");") + .attr("onclick", "createMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");") ; } -}/** +} + + + +/** * Create comparemap menus * from MD = the global metadata object for maps to compare - * [for now the same as the main MD] + * [TODO: for now the same as the main MD] */ function showCompareGroups() { @@ -394,54 +361,46 @@ 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", "chooseCompareMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");") + .attr("onclick", "createCompareMap(" + mapGroup + "," + mapSubject + "," + mapUnit + "," + i + ");") ; } } + + /** - * Create background layer + * Create background map layers * * @param URL : URL to metadata json * @param theClass : data attribute to use for CSS class name */ -function createBackgroundMap(mapLayer, URL, theClassAttr) { - setMessage(["ACHTERGRONDKAART LADEN...", "LOADING BACKGROUND MAP..."], showMsg); - setMessage(["", mapLayer[0][0].id + ": " + URL], debugMsg); - d3.json( - URL, - // inline call-back function - function (error, json) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["ACHTERGRONDKAART LADEN MISLUKT!\nURL= " + URL + ";\nError: " + theError, - "ERROR LOADING BACKGROUND MAP!\nURL= " + URL + ";\nError: " + theError], errorMsg); - return; - } - +function createBackgroundMap(mapLayer, theFormat, URL, theClassAttr) { + Messages.setMessage(["ACHTERGRONDKAART LADEN...", "LOADING BACKGROUND MAP..."], Messages.showMsg); + Messages.setMessage(["", mapLayer[0][0].id + ": " + URL], Messages.debugMsg); + DataLoader() + .geometries('BGMap', theFormat, URL) + .onload(function (dataLoaded) { // first make polygons: mapLayer.selectAll("path") // create path nodes - .data(json.features) // bind & join to features array + .data(dataLoaded.BGMap) // bind & join to features array .enter().append("path") // for each create a new path .attr("d", geo_path) // use special transformation stream initialised in init() for path data .attr("class", function (d) { return d3.map(d.properties).get(theClassAttr); //get class from data using the Attr }) ; - setMessage(["Achtergrondkaart geladen.", "Background Map loaded."], hideMsg); - }); + Messages.setMessage(["Achtergrondkaart geladen.", "Background Map loaded."], Messages.hideMsg); + } + ); } /** * trigger mapmaking according to mapgroup/etc chosen in menu * - * */ -function chooseMap(mapgroup, mapsubject, mapunit, mapdate) { +// * */ + +function createMap(mapgroup, mapsubject, mapunit, mapdate) { //fold down chooserDiv: d3.select("#chooserDiv") @@ -449,7 +408,6 @@ function chooseMap(mapgroup, mapsubject, mapunit, mapdate) { .style("width", "120px") .style("height", "20px") ; - var geoData = undefined; // empty data layer var attribData = undefined; // empty attrib layer @@ -458,135 +416,54 @@ function chooseMap(mapgroup, mapsubject, mapunit, mapdate) { || MD.mapgroups[mapgroup].mapsubjects[mapsubject] == undefined || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit] == undefined || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate] == undefined) { - setMessage( + Messages.setMessage( ["Geen metadata voor kaart [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]", "No metadata for map [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]" - ], errorMsg); + ], Messages.errorMsg); return; } else { - setMessage(["KAART MAKEN [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]...", + Messages.setMessage(["KAART MAKEN [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]...", "CREATING MAP [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]..."], - showMsg); + Messages.showMsg); - // foreign key to link geo with attrib data - var FK = MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].FK; - - // geo_data loader: 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); } - setMessage(["", "Loading geodata; URL=" + geoURL], debugMsg); - d3.json(geoURL, function (error, json) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["KAART LADEN MISLUKT!\nURL= " + geoURL + ";\nError: " + theError, - "ERROR LOADING MAP!\nURL= " + geoURL + ";\nError: " + theError], errorMsg); - return; - } - if (geoMD.serviceOutputFormat == "geojson") { - geoData = json; //load data - } else if (geoMD.serviceOutputFormat == "topojson") { - geoData = topojson.feature(json, json.objects.geo); - } else { - setMessage(["Ongeldig formaat [serviceOutputFormat = " + geoMD.serviceOutputFormat + "]", - "Invalid format [serviceOutputFormat = " + geoMD.serviceOutputFormat + "]"], errorMsg); - } + Messages.setMessage(["", "Loading geodata; URL=" + geoURL], Messages.debugMsg); + Messages.setMessage(["", "Loading attribute data; URL=" + attribURL], Messages.debugMsg); - // attrib_data loader: - try { - var attribMD = MD.attrib_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].attrib_data]; - var attribURL = attribMD.serviceURL; - } catch (e) { - console.log(e); - } - setMessage(["", "Loading attribute data; URL=" + attribURL], debugMsg); - if (attribMD.serviceOutputFormat == "geojson") { - - d3.json(attribURL, function (error, json) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["LADEN ATTRIBUUTDATA MISLUKT!\nURL= " + attribURL + ";\nError: " + theError, - "ERROR LOADING ATTRIBUTE DATA!\nURL= " + attribURL + ";\nError: " + theError], errorMsg); - return; - } - - //create a map using FK as key: - attribData = d3.map(); - json.features.forEach(function (d,i) { - var FKval = eval("d.properties." + FK); - var valuesObj = d.properties; - if (FKval == undefined || valuesObj == undefined) { - setMessage(["Geen geldige FK. Check metadata!\nFK=" + FK + "; FKval=" + FKval, - "No valid FK. Check metadata!\n(FK=" + FK + "; FKval=" + FKval], errorMsg); - } - attribData.set(FKval,valuesObj); - }); - - setMessage(["Kaartdata geladen.", "Map data loaded."], hideMsg); - createMap(geoData, mainMap); - symboliseMap(geoData, attribData, FK, mainMap, mapgroup, mapsubject, mapunit, mapdate); - setMessage(["Kaart gemaakt.", "Created map."], hideMsg); - showCompareMapBtn(); - }); // geojson attrib_data loader - - } else if (attribMD.serviceOutputFormat == "csv") { - - d3.csv(attribURL, function (error, csv) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["LADEN ATTRIBUUTDATA MISLUKT!\nURL= " + attribURL + ";\nError: " + theError, - "ERROR LOADING ATTRIBUTE DATA!\nURL= " + attribURL + ";\nError: " + theError], errorMsg); - return; - } - - //create a map using FK as key: - attribData = d3.map(csv, function (d) { - var FKval = eval("d." + FK); - if (FKval == undefined) { - setMessage(["Geen geldige FK. Check metadata!\nFK=" + FK + "; FKval=" + FKval, - "No valid FK. Check metadata!\n(FK=" + FK + "; FKval=" + FKval], errorMsg); - } - return FKval; - }); - - setMessage(["Kaartdata geladen.", "Map data loaded."], hideMsg); - createMap(geoData, mainMap); - symboliseMap(geoData, attribData, FK, mainMap, mapgroup, mapsubject, mapunit, mapdate); - setMessage(["Kaart gemaakt.", "Created map."], hideMsg); - showCompareMapBtn(); - }); // CSV attrib_data loader + 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, mainMap); + symboliseMap(dataLoaded.attribData, FK, mainMap, mapgroup, mapsubject, mapunit, mapdate); + Messages.setMessage(["Kaart gemaakt.", "Created map."], Messages.hideMsg); + showCompareBtn(); + + } + ); - } else { - setMessage(["Ongeldig formaat [serviceOutputFormat = " + attribMD.serviceOutputFormat + "]", - "Invalid format [serviceOutputFormat = " + attribMD.serviceOutputFormat + "]"], errorMsg); - } - }); //geo_data loader } //if-else -} // endfunction chooseMap() + +} // endfunction createMap() /** * trigger mapmaking according to mapgroup/etc chosen in menu * * */ -function chooseCompareMap(mapgroup, mapsubject, mapunit, mapdate) { +function createCompareMap(mapgroup, mapsubject, mapunit, mapdate) { //fold down compareDiv: d3.select("#compareDiv") @@ -604,130 +481,51 @@ function chooseCompareMap(mapgroup, mapsubject, mapunit, mapdate) { || MD.mapgroups[mapgroup].mapsubjects[mapsubject] == undefined || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit] == undefined || MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate] == undefined) { - setMessage( + Messages.setMessage( ["Geen metadata voor kaart [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]", "No metadata for map [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]" - ], errorMsg); + ], Messages.errorMsg); return; } else { - setMessage(["KAART MAKEN [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]...", + Messages.setMessage(["KAART MAKEN [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]...", "CREATING MAP [" + mapgroup + "," + mapsubject + "," + mapunit + "," + mapdate + "]..."], - showMsg); - - // foreign key to link geo with attrib data - var FK = MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].FK; + Messages.showMsg); - // geo_data loader: 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); } - setMessage(["", "Loading geodata; URL=" + geoURL], debugMsg); - d3.json(geoURL, function (error, json) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["KAART LADEN MISLUKT!\nURL= " + geoURL + ";\nError: " + theError, - "ERROR LOADING MAP!\nURL= " + geoURL + ";\nError: " + theError], errorMsg); - return; - } - if (geoMD.serviceOutputFormat == "geojson") { - geoData = json; //load data - } else if (geoMD.serviceOutputFormat == "topojson") { - geoData = topojson.feature(json, json.objects.geo); - } else { - setMessage(["Ongeldig formaat [serviceOutputFormat = " + geoMD.serviceOutputFormat + "]", - "Invalid format [serviceOutputFormat = " + geoMD.serviceOutputFormat + "]"], errorMsg); - } + Messages.setMessage(["", "Loading geodata; URL=" + geoURL], Messages.debugMsg); + Messages.setMessage(["", "Loading attribute data; URL=" + attribURL], Messages.debugMsg); - // attrib_data loader: - try { - var attribMD = MD.attrib_sources[MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].attrib_data]; - var attribURL = attribMD.serviceURL; - } catch (e) { - console.log(e); - } - setMessage(["", "Loading attribute data; URL=" + attribURL], debugMsg); - if (attribMD.serviceOutputFormat == "geojson") { - - d3.json(attribURL, function (error, json) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["LADEN ATTRIBUUTDATA MISLUKT!\nURL= " + attribURL + ";\nError: " + theError, - "ERROR LOADING ATTRIBUTE DATA!\nURL= " + attribURL + ";\nError: " + theError], errorMsg); - return; - } - - //create a map using FK as key: - attribData = d3.map(); - json.features.forEach(function (d,i) { - var FKval = eval("d.properties." + FK); - var valuesObj = d.properties; - if (FKval == undefined || valuesObj == undefined) { - setMessage(["Geen geldige FK. Check metadata!\nFK=" + FK + "; FKval=" + FKval, - "No valid FK. Check metadata!\n(FK=" + FK + "; FKval=" + FKval], errorMsg); - } - attribData.set(FKval,valuesObj); - }); - - setMessage(["Kaartdata geladen.", "Map data loaded."], hideMsg); - createMap(geoData, compareMap); - symboliseMap(geoData, attribData, FK, compareMap, mapgroup, mapsubject, mapunit, mapdate); - setMessage(["Kaart gemaakt.", "Created map."], hideMsg); - }); // geojson attrib_data loader - - } else if (attribMD.serviceOutputFormat == "csv") { - - d3.csv(attribURL, function (error, csv) { - if (error != undefined) { - if (error.status == undefined) { // it's not XMLHTTPrequest error} - theError = error.name + ": " + error.message; - } else { - theError = "HTTP " + error.status + "--" + error.statusText; - } - setMessage(["LADEN ATTRIBUUTDATA MISLUKT!\nURL= " + attribURL + ";\nError: " + theError, - "ERROR LOADING ATTRIBUTE DATA!\nURL= " + attribURL + ";\nError: " + theError], errorMsg); - return; - } - - //create a map using FK as key: - attribData = d3.map(csv, function (d) { - var FKval = eval("d." + FK); - if (FKval == undefined) { - setMessage(["Geen geldige FK. Check metadata!\nFK=" + FK + "; FKval=" + FKval, - "No valid FK. Check metadata!\n(FK=" + FK + "; FKval=" + FKval], errorMsg); - } - return FKval; - }); - - setMessage(["Kaartdata geladen.", "Map data loaded."], hideMsg); - createMap(geoData, compareMap); - symboliseMap(geoData, attribData, FK, compareMap, mapgroup, mapsubject, mapunit, mapdate); - setMessage(["Kaart gemaakt.", "Created map."], hideMsg); - }); // CSV attrib_data loader + 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(); + + } + ); - } else { - setMessage(["Ongeldig formaat [serviceOutputFormat = " + attribMD.serviceOutputFormat + "]", - "Invalid format [serviceOutputFormat = " + attribMD.serviceOutputFormat + "]"], errorMsg); - } - }); //geo_data loader } //if-else -} // endfunction chooseCompareMap() +} // endfunction createCompareMap() -function showCompareMapBtn() { + +function showCompareBtn() { compareDiv.style("display", "inline"); } @@ -750,14 +548,14 @@ function hideCompareMap() { /** * Creates an empty map with polygon, point and label placeholders */ -function createMap(geoData, mapLayer) { +function createMapPlaceholders(geoData, mapLayer) { // first delete existing map, if any: mapLayer.selectAll("*").remove(); // make polygons: mapLayer.selectAll("path") // select path nodes - .data(geoData.features) // bind and join these to features in json + .data(geoData) // bind and join these to features in json .enter().append("path") // for each create a new path .attr("d", geo_path) // transform supplied json geo to svg "d" .attr("class", "defaultPolygons") // for now all same fill-stroke (from css) @@ -770,7 +568,7 @@ function createMap(geoData, mapLayer) { ; // create proportional circles on top: mapLayer.selectAll("circle") // select circle nodes - .data(geoData.features) // bind and join these to the features array in json + .data(geoData) // bind and join these to the features array in json .enter().append("circle") // for each create a new circle .attr("cx", function (d) { return x = Math.round(geo_path.centroid(d)[0]); @@ -789,7 +587,7 @@ function createMap(geoData, mapLayer) { ; // create empty text items: mapLayer.selectAll("text") // select text nodes - .data(geoData.features) // bind and join these to the features array in json + .data(geoData) // bind and join these to the features array in json .enter().append("text") // for each create a new text object .text("") .attr("class", "label") @@ -815,7 +613,7 @@ function createMap(geoData, mapLayer) { /** * Sets point size, polygon fill and/or label text of map based on data chosen */ -function symboliseMap(geoData, attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, mapdate) { +function symboliseMap(attribData, FK, mapLayer, mapgroup, mapsubject, mapunit, mapdate) { var mapType = MD.mapgroups[mapgroup].mapsubjects[mapsubject].maptype; var mapAttrib = MD.mapgroups[mapgroup].mapsubjects[mapsubject].mapunits[mapunit].mapdates[mapdate].attrib; @@ -840,9 +638,16 @@ function symboliseMap(geoData, attribData, FK, mapLayer, mapgroup, mapsubject, m mapLayer.selectAll("text") // select text nodes .text("") ; - // change proportional circles sizes: + //determine colour to use: + var myCol; + if (mapLayer == mainMap) { + myCol = mapClassification.colours[0]; + } else { + myCol = mapClassification.colours[1]; + } + // change proportional circles sizes (and maybe colour): mapLayer.selectAll("circle") // select again all the current circle nodes - .style("fill", mapClassification.colours) + .style("fill", myCol) .on("mouseenter", function (d) { toolTipShow(infoTextFromData(d, attribData, tooltipLabel, mapAttrib, mapFK, mapUnit)); }) @@ -932,11 +737,11 @@ function symboliseMap(geoData, attribData, FK, mapLayer, mapgroup, mapsubject, m } else { - setMessage( - ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], errorMsg); + Messages.setMessage( + ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], Messages.errorMsg); } - setMessage(["", "Created map symbolisation."], debugMsg); + Messages.setMessage(["", "Created map symbolisation."], Messages.debugMsg); if (mapLayer == mainMap) { makeLegend(mainLegendDiv, mapgroup, mapsubject, mapunit, mapdate, mapType, mapClassification, dataStats); } else { @@ -948,11 +753,11 @@ function getAttribValue(d, attribData, mapAttrib, mapFK) { var FKval = undefined; var attribValue = undefined; try { - FKval = eval("d.properties." + mapFK); - attribValue = eval("attribData.get(FKval)." + mapAttrib); + FKval = d.properties[mapFK]; + attribValue = attribData.get(FKval)[mapAttrib]; } catch (e) { - setMessage(["Fout in data!\nFK=" + FKval + "; attribuut=" + mapAttrib + "; waarde=" + attribValue, - "Error retrieving data!\n(FK=" + FKval + "; attribute=" + mapAttrib + "; value=" + attribValue], errorMsg); + 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; } @@ -1008,7 +813,14 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType legendSVG.select(".mySizeLegend") .call(mySizeLegend) ; - legendSVG.selectAll("circle").style("fill", mapClassification.colours); + //determine colour to use: + var myCol; + if (whichLegend == mainLegendDiv) { + myCol = mapClassification.colours[0]; + } else { + myCol = mapClassification.colours[1]; + } + legendSVG.selectAll("circle").style("fill", myCol); legendSVG.style("height", mySizeLegend.legendHeight()); @@ -1057,8 +869,8 @@ function makeLegend(whichLegend, mapgroup, mapsubject, mapunit, mapdate, mapType legendSVG.style("height", legend.legendHeight()); } else { - setMessage( - ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], errorMsg); + Messages.setMessage( + ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], Messages.errorMsg); } var legendFooter = "<hr><p class='small'>" + geoSourceStr[curLang] + ": " @@ -1112,12 +924,12 @@ function makeStats(attribData, attrib, mapType, mapClassification) { var errorStr = ""; attribData.forEach(function (k, v) { if (mapType == "point_size" || mapType == "area_value") { - myStats.dValues[i] = +eval("v." + attrib); //+ to force numerical + myStats.dValues[i] = + v[attrib]; //+ to force numerical if (myStats.dValues[i] == undefined || isNaN(myStats.dValues[i])) { errorStr = "Maptype=" + mapType + "; data=" + myStats.dValues[i]; } } else { //area_label or area_colour - myStats.dValues[i] = eval("v." + attrib); + myStats.dValues[i] = v[attrib]; if (myStats.dValues[i] == undefined) { errorStr = "Maptype=" + mapType + "; data=" + myStats.dValues[i]; } @@ -1125,8 +937,8 @@ function makeStats(attribData, attrib, mapType, mapClassification) { i++; }); if (errorStr != "") { - setMessage(["ONGELDIGE DATA VOOR DIT MAPTYPE!\n" + errorStr, - "INVALID DATA FOR THIS MAPTYPE!\n" + errorStr], errorMsg); + Messages.setMessage(["ONGELDIGE DATA VOOR DIT MAPTYPE!\n" + errorStr, + "INVALID DATA FOR THIS MAPTYPE!\n" + errorStr], Messages.errorMsg); console.log(myStats.dValues); } @@ -1187,7 +999,7 @@ function makeStats(attribData, attrib, mapType, mapClassification) { } // a classed scale for (choropleth) ordered or relative ratio maps: try { - var CBrange = eval("colorbrewer." + mapClassification.colours + "[" + mapClassification.numclasses + "]"); + var CBrange = colorbrewer[mapClassification.colours][mapClassification.numclasses]; } catch (e) { InvalidClassMessage(clStr + "\n'" + mapClassification.colours + "' is not a valid ColorBrewer name."); } @@ -1210,7 +1022,7 @@ function makeStats(attribData, attrib, mapType, mapClassification) { InvalidClassMessage(clStr + "\nInvalid numclasses (<3 or >24)."); } try { - var CBrange = eval("colorbrewer." + mapClassification.colours + "[" + mapClassification.numclasses + "]"); + var CBrange = colorbrewer[mapClassification.colours][mapClassification.numclasses]; } catch (e) { InvalidClassMessage(clStr + "\n'" + mapClassification.colours + "' not valid ColorBrewer name, or no. of classes not available."); } @@ -1218,18 +1030,18 @@ function makeStats(attribData, attrib, mapType, mapClassification) { .range(CBrange) } else { - setMessage( - ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], errorMsg); + Messages.setMessage( + ["Onbekend Map Type [" + mapType + "]", "Unknown Map Type [" + mapType + "]"], Messages.errorMsg); } - setMessage(["", "Calculated map statistics."], debugMsg); + Messages.setMessage(["", "Calculated map statistics."], Messages.debugMsg); //if (debugOn) console.log(myStats); return myStats; } function InvalidClassMessage(Str) { - setMessage(["ONGELDIGE CLASSIFICATIE!\n" + Str, - "INVALID CLASSIFICATION!\n" + Str], errorMsg); + Messages.setMessage(["ONGELDIGE CLASSIFICATIE!\n" + Str, + "INVALID CLASSIFICATION!\n" + Str], Messages.errorMsg); } diff --git a/js/d3-legend-bjk.js b/js/d3-legend-bjk.js index 24705a3205205ab78e051561b59239ac8ea164a3..8f0ead102a22d96cd48961b1c46287ae8f6fc0a3 100644 --- a/js/d3-legend-bjk.js +++ b/js/d3-legend-bjk.js @@ -1,673 +1,750 @@ -(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'); +(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 + } - //BJK: addition/changed - // legend.legendHeight() returns total height, for SVG height determination - // Barend Köbben b.j.kobben@utwente.nl 10 Aug 2015 + 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'); - module.exports = function(){ + //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); + 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.style("fill", type.feature); + 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) + ")"; + }; } - } else { - shapes.attr("class", function(d){ return "swatch " + type.feature(d); }); - } - var cellTrans, - textTrans, - textAlign = (labelAlign == "start") ? 0 : (labelAlign == "middle") ? 0.5 : 1; + helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); + cell.transition().style("opacity", 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.scale = function(_) { - if (!arguments.length) return legend; - scale = _; - return legend; - }; + legend.shapeWidth = function (_) { + if (!arguments.length) return legend; + shapeWidth = +_; + return legend; + }; - legend.cells = function(_) { - if (!arguments.length) return legend; - if (_.length > 1 || _ >= 2 ){ - cells = _; - } - return legend; - }; + legend.shapeHeight = function (_) { + if (!arguments.length) return legend; + shapeHeight = +_; + 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.shapeRadius = function (_) { + if (!arguments.length) return legend; + shapeRadius = +_; + 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.shapeHeight = function(_) { - if (!arguments.length) return legend; - shapeHeight = +_; - return legend; - }; + legend.labels = function (_) { + if (!arguments.length) return legend; + labels = _; + return legend; + }; - legend.shapeRadius = function(_) { - if (!arguments.length) return legend; - shapeRadius = +_; - return legend; - }; + legend.labelAlign = function (_) { + if (!arguments.length) return legend; + if (_ == "start" || _ == "end" || _ == "middle") { + labelAlign = _; + } + return legend; + }; - legend.shapePadding = function(_) { - if (!arguments.length) return legend; - shapePadding = +_; - return legend; - }; + legend.labelFormat = function (_) { + if (!arguments.length) return legend; + labelFormat = _; + return legend; + }; - legend.labels = function(_) { - if (!arguments.length) return legend; - labels = _; - return legend; - }; + legend.labelOffset = function (_) { + if (!arguments.length) return legend; + labelOffset = +_; + return legend; + }; - legend.labelAlign = function(_) { - if (!arguments.length) return legend; - if (_ == "start" || _ == "end" || _ == "middle") { - labelAlign = _; - } - return legend; - }; + legend.labelDelimiter = function (_) { + if (!arguments.length) return legend; + labelDelimiter = _; + return legend; + }; - legend.labelFormat = function(_) { - if (!arguments.length) return legend; - labelFormat = _; - return legend; - }; + //BJK addition/change: + legend.legendHeight = function () { + return legendHeight; + }; - legend.labelOffset = function(_) { - if (!arguments.length) return legend; - labelOffset = +_; - return legend; - }; + legend.useClass = function (_) { + if (!arguments.length) return legend; + if (_ === true || _ === false) { + useClass = _; + } + 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; + }; - //BJK addition/change: - legend.legendHeight = function() { - return legendHeight; - }; + d3.rebind(legend, legendDispatcher, "on"); - 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; + }, -},{"./legend":2}],2:[function(require,module,exports){ - module.exports = { + d3_mergeLabels: function (gen, labels) { + if (labels.length === 0) return gen; - d3_identity: function (d) { - return d; - }, + gen = (gen) ? gen : []; - 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; - }, + var i = labels.length; + for (; i < gen.length; i++) { + labels.push(gen[i]); + } + return labels; + }, - d3_linearLegend: function (scale, cells, labelFormat) { - var data = []; + d3_linearLegend: function (scale, cells, labelFormat) { + var data = []; - if (cells.length > 1){ - data = cells; + if (cells.length > 1) { + data = cells; - } else { - var domain = scale.domain(), - increment = (domain[domain.length - 1] - domain[0])/(cells - 1), - i = 0; + } 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)); + 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: 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); - return {data: scale.range(), - labels: labels, - feature: this.d3_identity - }; - }, + } else if (shape === "circle") { + shapes.attr("r", shapeRadius)//.attr("cx", shapeRadius).attr("cy", shapeRadius); - d3_ordinalLegend: function (scale) { - return {data: scale.domain(), - labels: scale.domain(), - feature: function(d){ return scale(d); }}; - }, + } else if (shape === "line") { + shapes.attr("x1", 0).attr("x2", shapeWidth).attr("y1", 0).attr("y2", 0); - d3_drawShapes: function (shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) { - if (shape === "rect"){ - shapes.attr("height", shapeHeight).attr("width", shapeWidth); + } else if (shape === "path") { + shapes.attr("d", path); + } + }, - } else if (shape === "circle") { - shapes.attr("r", shapeRadius)//.attr("cx", shapeRadius).attr("cy", shapeRadius); + d3_addText: function (svg, enter, labels) { + enter.append("text").attr("class", "label"); + svg.selectAll("g.cell text").data(labels).text(this.d3_identity); + }, - } else if (shape === "line") { - shapes.attr("x1", 0).attr("x2", shapeWidth).attr("y1", 0).attr("y2", 0); + 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); - } else if (shape === "path") { - shapes.attr("d", path); - } - }, + type.labels = this.d3_mergeLabels(type.labels, labels); - d3_addText: function (svg, enter, labels){ - enter.append("text").attr("class", "label"); - svg.selectAll("g.cell text").data(labels).text(this.d3_identity); - }, + return type; + }, - 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); + 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); + }); + }, - type.labels = this.d3_mergeLabels(type.labels, labels); + d3_cellOver: function (cellDispatcher, d, obj) { + cellDispatcher.cellover.call(obj, d); + }, - return type; - }, + d3_cellOut: function (cellDispatcher, d, obj) { + cellDispatcher.cellout.call(obj, d); + }, - 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_cellClick: function (cellDispatcher, d, obj) { + cellDispatcher.cellclick.call(obj, d); } - }, - 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'); + }, {}], 3: [function (require, module, exports) { + var helper = require('./legend'); - module.exports = function(){ + 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; - } + 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); + } - return bbox; + 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 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"){ + 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 ) + ")"; + }; + } - 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) + ")"; }; + helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); + cell.transition().style("opacity", 1); - 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)"; }; + legend.scale = function (_) { + if (!arguments.length) return legend; + scale = _; + return legend; + }; - textTrans = function(d,i) { return "translate(" + (shapeSize[i].width*textAlign + shapeSize[i].x) + "," + - (maxH + labelOffset ) + ")"; }; - } + legend.cells = function (_) { + if (!arguments.length) return legend; + if (_.length > 1 || _ >= 2) { + cells = _; + } + return legend; + }; - helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); - cell.transition().style("opacity", 1); - } + legend.shape = function (_, d) { + if (!arguments.length) return legend; + if (_ == "rect" || _ == "circle" || _ == "line") { + shape = _; + path = d; + } + return legend; + }; - legend.scale = function(_) { - if (!arguments.length) return legend; - scale = _; - return legend; - }; + legend.shapeWidth = function (_) { + if (!arguments.length) return legend; + shapeWidth = +_; + 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.shape = function(_, d) { - if (!arguments.length) return legend; - if (_ == "rect" || _ == "circle" || _ == "line" ){ - shape = _; - path = d; - } - return legend; - }; + legend.labelAlign = function (_) { + if (!arguments.length) return legend; + if (_ == "start" || _ == "end" || _ == "middle") { + labelAlign = _; + } + return legend; + }; - legend.shapeWidth = function(_) { - if (!arguments.length) return legend; - shapeWidth = +_; - return legend; - }; + legend.labelFormat = function (_) { + if (!arguments.length) return legend; + labelFormat = _; + return legend; + }; - legend.shapePadding = function(_) { - if (!arguments.length) return legend; - shapePadding = +_; - return legend; - }; + legend.labelOffset = function (_) { + if (!arguments.length) return legend; + labelOffset = +_; + return legend; + }; - legend.labels = function(_) { - if (!arguments.length) return legend; - labels = _; - return legend; - }; + legend.labelDelimiter = function (_) { + if (!arguments.length) return legend; + labelDelimiter = _; + return legend; + }; - legend.labelAlign = function(_) { - if (!arguments.length) return legend; - if (_ == "start" || _ == "end" || _ == "middle") { - labelAlign = _; - } - return legend; - }; + //BJK addition/change: + legend.legendHeight = function () { + return legendHeight; + }; - legend.labelFormat = function(_) { - if (!arguments.length) return legend; - labelFormat = _; - return legend; - }; + legend.orient = function (_) { + if (!arguments.length) return legend; + _ = _.toLowerCase(); + if (_ == "horizontal" || _ == "vertical") { + orient = _; + } + return legend; + }; - legend.labelOffset = function(_) { - if (!arguments.length) return legend; - labelOffset = +_; - return legend; - }; + d3.rebind(legend, legendDispatcher, "on"); - 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"); + }, {"./legend": 2}], 4: [function (require, module, exports) { + var helper = require('./legend'); - return 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; + }); -},{"./legend":2}],4:[function(require,module,exports){ - var helper = require('./legend'); + 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 ) + ")"; + }; + } -//*** legend.symbol ***// -// alert("symbol"); + helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); + cell.transition().style("opacity", 1); - 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.scale = function(_) { - if (!arguments.length) return legend; - scale = _; - return legend; - }; + legend.shapePadding = function (_) { + if (!arguments.length) return legend; + shapePadding = +_; + return legend; + }; - legend.cells = function(_) { - if (!arguments.length) return legend; - if (_.length > 1 || _ >= 2 ){ - cells = _; - } - return legend; - }; + legend.labels = function (_) { + if (!arguments.length) return legend; + labels = _; + return legend; + }; - legend.shapePadding = function(_) { - if (!arguments.length) return legend; - shapePadding = +_; - return legend; - }; + legend.labelAlign = function (_) { + if (!arguments.length) return legend; + if (_ == "start" || _ == "end" || _ == "middle") { + labelAlign = _; + } + return legend; + }; - legend.labels = function(_) { - if (!arguments.length) return legend; - labels = _; - return legend; - }; + legend.labelFormat = function (_) { + if (!arguments.length) return legend; + labelFormat = _; + return legend; + }; - legend.labelAlign = function(_) { - if (!arguments.length) return legend; - if (_ == "start" || _ == "end" || _ == "middle") { - labelAlign = _; - } - return legend; - }; + legend.labelOffset = function (_) { + if (!arguments.length) return legend; + labelOffset = +_; + return legend; + }; - legend.labelFormat = function(_) { - if (!arguments.length) return legend; - labelFormat = _; - return legend; - }; + legend.labelDelimiter = function (_) { + if (!arguments.length) return legend; + labelDelimiter = _; + return legend; + }; - legend.labelOffset = function(_) { - if (!arguments.length) return legend; - labelOffset = +_; - return legend; - }; + legend.orient = function (_) { + if (!arguments.length) return legend; + _ = _.toLowerCase(); + if (_ == "horizontal" || _ == "vertical") { + orient = _; + } + return legend; + }; - legend.labelDelimiter = function(_) { - if (!arguments.length) return legend; - labelDelimiter = _; - return legend; - }; + d3.rebind(legend, legendDispatcher, "on"); - 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]); + }, {"./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]);