-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
135 lines (112 loc) · 4.05 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Populate the inputs from the querystring if set
addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams(window.location.search);
if (params.has('usage')) {
document.getElementById('usage').value = params.get('usage');
}
if (params.has('discountedRate')) {
document.getElementById('discountedRate').value = params.get('discountedRate');
}
if (params.has('fullPrice')) {
document.getElementById('fullPrice').value = params.get('fullPrice');
}
if (params.has('currency')) {
document.getElementById('currency').value = params.get('currency');
}
calculateOptimalCommitment();
});
function getCurrencyDisplay(currencyCode) {
if (currencyCode === 'GBP') {
return '£';
} else if (currencyCode === 'USD') {
return '$';
}
return '';
}
let chart = undefined;
function calculateCost(discountedRate, fullPrice, usageData, commitment) {
let totalCost = 0;
for (let usage of usageData) {
if (usage <= commitment) {
totalCost += commitment * discountedRate;
} else {
totalCost += commitment * discountedRate + (usage - commitment) * fullPrice;
}
}
return totalCost;
}
function calculateOptimalCommitment() {
// Get the inputs
const usageData = document.getElementById('usage').value.split(',').map(Number);
const discountedRate = parseFloat(document.getElementById('discountedRate').value);
const fullPrice = parseFloat(document.getElementById('fullPrice').value);
let _calculateCost = function(commitment) {
return calculateCost(discountedRate, fullPrice, usageData, commitment);
}
const minCommitment = Math.min(...usageData);
const maxCommitment = Math.max(...usageData);
const step = 1;
let optimalCommitment = minCommitment;
let minTotalCost = Infinity;
let evaluatedCommitments = [];
// Iterate through possible commitment levels
for (let commitment = minCommitment; commitment <= maxCommitment; commitment += step) {
let totalCost = _calculateCost(commitment);
evaluatedCommitments.push({
commitment,
totalCost,
});
if (totalCost < minTotalCost) {
minTotalCost = totalCost;
optimalCommitment = commitment;
}
}
let currency = document.getElementById('currency').value;
let currencyDisplay = getCurrencyDisplay(currency);
// Display the result
document.getElementById('result').innerText = [
`Optimal Commitment Level: ${optimalCommitment.toFixed(0)}`,
`Minimum Total Cost: ${currencyDisplay}${minTotalCost.toFixed(2)}`,
`Average Cost: ${currencyDisplay}${(minTotalCost / usageData.length).toFixed(2)}`,
'',
`One lower (${optimalCommitment - 1}) cost: ${currencyDisplay}${_calculateCost(optimalCommitment - 1).toFixed(2)}`,
`One higher (${optimalCommitment + 1}) cost: ${currencyDisplay}${_calculateCost(optimalCommitment + 1).toFixed(2)}`,
].join("\n");
if (!chart) {
chart = new Chart(document.getElementById('chart'), {
type: 'scatter',
data: {
datasets: [{
label: 'Total cost',
data: evaluatedCommitments,
}],
},
options: {
parsing: {
xAxisKey: 'commitment',
yAxisKey: 'totalCost',
},
},
});
} else {
chart.data = {
datasets: [{
label: 'Total cost',
data: evaluatedCommitments,
}],
};
chart.update();
}
// And show the link to this result using the querystring
function showLink() {
const usage = document.getElementById('usage').value;
const discountedRate = document.getElementById('discountedRate').value;
const fullPrice = document.getElementById('fullPrice').value;
const url = new URL(window.location);
url.searchParams.set('usage', usage);
url.searchParams.set('discountedRate', discountedRate);
url.searchParams.set('fullPrice', fullPrice);
document.getElementById('link').href = url.toString();
}
showLink();
}