Published
Edited
Apr 27, 2022
2 stars
Insert cell
Insert cell
Insert cell
svg_feature = geojson2svg(geojson, {
width: 300,
height: 300,
padding: 20,
backgroundColor: "#fff",
fillColor: "#f5f5f5",
strokeColor: "#ececec",
strokeWidth: 5,
label: (d) => `${d.properties.area.toFixed(1)} ha`
}).node()
Insert cell
svg_feature_2 = geojson2svg(fc, {
width: 200,
height: 200,
padding: 10,
dxText: -10,
dyText: 2,
backgroundColor: "green",
fillColor: "red",
textAnchor: "start",
strokeColor: "blue",
strokeWidth: 2,
label: (d) => d.properties.name
}).node()
Insert cell
Insert cell
svg_feature_string = svg_feature.parentNode.innerHTML
Insert cell
Insert cell
function geojson2svg(geojson, options = {}) {
// Options
const chartWidth = options.width || 300;
const chartHeight = options.height || 300;
const padding = options.padding !== undefined ? options.padding : 20;
const backgroundColor = options.backgroundColor || "#fff";
const fillColor = options.fillColor || "#09A573";
const strokeColor = options.strokeColor || "#FCF5E9";
const strokeWidth = options.strokeWidth || 1;
const labelColor = options.labelColor || "black";
const textAnchor = options.textAnchor || "start";
const dxText = options.dxText || 0;
const dyText = options.dyText || 0;
const svgTitle = options.title || "GeoJSON Feature";
const font =
options.font || "400 16px/1.5 'Source Sans Pro', 'Noto Sans', sans-serif";

// Feature preparation
// In case an array of featuers was passed, we convert it to a GeoJSON
// feature collection first
if (Array.isArray(geojson)) {
geojson = { type: "FeatureCollection", features: geojson };
} else if (geojson.type !== "FeatureCollection") {
geojson = { type: "FeatureCollection", features: [geojson] };
}

const projection = d3.geoMercator().fitExtent(
[
[padding, padding],
[chartWidth - padding, chartHeight - padding]
],
geojson
);

const pathGenerator = d3.geoPath(projection);

const svg = d3
.create("svg")
.attr("title", svgTitle)
.attr("width", chartWidth)
.attr("height", chartHeight);

// background color
svg
.append("rect")
.attr("width", chartWidth)
.attr("height", chartHeight)
.attr("fill", backgroundColor);

// fill GeoJSON
svg
.selectAll("path")
.data(geojson.features)
.join("path")
.attr("d", pathGenerator)
.attr("fill", fillColor)
.attr("stroke", strokeColor)
.attr("stroke-width", strokeWidth);

// add a label
if (options.label) {
svg
.selectAll("g.geojsonLabel text")
.data(geojson.features)
.join("text")
.attr("fill", labelColor)
.attr(
"transform",
(d) => `translate(${pathGenerator.centroid(maxInscribedCircle(d))})`
)
.attr("dx", dxText)
.attr("dy", dyText)
.attr("text-anchor", textAnchor)
.style("font", font)
.text(options.label);
}

return svg;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more