Show code
viewof deviceCount = Inputs.range([100, 10000], {
value: 1000,
step: 100,
label: "Number of devices:"
})
viewof deviceCost = Inputs.range([10, 200], {
value: 50,
step: 5,
label: "Cost per device ($):"
})
viewof installCost = Inputs.range([5, 100], {
value: 25,
step: 5,
label: "Installation cost per device ($):"
})
viewof connectivityCost = Inputs.range([5, 50], {
value: 12,
step: 1,
label: "Annual connectivity per device ($):"
})
viewof cloudCost = Inputs.range([2, 30], {
value: 8,
step: 1,
label: "Annual cloud cost per device ($):"
})
viewof maintenanceCost = Inputs.range([1, 20], {
value: 5,
step: 1,
label: "Annual maintenance per device ($):"
})
// Calculate TCO components
year1Devices = deviceCount * deviceCost
year1Install = deviceCount * installCost
year1Connectivity = deviceCount * connectivityCost
year1Cloud = deviceCount * cloudCost
year1Maintenance = deviceCount * maintenanceCost
year1Total = year1Devices + year1Install + year1Connectivity + year1Cloud + year1Maintenance
years25Connectivity = deviceCount * connectivityCost * 4
years25Cloud = deviceCount * cloudCost * 4
years25Maintenance = deviceCount * maintenanceCost * 4
years25Total = years25Connectivity + years25Cloud + years25Maintenance
tco5Year = year1Total + years25Total
hardwarePercentage = (year1Devices / tco5Year * 100).toFixed(1)
html`
<div style="background: #f8f9fa; border-left: 4px solid #16A085; padding: 1.5rem; margin: 1rem 0; border-radius: 4px;">
<h4 style="color: #2C3E50; margin-top: 0;">5-Year TCO Projection</h4>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; margin: 1rem 0;">
<div style="background: white; padding: 1rem; border-radius: 4px; border: 1px solid #dee2e6;">
<div style="color: #7F8C8D; font-size: 0.875rem; margin-bottom: 0.5rem;">Year 1 Total</div>
<div style="color: #2C3E50; font-size: 1.5rem; font-weight: 600;">$${year1Total.toLocaleString()}</div>
</div>
<div style="background: white; padding: 1rem; border-radius: 4px; border: 1px solid #dee2e6;">
<div style="color: #7F8C8D; font-size: 0.875rem; margin-bottom: 0.5rem;">Years 2-5 Total</div>
<div style="color: #E67E22; font-size: 1.5rem; font-weight: 600;">$${years25Total.toLocaleString()}</div>
</div>
<div style="background: white; padding: 1rem; border-radius: 4px; border: 1px solid #dee2e6;">
<div style="color: #7F8C8D; font-size: 0.875rem; margin-bottom: 0.5rem;">5-Year TCO</div>
<div style="color: #16A085; font-size: 1.5rem; font-weight: 600;">$${tco5Year.toLocaleString()}</div>
</div>
</div>
<table style="width: 100%; border-collapse: collapse; margin-top: 1rem;">
<thead>
<tr style="background: #2C3E50; color: white;">
<th style="padding: 0.75rem; text-align: left; border-radius: 4px 0 0 0;">Category</th>
<th style="padding: 0.75rem; text-align: right;">Year 1</th>
<th style="padding: 0.75rem; text-align: right;">Years 2-5</th>
<th style="padding: 0.75rem; text-align: right; border-radius: 0 4px 0 0;">Total 5-Year</th>
</tr>
</thead>
<tbody>
<tr style="background: white;">
<td style="padding: 0.75rem; border-bottom: 1px solid #dee2e6;">Devices</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Devices.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$0</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Devices.toLocaleString()}</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 0.75rem; border-bottom: 1px solid #dee2e6;">Installation</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Install.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$0</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Install.toLocaleString()}</td>
</tr>
<tr style="background: white;">
<td style="padding: 0.75rem; border-bottom: 1px solid #dee2e6;">Connectivity</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Connectivity.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${years25Connectivity.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${(year1Connectivity + years25Connectivity).toLocaleString()}</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 0.75rem; border-bottom: 1px solid #dee2e6;">Cloud Services</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Cloud.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${years25Cloud.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${(year1Cloud + years25Cloud).toLocaleString()}</td>
</tr>
<tr style="background: white;">
<td style="padding: 0.75rem; border-bottom: 1px solid #dee2e6;">Maintenance</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${year1Maintenance.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${years25Maintenance.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-bottom: 1px solid #dee2e6;">$${(year1Maintenance + years25Maintenance).toLocaleString()}</td>
</tr>
<tr style="background: #16A085; color: white; font-weight: 600;">
<td style="padding: 0.75rem; border-radius: 0 0 0 4px;">Total</td>
<td style="padding: 0.75rem; text-align: right;">$${year1Total.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right;">$${years25Total.toLocaleString()}</td>
<td style="padding: 0.75rem; text-align: right; border-radius: 0 0 4px 0;">$${tco5Year.toLocaleString()}</td>
</tr>
</tbody>
</table>
<div style="margin-top: 1rem; padding: 1rem; background: ${hardwarePercentage < 30 ? '#fff3cd' : '#f8d7da'}; border-radius: 4px; border-left: 4px solid ${hardwarePercentage < 30 ? '#E67E22' : '#E74C3C'};">
<strong style="color: #2C3E50;">Key Insight:</strong> Hardware represents only <strong>${hardwarePercentage}%</strong> of the 5-year cost.
${hardwarePercentage < 30 ? 'Organizations budgeting only upfront hardware costs will run out of funding in Year 2.' : 'This is an unusually high hardware percentage - verify your operational costs are realistic.'}
</div>
</div>
`