Calculate Comp

Calculate Comp: Your Comprehensive Compensation Analysis Tool :root { –primary-color: #004a99; –background-color: #f8f9fa; –card-background: #ffffff; –text-color: #333; –border-color: #ddd; –shadow-color: 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); margin: 0; padding: 0; line-height: 1.6; } .container { max-width: 960px; margin: 20px auto; padding: 20px; background-color: var(–card-background); border-radius: 8px; box-shadow: 0 2px 10px var(–shadow-color); } h1, h2, h3 { color: var(–primary-color); text-align: center; margin-bottom: 20px; } h1 { font-size: 2.2em; } h2 { font-size: 1.8em; margin-top: 30px; border-bottom: 2px solid var(–primary-color); padding-bottom: 5px; } h3 { font-size: 1.4em; margin-top: 25px; } .calculator-section { margin-bottom: 40px; padding: 25px; border: 1px solid var(–border-color); border-radius: 8px; background-color: var(–card-background); box-shadow: 0 2px 5px var(–shadow-color); } .loan-calc-container { display: flex; flex-direction: column; gap: 15px; } .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: 1em; box-sizing: border-box; /* Ensures padding doesn't affect width */ } .input-group input:focus, .input-group select:focus { outline: none; border-color: var(–primary-color); box-shadow: 0 0 0 2px rgba(0, 74, 153, 0.2); } .helper-text { font-size: 0.85em; color: #666; } .error-message { color: #dc3545; font-size: 0.85em; margin-top: 5px; display: none; /* Hidden by default */ } .button-group { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; justify-content: center; } .btn { padding: 12px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 1em; font-weight: bold; transition: background-color 0.3s ease, transform 0.2s ease; text-decoration: none; display: inline-block; text-align: center; } .btn-primary { background-color: var(–primary-color); color: white; } .btn-primary:hover { background-color: #003366; transform: translateY(-1px); } .btn-secondary { background-color: #6c757d; color: white; } .btn-secondary:hover { background-color: #5a6268; transform: translateY(-1px); } .results-display { margin-top: 30px; padding: 25px; border: 1px solid var(–border-color); border-radius: 8px; background-color: #e7f3ff; /* Light accent background */ box-shadow: 0 2px 5px var(–shadow-color); text-align: center; } .results-display h3 { margin-top: 0; color: var(–primary-color); } .primary-result { font-size: 2.5em; font-weight: bold; color: var(–primary-color); margin: 15px 0; } .intermediate-results div { margin-bottom: 10px; font-size: 1.1em; } .intermediate-results span { font-weight: bold; color: var(–primary-color); } .formula-explanation { font-size: 0.9em; color: #555; margin-top: 15px; font-style: italic; } .table-container { overflow-x: auto; margin-top: 30px; margin-bottom: 30px; border: 1px solid var(–border-color); border-radius: 4px; background-color: var(–card-background); box-shadow: 0 2px 5px var(–shadow-color); } table { width: 100%; border-collapse: collapse; min-width: 600px; /* For horizontal scrolling on mobile */ } caption { caption-side: bottom; padding: 10px; font-size: 0.9em; color: #666; text-align: center; font-style: italic; } th, td { padding: 12px 15px; text-align: left; border-bottom: 1px solid var(–border-color); } thead th { background-color: var(–primary-color); color: white; font-weight: bold; } tbody tr:nth-child(even) { background-color: var(–background-color); } tbody tr:hover { background-color: #e9ecef; } .chart-container { margin-top: 30px; margin-bottom: 30px; padding: 25px; border: 1px solid var(–border-color); border-radius: 8px; background-color: var(–card-background); box-shadow: 0 2px 5px var(–shadow-color); text-align: center; } canvas { max-width: 100%; height: auto; } .article-content { margin-top: 40px; background-color: var(–card-background); padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px var(–shadow-color); } .article-content p { margin-bottom: 15px; } .article-content a { color: var(–primary-color); text-decoration: none; } .article-content a:hover { text-decoration: underline; } .faq-item { margin-bottom: 15px; border-bottom: 1px dashed var(–border-color); padding-bottom: 10px; } .faq-item:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .faq-item h3 { margin-bottom: 5px; text-align: left; font-size: 1.2em; } .faq-item p { margin-bottom: 0; font-size: 0.95em; color: #555; } footer { text-align: center; margin-top: 40px; padding: 20px; font-size: 0.9em; color: #777; } #chartCanvas { display: block; /* Remove extra space below canvas */ margin: 0 auto; }

Calculate Comp: Your Compensation Analysis Hub

Compensation Calculator

Enter your fixed annual salary.
Enter your target bonus as a percentage of base salary.
Enter the percentage of the target bonus that was actually paid.
Enter the current market value of your vested equity granted annually.
Include things like allowances, stipends, etc.

Your Compensation Snapshot

Actual Bonus:
Total Cash Compensation:
Total Compensation (Incl. Equity):
Total Cash Compensation = Base Salary + (Base Salary * Annual Bonus Target % * Actual Bonus Payout %) + Other Annual Cash Benefits
Total Compensation (Incl. Equity) = Total Cash Compensation + Equity Value (Annual Vesting)
Component Value Details
Base Salary Fixed annual pay
Annual Bonus Target Target bonus % of base
Actual Bonus Payout Actual bonus % achieved
Bonus Amount Actual bonus earned
Equity Value (Annual) Vested equity value per year
Other Cash Benefits Additional cash compensation
Total Cash Comp Base + Bonus + Other Cash
Total Comp (Inc. Equity) Total Cash + Equity
Detailed breakdown of your compensation components.

Compensation Breakdown Visualization

Visual representation of your compensation mix.

Understanding and Calculating Your Compensation (Comp)

Welcome to our comprehensive guide and calculator for understanding your compensation package. In the professional world, "comp" is short for compensation, and it encompasses everything an employer pays an employee, directly or indirectly, in exchange for their work. This goes beyond just your base salary to include bonuses, equity, benefits, and more. Understanding your total comp is crucial for career growth, salary negotiations, and financial planning. This tool is designed to help you break down and analyze your compensation accurately.

What is Compensation (Comp)?

Compensation, or "comp," is the total remuneration an individual receives from their employer. It's a broad term that includes not only the fixed salary but also variable pay like bonuses, long-term incentives such as stock options or restricted stock units (RSUs), and non-monetary benefits like health insurance, retirement plans, paid time off, and perks. The composition of compensation varies significantly across industries, company types (startups vs. large corporations), and seniority levels. For many tech and finance roles, equity can form a substantial part of the total compensation package. Accurately assessing your compensation is key to making informed career decisions.

Compensation (Comp) Formula and Mathematical Explanation

The calculation of total compensation can be complex due to the many potential components. However, we can break down the core elements:

  • Base Salary: This is the fixed amount of money you receive for your work, typically paid on an hourly, bi-weekly, or monthly basis. It's the foundation of your pay.
  • Annual Bonus: This is a variable component, often tied to individual and company performance. It's usually expressed as a target percentage of your base salary. For example, a 15% annual bonus target means you could earn up to 15% of your base salary in bonus pay. The actual amount received depends on performance metrics and the bonus payout percentage.
  • Actual Bonus Amount: Calculated as: Base Salary × Annual Bonus Target (%) × Actual Bonus Payout (%). If your target was 15% and the actual payout was 100%, you receive 15% of your base salary as a bonus. If the payout was only 80%, you'd receive 12% of your base salary.
  • Equity: This can include stock options, RSUs, or other forms of company ownership. For our calculator, we focus on the annual vesting value of equity as a component of total compensation.
  • Other Cash Benefits: This category captures any additional cash payments not covered above, such as annual allowances, signing bonuses amortized annually, or performance stipends.

The primary outputs of our calculator are:

Total Cash Compensation: Base Salary + Actual Bonus Amount + Other Annual Cash Benefits

Total Compensation (Including Equity): Total Cash Compensation + Equity Value (Annual Vesting)

Understanding these calculations allows for a clear view of your overall financial package. Analyzing compensation structures is a fundamental aspect of professional financial literacy.

Practical Examples (Real-World Use Cases)

Let's look at how different individuals might use this compensation calculator:

Scenario 1: The Software Engineer

Sarah is a software engineer at a mid-sized tech company. Her details are:

  • Base Salary: $120,000
  • Annual Bonus Target: 10%
  • Actual Bonus Payout: 120% (due to strong company performance)
  • Equity Value (Annual Vesting): $25,000
  • Other Cash Benefits: $3,000 (annual professional development stipend)

Using our calculator:

  • Actual Bonus Amount = $120,000 × 0.10 × 1.20 = $14,400
  • Total Cash Compensation = $120,000 + $14,400 + $3,000 = $137,400
  • Total Compensation (Incl. Equity) = $137,400 + $25,000 = $162,400

This shows Sarah her total package is significantly higher than her base salary alone. For more insights, she might explore salary negotiation tips.

Scenario 2: The Sales Manager

David is a sales manager at a growing company. His compensation structure heavily emphasizes variable pay:

  • Base Salary: $90,000
  • Annual Bonus Target: 25% (commission-based)
  • Actual Bonus Payout: 90% (met most targets)
  • Equity Value (Annual Vesting): $0 (no equity offered)
  • Other Cash Benefits: $0

Using our calculator:

  • Actual Bonus Amount = $90,000 × 0.25 × 0.90 = $20,250
  • Total Cash Compensation = $90,000 + $20,250 + $0 = $110,250
  • Total Compensation (Incl. Equity) = $110,250 + $0 = $110,250

David can see that his bonus constitutes a large portion of his income, highlighting the importance of performance. He might also be interested in understanding industry salary benchmarks.

Scenario 3: The Early-Stage Startup Employee

Maria works at a startup with a lower base salary but significant equity potential:

  • Base Salary: $80,000
  • Annual Bonus Target: 5%
  • Actual Bonus Payout: 100%
  • Equity Value (Annual Vesting): $40,000 (estimated current value of annual grants)
  • Other Cash Benefits: $2,000

Using our calculator:

  • Actual Bonus Amount = $80,000 × 0.05 × 1.00 = $4,000
  • Total Cash Compensation = $80,000 + $4,000 + $2,000 = $86,000
  • Total Compensation (Incl. Equity) = $86,000 + $40,000 = $126,000

Maria's total comp is boosted significantly by equity, but she must consider the volatility and potential illiquidity of startup stock. Her understanding of compensation components is vital for risk assessment. For startup employees, understanding stock option vesting schedules is also critical.

How to Use This Compensation Calculator

Using our Calculate Comp tool is straightforward:

  1. Enter Base Salary: Input your fixed annual salary.
  2. Input Bonus Targets: Provide your target bonus percentage (e.g., 10% for 10%).
  3. Specify Actual Payout: Enter the percentage of the target bonus you actually received (e.g., 100% for achieving the full target, 120% for exceeding it, 80% for falling short).
  4. Add Equity Value: Enter the estimated annual value of your vested equity. If you don't receive equity, enter 0.
  5. Include Other Cash Benefits: Add any other regular cash payments you receive annually.

As you input your numbers, the results will update in real-time, showing your total cash compensation and total compensation including equity. Use the 'Copy Results' button to save or share your analysis. If you need to start over, click 'Reset' to revert to default values.

Key Factors That Affect Compensation Results

Several factors influence the components of your compensation package:

  • Industry: High-demand industries like technology and finance often offer higher compensation, especially with significant equity components.
  • Company Size and Stage: Large, established companies typically offer more structured compensation with potentially lower equity upside but higher base salaries and bonuses. Startups may offer lower base salaries but higher potential equity value.
  • Role and Seniority: More senior roles and specialized positions command higher compensation due to increased responsibility and demand.
  • Location: Cost of living and local market demand significantly impact salary ranges. Jobs in major metropolitan areas often pay more.
  • Individual Performance: Your performance directly affects bonus payouts and potential for raises or promotions, impacting your overall compensation.
  • Market Conditions: Economic factors, such as talent shortages or recessions, can influence compensation trends.

Understanding these factors helps contextualize your own compensation and informs strategic career moves. Evaluating career path options can provide context.

Frequently Asked Questions (FAQ)

What is the difference between total cash compensation and total compensation?

Total cash compensation includes your base salary, actual bonuses, and other cash benefits. Total compensation broadens this to include the value of equity (like stock options or RSUs) and sometimes other benefits like retirement contributions, though our calculator focuses on the primary cash and equity components.

How is equity value calculated for compensation purposes?

For this calculator, we use the 'Equity Value (Annual Vesting)' field. This represents the estimated market value of the equity that vests within a one-year period. For stock options, this might be based on the intrinsic value (current stock price minus strike price) for vested options. For RSUs, it's typically the market value of shares that vest annually. The actual realizable value can vary.

What if my bonus is commission-based?

If your compensation is primarily commission-based, you can still use this calculator. Enter your base salary, set a relevant bonus target percentage (e.g., 25% or higher if commissions are significant), and then input the actual percentage of your commission targets you achieved as the 'Actual Bonus Payout'. Understanding your commission structures is key here.

Are benefits like health insurance or 401(k) included in this calculation?

This calculator primarily focuses on direct cash and equity compensation. While benefits like health insurance, retirement contributions (e.g., 401(k) match), and paid time off are valuable components of your total rewards, they are not included in these specific calculations to keep the focus clear. You would need to value these separately to get a complete picture of your overall employment value.

How often should I update my compensation analysis?

It's advisable to review and update your compensation analysis at least annually, or whenever you receive a promotion, change roles, or experience a significant change in your bonus or equity payout. Market conditions and company performance can also warrant updates.

Related Tools and Internal Resources

© 2023 Your Company Name. All rights reserved.

var chartInstance = null; // Global variable to hold chart instance function calculateComp() { // Clear previous error messages document.getElementById('baseSalaryError').style.display = 'none'; document.getElementById('annualBonusTargetError').style.display = 'none'; document.getElementById('bonusPayoutError').style.display = 'none'; document.getElementById('equityValueError').style.display = 'none'; document.getElementById('otherCashBenefitsError').style.display = 'none'; // Get input values var baseSalary = parseFloat(document.getElementById('baseSalary').value); var annualBonusTarget = parseFloat(document.getElementById('annualBonusTarget').value); var bonusPayout = parseFloat(document.getElementById('bonusPayout').value); var equityValue = parseFloat(document.getElementById('equityValue').value); var otherCashBenefits = parseFloat(document.getElementById('otherCashBenefits').value); // Input validation var isValid = true; if (isNaN(baseSalary) || baseSalary < 0) { document.getElementById('baseSalaryError').textContent = "Please enter a valid non-negative number for Base Salary."; document.getElementById('baseSalaryError').style.display = 'block'; isValid = false; } if (isNaN(annualBonusTarget) || annualBonusTarget 1000) { // Allow for very high targets, but avoid unreasonable ones document.getElementById('annualBonusTargetError').textContent = "Please enter a valid non-negative percentage (e.g., 15)."; document.getElementById('annualBonusTargetError').style.display = 'block'; isValid = false; } if (isNaN(bonusPayout) || bonusPayout 1000) { // Allow for exceeding targets document.getElementById('bonusPayoutError').textContent = "Please enter a valid non-negative percentage (e.g., 100)."; document.getElementById('bonusPayoutError').style.display = 'block'; isValid = false; } if (isNaN(equityValue) || equityValue < 0) { document.getElementById('equityValueError').textContent = "Please enter a valid non-negative number for Equity Value."; document.getElementById('equityValueError').style.display = 'block'; isValid = false; } if (isNaN(otherCashBenefits) || otherCashBenefits 0 var labels = []; var dataValues = []; var colors = ['#004a99', '#3498db', '#f1c40f', '#e67e22']; // Primary, Secondary, Accent1, Accent2 if (baseSalary > 0) { labels.push('Base Salary'); dataValues.push(baseSalary); } if (actualBonusAmount > 0) { labels.push('Bonus'); dataValues.push(actualBonusAmount); } if (equityValue > 0) { labels.push('Equity'); dataValues.push(equityValue); } if (otherCashBenefits > 0) { labels.push('Other Cash'); dataValues.push(otherCashBenefits); } // Limit colors to the number of data points var backgroundColors = colors.slice(0, dataValues.length); chartInstance = new Chart(ctx, { type: 'pie', data: { labels: labels, datasets: [{ data: dataValues, backgroundColor: backgroundColors, hoverOffset: 4 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom', labels: { generateLabels: function(chart) { var data = chart.data; if (data.labels.length && data.datasets.length) { return data.labels.map(function(label, i) { var meta = chart.getDatasetMeta(0); var ds = data.datasets[0]; var arc = meta.data[i]; var currentValue = ds.data[i]; var total = ds.data.reduce(function(a, b) { return a + b; }, 0); var percentage = total > 0 ? ((currentValue / total) * 100).toFixed(1) + '%' : '0.0%'; var style = arc.`style`; // Ensure style is correctly accessed var color = ds.backgroundColor[i] || chart.options.defaultFontColor; return { text: label + ' (' + percentage + ')', fillStyle: color, strokeStyle: color, fontStyle: 'normal', fontFamily: chart.options.font.family, fontSize: chart.options.font.size, // Use index for unique ID datasetIndex: 0, index: i }; }); } return []; } } } } } }); } function copyResults() { var baseSalary = document.getElementById('baseSalary').value || 0; var annualBonusTarget = document.getElementById('annualBonusTarget').value || 0; var bonusPayout = document.getElementById('bonusPayout').value || 0; var equityValue = document.getElementById('equityValue').value || 0; var otherCashBenefits = document.getElementById('otherCashBenefits').value || 0; var actualBonusAmount = baseSalary * (annualBonusTarget / 100) * (bonusPayout / 100); var totalCashCompensation = parseFloat(baseSalary) + actualBonusAmount + parseFloat(otherCashBenefits); var totalCompensationWithEquity = totalCashCompensation + parseFloat(equityValue); var currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }); var textToCopy = "— Compensation Analysis —\n\n"; textToCopy += "Key Assumptions:\n"; textToCopy += "- Base Salary: " + currencyFormatter.format(baseSalary) + "\n"; textToCopy += "- Annual Bonus Target: " + parseFloat(annualBonusTarget).toFixed(1) + "%\n"; textToCopy += "- Actual Bonus Payout: " + parseFloat(bonusPayout).toFixed(1) + "%\n"; textToCopy += "- Equity Value (Annual Vesting): " + currencyFormatter.format(equityValue) + "\n"; textToCopy += "- Other Annual Cash Benefits: " + currencyFormatter.format(otherCashBenefits) + "\n\n"; textToCopy += "Calculated Results:\n"; textToCopy += "- Actual Bonus Amount: " + currencyFormatter.format(actualBonusAmount) + "\n"; textToCopy += "- Total Cash Compensation: " + currencyFormatter.format(totalCashCompensation) + "\n"; textToCopy += "- Total Compensation (Incl. Equity): " + currencyFormatter.format(totalCompensationWithEquity) + "\n"; // Use a temporary textarea to copy text 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!' : 'Failed to copy results.'; // Optionally, show a temporary message to the user var copyButton = document.querySelector('button.btn-primary'); var originalText = copyButton.textContent; copyButton.textContent = msg; setTimeout(function() { copyButton.textContent = originalText; }, 2000); } catch (err) { console.error('Unable to copy results', err); // Optionally, show an error message } document.body.removeChild(textArea); } function resetCalculator() { document.getElementById('baseSalary').value = ""; document.getElementById('annualBonusTarget').value = ""; document.getElementById('bonusPayout').value = ""; document.getElementById('equityValue').value = ""; document.getElementById('otherCashBenefits').value = ""; // Clear results document.getElementById('totalCompensation').textContent = "–"; document.getElementById('actualBonusAmount').textContent = "–"; document.getElementById('totalCashCompensation').textContent = "–"; document.getElementById('totalCompensationWithEquity').textContent = "–"; // Clear table updateTable('–', '–', '–', '–', '–', '–', '–', '–'); // Clear chart if (chartInstance) { chartInstance.destroy(); chartInstance = null; } var canvas = document.getElementById('compensationChart'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); document.getElementById('chartLegend').innerHTML = "; // Clear error messages document.getElementById('baseSalaryError').style.display = 'none'; document.getElementById('annualBonusTargetError').style.display = 'none'; document.getElementById('bonusPayoutError').style.display = 'none'; document.getElementById('equityValueError').style.display = 'none'; document.getElementById('otherCashBenefitsError').style.display = 'none'; } // Initial calculation on page load with default values if any are set, or just to ensure structure is ready // calculateComp(); // Commented out to prevent calculation with empty fields on load // Add event listener for chart resizing window.addEventListener('resize', function() { if (chartInstance) { // Re-create chart on resize to ensure it fits container. // A more sophisticated approach might involve updating chart options. // For simplicity and robustness, we'll redraw. // We need current values to redraw, so we call calculateComp() // to re-render the chart with potentially new dimensions. calculateComp(); } }); // Initial call to calculateComp to set up the chart on load if defaults are set document.addEventListener('DOMContentLoaded', function() { // You might want to populate with sensible defaults here if desired // For example: // document.getElementById('baseSalary').value = 100000; // document.getElementById('annualBonusTarget').value = 15; // document.getElementById('bonusPayout').value = 100; // document.getElementById('equityValue').value = 20000; // document.getElementById('otherCashBenefits').value = 5000; // calculateComp(); // Calculate initial values if defaults are set // Ensure chart rendering is attempted even if inputs are empty initially var canvas = document.getElementById('compensationChart'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear any residual canvas content document.getElementById('chartLegend').innerHTML = "; }); // Basic Chart.js setup (ensure Chart.js library is loaded if using it – for this pure JS setup, we'll use a simple canvas drawing if Chart.js is not assumed) // NOTE: The request specifically disallowed external libraries. // Therefore, the chart drawing needs to be implemented using native Canvas API. // The following is a placeholder for native canvas drawing. // A full implementation would require significant logic for arcs, labels, legends, etc. // For simplicity and to meet the requirement of 'no external libraries', I'll simulate a chart update. // — Native Canvas Drawing Implementation (Simplified Example) — // This is a conceptual implementation. A full pie chart with dynamic data // and legends is complex with native canvas. // A simpler approach would be to render basic text descriptions if a full // visual chart is too complex without libraries. // For this solution, I'll retain the Chart.js structure as a placeholder // and acknowledge the constraint. If Chart.js is truly forbidden, // this section would need a complete overhaul using canvas drawing APIs. // For now, assume Chart.js is available globally for demonstration, // but will adhere to native drawing if strictly required and complex. // Given the constraint "NO external chart libraries", Chart.js cannot be used. // We'll implement a placeholder using native canvas which might be less sophisticated // than a library-generated chart. // Re-implementing updateChart without Chart.js function updateChart(baseSalary, actualBonusAmount, equityValue, otherCashBenefits, totalCashCompensation) { var canvas = document.getElementById('compensationChart'); var ctx = canvas.getContext('2d'); var width = canvas.width; var height = canvas.height; ctx.clearRect(0, 0, width, height); // Clear previous drawing var data = []; var labels = []; var colors = ['#004a99', '#3498db', '#f1c40f', '#e67e22']; // Primary, Secondary, Accent1, Accent2 // Filter out zero or negative values and collect valid data if (baseSalary > 0) { data.push(baseSalary); labels.push('Base Salary'); } if (actualBonusAmount > 0) { data.push(actualBonusAmount); labels.push('Bonus'); } if (equityValue > 0) { data.push(equityValue); labels.push('Equity'); } if (otherCashBenefits > 0) { data.push(otherCashBenefits); labels.push('Other Cash'); } var total = data.reduce(function(acc, val) { return acc + val; }, 0); if (total === 0) { ctx.fillStyle = '#999′; ctx.font = '16px Segoe UI'; ctx.textAlign = 'center'; ctx.fillText("No data to display", width / 2, height / 2); document.getElementById('chartLegend').innerHTML = "; return; } var startAngle = 0; var radius = Math.min(width, height) / 2 * 0.8; // Make radius fit within canvas, with margin var centerX = width / 2; var centerY = height / 2; // Draw Pie Slices for (var i = 0; i < data.length; i++) { var sliceAngle = (data[i] / total) * 2 * Math.PI; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.arc(centerX, centerY, radius, startAngle, startAngle + sliceAngle); ctx.closePath(); ctx.fillStyle = colors[i % colors.length]; ctx.fill(); startAngle += sliceAngle; } // Generate Legend var legendHtml = '
'; for (var i = 0; i < labels.length; i++) { var percentage = ((data[i] / total) * 100).toFixed(1) + '%'; legendHtml += '
'; legendHtml += ''; legendHtml += '' + labels[i] + ' (' + percentage + ')'; legendHtml += '
'; } legendHtml += '
'; document.getElementById('chartLegend').innerHTML = legendHtml; }

Leave a Comment