Das kann man sehr leicht mit den vorhandenen Mitteln erreichen. Ich gebe dir hier jedoch ein Version mit SVG und d3.js, weil ich bei dieser auch die Animation des Textes implementiert habe. Beachte, dass Du dabei d3.js einbinden musst. jQuery ist nicht mehr erforderlich.
<!doctype html>
<html>
<head>
<script src="//d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg id="display1" width="500" height="500"></svg><br>
<input id="val">
<svg id="display2" width="500" height="500"></svg><br>
<button id="start">Start</button>
<script>
function DataDisplay(selector, max, value, options) {
var opts = {
textTemplate: "{value}.00 $",
barWidth: 300,
barHeight: 20,
radius: 5,
duration: 1500,
foregroundColor: "red",
backgroundColor: "lightgrey",
strokeWidth: 20,
colorText: "orange",
colors: [
{ threshold: 30, colorAbove: 'yellow' },
{ threshold: 60, colorAbove: 'green' }
]
}
function extend(a, b) {
for (var key in b)
if (b.hasOwnProperty(key))
a[key] = b[key];
return a;
}
function getText(value, max) {
return opts.textTemplate.replace("{value}", value)
.replace("{remaining}", max - value)
}
function getColor(value, opts) {
var color = opts.foregroundColor;
if (opts.colors) {
opts.colors.forEach(function (item, idx) {
if (value > item.threshold) color = item.colorAbove;
});
}
return color;
}
extend(opts, options);
var tau = 2 * Math.PI; // http://tauday.com/tau-manifesto
var delta = opts.strokeWidth / 2 / opts.radius;
var factor = max / opts.width;
var oldValue = value;
var xBar = 85;
var svg = d3.select(selector);
g = svg.append("g");
var background = g.append("rect")
.attr("rx", opts.radius)
.attr("ry", opts.radius)
.attr("x", xBar)
.attr("y", 0)
.attr("width", opts.barWidth)
.attr("height", opts.barHeight)
.style("fill", opts.backgroundColor);
var foreground = g.append("rect")
.attr("rx", opts.radius)
.attr("ry", opts.radius)
.attr("x", xBar)
.attr("y", 0)
.attr("width", opts.barWidth * value / max)
.attr("height", opts.barHeight)
.style("fill", opts.foregroundColor);
var text = g.append("text")
.attr("y", opts.barHeight / 2)
.text(opts.textTemplate.replace("{value}", max)
.replace("{remaining}", max))
.style("text-anchor", "left")
.attr("alignment-baseline", "central")
.attr("fill", "black")
.attr("font-family", "sans-serif")
.attr("font-size", "20px");
wtxt = text.node().getBBox().width;
text.text(getText(value, max))
svg.attr("width", wtxt + opts.barWidth + 2 * opts.radius);
svg.attr("height", opts.barHeight);
background.attr("x", wtxt);
foreground.attr("x", wtxt);
this.update = function (value) {
value = parseInt(value);
foreground
.transition()
.style("fill", getColor(value, opts))
.attr("width", opts.barWidth * value / max)
.ease(d3.easeLinear)
.duration(opts.duration)
.on("end", function (d) {
text.text(getText(value, max))
console.log("end");
oldValue = value;
})
.tween("progress", function () {
return function (t) {
var currentValue = Math.round(oldValue + t * (value - oldValue));
text.text(getText(currentValue, max));
}
});
}
}
var display1 = new DataDisplay("#display1", 1000, 400, {
foregroundColor: "red",
colors: [
{ threshold: 300, colorAbove: 'yellow' },
{ threshold: 600, colorAbove: 'green' }
],
textTemplate: "{value}.00 $"
});
val.addEventListener("change", function () {
display1.update(this.value);
});
var display2 = new DataDisplay("#display2", 100, 100, {
foregroundColor: "red",
colors: [
{ threshold: 30, colorAbove: 'yellow' },
{ threshold: 60, colorAbove: 'green' }
],
textTemplate: "{remaining}.00 m",
duration: 10000
});
start.addEventListener("click", function () {
display2.update(0);
});
</script>
</body>
</html>
Alles anzeigen