I am trying to make an Intrest calculator with histogram plotted I have found the scripts online as I am new to javaScript. So the output I want is like this Desired Outpyt and the output I am getting is this comming output So I really need some help One, the blue buttons with and - signs are crazy out. secondly, the histogram is not showing.
So please help me with this I will grateful.
I have copy-pasted the code from this site
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css" >
<meta charset="UTF-8">
<title>Savings Calculator</title>
</head>
<body>
<div >
<div >
<div >
<div >
<label for="initial_deposit">Initial Deposit</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="initial_deposit">−</button>
</div>
<input id="initial_deposit" type="text" name="initial_deposit" min="100" max="1000000" step="100" value="$5000" data-value="5000" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="initial_deposit"> </button>
</div>
</div>
</div>
</div>
<div >
<label for="contribution_amount">Contributions</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="contribution_amount">−</button>
</div>
<input id="contribution_amount" type="text" name="contribution_amount" min="0" max="10000" step="50" value="$100" data-value="100" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="contribution_amount"> </button>
</div>
</div>
</div>
<div >
<input id="contribution_period_monthly" type="radio" name="contribution_period" value="12" checked>
<label for="contribution_period_monthly">monthly</label>
</div>
<div >
<input id="contribution_period_annually" type="radio" name="contribution_period" value="1">
<label for="contribution_period_annually">annually</label>
</div>
</div>
<div >
<label for="investment_timespan">Investment Time Span</label>
<div >
<div >
<input id="investment_timespan" type="range" name="investment_timespan" min="2" max="50" step="1" value="5">
</div>
</div>
<span id="investment_timespan_text">5 years</span>
</div>
<div >
<label for="estimated_return">Estimated Rate of Return</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="estimated_return">−</button>
</div>
<input id="estimated_return" type="text" name="estimated_return" min="0" max="50" step="0.25" value="5.00%" data-value="5.00" data-append="%">
<div >
<button type="button" data-counter="add" data-field="estimated_return"> </button>
</div>
</div>
</div>
</div>
<div >
<div >
<div>Compound Frequency</div>
<div >
<input id="compound_period_daily" type="radio" name="compound_period" value="365">
<label for="compound_period_daily">daily</label>
</div>
<div >
<input id="compound_period_monthly" type="radio" name="compound_period" value="12" checked>
<label for="compound_period_monthly">monthly</label>
</div>
<div >
<input id="compound_period_annually" type="radio" name="compound_period" value="1">
<label for="compound_period_annually">annually</label>
</div>
</div>
</div>
</div>
<div >
<div>Future Balance</div>
<div id="future_balance">?</div>
<canvas id="myChart"></canvas>
</div>
</div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"> </script>
</html>
Script.js
(function () {
var initial_deposit = document.querySelector('#initial_deposit'),
contribution_amount = document.querySelector('#contribution_amount'),
investment_timespan = document.querySelector('#investment_timespan'),
investment_timespan_text = document.querySelector('#investment_timespan_text'),
estimated_return = document.querySelector('#estimated_return'),
future_balance = document.querySelector('#future_balance');
function updateValue(element, action) {
var min = parseFloat(element.getAttribute('min')),
max = parseFloat(element.getAttribute('max')),
step = parseFloat(element.getAttribute('step')) || 1,
oldValue = element.dataset.value || element.defaultValue || 0,
newValue = parseFloat(element.value.replace(/\$/, ''));
if (isNaN(parseFloat(newValue))) {
newValue = oldValue;
} else {
if (action == 'add') {
newValue = step;
} else if (action == 'sub') {
newValue -= step;
}
newValue = newValue < min ? min : newValue > max ? max : newValue;
}
element.dataset.value = newValue;
element.value = (element.dataset.prepend || '') newValue (element.dataset.append || '');
updateChart();
}
function getChartData() {
var P = parseFloat(initial_deposit.dataset.value), // Principal
r = parseFloat(estimated_return.dataset.value / 100), // Annual Interest Rate
c = parseFloat(contribution_amount.dataset.value), // Contribution Amount
n = parseInt(document.querySelector('[name="compound_period"]:checked').value), // Compound Period
n2 = parseInt(document.querySelector('[name="contribution_period"]:checked').value), // Contribution Period
t = parseInt(investment_timespan.value), // Investment Time Span
currentYear = (new Date()).getFullYear()
;
var labels = [];
for (var year = currentYear; year < currentYear t; year ) {
labels.push(year);
}
var principal_dataset = {
label: 'Total Principal',
backgroundColor: 'rgb(0, 123, 255)',
data: []
};
var interest_dataset = {
label: "Total Interest",
backgroundColor: 'rgb(23, 162, 184)',
data: []
};
for (var i = 1; i <= t; i ) {
var principal = P ( c * n2 * i ),
interest = 0,
balance = principal;
if (r) {
var x = Math.pow(1 r / n, n * i),
compound_interest = P * x,
contribution_interest = c * (x - 1) / (r / n2);
interest = (compound_interest contribution_interest - principal).toFixed(0)
balance = (compound_interest contribution_interest).toFixed(0);
}
future_balance.innerHTML = '$' balance;
principal_dataset.data.push(principal);
interest_dataset.data.push(interest);
}
return {
labels: labels,
datasets: [principal_dataset, interest_dataset]
}
}
function updateChart() {
var data = getChartData();
chart.data.labels = data.labels;
chart.data.datasets[0].data = data.datasets[0].data;
chart.data.datasets[1].data = data.datasets[1].data;
chart.update();
}
initial_deposit.addEventListener('change', function () {
updateValue(this);
});
contribution_amount.addEventListener('change', function () {
updateValue(this);
});
estimated_return.addEventListener('change', function () {
updateValue(this);
});
investment_timespan.addEventListener('change', function () {
investment_timespan_text.innerHTML = this.value ' years';
updateChart();
});
investment_timespan.addEventListener('input', function () {
investment_timespan_text.innerHTML = this.value ' years';
});
var radios = document.querySelectorAll('[name="contribution_period"], [name="compound_period"]');
for (var j = 0; j < radios.length; j ) {
radios[j].addEventListener('change', updateChart);
}
var buttons = document.querySelectorAll('[data-counter]');
for (var i = 0; i < buttons.length; i ) {
var button = buttons[i];
button.addEventListener('click', function () {
var field = document.querySelector('[name="' this.dataset.field '"]'),
action = this.dataset.counter;
if (field) {
updateValue(field, action);
}
});
}
var ctx = document.getElementById('myChart').getContext('2d'),
chart = new Chart(ctx, {
type: 'bar',
data: getChartData(),
options: {
legend: {
display: false
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label ': $' tooltipItem.yLabel;
}
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Year'
}
}],
yAxes: [{
stacked: true,
ticks: {
callback: function (value) {
return '$' value;
}
},
scaleLabel: {
display: true,
labelString: 'Balance'
}
}]
}
}
});
})();
CodePudding user response:
Please use the Symbols and delimiters on the returns. the errors are commented and the correction given.
// return data.datasets[tooltipItem.datasetIndex].label ':
// tooltipItem.yLabel;
return data.datasets[tooltipItem.datasetIndex].label ': ' tooltipItem.yLabel;
// future_balance.innerHTML = '
// balance;
future_balance.innerHTML = '$' balance;
// return '
// value;
return '$' value;
CodePudding user response:
You need to do four things
- Add
bootstrap.min.css
Replace
future_balance.innerHTML = ' balance;
with
future_balance.innerHTML = '' balance;
on line 74
Replace
return data.datasets[tooltipItem.datasetIndex].label ': tooltipItem.yLabel;
with
return data.datasets[tooltipItem.datasetIndex].label ':' tooltipItem.yLabel;
on line 148
Replace
return ' value;
with
return '' value;
on line 166
(function() {
var initial_deposit = document.querySelector('#initial_deposit'),
contribution_amount = document.querySelector('#contribution_amount'),
investment_timespan = document.querySelector('#investment_timespan'),
investment_timespan_text = document.querySelector('#investment_timespan_text'),
estimated_return = document.querySelector('#estimated_return'),
future_balance = document.querySelector('#future_balance');
function updateValue(element, action) {
var min = parseFloat(element.getAttribute('min')),
max = parseFloat(element.getAttribute('max')),
step = parseFloat(element.getAttribute('step')) || 1,
oldValue = element.dataset.value || element.defaultValue || 0,
newValue = parseFloat(element.value.replace(/$/, ''));
if (isNaN(parseFloat(newValue))) {
newValue = oldValue;
} else {
if (action == 'add') {
newValue = step;
} else if (action == 'sub') {
newValue -= step;
}
newValue = newValue < min ? min : newValue > max ? max : newValue;
}
element.dataset.value = newValue;
element.value = (element.dataset.prepend || '') newValue (element.dataset.append || '');
updateChart();
}
function getChartData() {
var P = parseFloat(initial_deposit.dataset.value), // Principal
r = parseFloat(estimated_return.dataset.value / 100), // Annual Interest Rate
c = parseFloat(contribution_amount.dataset.value), // Contribution Amount
n = parseInt(document.querySelector('[name="compound_period"]:checked').value), // Compound Period
n2 = parseInt(document.querySelector('[name="contribution_period"]:checked').value), // Contribution Period
t = parseInt(investment_timespan.value), // Investment Time Span
currentYear = (new Date()).getFullYear();
var labels = [];
for (var year = currentYear; year < currentYear t; year ) {
labels.push(year);
}
var principal_dataset = {
label: 'Total Principal',
backgroundColor: 'rgb(0, 123, 255)',
data: []
};
var interest_dataset = {
label: "Total Interest",
backgroundColor: 'rgb(23, 162, 184)',
data: []
};
for (var i = 1; i <= t; i ) {
var principal = P (c * n2 * i),
interest = 0,
balance = principal;
if (r) {
var x = Math.pow(1 r / n, n * i),
compound_interest = P * x,
contribution_interest = c * (x - 1) / (r / n2);
interest = (compound_interest contribution_interest - principal).toFixed(0)
balance = (compound_interest contribution_interest).toFixed(0);
}
future_balance.innerHTML = '' balance;
principal_dataset.data.push(principal);
interest_dataset.data.push(interest);
}
return {
labels: labels,
datasets: [principal_dataset, interest_dataset]
}
}
function updateChart() {
var data = getChartData();
chart.data.labels = data.labels;
chart.data.datasets[0].data = data.datasets[0].data;
chart.data.datasets[1].data = data.datasets[1].data;
chart.update();
}
initial_deposit.addEventListener('change', function() {
updateValue(this);
});
contribution_amount.addEventListener('change', function() {
updateValue(this);
});
estimated_return.addEventListener('change', function() {
updateValue(this);
});
investment_timespan.addEventListener('change', function() {
investment_timespan_text.innerHTML = this.value ' years';
updateChart();
});
investment_timespan.addEventListener('input', function() {
investment_timespan_text.innerHTML = this.value ' years';
});
var radios = document.querySelectorAll('[name="contribution_period"], [name="compound_period"]');
for (var j = 0; j < radios.length; j ) {
radios[j].addEventListener('change', updateChart);
}
var buttons = document.querySelectorAll('[data-counter]');
for (var i = 0; i < buttons.length; i ) {
var button = buttons[i];
button.addEventListener('click', function() {
var field = document.querySelector('[name="' this.dataset.field '"]'),
action = this.dataset.counter;
if (field) {
updateValue(field, action);
}
});
}
var ctx = document.getElementById('myChart').getContext('2d'),
chart = new Chart(ctx, {
type: 'bar',
data: getChartData(),
options: {
legend: {
display: false
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label ':' tooltipItem.yLabel;
}
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Year'
}
}],
yAxes: [{
stacked: true,
ticks: {
callback: function(value) {
return '' value;
}
},
scaleLabel: {
display: true,
labelString: 'Balance'
}
}]
}
}
});
})();
body {
margin-top: 60px;
}
<div >
<div >
<div >
<div >
<label for="initial_deposit">Initial Deposit</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="initial_deposit">−</button>
</div>
<input id="initial_deposit" type="text" name="initial_deposit" min="100" max="1000000" step="100" value="$5000" data-value="5000" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="initial_deposit"> </button>
</div>
</div>
</div>
</div>
<div >
<label for="contribution_amount">Contributions</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="contribution_amount">−</button>
</div>
<input id="contribution_amount" type="text" name="contribution_amount" min="0" max="10000" step="50" value="$100" data-value="100" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="contribution_amount"> </button>
</div>
</div>
</div>
<div >
<input id="contribution_period_monthly" type="radio" name="contribution_period" value="12" checked>
<label for="contribution_period_monthly">monthly</label>
</div>
<div >
<input id="contribution_period_annually" type="radio" name="contribution_period" value="1">
<label for="contribution_period_annually">annually</label>
</div>
</div>
<div >
<label for="investment_timespan">Investment Time Span</label>
<div >
<div >
<input id="investment_timespan" type="range" name="investment_timespan" min="2" max="50" step="1" value="5">
</div>
</div>
<span id="investment_timespan_text">5 years</span>
</div>
<div >
<label for="estimated_return">Estimated Rate of Return</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="estimated_return">−</button>
</div>
<input id="estimated_return" type="text" name="estimated_return" min="0" max="50" step="0.25" value="5.00%" data-value="5.00" data-append="%">
<div >
<button type="button" data-counter="add" data-field="estimated_return"> </button>
</div>
</div>
</div>
</div>
<div >
<div >
<div>Compound Frequency</div>
<div >
<input id="compound_period_daily" type="radio" name="compound_period" value="365">
<label for="compound_period_daily">daily</label>
</div>
<div >
<input id="compound_period_monthly" type="radio" name="compound_period" value="12" checked>
<label for="compound_period_monthly">monthly</label>
</div>
<div >
<input id="compound_period_annually" type="radio" name="compound_period" value="1">
<label for="compound_period_annually">annually</label>
</div>
</div>
</div>
</div>
<div >
<div>Future Balance</div>
<div id="future_balance">?</div>
<canvas id="myChart"></canvas>
</div>
</div>
</div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
CodePudding user response:
These Things were wrong in your attempt
- Bootstrap Reference should be a
link
instead ofscript
. your code should be
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css" rel="stylesheet"/>
instead of
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css"></script>
Make sure your HTML HIERARCHY is alright
<head> <link href="link to file" rel="stylesheet"> </head> <body> your code <script src=""> </body>
Your chart is not workig because you have syntax errors in Javascript code. there are unclosed
''
at line 74,148,166
future_balance.innerHTML = ' balance; //74 return data.datasets[tooltipItem.datasetIndex].label ': tooltipItem.yLabel;//148 return ' value;//166
handle them as
future_balance.innerHTML = '' balance; //74 return data.datasets[tooltipItem.datasetIndex].label ':' tooltipItem.yLabel;//148 return '' value;//166
Here is your working code
If you want to copy paste running code here it is
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div >
<div >
<div >
<div >
<label for="initial_deposit">Initial Deposit</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="initial_deposit">−</button>
</div>
<input id="initial_deposit" type="text" name="initial_deposit" min="100" max="1000000" step="100" value="$5000" data-value="5000" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="initial_deposit"> </button>
</div>
</div>
</div>
</div>
<div >
<label for="contribution_amount">Contributions</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="contribution_amount">−</button>
</div>
<input id="contribution_amount" type="text" name="contribution_amount" min="0" max="10000" step="50" value="$100" data-value="100" data-prepend="$">
<div >
<button type="button" data-counter="add" data-field="contribution_amount"> </button>
</div>
</div>
</div>
<div >
<input id="contribution_period_monthly" type="radio" name="contribution_period" value="12" checked>
<label for="contribution_period_monthly">monthly</label>
</div>
<div >
<input id="contribution_period_annually" type="radio" name="contribution_period" value="1">
<label for="contribution_period_annually">annually</label>
</div>
</div>
<div >
<label for="investment_timespan">Investment Time Span</label>
<div >
<div >
<input id="investment_timespan" type="range" name="investment_timespan" min="2" max="50" step="1" value="5">
</div>
</div>
<span id="investment_timespan_text">5 years</span>
</div>
<div >
<label for="estimated_return">Estimated Rate of Return</label>
<div >
<div >
<div >
<button type="button" data-counter="sub" data-field="estimated_return">−</button>
</div>
<input id="estimated_return" type="text" name="estimated_return" min="0" max="50" step="0.25" value="5.00%" data-value="5.00" data-append="%">
<div >
<button type="button" data-counter="add" data-field="estimated_return"> </button>
</div>
</div>
</div>
</div>
<div >
<div >
<div>Compound Frequency</div>
<div >
<input id="compound_period_daily" type="radio" name="compound_period" value="365">
<label for="compound_period_daily">daily</label>
</div>
<div >
<input id="compound_period_monthly" type="radio" name="compound_period" value="12" checked>
<label for="compound_period_monthly">monthly</label>
</div>
<div >
<input id="compound_period_annually" type="radio" name="compound_period" value="1">
<label for="compound_period_annually">annually</label>
</div>
</div>
</div>
</div>
<div >
<div>Future Balance</div>
<div id="future_balance">?</div>
<canvas id="myChart"></canvas>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
<script>
(function() {
var initial_deposit = document.querySelector('#initial_deposit'),
contribution_amount = document.querySelector('#contribution_amount'),
investment_timespan = document.querySelector('#investment_timespan'),
investment_timespan_text = document.querySelector('#investment_timespan_text'),
estimated_return = document.querySelector('#estimated_return'),
future_balance = document.querySelector('#future_balance');
function updateValue(element, action) {
var min = parseFloat(element.getAttribute('min')),
max = parseFloat(element.getAttribute('max')),
step = parseFloat(element.getAttribute('step')) || 1,
oldValue = element.dataset.value || element.defaultValue || 0,
newValue = parseFloat(element.value.replace(/$/, ''));
if (isNaN(parseFloat(newValue))) {
newValue = oldValue;
} else {
if (action == 'add') {
newValue = step;
} else if (action == 'sub') {
newValue -= step;
}
newValue = newValue < min ? min : newValue > max ? max : newValue;
}
element.dataset.value = newValue;
element.value = (element.dataset.prepend || '') newValue (element.dataset.append || '');
updateChart();
}
function getChartData() {
var P = parseFloat(initial_deposit.dataset.value), // Principal
r = parseFloat(estimated_return.dataset.value / 100), // Annual Interest Rate
c = parseFloat(contribution_amount.dataset.value), // Contribution Amount
n = parseInt(document.querySelector('[name="compound_period"]:checked').value), // Compound Period
n2 = parseInt(document.querySelector('[name="contribution_period"]:checked').value), // Contribution Period
t = parseInt(investment_timespan.value), // Investment Time Span
currentYear = (new Date()).getFullYear();
var labels = [];
for (var year = currentYear; year < currentYear t; year ) {
labels.push(year);
}
var principal_dataset = {
label: 'Total Principal',
backgroundColor: 'rgb(0, 123, 255)',
data: []
};
var interest_dataset = {
label: "Total Interest",
backgroundColor: 'rgb(23, 162, 184)',
data: []
};
for (var i = 1; i <= t; i ) {
var principal = P (c * n2 * i),
interest = 0,
balance = principal;
if (r) {
var x = Math.pow(1 r / n, n * i),
compound_interest = P * x,
contribution_interest = c * (x - 1) / (r / n2);
interest = (compound_interest contribution_interest - principal).toFixed(0)
balance = (compound_interest contribution_interest).toFixed(0);
}
future_balance.innerHTML = ''
balance;
principal_dataset.data.push(principal);
interest_dataset.data.push(interest);
}
return {
labels: labels,
datasets: [principal_dataset, interest_dataset]
}
}
function updateChart() {
var data = getChartData();
chart.data.labels = data.labels;
chart.data.datasets[0].data = data.datasets[0].data;
chart.data.datasets[1].data = data.datasets[1].data;
chart.update();
}
initial_deposit.addEventListener('change', function() {
updateValue(this);
});
contribution_amount.addEventListener('change', function() {
updateValue(this);
});
estimated_return.addEventListener('change', function() {
updateValue(this);
});
investment_timespan.addEventListener('change', function() {
investment_timespan_text.innerHTML = this.value ' years';
updateChart();
});
investment_timespan.addEventListener('input', function() {
investment_timespan_text.innerHTML = this.value ' years';
});
var radios = document.querySelectorAll('[name="contribution_period"], [name="compound_period"]');
for (var j = 0; j < radios.length; j ) {
radios[j].addEventListener('change', updateChart);
}
var buttons = document.querySelectorAll('[data-counter]');
for (var i = 0; i < buttons.length; i ) {
var button = buttons[i];
button.addEventListener('click', function() {
var field = document.querySelector('[name="' this.dataset.field '"]'),
action = this.dataset.counter;
if (field) {
updateValue(field, action);
}
});
}
var ctx = document.getElementById('myChart').getContext('2d'),
chart = new Chart(ctx, {
type: 'bar',
data: getChartData(),
options: {
legend: {
display: false
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label ':'
tooltipItem.yLabel;
}
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Year'
}
}],
yAxes: [{
stacked: true,
ticks: {
callback: function(value) {
return ''
value;
}
},
scaleLabel: {
display: true,
labelString: 'Balance'
}
}]
}
}
});
})();
</script>
</body>