Spaces:
Running
Running
Update index.html
Browse files- index.html +28 -207
index.html
CHANGED
@@ -1330,20 +1330,36 @@
|
|
1330 |
};
|
1331 |
|
1332 |
// 초기 비용 계산 및 구성 요소 목록 생성
|
1333 |
-
Object.
|
1334 |
-
if (
|
1335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1336 |
} else {
|
1337 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1338 |
}
|
1339 |
-
maxTime = Math.max(maxTime, component.time);
|
1340 |
-
|
1341 |
-
componentListHTML += `
|
1342 |
-
<div class="component-list-item">
|
1343 |
-
<span><strong>${categoryNames[component.category]}</strong>: ${component.name}</span>
|
1344 |
-
<span>${component.category === 'support' ? '월 ' : ''}₩${component.cost}M</span>
|
1345 |
-
</div>
|
1346 |
-
`;
|
1347 |
});
|
1348 |
|
1349 |
// 월별 운영 비용 계산
|
@@ -1359,112 +1375,6 @@
|
|
1359 |
const adjustedTime = Math.max(3, Math.ceil(maxTime));
|
1360 |
|
1361 |
// 결과 표시
|
1362 |
-
document.getElementById('outsourceCost').textContent = `₩${Math.round(outsourceCost)}M`;
|
1363 |
-
document.getElementById('inhouseCost').textContent = `₩${Math.round(inhouseCost)}M`;
|
1364 |
-
document.getElementById('platformCost').textContent = `₩${Math.round(platformCost)}M`;
|
1365 |
-
document.getElementById('results').style.display = 'block';
|
1366 |
-
|
1367 |
-
// 차트 그리기
|
1368 |
-
drawChart(duration, baseCosts[scale], multiplier);
|
1369 |
-
}
|
1370 |
-
|
1371 |
-
function drawChart(duration, costs, multiplier) {
|
1372 |
-
const ctx = document.getElementById('costChart').getContext('2d');
|
1373 |
-
|
1374 |
-
if (costChart) {
|
1375 |
-
costChart.destroy();
|
1376 |
-
}
|
1377 |
-
|
1378 |
-
const months = Array.from({length: duration}, (_, i) => i + 1);
|
1379 |
-
|
1380 |
-
costChart = new Chart(ctx, {
|
1381 |
-
type: 'line',
|
1382 |
-
data: {
|
1383 |
-
labels: months.map(m => `${m}개월`),
|
1384 |
-
datasets: [
|
1385 |
-
{
|
1386 |
-
label: '외주 용역',
|
1387 |
-
data: months.map(m => costs.outsource.initial + (costs.outsource.monthly * m * multiplier)),
|
1388 |
-
borderColor: '#764ba2',
|
1389 |
-
backgroundColor: 'rgba(118, 75, 162, 0.1)',
|
1390 |
-
tension: 0.4
|
1391 |
-
},
|
1392 |
-
{
|
1393 |
-
label: '자체 인력',
|
1394 |
-
data: months.map(m => costs.inhouse.initial + (costs.inhouse.monthly * m * multiplier)),
|
1395 |
-
borderColor: '#f5576c',
|
1396 |
-
backgroundColor: 'rgba(245, 87, 108, 0.1)',
|
1397 |
-
tension: 0.4
|
1398 |
-
},
|
1399 |
-
{
|
1400 |
-
label: '플랫폼 대여',
|
1401 |
-
data: months.map(m => costs.platform.initial + (costs.platform.monthly * m * multiplier)),
|
1402 |
-
borderColor: '#00f2fe',
|
1403 |
-
backgroundColor: 'rgba(0, 242, 254, 0.1)',
|
1404 |
-
tension: 0.4
|
1405 |
-
}
|
1406 |
-
]
|
1407 |
-
},
|
1408 |
-
options: {
|
1409 |
-
responsive: true,
|
1410 |
-
maintainAspectRatio: false,
|
1411 |
-
plugins: {
|
1412 |
-
title: {
|
1413 |
-
display: true,
|
1414 |
-
text: '시간에 따른 누적 비용 추이',
|
1415 |
-
color: '#ffffff',
|
1416 |
-
font: {
|
1417 |
-
size: 16
|
1418 |
-
}
|
1419 |
-
},
|
1420 |
-
legend: {
|
1421 |
-
labels: {
|
1422 |
-
color: '#ffffff'
|
1423 |
-
}
|
1424 |
-
}
|
1425 |
-
},
|
1426 |
-
scales: {
|
1427 |
-
x: {
|
1428 |
-
grid: {
|
1429 |
-
color: 'rgba(255, 255, 255, 0.1)'
|
1430 |
-
},
|
1431 |
-
ticks: {
|
1432 |
-
color: '#ffffff'
|
1433 |
-
}
|
1434 |
-
},
|
1435 |
-
y: {
|
1436 |
-
grid: {
|
1437 |
-
color: 'rgba(255, 255, 255, 0.1)'
|
1438 |
-
},
|
1439 |
-
ticks: {
|
1440 |
-
color: '#ffffff',
|
1441 |
-
callback: function(value) {
|
1442 |
-
return '₩' + value + 'M';
|
1443 |
-
}
|
1444 |
-
}
|
1445 |
-
}
|
1446 |
-
}
|
1447 |
-
}
|
1448 |
-
});
|
1449 |
-
}
|
1450 |
-
|
1451 |
-
// 애니메이션 효과를 위한 Intersection Observer
|
1452 |
-
const observer = new IntersectionObserver((entries) => {
|
1453 |
-
entries.forEach(entry => {
|
1454 |
-
if (entry.isIntersecting) {
|
1455 |
-
entry.target.style.animation = 'fadeInUp 0.8s ease-out forwards';
|
1456 |
-
}
|
1457 |
-
});
|
1458 |
-
});
|
1459 |
-
|
1460 |
-
document.querySelectorAll('.method-card').forEach(card => {
|
1461 |
-
observer.observe(card);
|
1462 |
-
});
|
1463 |
-
</script>
|
1464 |
-
</body>
|
1465 |
-
</html>
|
1466 |
-
</body>
|
1467 |
-
</html> 표시
|
1468 |
document.getElementById('initialCost').textContent = `₩${initialCost}M`;
|
1469 |
document.getElementById('devTime').textContent = `${adjustedTime}개월`;
|
1470 |
document.getElementById('totalCost').textContent = `₩${totalCost}M`;
|
@@ -1613,95 +1523,6 @@
|
|
1613 |
}
|
1614 |
});
|
1615 |
}
|
1616 |
-
</script> 표시
|
1617 |
-
document.getElementById('outsourceCost').textContent = `₩${Math.round(outsourceCost)}M`;
|
1618 |
-
document.getElementById('inhouseCost').textContent = `₩${Math.round(inhouseCost)}M`;
|
1619 |
-
document.getElementById('platformCost').textContent = `₩${Math.round(platformCost)}M`;
|
1620 |
-
document.getElementById('results').style.display = 'block';
|
1621 |
-
|
1622 |
-
// 차트 그리기
|
1623 |
-
drawChart(duration, baseCosts[scale], multiplier);
|
1624 |
-
}
|
1625 |
-
|
1626 |
-
function drawChart(duration, costs, multiplier) {
|
1627 |
-
const ctx = document.getElementById('costChart').getContext('2d');
|
1628 |
-
|
1629 |
-
if (costChart) {
|
1630 |
-
costChart.destroy();
|
1631 |
-
}
|
1632 |
-
|
1633 |
-
const months = Array.from({length: duration}, (_, i) => i + 1);
|
1634 |
-
|
1635 |
-
costChart = new Chart(ctx, {
|
1636 |
-
type: 'line',
|
1637 |
-
data: {
|
1638 |
-
labels: months.map(m => `${m}개월`),
|
1639 |
-
datasets: [
|
1640 |
-
{
|
1641 |
-
label: '외주 용역',
|
1642 |
-
data: months.map(m => costs.outsource.initial + (costs.outsource.monthly * m * multiplier)),
|
1643 |
-
borderColor: '#764ba2',
|
1644 |
-
backgroundColor: 'rgba(118, 75, 162, 0.1)',
|
1645 |
-
tension: 0.4
|
1646 |
-
},
|
1647 |
-
{
|
1648 |
-
label: '자체 인력',
|
1649 |
-
data: months.map(m => costs.inhouse.initial + (costs.inhouse.monthly * m * multiplier)),
|
1650 |
-
borderColor: '#f5576c',
|
1651 |
-
backgroundColor: 'rgba(245, 87, 108, 0.1)',
|
1652 |
-
tension: 0.4
|
1653 |
-
},
|
1654 |
-
{
|
1655 |
-
label: '플랫폼 대여',
|
1656 |
-
data: months.map(m => costs.platform.initial + (costs.platform.monthly * m * multiplier)),
|
1657 |
-
borderColor: '#00f2fe',
|
1658 |
-
backgroundColor: 'rgba(0, 242, 254, 0.1)',
|
1659 |
-
tension: 0.4
|
1660 |
-
}
|
1661 |
-
]
|
1662 |
-
},
|
1663 |
-
options: {
|
1664 |
-
responsive: true,
|
1665 |
-
maintainAspectRatio: false,
|
1666 |
-
plugins: {
|
1667 |
-
title: {
|
1668 |
-
display: true,
|
1669 |
-
text: '시간에 따른 누적 비용 추이',
|
1670 |
-
color: '#ffffff',
|
1671 |
-
font: {
|
1672 |
-
size: 16
|
1673 |
-
}
|
1674 |
-
},
|
1675 |
-
legend: {
|
1676 |
-
labels: {
|
1677 |
-
color: '#ffffff'
|
1678 |
-
}
|
1679 |
-
}
|
1680 |
-
},
|
1681 |
-
scales: {
|
1682 |
-
x: {
|
1683 |
-
grid: {
|
1684 |
-
color: 'rgba(255, 255, 255, 0.1)'
|
1685 |
-
},
|
1686 |
-
ticks: {
|
1687 |
-
color: '#ffffff'
|
1688 |
-
}
|
1689 |
-
},
|
1690 |
-
y: {
|
1691 |
-
grid: {
|
1692 |
-
color: 'rgba(255, 255, 255, 0.1)'
|
1693 |
-
},
|
1694 |
-
ticks: {
|
1695 |
-
color: '#ffffff',
|
1696 |
-
callback: function(value) {
|
1697 |
-
return '₩' + value + 'M';
|
1698 |
-
}
|
1699 |
-
}
|
1700 |
-
}
|
1701 |
-
}
|
1702 |
-
}
|
1703 |
-
});
|
1704 |
-
}
|
1705 |
|
1706 |
// 애니메이션 효과를 위한 Intersection Observer
|
1707 |
const observer = new IntersectionObserver((entries) => {
|
|
|
1330 |
};
|
1331 |
|
1332 |
// 초기 비용 계산 및 구성 요소 목록 생성
|
1333 |
+
Object.entries(selectedComponents).forEach(([category, value]) => {
|
1334 |
+
if (typeof value === 'object' && value.id) {
|
1335 |
+
// 단일 선택 항목
|
1336 |
+
if (category === 'support') {
|
1337 |
+
monthlySupport += value.cost;
|
1338 |
+
} else {
|
1339 |
+
initialCost += value.cost;
|
1340 |
+
}
|
1341 |
+
maxTime = Math.max(maxTime, value.time);
|
1342 |
+
|
1343 |
+
componentListHTML += `
|
1344 |
+
<div class="component-list-item">
|
1345 |
+
<span><strong>${categoryNames[category]}</strong>: ${value.name}</span>
|
1346 |
+
<span>${category === 'support' ? '월 ' : ''}₩${value.cost}M</span>
|
1347 |
+
</div>
|
1348 |
+
`;
|
1349 |
} else {
|
1350 |
+
// 복수 선택 항목
|
1351 |
+
Object.values(value).forEach(item => {
|
1352 |
+
initialCost += item.cost;
|
1353 |
+
maxTime = Math.max(maxTime, item.time);
|
1354 |
+
|
1355 |
+
componentListHTML += `
|
1356 |
+
<div class="component-list-item">
|
1357 |
+
<span><strong>${categoryNames[category]}</strong>: ${item.name}</span>
|
1358 |
+
<span>₩${item.cost}M</span>
|
1359 |
+
</div>
|
1360 |
+
`;
|
1361 |
+
});
|
1362 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
});
|
1364 |
|
1365 |
// 월별 운영 비용 계산
|
|
|
1375 |
const adjustedTime = Math.max(3, Math.ceil(maxTime));
|
1376 |
|
1377 |
// 결과 표시
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1378 |
document.getElementById('initialCost').textContent = `₩${initialCost}M`;
|
1379 |
document.getElementById('devTime').textContent = `${adjustedTime}개월`;
|
1380 |
document.getElementById('totalCost').textContent = `₩${totalCost}M`;
|
|
|
1523 |
}
|
1524 |
});
|
1525 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1526 |
|
1527 |
// 애니메이션 효과를 위한 Intersection Observer
|
1528 |
const observer = new IntersectionObserver((entries) => {
|