Spaces:
Running
Running
Update index.html
Browse files- index.html +335 -328
index.html
CHANGED
@@ -395,6 +395,7 @@
|
|
395 |
transition: all 0.3s ease;
|
396 |
position: relative;
|
397 |
overflow: hidden;
|
|
|
398 |
}
|
399 |
|
400 |
.option-card.selected {
|
@@ -420,7 +421,7 @@
|
|
420 |
font-weight: bold;
|
421 |
}
|
422 |
|
423 |
-
.option-card:hover {
|
424 |
border-color: #00d2ff;
|
425 |
background: rgba(255, 255, 255, 0.1);
|
426 |
transform: translateY(-2px);
|
@@ -1392,333 +1393,339 @@
|
|
1392 |
</div>
|
1393 |
</div>
|
1394 |
|
1395 |
-
```html
|
1396 |
-
</div>
|
1397 |
-
</div>
|
1398 |
-
|
1399 |
-
<!-- ๊ธฐ๊ฐ๋ณ ๋น์ฉ ์ฐจํธ -->
|
1400 |
-
<div class="chart-container">
|
1401 |
-
<canvas id="customChart"></canvas>
|
1402 |
-
</div>
|
1403 |
-
</div>
|
1404 |
-
</div>
|
1405 |
-
</div>
|
1406 |
-
</div>
|
1407 |
-
|
1408 |
-
<script>
|
1409 |
-
// ์ ์ญ ๋ณ์
|
1410 |
-
let selectedComponents = {
|
1411 |
-
service: [],
|
1412 |
-
db: null,
|
1413 |
-
auth: null,
|
1414 |
-
credit: null,
|
1415 |
-
payment: null,
|
1416 |
-
marketing: null,
|
1417 |
-
support: null,
|
1418 |
-
monitoring: null,
|
1419 |
-
additional: []
|
1420 |
-
};
|
1421 |
-
|
1422 |
-
let customChart = null;
|
1423 |
-
let currentPeriod = 3;
|
1424 |
-
|
1425 |
-
// ์ต์
์นด๋ ํด๋ฆญ ์ด๋ฒคํธ
|
1426 |
-
document.querySelectorAll('.option-card').forEach(card => {
|
1427 |
-
card.addEventListener('click', function() {
|
1428 |
-
const category = this.dataset.category;
|
1429 |
-
const id = this.dataset.id;
|
1430 |
-
|
1431 |
-
if (category === 'service' || category === 'additional') {
|
1432 |
-
// ๋ณต์ ์ ํ ๊ฐ๋ฅ
|
1433 |
-
this.classList.toggle('selected');
|
1434 |
-
|
1435 |
-
if (this.classList.contains('selected')) {
|
1436 |
-
if (!selectedComponents[category].includes(id)) {
|
1437 |
-
selectedComponents[category].push(id);
|
1438 |
-
}
|
1439 |
-
} else {
|
1440 |
-
const index = selectedComponents[category].indexOf(id);
|
1441 |
-
if (index > -1) {
|
1442 |
-
selectedComponents[category].splice(index, 1);
|
1443 |
-
}
|
1444 |
-
}
|
1445 |
-
} else {
|
1446 |
-
// ๋จ์ผ ์ ํ
|
1447 |
-
document.querySelectorAll(`[data-category="${category}"]`).forEach(c => {
|
1448 |
-
c.classList.remove('selected');
|
1449 |
-
});
|
1450 |
-
|
1451 |
-
this.classList.add('selected');
|
1452 |
-
selectedComponents[category] = id;
|
1453 |
-
}
|
1454 |
-
});
|
1455 |
-
});
|
1456 |
-
|
1457 |
-
// ํญ ์ ํ ํจ์
|
1458 |
-
function switchTab(tabId) {
|
1459 |
-
document.querySelectorAll('.tab').forEach(tab => {
|
1460 |
-
tab.classList.remove('active');
|
1461 |
-
});
|
1462 |
-
document.querySelectorAll('.tab-content').forEach(content => {
|
1463 |
-
content.classList.remove('active');
|
1464 |
-
});
|
1465 |
-
|
1466 |
-
event.target.classList.add('active');
|
1467 |
-
document.getElementById(tabId).classList.add('active');
|
1468 |
-
}
|
1469 |
-
|
1470 |
-
// ์ปค์คํ
๋น์ฉ ๊ณ์ฐ ํจ์
|
1471 |
-
function calculateCustomCost() {
|
1472 |
-
let totalInitialCost = 0;
|
1473 |
-
let totalResourceCost = 0;
|
1474 |
-
let maxTime = 0;
|
1475 |
-
let componentDetails = [];
|
1476 |
-
|
1477 |
-
// ์๋น์ค ๋น์ฉ ๊ณ์ฐ
|
1478 |
-
selectedComponents.service.forEach(serviceId => {
|
1479 |
-
const card = document.querySelector(`[data-id="${serviceId}"]`);
|
1480 |
-
const cost = parseFloat(card.dataset.cost);
|
1481 |
-
const time = parseFloat(card.dataset.time);
|
1482 |
-
const resource = parseFloat(card.dataset.resource) || 0;
|
1483 |
-
const name = card.querySelector('.option-name').textContent;
|
1484 |
-
|
1485 |
-
totalInitialCost += cost;
|
1486 |
-
totalResourceCost += resource;
|
1487 |
-
maxTime = Math.max(maxTime, time);
|
1488 |
-
|
1489 |
-
componentDetails.push({
|
1490 |
-
name: name,
|
1491 |
-
cost: cost,
|
1492 |
-
type: 'service'
|
1493 |
-
});
|
1494 |
-
});
|
1495 |
-
|
1496 |
-
// ๊ธฐํ ๊ตฌ์ฑ ์์ ๋น์ฉ ๊ณ์ฐ
|
1497 |
-
['db', 'auth', 'credit', 'payment', 'marketing', 'monitoring'].forEach(category => {
|
1498 |
-
if (selectedComponents[category]) {
|
1499 |
-
const card = document.querySelector(`[data-category="${category}"][data-id="${selectedComponents[category]}"]`);
|
1500 |
-
const cost = parseFloat(card.dataset.cost);
|
1501 |
-
const time = parseFloat(card.dataset.time);
|
1502 |
-
const name = card.querySelector('.option-name').textContent;
|
1503 |
-
|
1504 |
-
totalInitialCost += cost;
|
1505 |
-
maxTime = Math.max(maxTime, time);
|
1506 |
-
|
1507 |
-
componentDetails.push({
|
1508 |
-
name: name,
|
1509 |
-
cost: cost,
|
1510 |
-
type: category
|
1511 |
-
});
|
1512 |
-
}
|
1513 |
-
});
|
1514 |
-
|
1515 |
-
// ์ง์ ์๋น์ค (์๊ฐ ๋น์ฉ)
|
1516 |
-
let monthlySupport = 0;
|
1517 |
-
if (selectedComponents.support) {
|
1518 |
-
const card = document.querySelector(`[data-category="support"][data-id="${selectedComponents.support]}"]`);
|
1519 |
-
monthlySupport = parseFloat(card.dataset.cost);
|
1520 |
-
const name = card.querySelector('.option-name').textContent;
|
1521 |
-
|
1522 |
-
componentDetails.push({
|
1523 |
-
name: name,
|
1524 |
-
cost: monthlySupport,
|
1525 |
-
type: 'monthly'
|
1526 |
-
});
|
1527 |
-
}
|
1528 |
-
|
1529 |
-
// ์ถ๊ฐ ๊ธฐ๋ฅ ๋น์ฉ ๊ณ์ฐ
|
1530 |
-
selectedComponents.additional.forEach(additionalId => {
|
1531 |
-
const card = document.querySelector(`[data-category="additional"][data-id="${additionalId}"]`);
|
1532 |
-
const cost = parseFloat(card.dataset.cost);
|
1533 |
-
const time = parseFloat(card.dataset.time);
|
1534 |
-
const name = card.querySelector('.option-name').textContent;
|
1535 |
-
|
1536 |
-
totalInitialCost += cost;
|
1537 |
-
maxTime = Math.max(maxTime, time);
|
1538 |
-
|
1539 |
-
componentDetails.push({
|
1540 |
-
name: name,
|
1541 |
-
cost: cost,
|
1542 |
-
type: 'additional'
|
1543 |
-
});
|
1544 |
-
});
|
1545 |
-
|
1546 |
-
// ์๊ฐ ์ด์ ๋น์ฉ ๊ณ์ฐ
|
1547 |
-
const serverCost = totalInitialCost > 100 ? 5 : totalInitialCost > 50 ? 3 : totalInitialCost > 20 ? 2 : 1;
|
1548 |
-
const resourceCost = totalResourceCost;
|
1549 |
-
const maintenanceCost = totalInitialCost * 0.05; // ์ด๊ธฐ ๋น์ฉ์ 5%
|
1550 |
-
const totalMonthlyCost = serverCost + resourceCost + maintenanceCost + monthlySupport;
|
1551 |
-
|
1552 |
-
// ๊ฒฐ๊ณผ ํ์
|
1553 |
-
document.getElementById('initialCost').textContent = `$${totalInitialCost}K`;
|
1554 |
-
document.getElementById('devTime').textContent = `${maxTime}๊ฐ์`;
|
1555 |
-
document.getElementById('serverCost').textContent = `$${serverCost}K`;
|
1556 |
-
document.getElementById('resourceCost').textContent = `$${resourceCost.toFixed(1)}K`;
|
1557 |
-
document.getElementById('maintenanceCost').textContent = `$${maintenanceCost.toFixed(1)}K`;
|
1558 |
-
document.getElementById('totalMonthlyCost').textContent = `$${totalMonthlyCost.toFixed(1)}K`;
|
1559 |
-
|
1560 |
-
// ์ด ๋น์ฉ ๊ณ์ฐ (๊ธฐ๊ฐ๋ณ)
|
1561 |
-
updateTotalCost(totalInitialCost, totalMonthlyCost);
|
1562 |
-
|
1563 |
-
// ์ ํํ ๊ตฌ์ฑ ์์ ๋ชฉ๋ก ํ์
|
1564 |
-
displayComponentList(componentDetails);
|
1565 |
-
|
1566 |
-
// ๊ตฌ์ถ ๋ฐฉ์๋ณ ๋น๊ต
|
1567 |
-
compareBuilderMethods(totalInitialCost, totalMonthlyCost, maxTime);
|
1568 |
-
|
1569 |
-
// ์ฐจํธ ์
๋ฐ์ดํธ
|
1570 |
-
updateCustomChart(totalInitialCost, totalMonthlyCost);
|
1571 |
-
|
1572 |
-
// ๊ฒฐ๊ณผ ์น์
ํ์
|
1573 |
-
document.getElementById('customResult').style.display = 'block';
|
1574 |
-
}
|
1575 |
|
1576 |
-
// ์ด ๋น์ฉ ์
๋ฐ์ดํธ
|
1577 |
-
function updateTotalCost(initialCost, monthlyCost) {
|
1578 |
-
const totalCost = initialCost + (monthlyCost * currentPeriod);
|
1579 |
-
document.getElementById('totalCost').textContent = `$${totalCost.toFixed(1)}K`;
|
1580 |
-
}
|
1581 |
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
1633 |
-
|
1634 |
-
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
1638 |
-
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
1661 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
|
1668 |
-
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
1704 |
-
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1722 |
</body>
|
1723 |
-
</html>
|
1724 |
-
|
|
|
395 |
transition: all 0.3s ease;
|
396 |
position: relative;
|
397 |
overflow: hidden;
|
398 |
+
user-select: none;
|
399 |
}
|
400 |
|
401 |
.option-card.selected {
|
|
|
421 |
font-weight: bold;
|
422 |
}
|
423 |
|
424 |
+
.option-card:hover:not(.selected) {
|
425 |
border-color: #00d2ff;
|
426 |
background: rgba(255, 255, 255, 0.1);
|
427 |
transform: translateY(-2px);
|
|
|
1393 |
</div>
|
1394 |
</div>
|
1395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1396 |
|
|
|
|
|
|
|
|
|
|
|
1397 |
|
1398 |
+
</div>
|
1399 |
+
</div>
|
1400 |
+
|
1401 |
+
<!-- ๊ธฐ๊ฐ๋ณ ๋น์ฉ ์ฐจํธ -->
|
1402 |
+
<div class="chart-container">
|
1403 |
+
<canvas id="customChart"></canvas>
|
1404 |
+
</div>
|
1405 |
+
</div>
|
1406 |
+
</div>
|
1407 |
+
</div>
|
1408 |
+
</div>
|
1409 |
+
|
1410 |
+
<script>
|
1411 |
+
// ์ ์ญ ๋ณ์
|
1412 |
+
let selectedComponents = {
|
1413 |
+
service: [],
|
1414 |
+
db: null,
|
1415 |
+
auth: null,
|
1416 |
+
credit: null,
|
1417 |
+
payment: null,
|
1418 |
+
marketing: null,
|
1419 |
+
support: null,
|
1420 |
+
monitoring: null,
|
1421 |
+
additional: []
|
1422 |
+
};
|
1423 |
+
|
1424 |
+
let customChart = null;
|
1425 |
+
let currentPeriod = 3;
|
1426 |
+
|
1427 |
+
// ํ์ด์ง ๋ก๋ ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฑ๋ก
|
1428 |
+
document.addEventListener('DOMContentLoaded', function() {
|
1429 |
+
// ์ต์
์นด๋ ํด๋ฆญ ์ด๋ฒคํธ
|
1430 |
+
document.querySelectorAll('.option-card').forEach(card => {
|
1431 |
+
card.addEventListener('click', function(e) {
|
1432 |
+
e.preventDefault();
|
1433 |
+
const category = this.dataset.category;
|
1434 |
+
const id = this.dataset.id;
|
1435 |
+
|
1436 |
+
if (category === 'service' || category === 'additional') {
|
1437 |
+
// ๋ณต์ ์ ํ ๊ฐ๋ฅ
|
1438 |
+
this.classList.toggle('selected');
|
1439 |
+
|
1440 |
+
if (this.classList.contains('selected')) {
|
1441 |
+
if (!selectedComponents[category].includes(id)) {
|
1442 |
+
selectedComponents[category].push(id);
|
1443 |
+
}
|
1444 |
+
} else {
|
1445 |
+
const index = selectedComponents[category].indexOf(id);
|
1446 |
+
if (index > -1) {
|
1447 |
+
selectedComponents[category].splice(index, 1);
|
1448 |
+
}
|
1449 |
+
}
|
1450 |
+
} else {
|
1451 |
+
// ๋จ์ผ ์ ํ
|
1452 |
+
document.querySelectorAll(`[data-category="${category}"]`).forEach(c => {
|
1453 |
+
c.classList.remove('selected');
|
1454 |
+
});
|
1455 |
+
|
1456 |
+
this.classList.add('selected');
|
1457 |
+
selectedComponents[category] = id;
|
1458 |
+
}
|
1459 |
+
|
1460 |
+
console.log('Selected:', selectedComponents); // ๋๋ฒ๊น
์ฉ
|
1461 |
+
});
|
1462 |
+
});
|
1463 |
+
});
|
1464 |
+
|
1465 |
+
// ํญ ์ ํ ํจ์
|
1466 |
+
function switchTab(tabId) {
|
1467 |
+
document.querySelectorAll('.tab').forEach(tab => {
|
1468 |
+
tab.classList.remove('active');
|
1469 |
+
});
|
1470 |
+
document.querySelectorAll('.tab-content').forEach(content => {
|
1471 |
+
content.classList.remove('active');
|
1472 |
+
});
|
1473 |
+
|
1474 |
+
event.target.classList.add('active');
|
1475 |
+
document.getElementById(tabId).classList.add('active');
|
1476 |
+
}
|
1477 |
+
|
1478 |
+
// ์ปค์คํ
๋น์ฉ ๊ณ์ฐ ํจ์
|
1479 |
+
function calculateCustomCost() {
|
1480 |
+
let totalInitialCost = 0;
|
1481 |
+
let totalResourceCost = 0;
|
1482 |
+
let maxTime = 0;
|
1483 |
+
let componentDetails = [];
|
1484 |
+
|
1485 |
+
// ์๋น์ค ๋น์ฉ ๊ณ์ฐ
|
1486 |
+
selectedComponents.service.forEach(serviceId => {
|
1487 |
+
const card = document.querySelector(`[data-id="${serviceId}"]`);
|
1488 |
+
const cost = parseFloat(card.dataset.cost);
|
1489 |
+
const time = parseFloat(card.dataset.time);
|
1490 |
+
const resource = parseFloat(card.dataset.resource) || 0;
|
1491 |
+
const name = card.querySelector('.option-name').textContent;
|
1492 |
+
|
1493 |
+
totalInitialCost += cost;
|
1494 |
+
totalResourceCost += resource;
|
1495 |
+
maxTime = Math.max(maxTime, time);
|
1496 |
+
|
1497 |
+
componentDetails.push({
|
1498 |
+
name: name,
|
1499 |
+
cost: cost,
|
1500 |
+
type: 'service'
|
1501 |
+
});
|
1502 |
+
});
|
1503 |
+
|
1504 |
+
// ๊ธฐํ ๊ตฌ์ฑ ์์ ๋น์ฉ ๊ณ์ฐ
|
1505 |
+
['db', 'auth', 'credit', 'payment', 'marketing', 'monitoring'].forEach(category => {
|
1506 |
+
if (selectedComponents[category]) {
|
1507 |
+
const card = document.querySelector(`[data-category="${category}"][data-id="${selectedComponents[category]}"]`);
|
1508 |
+
const cost = parseFloat(card.dataset.cost);
|
1509 |
+
const time = parseFloat(card.dataset.time);
|
1510 |
+
const name = card.querySelector('.option-name').textContent;
|
1511 |
+
|
1512 |
+
totalInitialCost += cost;
|
1513 |
+
maxTime = Math.max(maxTime, time);
|
1514 |
+
|
1515 |
+
componentDetails.push({
|
1516 |
+
name: name,
|
1517 |
+
cost: cost,
|
1518 |
+
type: category
|
1519 |
+
});
|
1520 |
+
}
|
1521 |
+
});
|
1522 |
+
|
1523 |
+
// ์ง์ ์๋น์ค (์๊ฐ ๋น์ฉ)
|
1524 |
+
let monthlySupport = 0;
|
1525 |
+
if (selectedComponents.support) {
|
1526 |
+
const card = document.querySelector(`[data-category="support"][data-id="${selectedComponents.support]}"]`);
|
1527 |
+
monthlySupport = parseFloat(card.dataset.cost);
|
1528 |
+
const name = card.querySelector('.option-name').textContent;
|
1529 |
+
|
1530 |
+
componentDetails.push({
|
1531 |
+
name: name,
|
1532 |
+
cost: monthlySupport,
|
1533 |
+
type: 'monthly'
|
1534 |
+
});
|
1535 |
+
}
|
1536 |
+
|
1537 |
+
// ์ถ๊ฐ ๊ธฐ๋ฅ ๋น์ฉ ๊ณ์ฐ
|
1538 |
+
selectedComponents.additional.forEach(additionalId => {
|
1539 |
+
const card = document.querySelector(`[data-category="additional"][data-id="${additionalId}"]`);
|
1540 |
+
const cost = parseFloat(card.dataset.cost);
|
1541 |
+
const time = parseFloat(card.dataset.time);
|
1542 |
+
const name = card.querySelector('.option-name').textContent;
|
1543 |
+
|
1544 |
+
totalInitialCost += cost;
|
1545 |
+
maxTime = Math.max(maxTime, time);
|
1546 |
+
|
1547 |
+
componentDetails.push({
|
1548 |
+
name: name,
|
1549 |
+
cost: cost,
|
1550 |
+
type: 'additional'
|
1551 |
+
});
|
1552 |
+
});
|
1553 |
+
|
1554 |
+
// ์๊ฐ ์ด์ ๋น์ฉ ๊ณ์ฐ
|
1555 |
+
const serverCost = totalInitialCost > 100 ? 5 : totalInitialCost > 50 ? 3 : totalInitialCost > 20 ? 2 : 1;
|
1556 |
+
const resourceCost = totalResourceCost;
|
1557 |
+
const maintenanceCost = totalInitialCost * 0.05; // ์ด๊ธฐ ๋น์ฉ์ 5%
|
1558 |
+
const totalMonthlyCost = serverCost + resourceCost + maintenanceCost + monthlySupport;
|
1559 |
+
|
1560 |
+
// ๊ฒฐ๊ณผ ํ์
|
1561 |
+
document.getElementById('initialCost').textContent = `$${totalInitialCost}K`;
|
1562 |
+
document.getElementById('devTime').textContent = `${maxTime}๊ฐ์`;
|
1563 |
+
document.getElementById('serverCost').textContent = `$${serverCost}K`;
|
1564 |
+
document.getElementById('resourceCost').textContent = `$${resourceCost.toFixed(1)}K`;
|
1565 |
+
document.getElementById('maintenanceCost').textContent = `$${maintenanceCost.toFixed(1)}K`;
|
1566 |
+
document.getElementById('totalMonthlyCost').textContent = `$${totalMonthlyCost.toFixed(1)}K`;
|
1567 |
+
|
1568 |
+
// ์ด ๋น์ฉ ๊ณ์ฐ (๊ธฐ๊ฐ๋ณ)
|
1569 |
+
updateTotalCost(totalInitialCost, totalMonthlyCost);
|
1570 |
+
|
1571 |
+
// ์ ํํ ๊ตฌ์ฑ ์์ ๋ชฉ๋ก ํ์
|
1572 |
+
displayComponentList(componentDetails);
|
1573 |
+
|
1574 |
+
// ๊ตฌ์ถ ๋ฐฉ์๋ณ ๋น๊ต
|
1575 |
+
compareBuilderMethods(totalInitialCost, totalMonthlyCost, maxTime);
|
1576 |
+
|
1577 |
+
// ์ฐจํธ ์
๋ฐ์ดํธ
|
1578 |
+
updateCustomChart(totalInitialCost, totalMonthlyCost);
|
1579 |
+
|
1580 |
+
// ๊ฒฐ๊ณผ ์น์
ํ์
|
1581 |
+
document.getElementById('customResult').style.display = 'block';
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
// ์ด ๋น์ฉ ์
๋ฐ์ดํธ
|
1585 |
+
function updateTotalCost(initialCost, monthlyCost) {
|
1586 |
+
const totalCost = initialCost + (monthlyCost * currentPeriod);
|
1587 |
+
document.getElementById('totalCost').textContent = `$${totalCost.toFixed(1)}K`;
|
1588 |
+
}
|
1589 |
+
|
1590 |
+
// ๊ตฌ์ฑ ์์ ๋ชฉ๋ก ํ์
|
1591 |
+
function displayComponentList(components) {
|
1592 |
+
const listContainer = document.getElementById('componentList');
|
1593 |
+
listContainer.innerHTML = '';
|
1594 |
+
|
1595 |
+
components.forEach(component => {
|
1596 |
+
const item = document.createElement('div');
|
1597 |
+
item.className = 'component-list-item';
|
1598 |
+
|
1599 |
+
let costDisplay = component.type === 'monthly'
|
1600 |
+
? `์ $${component.cost}K`
|
1601 |
+
: `$${component.cost}K`;
|
1602 |
+
|
1603 |
+
item.innerHTML = `
|
1604 |
+
<span>${component.name}</span>
|
1605 |
+
<span style="color: #00d2ff;">${costDisplay}</span>
|
1606 |
+
`;
|
1607 |
+
|
1608 |
+
listContainer.appendChild(item);
|
1609 |
+
});
|
1610 |
+
}
|
1611 |
+
|
1612 |
+
// ๊ตฌ์ถ ๋ฐฉ์๋ณ ๋น๊ต
|
1613 |
+
function compareBuilderMethods(initialCost, monthlyCost, devTime) {
|
1614 |
+
// ์ธ์ฃผ ์ฉ์ญ ๊ฐ๋ฐ
|
1615 |
+
const outsourceInitial = initialCost;
|
1616 |
+
const outsourceMonthly = monthlyCost;
|
1617 |
+
const outsourceTotal = outsourceInitial + (outsourceMonthly * currentPeriod);
|
1618 |
+
|
1619 |
+
// ์์ฒด ์ธ๋ ฅ ๊ฐ๋ฐ
|
1620 |
+
const developerSalary = 10; // ์ $10K
|
1621 |
+
const teamSize = Math.ceil(initialCost / 50); // $50K๋น 1๋ช
|
1622 |
+
const inhouseDevTime = Math.max(devTime * 1.5, 3); // ์ต์ 3๊ฐ์
|
1623 |
+
const inhouseInitial = developerSalary * teamSize * inhouseDevTime;
|
1624 |
+
const inhouseMonthly = monthlyCost + (developerSalary * Math.ceil(teamSize / 2)); // ์ ์ง๋ณด์ ์ธ๋ ฅ
|
1625 |
+
const inhouseTotal = inhouseInitial + (inhouseMonthly * currentPeriod);
|
1626 |
+
|
1627 |
+
// ํ๋ซํผ ๋์ฌ
|
1628 |
+
const platformInitial = 1; // ์ค์ ๋น์ฉ
|
1629 |
+
const platformMonthly = monthlyCost * 2 + 5; // ํ๋ซํผ ์์๋ฃ ํฌํจ
|
1630 |
+
const platformTotal = platformInitial + (platformMonthly * currentPeriod);
|
1631 |
+
|
1632 |
+
// ๊ฒฐ๊ณผ ํ์
|
1633 |
+
document.getElementById('outsourceInitial').textContent = `$${outsourceInitial}K`;
|
1634 |
+
document.getElementById('outsourceMonthly').textContent = `$${outsourceMonthly.toFixed(1)}K`;
|
1635 |
+
document.getElementById('outsourceTotal').textContent = `$${outsourceTotal.toFixed(1)}K`;
|
1636 |
+
|
1637 |
+
document.getElementById('inhouseInitial').textContent = `$${inhouseInitial}K`;
|
1638 |
+
document.getElementById('inhouseMonthly').textContent = `$${inhouseMonthly.toFixed(1)}K`;
|
1639 |
+
document.getElementById('inhouseTotal').textContent = `$${inhouseTotal.toFixed(1)}K`;
|
1640 |
+
|
1641 |
+
document.getElementById('platformInitial').textContent = `$${platformInitial}K`;
|
1642 |
+
document.getElementById('platformMonthly').textContent = `$${platformMonthly.toFixed(1)}K`;
|
1643 |
+
document.getElementById('platformTotal').textContent = `$${platformTotal.toFixed(1)}K`;
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
// ์ฐจํธ ์
๋ฐ์ดํธ
|
1647 |
+
function updateCustomChart(initialCost, monthlyCost) {
|
1648 |
+
const ctx = document.getElementById('customChart').getContext('2d');
|
1649 |
+
|
1650 |
+
if (customChart) {
|
1651 |
+
customChart.destroy();
|
1652 |
+
}
|
1653 |
+
|
1654 |
+
const months = Array.from({length: 12}, (_, i) => `${i + 1}๊ฐ์`);
|
1655 |
+
const outsourceData = months.map((_, i) => initialCost + (monthlyCost * (i + 1)));
|
1656 |
+
const inhouseData = months.map((_, i) => {
|
1657 |
+
const teamSize = Math.ceil(initialCost / 50);
|
1658 |
+
const inhouseInitial = 10 * teamSize * 3;
|
1659 |
+
const inhouseMonthly = monthlyCost + (10 * Math.ceil(teamSize / 2));
|
1660 |
+
return inhouseInitial + (inhouseMonthly * (i + 1));
|
1661 |
+
});
|
1662 |
+
const platformData = months.map((_, i) => 1 + ((monthlyCost * 2 + 5) * (i + 1)));
|
1663 |
+
|
1664 |
+
customChart = new Chart(ctx, {
|
1665 |
+
type: 'line',
|
1666 |
+
data: {
|
1667 |
+
labels: months,
|
1668 |
+
datasets: [{
|
1669 |
+
label: '์ธ์ฃผ ์ฉ์ญ ๊ฐ๋ฐ',
|
1670 |
+
data: outsourceData,
|
1671 |
+
borderColor: '#764ba2',
|
1672 |
+
backgroundColor: 'rgba(118, 75, 162, 0.1)',
|
1673 |
+
tension: 0.4
|
1674 |
+
}, {
|
1675 |
+
label: '์์ฒด ์ธ๋ ฅ ๊ฐ๋ฐ',
|
1676 |
+
data: inhouseData,
|
1677 |
+
borderColor: '#f5576c',
|
1678 |
+
backgroundColor: 'rgba(245, 87, 108, 0.1)',
|
1679 |
+
tension: 0.4
|
1680 |
+
}, {
|
1681 |
+
label: 'ํ๋ซํผ ๋์ฌ',
|
1682 |
+
data: platformData,
|
1683 |
+
borderColor: '#4facfe',
|
1684 |
+
backgroundColor: 'rgba(79, 172, 254, 0.1)',
|
1685 |
+
tension: 0.4
|
1686 |
+
}]
|
1687 |
+
},
|
1688 |
+
options: {
|
1689 |
+
responsive: true,
|
1690 |
+
maintainAspectRatio: false,
|
1691 |
+
plugins: {
|
1692 |
+
legend: {
|
1693 |
+
labels: {
|
1694 |
+
color: '#ffffff'
|
1695 |
+
}
|
1696 |
+
},
|
1697 |
+
tooltip: {
|
1698 |
+
callbacks: {
|
1699 |
+
label: function(context) {
|
1700 |
+
return context.dataset.label + ': $' + context.parsed.y.toFixed(1) + 'K';
|
1701 |
+
}
|
1702 |
+
}
|
1703 |
+
}
|
1704 |
+
},
|
1705 |
+
scales: {
|
1706 |
+
x: {
|
1707 |
+
grid: {
|
1708 |
+
color: 'rgba(255, 255, 255, 0.1)'
|
1709 |
+
},
|
1710 |
+
ticks: {
|
1711 |
+
color: '#a8a8b3'
|
1712 |
+
}
|
1713 |
+
},
|
1714 |
+
y: {
|
1715 |
+
grid: {
|
1716 |
+
color: 'rgba(255, 255, 255, 0.1)'
|
1717 |
+
},
|
1718 |
+
ticks: {
|
1719 |
+
color: '#a8a8b3',
|
1720 |
+
callback: function(value) {
|
1721 |
+
return '$' + value + 'K';
|
1722 |
+
}
|
1723 |
+
}
|
1724 |
+
}
|
1725 |
+
}
|
1726 |
+
}
|
1727 |
+
});
|
1728 |
+
}
|
1729 |
+
</script>
|
1730 |
</body>
|
1731 |
+
</html>
|
|