Airbnb Occupancy Rate Calculator

Airbnb Occupancy Rate Calculator & Guide :root { –primary-color: #004a99; –success-color: #28a745; –background-color: #f8f9fa; –text-color: #333; –border-color: #ddd; –card-background: #fff; –shadow: 0 2px 5px rgba(0,0,0,0.1); } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: var(–background-color); color: var(–text-color); line-height: 1.6; margin: 0; padding: 0; } .container { max-width: 960px; margin: 20px auto; padding: 20px; background-color: var(–card-background); border-radius: 8px; box-shadow: var(–shadow); } header { text-align: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid var(–border-color); } header h1 { color: var(–primary-color); margin-bottom: 10px; } .calculator-section { margin-bottom: 40px; padding: 30px; background-color: var(–card-background); border-radius: 8px; box-shadow: var(–shadow); } .calculator-section h2 { color: var(–primary-color); text-align: center; margin-bottom: 20px; } .loan-calc-container { display: flex; flex-direction: column; gap: 20px; } .input-group { display: flex; flex-direction: column; gap: 8px; } .input-group label { font-weight: bold; color: var(–primary-color); } .input-group input[type="number"], .input-group input[type="text"], .input-group select { padding: 10px; border: 1px solid var(–border-color); border-radius: 4px; font-size: 1rem; width: 100%; box-sizing: border-box; } .input-group input[type="number"]:focus, .input-group input[type="text"]:focus, .input-group select:focus { outline: none; border-color: var(–primary-color); box-shadow: 0 0 0 2px rgba(0, 74, 153, 0.2); } .input-group .helper-text { font-size: 0.85rem; color: #666; } .input-group .error-message { color: red; font-size: 0.8rem; margin-top: 5px; display: none; /* Hidden by default */ } .button-group { display: flex; gap: 10px; margin-top: 20px; justify-content: center; flex-wrap: wrap; } .button-group button { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; font-weight: bold; transition: background-color 0.3s ease; } .btn-calculate { background-color: var(–primary-color); color: white; } .btn-calculate:hover { background-color: #003366; } .btn-reset { background-color: #6c757d; color: white; } .btn-reset:hover { background-color: #5a6268; } .btn-copy { background-color: #17a2b8; color: white; } .btn-copy:hover { background-color: #117a8b; } #results-container { margin-top: 30px; padding: 25px; background-color: var(–primary-color); color: white; border-radius: 8px; box-shadow: var(–shadow); text-align: center; } #results-container h3 { margin-top: 0; color: white; } #main-result { font-size: 2.5rem; font-weight: bold; margin: 10px 0; display: block; color: var(–success-color); } .intermediate-results { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin-top: 20px; padding-top: 15px; border-top: 1px solid rgba(255, 255, 255, 0.3); } .intermediate-results div { text-align: center; } .intermediate-results span { display: block; font-size: 1.8rem; font-weight: bold; } .intermediate-results p { margin: 0; font-size: 0.9rem; opacity: 0.8; } .formula-explanation { margin-top: 15px; font-size: 0.9rem; opacity: 0.8; color: white; } .chart-container { margin-top: 30px; padding: 20px; background-color: var(–card-background); border-radius: 8px; box-shadow: var(–shadow); text-align: center; } .chart-container h3 { color: var(–primary-color); margin-bottom: 15px; } canvas { max-width: 100%; height: auto; } .table-container { margin-top: 30px; overflow-x: auto; } table { width: 100%; border-collapse: collapse; margin-top: 15px; box-shadow: var(–shadow); } th, td { padding: 12px 15px; text-align: left; border: 1px solid var(–border-color); } thead { background-color: var(–primary-color); color: white; } tbody tr:nth-child(even) { background-color: #f2f2f2; } caption { font-size: 1.1rem; font-weight: bold; color: var(–primary-color); margin-bottom: 10px; caption-side: top; text-align: left; } .article-section { margin-top: 40px; padding: 30px; background-color: var(–card-background); border-radius: 8px; box-shadow: var(–shadow); } .article-section h2, .article-section h3 { color: var(–primary-color); margin-bottom: 15px; } .article-section h2 { border-bottom: 2px solid var(–primary-color); padding-bottom: 10px; } .article-section p, .article-section ul, .article-section ol { margin-bottom: 15px; } .article-section li { margin-bottom: 8px; } .faq-item { margin-bottom: 15px; border-left: 3px solid var(–primary-color); padding-left: 15px; } .faq-item strong { color: var(–primary-color); display: block; margin-bottom: 5px; } .internal-links { margin-top: 30px; padding: 20px; background-color: var(–card-background); border-radius: 8px; box-shadow: var(–shadow); } .internal-links h3 { color: var(–primary-color); margin-bottom: 15px; } .internal-links ul { list-style: none; padding: 0; } .internal-links li { margin-bottom: 10px; } .internal-links a { color: var(–primary-color); text-decoration: none; font-weight: bold; } .internal-links a:hover { text-decoration: underline; } .internal-links p { font-size: 0.9rem; color: #555; margin-top: 5px; } .highlight { background-color: var(–success-color); color: white; padding: 2px 5px; border-radius: 3px; } .error { border-color: red !important; } .tooltip { position: relative; display: inline-block; cursor: help; border-bottom: 1px dotted #004a99; } .tooltip .tooltiptext { visibility: hidden; width: 220px; background-color: #555; color: #fff; text-align: center; border-radius: 6px; padding: 5px 10px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -110px; opacity: 0; transition: opacity 0.3s; font-size: 0.8rem; line-height: 1.4; } .tooltip .tooltiptext::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: #555 transparent transparent transparent; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; }

Airbnb Occupancy Rate Calculator

Understand and improve your short-term rental's booking performance.

Airbnb Occupancy Rate Calculator

Enter the total number of nights your listing was available for booking during the selected period (e.g., 365 for a full year).
Enter the total number of nights your listing was actually booked during the same period.

Your Occupancy Rate

Nights Booked

Nights Available

Avg. Daily Rate (ADR)

Occupancy Rate = (Total Nights Booked / Total Nights Available) * 100

Occupancy Trend Over Time

Monthly Occupancy Rate Comparison
Metric Value Description
Total Nights Available Nights your listing was listed and available for booking.
Total Nights Booked Nights your listing was occupied by guests.
Occupancy Rate Percentage of available nights that were booked.
Average Daily Rate (ADR) Average revenue earned per occupied night.
Total Revenue (Estimated) Estimated total booking revenue based on ADR and booked nights.

What is Airbnb Occupancy Rate?

The Airbnb occupancy rate is a crucial metric for short-term rental hosts. It represents the percentage of nights your property was booked and occupied compared to the total number of nights it was available for booking over a specific period. Essentially, it tells you how successful you are at filling your rental calendar.

Understanding your occupancy rate is vital for assessing the performance of your Airbnb listing. A high occupancy rate generally indicates strong demand, effective marketing, competitive pricing, and positive guest experiences. Conversely, a low occupancy rate might signal issues with pricing, listing visibility, property appeal, or seasonality.

Who Should Use It?

This calculator is designed for:

  • Airbnb Hosts: Both new and experienced hosts can use it to track performance, set goals, and identify areas for improvement.
  • Property Managers: Professionals managing multiple short-term rentals need this metric to evaluate individual property performance and overall portfolio health.
  • Real Estate Investors: Those considering investing in short-term rental properties can use occupancy rate projections to estimate potential returns.
  • Vacation Rental Analysts: Anyone interested in the short-term rental market can use this to gauge market trends and demand.

Common Misconceptions

  • Occupancy Rate = Profitability: While related, a high occupancy rate doesn't automatically mean high profits. High booking volume with low nightly rates or high operating costs can still lead to low profitability.
  • One-Size-Fits-All Ideal Rate: The "ideal" occupancy rate varies significantly by location, market type (e.g., business vs. leisure), seasonality, and the host's specific financial goals. A host aiming for maximum revenue might accept a slightly lower occupancy for higher nightly rates.
  • Focusing Only on Booked Nights: While booked nights are key, understanding the total nights available is equally important. A property booked 100 nights out of 120 available has a higher occupancy rate (83%) than one booked 200 nights out of 365 (55%).

Airbnb Occupancy Rate Formula and Mathematical Explanation

The calculation for Airbnb occupancy rate is straightforward, focusing on the ratio of booked time to available time.

The Formula

The core formula is:

Occupancy Rate (%) = (Total Nights Booked / Total Nights Available) * 100

Variable Explanations

Let's break down the components:

  • Total Nights Booked: This is the sum of all nights your listing was occupied by guests during the specified period. This includes all bookings, regardless of length or guest type.
  • Total Nights Available: This is the total number of nights your listing was actively available for booking on the platform during the same period. If your listing was live for the entire year, this would typically be 365 nights. If you took it down for renovations for a month, you would subtract those nights.

Variables Table

Variable Meaning Unit Typical Range
Total Nights Booked Nights guests stayed at your property. Nights 0 to Total Nights Available
Total Nights Available Nights your property was listed and open for bookings. Nights 1 to 366 (depending on period and leap year)
Occupancy Rate Percentage of available nights that were booked. % 0% to 100%
Average Daily Rate (ADR) Average revenue earned per occupied night. Currency (e.g., USD, EUR) Varies widely based on property type, location, and season.

The calculator also estimates Total Revenue using the formula: Total Revenue = Total Nights Booked * Average Daily Rate (ADR). The ADR is calculated by dividing the total revenue from bookings by the number of booked nights. For simplicity in this calculator, we focus on the core occupancy rate, assuming ADR is a separate, though related, metric.

Practical Examples (Real-World Use Cases)

Let's see how the Airbnb occupancy rate calculator works in practice.

Example 1: A Busy City Apartment

Scenario: Sarah manages a one-bedroom apartment in a popular tourist city. She wants to know her occupancy rate for the past year.

  • Total Nights Available: 365 (The apartment was listed year-round).
  • Total Nights Booked: 275 (The apartment was booked for 275 nights).
  • Average Daily Rate (ADR): $150

Calculation:

  • Occupancy Rate: (275 / 365) * 100 = 75.34%
  • Estimated Total Revenue: 275 nights * $150/night = $41,250

Interpretation:

Sarah's apartment has a strong occupancy rate of 75.34%. This indicates good demand, likely due to its prime location and competitive pricing. She can use this data to negotiate better terms with suppliers or plan for future investments.

Example 2: A Seasonal Beach House

Scenario: Mark owns a beach house that is primarily popular during the summer months. He wants to calculate his occupancy rate for the last quarter (July-September).

  • Total Nights Available: 92 (July: 31, Aug: 31, Sep: 30).
  • Total Nights Booked: 60 (The house was booked for 60 nights during this peak season).
  • Average Daily Rate (ADR): $300

Calculation:

  • Occupancy Rate: (60 / 92) * 100 = 65.22%
  • Estimated Total Revenue: 60 nights * $300/night = $18,000

Interpretation:

The beach house achieved a 65.22% occupancy rate during its peak season. While this might seem lower than the city apartment, it's likely a good performance for a seasonal property. Mark might focus on strategies to fill the shoulder seasons (spring/fall) or optimize pricing during peak times to maximize revenue further.

How to Use This Airbnb Occupancy Rate Calculator

Using our calculator is simple and provides immediate insights into your rental's performance. Follow these steps:

  1. Input Total Nights Available: In the first field, enter the total number of nights your listing was available for booking during the period you want to analyze (e.g., 365 for a full year, 90 for a quarter).
  2. Input Total Nights Booked: In the second field, enter the total number of nights your listing was actually booked by guests during that same period.
  3. Calculate: Click the "Calculate Rate" button.

Reading the Results

  • Main Result (Occupancy Rate): This is the primary output, displayed prominently. It shows the percentage of your available nights that were successfully booked. A higher percentage is generally better.
  • Intermediate Values: You'll see the nights booked, nights available, and an estimated Average Daily Rate (ADR). These provide context for the main occupancy rate.
  • Chart: The dynamic chart visualizes monthly occupancy trends, helping you spot seasonal patterns or performance dips.
  • Table: A detailed breakdown of all key metrics, including estimated total revenue, offering a comprehensive performance summary.

Decision-Making Guidance

  • High Occupancy (>75%): Congratulations! Your listing is performing well. Consider if you can optimize pricing for higher revenue or if you're nearing capacity and should focus on guest experience.
  • Moderate Occupancy (50%-75%): Good performance, but there's room for improvement. Analyze factors like pricing, listing photos, descriptions, reviews, and seasonality. Explore dynamic pricing strategies.
  • Low Occupancy (<50%): This suggests potential issues. Investigate pricing competitiveness, listing visibility (SEO, keywords), market demand, property condition, and guest reviews. Consider promotions or adjusting your target audience.

Use the "Copy Results" button to easily share your performance data or save it for your records. The "Reset" button allows you to quickly start a new calculation.

Key Factors That Affect Airbnb Occupancy Rate

Several elements influence how often your Airbnb property gets booked. Understanding these can help you strategize for better occupancy:

  1. Pricing Strategy: This is arguably the most significant factor. Overpriced listings deter bookings, while competitive pricing, especially during off-peak times, can significantly boost occupancy. Dynamic pricing tools that adjust rates based on demand, seasonality, and local events are invaluable.
  2. Listing Quality and Visibility: High-quality photos, a compelling description, accurate details, and a strong title are essential for attracting potential guests. Optimizing your listing with relevant keywords helps it rank higher in Airbnb search results, increasing visibility and bookings. A well-optimized listing is key.
  3. Guest Reviews and Ratings: Positive reviews build trust and encourage future bookings. Consistently high ratings signal a great guest experience, making your property more attractive. Negative reviews can severely damage occupancy.
  4. Location and Local Demand: Proximity to attractions, transport hubs, business centers, or natural amenities plays a huge role. Understanding the local market – whether it's driven by tourism, business travel, or events – helps you tailor your offering and pricing.
  5. Seasonality and Events: Demand fluctuates throughout the year. Peak seasons (summer holidays, major festivals) naturally see higher occupancy, while off-peak seasons require more effort (and potentially lower prices) to attract guests. Tracking local events can help you capitalize on demand surges.
  6. Amenities and Property Features: Modern amenities, unique features (e.g., hot tub, stunning view, pet-friendly options), and overall property condition can differentiate your listing and attract a wider range of guests, potentially increasing bookings.
  7. Booking Policies and Flexibility: Offering flexible cancellation policies can make guests more comfortable booking. Similarly, clear house rules and a responsive communication style contribute to a positive guest experience, leading to better reviews and repeat bookings.
  8. Competition: The number of competing listings in your area directly impacts your potential occupancy. Analyze what your competitors offer, their pricing, and their occupancy levels to position your property effectively.

Frequently Asked Questions (FAQ)

Q1: What is a good Airbnb occupancy rate?

A: A "good" occupancy rate varies greatly. For many markets, 60-80% is considered strong. However, in highly seasonal markets, a lower rate during the off-season might be acceptable if the peak season is very strong. Some hosts prioritize higher nightly rates over maximum occupancy.

Q2: How often should I calculate my occupancy rate?

A: It's best to calculate it monthly to track trends and identify issues quickly. Analyzing quarterly or annually provides a broader performance overview.

Q3: Does occupancy rate include blocked dates (e.g., for personal use)?

A: No. For accurate calculation, 'Total Nights Available' should only include nights your property was genuinely available to guests. Nights blocked for personal use, maintenance, or renovations should be excluded from the 'Available' count.

Q4: How does occupancy rate relate to revenue?

A: Occupancy rate tells you how often you're booked, while Average Daily Rate (ADR) tells you how much you earn per night. Total Revenue = Booked Nights * ADR. A high occupancy rate with a low ADR might yield less revenue than a moderate occupancy rate with a high ADR.

Q5: Can I calculate occupancy rate directly from Airbnb analytics?

A: Yes, Airbnb provides some performance insights, but manually calculating allows for precise control over the 'Total Nights Available' period, especially if you've had downtime. Our calculator helps ensure accuracy.

Q6: What if my listing was only available for part of the year?

A: Simply adjust the 'Total Nights Available' input to reflect the actual number of days the listing was active and bookable during your chosen period. For example, if you listed for 6 months (183 days) and booked 100 nights, your occupancy is (100/183)*100.

Q7: How can I increase my occupancy rate?

A: Focus on competitive pricing, improving listing quality (photos, description), encouraging positive reviews, offering amenities guests value, and potentially running promotions or discounts, especially during off-peak times.

Q8: Does Airbnb charge fees that affect occupancy rate calculation?

A: Airbnb fees (guest service fee, host service fee) don't directly impact the occupancy rate calculation itself, which is based purely on nights booked vs. available. However, they significantly affect your net revenue and profitability, which should be considered alongside occupancy.

© 2023 Your Website Name. All rights reserved.

var chartInstance = null; // Global variable to hold chart instance function validateInput(value, id, min, max, errorMessageId, fieldName) { var errorElement = document.getElementById(errorMessageId); errorElement.style.display = 'none'; var inputElement = document.getElementById(id); inputElement.classList.remove('error'); if (value === ") { errorElement.innerText = fieldName + ' cannot be empty.'; errorElement.style.display = 'block'; inputElement.classList.add('error'); return false; } var numValue = parseFloat(value); if (isNaN(numValue)) { errorElement.innerText = fieldName + ' must be a number.'; errorElement.style.display = 'block'; inputElement.classList.add('error'); return false; } if (numValue max) { errorElement.innerText = fieldName + ' cannot be greater than ' + max + '.'; errorElement.style.display = 'block'; inputElement.classList.add('error'); return false; } return true; } function calculateOccupancy() { var totalNightsAvailableInput = document.getElementById('totalNightsAvailable'); var bookedNightsInput = document.getElementById('bookedNights'); var totalNightsAvailable = totalNightsAvailableInput.value; var bookedNights = bookedNightsInput.value; var isValidTotalNights = validateInput(totalNightsAvailable, 'totalNightsAvailable', 1, 366, 'errorTotalNights', 'Total Nights Available'); var isValidBookedNights = validateInput(bookedNights, 'bookedNights', 0, parseFloat(totalNightsAvailable) || 366, 'errorBookedNights', 'Total Nights Booked'); if (!isValidTotalNights || !isValidBookedNights) { document.getElementById('main-result').innerText = '–'; document.getElementById('nightsBookedDisplay').innerText = '–'; document.getElementById('nightsAvailableDisplay').innerText = '–'; document.getElementById('averageDailyRateDisplay').innerText = '–'; updateTable('–', '–', '–', '–', '–'); updateChart([], []); // Clear chart on invalid input return; } var numTotalNightsAvailable = parseFloat(totalNightsAvailable); var numBookedNights = parseFloat(bookedNights); var occupancyRate = (numBookedNights / numTotalNightsAvailable) * 100; var averageDailyRate = 0; // Placeholder, as ADR is not directly calculated from inputs var estimatedTotalRevenue = 0; // Placeholder // Basic check for ADR and Revenue if we had those inputs // For this calculator, we'll just display placeholders or 0 // If you had an ADR input: // var adrInput = document.getElementById('averageDailyRate'); // var numADR = parseFloat(adrInput.value); // if (!isNaN(numADR) && numADR >= 0) { // averageDailyRate = numADR; // estimatedTotalRevenue = numBookedNights * numADR; // } document.getElementById('main-result').innerText = occupancyRate.toFixed(2) + '%'; document.getElementById('nightsBookedDisplay').innerText = numBookedNights.toFixed(0); document.getElementById('nightsAvailableDisplay').innerText = numTotalNightsAvailable.toFixed(0); document.getElementById('averageDailyRateDisplay').innerText = averageDailyRate.toFixed(2); // Display placeholder or calculated ADR updateTable(numTotalNightsAvailable.toFixed(0), numBookedNights.toFixed(0), occupancyRate.toFixed(2) + '%', averageDailyRate.toFixed(2), estimatedTotalRevenue.toFixed(2)); updateChart(numTotalNightsAvailable, numBookedNights); } function updateTable(nightsAvailable, bookedNights, occupancyRate, adr, totalRevenue) { document.getElementById('tableNightsAvailable').innerText = nightsAvailable; document.getElementById('tableBookedNights').innerText = bookedNights; document.getElementById('tableOccupancyRate').innerText = occupancyRate; document.getElementById('tableADR').innerText = adr; document.getElementById('tableTotalRevenue').innerText = totalRevenue; } function resetCalculator() { document.getElementById('totalNightsAvailable').value = '365'; document.getElementById('bookedNights').value = '180'; document.getElementById('errorTotalNights').style.display = 'none'; document.getElementById('errorBookedNights').style.display = 'none'; document.getElementById('totalNightsAvailable').classList.remove('error'); document.getElementById('bookedNights').classList.remove('error'); calculateOccupancy(); // Recalculate with default values } function copyResults() { var mainResult = document.getElementById('main-result').innerText; var nightsBooked = document.getElementById('nightsBookedDisplay').innerText; var nightsAvailable = document.getElementById('nightsAvailableDisplay').innerText; var adr = document.getElementById('averageDailyRateDisplay').innerText; var tableNightsAvailable = document.getElementById('tableNightsAvailable').innerText; var tableBookedNights = document.getElementById('tableBookedNights').innerText; var tableOccupancyRate = document.getElementById('tableOccupancyRate').innerText; var tableADR = document.getElementById('tableADR').innerText; var tableTotalRevenue = document.getElementById('tableTotalRevenue').innerText; var textToCopy = "— Airbnb Occupancy Rate Results —\n\n"; textToCopy += "Primary Result:\n"; textToCopy += "Occupancy Rate: " + mainResult + "\n\n"; textToCopy += "Key Metrics:\n"; textToCopy += "Nights Booked: " + nightsBooked + "\n"; textToCopy += "Nights Available: " + nightsAvailable + "\n"; textToCopy += "Average Daily Rate (ADR): " + adr + "\n\n"; textToCopy += "Detailed Breakdown:\n"; textToCopy += "Total Nights Available: " + tableNightsAvailable + "\n"; textToCopy += "Total Nights Booked: " + tableBookedNights + "\n"; textToCopy += "Occupancy Rate: " + tableOccupancyRate + "\n"; textToCopy += "Average Daily Rate (ADR): " + tableADR + "\n"; textToCopy += "Estimated Total Revenue: " + tableTotalRevenue + "\n\n"; textToCopy += "Formula Used: Occupancy Rate = (Total Nights Booked / Total Nights Available) * 100"; var textArea = document.createElement("textarea"); textArea.value = textToCopy; textArea.style.position = "fixed"; textArea.style.left = "-9999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { var successful = document.execCommand('copy'); var msg = successful ? 'Results copied!' : 'Copying failed!'; console.log(msg); // Optionally show a temporary message to the user var copyButton = document.querySelector('.btn-copy'); var originalText = copyButton.innerText; copyButton.innerText = msg; setTimeout(function() { copyButton.innerText = originalText; }, 2000); } catch (err) { console.error('Fallback: Oops, unable to copy', err); } document.body.removeChild(textArea); } function updateChart(bookedNights, nightsAvailable) { var ctx = document.getElementById('occupancyChart').getContext('2d'); // Destroy previous chart instance if it exists if (chartInstance) { chartInstance.destroy(); } // Generate sample monthly data if inputs are valid numbers var labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var monthlyOccupancy = []; var monthlyBooked = []; var monthlyAvailable = []; if (typeof bookedNights === 'number' && typeof nightsAvailable === 'number' && nightsAvailable > 0) { var avgMonthlyBooked = bookedNights / 12; var avgMonthlyAvailable = nightsAvailable / 12; for (var i = 0; i < 12; i++) { // Simulate some variation var booked = Math.max(0, avgMonthlyBooked + (Math.random() – 0.5) * avgMonthlyBooked * 0.5); var available = Math.max(1, avgMonthlyAvailable + (Math.random() – 0.5) * avgMonthlyAvailable * 0.2); monthlyBooked.push(booked); monthlyAvailable.push(available); monthlyOccupancy.push((booked / available) * 100); } } else { // Default to empty or zero data if inputs are invalid/missing for (var i = 0; i < 12; i++) { monthlyOccupancy.push(0); monthlyBooked.push(0); monthlyAvailable.push(0); } } chartInstance = new Chart(ctx, { type: 'bar', // Changed to bar for better comparison data: { labels: labels, datasets: [{ label: 'Occupancy Rate (%)', data: monthlyOccupancy, backgroundColor: 'rgba(0, 74, 153, 0.6)', // Primary color borderColor: 'rgba(0, 74, 153, 1)', borderWidth: 1, yAxisID: 'y-axis-rate', // Assign to the rate axis type: 'line', // Display occupancy rate as a line fill: false, tension: 0.1 }, { label: 'Nights Booked', data: monthlyBooked, backgroundColor: 'rgba(40, 167, 69, 0.6)', // Success color borderColor: 'rgba(40, 167, 69, 1)', borderWidth: 1, yAxisID: 'y-axis-nights' // Assign to the nights axis }, { label: 'Nights Available', data: monthlyAvailable, backgroundColor: 'rgba(255, 193, 7, 0.6)', // Warning color borderColor: 'rgba(255, 193, 7, 1)', borderWidth: 1, yAxisID: 'y-axis-nights' // Assign to the nights axis }] }, options: { responsive: true, maintainAspectRatio: true, scales: { x: { title: { display: true, text: 'Month' } }, 'y-axis-rate': { type: 'linear', position: 'right', min: 0, max: 100, title: { display: true, text: 'Occupancy Rate (%)' }, grid: { drawOnChartArea: false, // Only draw grid lines for the primary y-axis } }, 'y-axis-nights': { type: 'linear', position: 'left', min: 0, title: { display: true, text: 'Number of Nights' } } }, plugins: { tooltip: { mode: 'index', intersect: false, callbacks: { label: function(context) { var label = context.dataset.label || ''; if (label) { label += ': '; } if (context.parsed.y !== null) { if (context.dataset.label.includes('Rate')) { label += context.parsed.y.toFixed(2) + '%'; } else { label += context.parsed.y.toFixed(0); } } return label; } } }, legend: { position: 'top', } } } }); } // Initial calculation on page load window.onload = function() { // Load Chart.js library dynamically var script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/chart.js'; script.onload = function() { console.log('Chart.js loaded.'); calculateOccupancy(); // Calculate once Chart.js is ready }; document.head.appendChild(script); };

Leave a Comment