Repository: timwis/leaflet-choropleth Branch: gh-pages Commit: ab29390684b5 Files: 19 Total size: 846.1 KB Directory structure: gitextract_lhsux0s0/ ├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── bower.json ├── dist/ │ └── choropleth.js ├── examples/ │ ├── basic/ │ │ ├── crimes_by_district.geojson │ │ ├── demo.js │ │ └── index.html │ ├── computed_values/ │ │ ├── demo.js │ │ └── index.html │ ├── fetch_join/ │ │ ├── demo.js │ │ └── index.html │ └── legend/ │ ├── demo.js │ └── index.html ├── package.json ├── src/ │ └── choropleth.js ├── test/ │ └── choropleth.test.js └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ node_modules *.swp ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - "4.0" branches: only: - gh-pages ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) Copyright (c) 2015 Tim Wisniewski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Leaflet Choropleth [](https://travis-ci.org/timwis/leaflet-choropleth) [](http://standardjs.com/) [](https://nodei.co/npm/leaflet-choropleth/) Choropleth plugin for Leaflet (color scale based on value) - [Demo](http://timwis.com/leaflet-choropleth/examples/basic) [](http://timwis.com/leaflet-choropleth/examples/basic) This plugin extends `L.geoJson`, giving each feature a `style.fillColor` that corresponds to a specified value in its `properties` object. For information on how to use `L.geoJson`, see the Leaflet [tutorial](http://leafletjs.com/examples/geojson.html) and [documentation](http://leafletjs.com/reference.html#geojson). While Leaflet provides a [choropleth tutorial](http://leafletjs.com/examples/choropleth.html), that approach requires you to specify exact breakpoints and colors. This plugin uses [chroma.js](http://gka.github.io/chroma.js/) to abstract that for you. Just tell it which property in the GeoJSON to use and some idea of the color scale you want. ## Usage ```javascript L.choropleth(geojsonData, { valueProperty: 'incidents', // which property in the features to use scale: ['white', 'red'], // chroma.js scale - include as many as you like steps: 5, // number of breaks or steps in range mode: 'q', // q for quantile, e for equidistant, k for k-means style: { color: '#fff', // border color weight: 2, fillOpacity: 0.8 }, onEachFeature: function(feature, layer) { layer.bindPopup(feature.properties.value) } }).addTo(map) ``` ### Advanced * **colors**: If you prefer to specify your own exact colors, use `colors: ['#fff', '#777', ...]` instead of `scale`. Just make sure the number of colors is the same as the number of `steps` specified. * **valueProperty**: To use computed values (such as [standardizing](http://axismaps.github.io/thematic-cartography/articles/standardize.html)), you can use a function for `valueProperty` that is passed `(feature)` and returns a number ([example](examples/computed_values/demo.js)). ## Installation * via NPM: `npm install leaflet-choropleth` * via Bower: `bower install leaflet-choropleth` Include `dist/choropleth.js` from this repository on your page after Leaflet: ```html ``` Or, if using via CommonJS (Browserify, Webpack, etc.): ```javascript var L = require('leaflet') require('leaflet-choropleth') ``` ## Examples * [Basic usage](examples/basic/demo.js) * [Legend](examples/legend/demo.js) * [Fetch & join](examples/fetch_join/demo.js) * [Computed values](examples/computed_values/demo.js) ## Development This project uses [webpack](http://webpack.github.io/) to build the JavaScript and [standard](https://github.com/feross/standard) for code style linting. * While developing, use `npm run watch` to automatically rebuild when files are saved * Use `npm test` to run unit tests and code style linter * Before committing `dist/`, use `npm run build` to optimize and minify for production use ================================================ FILE: bower.json ================================================ { "name": "leaflet-choropleth", "version": "1.1.2", "homepage": "https://github.com/timwis/leaflet-choropleth", "authors": [ "timwis " ], "description": "Choropleth plugin for Leaflet (color scale based on value)", "main": "dist/choropleth.js", "keywords": [ "leaflet", "choropleth", "chloropleth" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ] } ================================================ FILE: dist/choropleth.js ================================================ !function(n){function r(e){if(t[e])return t[e].exports;var o=t[e]={exports:{},id:e,loaded:!1};return n[e].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}var t={};return r.m=n,r.c=t,r.p="",r(0)}([function(n,r,t){var e=t(111),o=t(51),u=t(85);e.choropleth=n.exports=function(n,r){r=r||{},u.defaults(r,{valueProperty:"value",scale:["white","red"],steps:5,mode:"q"});var t=r.style,f=n.features.map("function"==typeof r.valueProperty?r.valueProperty:function(n){return n.properties[r.valueProperty]}),a=o.limits(f,r.mode,r.steps-1),c=r.colors&&r.colors.length===a.length?r.colors:o.scale(r.scale).colors(a.length);return e.geoJson(n,u.extend(r,{limits:a,colors:c,style:function(n){var e,o={};if(e="function"==typeof r.valueProperty?r.valueProperty(n):n.properties[r.valueProperty],!isNaN(e))for(var f=0;f0;++e-1&&n%1==0&&n<=e}var e=9007199254740991;n.exports=t},function(n,r,t){function e(n){if(u(n))return n;var r=[];return o(n).replace(f,function(n,t,e,o){r.push(e?o.replace(a,"$1"):t||n)}),r}var o=t(70),u=t(2),f=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,a=/\\(\\)?/g;n.exports=e},function(n,r,t){function e(n){return u(n)&&o(n)&&a.call(n,"callee")&&!c.call(n,"callee")}var o=t(8),u=t(4),f=Object.prototype,a=f.hasOwnProperty,c=f.propertyIsEnumerable;n.exports=e},function(n,r,t){function e(n,r,t){if(null!=n){void 0!==t&&t in o(n)&&(r=[t]);for(var e=0,u=r.length;null!=n&&e-1&&n%1==0&&no?0:o+r),t=void 0===t||t>o?o:+t||0,t<0&&(t+=o),o=r>t?0:t-r>>>0,r>>>=0;for(var u=Array(o);++e2?t[f-2]:void 0,c=f>2?t[2]:void 0,i=f>1?t[f-1]:void 0;for("function"==typeof a?(a=o(a,i,5),f-=2):(a="function"==typeof i?i:void 0,f-=a?1:0),c&&u(t[0],t[1],c)&&(a=f<3?void 0:a,f=1);++et&&(n=t),n},An=function(n){return n.length>=3?[].slice.call(n):n[0]},j=function(n){var r,t;for(n._clipped=!1,n._unclipped=n.slice(0),r=t=0;t<3;r=++t)r<3?((n[r]<0||n[r]>255)&&(n._clipped=!0),n[r]<0&&(n[r]=0),n[r]>255&&(n[r]=255)):3===r&&(n[r]<0&&(n[r]=0),n[r]>1&&(n[r]=1));return n._clipped||delete n._unclipped,n},a=Math.PI,wn=Math.round,N=Math.cos,E=Math.floor,on=Math.pow,T=Math.log,jn=Math.sin,_n=Math.sqrt,v=Math.atan2,Q=Math.max,b=Math.abs,l=2*a,c=a/3,u=a/180,i=180/a,k=function(){return arguments[0]instanceof t?arguments[0]:function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,arguments,function(){})},h=[],"undefined"!=typeof n&&null!==n&&null!=n.exports&&(n.exports=k),e=[],o=function(){return k}.apply(r,e),!(void 0!==o&&(n.exports=o)),k.version="1.3.4",d={},s=[],p=!1,t=function(){function n(){var n,r,t,e,o,u,f,a,c;for(u=this,r=[],a=0,e=arguments.length;a3?r[3]:1]},Sn=function(n){return 255*(n<=.00304?12.92*n:1.055*on(n,1/2.4)-.055)},V=function(n){return n>f.t1?n*n*n:f.t2*(n-f.t0)},f={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},dn=function(){var n,r,t,e,o,u,f,a;return e=An(arguments),t=e[0],r=e[1],n=e[2],o=yn(t,r,n),u=o[0],f=o[1],a=o[2],[116*f-16,500*(u-f),200*(f-a)]},mn=function(n){return(n/=255)<=.04045?n/12.92:on((n+.055)/1.055,2.4)},Pn=function(n){return n>f.t3?on(n,1/3):n/f.t2+f.t0},yn=function(){var n,r,t,e,o,u,a;return e=An(arguments),t=e[0],r=e[1],n=e[2],t=mn(t),r=mn(r),n=mn(n),o=Pn((.4124564*t+.3575761*r+.1804375*n)/f.Xn),u=Pn((.2126729*t+.7151522*r+.072175*n)/f.Yn),a=Pn((.0193339*t+.119192*r+.9503041*n)/f.Zn),[o,u,a]},k.lab=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["lab"]),function(){})},d.lab=K,t.prototype.lab=function(){return dn(this._rgb)},g=function(n){var r,t,e,o,u,f,a,c,i,l,s;return n=function(){var r,t,e;for(e=[],t=0,r=n.length;t=360;)t-=360;h[l]=t}return k(h,r).alpha(e/s)},d.rgb=function(){var n,r,t,e;r=An(arguments),t=[];for(n in r)e=r[n],t.push(e);return t},k.rgb=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["rgb"]),function(){})},t.prototype.rgb=function(n){return null==n&&(n=!0),n?this._rgb.map(Math.round).slice(0,3):this._rgb.slice(0,3)},t.prototype.rgba=function(n){return null==n&&(n=!0),n?[Math.round(this._rgb[0]),Math.round(this._rgb[1]),Math.round(this._rgb[2]),this._rgb[3]]:this._rgb.slice(0)},s.push({p:3,test:function(n){var r;return r=An(arguments),"array"===Nn(r)&&3===r.length?"rgb":4===r.length&&"number"===Nn(r[3])&&r[3]>=0&&r[3]<=1?"rgb":void 0}}),L=function(n){var r,t,e,o,u,f;if(n.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/))return 4!==n.length&&7!==n.length||(n=n.substr(1)),3===n.length&&(n=n.split(""),n=n[0]+n[0]+n[1]+n[1]+n[2]+n[2]),f=parseInt(n,16),o=f>>16,e=f>>8&255,t=255&f,[o,e,t,1];if(n.match(/^#?([A-Fa-f0-9]{8})$/))return 9===n.length&&(n=n.substr(1)),f=parseInt(n,16),o=f>>24&255,e=f>>16&255,t=f>>8&255,r=wn((255&f)/255*100)/100,[o,e,t,r];if(null!=d.css&&(u=d.css(n)))return u;throw"unknown color: "+n},cn=function(n,r){var t,e,o,u,f,a,c;return null==r&&(r="rgb"),f=n[0],o=n[1],e=n[2],t=n[3],f=Math.round(f),o=Math.round(o),e=Math.round(e),c=f<<16|o<<8|e,a="000000"+c.toString(16),a=a.substr(a.length-6),u="0"+wn(255*t).toString(16),u=u.substr(u.length-2),"#"+function(){switch(r.toLowerCase()){case"rgba":return a+u;case"argb":return u+a;default:return a}}()},d.hex=function(n){return L(n)},k.hex=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["hex"]),function(){})},t.prototype.hex=function(n){return null==n&&(n="rgb"),cn(this._rgb,n)},s.push({p:4,test:function(n){if(1===arguments.length&&"string"===Nn(n))return"hex"}}),G=function(){var n,r,t,e,o,u,f,a,c,i,l,s,p,d;if(n=An(arguments),o=n[0],l=n[1],f=n[2],0===l)c=e=r=255*f;else{for(d=[0,0,0],t=[0,0,0],p=f<.5?f*(1+l):f+l-f*l,s=2*f-p,o/=360,d[0]=o+1/3,d[1]=o,d[2]=o-1/3,u=a=0;a<=2;u=++a)d[u]<0&&(d[u]+=1),d[u]>1&&(d[u]-=1),6*d[u]<1?t[u]=s+6*(p-s)*d[u]:2*d[u]<1?t[u]=p:3*d[u]<2?t[u]=s+(p-s)*(2/3-d[u])*6:t[u]=s;i=[wn(255*t[0]),wn(255*t[1]),wn(255*t[2])],c=i[0],e=i[1],r=i[2]}return n.length>3?[c,e,r,n[3]]:[c,e,r]},sn=function(n,r,t){var e,o,u,f,a;return void 0!==n&&n.length>=3&&(f=n,n=f[0],r=f[1],t=f[2]),n/=255,r/=255,t/=255,u=Math.min(n,r,t),Q=Math.max(n,r,t),o=(Q+u)/2,Q===u?(a=0,e=Number.NaN):a=o<.5?(Q-u)/(Q+u):(Q-u)/(2-Q-u),n===Q?e=(r-t)/(Q-u):r===Q?e=2+(t-n)/(Q-u):t===Q&&(e=4+(n-r)/(Q-u)),e*=60,e<0&&(e+=360),[e,a,o]},k.hsl=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["hsl"]),function(){})},d.hsl=G,t.prototype.hsl=function(){return sn(this._rgb)},I=function(){var n,r,t,e,o,u,f,a,c,i,l,s,p,d,h,b,v,g;if(n=An(arguments),o=n[0],b=n[1],g=n[2],g*=255,0===b)c=e=r=g;else switch(360===o&&(o=0),o>360&&(o-=360),o<0&&(o+=360),o/=60,u=E(o),t=o-u,f=g*(1-b),a=g*(1-b*t),v=g*(1-b*(1-t)),u){case 0:i=[g,v,f],c=i[0],e=i[1],r=i[2];break;case 1:l=[a,g,f],c=l[0],e=l[1],r=l[2];break;case 2:s=[f,g,v],c=s[0],e=s[1],r=s[2];break;case 3:p=[f,a,g],c=p[0],e=p[1],r=p[2];break;case 4:d=[v,f,g],c=d[0],e=d[1],r=d[2];break;case 5:h=[g,f,a],c=h[0],e=h[1],r=h[2]}return[c,e,r,n.length>3?n[3]:1]},pn=function(){var n,r,t,e,o,u,f,a,c;return f=An(arguments),u=f[0],t=f[1],n=f[2],o=Math.min(u,t,n),Q=Math.max(u,t,n),r=Q-o,c=Q/255,0===Q?(e=Number.NaN,a=0):(a=r/Q,u===Q&&(e=(t-n)/r),t===Q&&(e=2+(n-u)/r),n===Q&&(e=4+(u-t)/r),e*=60,e<0&&(e+=360)),[e,a,c]},k.hsv=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["hsv"]),function(){})},d.hsv=I,t.prototype.hsv=function(){return pn(this._rgb)},tn=function(n){var r,t,e;return"number"===Nn(n)&&n>=0&&n<=16777215?(e=n>>16,t=n>>8&255,r=255&n,[e,t,r,1]):(console.warn("unknown num color: "+n),[0,0,0,1])},vn=function(){var n,r,t,e;return e=An(arguments),t=e[0],r=e[1],n=e[2],(t<<16)+(r<<8)+n},k.num=function(n){return new t(n,"num")},t.prototype.num=function(n){return null==n&&(n="rgb"),vn(this._rgb,n)},d.num=tn,s.push({p:1,test:function(n){if(1===arguments.length&&"number"===Nn(n)&&n>=0&&n<=16777215)return"num"}}),B=function(){var n,r,t,e,o,u,f,a,c,i,l,s,p,d,h,b,v,g,y,m;if(t=An(arguments),a=t[0],o=t[1],r=t[2],o/=100,f=f/100*255,n=255*o,0===o)s=f=e=r;else switch(360===a&&(a=0),a>360&&(a-=360),a<0&&(a+=360),a/=60,c=E(a),u=a-c,i=r*(1-o),l=i+n*(1-u),y=i+n*u,m=i+n,c){case 0:p=[m,y,i],s=p[0],f=p[1],e=p[2];break;case 1:d=[l,m,i],s=d[0],f=d[1],e=d[2];break;case 2:h=[i,m,y],s=h[0],f=h[1],e=h[2];break;case 3:b=[i,l,m],s=b[0],f=b[1],e=b[2];break;case 4:v=[y,i,m],s=v[0],f=v[1],e=v[2];break;case 5:g=[m,i,l],s=g[0],f=g[1],e=g[2]}return[s,f,e,t.length>3?t[3]:1]},an=function(){var n,r,t,e,o,u,f,a,c;return c=An(arguments),a=c[0],o=c[1],r=c[2],f=Math.min(a,o,r),Q=Math.max(a,o,r),e=Q-f,t=100*e/255,n=f/(255-e)*100,0===e?u=Number.NaN:(a===Q&&(u=(o-r)/e),o===Q&&(u=2+(r-a)/e),r===Q&&(u=4+(a-o)/e),u*=60,u<0&&(u+=360)),[u,t,n]},k.hcg=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["hcg"]),function(){})},d.hcg=B,t.prototype.hcg=function(){return an(this._rgb)},A=function(n){var r,t,e,o,u,f,a,c;if(n=n.toLowerCase(),null!=k.colors&&k.colors[n])return L(k.colors[n]);if(u=n.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)){for(a=u.slice(1,4),o=f=0;f<=2;o=++f)a[o]=+a[o];a[3]=1}else if(u=n.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/))for(a=u.slice(1,5),o=c=0;c<=3;o=++c)a[o]=+a[o];else if(u=n.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)){for(a=u.slice(1,4),o=r=0;r<=2;o=++r)a[o]=wn(2.55*a[o]);a[3]=1}else if(u=n.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)){for(a=u.slice(1,5),o=t=0;t<=2;o=++t)a[o]=wn(2.55*a[o]);a[3]=+a[3]}else(u=n.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/))?(e=u.slice(1,4),e[1]*=.01,e[2]*=.01,a=G(e),a[3]=1):(u=n.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/))&&(e=u.slice(1,4),e[1]*=.01,e[2]*=.01,a=G(e),a[3]=+u[4]);return a},fn=function(n){var r;return r=n[3]<1?"rgba":"rgb","rgb"===r?r+"("+n.slice(0,3).map(wn).join(",")+")":"rgba"===r?r+"("+n.slice(0,3).map(wn).join(",")+","+n[3]+")":void 0},xn=function(n){return wn(100*n)/100},q=function(n,r){var t;return t=r<1?"hsla":"hsl",n[0]=xn(n[0]||0),n[1]=xn(100*n[1])+"%",n[2]=xn(100*n[2])+"%","hsla"===t&&(n[3]=r),t+"("+n.join(",")+")"},d.css=function(n){return A(n)},k.css=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["css"]),function(){})},t.prototype.css=function(n){return null==n&&(n="rgb"),"rgb"===n.slice(0,3)?fn(this._rgb):"hsl"===n.slice(0,3)?q(this.hsl(),this.alpha()):void 0},d.named=function(n){return L(Mn[n])},s.push({p:5,test:function(n){if(1===arguments.length&&null!=Mn[n])return"named"}}),t.prototype.name=function(n){var r,t;arguments.length&&(Mn[n]&&(this._rgb=L(Mn[n])),this._rgb[3]=1),r=this.hex();for(t in Mn)if(r===Mn[t])return t;return r},z=function(){var n,r,t,e;return e=An(arguments),t=e[0],n=e[1],r=e[2],r*=u,[t,N(r)*n,jn(r)*n]},D=function(){var n,r,t,e,o,u,f,a,c,i,l;return t=An(arguments),a=t[0],o=t[1],f=t[2],i=z(a,o,f),n=i[0],r=i[1],e=i[2],l=K(n,r,e),c=l[0],u=l[1],e=l[2],[c,u,e,t.length>3?t[3]:1]},X=function(){var n,r,t,e,o,u;return u=An(arguments),o=u[0],n=u[1],r=u[2],t=_n(n*n+r*r),e=(v(r,n)*i+360)%360,0===wn(1e4*t)&&(e=Number.NaN),[o,t,e]},hn=function(){var n,r,t,e,o,u,f;return u=An(arguments),o=u[0],t=u[1],r=u[2],f=dn(o,t,r),e=f[0],n=f[1],r=f[2],X(e,n,r)},k.lch=function(){var n;return n=An(arguments),new t(n,"lch")},k.hcl=function(){var n;return n=An(arguments),new t(n,"hcl")},d.lch=D,d.hcl=function(){var n,r,t,e;return e=An(arguments),r=e[0],n=e[1],t=e[2],D([t,n,r])},t.prototype.lch=function(){return hn(this._rgb)},t.prototype.hcl=function(){return hn(this._rgb).reverse()},un=function(n){var r,t,e,o,u,f,a,c,i;return null==n&&(n="rgb"),c=An(arguments),a=c[0],o=c[1],r=c[2],a/=255,o/=255,r/=255,u=1-Math.max(a,Math.max(o,r)),e=u<1?1/(1-u):0,t=(1-a-u)*e,f=(1-o-u)*e,i=(1-r-u)*e,[t,f,i,u]},_=function(){var n,r,t,e,o,u,f,a,c;return r=An(arguments),e=r[0],f=r[1],c=r[2],u=r[3],n=r.length>4?r[4]:1,1===u?[0,0,0,n]:(a=e>=1?0:255*(1-e)*(1-u),o=f>=1?0:255*(1-f)*(1-u),t=c>=1?0:255*(1-c)*(1-u),[a,o,t,n])},d.cmyk=function(){return _(An(arguments))},k.cmyk=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["cmyk"]),function(){})},t.prototype.cmyk=function(){return un(this._rgb)},d.gl=function(){var n,r,t,e,o;for(e=function(){var n,t;n=An(arguments),t=[];for(r in n)o=n[r],t.push(o);return t}.apply(this,arguments),n=t=0;t<=2;n=++t)e[n]*=255;return e},k.gl=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["gl"]),function(){})},t.prototype.gl=function(){var n;return n=this._rgb,[n[0]/255,n[1]/255,n[2]/255,n[3]]},bn=function(n,r,t){var e;return e=An(arguments),n=e[0],r=e[1],t=e[2],n=W(n),r=W(r),t=W(t),.2126*n+.7152*r+.0722*t},W=function(n){return n/=255,n<=.03928?n/12.92:on((n+.055)/1.055,2.4)},h=[],U=function(n,r,t,e){var o,u,f,a;for(null==t&&(t=.5),null==e&&(e="rgb"),"object"!==Nn(n)&&(n=k(n)),"object"!==Nn(r)&&(r=k(r)),f=0,u=h.length;fn?u(t,c):u(c,f)},t=bn(this._rgb),this._rgb=(t>n?u(k("black"),this):u(this,k("white"))).rgba()),this):bn(this._rgb)},On=function(n){var r,t,e,o;return o=n/100,o<66?(e=255,t=-155.25485562709179-.44596950469579133*(t=o-2)+104.49216199393888*T(t),r=o<20?0:-254.76935184120902+.8274096064007395*(r=o-10)+115.67994401066147*T(r)):(e=351.97690566805693+.114206453784165*(e=o-55)-40.25366309332127*T(e),t=325.4494125711974+.07943456536662342*(t=o-50)-28.0852963507957*T(t),r=255),[e,t,r]},gn=function(){var n,r,t,e,o,u,f,a,c;for(f=An(arguments),u=f[0],t=f[1],n=f[2],o=1e3,e=4e4,r=.4;e-o>r;)c=.5*(e+o),a=On(c),a[2]/a[0]>=n/u?e=c:o=c;return wn(c)},k.temperature=k.kelvin=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["temperature"]),function(){})},d.temperature=d.kelvin=d.K=On,t.prototype.temperature=function(){return gn(this._rgb)},t.prototype.kelvin=t.prototype.temperature,k.contrast=function(n,r){var e,o,u,f;return"string"!==(u=Nn(n))&&"number"!==u||(n=new t(n)),"string"!==(f=Nn(r))&&"number"!==f||(r=new t(r)),e=n.luminance(),o=r.luminance(),e>o?(e+.05)/(o+.05):(o+.05)/(e+.05)},k.distance=function(n,r,e){var o,u,f,a,c,i,l;null==e&&(e="lab"),"string"!==(c=Nn(n))&&"number"!==c||(n=new t(n)),"string"!==(i=Nn(r))&&"number"!==i||(r=new t(r)),f=n.get(e),a=r.get(e),l=0;for(u in f)o=(f[u]||0)-(a[u]||0),l+=o*o;return Math.sqrt(l)},k.deltaE=function(n,r,e,o){var u,f,c,i,l,s,p,d,h,g,y,m,x,w,k,j,_,O,A,M,P,S,E,B,L,R,q;for(null==e&&(e=1),null==o&&(o=1),"string"!==(_=Nn(n))&&"number"!==_||(n=new t(n)),"string"!==(O=Nn(r))&&"number"!==O||(r=new t(r)),A=n.lab(),u=A[0],c=A[1],l=A[2],M=r.lab(),f=M[0],i=M[1],s=M[2],p=_n(c*c+l*l),d=_n(i*i+s*s),E=u<16?.511:.040975*u/(1+.01765*u),P=.0638*p/(1+.0131*p)+.638,j=p<1e-6?0:180*v(l,c)/a;j<0;)j+=360;for(;j>=360;)j-=360;return B=j>=164&&j<=345?.56+b(.2*N(a*(j+168)/180)):.36+b(.4*N(a*(j+35)/180)),h=p*p*p*p,k=_n(h/(h+1900)),S=P*(k*B+1-k),w=u-f,x=p-d,y=c-i,m=l-s,g=y*y+m*m-x*x,L=w/(e*E),R=x/(o*P),q=S,_n(L*L+R*R+g/(q*q))},t.prototype.get=function(n){var r,t,e,o,u,f;return e=this,u=n.split("."),o=u[0],r=u[1],f=e[o](),r?(t=o.indexOf(r),t>-1?f[t]:console.warn("unknown channel "+r+" in mode "+o)):f},t.prototype.set=function(n,r){var t,e,o,u,f,a;if(o=this,f=n.split("."),u=f[0],t=f[1],t)if(a=o[u](),e=u.indexOf(t),e>-1)if("string"===Nn(r))switch(r.charAt(0)){case"+":a[e]+=+r;break;case"-":a[e]+=+r;break;case"*":a[e]*=+r.substr(1);break;case"/":a[e]/=+r.substr(1);break;default:a[e]=+r}else a[e]=r;else console.warn("unknown channel "+t+" in mode "+u);else a=r;return k(a,u).alpha(o.alpha())},t.prototype.clipped=function(){return this._rgb._clipped||!1},t.prototype.alpha=function(n){return arguments.length?k.rgb([this._rgb[0],this._rgb[1],this._rgb[2],n]):this._rgb[3]},t.prototype.darken=function(n){var r,t;return null==n&&(n=1),t=this,r=t.lab(),r[0]-=f.Kn*n,k.lab(r).alpha(t.alpha())},t.prototype.brighten=function(n){return null==n&&(n=1),this.darken(-n)},t.prototype.darker=t.prototype.darken,t.prototype.brighter=t.prototype.brighten,t.prototype.saturate=function(n){var r,t;return null==n&&(n=1),t=this,r=t.lch(),r[1]+=n*f.Kn,r[1]<0&&(r[1]=0),k.lch(r).alpha(t.alpha())},t.prototype.desaturate=function(n){return null==n&&(n=1),this.saturate(-n)},t.prototype.premultiply=function(){var n,r;return r=this.rgb(),n=this.alpha(),k(r[0]*n,r[1]*n,r[2]*n,n)},y=function(n,r,t){if(!y[t])throw"unknown blend mode "+t;return y[t](n,r)},m=function(n){return function(r,t){var e,o;return e=k(t).rgb(),o=k(r).rgb(),k(n(e,o),"rgb")}},S=function(n){return function(r,t){var e,o,u;for(u=[],e=o=0;o<=3;e=++o)u[e]=n(r[e],t[e]);return u}},rn=function(n,r){return n},nn=function(n,r){return n*r/255},M=function(n,r){return n>r?r:n},Z=function(n,r){return n>r?n:r},kn=function(n,r){return 255*(1-(1-n/255)*(1-r/255))},en=function(n,r){return r<128?2*n*r/255:255*(1-2*(1-n/255)*(1-r/255))},w=function(n,r){return 255*(1-(1-r/255)/(n/255))},P=function(n,r){return 255===n?255:(n=255*(r/255)/(1-n/255),n>255?255:n)},y.normal=m(S(rn)),y.multiply=m(S(nn)),y.screen=m(S(kn)),y.overlay=m(S(en)),y.darken=m(S(M)),y.lighten=m(S(Z)),y.dodge=m(S(P)),y.burn=m(S(w)),k.blend=y,k.analyze=function(n){var r,t,e,o;for(e={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},t=0,r=n.length;te.max&&(e.max=o),e.count+=1);return e.domain=[e.min,e.max],e.limits=function(n,r){return k.limits(e,n,r)},e},k.scale=function(n,r){var t,e,o,u,f,a,c,i,l,s,p,d,h,b,v,g,y,m,x,w,j,_;return l="rgb",s=k("#ccc"),b=0,a=!1,f=[0,1],h=[],d=[0,0],t=!1,o=[],p=!1,i=0,c=1,u=!1,e={},v=!0,j=function(n){var r,t,e,u,f,a;if(null==n&&(n=["#fff","#000"]),null!=n&&"string"===Nn(n)&&null!=k.brewer&&(n=k.brewer[n]||k.brewer[n.toLowerCase()]||n),"array"===Nn(n)){for(n=n.slice(0),r=e=0,u=n.length-1;0<=u?e<=u:e>=u;r=0<=u?++e:--e)t=n[r],"string"===Nn(t)&&(n[r]=k(t));for(h.length=0,r=a=0,f=n.length-1;0<=f?a<=f:a>=f;r=0<=f?++a:--a)h.push(r/(n.length-1))}return w(),o=n},m=function(n){var r,e;if(null!=t){for(e=t.length-1,r=0;r=t[r];)r++;return r-1}return 0},_=function(n){return n},g=function(n){var r,e,o,u,f;return f=n,t.length>2&&(u=t.length-1,r=m(n),o=t[0]+(t[1]-t[0])*(0+.5*b),e=t[u-1]+(t[u]-t[u-1])*(1-.5*b),f=i+(t[r]+.5*(t[r+1]-t[r])-o)/(e-o)*(c-i)),f},x=function(n,r){var u,f,a,p,b,g,y,x;if(null==r&&(r=!1),isNaN(n))return s;if(r?x=n:t&&t.length>2?(u=m(n),x=u/(t.length-2),x=d[0]+x*(1-d[0]-d[1])):c!==i?(x=(n-i)/(c-i),x=d[0]+x*(1-d[0]-d[1]),x=Math.min(1,Math.max(0,x))):x=1,r||(x=_(x)),p=Math.floor(1e4*x),v&&e[p])f=e[p];else{if("array"===Nn(o))for(a=b=0,y=h.length-1;0<=y?b<=y:b>=y;a=0<=y?++b:--b){if(g=h[a],x<=g){f=o[a];break}if(x>=g&&a===h.length-1){f=o[a];break}if(x>g&&x=l;r=0<=l?++s:--s)h.push(r/(e-1));return f=[i,c],y},y.mode=function(n){return arguments.length?(l=n,w(),y):l},y.range=function(n,r){return j(n,r),y},y.out=function(n){return p=n,y},y.spread=function(n){return arguments.length?(b=n,y):b},y.correctLightness=function(n){return null==n&&(n=!0),u=n,w(),_=u?function(n){var r,t,e,o,u,f,a,c,i;for(r=x(0,!0).lab()[0],t=x(1,!0).lab()[0],a=r>t,e=x(n,!0).lab()[0],u=r+(t-r)*n,o=e-u,c=0,i=1,f=20;Math.abs(o)>.01&&f-- >0;)!function(){return a&&(o*=-1),o<0?(c=n,n+=.5*(i-n)):(i=n,n+=.5*(c-n)),e=x(n,!0).lab()[0],o=e-u}();return n}:function(n){return n},y},y.padding=function(n){return null!=n?("number"===Nn(n)&&(n=[n,n]),d=n,y):d},y.colors=function(r,e){var u,a,c,i,l,s,p,d;if(arguments.length<2&&(e="hex"),l=[],0===arguments.length)l=o.slice(0);else if(1===r)l=[y(.5)];else if(r>1)a=f[0],u=f[1]-a,l=function(){s=[];for(var n=0;0<=r?nr;0<=r?n++:n--)s.push(n);return s}.apply(this).map(function(n){return y(a+n/(r-1)*u)});else{if(n=[],p=[],t&&t.length>2)for(c=d=1,i=t.length;1<=i?di;c=1<=i?++d:--d)p.push(.5*(t[c-1]+t[c]));else p=f;l=p.map(function(n){return y(n)})}return k[e]&&(l=l.map(function(n){return n[e]()})),l},y.cache=function(n){return null!=n?v=n:v},y},null==k.scales&&(k.scales={}),k.scales.cool=function(){return k.scale([k.hsl(180,1,.9),k.hsl(250,.7,.4)])},k.scales.hot=function(){return k.scale(["#000","#f00","#ff0","#fff"],[0,.25,.75,1]).mode("rgb")},k.analyze=function(n,r,t){var e,o,u,f,a,c,i;if(a={min:Number.MAX_VALUE,max:Number.MAX_VALUE*-1,sum:0,values:[],count:0},null==t&&(t=function(){return!0}),e=function(n){null==n||isNaN(n)||(a.values.push(n),a.sum+=n,na.max&&(a.max=n),a.count+=1)},i=function(n,o){if(t(n,o))return e(null!=r&&"function"===Nn(r)?r(n):null!=r&&"string"===Nn(r)||"number"===Nn(r)?n[r]:n)},"array"===Nn(n))for(f=0,u=n.length;f=$;_=1<=$?++G:--G)A.push(P+_/t*(Q-P));A.push(Q)}else if("l"===r.substr(0,1)){if(P<=0)throw"Logarithmic scales are only possible for values > 0";for(S=Math.LOG10E*T(P),M=Math.LOG10E*T(Q),A.push(P),_=sn=1,F=t-1;1<=F?sn<=F:sn>=F;_=1<=F?++sn:--sn)A.push(on(10,S+_/t*(M-S)));A.push(Q)}else if("q"===r.substr(0,1)){for(A.push(P),_=e=1,D=t-1;1<=D?e<=D:e>=D;_=1<=D?++e:--e)I=(ln.length-1)*_/t,U=E(I),U===I?A.push(ln[U]):(Y=I-U,A.push(ln[U]*(1-Y)+ln[U+1]*Y));A.push(Q)}else if("k"===r.substr(0,1)){for(L=ln.length,g=new Array(L),w=new Array(t),en=!0,R=0,m=null,m=[],m.push(P),_=o=1,Z=t-1;1<=Z?o<=Z:o>=Z;_=1<=Z?++o:--o)m.push(P+_/t*(Q-P));for(m.push(Q);en;){for(O=u=0,J=t-1;0<=J?u<=J:u>=J;O=0<=J?++u:--u)w[O]=0;for(_=f=0,W=L-1;0<=W?f<=W:f>=W;_=0<=W?++f:--f){for(cn=ln[_],B=Number.MAX_VALUE,O=a=0,H=t-1;0<=H?a<=H:a>=H;O=0<=H?++a:--a)j=b(m[O]-cn),j=nn;O=0<=nn?++c:--c)q[O]=null;for(_=i=0,rn=L-1;0<=rn?i<=rn:i>=rn;_=0<=rn?++i:--i)x=g[_],null===q[x]?q[x]=ln[_]:q[x]+=ln[_];for(O=l=0,tn=t-1;0<=tn?l<=tn:l>=tn;O=0<=tn?++l:--l)q[O]*=1/w[O];for(en=!1,O=s=0,C=t-1;0<=C?s<=C:s>=C;O=0<=C?++s:--s)if(q[O]!==m[_]){en=!0;break}m=q,R++,R>200&&(en=!1)}for(N={},O=p=0,X=t-1;0<=X?p<=X:p>=X;O=0<=X?++p:--p)N[O]=[];for(_=d=0,K=L-1;0<=K?d<=K:d>=K;_=0<=K?++d:--d)x=g[_],N[x].push(ln[_]);for(fn=[],O=h=0,V=t-1;0<=V?h<=V:h>=V;O=0<=V?++h:--h)fn.push(N[O][0]),fn.push(N[O][N[O].length-1]);for(fn=fn.sort(function(n,r){return n-r}),A.push(fn[0]),_=v=1,z=fn.length-1;v<=z;_=v+=2)an=fn[_],isNaN(an)||A.indexOf(an)!==-1||A.push(an)}return A},R=function(n,r,t){var e,o,u,f;return e=An(arguments),n=e[0],r=e[1],t=e[2],isNaN(n)&&(n=0),n/=360,n<1/3?(o=(1-r)/3,f=(1+r*N(l*n)/N(c-l*n))/3,u=1-(o+f)):n<2/3?(n-=1/3,f=(1-r)/3,u=(1+r*N(l*n)/N(c-l*n))/3,o=1-(f+u)):(n-=2/3,u=(1-r)/3,o=(1+r*N(l*n)/N(c-l*n))/3,f=1-(u+o)),f=J(t*f*3),u=J(t*u*3),o=J(t*o*3),[255*f,255*u,255*o,e.length>3?e[3]:1]},ln=function(){var n,r,t,e,o,u,f,a;return f=An(arguments),u=f[0],r=f[1],n=f[2],l=2*Math.PI,u/=255, r/=255,n/=255,o=Math.min(u,r,n),e=(u+r+n)/3,a=1-o/e,0===a?t=0:(t=(u-r+(u-n))/2,t/=Math.sqrt((u-r)*(u-r)+(u-n)*(r-n)),t=Math.acos(t),n>r&&(t=l-t),t/=l),[360*t,a,e]},k.hsi=function(){return function(n,r,t){t.prototype=n.prototype;var e=new t,o=n.apply(e,r);return Object(o)===o?o:e}(t,En.call(arguments).concat(["hsi"]),function(){})},d.hsi=R,t.prototype.hsi=function(){return ln(this._rgb)},Y=function(n,r,t,e){var o,u,f,a,c,i,l,s,p,d,h,b,v;return"hsl"===e?(b=n.hsl(),v=r.hsl()):"hsv"===e?(b=n.hsv(),v=r.hsv()):"hcg"===e?(b=n.hcg(),v=r.hcg()):"hsi"===e?(b=n.hsi(),v=r.hsi()):"lch"!==e&&"hcl"!==e||(e="hcl",b=n.hcl(),v=r.hcl()),"h"===e.substr(0,1)&&(f=b[0],d=b[1],i=b[2],a=v[0],h=v[1],l=v[2]),isNaN(f)||isNaN(a)?isNaN(f)?isNaN(a)?u=Number.NaN:(u=a,1!==i&&0!==i||"hsv"===e||(p=h)):(u=f,1!==l&&0!==l||"hsv"===e||(p=d)):(o=a>f&&a-f>180?a-(f+360):a180?a+360-f:a-f,u=f+t*o),null==p&&(p=d+t*(h-d)),c=i+t*(l-i),s=k[e](u,p,c)},h=h.concat(function(){var n,r,t,e;for(t=["hsv","hsl","hsi","hcl","lch","hcg"],e=[],r=0,n=t.length;r=a?f(r):null,p=r.length;s&&(i=u,l=!1,r=s);n:for(;++ci))return!1;for(;++cOpenStreetMap' }).addTo(map) // Add GeoJSON $.getJSON('./crimes_by_district.geojson', function (geojson) { L.choropleth(geojson, { valueProperty: 'incidents', scale: ['white', 'red'], steps: 5, mode: 'q', style: { color: '#fff', weight: 2, fillOpacity: 0.8 }, onEachFeature: function (feature, layer) { layer.bindPopup('District ' + feature.properties.dist_num + '' + feature.properties.incidents.toLocaleString() + ' incidents') } }).addTo(map) }) ================================================ FILE: examples/basic/index.html ================================================ Leaflet Choropleth ================================================ FILE: examples/computed_values/demo.js ================================================ var map = L.map('map').setView([39.9897471840457, -75.13893127441406], 11) // Add basemap L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '© OpenStreetMap' }).addTo(map) // Add GeoJSON $.getJSON('../basic/crimes_by_district.geojson', function (geojson) { L.choropleth(geojson, { valueProperty: function (feature) { return feature.properties.incidents / feature.properties.area_sqmi }, scale: ['white', 'red'], steps: 5, mode: 'q', style: { color: '#fff', weight: 2, fillOpacity: 0.8 }, onEachFeature: function (feature, layer) { layer.bindPopup('District ' + feature.properties.dist_num + '' + feature.properties.incidents.toLocaleString() + ' incidents' + Math.round(feature.properties.area_sqmi).toLocaleString() + ' sq mi') } }).addTo(map) }) ================================================ FILE: examples/computed_values/index.html ================================================ Leaflet Choropleth ================================================ FILE: examples/fetch_join/demo.js ================================================ /** * Advanced demo * Fetches a geojson file as well as a data file and joins them before passing to L.choropleth */ var map = L.map('map').setView([39.9897471840457, -75.13893127441406], 11) // Add basemap L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '© OpenStreetMap' }).addTo(map) // Fetch GeoJSON and data to join to it $.when( $.getJSON('https://data.phila.gov/resource/bbgf-pidf.geojson'), $.getJSON('https://data.phila.gov/resource/r24g-zx3n.json?%24select=count(*)%20as%20value%2C%20%3A%40computed_region_bbgf_pidf%20as%20label&%24group=%3A%40computed_region_bbgf_pidf&%24order=value%20desc') ).done(function (responseGeojson, responseData) { var data = responseData[0] var geojson = responseGeojson[0] // Create hash table for easy reference var dataHash = data.reduce(function (hash, item) { if (item.label) { hash[item.label] = isNaN(item.value) ? null : +item.value } return hash }, {}) // Add value from hash table to geojson properties geojson.features.forEach(function (item) { item.properties.incidents = dataHash[item.properties._feature_id] || null }) L.choropleth(geojson, { valueProperty: 'incidents', scale: ['white', 'red'], steps: 5, mode: 'q', style: { color: '#fff', weight: 2, fillOpacity: 0.8 }, onEachFeature: function (feature, layer) { layer.bindPopup('District ' + feature.properties.dist_num + '' + feature.properties.incidents.toLocaleString() + ' incidents') } }).addTo(map) }) ================================================ FILE: examples/fetch_join/index.html ================================================ Leaflet Choropleth ================================================ FILE: examples/legend/demo.js ================================================ var map = L.map('map').setView([39.9897471840457, -75.13893127441406], 11) // Add basemap L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '© OpenStreetMap' }).addTo(map) // Add GeoJSON $.getJSON('../basic/crimes_by_district.geojson', function (geojson) { var choroplethLayer = L.choropleth(geojson, { valueProperty: 'incidents', scale: ['white', 'red'], steps: 5, mode: 'q', style: { color: '#fff', weight: 2, fillOpacity: 0.8 }, onEachFeature: function (feature, layer) { layer.bindPopup('District ' + feature.properties.dist_num + '' + feature.properties.incidents.toLocaleString() + ' incidents') } }).addTo(map) // Add legend (don't forget to add the CSS from index.html) var legend = L.control({ position: 'bottomright' }) legend.onAdd = function (map) { var div = L.DomUtil.create('div', 'info legend') var limits = choroplethLayer.options.limits var colors = choroplethLayer.options.colors var labels = [] // Add min & max div.innerHTML = '' + limits[0] + ' \ ' + limits[limits.length - 1] + '' limits.forEach(function (limit, index) { labels.push('') }) div.innerHTML += '' + labels.join('') + '' return div } legend.addTo(map) }) ================================================ FILE: examples/legend/index.html ================================================ Leaflet Choropleth ================================================ FILE: package.json ================================================ { "name": "leaflet-choropleth", "version": "1.1.4", "description": "Choropleth plugin for Leaflet (color scale based on value)", "main": "src/choropleth.js", "scripts": { "build": "webpack -p", "watch": "webpack --watch", "test": "standard src | snazzy && mocha test" }, "keywords": [ "leaflet", "choropleth", "chloropleth" ], "author": "timwis ", "homepage": "https://github.com/timwis/leaflet-choropleth", "repository": { "type": "git", "url": "https://github.com/timwis/leaflet-choropleth.git" }, "license": "MIT", "devDependencies": { "jsdom": "^7.2.0", "mocha": "^2.3.4", "mocha-jsdom": "^1.0.0", "should": "^8.0.0", "snazzy": "^2.0.1", "standard": "^5.4.1", "webpack": "^2.5.1" }, "dependencies": { "chroma-js": "^1.1.1", "leaflet": "^1.0.2", "lodash": "^4.17.4" } } ================================================ FILE: src/choropleth.js ================================================ var L = require('leaflet') var chroma = require('chroma-js') var _ = require('lodash/object') L.choropleth = module.exports = function (geojson, opts) { opts = opts || {} // Set default options in case any weren't passed _.defaults(opts, { valueProperty: 'value', scale: ['white', 'red'], steps: 5, mode: 'q' }) // Save what the user passed as the style property for later use (since we're overriding it) var userStyle = opts.style // Calculate limits var values = geojson.features.map( typeof opts.valueProperty === 'function' ? opts.valueProperty : function (item) { return item.properties[opts.valueProperty] }) var limits = chroma.limits(values, opts.mode, opts.steps - 1) // Create color buckets var colors = (opts.colors && opts.colors.length === limits.length ? opts.colors : chroma.scale(opts.scale).colors(limits.length)) return L.geoJson(geojson, _.extend(opts, { limits: limits, colors: colors, style: function (feature) { var style = {} var featureValue if (typeof opts.valueProperty === 'function') { featureValue = opts.valueProperty(feature) } else { featureValue = feature.properties[opts.valueProperty] } if (!isNaN(featureValue)) { // Find the bucket/step/limit that this value is less than and give it that color for (var i = 0; i < limits.length; i++) { if (featureValue <= limits[i]) { style.fillColor = colors[i] break } } } // Return this style, but include the user-defined style if it was passed switch (typeof userStyle) { case 'function': return _.defaults(style, userStyle(feature)) case 'object': return _.defaults(style, userStyle) default: return style } } })) } ================================================ FILE: test/choropleth.test.js ================================================ /* global describe, it, before */ var fs = require('fs') require('should') var jsdom = require('mocha-jsdom') var geojson = JSON.parse(fs.readFileSync('./examples/basic/crimes_by_district.geojson')) describe('basic usage', function () { jsdom() before(function () { this.choropleth = require('../src/choropleth') this.style = {fillColor: 'lime'} this.layer = this.choropleth(geojson, { style: this.style, valueProperty: 'incidents' }) // console.log(require('util').inspect(this.layer.options, {colors: true, depth: 2})) }) it('returns a layer', function () { this.layer.should.have.property('_layers') }) it('sets limits', function () { this.layer.options.should.have.property('limits') var limits = this.layer.options.limits limits.should.have.length(5) limits[0].should.be.equal(814) limits[4].should.be.equal(45529) }) it('sets colors', function () { this.layer.options.should.have.property('colors') var colors = this.layer.options.colors colors.should.have.length(5) colors[0].should.be.equal('#ffffff') colors[4].should.be.equal('#ff0000') }) it('sets the color of a feature', function () { var style = this.layer.options.style(geojson.features[0]) style.should.have.property('fillColor', '#ffbfbf') }) it("doesn't modify style object", function () { this.style.should.be.eql({fillColor: 'lime'}) }) }) describe('valueProperty function', function () { jsdom() before(function () { this.choropleth = require('../src/choropleth') this.layer = this.choropleth(geojson, { valueProperty: function (feature) { return feature.properties.incidents } }) // console.log(require('util').inspect(this.layer.options, {colors: true, depth: 2})) }) it('sets limits', function () { this.layer.options.should.have.property('limits') var limits = this.layer.options.limits limits.should.have.length(5) limits[0].should.be.equal(814) limits[4].should.be.equal(45529) }) it('sets the color of a feature', function () { var style = this.layer.options.style(geojson.features[0]) style.should.have.property('fillColor', '#ffbfbf') }) }) ================================================ FILE: webpack.config.js ================================================ module.exports = { entry: './src/choropleth.js', output: { path: __dirname + '/dist', filename: 'choropleth.js' }, externals: { 'leaflet': 'L' } }