openwebrxplus/htdocs/lib/Bandplan.js

132 lines
3.9 KiB
JavaScript

function Bandplan(el) {
this.el = el;
this.bands = [];
this.ctx = null;
this.enabled = false;
// Make sure canvas fills the container
el.style.width = '100%';
el.style.height = '100%';
// Redraw bandplan once it fully shows up
var me = this;
el.parentElement.addEventListener("transitionend", function(ev) {
me.draw();
});
// Colors used for band types
this.colors = {
'hamradio' : '#006000',
'broadcast': '#000080',
'public' : '#400040',
'service' : '#800000'
};
};
Bandplan.prototype.getColor = function(type) {
// Default color is gray
return type in this.colors? this.colors[type] : '#808080';
};
Bandplan.prototype.update = function(bands) {
// Sort by low_bound for accurate rendering of overlapping bands
this.bands = bands.sort(function (a, b) {
return a.low_bound - b.low_bound;
});
// Draw new bands
this.draw();
};
Bandplan.prototype.draw = function() {
// Must be enabled to draw
if (!this.enabled) return;
var width = this.el.offsetWidth;
var height = this.el.offsetHeight;
// If new dimensions are available...
if ((height>0) && (width>0)) {
// If canvas got resized or no context yet...
if (!this.ctx || width!=this.el.width || height!=this.el.height) {
this.el.width = width;
this.el.height = height;
this.ctx = this.el.getContext('2d');
this.ctx.lineWidth = height - 2;
this.ctx.fillStyle = '#FFFFFF';
this.ctx.textAlign = 'center';
this.ctx.font = 'bold 11px sans-serif';
this.ctx.textBaseline = 'middle';
}
}
// Use whatever dimensions we have at the moment
width = this.el.width;
height = this.el.height;
// Must have context and dimensions here
if (!this.ctx || !height || !width) return;
// Clear canvas to transparency
this.ctx.clearRect(0, 0, width, height);
// Do not draw anything if there is nothing to draw
var range = get_visible_freq_range();
if (!range || !this.bands.length) return;
// Center of the ribbon
var center = (height - 2) / 2;
//console.log("Drawing range of " + range.start + " - " + range.end);
this.bands.forEach((x) => {
if (x.low_bound < range.end && x.high_bound > range.start) {
var start = Math.max(scale_px_from_freq(x.low_bound, range), 0);
var end = Math.min(scale_px_from_freq(x.high_bound, range), width);
var tag = x.tags.length > 0? x.tags[0] : '';
//console.log("Drawing " + x.name + "(" + tag + ", " + x.low_bound
// + ", " + x.high_bound + ") => " + start + " - " + end);
this.ctx.strokeStyle = this.getColor(tag);
this.ctx.beginPath();
this.ctx.moveTo(start, center);
this.ctx.lineTo(end, center);
this.ctx.stroke();
var label = x.name;
for (var j = 0 ; j >= 0 ; )
{
var w = this.ctx.measureText(label).width;
if (w + height * 2 <= end - start) {
this.ctx.fillText(label, (start + end) / 2, center);
break;
}
j = label.lastIndexOf(' ');
if (j >= 0) {
label = label.substring(0, j);
}
}
}
});
};
Bandplan.prototype.toggle = function(on) {
// If no argument given, toggle bandplan
if (typeof(on) === 'undefined') on = !this.enabled;
if (on != this.enabled) {
this.enabled = on;
if (on) {
this.el.parentElement.classList.add('expanded');
// Try drawing right away, since we may know dimensions
this.draw();
} else {
this.el.parentElement.classList.remove('expanded');
}
}
};