How to Make a D3 Chart in Astrology
An astrology wheel is a polar chart. D3 already has pie and arc. Here's the drawing half, with fake planet positions on purpose.
How to make a D3 chart in astrology is, as a programming problem, a labeled ring. Twelve signs, equal width, planets sitting at ecliptic longitudes. I don't cast charts. I do know how to draw a circle that other people insist on calling a wheel.
The preview uses fake planet positions so we can talk about the SVG. Plug in numbers from an ephemeris when you have them. If you wanted a normal dashboard chart instead, start from D3 graph examples or the D3.js page.
The drawing problem, not the sky
Astrology software has two halves. One half computes where the planets were. The other half paints a wheel. D3 is the second half. Mixing them in one file is how you get a 400-line script nobody can debug.
A natal chart as drawn in the West often puts the Ascendant on the left. This example puts 0° Aries at the top because the math is obvious: longitude 0 lives at 12 o'clock. Rotate the whole group when you want the house cusps to match a printed chart.
A D3 astrology wheel
Twelve slices from d3.pie with value: 1 so
they're equal. Planet marks are circles on a smaller radius. Abbreviations
around the rim are the first three letters of each sign, not glyphs.
Glyphs are a font problem, not a D3 problem.
Preview
The code
d3.pie already lives in the polar world. You don't need a
custom layout. Longitude to x/y is high-school trigonometry. The
- 90 is so 0° sits at the top of the SVG, not at 3 o'clock.
Code
const signs = ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"];
const pie = d3.pie().value(() => 1).sort(null);
const arc = d3.arc().innerRadius(132).outerRadius(168);
svg.append("g")
.attr("transform", "translate(210,210)")
.selectAll("path")
.data(pie(signs.map((name) => ({ name }))))
.join("path")
.attr("d", arc);
function xy(longitude, r) {
const a = ((longitude - 90) * Math.PI) / 180;
return [210 + r * Math.cos(a), 210 + r * Math.sin(a)];
}
const [x, y] = xy(42, 96); // Sun at 42° ecliptic longitude
svg.append("circle").attr("cx", x).attr("cy", y).attr("r", 7);
Real planet positions
For actual longitudes you want an ephemeris (Swiss Ephemeris and ports
of it are the usual path), plus a birth time and a lat/long. That's
outside D3. Feed this wheel an array of { name, lon } and
stop there.
Aspect lines are just line segments between those points. Houses are another pie, inner radius smaller, if you want them. I would not compute Placidus in the render function.
Polar charts that aren't zodiacs — skill wheels, wind roses — use the
same pie + arc setup. The
sankey and
map posts cover the
layouts that don't fit on a circle.
Questions I get
How do I make a D3 chart in astrology?
Treat the natal wheel as a polar chart. Twelve equal slices are a pie with value 1. Planet positions are ecliptic longitudes you plot on a circle with sine and cosine. D3 draws the wheel; an ephemeris library gives real longitudes.
Does this calculate my natal chart?
No. The planet marks in the example are hardcoded. A real chart needs birth time, place, and an ephemeris. This post is the drawing step.
Should astrology charts use D3 or a canvas library?
D3 is a good fit because the wheel is SVG arcs and text. Canvas is fine if you paint a lot of aspect lines. I would not start with Chart.js; it does not think in zodiac degrees.