I have a special case for which I do not want to add my generated path of a topojson file to the DOM, but rather only get the generated d
attribute (the SVG path).
So I usually did something like this:
let features = feature(landmass, landmass.objects.land).features
let projection = d3.geoAzimuthalEqualArea()
.center([180, -180])
.fitSize([width, height], { type: "FeatureCollection", features: features })
let path = d3.geoPath().projection(projection)
g.selectAll("#landmass")
.data(features)
.enter().append("path")
.attr("id", "landmass")
.attr("d", path);
But I actually just want the features
to be translated to the path using the chosen geoPath
, without adding any svg object to the DOM.
How can I achieve this?
D3's docs on the geographic path generators have you covered (emphasis mine):
The geographic path generator, d3.geoPath, is similar to the shape generators in d3-shape: given a GeoJSON geometry or feature object, it generates an SVG path data string or renders the path to a Canvas.
You can pass a GeoJSON feature into the path generator and have it create the path data—i.e. the path commands—which are then assigned to the d
property of the <path>
element. This is basically what happens when coding
.data(features)
// ... enter, append, etc...
.attr("d", path);
This statement can be rewritten as:
.data(features)
// ... enter, append, etc...
.attr("d", d => path(d));
or, even more explicitly:
.data(features)
// ... enter, append, etc...
.attr("d", feature => path(feature));
Looking at the latter code snippet it becomes clear that D3—via its data binding means—creates a <path>
element for every feature and passes that feature, i.e. the datum bound the the <path>
element, to the path generator path
to create the d
property's path command string.
With this knowledge you can easily create the path data strings for all your features without creating any DOM nodes:
const pathData = features.map(feature => path(feature));
More concisely, you can just pass the generator function to .map()
:
const pathData = features.map(path);