function FrequencyDisplay(element) { this.prefixes = { 'k': 3, 'M': 6, 'G': 9, 'T': 12 }; this.element = $(element); this.digits = []; this.precision = 2; this.setupElements(); this.setFrequency(0); } FrequencyDisplay.prototype.setupElements = function() { this.displayContainer = $('
'); this.digitContainer = $(''); this.unitContainer = $(' Hz'); this.displayContainer.html([this.digitContainer, this.unitContainer]); this.element.html(this.displayContainer); }; FrequencyDisplay.prototype.getPrefix = function() { var me = this; return Object.keys(me.prefixes).filter(function(key){ return me.prefixes[key] == me.exponent; })[0] || ""; }; FrequencyDisplay.prototype.setFrequency = function(freq) { this.frequency = freq; this.exponent = Math.floor(Math.log10(this.frequency) / 3) * 3; var digits = Math.max(0, this.exponent - this.precision); var formatted = (freq / 10 ** this.exponent).toLocaleString( undefined, {maximumFractionDigits: digits, minimumFractionDigits: digits} ); var children = this.digitContainer.children(); for (var i = 0; i < formatted.length; i++) { if (!this.digits[i]) { this.digits[i] = $(''); var before = children[i]; if (before) { $(before).after(this.digits[i]); } else { this.digitContainer.append(this.digits[i]); } } this.digits[i][(isNaN(formatted[i]) ? 'remove' : 'add') + 'Class']('digit'); this.digits[i].html(formatted[i]); } while (this.digits.length > formatted.length) { this.digits.pop().remove(); } this.unitContainer.text(' ' + this.getPrefix() + 'Hz'); }; FrequencyDisplay.prototype.setTuningPrecision = function(precision) { if (typeof(precision) == 'undefined') return; this.precision = precision; this.setFrequency(this.frequency); }; function TuneableFrequencyDisplay(element) { FrequencyDisplay.call(this, element); this.setupEvents(); } TuneableFrequencyDisplay.prototype = new FrequencyDisplay(); TuneableFrequencyDisplay.prototype.setupElements = function() { FrequencyDisplay.prototype.setupElements.call(this); this.input = $(''); this.prefixInput = $('