What would be the least 'expensive' way to hide all voronoi strokes that fall in the sea?
The strokes (and polygon fill) that run on land should be visible, whilst those that are on sea should be hidden from view. I think my objective should be clear from the picture below:
I can think of two options:
Any ideas
?
A simple option, which requires none of:
is to use an svg pattern. This may sound a bit odd, and I'm not positive as to what the performance implications are, but a pattern of your voronoi diagram can be used to fill your countries/features (preserving boundaries and allowing features to be drawn once and only once).
This requires that the polygon fill is not geographic feature dependent but rather voronoi dependent - your image uses the same fill for each polygon, but your question text might be suggesting this is not the case
To use a pattern like this, create a pattern that is the same width and height as your map. In the pattern, place the voronoi diagram paths. Lastly, set the fill of each feature to the pattern:
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var projection = d3.geoMercator()
.scale((width - 3) / (2 * Math.PI))
.translate([width / 2, height / 2]);
var path = d3.geoPath()
.projection(projection);
var graticule = d3.geoGraticule();
d3.json("https://unpkg.com/world-atlas@1/world/50m.json", function(error, world) {
if (error) throw error;
// random points:
var circles = d3.range(20).map(function() {
return {
x: Math.round(Math.random() * width),
y: Math.round(Math.random() * height)
};
});
// voronoi:
var voronoi = d3.voronoi()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.extent([[-1, -1], [width + 1, height + 1]]);
// pattern:
var pattern = svg.append("defs")
.append("pattern")
.attr("id","voronoi")
.attr("patternUnits","userSpaceOnUse")
.attr("width", width)
.attr("height",height)
.attr("x",0)
.attr("y",0)
pattern.selectAll("path")
.data(voronoi.polygons(circles))
.enter()
.append("path")
.attr("d", renderCell)
.attr("fill",function(d,i) { return d3.schemeCategory20[i]; })
// append paths as normal:
var features = svg.selectAll(null)
.data(topojson.feature(world,world.objects.countries).features)
.enter()
.append("path")
.attr("class", "boundary")
.attr("d", path)
.attr("fill","url(#voronoi)"); // fill with pattern
function renderCell(d) {
return d == null ? null : "M" + d.join("L") + "Z";
}
});
.boundary {
stroke: black;
stroke-width: 1px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<svg width="600" height="400"></svg>