### Install chart2txt using npm Source: https://github.com/simpolism/chart2txt/blob/master/README.md Installs the chart2txt library using npm. This is the first step to using the library in your project. ```bash npm install chart2txt ``` -------------------------------- ### Install, Test, and Build Project Dependencies (Bash) Source: https://github.com/simpolism/chart2txt/blob/master/README.md This snippet provides essential bash commands for managing the chart2txt project. It covers installing project dependencies using npm, running automated tests, and building the library for distribution. ```bash # Install dependencies npm install # Run tests npm test # Build the library npm run build ``` -------------------------------- ### Process Transit Data (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Processes transit data by first obtaining the transit location from user input and performing geocoding. It then calls an API to get planetary positions for the transit. Returns transit data or null if location or API calls fail. Dependencies include `geocodeLocation` and `getPlanetaryPositions`. ```javascript async function processTransitData(houseSystem) { const transitLocation = transitLocationInput.value.trim(); if (!transitLocation) { transitLocationError.textContent = 'Please enter a location for transits.'; return null; } const coordinatesTransit = await geocodeLocation(transitLocation, transitLocationError); if (!coordinatesTransit) { return null; } // Further processing for transit data would follow here, likely involving getPlanetaryPositions ``` -------------------------------- ### Handle Transit Date and Time Input (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This function processes user input for transit date and time, creating a timestamp. It handles cases where input is missing or invalid, defaulting to the current time. It then calls an API to get planetary positions for the specified transit. ```javascript function processTransitInput(transitDateInput, transitHoursInput, transitMinutesInput, transitTimestamp, transitLocation, coordinatesTransit, houseSystem, transitLocationError) { let transitDate = transitDateInput.value; let transitHours = parseInt(transitHoursInput.value); let transitMinutes = parseInt(transitMinutesInput.value); if (transitDate && !isNaN(transitHours) && !isNaN(transitMinutes)) { transitTimestamp = new Date(`${transitDate}T${transitHours.toString().padStart(2, '0')}:${transitMinutes.toString().padStart(2, '0')}:00`); } else { transitDate = `${transitTimestamp.getFullYear()}-${(transitTimestamp.getMonth() + 1).toString().padStart(2, '0')}-${transitTimestamp.getDate().toString().padStart(2, '0')}`; transitHours = transitTimestamp.getHours(); transitMinutes = transitTimestamp.getMinutes(); } const transitTimeString = `${transitHours.toString().padStart(2, '0')}:${transitMinutes.toString().padStart(2, '0')}:00`; const apiDataTransit = await getPlanetaryPositions(transitDate, transitTimeString, coordinatesTransit.latitude, coordinatesTransit.longitude, houseSystem, transitLocationError); if (!apiDataTransit) { return null; } return { name: `Transits for ${transitDate} at ${transitLocation}`, planets: apiDataTransit.planets.map(({ name, longitude, speed }) => ({ name, degree: longitude, speed })), ascendant: apiDataTransit.ascendant, midheaven: apiDataTransit.midheaven, points: apiDataTransit.points || [], houseCusps: apiDataTransit.houseCusps, location: transitLocation, timestamp: transitTimestamp, chartType: 'transit' }; } ``` -------------------------------- ### Get All Chart Field IDs for Persistence (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Collects all input field IDs associated with the current charts. This list is used for saving and loading form data, ensuring all relevant user inputs are captured. ```javascript function getAllChartFieldIds() { const fieldIds = [] charts.forEach(chart => { fieldIds.push( `name_${chart.id}`, `isEvent_${chart.id}`, `birthdate_${chart.id}`, `hours_${chart.id}`, `minutes_${chart.id}`, `loca` ) }) return fieldIds } ``` -------------------------------- ### Process Individual Chart Data (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Processes data for an individual astrological chart, including fetching user inputs for name, birthdate, time, and location. It uses geocoding to get coordinates and then retrieves planetary positions via an API. Returns a structured object with chart details or null if errors occur. Dependencies include `geocodeLocation` and `getPlanetaryPositions`. ```javascript async function processChart(chart, houseSystem) { const nameInput = document.getElementById(`name_${chart.id}`); const isEventInput = document.getElementById(`isEvent_${chart.id}`); const birthdateInput = document.getElementById(`birthdate_${chart.id}`); const hoursInput = document.getElementById(`hours_${chart.id}`); const minutesInput = document.getElementById(`minutes_${chart.id}`); const locationInput = document.getElementById(`location_${chart.id}`); const locationError = document.getElementById(`locationError_${chart.id}`); const name = nameInput.value.trim(); const isEvent = isEventInput.checked; const birthdate = birthdateInput.value; const hours = parseInt(hoursInput.value); const minutes = parseInt(minutesInput.value); const location = locationInput.value.trim(); if (!birthdate || isNaN(hours) || isNaN(minutes) || !location) { locationError.textContent = `Chart ${chart.number}: Please fill all required date, time, and location fields.`; return null; } const coordinates = await geocodeLocation(location, locationError); if (!coordinates) { return null; } const timeString = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`; const apiData = await getPlanetaryPositions(birthdate, timeString, coordinates.latitude, coordinates.longitude, houseSystem, locationError); if (!apiData) { return null; } return { name: name || `Chart ${chart.number}`, planets: apiData.planets.map(({ name, longitude, speed }) => ({ name, degree: longitude, speed })), ascendant: apiData.ascendant, midheaven: apiData.midheaven, points: apiData.points || [], houseCusps: apiData.houseCusps, location: location, timestamp: new Date(`${apiData.date.replace(/-/g, '/')} ${apiData.time.replace(/-/g, ':')}`), chartType: isEvent ? 'event' : 'natal', }; } ``` -------------------------------- ### Convert Astrological Chart to Text Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This functionality converts an astrological chart into a textual representation. It is a core feature of the project, enabling users to get a text-based output of their chart data. No specific dependencies are mentioned, and the input is an astrological chart, with the output being its text equivalent. -------------------------------- ### Get UI Categories for Aspect Thresholds (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Reads the user-defined aspect categories and their orb thresholds from the UI. It returns an array of objects, where each object represents a category with a 'label' and 'orb' value, sorted by the orb value. This function is crucial for retrieving the current threshold configuration. ```javascript /** * Reads the user-defined aspect categories and their orb thresholds from the UI. * @returns {Array} An array of category objects, sorted by orb. * Example: [{ label: 'TIGHT', orb: 2.0 }, { label: 'MODERATE', orb: 4.0 }] */ function getUiCategories() { const categories = []; const rows = aspectThresholdsList.querySelectorAll('.aspect-strength-row'); rows.forEach(row => { const labelInput = row.querySelector('input[data-field="label"]'); const orbInput = row.querySelector('input[data-field="orb"]'); if (labelInput && orbInput) { const label = labelInput.value.trim(); const orb = parseFloat(orbInput.value); if (label && !isNaN(orb)) { categories.push({ label: label, orb: orb }); } } }); // Sort by orb value categories.sort((a, b) => a.orb - b.orb); return categories; } ``` -------------------------------- ### Initialize Charts from Local Storage (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Initializes the chart interface by loading saved chart data from local storage. If no saved data is found, it creates the first chart. This function ensures that user progress is maintained across sessions. ```javascript function initializeCharts() { // Load chart structure first const savedChartStructure = localStorage.getItem('chartStructure'); const savedChartCounter = localStorage.getItem('chartCounter'); if (savedChartStructure && savedChartCounter) { const savedCharts = JSON.parse(savedChartStructure); chartCounter = parseInt(savedChartCounter); // Recreate charts with their original IDs savedCharts.forEach(savedChart => { recreateChart(savedChart.id, savedChart.number); }); } else { // Create first chart if no saved structure addChart(true); // skipSave = true } // Load form data after all charts are created loadFormData(); } ``` -------------------------------- ### Initialize Application and Restore Mode Preference (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This code snippet initializes the application by calling the `initializeCharts()` function. It then checks local storage for a saved display mode preference ('chartMode'). If 'humandesign' is found, it sets the application to that mode using the `setMode` function. ```javascript // Initialize the application initializeCharts(); // Restore saved mode preference const savedMode = localStorage.getItem('chartMode'); if (savedMode === 'humandesign') { setMode('humandesign'); } ``` -------------------------------- ### Initialize Aspect Strength Thresholds from Local Storage Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Initializes the aspect strength thresholds by attempting to load saved settings from localStorage. If saved thresholds exist, they are parsed and used to recreate the UI rows. Otherwise, it calls a function to reset to default thresholds. Includes error handling for JSON parsing. ```javascript function initializeAspectStrengthThresholds() { const savedThresholds = localStorage.getItem('chartForm_aspectThresholds'); if (savedThresholds) { try { const thresholds = JSON.parse(savedThresholds); aspectThresholdsList.innerHTML = ''; thresholdCounter = 0; thresholds.forEach(cat => { createThresholdRow(cat.label, cat.orb.toString()); }); } catch (error) { console.error('Error loading saved thresholds:', error); resetAspectStrengthThresholds(); } } else { resetAspectStrengthThresholds(); } } ``` -------------------------------- ### Advanced Chart Analysis Configuration with ChartSettings (TypeScript) Source: https://context7.com/simpolism/chart2txt/llms.txt Shows how to use the `ChartSettings` class for advanced configuration of chart analysis. This includes defining aspect orb presets, skipping out-of-sign aspects, including pattern detection, and setting aspect strength thresholds. Requires the 'chart2txt' library. ```typescript import { ChartSettings, analyzeCharts } from 'chart2txt'; // Create custom settings const settings = new ChartSettings({ // Aspect orb presets: 'traditional' | 'modern' | 'tight' | 'wide' aspectDefinitions: 'traditional', // Or provide custom aspect definitions // aspectDefinitions: [ // { name: 'conjunction', angle: 0, orb: 8, classification: 'major' }, // { name: 'opposition', angle: 180, orb: 8, classification: 'major' }, // { name: 'trine', angle: 120, orb: 6, classification: 'major' }, // { name: 'square', angle: 90, orb: 6, classification: 'major' }, // { name: 'sextile', angle: 60, orb: 4, classification: 'minor' }, // ], // Skip aspects that cross sign boundaries skipOutOfSignAspects: true, // Include pattern detection (T-Square, Grand Trine, Yod, etc.) includeAspectPatterns: true, // Include element/modality/polarity distributions includeSignDistributions: true, // Include dispositor chains: true | false | 'finals' includeDispositors: 'finals', // Include house overlay analysis for synastry includeHouseOverlays: true, // Aspect strength grouping thresholds aspectStrengthThresholds: { tight: 2.0, // orb <= 2° = tight moderate: 4.0 // orb 2-4° = moderate, >4° = wide }, // Date formatting dateFormat: 'YYYY-MM-DD', houseSystemName: 'placidus' }); // Use with analysis const report = analyzeCharts(chartData, settings); ``` -------------------------------- ### Get UI Categories from Aspect Thresholds List Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Retrieves user-defined categories from the UI, specifically from elements with the class 'aspect-strength-row'. It extracts labels and orb values, filters out invalid entries, and returns a sorted list of categories. This function is crucial for custom grouping in advanced workflows. ```javascript function getUiCategories() { const categories = []; const rows = aspectThresholdsList.querySelectorAll('.aspect-strength-row'); rows.forEach(row => { const labelInput = row.querySelector('[data-field="label"]'); const orbInput = row.querySelector('[data-field="orb"]'); const label = labelInput.value.trim().toUpperCase(); const orb = parseFloat(orbInput.value); if (label && !isNaN(orb)) { categories.push({ label: label, orb: orb }); } }); // Sort categories by orb to ensure correct grouping. categories.sort((a, b) => a.orb - b.orb); return categories; } ``` -------------------------------- ### Initialize UI Elements and Event Listeners Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This JavaScript code initializes various UI elements from the HTML form, sets up event listeners for user interactions, and defines constants for API endpoints and maximum chart limits. It manages the display and behavior of elements related to astrological and Human Design chart conversions, including transit and partnership options. ```javascript document.addEventListener('DOMContentLoaded', function() { const MAX_CHARTS = 10; let chartCounter = 0; let charts = []; const form = document.getElementById('birthDataForm'); const chartsContainer = document.getElementById('chartsContainer'); const addChartBtn = document.getElementById('addChartBtn'); const resultDiv = document.getElementById('result'); const loadingDiv = document.getElementById('loading'); const copyBtn = document.getElementById('copyBtn'); // Transit inputs const enableTransitsCheckbox = document.getElementById('enableTransits'); const transitLocationGroup = document.getElementById('transitLocationGroup'); const transitLocationInput = document.getElementById('transitLocation'); const transitLocationError = document.getElementById('transitLocationError'); const transitDateTimeGroup = document.getElementById('transitDateTimeGroup'); const transitDateInput = document.getElementById('transitDate'); const transitHoursInput = document.getElementById('transitHours'); const transitMinutesInput = document.getElementById('transitMinutes'); const houseSystemSelect = document.getElementById('houseSystem'); // Aspect strength threshold elements const aspectThresholdsList = document.getElementById('aspectThresholdsList'); const addThresholdBtn = document.getElementById('addThreshold'); const resetThresholdsBtn = document.getElementById('resetThresholds'); let thresholdCounter = 0; // Mode toggle elements const modeAstrologyBtn = document.getElementById('modeAstrology'); const modeHumanDesignBtn = document.getElementById('modeHumanDesign'); const pageTitle = document.getElementById('pageTitle'); let currentMode = 'astrology'; // 'astrology' or 'humandesign' // HD Partnership elements const hdPartnershipSection = document.getElementById('hdPartnershipSection'); const enableHdPartnershipCheckbox = document.getElementById('enableHdPartnership'); const hdPartnerChartContainer = document.getElementById('hdPartnerChartContainer'); const hdPartnerNameInput = document.getElementById('hdPartnerName'); const hdPartnerBirthdateInput = document.getElementById('hdPartnerBirthdate'); const hdPartnerHoursInput = document.getElementById('hdPartnerHours'); const hdPartnerMinutesInput = document.getElementById('hdPartnerMinutes'); const hdPartnerLocationInput = document.getElementById('hdPartnerLocation'); const hdPartnerLocationError = document.getElementById('hdPartnerLocationError'); // HD Partnership checkbox event listener enableHdPartnershipCheckbox.addEventListener('change', function() { hdPartnerChartContainer.style.display = this.checked ? 'block' : 'none'; saveFormData(); }); // API endpoints const ASTROLOGY_API_ENDPOINT = 'https://simple-astro-api.netlify.app/api/positions'; const HUMAN_DESIGN_API_ENDPOINT = 'https://simple-astro-api.netlify.app/api/positions-with-design'; // Mode toggle functions function setMode(mode) { currentMode = mode; const astrologyElements = document.querySelectorAll('.astrology-only'); const humanDesignElements = document.querySelectorAll('.human-design-only'); if (mode === 'astrology') { modeAstrologyBtn.classList.add('active'); modeHumanDesignBtn.classList.remove('active'); pageTitle.textContent = 'Convert Astrological Chart to Text'; astrologyElements.forEach(el => el.classList.remove('hidden-mode')); humanDesignElements.forEach(el => el.classList.add('hidden-mode')); // Show all charts in astrology mode document.querySelectorAll('#chartsContainer .chart-container').forEach((el, index) => { el.style.display = 'block'; }); // Show "Is Event?" checkbox in astrology mode document.querySelectorAll('.checkbox-group').forEach(el => { const checkbox = el.querySelector('input[type="checkbox"]'); if (checkbox && checkbox.id.startsWith('isEvent_')) { el.style.display = 'flex'; } }); updateAddButtonVisibility(); } else { modeAstrologyBtn.classList.remove('active'); modeHumanDesignBtn.classList.add('active'); pageTitle.textContent = 'Convert Human Design Chart to Text'; astrologyElements.forEach(el => el.classList.add('hidden-mode')); humanDesignElements.forEach(el => el.classList.remove('hidden-mode')); // Only show first chart in HD mode (single chart only) document.querySelectorAll('#chartsContainer .chart-container').forEach((el, index) => { el.style.display = index === 0 ? 'block' : 'none'; }); // Hide "Is Event?" checkbox in HD mode document.querySelectorAll('.checkbox-group').forEach(el => { const checkbox = el.querySe ``` -------------------------------- ### Build and Analyze Human Design Charts and Partnerships (TypeScript) Source: https://context7.com/simpolism/chart2txt/llms.txt Demonstrates how to build individual Human Design chart objects and analyze partnerships programmatically. It shows accessing chart properties and partnership data, including electromagnetic channels and composite types. Requires the 'chart2txt' library. ```typescript import { buildChart, analyzePartnership, HumanDesignChart, HumanDesignPartnership } from 'chart2txt'; // Build individual charts from API responses const chart1: HumanDesignChart = buildChart(person1ApiResponse, { name: 'Alice' }); const chart2: HumanDesignChart = buildChart(person2ApiResponse, { name: 'Bob' }); // Access chart properties console.log(`${chart1.name}: ${chart1.type} with ${chart1.authority} authority`); console.log(`Profile: ${chart1.profile} (${chart1.profileName})`); console.log(`Defined Centers: ${chart1.definedCenters.join(', ')}`); console.log(`Active Channels: ${chart1.activeChannels.length}`); // Analyze partnership const partnership: HumanDesignPartnership = analyzePartnership(chart1, chart2); // Access partnership data programmatically console.log(`Electromagnetic Channels: ${partnership.electromagneticChannels.length}`); partnership.electromagneticChannels.forEach(conn => { console.log(` ${conn.channel.name}: ${conn.description}`); }); console.log(`Composite Type: ${partnership.compositeType}`); console.log(`Composite Definition: ${partnership.compositeDefinition}`); console.log(`Shared Gates: ${partnership.sharedGates.length}`); ``` -------------------------------- ### Accessing Constants and Presets in chart2txt (TypeScript) Source: https://context7.com/simpolism/chart2txt/llms.txt Illustrates how to access built-in constants and presets provided by the 'chart2txt' library for use in custom implementations. This includes orb configurations, zodiac sign names, and default settings. Requires the 'chart2txt' library. ```typescript import { DEFAULT_SETTINGS, DEFAULT_ASPECTS, ZODIAC_SIGNS, SIMPLE_TRADITIONAL_ORBS, SIMPLE_MODERN_ORBS, SIMPLE_TIGHT_ORBS, SIMPLE_WIDE_ORBS } from 'chart2txt'; // Use preset orb configurations console.log('Traditional orbs:', SIMPLE_TRADITIONAL_ORBS); // [ // { name: 'conjunction', angle: 0, orb: 10, classification: 'major' }, // { name: 'opposition', angle: 180, orb: 10, classification: 'major' }, // ... // ] console.log('Zodiac signs:', ZODIAC_SIGNS); // ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', // 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'] console.log('Default settings:', DEFAULT_SETTINGS); ``` -------------------------------- ### Copy Text to Clipboard Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Implements functionality to copy the content of the `resultDiv` to the user's clipboard. It uses the `navigator.clipboard.writeText` API and provides visual feedback to the user by changing the button text temporarily. Handles potential errors during the copy operation. ```javascript copyBtn.addEventListener('click', function() { const textToCopy = resultDiv.textContent; if (textToCopy) { navigator.clipboard.writeText(textToCopy) .then(() => { const originalText = copyBtn.textContent; copyBtn.textContent = 'Copied!'; setTimeout(() => { copyBtn.textContent = originalText; }, 2000); }) .catch(err => { console.error('Failed to copy text: ', err); }); } }); ``` -------------------------------- ### Advanced Workflow: Analyze, Group, and Format Astrological Data Source: https://github.com/simpolism/chart2txt/blob/master/README.md Illustrates the advanced workflow for complete control over astrological data processing. This involves analyzing charts, applying custom aspect grouping logic, and then formatting the report to text. ```typescript import { analyzeCharts, formatReportToText, AstrologicalReport, AspectData } from 'chart2txt'; const synastryData = [ { name: "Person A", planets: [{ name: 'Sun', degree: 45 }] }, { name: "Person B", planets: [{ name: 'Sun', degree: 225 }] } ]; // 1. ANALYZE: Get the raw, ungrouped report object. const report: AstrologicalReport = analyzeCharts(synastryData, { includeAspectPatterns: true }); // 2. CUSTOM GROUPING: Apply your own business logic. // Here, you can implement any grouping strategy you want. For this example, // we'll group aspects into "Hard" and "Soft" categories. const hardAspects: AspectData[] = []; const softAspects: AspectData[] = []; report.pairwiseAnalyses[0].synastryAspects.forEach(aspect => { if (['square', 'opposition'].includes(aspect.aspectType)) { hardAspects.push(aspect); } else { softAspects.push(aspect); } }); // Create a Map to preserve category order. const myGroupedAspects = new Map(); myGroupedAspects.set('[HARD ASPECTS]', hardAspects); myGroupedAspects.set('[SOFT ASPECTS]', softAspects); // Inject your custom-grouped map back into the report object. report.pairwiseAnalyses[0].groupedSynastryAspects = myGroupedAspects; // 3. FORMAT: Generate the text from your modified report object. const reportText = formatReportToText(report); console.log(reportText); ``` -------------------------------- ### Simple Workflow: Generate Text Report with chart2txt Source: https://github.com/simpolism/chart2txt/blob/master/README.md Demonstrates the simple, all-in-one workflow for generating a text-based astrological report. The `chart2txt()` function handles analysis and formatting with default settings or custom aspect thresholds. ```typescript import { chart2txt } from 'chart2txt'; const natalChart = { name: "John Doe", planets: [ { name: 'Sun', degree: 35.5 }, { name: 'Moon', degree: 120.25 }, ], }; // Get a report with default settings const reportText = chart2txt(natalChart); console.log(reportText); // Override the default aspect grouping const reportWithCustomGrouping = chart2txt(natalChart, { aspectStrengthThresholds: { tight: 1.0, moderate: 5.0 } }); console.log(reportWithCustomGrouping); ``` -------------------------------- ### Create Aspect Strength Threshold Row (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Dynamically creates a new row in the UI for defining aspect strength thresholds. Each row includes input fields for a label and orb value, along with a button to remove the threshold. It ensures the orb value is formatted to one decimal place and attaches event listeners for saving data. ```javascript function createThresholdRow(label = '', orb = '') { thresholdCounter++; const thresholdId = `threshold_${thresholdCounter}`; // Format orb value to always have one decimal place const formattedOrb = orb ? parseFloat(orb).toFixed(1) : ''; const row = document.createElement('div'); row.className = 'aspect-strength-row'; row.dataset.thresholdId = thresholdId; row.innerHTML = ` max orb `; // Add event listeners for the inputs const inputs = row.querySelectorAll('input'); inputs.forEach(input => { input.addEventListener('input', saveFormData); }); // Format number input to always show one decimal place const orbInput = row.querySelector('input[data-field="orb"]'); if (orbInput) { orbInput.addEventListener('blur', function() { const value = parseFloat(this.value); if (!isNaN(value)) { this.value = value.toFixed(1); } }); } aspectThresholdsList.appendChild(row); return thresholdId; } ``` -------------------------------- ### Create Chart HTML Structure (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Generates the HTML structure for a single chart, including input fields for name, event status, birthdate, birthtime, and location. It also includes a button to remove the chart if it's not the first one. This function is crucial for dynamically building the chart interface. ```javascript function createChartHTML(chartId, chartNumber) { return `

Chart ${chartNumber}

${chartNumber > 1 ? `` : ''}
`; } ``` -------------------------------- ### Handle Form Submission for Chart Generation Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Handles the submission of the main form, preventing default submission behavior. It clears previous results, shows a loading indicator, and then calls either `processHumanDesignChart` or `processAstrologyCharts` based on the `currentMode`. Includes basic error logging. ```javascript form.addEventListener('submit', async function(e) { e.preventDefault(); resultDiv.textContent = ''; copyBtn.style.display = 'none'; loadingDiv.style.display = 'block'; // Clear all error messages charts.forEach(chart => { const errorElement = document.getElementById(`locationError_${chart.id}`); if (errorElement) errorElement.textContent = ''; }); transitLocationError.textContent = ''; try { // Branch based on current mode if (currentMode === 'humandesign') { await processHumanDesignChart(); } else { await processAstrologyCharts(); } } catch (error) { console.error('Error generating chart:', error); res ``` -------------------------------- ### Load Form Data from Local Storage (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Loads previously saved form data from localStorage and populates the corresponding UI elements. It correctly restores values for text inputs, checkboxes, and applies saved aspect strength thresholds. It also updates transit field visibility and initializes aspect strength thresholds. ```javascript function loadFormData() { // Load chart field values const chartFieldIds = getAllChartFieldIds(); chartFieldIds.forEach(fieldId => { const field = document.getElementById(fieldId); if (field) { const savedValue = localStorage.getItem(`chartForm_${fieldId}`); if (savedValue !== null) { if (field.type === 'checkbox') { field.checked = (savedValue === 'true'); } else { field.value = savedValue; } } } }); // Load transit and other fields const otherFields = [ 'enableTransits', 'transitLocation', 'transitDate', 'transitHours', 'transitMinutes', 'houseSystem' ]; otherFields.forEach(fieldId => { const field = document.getElementById(fieldId); if (field) { const savedValue = localStorage.getItem(`chartForm_${fieldId}`); if (savedValue !== null) { if (field.type === 'checkbox') { field.checked = (savedValue === 'true'); } else { field.value = savedValue; } } } }); // Update transit field visibility updateTransitFieldsVisibility(); // Initialize aspect strength thresholds initializeAspectStrengthThresholds(); } ``` -------------------------------- ### Geocode Location using Photon API (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This asynchronous function takes a location string and an error element as input. It uses the Photon geocoding API to find the latitude and longitude of the provided location. If the location is not found or an error occurs during the fetch request, it updates the error element and returns null. ```javascript async function geocodeLocation(locationString, errorElement) { errorElement.textContent = ''; try { const params = `q=${encodeURIComponent(locationString)}&limit=1`; const response = await fetch(`https://photon.komoot.io/api/?${params}`); const data = await response.json(); if (data?.features?.length > 0) { const feature = data.features[0]; const coordinates = feature.geometry.coordinates; return { latitude: coordinates[1], longitude: coordinates[0] }; } errorElement.textContent = 'Location not found. Please enter a valid city and country.'; return null; } catch (error) { console.error('Geocoding error:', error); errorElement.textContent = 'Failed to geocode location.'; return null; } } ``` -------------------------------- ### Process Human Design Chart Data and Generate Text Description (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This function processes user-provided Human Design chart data (name, birthdate, time, location), geocodes the location, calls the Human Design API, and then uses the chart2txt library to generate a text description. It supports both single-person and partnership modes, with error handling for API requests and input validation. ```javascript async function processHumanDesignChart() { const chart = charts[0]; // HD only uses first chart if (!chart) { resultDiv.textContent = 'Please provide chart data.'; return; } const nameInput = document.getElementById(`name_${chart.id}`); const birthdateInput = document.getElementById(`birthdate_${chart.id}`); const hoursInput = document.getElementById(`hours_${chart.id}`); const minutesInput = document.getElementById(`minutes_${chart.id}`); const locationInput = document.getElementById(`location_${chart.id}`); const locationError = document.getElementById(`locationError_${chart.id}`); const name = nameInput.value.trim() || 'Person 1'; const birthdate = birthdateInput.value; const hours = parseInt(hoursInput.value); const minutes = parseInt(minutesInput.value); const location = locationInput.value.trim(); if (!birthdate || isNaN(hours) || isNaN(minutes) || !location) { locationError.textContent = 'Please fill all required date, time, and location fields.'; return; } const coordinates = await geocodeLocation(location, locationError); if (!coordinates) return; const timeString = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`; // Call Human Design API for first person const url = `${HUMAN_DESIGN_API_ENDPOINT}?date=${birthdate}&time=${timeString}&lat=${coordinates.latitude}&lng=${coordinates.longitude}`; const response = await fetch(url); if (!response.ok) { locationError.textContent = `API error: ${response.statusText || response.status}`; throw new Error(`HTTP error! status: ${response.status}`); } const apiResponse1 = await response.json(); // Check if partnership mode is enabled if (enableHdPartnershipCheckbox.checked) { // Get partner data const partnerName = hdPartnerNameInput.value.trim() || 'Person 2'; const partnerBirthdate = hdPartnerBirthdateInput.value; const partnerHours = parseInt(hdPartnerHoursInput.value); const partnerMinutes = parseInt(hdPartnerMinutesInput.value); const partnerLocation = hdPartnerLocationInput.value.trim(); if (!partnerBirthdate || isNaN(partnerHours) || isNaN(partnerMinutes) || !partnerLocation) { hdPartnerLocationError.textContent = 'Please fill all required partner date, time, and location fields.'; return; } const partnerCoordinates = await geocodeLocation(partnerLocation, hdPartnerLocationError); if (!partnerCoordinates) return; const partnerTimeString = `${partnerHours.toString().padStart(2, '0')}:${partnerMinutes.toString().padStart(2, '0')}:00`; // Call Human Design API for partner const partnerUrl = `${HUMAN_DESIGN_API_ENDPOINT}?date=${partnerBirthdate}&time=${partnerTimeString}&lat=${partnerCoordinates.latitude}&lng=${partnerCoordinates.longitude}`; const partnerResponse = await fetch(partnerUrl); if (!partnerResponse.ok) { hdPartnerLocationError.textContent = `API error: ${partnerResponse.statusText || response.status}`; throw new Error(`HTTP error! status: ${response.status}`); } const apiResponse2 = await partnerResponse.json(); // Generate Partnership analysis using the library const textDescription = window.chart2txt.humandesignPartnership2txt(apiResponse1, apiResponse2, { person1Name: name, person1Location: location, person2Name: partnerName, person2Location: partnerLocation }); resultDiv.textContent = textDescription; copyBtn.style.display = 'block'; } else { // Single chart mode const textDescription = window.chart2txt.humandesign2txt(apiResponse1, { name: name, location: location }); resultDiv.textContent = textDescription; copyBtn.style.display = 'block'; } } ``` -------------------------------- ### Add New Aspect Strength Threshold (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Adds a new, empty threshold row to the aspect strength settings UI by calling `createThresholdRow` and then saves the updated form data. This allows users to easily add custom thresholds. ```javascript function addThreshold() { createThresholdRow(); saveFormData(); } ``` -------------------------------- ### Add New Chart Functionality (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Adds a new chart to the interface, incrementing the chart counter and creating the necessary HTML structure. It also updates the visibility of the 'Add Chart' button and attaches event listeners to the new chart's input fields. Saving is optional. ```javascript function addChart(skipSave = false) { if (charts.length >= MAX_CHARTS) { alert(`Maximum of ${MAX_CHARTS} charts allowed.`); return; } chartCounter++; const chartId = `chart_${chartCounter}`; const chartNumber = charts.length + 1; charts.push({ id: chartId, number: chartNumber }); const chartHTML = createChartHTML(chartId, chartNumber); chartsContainer.insertAdjacentHTML('beforeend', chartHTML); updateAddButtonVisibility(); attachChartEventListeners(chartId); if (!skipSave) { saveFormData(); } } ``` -------------------------------- ### Process Multiple Astrology Charts and Transit Data (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html This function processes multiple Astrology charts, optionally including transit data. It iterates through provided chart data, applies a specified house system, and then uses the chart2txt library for analysis. It includes error handling and checks for the presence of charts before proceeding. ```javascript async function processAstrologyCharts() { const multiChartData = []; const houseSystem = houseSystemSelect.value; // Process each chart for (const chart of charts) { const chartData = await processChart(chart, houseSystem); if (chartData) { multiChartData.push(chartData); } else { return; // Error occurred, stop processing } } // Process transit data if enabled if (enableTransitsCheckbox.checked) { const transitData = await processTransitData(houseSystem); if (transitData) { multiChartData.push(transitData); } else { return; // Error occurred, stop processing } } if (multiChartData.length === 0) { resultDiv.textContent = 'Please provide at least one chart.'; return; } // --- ADVANCED WORKFLOW DEMONSTRATION --- // 1. ANALYZE: Get the raw, ungrouped report from the library. const analysisSettings = { includeAspectPatterns: true, includeSignDistributions: true }; const report = window.chart2txt.analyzeCharts(multiChartData, analysisSettings); // --- CUSTOM FILTERING & GROUPING DEMONSTRATION --- // 2a. GET UI DEFINITIONS & DETERMINE MAX ORB const uiCategories = getUiCategories(); // Get categories from the UI. // Find the widest orb defined by the user to use as a filter threshold. // If no categories are defined, default to a wide orb so nothing is filter ``` -------------------------------- ### Update Add Chart Button Visibility (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Controls the display of the 'Add Chart' button based on the current number of charts. The button is hidden if the maximum number of charts has been reached. ```javascript function updateAddButtonVisibility() { addChartBtn.style.display = charts.length >= MAX_CHARTS ? 'none' : 'inline-block'; } ``` -------------------------------- ### Group Aspects and Format Report (JavaScript) Source: https://github.com/simpolism/chart2txt/blob/master/examples/birth-chart/index.html Groups filtered astrological aspects using UI settings and then formats the entire report object into a text description. The formatted text is then displayed in a designated result div, and a copy button is shown. Dependencies include `groupAspectsFromUiSettings` and `window.chart2txt.formatReportToText`. ```javascript // 2c. GROUP THE FILTERED ASPECTS // Now, we pass the cleaned-up data to our grouping function. report.chartAnalyses.forEach(ca => { ca.groupedAspects = groupAspectsFromUiSettings(ca.aspects, uiCategories); }); report.pairwiseAnalyses.forEach(pa => { // For multi-chart aspects, we can use a different grouping or the same one. // Here, we'll just use the same UI categories for simplicity. pa.groupedSynastryAspects = groupAspectsFromUiSettings(pa.synastryAspects, uiCategories); }); report.transitAnalyses.forEach(ta => { ta.groupedAspects = groupAspectsFromUiSettings(ta.aspects, uiCategories); }); // 3. FORMAT: Pass the modified report object to the formatter. const textDescription = window.chart2txt.formatReportToText(report); resultDiv.textContent = textDescription; copyBtn.style.display = 'block'; ``` -------------------------------- ### Analyze Human Design Partnership (TypeScript) Source: https://context7.com/simpolism/chart2txt/llms.txt Analyzes the relationship between two Human Design charts using the humandesignPartnership2txt function from the chart2txt library. It requires two HumanDesignApiResponse objects and optional details for each person (name, location). The output is a string detailing compatibility aspects like electromagnetic connections, companionship channels, and dominance dynamics. ```typescript import { humandesignPartnership2txt, HumanDesignApiResponse } from 'chart2txt'; const person1Response: HumanDesignApiResponse = { personality: { planets: [ { name: 'Sun', longitude: 120.5, speed: 1.0 }, { name: 'Moon', longitude: 240.2, speed: 13.0 }, // ... other planets ], ascendant: 45, midheaven: 315, houseCusps: [45, 75, 105, 135, 165, 195, 225, 255, 285, 315, 345, 15], date: '1980-08-10', time: '09:00:00', location: { latitude: 34.0522, longitude: -118.2437 } }, design: { planets: [ { name: 'Sun', longitude: 30.2, speed: 1.0 }, // ... design planets ], ascendant: 225, midheaven: 135, houseCusps: [225, 255, 285, 315, 345, 15, 45, 75, 105, 135, 165, 195], date: '1980-05-13', time: '21:00:00', location: { latitude: 34.0522, longitude: -118.2437 } }, metadata: { designUtcDateTime: '1980-05-14T04:00:00Z', solarArcDegrees: 88, personalitySunLongitude: 120.5, designSunLongitude: 30.2 } }; const person2Response: HumanDesignApiResponse = { // Similar structure for person 2 personality: { /* ... */ }, design: { /* ... */ }, metadata: { /* ... */ } }; const partnershipReport = humandesignPartnership2txt( person1Response, person2Response, { person1Name: 'Alice', person1Location: 'Los Angeles, CA', person2Name: 'Bob', person2Location: 'San Francisco, CA' } ); console.log(partnershipReport); // Output includes: Individual summaries, Composite overview, // Electromagnetic connections, Companionship channels, // Dominance dynamics, Shared/Unique gates, Channel breakdowns ```