World GDP shown using Textures.js SVG textures with d3.carto.map.
<html xmlns="//www.w3.org/1999/xhtml">
<head>
<title>d3.carto with awesome textures</title>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="d3map.css" />
</head>
<style>
html,body {
height: 100%;
width: 100%;
margin: 0;
}
#map {
height: 100%;
width: 100%;
position: absolute;
}
.country {
stroke: #A39480;
stroke-width: 1px;
}
.smallmap {
width: 33%;
float: left;
border: 1px lightgray solid;
}
#legend {
position: absolute;
left: 20px;
bottom: 20px;
width: 400px;
height: 95px;
background: white;
z-index: 99;
}
#buttondiv {
position: absolute;
left: 120px;
top: 20px;
background: white;
z-index: 99;
}
</style>
<script>
function makeSomeMaps() {
legendSVG = d3.select("#legend").append("svg").style("width", "100%").style("height", "100%");
texturesArray = [];
for (var x = 0; x<5;x++) {
var t = textures.lines().size(4).strokeWidth(1);
switch(x) {
case 0:
t = textures.circles()
.heavier();
break;
case 1:
t = textures.lines().orientation("vertical")
.strokeWidth(1)
.shapeRendering("crispEdges");
break;
case 2:
t = textures.lines().lighter();
break;
case 3:
t = textures.lines().heavier();
break;
case 4:
t = textures.lines()
.orientation("3/8", "7/8");
break;
}
t.background("#FAEBD7");
legendSVG.call(t);
texturesArray.push(t.url());
}
colorScale = d3.scale.linear().domain([250,500,2000,10000,16000])
.range(texturesArray)
legend = d3.svg.legend().unitLabel("billion")
.unitTranslate([10,0])
.formatter(d3.format(".0f"))
.title("GDP")
.scale(colorScale);
legendSVG.append("g").attr("transform", "translate(20,35)").attr("class", "legend").call(legend);
map = d3.carto.map();
d3.select("#map").call(map);
map.mode("globe");
projection = d3.geo.conicEquidistant()
.scale(350)
.translate([550,600]);
map.projection(projection);
map.refresh();
countryLayer = d3.carto.layer.topojson();
countryLayer.path("world.topojson")
.label("Countries")
.renderMode("svg")
.cssClass("country")
.on("load", applyTextures);
map.addCartoLayer(countryLayer);
function applyTextures() {
d3.selectAll("path.country").style("fill", function(d) {return colorScale(parseFloat(d.properties.gdp))});
}
d3.select("#buttondiv").append("button").html("globe").on("click", function() {map.mode("globe")});
d3.select("#buttondiv").append("button").html("mercator").on("click", function() {map.mode("transform")});
d3.select("#buttondiv").append("button").html("equidistant").on("click", function() {map.mode("projection")});
}
</script>
<body onload="makeSomeMaps()">
<div id="map"></div>
<div id="legend"></div>
<div id="buttondiv"></div>
<footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//d3js.org/colorbrewer.v1.min.js" charset="utf-8" type="text/javascript"></script>
<script src="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.js" type="text/javascript">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<script src="textures.min.js" type="text/javascript">
</script>
<script src="legend.js" type="text/javascript">
</script>
</footer>
</body>
</html>
path,circle,rect,polygon,ellipse,line {
vector-effect: non-scaling-stroke;
}
svg, canvas {
top: 0;
}
#d3MapZoomBox {
position: absolute;
z-index: 10;
height: 100px;
width: 25px;
top: 10px;
right: 50px;
}
#d3MapZoomBox > button {
height:25px;
width: 25px;
line-height: 25px;
}
.d3MapControlsBox > button {
font-size:22px;
font-weight:900;
border: none;
height:25px;
width:25px;
background: rgba(35,31,32,.85);
color: white;
padding: 0;
cursor: pointer;
}
.d3MapControlsBox > button:hover {
background: black;
}
#d3MapPanBox {
position: absolute;
z-index: 10;
height: 100px;
width: 25px;
top: 60px;
right: 50px;
}
#d3MapPanBox > button {
height:25px;
width: 25px;
line-height: 25px;
}
#d3MapPanBox > button#left {
position: absolute;
left: -25px;
top: 10px;
}
#d3MapPanBox > button#right {
position: absolute;
right: -25px;
top: 10px;
}
#d3MapLayerBox {
position: relative;
z-index: 10;
height: 100px;
width: 120px;
top: 10px;
left: 10px;
overflow: auto;
color: white;
background: rgba(35,31,32,.85);
}
#d3MapLayerBox > div {
margin: 5px;
border: none;
}
#d3MapLayerBox ul {
list-style: none;
padding: 0;
margin: 0;
cursor: pointer;
}
#d3MapLayerBox li {
list-style: none;
padding: 0;
}
#d3MapLayerBox li:hover {
font-weight:700;
}
#d3MapLayerBox li input {
cursor: pointer;
}
div.d3MapModal {
position: absolute;
z-index: 11;
background: rgba(35,31,32,.90);
top: 50px;
left: 50px;
color: white;
max-width: 400px;
}
div.d3MapModalContent {
width:100%;
height: 100%;
overflow: auto;
}
div.d3MapModalContent > p {
padding: 0px 20px;
margin: 5px 0;
}
div.d3MapModalContent > h1 {
padding: 0px 20px;
font-size: 20px;
}
div.d3MapModalArrow {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid rgba(35,31,32,.90);
position: absolute;
bottom: -20px;
left: 33px;
}
#d3MapSVG {
}
rect.minimap-extent {
fill: rgba(200,255,255,0.35);
stroke: black;
stroke-width: 2px;
stroke-dasharray: 5 5;
}
circle.newpoints {
fill: black;
stroke: red;
stroke-width: 2px;
}
path.newfeatures {
fill: steelblue;
fill-opacity: .5;
stroke: pink;
stroke-width: 2px;
}
d3.svg.legend = function() {
var data = [];
var size = [300,20];
var xScale = d3.scale.linear();
var scale;
var title = "Legend";
var numberFormat = d3.format(".4n");
var units = "Units";
var unitTranslate =[0,0];
function legend(gSelection) {
createLegendData(scale);
var xMin = d3.min(data, function(d) {return d.domain[0]});
var xMax = d3.max(data, function(d) {return d.domain[1]});
xScale.domain([xMin,xMax]).range([0,size[0]])
console.log(data)
gSelection.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("height", size[1])
// .attr("width", function (d) {return xScale(d.domain[1]) - xScale(d.domain[0])})
.attr("width", size[0] / scale.domain().length)
// .attr("x", function (d) {return xScale(d.domain[0])})
.attr("x", function(d,i) {return i * (size[0] / scale.domain().length)})
.style("fill", function(d) {return d.color})
gSelection.selectAll("line")
.data(data)
.enter()
.append("line")
// .attr("x1", function (d) {return xScale(d.domain[0])})
// .attr("x2", function (d) {return xScale(d.domain[0])})
.attr("x1", function(d,i) {return (i + .5) * (size[0] / scale.domain().length)})
.attr("x2", function(d,i) {return (i + .5) * (size[0] / scale.domain().length)})
.attr("y1", 0)
.attr("y2", size[1] + 5)
.style("stroke", "black")
.style("stroke-width", "2px")
gSelection.selectAll("text")
.data(data)
.enter()
.append("g")
// .attr("transform", function (d) {return "translate(" + (xScale(d.domain[0])) +"," + (size[1] + 20) + ")"})
.attr("transform", function (d,i) {return "translate(" + ((i + .5) * (size[0] / scale.domain().length)) +"," + (size[1] + 20) + ")"})
.style("text-anchor", "middle")
.append("text")
.text(function(d) {return numberFormat(d.domain[0])})
gSelection.append("text")
.attr("transform", function (d) {return "translate(" + (xScale(xMin)) +"," + (size[1] - 30) + ")"})
.text(title)
gSelection.append("text")
.attr("transform", function (d) {return "translate(" + (xScale(xMax) + unitTranslate[0]) +"," + (size[1] + 20 + unitTranslate[1]) + ")"})
.text(units)
return legend;
}
function createLegendData(incScale) {
var rangeArray = incScale.range();
data = [];
for (x in rangeArray) {
var colorValue = rangeArray[x];
if (incScale.invertExtent) {
var domainValues = incScale.invertExtent(colorValue);
}
else {
if (x == incScale.domain().length) {
var domainValues = [incScale.domain()[x],incScale.domain()[x]];
}
else {
var domainValues = [incScale.domain()[x],incScale.domain()[parseInt(x) + 1]];
}
}
data.push({color: colorValue, domain: domainValues})
}
}
legend.scale = function(newScale) {
if (!arguments.length) return scale;
scale = newScale;
return this;
}
legend.title = function(newTitle) {
if (!arguments.length) return title;
title = newTitle;
return this;
}
legend.unitLabel = function(newUnits) {
if (!arguments.length) return units;
units = newUnits;
return this;
}
legend.unitTranslate = function(newTranslate) {
if (!arguments.length) return unitTranslate;
unitTranslate = newTranslate;
return this;
}
legend.formatter = function(newFormatter) {
if (!arguments.length) return numberFormat;
numberFormat = newFormatter;
return this;
}
return legend;
}
(function(){var rand,root,__slice=[].slice;root=typeof exports!=="undefined"&&exports!==null?exports:this;rand=function(){return(Math.random().toString(36)+"00000000000000000").replace(/[^a-z]+/g,"").slice(0,5)};root.textures={circles:function(){var background,circles,complement,fill,id,radius,size,stroke,strokeWidth;size=20;background="";radius=2;complement=false;fill="#343434";stroke="#343434";strokeWidth=0;id=rand();circles=function(){var corner,g,_i,_len,_ref,_results;g=this.append("defs").append("pattern").attr("id",id).attr("patternUnits","userSpaceOnUse").attr("width",size).attr("height",size);if(background){g.append("rect").attr("width",size).attr("height",size).attr("fill",background)}g.append("circle").attr("cx",size/2).attr("cy",size/2).attr("r",radius).attr("fill",fill).attr("stroke",stroke).attr("stroke-width",strokeWidth);if(complement){_ref=[[0,0],[0,size],[size,0],[size,size]];_results=[];for(_i=0,_len=_ref.length;_i<_len;_i++){corner=_ref[_i];_results.push(g.append("circle").attr("cx",corner[0]).attr("cy",corner[1]).attr("r",radius).attr("fill",fill).attr("stroke",stroke).attr("stroke-width",strokeWidth))}return _results}};circles.heavier=function(_){if(!arguments.length){radius=radius*2}else{radius=_?radius*2*_:radius*2}return circles};circles.lighter=function(_){if(!arguments.length){radius=radius/2}else{radius=_?radius/(2*_):radius/2}return circles};circles.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return circles};circles.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return circles};circles.background=function(_){background=_;return circles};circles.size=function(_){size=_;return circles};circles.complement=function(){complement=true;return circles};circles.radius=function(_){radius=_;return circles};circles.fill=function(_){fill=_;return circles};circles.stroke=function(_){stroke=_;return circles};circles.strokeWidth=function(_){strokeWidth=_;return circles};circles.id=function(_){if(!arguments.length){return id}else{id=_;return circles}};circles.url=function(){return"url(#"+circles.id()+")"};return circles},lines:function(){var background,id,lines,orientation,path,shapeRendering,size,stroke,strokeWidth;size=20;strokeWidth=2;stroke="#343434";id=rand();background="";orientation=["diagonal"];shapeRendering="auto";path=function(orientation){switch(orientation){case"0/8":return function(s){return"M "+s/2+", 0 l 0, "+s}(size);case"vertical":return function(s){return"M "+s/2+", 0 l 0, "+s}(size);case"1/8":return function(s){return"M "+s/4+",0 l "+s/2+","+s+" M "+-s/4+",0 l "+s/2+","+s+" M "+s*3/4+",0 l "+s/2+","+s}(size);case"2/8":return function(s){return"M 0,"+s+" l "+s+","+-s+" M "+-s/4+","+s/4+" l "+s/2+","+-s/2+" M "+3/4*s+","+5/4*s+" l "+s/2+","+-s/2}(size);case"diagonal":return function(s){return"M 0,"+s+" l "+s+","+-s+" M "+-s/4+","+s/4+" l "+s/2+","+-s/2+" M "+3/4*s+","+5/4*s+" l "+s/2+","+-s/2}(size);case"3/8":return function(s){return"M 0,"+3/4*s+" l "+s+","+-s/2+" M 0,"+s/4+" l "+s+","+-s/2+" M 0,"+s*5/4+" l "+s+","+-s/2}(size);case"4/8":return function(s){return"M 0,"+s/2+" l "+s+",0"}(size);case"horizontal":return function(s){return"M 0,"+s/2+" l "+s+",0"}(size);case"5/8":return function(s){return"M 0,"+-s/4+" l "+s+","+s/2+"M 0,"+s/4+" l "+s+","+s/2+"M 0,"+s*3/4+" l "+s+","+s/2}(size);case"6/8":return function(s){return"M 0,0 l "+s+","+s+" M "+-s/4+","+3/4*s+" l "+s/2+","+s/2+" M "+s*3/4+","+-s/4+" l "+s/2+","+s/2}(size);case"7/8":return function(s){return"M "+-s/4+",0 l "+s/2+","+s+" M "+s/4+",0 l "+s/2+","+s+" M "+s*3/4+",0 l "+s/2+","+s}(size);default:return function(s){return"M "+s/2+", 0 l 0, "+s}(size)}};lines=function(){var g,o,_i,_len,_results;g=this.append("defs").append("pattern").attr("id",id).attr("patternUnits","userSpaceOnUse").attr("width",size).attr("height",size);if(background){g.append("rect").attr("width",size).attr("height",size).attr("fill",background)}_results=[];for(_i=0,_len=orientation.length;_i<_len;_i++){o=orientation[_i];_results.push(g.append("path").attr("d",path(o)).attr("stroke-width",strokeWidth).attr("shape-rendering",shapeRendering).attr("stroke",stroke).attr("stroke-linecap","square"))}return _results};lines.background=function(_){background=_;return lines};lines.shapeRendering=function(_){shapeRendering=_;return lines};lines.heavier=function(_){if(!arguments.length){strokeWidth=strokeWidth*2}else{strokeWidth=_?strokeWidth*2*_:strokeWidth*2}return lines};lines.lighter=function(_){if(!arguments.length){strokeWidth=strokeWidth/2}else{strokeWidth=_?strokeWidth/(2*_):strokeWidth/2}return lines};lines.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return lines};lines.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return lines};lines.orientation=function(){var args;args=1<=arguments.length?__slice.call(arguments,0):[];orientation=args;return lines};lines.size=function(_){size=_;return lines};lines.stroke=function(_){stroke=_;return lines};lines.strokeWidth=function(_){strokeWidth=_;return lines};lines.id=function(_){if(!arguments.length){return id}else{id=_;return lines}};lines.url=function(){return"url(#"+lines.id()+")"};return lines},paths:function(){var background,d,fill,height,id,paths,shapeRendering,size,stroke,strokeWidth,svgPath,width;size=20;height=1;width=1;strokeWidth=2;stroke="#343434";background="";d="";shapeRendering="auto";fill="transparent";id=void 0;svgPath=function(_){switch(_){case"squares":return function(s){return"M "+s/4+" "+s/4+" l "+s/2+" 0 l 0 "+s/2+" l "+-s/2+" 0 Z"}(size);case"nylon":return function(s){return"M 0 "+s/4+" l "+s/4+" 0 l 0 "+-s/4+" M "+s*3/4+" "+s+" l 0 "+-s/4+" l "+s/4+" 0 M "+s/4+" "+s/2+" l 0 "+s/4+" l "+s/4+" 0 M "+s/2+" "+s/4+" l "+s/4+" 0 l 0 "+s/4}(size);case"waves":return function(s){return"M 0 "+s/2+" c "+s/8+" "+-s/4+" , "+s*3/8+" "+-s/4+" , "+s/2+" 0 c "+s/8+" "+s/4+" , "+s*3/8+" "+s/4+" , "+s/2+" 0 M "+-s/2+" "+s/2+" c "+s/8+" "+s/4+" , "+s*3/8+" "+s/4+" , "+s/2+" 0 M "+s+" "+s/2+" c "+s/8+" "+-s/4+" , "+s*3/8+" "+-s/4+" , "+s/2+" 0"}(size);case"woven":return function(s){return"M "+s/4+","+s/4+"l"+s/2+","+s/2+"M"+s*3/4+","+s/4+"l"+s/2+","+-s/2+"M"+s/4+","+s*3/4+"l"+-s/2+","+s/2+"M"+s*3/4+","+s*5/4+"l"+s/2+","+-s/2+"M"+-s/4+","+s/4+"l"+s/2+","+-s/2}(size);case"crosses":return function(s){return"M "+s/4+","+s/4+"l"+s/2+","+s/2+"M"+s/4+","+s*3/4+"l"+s/2+","+-s/2}(size);case"caps":return function(s){return"M "+s/4+","+s*3/4+"l"+s/4+","+-s/2+"l"+s/4+","+s/2}(size);case"hexagons":return function(s){width=3;height=Math.sqrt(3);return"M "+s+",0 l "+s+",0 l "+s/2+","+s*Math.sqrt(3)/2+" l "+-s/2+","+s*Math.sqrt(3)/2+" l "+-s+",0 l "+-s/2+","+-s*Math.sqrt(3)/2+" Z M 0,"+s*Math.sqrt(3)/2+" l "+s/2+",0 M "+3*s+","+s*Math.sqrt(3)/2+" l "+-s/2+",0"}(size);default:return _(size)}};paths=function(){var g,path;path=svgPath(d);id=rand();g=this.append("defs").append("pattern").attr("id",id).attr("patternUnits","userSpaceOnUse").attr("width",size*width).attr("height",size*height);if(background){g.append("rect").attr("width",size*width).attr("height",size*height).attr("fill",background)}return g.append("path").attr("d",path).attr("fill",fill).attr("stroke-width",strokeWidth).attr("shape-rendering",shapeRendering).attr("stroke",stroke).attr("stroke-linecap","square")};paths.background=function(_){background=_;return paths};paths.shapeRendering=function(_){shapeRendering=_;return paths};paths.heavier=function(_){if(!arguments.length){strokeWidth=strokeWidth*2}else{strokeWidth=_?strokeWidth*2*_:strokeWidth*2}return paths};paths.lighter=function(_){if(!arguments.length){strokeWidth=strokeWidth/2}else{strokeWidth=_?strokeWidth/(2*_):strokeWidth/2}return paths};paths.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return paths};paths.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return paths};paths.d=function(_){d=_;return paths};paths.size=function(_){size=_;return paths};paths.stroke=function(_){stroke=_;return paths};paths.strokeWidth=function(_){strokeWidth=_;return paths};paths.id=function(_){if(!arguments.length){return id}else{id=_;return paths}};paths.url=function(){return"url(#"+paths.id()+")"};return paths}}}).call(this);