JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.1.0/bootstrap-slider.js"></script>
<script src="//code.highcharts.com/highcharts.js"></script>
<script src="//code.highcharts.com/highcharts-more.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.1.0/css/bootstrap-slider.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div style="float:left; width:100%; max-width:1200px;position:relative;">
<ul class="controls">
<li class="hasslider">
<label for="balance"><span class="labeltext">Starting Balance</span><input type="number" data-slider-id="balanceSlider" id="balance" min="0" max="2000000" placeholder="438676" class="inputline dollars" value="400000" /><span class="units">$</span></label>
<input id="balanceSlider" class="slider" data-value-id="balance" type="text" data-slider-min="0" data-slider-max="2000000" data-slider-step="1000" data-slider-value="400000" value="400000" />
</li>
<li class="hasslider">
<label for="goal"><span class="labeltext">Goal</span><input type="number" data-slider-id="goalSlider" id="goal" min="100000" max="10000000" placeholder="2000000" class="inputline dollars" value="2000000" /><span class="units">$</span></label>
<input id="goalSlider" class="slider" data-value-id="goal" type="text" data-slider-min="100000" data-slider-max="10000000" data-slider-step="100000" data-slider-value="2000000" value="2000000" />
</li>
<li class="hasslider">
<label for="date"><span class="labeltext">Years</span><input type="number" data-slider-id="dateSlider" id="date" min="1" max="60" placeholder="20" class="inputline" value="20" /></label>
<input id="dateSlider" class="slider"...
CSS
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
color: #222;
font-family: sans-serif;
background: #fff;
padding: 5px;
}
.tooltipLabel {
color: #999;
}
input {
color: #222
}
.slider.slider-horizontal {
margin-bottom: 0
}
.tooltipValue {
font-size: 1.8em;
font-family: sans-serif;
}
.tooltipValue2 {
font-size: 1.2em;
font-weight: 100;
font-family: sans-serif;
}
.summary {
display: inline-block;
color: #fff;
z-index: 20;
padding: 10px;
border-radius: 10px;
}
.summaryAverage,
.summaryRange {}
.offTargetCompletion {
background: #dd0011;
color: #fff;
padding: 0 5px;
}
.onTargetCompletion {
background: #7ED321;
color: #fff;
padding: 0 5px;
}
.highcharts-tooltip {
padding: 0;
z-index: 9998;
}
.goalLabel {
text-align: right;
display: inline-block;
font-size: 20px;
font-family: sans-serif;
font-weight: normal;
}
.goalHeader {
text-align: right;
display: inline-block;
font-size: 14px;
margin-bottom: 4px;
font-family: sans-serif;
}
.balanceValue {
text-align: left;
display: inline-block;
font-size: 18px;
font-family: sans-serif;
}
.balanceHeader {
text-align: left;
display: inline-block;
font-size: 14px;
margin-bottom: 4px;
font-family: sans-serif;
font-weight: normal;
}
.balanceLabel {
background: rgba(256, 256, 256, 0.8);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
color: #222;
padding: 6px 10px 4px;
text-align: right;
border-radius: 3px;
z-index: 1;
font-weight: 100;
font-size: 12px;
}
.balanceLabel:before {
content: "";
position: absolute;
bottom: 9px;
left: -5px;
border-width: 5px 0 0 5px;
border-style: solid;
border-color: rgba(256, 256, 256, 0.8) transparent;
display: block;
width: 0;
}
.balanceLabel:after {
content: "";
position: absolute;
bottom: 14px;
left: -5px;
border-width: 0 0 5px 5px;
border-style: solid;
border-color: rgba(256, 256, 256, 0.8) transparent;
display:...
JavaScript
$(function() {
$('.slider').slider();
$('.slider').on("slide", function(slideEvt) {
$("#" + $(this).attr("data-value-id")).val(slideEvt.value);
updateData();
});
$('li.hasslider').click(function(e) {
e.preventDefault();
$('li.hasslider').removeClass("active");
$(this).addClass("active");
});
$(".inputline").change(function() {
$("#" + $(this).attr("data-slider-id")).slider('setValue', parseInt($(this).val(), 10));
updateData();
});
$("input:radio[name=offset]").click(function() {
updateData();
});
$("input.percentage").change(function() {
updateData();
});
$("input#showProjection").change(function() {
updateData();
});
Highcharts.setOptions({
lang: {
thousandsSep: ','
}
});
function updateData() {
var principle = parseInt($('#balance').val(), 10);
var oneTime = parseInt($('#lumpsum').val(), 10);
var goal = parseInt($('#goal').val(), 10);
var years = parseInt($('#date').val(), 10);
var contributions = parseInt($('#contributions').val(), 10);
var offset = $("input:radio[name=offset]:checked").val();
var high = ($('#high').val() * .01);
var average = ($('#average').val() * .01);
var low = ($('#low').val() * .01);
var highTolerance = 100 / (years * 2);
var lowTolerance = -highTolerance;
var today = new Date();
var thisyear = today.getFullYear();
var futureValueLow = principle + oneTime;
var futureValueAverage = principle + oneTime;
var futureValueHigh = principle + oneTime;
var averages = [
[thisyear, futureValueAverage]
];
var range = [
[thisyear, futureValueLow, futureValueHigh]
];
var pastAverages = [
[thisyear + years, goal]
];
var pastRange = [
[thisyear + years, goal, goal]
];
var status = "On Target";
var statusColor = "#222";
var statusClass = "onTarget";
var goalYear = thisyear + years;
var goalAchieved = '0';
var...