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.

D3 Astrology Examples
← All posts
How to Make a D3 Chart in Astrology

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 need an ephemeris — Swiss Ephemeris is the standard, and there are JavaScript ports of it. You provide a birth date, time, and location, and the library gives you ecliptic longitudes for each planet. None of that is D3's job. Once you have the numbers, just feed this wheel an array of { name, lon } objects and it places the markers.

Aspect lines are line segments drawn between planet points — entirely straightforward once you have the coordinates. Houses are another concentric pie with a smaller inner radius. And for what it's worth, I would not compute Placidus house cusps inside a render function. Do that calculation once, cache the result, pass it in.

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. The twelve zodiac signs are just a pie chart where every slice has equal value — d3.pie with value: () => 1 handles that. Planet positions are ecliptic longitudes, which you convert to screen coordinates with sine and cosine. D3 draws the wheel; you get the actual planetary longitudes from a separate ephemeris library.

Does this calculate my natal chart?

No — this post is only about the drawing step. The planet positions in the example are hardcoded so we can talk about the SVG without getting tangled up in astronomical math. A real natal chart requires a birth date, time, and location, run through an ephemeris library like Swiss Ephemeris or one of its JavaScript ports.

Should astrology charts use D3 or a canvas library?

D3 is a natural fit because the wheel is made of SVG arcs, circles, and text — things D3 handles well. Canvas works fine too if you're drawing a lot of aspect lines (the lines connecting planets that form aspects), since SVG can get slow with many overlapping paths. I wouldn't reach for Chart.js here; its mental model is Cartesian charts and it doesn't think in degrees or polar coordinates.

Latest posts

All posts