D3: hide a black brush stroke falling “into the sea”

What would be the least "expensive" way to hide all the raven touches that fall into the sea?

Strokes (and polygonal fill) that run on land should be visible, while those at sea should be hidden from view. I think my goal should be clear from the image below:

enter image description here

I can imagine two options:

  • Somehow "double-check" raven polygons in the base country ("land"). It sounds very intense. This is not a good option, so do not go there.
  • Place a “marine” polygon on top of the crow tessellation. Which would be super efficient visually and exactly what I need. How can I calculate a new marine range from the base map of countries? (for example, this is jsfiddle with a geoJSON D3 map ) I have several maps with different levels of polygon complexity, so I need a reliable way to create this map.

Any ideas ?

+5
source share
1 answer

A simple option that does not require any of the following elements:

  • ocean polygon
  • redrawing landfills / merging landfills
  • clip paths

- use the svg template. This may seem a little strange, and I'm not sure what the performance implications are, but you can use the voronoi diagram template to fill in your countries / functions (saving borders and the ability to select objects once and only once).

This requires that the polygon fill does not depend on geographic function, but depends on voronoi - your image uses the same fill for each polygon, but your question text may suggest that it is not.

To use such a template, create a template that will have the same width and height as your map. In the template, place the paths of the voronoi diagram. Finally, set the fill of each function to the template:

 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 dx; }) .y(function(d) { return dy; }) .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> 
+2
source

Source: https://habr.com/ru/post/1275504/


All Articles