{
const width = 400, height = 300;
const toRadians = (degrees) => degrees * (Math.PI / 180);
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
const g = svg.append("g")
.attr("transform", `translate(${width / 2},${height / 2})`);
g.append("path")
.attr("d", d3.arc()({
innerRadius: 105,
outerRadius: 110,
startAngle: 0,
endAngle: Math.PI * 2
}))
.attr("fill", "black");
g.append("path")
.attr("d", d3.arc()({
innerRadius: 100,
outerRadius: 120,
startAngle: toRadians(sunData.properties.sunrise.azimuth),
endAngle: toRadians(sunData.properties.sunset.azimuth)
}))
.attr("fill", "red");
g.append("path")
.attr("d", d3.arc()({
innerRadius: 130,
outerRadius: 140,
startAngle: toRadians(moonData.properties.moonrise.azimuth),
endAngle: toRadians(moonData.properties.moonset.azimuth)
}))
.attr("fill", "blue");
function polarToCartesian(r, angleInRadians) {
return {
x: r * Math.cos(angleInRadians - Math.PI / 2),
y: r * Math.sin(angleInRadians - Math.PI / 2)
};
}
const sunLabelRadius = 125;
const sunriseAngle = toRadians(sunData.properties.sunrise.azimuth);
const sunsetAngle = toRadians(sunData.properties.sunset.azimuth);
let pos = polarToCartesian(sunLabelRadius, sunriseAngle);
g.append("text")
.attr("x", pos.x)
.attr("y", pos.y)
.attr("text-anchor", "start")
.attr("dy", "-0.5em")
.text("Sunrise")
.style("fill","red");
pos = polarToCartesian(sunLabelRadius, sunsetAngle);
g.append("text")
.attr("x", pos.x)
.attr("y", pos.y)
.attr("text-anchor", "end")
.attr("dy", "-0.5em")
.text("Sunset")
.style("fill","red");
const moonLabelRadius = 145;
const moonriseAngle = toRadians(moonData.properties.moonrise.azimuth);
const moonsetAngle = toRadians(moonData.properties.moonset.azimuth);
pos = polarToCartesian(moonLabelRadius, moonriseAngle);
g.append("text")
.attr("x", pos.x)
.attr("y", pos.y)
.attr("text-anchor", "start")
.attr("dy", "-0.5em")
.text("Moonrise")
.style("fill","blue");
pos = polarToCartesian(moonLabelRadius, moonsetAngle);
g.append("text")
.attr("x", pos.x)
.attr("y", pos.y)
.attr("text-anchor", "end")
.attr("dy", "-0.5em")
.text("Moonset")
.style("fill","blue");
const cardinalLabelRadius = 80;
const cardinals = [
{ label: "N", angle: 0 },
{ label: "E", angle: 90 },
{ label: "S", angle: 180 },
{ label: "W", angle: 270 }
];
cardinals.forEach(d => {
const pos = polarToCartesian(cardinalLabelRadius, toRadians(d.angle));
g.append("text")
.attr("x", pos.x)
.attr("y", pos.y)
.attr("text-anchor", "middle")
.attr("dy", "0.35em")
.style("font-weight", "bold")
.text(d.label);
});
return svg.node();
}