block by emeeks f2fea17ba3ec3cd66f60

addXYLayer - d3.carto.map

Full Screen

Labeling features using addXYLayer d3.carto.map.

You can add any array of objects with XY data by using d3.carto.layer.xyArray(). Here an array of centroid objects is made for the paths and then added to the map to display labels. Notice that the paths are added using addFeatureLayer because using addTopoJSON would load asynchronously and not have the data available to make the array for addXYLayer.

index.html

<html xmlns="//www.w3.org/1999/xhtml">
<head>
  <title>d3.carto.map - Label Features</title>
  <meta charset="utf-8" />
    <link type="text/css" rel="stylesheet" href="d3map.css" />
    <link type="text/css" rel="stylesheet" href="https://raw.githubusercontent.com/emeeks/d3-carto-map/master/examples/example.css" />
</head>
<style>
  html,body {
    height: 100%;
    width: 100%;
    margin: 0;
  }

  #map {
    height: 100%;
    width: 100%;
    position: absolute;
  }

</style>
<script>
  function makeSomeMaps() {
    zoomMap = d3.carto.map();

    d3.select("#map").call(zoomMap);

    zoomMap.setScale(2)

    tileLayer = d3.carto.layer.tile();
    tileLayer
    .path("elijahmeeks.map-ktkeam22")
    .label("Terrain");
    
    zoomMap.addCartoLayer(tileLayer);

    d3.json("//bl.ocks.org/emeeks/raw/c970c9ee3e242e90004b/world.geojson", function(error,data) {

    featureLayer = d3.carto.layer.featureArray();
    featureLayer
    .features(data.features)
    .label("Countries")
    .cssClass("invisible")
    .renderMode("svg")
    .clickableFeatures(true)
    .on("load", clickToZoom);
    
    function clickToZoom() {
      d3.select("#map").selectAll("path.countryborders").on("click", function (d) {

        var path = d3.geo.path().projection(zoomMap.projection());
        zoomMap.zoomTo(path.bounds(d),"scaled",.95,2000);

      })
    }

      labelPoints = [];

      for (x in data.features) {
        var center = d3.geo.centroid(data.features[x]);
        var newPoint = {label: data.features[x].properties.name, x: center[0], y: center[1]}
        labelPoints.push(newPoint)
      }
      
    xyLayer = d3.carto.layer.xyArray();
    xyLayer
    .features(data.features)
    .label("Labels")
    .cssClass("countrylabel")
    .renderMode("svg")
    .x("x")
    .y("y")
    .markerSize(10)
    .clickableFeatures(true);
    
    zoomMap.addCartoLayer(xyLayer)
      
      d3.selectAll("g.countrylabel").append("text")
      .text(function(d) {return d.label});
      d3.selectAll("circle.countrylabel").remove();
      zoomMap.refresh();


    })

  }
</script>
<body onload="makeSomeMaps()">
<div id="map"></div>
<footer>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="//d3js.org/topojson.v1.min.js" type="text/javascript">
</script>
<script src="//d3js.org/d3.geo.projection.v0.min.js" type="text/javascript">
</script>
<script src="//d3js.org/colorbrewer.v1.min.js"></script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/tile.js" type="text/javascript">
</script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/d3.quadtiles.js" type="text/javascript">
</script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/d3.geo.raster.js" type="text/javascript">
</script>
<script src="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.js" type="text/javascript">
</script>
</footer>
</body>
</html>

d3map.css

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;
}