You can thank @quantass; for replying earlier today, made me notice this post
I thought this sounded like something that would be fun to build, so I just went ahead and built something. I’ll run you through the process
Ok, first up, since we’re talking something that’s HTML based, we need a little bit of markup
<div id="thermometer">
<div class="track">
<div class="goal">
<div class="amount"> 90000 </div>
</div>
<div class="progress">
<div class="amount">47835 </div>
</div>
</div>
</div>
You’ll notice I’ve put some values in there for the goal amount and the progress amount. The reason they are unformatted is so it’s easier to parse them with JavaScript, we can format them later
These values could have come from a database and inserted on the server side, of course it’s possible to update the progress bar of this “thermometer” dynamically too if you were to get new values via AJAX or something like that.
Now that we have some basic markup, we can add some CSS to make it look all pretty (well, pretty is a relative term, I am definitely no designer!).
/* Base thermometer style, this is the slate */
#thermometer {
width:70px;
height:300px;
position: relative;
background: #ddd;
border:1px solid #aaa;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
-ms-border-radius: 12px;
-o-border-radius: 12px;
border-radius: 12px;
-webkit-box-shadow: 1px 1px 4px #999, 5px 0 20px #999;
-moz-box-shadow: 1px 1px 4px #999, 5px 0 20px #999;
-ms-box-shadow: 1px 1px 4px #999, 5px 0 20px #999;
-o-box-shadow: 1px 1px 4px #999, 5px 0 20px #999;
box-shadow: 1px 1px 4px #999, 5px 0 20px #999;
}
/* This represents the track of the thermometer, the linear background
with a background size set will generate a line every 5% of the track. */
#thermometer .track {
height:280px;
top:10px;
width:20px;
border: 1px solid #aaa;
position: relative;
margin:0 auto;
background: rgb(255,255,255);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(0,0,0)), color-stop(1%,rgb(255,255,255)));
background: -webkit-linear-gradient(top, rgb(0,0,0) 0%,rgb(255,255,255) 10%);
background: -o-linear-gradient(top, rgb(0,0,0) 0%,rgb(255,255,255) 10%);
background: -ms-linear-gradient(top, rgb(0,0,0) 0%,rgb(255,255,255) 10%);
background: -moz-linear-gradient(top, rgb(0,0,0) 0%,rgb(255,255,255) 10%);
background: linear-gradient(to bottom, rgb(0,0,0) 0%,rgb(255,255,255) 10%);
background-position: 0 -1px;
background-size: 100% 5%;
}
/* The progress indicator (the mercury, if you will) */
#thermometer .progress {
height:0%;
width:100%;
background: rgb(20,100,20);
background: rgba(20,100,20,0.6);
position: absolute;
bottom:0;
left:0;
}
/* let's position the goal */
#thermometer .goal {
position:absolute;
top:0;
}
/* just style the amounts a little bit */
#thermometer .amount {
display: inline-block;
padding:0 5px 0 60px;
border-top:1px solid black;
font-family: Trebuchet MS;
font-weight: bold;
color:#333;
}
/* make sure the progress amount appears on the left side,
this way they progress and goal amounts won't overlap should we reach 100% (or greater) */
#thermometer .progress .amount {
padding:0 60px 0 5px;
position: absolute;
border-top:1px solid #060;
color:#060;
right:0;
}
Now, if you were to load this up in your browser right now, we wouldn’t see anything too exciting, just the two amounts on either end of this thermometer.
We’ll need a little bit of JavaScript to spuce things up.
First up, I realised that we need to format the numbers like currency at some point, so I did a quick google search, since I figured there had to have been a lot of people that have written something to format numbers in JavaScript.
I found this little snippet (I’ve adapted it a little) on Stack Overflow
//originally from http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript
function formatCurrency(n, c, d, t) {
"use strict";
var s, i, j;
c = isNaN(c = Math.abs(c)) ? 2 : c;
d = d === undefined ? "." : d;
t = t === undefined ? "," : t;
s = n < 0 ? "-" : "";
i = parseInt(n = Math.abs(+n || 0).toFixed(c), 10) + "";
j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\\d{3})(?=\\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
}
Ok, now that our number formatting is out of the way, we can get on with the good bits.
/**
* Thermometer Progress meter.
* This function will update the progress element in the "thermometer"
* to the updated percentage.
* If no parameters are passed in it will read them from the DOM
*
* @param {Number} goalAmount The Goal amount, this represents the 100% mark
* @param {Number} progressAmount The progress amount is the current amount
* @param {Boolean} animate Whether to animate the height or not
*
*/
function thermometer(goalAmount, progressAmount, animate) {
"use strict";
//set up our vars and cache some jQuery objects
var $thermo = $("#thermometer"),
$progress = $(".progress", $thermo),
$goal = $(".goal", $thermo),
percentageAmount;
//work out our numbers
goalAmount = goalAmount || parseFloat( $goal.text() ),
progressAmount = progressAmount || parseFloat( $progress.text() ),
percentageAmount = Math.min( Math.round(progressAmount / goalAmount * 1000) / 10, 100); //make sure we have 1 decimal point
//let's format the numbers and put them back in the DOM
$goal.find(".amount").text( "$" + formatCurrency( goalAmount ) );
$progress.find(".amount").text( "$" + formatCurrency( progressAmount ) );
//let's set the progress indicator
$progress.find(".amount").hide();
if (animate !== false) {
$progress.animate({
"height": percentageAmount + "%"
}, 1200, function(){
$(this).find(".amount").fadeIn(500);
});
}
else { // we don't always want to animate
$progress.css({
"height": percentageAmount + "%"
});
$progress.find(".amount").fadeIn(500);
}
}
$(document).ready(function(){
//call without the parameters to have it read from the DOM
thermometer();
// or with parameters if you want to update it using JavaScript.
// you can update it live, and choose whether to show the animation
// (which you might not if the updates are relatively small)
//thermometer( 1000000, 425610, false );
});
A fully working example on JS Fiddle: http://jsfiddle.net/GeekyJohn/vQ4Xn/
I realize the helpfulness of this post to the OP is completely negated by the lateness of the response, but who knows, maybe someone finds this helpful