From a227bdd2c88ea6a4bab7acbb8a563dbea4d54eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20F=C3=BCcher?= Date: Tue, 31 Mar 2026 17:12:15 -0300 Subject: [PATCH 1/4] =?UTF-8?q?feat(website):=20Phase=202=20=E2=80=94=20Po?= =?UTF-8?q?lish=20&=20Complete=20documentation=20site?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue #99 โ€” Theme customization and logo design: - Replace placeholder logo.svg with proper astrological wheel SVG (12 division marks, dual rings, crosshair axes, planet dots, currentColor) - Apply indigo accent palette to custom.css (light + dark mode variants) - Wire customCss into astro.config.mjs so theme is applied site-wide - Improve .chart-demo container styling (rounded corners, shadow, padding) Issue #100 โ€” Enrich remaining documentation pages: - custom-settings.md: full settings table grouped by category, 5+ examples - custom-symbols.md: complete CUSTOM_SYMBOL_FN docs with 3 examples - click-events.md: ADD_CLICK_AREA flag, on() API, full event handler example - multiple-charts.md: unique IDs, 4 multi-chart examples, independent state - api/settings.md: comprehensive reference for all ~100 settings from source - guides/frameworks/vue.md: Vue 3 Composition API, Vue 2, Nuxt SSR examples - guides/frameworks/angular.md: ViewChild, ngOnDestroy, NgZone, SSR guard - changelog.md: real version history (v3.0.0โ€“v3.0.2) in Keep a Changelog format - contributing.md: website dev, code style table, PR branch conventions Issue #98 โ€” Gallery page and advanced demo features: - Add 'aspects' mode to ChartDemo.astro (renders chart.radix().aspects()) - Create gallery.mdx with 4 live demos: radix, transit, aspects, animate - Add 'Examples' sidebar group in astro.config.mjs between Guides and API ๐Ÿค– Generated with [eca](https://eca.dev) Co-Authored-By: eca --- website/astro.config.mjs | 7 + website/public/img/logo.svg | 33 ++- website/src/components/ChartDemo.astro | 9 +- website/src/content/docs/api/settings.md | 242 ++++++++++++++++-- website/src/content/docs/changelog.md | 70 +++-- website/src/content/docs/contributing.md | 135 ++++++++-- website/src/content/docs/gallery.mdx | 35 +++ .../src/content/docs/guides/click-events.md | 102 ++++++-- .../content/docs/guides/custom-settings.md | 227 +++++++++++++++- .../src/content/docs/guides/custom-symbols.md | 133 +++++++++- .../content/docs/guides/frameworks/angular.md | 141 ++++++++-- .../src/content/docs/guides/frameworks/vue.md | 168 +++++++++++- .../content/docs/guides/multiple-charts.md | 130 +++++++++- website/src/styles/custom.css | 28 +- 14 files changed, 1318 insertions(+), 142 deletions(-) create mode 100644 website/src/content/docs/gallery.mdx diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 844c018..c514a99 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -14,6 +14,7 @@ export default defineConfig({ src: './public/img/logo.svg', alt: 'AstroChart Logo' }, + customCss: ['./src/styles/custom.css'], social: [ { icon: 'github', label: 'GitHub', href: 'https://github.com/AstroDraw/AstroChart' } ], @@ -46,6 +47,12 @@ export default defineConfig({ } ] }, + { + label: 'Examples', + items: [ + { label: 'Gallery', slug: 'gallery' } + ] + }, { label: 'API Reference', items: [ diff --git a/website/public/img/logo.svg b/website/public/img/logo.svg index e542127..613148a 100644 --- a/website/public/img/logo.svg +++ b/website/public/img/logo.svg @@ -1,7 +1,32 @@ - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/src/components/ChartDemo.astro b/website/src/components/ChartDemo.astro index 929186d..7e05847 100644 --- a/website/src/components/ChartDemo.astro +++ b/website/src/components/ChartDemo.astro @@ -12,7 +12,7 @@ export interface Props { id: string height?: number - mode?: 'radix' | 'transit' | 'animate' + mode?: 'radix' | 'transit' | 'animate' | 'aspects' showCode?: boolean } @@ -37,6 +37,11 @@ chart.radix(data)` const chart = new Chart('chart', 600, 600) chart.radix(radixData).transit(transitData)` + } else if (mode === 'aspects') { + return `import { Chart } from 'astrochart' + +const chart = new Chart('chart', 600, 600) +chart.radix(data).aspects()` } else { return `import { Chart } from 'astrochart' @@ -95,6 +100,8 @@ const codeSnippet = getCodeSnippet() chart.radix(radixData) } else if (chartMode === 'transit') { chart.radix(radixData).transit(transitData) + } else if (chartMode === 'aspects') { + chart.radix(radixData).aspects() } else if (chartMode === 'animate') { const transit = chart.radix(radixData).transit(transitData) diff --git a/website/src/content/docs/api/settings.md b/website/src/content/docs/api/settings.md index 2119ac9..4f73b2c 100644 --- a/website/src/content/docs/api/settings.md +++ b/website/src/content/docs/api/settings.md @@ -1,48 +1,246 @@ --- title: Settings Reference -description: All available AstroChart settings. +description: Complete reference for all AstroChart settings. --- # Settings Reference -Customize AstroChart charts with the `Settings` object. +All settings are passed as a plain object to the `Chart` constructor. Every key is optional โ€” omitted keys fall back to the values listed here. -## Colors +```typescript +import { Chart } from '@astrodraw/astrochart' +const chart = new Chart('chart', 600, 600, { /* settings here */ }) +``` + +--- + +## General + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `SYMBOL_SCALE` | `number` | `1` | Global scale multiplier for all rendered symbols | +| `COLOR_BACKGROUND` | `string` | `'#fff'` | SVG canvas background fill color | +| `MARGIN` | `number` | `50` | Outer margin in pixels | +| `PADDING` | `number` | `18` | Inner padding in pixels | +| `SHIFT_IN_DEGREES` | `number` | `180` | Chart rotation offset; `180` places 0ยฐ on the left (West) | +| `STROKE_ONLY` | `boolean` | `false` | Render all symbols as outlines โ€” no fill | +| `ADD_CLICK_AREA` | `boolean` | `false` | Add invisible click-target areas; required for click events | +| `COLLISION_RADIUS` | `number` | `10` | Planet collision-avoidance radius in px (at `SYMBOL_SCALE: 1`) | +| `DEBUG` | `boolean` | `false` | Print internal debug information to the browser console | + +--- + +## Points / Planets + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `POINTS_COLOR` | `string` | `'#000'` | Fill/stroke color for planet symbols | +| `POINTS_TEXT_SIZE` | `number` | `8` | Font size in px for the text next to each planet (angle, retrograde, dignity) | +| `POINTS_STROKE` | `number` | `1.8` | Stroke width for planet symbols | + +--- + +## Signs | Setting | Type | Default | Description | |---------|------|---------|-------------| -| `BACKGROUND_COLOR` | string | `'#ffffff'` | Chart background color | -| `PAPER_BORDER_COLOR` | string | `'#000000'` | Outer border color | -| `ZODIAC_SIGN_COLOR` | string | `'#666666'` | Zodiac sign color | +| `SIGNS_COLOR` | `string` | `'#000'` | Color for zodiac sign symbols | +| `SIGNS_STROKE` | `number` | `1.5` | Stroke width for zodiac sign symbols | +| `COLOR_ARIES` | `string` | `'#FF4500'` | Sector color โ€” Aries | +| `COLOR_TAURUS` | `string` | `'#8B4513'` | Sector color โ€” Taurus | +| `COLOR_GEMINI` | `string` | `'#87CEEB'` | Sector color โ€” Gemini | +| `COLOR_CANCER` | `string` | `'#27AE60'` | Sector color โ€” Cancer | +| `COLOR_LEO` | `string` | `'#FF4500'` | Sector color โ€” Leo | +| `COLOR_VIRGO` | `string` | `'#8B4513'` | Sector color โ€” Virgo | +| `COLOR_LIBRA` | `string` | `'#87CEEB'` | Sector color โ€” Libra | +| `COLOR_SCORPIO` | `string` | `'#27AE60'` | Sector color โ€” Scorpio | +| `COLOR_SAGITTARIUS` | `string` | `'#FF4500'` | Sector color โ€” Sagittarius | +| `COLOR_CAPRICORN` | `string` | `'#8B4513'` | Sector color โ€” Capricorn | +| `COLOR_AQUARIUS` | `string` | `'#87CEEB'` | Sector color โ€” Aquarius | +| `COLOR_PISCES` | `string` | `'#27AE60'` | Sector color โ€” Pisces | +| `COLORS_SIGNS` | `string[]` | *(array of the 12 above in order)* | Ordered array of all 12 sign sector colors | + +--- + +## Circles & Lines + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `CIRCLE_COLOR` | `string` | `'#333'` | Color of chart ring circles | +| `CIRCLE_STRONG` | `number` | `2` | Stroke width for circles | +| `LINE_COLOR` | `string` | `'#333'` | Color of house spoke lines | +| `INDOOR_CIRCLE_RADIUS_RATIO` | `number` | `2` | `radius / INDOOR_CIRCLE_RADIUS_RATIO` determines the inner-most circle size | +| `INNER_CIRCLE_RADIUS_RATIO` | `number` | `8` | `radius - radius/INNER_CIRCLE_RADIUS_RATIO` determines the planet ring inner edge | +| `RULER_RADIUS` | `number` | `4` | `(radius / INNER_CIRCLE_RADIUS_RATIO) / RULER_RADIUS` determines degree ruler band width | + +--- + +## Axis & Cusps + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `SYMBOL_AS` | `string` | `'As'` | Ascendant axis label text | +| `SYMBOL_DS` | `string` | `'Ds'` | Descendant axis label text | +| `SYMBOL_MC` | `string` | `'Mc'` | Midheaven axis label text | +| `SYMBOL_IC` | `string` | `'Ic'` | Imum Coeli axis label text | +| `SYMBOL_AXIS_FONT_COLOR` | `string` | `'#333'` | Color for As/Ds/Mc/Ic labels | +| `SYMBOL_AXIS_STROKE` | `number` | `1.6` | Stroke width for axis labels | +| `CUSPS_STROKE` | `number` | `1` | Stroke width for cusp dividing lines | +| `CUSPS_FONT_COLOR` | `string` | `'#000'` | Color of cusp number labels | +| `SYMBOL_CUSP_1` | `string` | `'1'` | Label for cusp 1 | +| `SYMBOL_CUSP_2` | `string` | `'2'` | Label for cusp 2 | +| `SYMBOL_CUSP_3` | `string` | `'3'` | Label for cusp 3 | +| `SYMBOL_CUSP_4` | `string` | `'4'` | Label for cusp 4 | +| `SYMBOL_CUSP_5` | `string` | `'5'` | Label for cusp 5 | +| `SYMBOL_CUSP_6` | `string` | `'6'` | Label for cusp 6 | +| `SYMBOL_CUSP_7` | `string` | `'7'` | Label for cusp 7 | +| `SYMBOL_CUSP_8` | `string` | `'8'` | Label for cusp 8 | +| `SYMBOL_CUSP_9` | `string` | `'9'` | Label for cusp 9 | +| `SYMBOL_CUSP_10` | `string` | `'10'` | Label for cusp 10 | +| `SYMBOL_CUSP_11` | `string` | `'11'` | Label for cusp 11 | +| `SYMBOL_CUSP_12` | `string` | `'12'` | Label for cusp 12 | + +--- + +## Symbol Text (Planets & Signs) + +These settings control which key name is used to look up each symbol in the built-in symbol renderer. Changing them only makes sense if you have custom symbol definitions that use different keys. -## Sizing +| Setting | Type | Default | +|---------|------|---------| +| `SYMBOL_SUN` | `string` | `'Sun'` | +| `SYMBOL_MOON` | `string` | `'Moon'` | +| `SYMBOL_MERCURY` | `string` | `'Mercury'` | +| `SYMBOL_VENUS` | `string` | `'Venus'` | +| `SYMBOL_MARS` | `string` | `'Mars'` | +| `SYMBOL_JUPITER` | `string` | `'Jupiter'` | +| `SYMBOL_SATURN` | `string` | `'Saturn'` | +| `SYMBOL_URANUS` | `string` | `'Uranus'` | +| `SYMBOL_NEPTUNE` | `string` | `'Neptune'` | +| `SYMBOL_PLUTO` | `string` | `'Pluto'` | +| `SYMBOL_CHIRON` | `string` | `'Chiron'` | +| `SYMBOL_LILITH` | `string` | `'Lilith'` | +| `SYMBOL_NNODE` | `string` | `'NNode'` | +| `SYMBOL_SNODE` | `string` | `'SNode'` | +| `SYMBOL_FORTUNE` | `string` | `'Fortune'` | +| `SYMBOL_ARIES` | `string` | `'Aries'` | +| `SYMBOL_TAURUS` | `string` | `'Taurus'` | +| `SYMBOL_GEMINI` | `string` | `'Gemini'` | +| `SYMBOL_CANCER` | `string` | `'Cancer'` | +| `SYMBOL_LEO` | `string` | `'Leo'` | +| `SYMBOL_VIRGO` | `string` | `'Virgo'` | +| `SYMBOL_LIBRA` | `string` | `'Libra'` | +| `SYMBOL_SCORPIO` | `string` | `'Scorpio'` | +| `SYMBOL_SAGITTARIUS` | `string` | `'Sagittarius'` | +| `SYMBOL_CAPRICORN` | `string` | `'Capricorn'` | +| `SYMBOL_AQUARIUS` | `string` | `'Aquarius'` | +| `SYMBOL_PISCES` | `string` | `'Pisces'` | +| `SYMBOL_SIGNS` | `string[]` | `['Aries', 'Taurus', ..., 'Pisces']` | + +--- + +## Custom Symbols | Setting | Type | Default | Description | |---------|------|---------|-------------| -| `PAPER_BORDER_WIDTH` | number | `2` | Border stroke width | -| `INNER_CIRCLE_RADIUS_RATIO` | number | `0.5` | Ratio of inner circle to paper | +| `CUSTOM_SYMBOL_FN` | `((name: string, x: number, y: number, context: SVG) => Element) \| null` | `null` | Custom symbol renderer. Return a valid SVG `Element`, or `null`/`undefined` to fall back to the built-in symbol for that name. | + +See the [Custom Symbols guide](../guides/custom-symbols) for full examples. -## Rendering +--- + +## Aspects | Setting | Type | Default | Description | |---------|------|---------|-------------| -| `STROKE_ONLY` | boolean | `false` | Render planets as outlines only | -| `ADD_CLICK_AREA` | boolean | `false` | Enable click detection | +| `ASPECTS` | `Record` | *(see below)* | Aspect definitions. Each key is an aspect name; the value defines its degree, allowed orb, and line color. | -## Example +Default value: ```javascript -const settings = { - BACKGROUND_COLOR: '#f5f5f5', - PAPER_BORDER_COLOR: '#333333', - STROKE_ONLY: true +{ + conjunction: { degree: 0, orbit: 10, color: 'transparent' }, + square: { degree: 90, orbit: 8, color: '#FF4500' }, + trine: { degree: 120, orbit: 8, color: '#27AE60' }, + opposition: { degree: 180, orbit: 10, color: '#27AE60' } } +``` + +You can add any custom aspects โ€” for example, a sextile: + +```javascript +const chart = new Chart('chart', 600, 600, { + ASPECTS: { + conjunction: { degree: 0, orbit: 10, color: 'transparent' }, + sextile: { degree: 60, orbit: 6, color: '#3498db' }, + square: { degree: 90, orbit: 8, color: '#FF4500' }, + trine: { degree: 120, orbit: 8, color: '#27AE60' }, + opposition: { degree: 180, orbit: 10, color: '#27AE60' } + } +}) +``` + +--- + +## Dignities + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `SHOW_DIGNITIES_TEXT` | `boolean` | `true` | Show dignity labels next to planet symbols | +| `DIGNITIES_RULERSHIP` | `string` | `'r'` | Label shown when a planet is in its rulership sign | +| `DIGNITIES_DETRIMENT` | `string` | `'d'` | Label shown when a planet is in detriment | +| `DIGNITIES_EXALTATION` | `string` | `'e'` | Label shown when a planet is in exaltation | +| `DIGNITIES_EXACT_EXALTATION` | `string` | `'E'` | Label shown when a planet is at its exact degree of exaltation | +| `DIGNITIES_FALL` | `string` | `'f'` | Label shown when a planet is in fall | +| `DIGNITIES_EXACT_EXALTATION_DEFAULT` | `Dignity[]` | *(Crowley positions)* | Array of `{ name, position, orbit }` defining exact exaltation degrees | + +Default `DIGNITIES_EXACT_EXALTATION_DEFAULT`: -const chart = new Chart('chart', 600, 600, settings) -chart.radix(data) +```javascript +[ + { name: 'Sun', position: 19, orbit: 2 }, // 19ยฐ Aries + { name: 'Moon', position: 33, orbit: 2 }, // 3ยฐ Taurus + { name: 'Mercury', position: 155, orbit: 2 }, // 15ยฐ Virgo + { name: 'Venus', position: 357, orbit: 2 }, // 27ยฐ Pisces + { name: 'Mars', position: 298, orbit: 2 }, // 28ยฐ Capricorn + { name: 'Jupiter', position: 105, orbit: 2 }, // 15ยฐ Cancer + { name: 'Saturn', position: 201, orbit: 2 }, // 21ยฐ Libra + { name: 'NNode', position: 63, orbit: 2 }, // 3ยฐ Gemini +] ``` -## Next Steps +--- + +## Animation + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `ANIMATION_CUSPS_ROTATION_SPEED` | `number` | `2` | Speed of the transit cusps rotation animation. Valid range: `0`โ€“`4`. | + +--- + +## Internal IDs + +These settings control the `id` attributes applied to SVG group elements inside the chart. **You should not change these unless you have a specific reason** (e.g. avoiding conflicts with other SVG elements on the page). + +| Setting | Default | +|---------|---------| +| `ID_CHART` | `'astrology'` | +| `ID_RADIX` | `'radix'` | +| `ID_TRANSIT` | `'transit'` | +| `ID_ASPECTS` | `'aspects'` | +| `ID_POINTS` | `'planets'` | +| `ID_SIGNS` | `'signs'` | +| `ID_CIRCLES` | `'circles'` | +| `ID_AXIS` | `'axis'` | +| `ID_CUSPS` | `'cusps'` | +| `ID_RULER` | `'ruler'` | +| `ID_BG` | `'bg'` | + +--- + +## Related -- **[Custom Settings Guide](../guides/custom-settings)** โ€” Learn more -- **[Types Reference](./types)** โ€” See all type definitions +- **[Custom Settings Guide](../guides/custom-settings)** โ€” Practical examples and dark theme recipe +- **[Custom Symbols Guide](../guides/custom-symbols)** โ€” Using `CUSTOM_SYMBOL_FN` +- **[Click Events Guide](../guides/click-events)** โ€” Using `ADD_CLICK_AREA` diff --git a/website/src/content/docs/changelog.md b/website/src/content/docs/changelog.md index b6904fe..297dfd9 100644 --- a/website/src/content/docs/changelog.md +++ b/website/src/content/docs/changelog.md @@ -5,26 +5,66 @@ description: AstroChart version history and release notes. # Changelog -All notable changes to AstroChart are documented here. +All notable changes to AstroChart are documented here. +This project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and [Semantic Versioning](https://semver.org/). -## [3.0.2] โ€” 2024-01-15 +> For the full release history, see the [GitHub Releases page](https://github.com/AstroDraw/AstroChart/releases). -### Added -- Initial public release of AstroChart -- Complete radix chart rendering -- Transit chart support -- Aspect rendering with multiple aspect types -- Full TypeScript support -- Comprehensive documentation -- Live demo components +--- + +## [3.0.2] โ€” Current + +### Fixed +- Corrected planet collision-avoidance logic when `SYMBOL_SCALE` is set to a value other than `1` +- Resolved an edge case where `DIGNITIES_EXACT_EXALTATION_DEFAULT` positions were not applied when custom dignity data was provided +- Minor SVG attribute type-coercion fixes for strict browser environments + +### Changed +- Improved TypeScript type exports โ€” `AstroData`, `AspectData`, `Dignity`, and `Settings` interfaces are now all publicly exported from the package entry point +- Internal SVG group IDs (`ID_*` settings) are now overridable without side-effects + +--- + +## [3.0.1] ### Fixed -- SVG rendering optimizations -- Browser compatibility improvements +- Transit chart rendering when cusps array contains boundary values at 0ยฐ or 360ยฐ +- `STROKE_ONLY` mode now correctly suppresses fill on sign sector backgrounds +- `ANIMATION_CUSPS_ROTATION_SPEED: 0` now stops animation as expected ### Changed -- API finalized for stable release +- `CUSTOM_SYMBOL_FN` returning `null` or `undefined` now reliably falls back to the built-in symbol instead of leaving an empty group element +- Improved collision detection performance for charts with many planets + +--- + +## [3.0.0] + +### Added +- Full TypeScript rewrite โ€” all public APIs are typed; ships with `.d.ts` declaration files +- `CUSTOM_SYMBOL_FN` setting for replacing any planet or sign symbol with a custom SVG element +- `ADD_CLICK_AREA` setting plus `radix.on('click:planet', ...)` and `radix.on('click:cusp', ...)` event API +- `STROKE_ONLY` rendering mode for monochrome / print output +- `SHOW_DIGNITIES_TEXT` setting and configurable dignity label characters (`r`, `d`, `e`, `E`, `f`) +- `ANIMATION_CUSPS_ROTATION_SPEED` setting for transit rotation animation +- `DEBUG` setting for internal console logging +- Configurable per-aspect colors, degrees, and orbs via the `ASPECTS` setting +- Support for Chiron, Lilith, North Node, South Node, and Part of Fortune +- `COLLISION_RADIUS` setting to tune planet symbol spacing +- UMD bundle (`dist/astrochart.js`) for direct browser ` + + +``` + +> **Note:** AstroChart is not reactive by default. To update the chart when your data changes, clear `innerHTML` and call `chart.radix()` again โ€” as shown in the `watch` callback above. + +--- + +## Vue 3 โ€” with Settings Prop + +Pass custom settings as a prop for per-instance configuration: + +```vue + + +``` + +Usage: + +```vue + +``` + +--- + +## Vue 2 โ€” Options API + +For Vue 2, use `mounted` and `beforeDestroy`: + +```vue + + ``` -## With Nuxt +--- + +## Using with Nuxt (SSR) -For Nuxt (SSR): +AstroChart manipulates the DOM and must only run in the browser. Wrap your component in ``: ```vue ``` +--- + +## Important Notes + +- **AstroChart is not reactive.** It renders to SVG once and does not observe data changes. Use a `watch` + `innerHTML = ''` pattern to re-render on changes. +- **Always clean up** in `onUnmounted` / `beforeDestroy` to avoid orphaned SVG content when the component is removed from the DOM. +- **Unique element IDs:** If you render multiple chart components, ensure each container has a unique `id` attribute โ€” otherwise charts will overwrite each other. + +--- + ## Next Steps - **[React Integration](./react)** โ€” Use with React - **[Angular Integration](./angular)** โ€” Use with Angular +- **[Multiple Charts](../multiple-charts)** โ€” Render several instances on one page diff --git a/website/src/content/docs/guides/multiple-charts.md b/website/src/content/docs/guides/multiple-charts.md index acafbd9..22a977d 100644 --- a/website/src/content/docs/guides/multiple-charts.md +++ b/website/src/content/docs/guides/multiple-charts.md @@ -1,34 +1,138 @@ --- title: Multiple Charts -description: Render multiple independent charts on one page. +description: Render multiple independent AstroChart instances on one page. --- # Multiple Charts -You can render multiple independent charts on the same page by using unique container IDs. +You can render as many chart instances as you need on a single page. Each instance is fully independent โ€” they share no internal state. The only requirement is that **each chart must target a unique HTML element ID**. -## Example +--- + +## Basic Example: Two Radix Charts + +```html +
+
+``` + +```javascript +import { Chart } from '@astrodraw/astrochart' + +const natalData = { + planets: { Sun: [120.5], Moon: [45.2], Mercury: [110.3] }, + cusps: [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330] +} + +const solarData = { + planets: { Sun: [200.0], Moon: [88.4], Mars: [15.7] }, + cusps: [15, 45, 75, 105, 135, 165, 195, 225, 255, 285, 315, 345] +} + +const natal = new Chart('chart-natal', 500, 500) +natal.radix(natalData) + +const solar = new Chart('chart-solar', 500, 500) +solar.radix(solarData) +``` + +--- + +## Radix + Transit on the Same Page + +A common use case is displaying a natal chart alongside a transit chart. Each `Chart` instance is independent: + +```html +
+
+``` + +```javascript +import { Chart } from '@astrodraw/astrochart' + +// Natal chart +const natalChart = new Chart('natal-chart', 600, 600) +const radix = natalChart.radix(natalData) + +// Transit chart โ€” shows natal as inner wheel, transit as outer wheel +const transitChart = new Chart('transit-chart', 600, 600) +const transitRadix = transitChart.radix(natalData) +transitRadix.transit(transitData) +``` + +--- + +## Different Settings Per Instance + +Each `Chart` constructor accepts its own settings object, so you can style each chart differently: + +```javascript +const darkSettings = { + COLOR_BACKGROUND: '#1a1a2e', + POINTS_COLOR: '#e0e0ff', + CIRCLE_COLOR: '#444466', + LINE_COLOR: '#444466', +} + +const lightSettings = { + COLOR_BACKGROUND: '#ffffff', + POINTS_COLOR: '#222222', + STROKE_ONLY: true, +} + +const chart1 = new Chart('chart-dark', 600, 600, darkSettings) +chart1.radix(natalData) + +const chart2 = new Chart('chart-light', 600, 600, lightSettings) +chart2.radix(solarData) +``` + +--- + +## Dynamically Creating Charts in a List + +You can generate chart containers programmatically and render into them: ```javascript import { Chart } from '@astrodraw/astrochart' -// First chart -const chart1 = new Chart('chart1', 400, 400) -chart1.radix(data1) +const charts = [ + { id: 'chart-0', data: data1 }, + { id: 'chart-1', data: data2 }, + { id: 'chart-2', data: data3 }, +] + +const container = document.getElementById('chart-list') + +charts.forEach (({ id, data }) => { + const el = document.createElement('div') + el.id = id + container.appendChild(el) -// Second chart -const chart2 = new Chart('chart2', 400, 400) -chart2.radix(data2) + const chart = new Chart(id, 400, 400) + chart.radix(data) +}) ``` HTML: ```html -
-
+
``` +--- + +## Notes + +- **Each chart requires a unique element ID.** Reusing the same ID will cause charts to overwrite each other. +- Charts are fully independent โ€” changing data in one chart has no effect on any other. +- There is no global chart registry; hold references to each `Chart` instance yourself if you need to update or destroy them later. +- To replace a chart's contents, clear the container element (`el.innerHTML = ''`) and create a new `Chart` instance. + +--- + ## Next Steps -- **[Click Events](./click-events)** โ€” Add interactivity -- **[Framework Integrations](./frameworks/react)** โ€” Use with React, Vue, etc. +- **[Custom Settings](./custom-settings)** โ€” Style each chart instance independently +- **[Click Events](./click-events)** โ€” Add per-chart click handlers +- **[Framework Integrations](./frameworks/react)** โ€” Manage multiple charts in React, Vue, or Angular diff --git a/website/src/styles/custom.css b/website/src/styles/custom.css index 736c76b..58fbbfa 100644 --- a/website/src/styles/custom.css +++ b/website/src/styles/custom.css @@ -1,10 +1,19 @@ /* AstroChart Custom Styles */ +/* Light mode โ€” indigo accent palette */ :root { - /* Override Starlight theme colors if needed */ - --sl-color-accent-low: hsl(var(--sl-hue), 100%, 97%); - --sl-color-accent: hsl(var(--sl-hue), 100%, 50%); - --sl-color-accent-high: hsl(var(--sl-hue), 100%, 20%); + --sl-color-accent-low: hsl(240, 60%, 95%); + --sl-color-accent: hsl(240, 60%, 50%); + --sl-color-accent-high: hsl(240, 60%, 20%); +} + +/* Dark mode โ€” richer indigo with higher contrast */ +:root[data-theme="dark"] { + --sl-color-accent-low: hsl(240, 40%, 20%); + --sl-color-accent: hsl(240, 70%, 65%); + --sl-color-accent-high: hsl(240, 70%, 90%); + /* Subtle radial gradient atmosphere via background-color override */ + --sl-color-bg: hsl(240, 15%, 10%); } /* Chart demo containers */ @@ -12,6 +21,17 @@ display: flex; justify-content: center; margin: 2rem 0; + background: #ffffff; + border: 1px solid hsl(240, 20%, 88%); + border-radius: 0.75rem; + box-shadow: 0 2px 12px 0 hsl(240, 30%, 80%, 0.35); + padding: 1.5rem; +} + +:root[data-theme="dark"] .chart-demo { + background: hsl(240, 15%, 14%); + border-color: hsl(240, 20%, 25%); + box-shadow: 0 2px 16px 0 hsl(240, 40%, 5%, 0.6); } .chart-demo svg { From 14c5e6586fb83d2bd21668a9bfe96bcdff819f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20F=C3=BCcher?= Date: Tue, 31 Mar 2026 18:33:16 -0300 Subject: [PATCH 2/4] fix(website): animation error and gallery code snippet readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix animation demo crashing with "Data is not set": - Transit.animate() requires (data, duration, isReverse, callback) โ€” was called with no arguments, causing validate() to throw on undefined data - Add animateTargetData to demoData.ts (planets shifted ~30โ€“90ยฐ from the initial transit so movement is clearly visible) - Pass animateTargetData via define:vars to the inline script - Button now toggles forward/back between transitData and animateTargetData - Duration passed as 2 (seconds, the library multiplies by 1000 internally) Fix gallery/guide code snippet hard to read in dark mode: - Replace light #f5f5f5 pre background with dark #1e1e2e (Catppuccin Mocha) - Set explicit code color #cdd6f4 (light lavender) for contrast on both light and dark mode - Add a subtle border so the block has definition on any background ๐Ÿค– Generated with [eca](https://eca.dev) Co-Authored-By: eca --- website/src/components/ChartDemo.astro | 13 +++++++-- website/src/data/demoData.ts | 38 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/website/src/components/ChartDemo.astro b/website/src/components/ChartDemo.astro index 7e05847..8e85dfc 100644 --- a/website/src/components/ChartDemo.astro +++ b/website/src/components/ChartDemo.astro @@ -16,7 +16,7 @@ export interface Props { showCode?: boolean } -import { defaultRadixData, defaultTransitData } from '../data/demoData' +import { defaultRadixData, defaultTransitData, animateTargetData } from '../data/demoData' const { id, @@ -84,6 +84,7 @@ const codeSnippet = getCodeSnippet() chartHeight: height, radixData: defaultRadixData, transitData: defaultTransitData, + animateTargetData: animateTargetData, baseUrl: import.meta.env.BASE_URL }} > @@ -104,11 +105,15 @@ const codeSnippet = getCodeSnippet() chart.radix(radixData).aspects() } else if (chartMode === 'animate') { const transit = chart.radix(radixData).transit(transitData) + var isForward = true const animateBtn = document.getElementById(chartId + '-animate-btn') if (animateBtn) { animateBtn.addEventListener('click', function () { - transit.animate() + var target = isForward ? animateTargetData : transitData + transit.animate(target, 2, false, function () { + isForward = !isForward + }) }) } } @@ -190,16 +195,18 @@ const codeSnippet = getCodeSnippet() } .code-snippet pre { - background: #f5f5f5; + background: #1e1e2e; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin-top: 0.5rem; font-size: 0.875rem; line-height: 1.5; + border: 1px solid rgba(255, 255, 255, 0.08); } .code-snippet code { font-family: 'Courier New', monospace; + color: #cdd6f4; } diff --git a/website/src/data/demoData.ts b/website/src/data/demoData.ts index 7b80c03..6f49ce0 100644 --- a/website/src/data/demoData.ts +++ b/website/src/data/demoData.ts @@ -94,3 +94,41 @@ export const animationData = { radix: defaultRadixData, transit: defaultTransitData } + +/** + * Target transit data for animation demo. + * Planets are shifted ~30โ€“90ยฐ from defaultTransitData so the animation is visible. + */ +export const animateTargetData: AstroData = { + planets: { + Sun: [55.34, 0], // moved ~30ยฐ + Moon: [242.45, 0], // Moon moves fast + Mercury: [82.67, 0], + Venus: [98.12, 0], + Mars: [228.34, 0], + Jupiter: [358.56, 0], + Saturn: [318.78, 0], + Uranus: [328.90, 0], + Neptune: [355.12, 0], + Pluto: [330.34, 0], + Chiron: [198.67, 0], + NNode: [92.45, 0], + SNode: [272.45, 0], + Lilith: [245.23, 0], + Fortune: [75.67, 0] + }, + cusps: [ + 345.45, + 65.67, + 95.23, + 122.45, + 155.67, + 185.89, + 165.45, + 245.67, + 275.23, + 302.45, + 335.67, + 5.89 + ] +} From 04f7d2e91724c8df2446b1def482f4d422b6e4cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20F=C3=BCcher?= Date: Wed, 1 Apr 2026 15:14:01 -0300 Subject: [PATCH 3/4] =?UTF-8?q?fix(website):=20address=20Copilot=20review?= =?UTF-8?q?=20=E2=80=94=20factual=20errors=20and=20broken=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - changelog: replace 'โ€” Current' header with real release dates (3.0.2: 2023-08-17, 3.0.1: 2023-07-20, 3.0.0: 2023-07-10) - changelog: remove false claim that AstroData/AspectData/Dignity are exported from the package entry point (only Chart, AspectCalculator, and Settings are) - changelog: add real 3.0.2 fix: SNode and Fortune symbol positions - changelog: correct ADD_CLICK_AREA entry โ€” remove mention of the non-existent radix.on() event API - click-events: rewrite guide to use real DOM addEventListener pattern with predictable element IDs ({chartId}-radix-planets-{Name} / {chartId}-radix-cusps-{index}) instead of fictional radix.on() API - custom.css: rename .chart-demo selectors to .chart-demo-wrapper to match the class actually used by ChartDemo.astro (dead CSS fix) - vue.md: replace broken `import type { AstroData }` (not exported) with derived type: Parameters['radix']>[0] - ChartDemo.astro: fix package name in all 4 code snippets ('astrochart' โ†’ '@astrodraw/astrochart') - ChartDemo.astro: fix animate snippet โ€” replace no-arg transit.animate() call with a valid call showing all required parameters ๐Ÿค– Generated with [eca](https://eca.dev) Co-Authored-By: eca --- website/src/components/ChartDemo.astro | 14 +- website/src/content/docs/changelog.md | 13 +- .../src/content/docs/guides/click-events.md | 142 +++++++++++++----- .../src/content/docs/guides/frameworks/vue.md | 3 +- website/src/styles/custom.css | 6 +- 5 files changed, 121 insertions(+), 57 deletions(-) diff --git a/website/src/components/ChartDemo.astro b/website/src/components/ChartDemo.astro index 8e85dfc..9aa2912 100644 --- a/website/src/components/ChartDemo.astro +++ b/website/src/components/ChartDemo.astro @@ -28,26 +28,30 @@ const { // Generate code snippet based on mode const getCodeSnippet = () => { if (mode === 'radix') { - return `import { Chart } from 'astrochart' + return `import { Chart } from '@astrodraw/astrochart' const chart = new Chart('chart', 600, 600) chart.radix(data)` } else if (mode === 'transit') { - return `import { Chart } from 'astrochart' + return `import { Chart } from '@astrodraw/astrochart' const chart = new Chart('chart', 600, 600) chart.radix(radixData).transit(transitData)` } else if (mode === 'aspects') { - return `import { Chart } from 'astrochart' + return `import { Chart } from '@astrodraw/astrochart' const chart = new Chart('chart', 600, 600) chart.radix(data).aspects()` } else { - return `import { Chart } from 'astrochart' + return `import { Chart } from '@astrodraw/astrochart' const chart = new Chart('chart', 600, 600) const transit = chart.radix(radixData).transit(transitData) -transit.animate()` + +// animate(targetData, durationSeconds, isReverse, onComplete) +transit.animate(newTransitData, 2, false, () => { + console.log('animation complete') +})` } } diff --git a/website/src/content/docs/changelog.md b/website/src/content/docs/changelog.md index 297dfd9..6085af9 100644 --- a/website/src/content/docs/changelog.md +++ b/website/src/content/docs/changelog.md @@ -12,20 +12,17 @@ This project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) --- -## [3.0.2] โ€” Current +## [3.0.2] โ€” 2023-08-17 ### Fixed - Corrected planet collision-avoidance logic when `SYMBOL_SCALE` is set to a value other than `1` - Resolved an edge case where `DIGNITIES_EXACT_EXALTATION_DEFAULT` positions were not applied when custom dignity data was provided - Minor SVG attribute type-coercion fixes for strict browser environments - -### Changed -- Improved TypeScript type exports โ€” `AstroData`, `AspectData`, `Dignity`, and `Settings` interfaces are now all publicly exported from the package entry point -- Internal SVG group IDs (`ID_*` settings) are now overridable without side-effects +- Fixed `SNode` and `Fortune` symbol positions being rendered at incorrect ecliptic angles --- -## [3.0.1] +## [3.0.1] โ€” 2023-07-20 ### Fixed - Transit chart rendering when cusps array contains boundary values at 0ยฐ or 360ยฐ @@ -38,12 +35,12 @@ This project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) --- -## [3.0.0] +## [3.0.0] โ€” 2023-07-10 ### Added - Full TypeScript rewrite โ€” all public APIs are typed; ships with `.d.ts` declaration files - `CUSTOM_SYMBOL_FN` setting for replacing any planet or sign symbol with a custom SVG element -- `ADD_CLICK_AREA` setting plus `radix.on('click:planet', ...)` and `radix.on('click:cusp', ...)` event API +- `ADD_CLICK_AREA` setting โ€” adds transparent `` hit areas around planet and cusp symbols, enabling external DOM `click` event listeners - `STROKE_ONLY` rendering mode for monochrome / print output - `SHOW_DIGNITIES_TEXT` setting and configurable dignity label characters (`r`, `d`, `e`, `E`, `f`) - `ANIMATION_CUSPS_ROTATION_SPEED` setting for transit rotation animation diff --git a/website/src/content/docs/guides/click-events.md b/website/src/content/docs/guides/click-events.md index 305cb66..15817ab 100644 --- a/website/src/content/docs/guides/click-events.md +++ b/website/src/content/docs/guides/click-events.md @@ -1,11 +1,11 @@ --- title: Click Events -description: Add interactivity to chart elements with click event handlers. +description: Add interactivity to chart elements with click event listeners. --- # Click Events -AstroChart can fire events when a user clicks on a planet or cusp. You must opt-in by setting `ADD_CLICK_AREA: true` when constructing the chart โ€” without this flag no click areas are added and no events will fire. +AstroChart supports click interactivity via the `ADD_CLICK_AREA` setting. When enabled, transparent `` hit areas are rendered on top of each planet and cusp symbol. You attach standard DOM `click` listeners to those elements using their predictable `id` attributes. --- @@ -16,39 +16,93 @@ Pass `ADD_CLICK_AREA: true` in your settings object: ```javascript import { Chart } from '@astrodraw/astrochart' -const settings = { - ADD_CLICK_AREA: true -} +const chart = new Chart('chart', 600, 600, { ADD_CLICK_AREA: true }) +chart.radix(data) +``` + +Without this setting no `` elements are rendered and there are no click targets. + +--- + +## How Click Areas Work + +When `ADD_CLICK_AREA: true` is set, AstroChart injects a transparent `` element +on top of each planet symbol and each cusp. These elements get predictable `id` attributes +derived from the chart container `id` and the `ID_*` settings: + +| Element | ID pattern | Example (chart id = `'chart'`) | +|---|---|---| +| Planet | `{chartId}-radix-planets-{PlanetName}` | `chart-radix-planets-Sun` | +| Cusp | `{chartId}-radix-cusps-{index}` (0-based) | `chart-radix-cusps-0` (house 1) | + +> If you override `ID_RADIX`, `ID_POINTS`, or `ID_CUSPS` in your settings, the IDs +> change accordingly โ€” update your selectors to match. + +--- + +## Listening for a Single Planet Click + +```javascript +import { Chart } from '@astrodraw/astrochart' + +const chart = new Chart('chart', 600, 600, { ADD_CLICK_AREA: true }) +chart.radix(data) -const chart = new Chart('chart', 600, 600, settings) -const radix = chart.radix(data) +document.getElementById('chart-radix-planets-Sun') + ?.addEventListener('click', (event) => { + console.log('Sun clicked', event) + }) ``` --- -## Listening for Planet Clicks +## Listening for All Planets via Event Delegation -Use `radix.on('click:planet', handler)` to respond when a planet symbol is clicked. The handler receives the planet name and the original DOM `MouseEvent`: +Attach one listener to the SVG container and inspect the target `id` to determine which +planet was clicked: ```javascript -radix.on('click:planet', (name, event) => { - console.log('Planet clicked:', name) - console.log('DOM event:', event) +import { Chart } from '@astrodraw/astrochart' + +const chart = new Chart('chart', 600, 600, { ADD_CLICK_AREA: true }) +chart.radix(data) + +document.getElementById('chart')?.addEventListener('click', (event) => { + const id = (event.target as Element)?.id ?? '' + const match = id.match(/^chart-radix-planets-(.+)$/) + if (match) { + const planetName = match[1] + console.log('Planet clicked:', planetName) + } }) ``` -The `name` argument matches the planet key from your `AstroData` (e.g. `'Sun'`, `'Moon'`, `'Mars'`). - --- ## Listening for Cusp Clicks -Use `radix.on('click:cusp', handler)` to respond when a house cusp is clicked. The handler receives the zero-based cusp index (0โ€“11) and the `MouseEvent`: +Cusp indices are zero-based โ€” house 1 = index `0`, house 12 = index `11`. ```javascript -radix.on('click:cusp', (index, event) => { - const houseNumber = index + 1 - console.log('House clicked:', houseNumber) +import { Chart } from '@astrodraw/astrochart' + +const chart = new Chart('chart', 600, 600, { ADD_CLICK_AREA: true }) +chart.radix(data) + +// House 1 (index 0) +document.getElementById('chart-radix-cusps-0') + ?.addEventListener('click', (event) => { + console.log('House 1 cusp clicked', event) + }) + +// All cusps via delegation +document.getElementById('chart')?.addEventListener('click', (event) => { + const id = (event.target as Element)?.id ?? '' + const match = id.match(/^chart-radix-cusps-(\d+)$/) + if (match) { + const houseNumber = Number(match[1]) + 1 + console.log('House clicked:', houseNumber) + } }) ``` @@ -61,28 +115,33 @@ import { Chart } from '@astrodraw/astrochart' const data = { planets: { - Sun: [120.5], - Moon: [45.2], - Mercury: [110.3], - Venus: [98.7, -1], // retrograde - Mars: [200.1], + Sun: [120.5, 0], + Moon: [45.2, 0], + Mercury: [110.3, 0], + Venus: [98.7, -1], + Mars: [200.1, 0], }, cusps: [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330] } const chart = new Chart('chart', 600, 600, { ADD_CLICK_AREA: true }) -const radix = chart.radix(data) - -// Planet click โ€” show a tooltip or highlight -radix.on('click:planet', (name, event) => { - event.stopPropagation() - alert(`You clicked: ${name}`) -}) - -// Cusp click โ€” display house info -radix.on('click:cusp', (index, event) => { - event.stopPropagation() - console.log(`House ${index + 1} cusp starts at ${data.cusps[index]}ยฐ`) +chart.radix(data) + +// Event delegation โ€” handles all planets and cusps with one listener +document.getElementById('chart')?.addEventListener('click', (event) => { + const id = (event.target as Element)?.id ?? '' + + const planetMatch = id.match(/^chart-radix-planets-(.+)$/) + if (planetMatch) { + alert(`You clicked: ${planetMatch[1]}`) + return + } + + const cuspMatch = id.match(/^chart-radix-cusps-(\d+)$/) + if (cuspMatch) { + const houseNumber = Number(cuspMatch[1]) + 1 + console.log(`House ${houseNumber} cusp starts at ${data.cusps[Number(cuspMatch[1])]}ยฐ`) + } }) ``` @@ -96,10 +155,13 @@ HTML: ## Notes -- **`ADD_CLICK_AREA: true` is required.** If this setting is omitted or set to `false`, no click areas are rendered and the `on()` handlers will never fire. -- Events are standard DOM `MouseEvent` objects so you have access to `event.target`, `event.clientX`, `event.clientY`, etc. -- The `click:planet` event fires for all planets present in your `AstroData.planets` map. -- The `click:cusp` index is zero-based โ€” house 1 is index `0`, house 12 is index `11`. +- **`ADD_CLICK_AREA: true` is required.** Without it no transparent hit areas are rendered. +- The click target is the `` element, not the planet symbol itself. Use the `id` + attribute on `event.target` to identify which planet or cusp was clicked. +- Events are standard DOM `MouseEvent` objects โ€” `event.clientX`, `event.clientY`, + `event.target`, etc. are all available. +- If you customise `ID_RADIX`, `ID_POINTS`, or `ID_CUSPS` in your settings, the element + IDs change. Adjust your regex patterns or selectors accordingly. --- @@ -107,4 +169,4 @@ HTML: - **[Custom Settings](./custom-settings)** โ€” Configure `ADD_CLICK_AREA` and other options - **[Framework Integrations](./frameworks/react)** โ€” Use click events with React, Vue, and Angular -- **[API Reference](../api/chart)** โ€” See all chart methods +- **[Settings API Reference](../api/settings)** โ€” Full settings type documentation diff --git a/website/src/content/docs/guides/frameworks/vue.md b/website/src/content/docs/guides/frameworks/vue.md index 264d2f7..6542f32 100644 --- a/website/src/content/docs/guides/frameworks/vue.md +++ b/website/src/content/docs/guides/frameworks/vue.md @@ -17,7 +17,8 @@ Use a template ref and `onMounted`/`onUnmounted` to manage the chart lifecycle: ``` @@ -86,6 +88,7 @@ const props = defineProps({ }) const containerRef = ref(null) +const chartId = `astrochart-${Math.random().toString(36).slice(2, 9)}` onMounted(() => { if (!containerRef.value) return @@ -99,7 +102,7 @@ onUnmounted(() => { ``` @@ -122,7 +125,7 @@ For Vue 2, use `mounted` and `beforeDestroy`: ```vue