function drawGraticules(
svgNode,
{
fontSize = 10,
fontFamily = defaultFontFamily,
tickFill = "black",
stroke = "#999",
strokeWidth = 0.5,
step = [1, 1],
clipId = DOM.uid("clip"),
debug = false
} = {}
) {
const {
projection,
marginTop,
marginRight,
marginLeft,
marginBottom,
height,
width
} = svgNode.props;
const extent = {
topLeft: projection.invert([marginLeft, marginTop]),
topRight: projection.invert([width - marginRight, marginTop]),
bottomRight: projection.invert([
width - marginRight,
height - marginBottom
]),
bottomLeft: projection.invert([marginLeft, height - marginRight])
};
const canvas = d3.select(svgNode);
const graticuleGenerator = d3.geoGraticule().step(step);
graticuleGenerator.extent([
[extent.topLeft[0], extent.topLeft[1]],
[extent.bottomRight[0], extent.bottomRight[1]]
]);
const graticules = graticuleGenerator();
const path = d3.geoPath(projection);
const [lonStep, latStep] = graticuleGenerator.step();
const defs = d3.select(svgNode).select("defs").node()
? d3.select(svgNode).select("defs")
: d3.select(svgNode).insert("defs", ":first-child");
defs
.append("clipPath")
.attr("id", clipId.id)
.append("rect")
.attr("x", marginLeft)
.attr("y", marginTop)
.attr("width", width - (marginLeft + marginRight))
.attr("height", height - (marginTop + marginBottom));
const g = d3
.select(svgNode)
.append("g")
.attr("class", "key-graticules")
.attr("font-family", fontFamily)
.attr("font-size", fontSize);
g.append("path")
.attr("class", "graticules")
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth)
.attr("fill", "none")
.attr("clip-path", clipId)
.attr("d", path(graticules));
g.append("rect")
.attr("class", "graticule-outline")
.attr("fill", "none")
.attr("stroke", stroke)
.attr("stroke-width", strokeWidth)
.attr("x", marginLeft)
.attr("y", marginTop)
.attr("width", width - (marginLeft + marginRight))
.attr("height", height - (marginTop + marginBottom));
if (debug) {
g.selectAll("circle.corner")
.data(Object.values(extent))
.join("circle")
.attr("class", "corner")
.attr("cx", (d) => projection(d)[0])
.attr("cy", (d) => projection(d)[1])
.attr("r", 4)
.attr("fill", "#f0f");
}
}