npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@eaprelsky/nocturna-wheel

v4.0.1

Published

A JavaScript library for rendering astrological natal charts

Readme

Nocturna Wheel

A JavaScript library for rendering astrological natal charts.

Features

  • Responsive SVG-based chart rendering
  • Dual chart support - independent inner and outer circles for synastry and transit charts
  • Zodiac sign display with customizable styling
  • House system rendering with multiple system options (Placidus, Koch, Equal, etc.)
  • Automatic wheel rotation - chart automatically positions Ascendant at 9 o'clock when house data is provided
  • Planet placement with customizable icons and colors on two independent circles
  • Three types of aspects:
    • Primary aspects (outer circle to outer circle)
    • Secondary aspects (inner circle to inner circle)
    • Synastry aspects (outer to inner circle with projection dots)
  • Interactive tooltips for celestial objects
  • Full control over colors, line styles, and orbs for each aspect type

Installation

NPM Installation (Recommended)

npm install @eaprelsky/nocturna-wheel

The library comes with inline SVG icons bundled as data URLs, so you don't need to worry about copying asset files. Icons work out of the box!

Direct Script Include

<!-- Include the Nocturna Wheel stylesheet -->
<link rel="stylesheet" href="path/to/nocturna-wheel.css">

<!-- Include the Nocturna Wheel library -->
<script src="path/to/nocturna-wheel.min.js"></script>

Basic Usage

ES Module (Recommended)

import { WheelChart } from 'nocturna-wheel';

const chart = new WheelChart({
  container: "#chart-container",
  planets: {
    sun: { lon: 85.83 },
    moon: { lon: 133.21 }
  },
  houses: [
    { lon: 300.32 },  // 1st house cusp
    { lon: 330.15 },  // 2nd house cusp
    { lon: 355.24 },  // 3rd house cusp
    { lon: 20.32 },   // 4th house cusp
    { lon: 45.15 },   // 5th house cusp
    { lon: 75.24 },   // 6th house cusp
    { lon: 120.32 },  // 7th house cusp
    { lon: 150.15 },  // 8th house cusp
    { lon: 175.24 },  // 9th house cusp
    { lon: 200.32 },  // 10th house cusp
    { lon: 225.15 },  // 11th house cusp
    { lon: 255.24 }   // 12th house cusp
  ]
});

chart.render();

Browser Script

<div id="chart-container"></div>

<script>
  // The library exports a NocturnaWheel object with all components
  const { WheelChart } = NocturnaWheel;
  
  const chart = new WheelChart({
    container: "#chart-container",
    planets: {
      sun: { lon: 85.83 },
      moon: { lon: 133.21 }
    },
    houses: [
      { lon: 300.32 },  // 1st house cusp
      { lon: 330.15 },  // 2nd house cusp
      { lon: 355.24 },  // 3rd house cusp
      { lon: 20.32 },   // 4th house cusp
      { lon: 45.15 },   // 5th house cusp
      { lon: 75.24 },   // 6th house cusp
      { lon: 120.32 },  // 7th house cusp
      { lon: 150.15 },  // 8th house cusp
      { lon: 175.24 },  // 9th house cusp
      { lon: 200.32 },  // 10th house cusp
      { lon: 225.15 },  // 11th house cusp
      { lon: 255.24 }   // 12th house cusp
    ]
  });
  
  chart.render();
</script>

API Documentation

WheelChart Class

Main class for creating and managing astrological charts.

Constructor Options

  • container: String selector or DOM element for the chart container
  • planets: Object containing primary planet positions (outer circle)
  • secondaryPlanets: Object containing secondary planet positions (inner circle, optional)
  • houses: Array of house cusp positions
  • config: Additional configuration options including aspect settings
const chart = new NocturnaWheel.WheelChart({
  container: "#chart-container",
  planets: {
    sun: { lon: 85.83, color: "#000000" },
    moon: { lon: 133.21, color: "#000000" }
  },
  secondaryPlanets: {
    sun: { lon: 115.20, color: "#FF5500" },
    moon: { lon: 200.45, color: "#0066CC" }
  },
  houses: [{ lon: 300.32 }, ...],
  config: {
    zodiacSettings: { enabled: true },
    planetSettings: { enabled: true },
    // Primary aspects (outer circle to outer circle)
    primaryAspectSettings: {
      enabled: true,
      orb: 6,
      types: {
        conjunction: { angle: 0, orb: 8, color: "#000000", enabled: true, lineStyle: 'none', strokeWidth: 1 },
        opposition: { angle: 180, orb: 6, color: "#E41B17", enabled: true, lineStyle: 'solid', strokeWidth: 1 }
      }
    },
    // Secondary aspects (inner circle to inner circle)
    secondaryAspectSettings: {
      enabled: true,
      orb: 6,
      types: { /* ... */ }
    },
    // Synastry aspects (outer to inner circle projections)
    synastryAspectSettings: {
      enabled: true,
      orb: 6,
      types: { /* ... */ }
    }
  }
});

Methods

  • render(): Renders the chart
  • update(config): Updates chart configuration
  • updateData(data): Updates planet and house data
  • togglePlanet(name, visible): Toggles visibility of a specific planet
  • toggleHouses(visible): Toggles visibility of houses
  • togglePrimaryPlanets(visible): Toggles visibility of primary planets (outer circle)
  • toggleSecondaryPlanets(visible): Toggles visibility of secondary planets (inner circle)
  • togglePrimaryAspects(visible): Toggles visibility of primary aspects (outer circle)
  • toggleSecondaryAspects(visible): Toggles visibility of secondary aspects (inner circle)
  • toggleSynastryAspects(visible): Toggles visibility of synastry aspects (cross-circle)
  • setHouseRotation(angle): Sets house system rotation (optional - automatic rotation is enabled by default)
  • setHouseSystem(name): Changes the house system
  • destroy(): Removes the chart and cleans up resources

Automatic Wheel Rotation

The library automatically rotates the zodiac wheel to position the Ascendant (1st house cusp) at the 9 o'clock position when house data is provided. This happens in two ways:

  1. When providing a houses array: The first house cusp longitude (houses[0].lon) is used for rotation
  2. When using astronomicalData.ascendant: The ascendant value is used for rotation
// Auto-rotation with houses array
const chart = new WheelChart({
  container: '#chart',
  houses: [
    { lon: 300.32 },  // Ascendant - automatically used for rotation
    // ... other houses
  ]
});

// Auto-rotation with astronomicalData
const chart = new WheelChart({
  container: '#chart',
  config: {
    astronomicalData: {
      ascendant: 120.5,  // Automatically used for rotation
      mc: 210.5,
      latitude: 55.75,
      houseSystem: "Placidus"
    }
  }
});

Manual override: You can still override the automatic rotation by calling setHouseRotation() after initialization:

chart.setHouseRotation(90);  // Custom rotation angle

For more details, see Auto-Rotation Documentation.

Advanced Configuration

ChartConfig Options

const chartConfig = {
  // Astronomical data
  astronomicalData: {
    ascendant: 0,
    mc: 90,
    latitude: 51.5,
    houseSystem: "Placidus"
  },
  
  // Primary aspect settings (outer circle to outer circle)
  primaryAspectSettings: {
    enabled: true,
    orb: 6,
    types: {
      conjunction: { angle: 0, orb: 8, color: "#000000", enabled: true, lineStyle: 'none', strokeWidth: 1 },
      opposition: { angle: 180, orb: 6, color: "#E41B17", enabled: true, lineStyle: 'solid', strokeWidth: 1 },
      trine: { angle: 120, orb: 6, color: "#4CC417", enabled: true, lineStyle: 'solid', strokeWidth: 1 },
      square: { angle: 90, orb: 6, color: "#F62817", enabled: true, lineStyle: 'dashed', strokeWidth: 1 },
      sextile: { angle: 60, orb: 4, color: "#56A5EC", enabled: true, lineStyle: 'dashed', strokeWidth: 1 }
    }
  },
  
  // Secondary aspect settings (inner circle to inner circle)
  secondaryAspectSettings: {
    enabled: true,
    orb: 6,
    types: {
      conjunction: { angle: 0, orb: 8, color: "#AA00AA", enabled: true, lineStyle: 'none', strokeWidth: 1 },
      opposition: { angle: 180, orb: 6, color: "#FF6600", enabled: true, lineStyle: 'solid', strokeWidth: 1 }
      // ... other aspects
    }
  },
  
  // Synastry aspect settings (outer to inner circle)
  synastryAspectSettings: {
    enabled: true,
    orb: 6,
    types: {
      conjunction: { angle: 0, orb: 8, color: "#666666", enabled: true, lineStyle: 'none', strokeWidth: 1 },
      opposition: { angle: 180, orb: 6, color: "#9933CC", enabled: true, lineStyle: 'solid', strokeWidth: 0.5 }
      // ... other aspects
    }
  },
  
  // Visual settings
  zodiacSettings: {
    enabled: true,
    colors: {
      aries: "#ff6666",
      taurus: "#66cc66"
      // Other signs...
    }
  },
  
  // SVG dimensions
  svg: {
    width: 460,
    height: 460,
    viewBox: "0 0 460 460",
    center: { x: 230, y: 230 }
  },
  
  // Asset paths
  assets: {
    basePath: "./assets/",
    zodiacIconPath: "svg/zodiac/"
  }
};

Library Integration

The Nocturna Wheel library is available as both UMD and ES modules bundles for easy integration into modern web applications.

Using with Module Bundlers (Webpack, Rollup, Vite)

// Import specific components
import { WheelChart, ChartConfig } from 'nocturna-wheel';

// Create a chart instance
const chart = new WheelChart({
  container: '#chart-container',
  planets: {
    sun: { lon: 85.83 },
    moon: { lon: 133.21 }
  }
});

// Render the chart
chart.render();

Using with Factory Injection Pattern

The library supports Factory Injection for better decoupling and testability:

import { WheelChart, NocturnaWheel } from 'nocturna-wheel';

// Create a custom factory
const chartFactory = (options) => {
  console.log("Creating chart with custom factory");
  return new NocturnaWheel({
    ...options,
    // Apply custom configurations
    config: {
      ...options.config,
      theme: 'dark'
    }
  });
};

// Use the factory when creating WheelChart
const chart = new WheelChart(options, chartFactory);
chart.render();

See MODULE_ARCHITECTURE.md for more details on the library's architecture.

Synastry and Dual Charts

The library supports dual charts for synastry, transits, and progressions. Each circle operates independently:

const chart = new WheelChart({
  container: '#chart-container',
  // Natal chart (outer circle)
  planets: {
    sun: { lon: 85.83, color: '#000000' },
    moon: { lon: 133.21, color: '#000000' }
  },
  // Transit/Partner chart (inner circle)
  secondaryPlanets: {
    sun: { lon: 115.20, color: '#FF5500' },
    moon: { lon: 200.45, color: '#0066CC' }
  },
  config: {
    // Configure three independent aspect systems
    primaryAspectSettings: { /* natal-to-natal */ },
    secondaryAspectSettings: { /* transit-to-transit */ },
    synastryAspectSettings: { /* natal-to-transit with projection dots */ }
  }
});

// Toggle each aspect type independently
chart.togglePrimaryAspects(true);
chart.toggleSecondaryAspects(false);
chart.toggleSynastryAspects(true);

Synastry aspects are rendered with hollow projection dots on the inner circle, showing where outer circle planets project onto the inner radius. This creates a cleaner, more aesthetically pleasing visualization.

Working with Icons

Inline Icons (Default)

By default, the library uses inline SVG icons bundled as data URLs. This means:

  • No asset copying needed - icons are bundled with the JavaScript
  • Works out of the box - no path configuration required
  • Cross-platform - works in all environments (browser, webpack, vite, etc.)
// Icons work automatically - no configuration needed!
const chart = new WheelChart({
    container: '#chart-container',
    planets: { sun: { lon: 85.83 } }
});

Using Custom External Icons

If you want to use your own custom icons, you can disable inline mode:

import { IconProvider } from '@eaprelsky/nocturna-wheel';

// Create IconProvider with external icons
const iconProvider = new IconProvider({
    useInline: false,
    basePath: '/my-custom-icons/'
});

// Pass to ServiceRegistry
import { ServiceRegistry } from '@eaprelsky/nocturna-wheel';
ServiceRegistry.register('iconProvider', iconProvider);

// Now create your chart
const chart = new WheelChart({ /* ... */ });

Accessing Bundled Icon Files

If you need direct access to the SVG files (e.g., for documentation or custom usage):

// Using package.json exports
import sunIcon from '@eaprelsky/nocturna-wheel/icons/zodiac-planet-sun.svg';

Or copy them from node_modules:

cp -r node_modules/@eaprelsky/nocturna-wheel/dist/assets/svg ./public/

Custom Icon Data URLs

You can also provide custom icons as data URLs:

const customIcons = {
    planets: {
        sun: 'data:image/svg+xml,...',
        moon: 'data:image/svg+xml,...'
    }
};

const iconProvider = new IconProvider({
    customIcons: customIcons
});

License

This project is licensed under the MIT License - see the LICENSE file for details.