Building a Dynamic Vedic Astrology Chart in Flutter – Part 2 | Planet Mapping, Lagna Calculation & Kunjara Integration

Implementing Real Planetary Data in a Flutter Kundali Chart (Part 2)

Introduction

In Part 1 of this series, we focused on constructing the complete geometric layout of a Vedic horoscope (kundali) in Flutter using CustomPainter. We drew the outer square, diagonal lines, the diamond at the center, and divided the whole structure into 12 houses with precise trigonometric calculations.

Now in Part 2, we enter the real world of astrology.

In this part, we:

  • Fetch real planetary values using Kunjara
  • Calculate the Ascendant (Lagna)
  • Determine which planet goes into which house
  • Dynamically label the chart with planets and rashis
  • Render the information cleanly in Flutter

With this, our kundali transitions from just a drawn shape to a fully functional astrological chart that is ready for production apps.


Integrating Planet Data with Kunjara

To build a real kundali, we first need accurate planetary degrees. Instead of manually computing astronomical values, we use Kunjara, which returns:

  • Planetary longitude
  • Zodiac sign
  • Nakshatra details
  • Ascendant
  • Other relevant Vedic information

Fetching Planetary Positions

final planets = await kunjara.getPlanets(
  date: birthDate,
  time: birthTime,
  lat: latitude,
  lon: longitude,
);

A typical result looks like:

Sun – 42.21° → Taurus  
Moon – 93.50° → Gemini  
Mars – 120.11° → Leo  

This gives us everything needed to determine planetary house placement.


Calculating the Ascendant (Lagna)

The Lagna determines House 1 in a Vedic chart. With Kunjara:

final ascendant = await kunjara.getAscendant(
  date: birthDate,
  time: birthTime,
  lat: latitude,
  lon: longitude,
);

For example:

Ascendant = Taurus

This means:

  • House 1 = Taurus
  • House 2 = Gemini
  • House 3 = Cancer
  • …and so on around the chart

Determining House Placement for Planets

Once we have:

  • Ascendant sign
  • Planet’s zodiac sign

We determine each planet’s house.

House Calculation Formula

house = ((planetRashiIndex - ascendantIndex + 12) % 12) + 1

Example:

Ascendant = Taurus (index 1)
Mars = Leo (index 4)

house = ((4 - 1 + 12) % 12) + 1 = 4

So Mars goes into House 4.

Flutter Logic

Map<int, List<String>> housePlanets = {};

for (final planet in planets) {
  final ascIndex = ascendant.signIndex;
  final planetRashi = planet.signIndex;

  final house = ((planetRashi - ascIndex + 12) % 12) + 1;
  housePlanets.putIfAbsent(house, () => []).add(planet.name);
}

A sample output:

{
  1: ["Asc"],
  2: ["Moon"],
  4: ["Mars"],
  10: ["Sun", "Mercury"]
}

This structure is then passed to the painter to draw planet labels inside their respective houses.


Passing Planet Data to the Custom Painter

From Part 1, the painter already knows how to render the geometric structure. Now we include planetary data:

HoroscopePainter(
  housePlanetMap: housePlanets,
  ascendant: ascendant,
)

The painter:

  • Reads house centers
  • Computes text positions
  • Draws planet abbreviations or symbols on the canvas

Rendering Planet Labels in the Chart

Each house now has:

  • A bounding rectangle
  • A center point
  • A list of planets

Distributing Multiple Planets

When one house has multiple planets, we avoid overlapping by calculating evenly spaced coordinates.

For example, arranging planets in a circular pattern:

final angle = (i * 2 * math.pi) / planets.length;
final x = centerX + radius * math.cos(angle);
final y = centerY + radius * math.sin(angle);

This ensures that three or more planets remain readable without collision.


Displaying House Rashis

House numbers and rashis are determined with:

rashiForHouse = (ascendantIndex + house - 1) % 12

You can display:

  • Sign symbols (♉, ♊, ♋)
  • Names (Taurus, Gemini, Cancer)
  • Abbreviations (Ta, Ge, Ca)

Rendered using canvas text drawing functions.


Math Behind the Chart

Throughout the process, a few formulas are the backbone of everything:

1. Positioning points on the canvas

x = centerX + radius × cos(angle)
y = centerY + radius × sin(angle)

2. Midpoint of a line

((x1 + x2) / 2, (y1 + y2) / 2)

3. House angle

angle = houseIndex × 30°

Because:

360° / 12 houses = 30° per house

Performance Optimization

For smooth rendering, avoid recalculating everything on every frame. Cache:

  • House boundaries
  • House center points
  • Planet text measurements

Only recalculate when:

  • Screen size changes
  • Planet data changes
  • User rotates device
  • User changes view mode

This ensures high performance even on large screens and web builds.


Final Output

By the end of Part 2, the kundali chart displays:

Correct geometric structure
Ascendant-based house ordering
Real planetary positions from Kunjara
Cleanly spaced labels
Automatic resizing for mobile and web

This transforms the chart from a drawing exercise into a functional astrology engine.


What’s Coming in Part 3

In the next article, we’ll explore:

  • Shadbal and Bhavbal
  • Showing Nakshatra and Pada
  • Supporting divisional charts (D9, D10, etc.)
  • Exporting the kundali as an image or PDF.

If You Missed Part 1

Part 1 explains how we:

  • Drew the kundali structure
  • Built the geometric layout
  • Used math + canvas to create a scalable chart