I was trying to Build a spectrum and waterfall Plot HTML canvas. After a long research and googling i found this SOURCE CODE
Now i am trying to learn how this code works. i added 3 points on the spectrum using drawPoint2
function.
Can some one please Guild me. thank you.
"use strict";
var colors = [
"rgba(60, 229, 42, 0.31)",
"rgba(60, 229, 42, 0.31)",
"rgba(60, 229, 42, 0.31)",
"rgba(60, 229, 42, 0.31)",
"rgba(60, 229, 42, 0.31)",
"rgba(252, 182, 3, 0.31)",
"rgba(3, 103, 252, 0.31)",
"rgba(219, 3, 252, 0.31)",
"rgba(252, 3, 49, 0.31)",
"rgba(221, 48, 232, 0.31)",
];
var closeEnough = 5;
var crop = 150;
var data_sb = -10;
var canvas = document.getElementById("spectrumSM");
Spectrum.prototype.countDecimals = function (value) {
if (Math.floor(value) !== value)
return value.toString().split(".")[1].length || 0;
return 0;
};
Spectrum.prototype.map = function (x, in_min, in_max, out_min, out_max) {
return Math.round(
((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
);
};
Spectrum.prototype.updateSpectrumRatio = function () {
this.spectrumHeight = Math.round(
(this.canvas.height * this.spectrumPercent) / 100.0
);
// create a slop
this.gradient = this.ctx.createLinearGradient(0, 0, 0, this.spectrumHeight);
for (var i = 0; i < this.colormap.length; i++) {
var c = this.colormap[this.colormap.length - 1 - i];
this.gradient.addColorStop(
i / this.colormap.length,
"rgba(220,220,220,0.2)"
); //hardcode the patch above Xaxis
}
};
Spectrum.prototype.resize = function () {
var width = this.canvas.clientWidth;
var height = this.canvas.clientHeight;
if (this.canvas.width != width || this.canvas.height != height) {
this.canvas.width = width;
this.canvas.height = height;
this.updateSpectrumRatio();
for (var z = 0; z < this.tags.length; z++) {
this.tags[z].StayX = this.map(
this.tags[z].xval,
this.cutfromArray,
this.orignalArrayLength - this.cutfromArray,
0 + crop,
width
); ///////
}
}
if (this.axes.width != width || this.axes.height != this.spectrumHeight) {
this.axes.width = width;
this.axes.height = this.spectrumHeight;
this.updateAxes();
}
};
Spectrum.prototype.updateAxes = function () {
var width = this.ctx_axes.canvas.width + 100; //width of x axis izz
var height = this.ctx_axes.canvas.height;
this.maxScaleX = this.centerHz + this.spanHz / 2;
this.minScaleX = this.centerHz - this.spanHz / 2;
// Clear and fill with black
this.ctx_axes.fillStyle = "black";
this.ctx_axes.fillRect(0, 0, width, height);
// Draw axes
this.ctx_axes.font = "12px Arial";
this.ctx_axes.fillStyle = "white";
this.ctx_axes.textBaseline = "middle";
this.ctx_axes.textAlign = "center"; //change izz
var step = 10; //steps for y-axis
for (var i = this.max_db - 10; i >= this.min_db + 10; i -= step) {
var y = height - this.squeeze(i, 0, height);
this.ctx_axes.fillText(i, 20, y); // height - y
this.ctx_axes.beginPath();
this.ctx_axes.moveTo(22, y); //y axis stroked set izz
this.ctx_axes.lineTo(width, y);
this.ctx_axes.strokeStyle = "rgba(255, 255, 255, 0.15)"; //changed strokes izz
this.ctx_axes.stroke();
}
this.ctx_axes.textBaseline = "bottom";
// change X-axis
var x_axisSteps = 10;
for (var i = 0; i < x_axisSteps; i++) {
var x = Math.round((width - crop) / x_axisSteps - 1) * i + crop;
if (this.spanHz > 0) {
var adjust = 0;
if (i == 0) {
this.ctx_axes.textAlign = "left";
adjust = 3;
} else if (i == 10) {
this.ctx_axes.textAlign = "right";
adjust = -3;
} else {
this.ctx_axes.textAlign = "center";
}
//Graph points in whole points
var freq = this.centerHz + (this.spanHz / 10) * (i - 5);
if (freq > 1e9) {
freq = freq / 1e9;
if (this.countDecimals(freq) > 4) {
freq = freq.toFixed(0);
}
freq = freq + " GHz";
} else if (freq > 1e6) {
freq = freq / 1e6;
if (this.countDecimals(freq) > 4) {
freq = freq.toFixed(0);
}
freq = freq + " MHz"; //this function executed
} else {
if (this.countDecimals(freq) > 2) {
freq = freq.toFixed(0);
}
freq = freq + " MHz";
}
this.ctx_axes.fillText(freq, x - 130, height); // x axia height change izz plus values placment
}
//console.log("ctx_axes : ", this.ctx_axes);
this.ctx_axes.beginPath();
this.ctx_axes.moveTo(x, 0);
this.ctx_axes.lineTo(x, height);
this.ctx_axes.strokeStyle = "rgba(200, 200, 200, 0.2)"; //straight gridline on x axis izza
this.ctx_axes.stroke();
}
// const input = prompt("What's your name?");
};
Spectrum.prototype.toggleColor = function () {
this.colorindex++;
if (this.colorindex >= colormaps.length) this.colorindex = 0;
this.colormap = colormaps[this.colorindex];
this.updateSpectrumRatio();
};
Spectrum.prototype.setCenterHz = function (hz) {
this.centerHz = hz;
if (this.center != 0 && this.center != this.centerHz) {
this.centerHz = this.center;
}
this.updateAxes();
};
Spectrum.prototype.setSpanHz = function (hz) {
this.orignalSpanHz = hz;
this.spanHz = hz;
if (this.zoom != 0 && this.spanHz != this.zoom) {
this.spanHz = this.zoom;
}
this.updateAxes();
};
Spectrum.prototype.squeeze = function (value, out_min, out_max) {
if (value <= this.min_db) {
return out_min;
} else if (value >= this.max_db) {
return out_max;
} else {
return Math.round(
((value - this.min_db) / (this.max_db - this.min_db)) * out_max
);
}
};
Spectrum.prototype.squeeze2 = function (value, out_min, out_max) {
if (value <= 30000000) {
return out_min;
} else if (value >= 300000000) {
return out_max;
} else {
return Math.round(
((value - 30000000) / (300000000 - 30000000)) * out_max
);
}
};
Spectrum.prototype.drawRectSpectrogram = function (y, h) {
this.ctx.beginPath();
this.ctx.fillStyle = colors[this.rectColor]; //"rgba(60, 229, 42, 0.31)"; //rect color
this.ctx.strokeStyle = "green";
this.ctx.rect(this.clickRectX, y, this.clickRectWidth, h);
this.ctx.stroke();
this.ctx.fill();
this.ctx.closePath();
};
Spectrum.prototype.threshold = function (y, width, color) {
this.ctx.beginPath();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = 2; //threshold line width
this.ctx.beginPath();
this.ctx.moveTo(0, y);
this.ctx.lineTo(width + crop, y);
this.ctx.stroke();
this.ctx.closePath();
this.ctx.lineWidth = 1;
};
function drawPoint2(can, x, y, label) {
can.beginPath();
can.arc(x, y, 5, 0, 2 * Math.PI);
can.fillStyle = "red";
can.fill();
can.fillText(label, x + 10, y);
can.stroke(); // it creates X axies and
}
Spectrum.prototype.drawSpectrum = function (bins) {
//get canvas height and width to draw spectrum ayaz
var width = this.ctx.canvas.width;
var height = this.ctx.canvas.height;
//console.log("spectrum width and height : "+width+" "+ height);
// width of Green Color ayaz
this.ctx.lineWidth = 1; //Amplitude green line width .
//All of the points are 119 nut few points are 118 and few 120 ayaz
if (!this.binsAverage || this.binsAverage.length != bins.length) {
//console.log('this.binsAverage ', this.binsAverage );
this.binsAverage = bins;
} else {
for (var i = 0; i < bins.length; i++) {
this.binsAverage[i] +=
(1 - this.averaging) * (bins[i] - this.binsAverage[i]);
}
}
bins = this.binsAverage;
//Do not draw anything if spectrum is not visible
if (this.ctx_axes.canvas.height < 1) return;
//////////////////////////////////////////////////////////////Creation of X and Y axis completed
// Copy axes from offscreen canvas
this.ctx.drawImage(this.ctx_axes.canvas, -1, -1); // create Spectrums X and Y axis
// // Scale for FFT
this.ctx.save(); // saves sppectrum previous stage
//////////////////////////////////////////////////////////////Creation of X and Y axis completed
this.ctx.scale(width / this.wf_size, 1); //green line visiblity izza
var peakY = this.spectrumHeight;
// Draw FFT bins
this.ctx.beginPath();
this.offset = Math.round(
this.map(crop, 0, this.ctx.canvas.width + 6000, 0, this.wf_size)
); // green line axis set izza
//console.log('this.offset : ', this.offset);
console.log(
"X and Y are : ",
-1 + this.offset + " " + this.spectrumHeight + 0
);
this.ctx.moveTo(-1 + this.offset, this.spectrumHeight + 0); //change for waterfall izza
// above line is the address of left bottom corner of spectrum
// console.log(
// "clkkkkkkkkkkkkkkk : ",
// this.clickRectX+
// crop+
// width+
// this.minScaleX+
// this.maxScaleX
// );
var rangeMin = this.map(
this.clickRectX,
crop,
width,
this.minScaleX,
this.maxScaleX
);
var rangeMax = this.map(
this.clickRectWidth + this.clickRectX,
crop,
width,
this.minScaleX,
this.maxScaleX
);
if (rangeMin > rangeMax) {
var temp;
temp = rangeMax;
rangeMax = rangeMin;
rangeMin = temp;
}
var max = 100000000;
this.scaleY = this.map(this.threshY, this.min_db, this.max_db, height / 2, 0); // 0, height/2 // height of threshold izza
this.detectedFrequency.length = 0;
// console.log('bins are ', bins);
//console.log('new array ');
for (var i = 0; i < bins.length; i++) {
// if ( parseFloat( bins[i]) > -100 ) {
// console.log("bins : ", bins[i]);
// const input = prompt("What's your name?");
// alert(`Your name is ${input}`);
// }
var y =
this.spectrumHeight - 1 - this.squeeze(bins[i], 0, this.spectrumHeight);
peakY = this.squeeze(bins[i], 0, this.spectrumHeight);
if (y > this.spectrumHeight - 1) {
y = this.spectrumHeight - 1;
console.log("Y has chnaged : ", y);
}
if (y < 0) {
y = 0;
console.log("y=0");
}
if (i == 0) {
this.ctx.lineTo(-1 + this.offset, y);//responsible for height of green line
}
// green lines are created here ayaz
// create green lines
// important
//drawPoint2(this.ctx ,i + this.offset, y);
this.ctx.lineTo(i + this.offset, y); // that what point we start drawing green horizental green line
// console.log(
// "Starting Line 1 i " +
// i +
// " X : " +
// parseInt(i + this.offset) +
// " y : " +
// y
// );
if (i == bins.length - 1) {
//drawPoint2(this.ctx ,i + this.offset, y);
this.ctx.lineTo(this.wf_size + 1 + this.offset, y);
// console.log(
// "Second 2 i == bins.length - 1 i " +
// i +
// " Drawingg -1 + this.offset : " +
// parseInt(i + this.offset) +
// " y : " +
// y
// );
}
for (var z = 0; z < this.tags.length; z++) {
if (
i + this.cutfromArray == this.tags[z].xval &&
this.check_click == true
) {
this.tags[z].tagY = y;
this.tags[z].yval = Math.round(bins[i]);
this.tags[z].displayX = Math.round(
this.map(i, 0, bins.length, this.minScaleX, this.maxScaleX)
);
}
}
if (y < max) {
max = y;
}
let newVal = Math.round(
this.map(i, 0, bins.length, this.minScaleX, this.maxScaleX)
);
if (this.check_bar) {
if (newVal < rangeMax && newVal > rangeMin) {
if (y < this.scaleY) {
var obj = new Object();
obj.x = newVal;
obj.y = Math.round(bins[i]);
obj.count = 1;
var check = true;
for (var j = 0; j < this.threshRange.length; j++) {
if (
this.threshRange[j].x == obj.x &&
this.threshRange[j].y == obj.y
) {
this.threshRange[j].count++;
check = false;
}
}
if (check) {
let tableRows = document
.getElementById("thresh-table-body")
.getElementsByTagName("tr").length;
if (tableRows < 100) {
this.threshRange.push(obj);
// filling table
let tbody = document.getElementById("thresh-table-body");
let tr = document.createElement("tr");
let td1 = document.createElement("td");
let td2 = document.createElement("td");
let td3 = document.createElement("td");
td1.innerHTML = obj.x; //+" Hz"
td2.innerHTML = obj.y;
td3.innerHTML = obj.count;
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tbody.appendChild(tr);
}
} else {
// update table count
for (let c = 0; c < this.threshRange.length; c++) {
let tableRows =
document.getElementById("thresh-table-body").rows[c].cells;
if (
tableRows[0].innerHTML == obj.x &&
tableRows[1].innerHTML == obj.y
) {
let countValue = Number(tableRows[2].innerHTML);
countValue++;
tableRows[2].innerHTML = countValue;
}
}
}
}
}
} else {
if (y < this.scaleY) {
var obj = new Object();
obj.x = newVal;
obj.y = Math.round(bins[i]);
obj.count = 1;
var check = true;
for (var j = 0; j < this.threshRange.length; j++) {
if (
this.threshRange[j].x == obj.x &&
this.threshRange[j].y == obj.y
) {
this.threshRange[j].count++;
check = false;
}
}
}
}
}
// this.ctx.beginPath();
// this.ctx.arc(100, 75, 20, 0, 1 * Math.PI);
// this.ctx.stroke();
//this.ctx.strokeRect(1800,10, 40, 190);
function containsObject(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (list[i] === obj) {
return true;
}
}
return false;
}
this.ctx.fillStyle = "rgba(0, 0, 0, 0.11)";
// drawPoint2(this.ctx ,
// this.wf_size + 1 + this.offset,
// this.spectrumHeight + 1
// );
this.ctx.lineTo(this.wf_size + 1 + this.offset, this.spectrumHeight + 1);
// console.log(
// "thired 3 this.wf_size + 1 + this.offset : " +
// parseInt(this.wf_size + 1 + this.offset) +
// " this.spectrumHeight + 1 : " +
// parseInt(this.spectrumHeight + 1)
// );
// drawPoint2(this.ctx ,
// this.wf_size + this.offset,
// this.spectrumHeight
// );
this.ctx.lineTo(this.wf_size + this.offset, this.spectrumHeight );
// console.log(
// "Forth this.wf_size + this.offset : " +
// parseInt(this.wf_size + this.offset) +
// " y : " +
// y
// );
if (y < 230 && y > 245) {
console.log("foundddddddddddddd");
}
this.ctx.closePath();
this.ctx.restore();
this.ctx.strokeStyle = "#259a00"; //color of spectrum green
this.ctx.stroke(); // it creates X axies and
/////////////////////////////////////////////////////////////////////////green ended
if (this.spectrumColorCheck) {
this.ctx.fillStyle = this.gradient; //chnage color of under line chart
} else {
this.ctx.fillStyle = "rgba(0, 0, 0, 0.0)";
}
this.ctx.fill();
if (this.check_bar) {
this.drawRectSpectrogram(0, height);
}
var colorTh = "#cc8315"; //By uncomment Change the threshold line color change
this.threshold(this.scaleY, width, colorTh); // yellow light
if (this.check_click == true) {
for (let c = 0; c < this.tags.length; c++) {
this.drawTag(
this.tags[c].StayX,
this.tags[c].tagY,
this.tags[c].displayX,
this.tags[c].yval
);
}
if (this.removeTagCheck == true) {
closeEnough = 30;
for (var z = 0; z < this.tags.length; z++) {
if (this.checkCloseEnough(this.StayX, this.tags[z].StayX + 15)) {
this.tags.splice(z, 1);
z--;
}
}
}
}
closeEnough = 5;
// span hz commented
if (this.updateValueCheck) {
if (this.countDecimals(this.threshY) > 2) {
this.threshY = this.threshY.toFixed(2);
}
this.updateValueCheck = false;
}
var arrt = [ -100000000 , 40000000,35000000];
this.spectrumWidth = Math.round(
(this.canvas.width * this.spectrumPercent) / 100.0
);
for (var k = 0; k < 4; k++) {
var alpha =
this.spectrumHeight - 620 - this.squeeze2(arrt[k], 0, this.spectrumWidth);
drawPoint2(this.ctx, alpha + 600, 150, "A");
}
// draw separate lines
// for (var k=0;k< 4; k++){
// drawPoint2(this.ctx, "200000000", "-80");
// drawPoint2(this.ctx,"100000000", "-80");
// drawPoint2(this.ctx,"35000000", "-80");
// }
//console.log('this.ctx : ',this.ctx);
};
Spectrum.prototype.addData = function (data, bmp) {
if (!this.paused) {
if (data.length > 32768) {
data = this.sequenceResize(data, 32767);
}
this.orignalArrayLength = data.length;
if (this.orignalSpanHz > this.spanHz) {
data = data.slice(
this.cutfromArray,
this.orignalArrayLength - this.cutfromArray
);
}
if (data.length != this.wf_size) {
this.wf_size = data.length;
if (data.length > 32767) {
this.ctx_wf.canvas.width = 32767;
} else {
this.ctx_wf.canvas.width = data.length;
}
this.ctx_wf.fillStyle = "black";
this.ctx_wf.fillRect(0, 0, this.wf.width, 0); //strokes of waterfall
for (var z = 0; z < this.tags.length; z++) {
this.tags[z].StayX = this.map(
this.tags[z].xval,
this.cutfromArray,
this.orignalArrayLength - this.cutfromArray,
crop,
this.ctx.canvas.width
);
}
}
this.drawSpectrum(data);
// this.addWaterfallRowBmp(bmp);
// this.addWaterfallRow(data);
this.resize();
}
};
function Spectrum(id, options) {
// Handle options
this.centerHz = options && options.centerHz ? options.centerHz : 0;
this.spanHz = options && options.spanHz ? options.spanHz : 0;
this.wf_size = options && options.wf_size ? options.wf_size : 0;
this.wf_rows = options && options.wf_rows ? options.wf_rows : 50;
this.spectrumPercent =
options && options.spectrumPercent ? options.spectrumPercent : 25;
this.spectrumPercentStep =
options && options.spectrumPercentStep ? options.spectrumPercentStep : 5;
this.averaging = options && options.averaging ? options.averaging : 0.5;
this.rectColor = options && options.rectColor ? options.rectColor : 0;
// Setup state
this.paused = false;
this.fullscreen = true;
this.min_db = -140;
this.max_db = -20;
this.spectrumHeight = 0;
// Colors
this.colorindex = 2;
this.colormap = colormaps[0];
// Create main canvas and adjust dimensions to match actual
this.canvas = document.getElementById("spectrumSM");
canvas.height = this.canvas.clientHeight;
this.canvas.width = this.canvas.clientWidth;
this.ctx = this.canvas.getContext("2d");
this.checkclick = false;
this.clickRectWidth = 1000;
this.dragL = true;
this.dragR = true;
// this.ctx.globalAlpha = 0.1;
this.drag = true;
this.click_x = 0;
this.click_y = 0;
this.check_click = true;
this.threshY = -70;
this.StayX = -10;
this.scaleY = 0;
//for change waterfall design
this.threshCheck = true;
this.removeTagCheck = true;
this.spectrumColorCheck = true;
this.check_bar = true;
this.updateValueCheck = true;
this.tags = [];
this.addTagsCheck = true;
this.maxScaleX = 0;
this.minScaleX = 0;
this.orignalArrayLength = 0;
this.zoom = this.spanHz;
this.center = this.centerHz;
this.threshRange = [];
this.detectedFrequency = [];
this.offset = 10;
this.arraySizeto = 0;
this.orignalSpanHz = 0;
this.cutfromArray = 0;
this.ctx.fillStyle = "black";
this.ctx.fillRect(10, 10, this.canvas.width, this.canvas.height);
// Create offscreen canvas for axes
this.axes = document.createElement("canvas");
this.axes.id = "myCheck";
this.axes.height = 1; // Updated later
this.axes.width = this.canvas.width;
this.ctx_axes = this.axes.getContext("2d");
function myFunction() {
this.style.fontSize = "40px";
}
// Create offscreen canvas for waterfall
this.wf = document.createElement("canvas");
this.wf.height = this.wf_rows;
this.wf.width = this.wf_size;
this.ctx_wf = this.wf.getContext("2d");
// Trigger first render
this.updateSpectrumRatio();
this.resize();
}
Here showing value of spectrum at specific point via click and zoom in/ zoom out functionality.
var closeEnough = 5;
var crop = 150;
var data_sb = -10;
var canvas = document.getElementById("spectrumSM");
Spectrum.prototype.mousedown = function (evt) {
this.checkclick = true;
if (this.checkCloseEnough(this.click_x-3, this.clickRectX)) {
this.dragR = false;
this.dragL = true;
} else if (
this.checkCloseEnough(this.click_x-3, this.clickRectX + this.clickRectWidth)
) {
this.dragR = true;
this.dragL = false;
} else if (this.checkCloseEnough(this.click_y-3, this.scaleY)) {
this.drag = true;
}
};
Spectrum.prototype.mouseup = function (evt) {
this.checkclick = false;
this.dragL = false;
this.dragR = false;
this.drag = false;
if (evt.button === "right") {
this.tags = [];
}
};
Spectrum.prototype.mousemove = function (evt) {
var rect = this.canvas.getBoundingClientRect();
this.click_x = evt.clientX - rect.left;
this.click_y = evt.clientY - rect.top;
closeEnough = Math.abs(this.clickRectWidth);
if (this.dragL == false && this.dragR == false && this.drag == false) {
if (
this.checkclick == true &&
this.checkCloseEnough(
this.click_x,
this.clickRectX + this.clickRectWidth / 2
)
) {
this.clickRectX = this.click_x - this.clickRectWidth / 2;
}
} else if (this.dragL) {
this.clickRectWidth += this.clickRectX - this.click_x;
this.clickRectX = this.click_x;
} else if (this.dragR) {
this.clickRectWidth = -(this.clickRectX - this.click_x);
} else if (this.drag && this.threshCheck) {
this.updateValueCheck = true;
this.threshY = this.map(
this.click_y,
this.canvas.height / 2,
0,
this.min_db,
this.max_db
); // this.max_db, this.min_db
}
closeEnough = 10;
};
Spectrum.prototype.click = function (evt) {
// change izza
this.check_click = true;
this.StayX = this.click_x;
console.log('tag list : ',this.addTagsCheck);
if (this.addTagsCheck == true && this.StayX > 3) {
var tag = {
StayX: this.click_x,
tagY: 0,
yval: 0,
xval: Math.round(
this.map(
this.click_x,
28,
this.ctx.canvas.width,
this.cutfromArray,
this.orignalArrayLength - this.cutfromArray
)
),
displayX: 0,
};
this.tags.push(tag);
}
};
Spectrum.prototype.wheel = function (evt) {
this.zoom = this.spanHz;
var inc;
if (this.arraySizeto == 0) {
inc = Math.round(this.orignalArrayLength * 0.05);
} else {
inc = Math.round(this.arraySizeto * 0.05);
}
let zoomInc = 0;
if (this.orignalSpanHz > this.orignalArrayLength) {
zoomInc = this.orignalSpanHz / this.orignalArrayLength;
} else {
zoomInc = this.orignalArrayLength / this.orignalSpanHz;
}
if (evt.deltaY > 0) {
if (
this.orignalSpanHz - (zoomInc * this.cutfromArray - inc * 2) <
this.orignalSpanHz &&
this.cutfromArray - inc >= 0
) {
this.cutfromArray = this.cutfromArray - inc;
this.zoom = this.orignalSpanHz - zoomInc * this.cutfromArray * 2;
} else if (
this.orignalSpanHz + zoomInc * this.cutfromArray * 2 >=
this.orignalSpanHz &&
this.cutfromArray - inc <= 0
) {
this.zoom = this.orignalSpanHz;
this.cutfromArray = 0;
}
} else if (evt.deltaY < 0) {
if (
this.orignalSpanHz - (zoomInc * this.cutfromArray + inc * 2) > inc &&
this.orignalArrayLength - this.cutfromArray * 2 - inc * 2 >
this.ctx.canvas.width
) {
this.cutfromArray = this.cutfromArray + inc;
this.zoom = this.orignalSpanHz - zoomInc * this.cutfromArray * 2;
}
}
this.arraySizeto = this.orignalArrayLength - this.cutfromArray * 2;
this.maxScaleX = this.centerHz + this.zoom / 20;
this.minScaleX = this.centerHz - this.zoom / 20;
};
Spectrum.prototype.undoTag = function () {
this.tags.pop();
};
Spectrum.prototype.checkCloseEnough = function (p1, p2) {
return Math.abs(p1 - p2) < closeEnough;
};
Spectrum.prototype.drawTag = function (locx, locy, xval, yval) {
this.ctx.beginPath();
this.ctx.strokeStyle = "#cc8315";
let freq = xval;
if (freq > 1e9) {
freq = freq / 1e9;
if (this.countDecimals(freq) > 2) {
freq = freq.toFixed(2);
}
freq = freq + " GHz";
} else if (freq > 1e6) {
freq = freq / 1e6;
if (this.countDecimals(freq) > 2) {
freq = freq.toFixed(2);
}
freq = freq + " MHz";
} else {
if (this.countDecimals(freq) > 2) {
freq = freq.toFixed(2);
}
}
var text = " ( " + freq + ", " + yval + ")";
var padding = 5;
var fontSize = 20;
var xPos = locx - padding;
var width = this.ctx.measureText(text).width + padding * 2;
var height = fontSize * 1.286;
var yPos = locy - height / 1.5;
this.ctx.lineWidth = 2;
this.ctx.fillStyle = "rgba(204, 131, 21, 0.8)";
// draw the rect
this.ctx.fillRect(xPos, yPos, width, height);
this.ctx.fillStyle = "white";
this.ctx.font = "bold 10pt droid_serif";
this.ctx.fillText(text, locx, locy);
this.ctx.fillStyle = "white";
this.ctx.beginPath();
this.ctx.arc(locx, locy, 2, 0, Math.PI * 2, true);
this.ctx.fill();
this.ctx.closePath();
};