4712 lines
140 KiB
JavaScript
4712 lines
140 KiB
JavaScript
// @ts-nocheck
|
||
class WsLabel {
|
||
constructor() {
|
||
this.name = 'label';
|
||
this.id = 'id';
|
||
this.bg_color = '#fff';
|
||
this.fore_color = '#ddd';
|
||
this.location = 0;
|
||
this.width = 1000;
|
||
}
|
||
}
|
||
//this.area_x //绘图区域 起始X
|
||
//this.area_y //绘图区域 起始Y
|
||
//this.area_width //绘图区域 宽度
|
||
//this.area_height //绘图区域 高度
|
||
//this.spectrogram_y //频谱区域 起始Y
|
||
//this.spectrogram_x //频谱区域 起始X
|
||
//this.spectrogram_width //频谱区域 宽度
|
||
//this.spectrogram_height //频谱区域 高度
|
||
//this.waterfall_y //瀑布区域 起始Y
|
||
//this.waterfall_x //瀑布区域 起始X
|
||
//this.waterfall_width //瀑布区域 宽度
|
||
//this.waterfall_height //瀑布区域 高度
|
||
|
||
//新增数据
|
||
waterfallwidget.prototype.addData = function (d, time) {
|
||
if (this.willFitDbRange == true) {
|
||
this.willFitDbRange = false;
|
||
|
||
var max = Math.max(...d) + 10;
|
||
var min = Math.min(...d) - 10;
|
||
if (-200 > min) {
|
||
min = -200;
|
||
}
|
||
if (0 < max) {
|
||
max = 0;
|
||
}
|
||
this.changeDBRange(min, max, true);
|
||
|
||
return;
|
||
}
|
||
|
||
this.drawWaterFall(d);
|
||
this.drawAllSpectrogram(d);
|
||
|
||
//时间
|
||
if (time) {
|
||
if (this.timeIndex > this.waterfall_height) {
|
||
this.timeQueue.splice(this.timeQueue.length - this.time_span, this.time_span);
|
||
this.timeIndex = this.timeIndex - this.time_span;
|
||
}
|
||
this.timeQueue.unshift(time);
|
||
this.drawCoorTime();
|
||
this.timeIndex++;
|
||
}
|
||
};
|
||
waterfallwidget.prototype.addCompareCurLineData = function (d) {
|
||
this.CompareCurLineBuff = d;
|
||
};
|
||
waterfallwidget.prototype.lastPeakMarker = false;
|
||
waterfallwidget.prototype.drawAllSpectrogram = function (bins) {
|
||
var size = this.visual_MapLen; //bins.length;
|
||
var top = this.spectrogram_y;
|
||
var left = this.spectrogram_x;
|
||
var width = this.spectrogram_width;
|
||
var height = this.spectrogram_height;
|
||
this.drawSpectrogrambg();
|
||
this.drawAfterglow(bins, this.waveAfterglow_color);
|
||
this._drawSpectrogram(bins, this.wave_color, peakMarkIndex);
|
||
|
||
//峰值标注
|
||
var peakMarkIndex = 0;
|
||
if (this.showPeakMarker) {
|
||
if (bins.length < 100) {
|
||
console.log('waterfall len cannot < 100');
|
||
}
|
||
var band = this.max_db - this.min_db;
|
||
|
||
var max = -10000;
|
||
peakMarkIndex = 50;
|
||
for (var i = 5; i < bins.length - 5; i++) {
|
||
if (bins[i] > max) {
|
||
max = bins[i];
|
||
peakMarkIndex = i;
|
||
}
|
||
}
|
||
|
||
//var max = Math.max(...bins);
|
||
//peakMarkIndex = bins.indexOf(max);
|
||
|
||
var markv = max;
|
||
var marky = top + height - ((markv - this.min_db) / band) * height;
|
||
var markx = left + width * (peakMarkIndex / bins.length);
|
||
|
||
var markfre = this.getFreqByPoint(markx);
|
||
var textfre = `${(markfre / 1000000).toFixed(6)} MHz`;
|
||
var context = this.layer_info2.getContext();
|
||
context.clearRect(0, 0, this.layer_info2.getWidth(), this.layer_info2.getHeight());
|
||
context.beginPath();
|
||
context.moveTo(markx - 3, marky - 15);
|
||
context.lineTo(markx + 3, marky - 15);
|
||
context.lineTo(markx, marky - 5);
|
||
context.fillStyle = '#ff0000';
|
||
context.fill();
|
||
|
||
context.strokeStyle = this.fore_color;
|
||
context.font = '13px serif';
|
||
context.strokeText(textfre, markx + 5, marky - 15);
|
||
context.strokeText(markv.toFixed(2) + ' dBm', markx + 5, marky - 1);
|
||
}
|
||
|
||
//最大保持
|
||
if (this.showSpectrogramMax) {
|
||
if (this.SpectrogramMaxBuff.length == 0 || this.SpectrogramMaxBuff.length != bins.length) {
|
||
this.SpectrogramMaxBuff = new Array(bins.length);
|
||
for (var i = 0; i < bins.length; i++) {
|
||
this.SpectrogramMaxBuff[i] = bins[i];
|
||
}
|
||
} else {
|
||
for (var i = 0; i < bins.length; i++) {
|
||
this.SpectrogramMaxBuff[i] = Math.max(this.SpectrogramMaxBuff[i], bins[i]);
|
||
}
|
||
}
|
||
this._drawSpectrogram(this.SpectrogramMaxBuff, this.wave_color_max);
|
||
}
|
||
|
||
//最小保持
|
||
if (this.showSpectrogramMin) {
|
||
if (this.SpectrogramMinBuff.length == 0 || this.SpectrogramMinBuff.length != bins.length) {
|
||
this.SpectrogramMinBuff = new Array(bins.length);
|
||
for (var i = 0; i < bins.length; i++) {
|
||
this.SpectrogramMinBuff[i] = bins[i];
|
||
}
|
||
} else {
|
||
for (var i = 0; i < bins.length; i++) {
|
||
this.SpectrogramMinBuff[i] = Math.min(this.SpectrogramMinBuff[i], bins[i]);
|
||
}
|
||
}
|
||
this._drawSpectrogram(this.SpectrogramMinBuff, this.wave_color_min);
|
||
}
|
||
|
||
//平均保持
|
||
if (this.showSpectrogramAvg) {
|
||
if (this.SpectrogramBuff.length >= this.SpectrogramBuffCount) {
|
||
this.SpectrogramBuff.shift();
|
||
}
|
||
this.SpectrogramBuff.push(bins);
|
||
var count = this.SpectrogramBuff.length;
|
||
var len = this.SpectrogramBuff[0].length;
|
||
var ls = new Array(len);
|
||
var sum = 0;
|
||
for (var i = 0; i < len; i++) {
|
||
sum = 0;
|
||
for (var j = 0; j < count; j++) {
|
||
sum += this.SpectrogramBuff[j][i];
|
||
}
|
||
ls[i] = Math.round(sum / count);
|
||
}
|
||
this._drawSpectrogram(ls, this.wave_color_avg);
|
||
}
|
||
//Make功能
|
||
if (this.showPeakMarker) {
|
||
this.setShowMake(bins, this.layer_info3, 0);
|
||
this.setShowMake(bins, this.layer_info4, 1);
|
||
this.showInfoMakeDb();
|
||
//this.setShowMake(bins, this.layer_info5, 2);
|
||
//this.setShowMake(bins, this.layer_info6, 3);
|
||
//this.setShowMake(bins, this.layer_info7, 4);
|
||
}
|
||
//显示对比频谱
|
||
if (this.showCompareCurLine) {
|
||
if (this.CompareCurLineBuff != null) {
|
||
let _first = this.CompareCurLineBuff;
|
||
this._drawSpectrogram(_first, this.wave_color_compare);
|
||
}
|
||
}
|
||
|
||
this.layer_wf.getContext().drawImage(this.ctx_spec.canvas, 0, 0, size, height, left, top, width, height);
|
||
};
|
||
waterfallwidget.prototype.drawSpectrogrambg = function () {
|
||
var size = this.visual_MapLen;
|
||
var height = this.spectrogram_height;
|
||
|
||
this.ctx_spec.fillStyle = this.bg_color;
|
||
this.ctx_spec.fillRect(0, 0, size, height);
|
||
};
|
||
|
||
//余晖图
|
||
waterfallwidget.prototype.drawAfterglow = function (bins, color) {
|
||
if (!this.afterglowBuff) {
|
||
this.afterglowBuff = [];
|
||
}
|
||
if (this.delayAfterglow == 0) {
|
||
this.afterglowBuff = [];
|
||
return;
|
||
}
|
||
|
||
var delayTime = Math.min(this.delayAfterglow, 5000);
|
||
|
||
var removeCount = 0;
|
||
for (var i = 0; i < this.afterglowBuff.length; i++) {
|
||
if (Date.now() - this.afterglowBuff[i].time.getTime() > delayTime) {
|
||
removeCount++;
|
||
}
|
||
}
|
||
for (var i = 0; i < removeCount; i++) {
|
||
this.afterglowBuff.shift();
|
||
}
|
||
if (this.afterglowBuff.length > 0) {
|
||
var alpaStep = 1 / (this.afterglowBuff.length + 1);
|
||
|
||
for (var i = 0; i < this.afterglowBuff.length; i++) {
|
||
this._drawSpectrogram(
|
||
this.afterglowBuff[i].data,
|
||
this.hexToRGBA(this.afterglowBuff[i].color, alpaStep * (i + 1)),
|
||
);
|
||
}
|
||
}
|
||
|
||
this.afterglowBuff.push({
|
||
time: new Date(),
|
||
data: bins,
|
||
color: color,
|
||
});
|
||
};
|
||
waterfallwidget.prototype._drawSpectrogram = function (bins, color) {
|
||
this.ctx_spec.strokeStyle = color;
|
||
var size = this.visual_MapLen;
|
||
//var top = this.spectrogram_y;
|
||
//var left = this.spectrogram_x;
|
||
//var width = this.spectrogram_width;
|
||
var height = this.spectrogram_height;
|
||
if (height == 0) return;
|
||
|
||
if (bins.length < 2) {
|
||
return;
|
||
}
|
||
|
||
this.ctx_spec.beginPath();
|
||
this.ctx_spec.moveTo(0, height - ((bins[0] - this.min_db) / band) * height);
|
||
|
||
var band = this.max_db - this.min_db;
|
||
var per = size / bins.length;
|
||
for (var j = 0; j < bins.length - 1; j++) {
|
||
var val = bins[j];
|
||
var i = Math.floor(per * j);
|
||
|
||
if (val < this.min_db) val = this.min_db;
|
||
if (val > this.max_db) val = this.max_db;
|
||
|
||
var y = 0;
|
||
y = height - ((val - this.min_db) / band) * height;
|
||
|
||
this.ctx_spec.lineTo(i, y);
|
||
}
|
||
|
||
this.ctx_spec.stroke();
|
||
};
|
||
|
||
/**
|
||
* 十六进制颜色值转为带透明度的颜色
|
||
* @param _color 十六进制颜色
|
||
* @param _opacity 透明度
|
||
* @returns {string} rgba
|
||
*/
|
||
waterfallwidget.prototype.hexToRGBA = function (_color, _opacity) {
|
||
var sColor = _color.toLowerCase();
|
||
//十六进制颜色值的正则表达式
|
||
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
||
// 如果是16进制颜色
|
||
if (sColor && reg.test(sColor)) {
|
||
if (sColor.length === 4) {
|
||
var sColorNew = '#';
|
||
for (var i = 1; i < 4; i += 1) {
|
||
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
|
||
}
|
||
sColor = sColorNew;
|
||
}
|
||
//处理六位的颜色值
|
||
var sColorChange = [];
|
||
for (var i = 1; i < 7; i += 2) {
|
||
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)));
|
||
}
|
||
return 'rgba(' + sColorChange.join(',') + ',' + _opacity + ')';
|
||
}
|
||
return sColor;
|
||
};
|
||
|
||
waterfallwidget.prototype.drawWaterFall = function (bins) {
|
||
var size = this.visual_MapLen; // bins.length;
|
||
var row = this.waterfall_height;
|
||
var width = this.waterfall_width;
|
||
if (row == 0) return;
|
||
if (this.ctx_wf.canvas.width != size || this.ctx_wf.canvas.height != row) {
|
||
this.ctx_wf.canvas.width = size;
|
||
this.ctx_wf.canvas.height = row;
|
||
}
|
||
|
||
// Shift waterfall 1 row down
|
||
this.ctx_wf.drawImage(this.ctx_wf.canvas, 0, 0, size, row - 1, 0, 1, size, row - 1);
|
||
|
||
// Draw new line on waterfall canvas
|
||
var imgData = this.rowToImageData(this.ctx_wf, bins);
|
||
this.ctx_wf.putImageData(imgData, 0, 0);
|
||
|
||
// Copy scaled FFT canvas to screen
|
||
this.layer_wf
|
||
.getContext()
|
||
.drawImage(this.ctx_wf.canvas, 0, 0, size, row, this.waterfall_x, this.waterfall_y, width, row);
|
||
};
|
||
waterfallwidget.prototype.squeeze = function (value) {
|
||
if (value < this.min_db) {
|
||
value = this.min_db;
|
||
} else if (value > this.max_db) {
|
||
value = this.max_db;
|
||
}
|
||
value = value + Math.abs(this.min_db);
|
||
|
||
//value= (value - this.min_db) / (this.max_db - this.min_db) * 200;
|
||
//value = value * 200 / (this.max_db - this.min_db);
|
||
value = Math.round(value);
|
||
return value;
|
||
};
|
||
waterfallwidget.prototype.rowToImageData = function (c, bins) {
|
||
var colors = this.color_map.getMapColors();
|
||
var size = this.visual_MapLen;
|
||
var imgData = c.createImageData(size, 1);
|
||
|
||
var per = bins.length / size;
|
||
if (per > 1) {
|
||
for (var p = 0; p < size; p++) {
|
||
var binStart = Math.floor(p * per);
|
||
var binEnd = Math.min(Math.floor(p * per + per), bins.length - 1);
|
||
var vals = [];
|
||
for (var q = binStart; q < binEnd; q++) {
|
||
vals.push(bins[q]);
|
||
}
|
||
|
||
var cindex = this.squeeze(Math.max(...vals));
|
||
|
||
if (cindex > Math.abs(this.min_db) || 0) {
|
||
console.log(cindex + '-' + colors.length);
|
||
return imgData;
|
||
}
|
||
var color = colors[cindex];
|
||
|
||
var i = p * 4;
|
||
if (color) {
|
||
imgData.data[i + 0] = color[0];
|
||
imgData.data[i + 1] = color[1];
|
||
imgData.data[i + 2] = color[2];
|
||
imgData.data[i + 3] = 255;
|
||
}
|
||
}
|
||
} else {
|
||
per = size / bins.length;
|
||
for (var j = 0; j < bins.length; j++) {
|
||
var i = Math.floor(j * per) * 4;
|
||
var cindex = this.squeeze(bins[j]);
|
||
if (cindex > Math.abs(this.min_db) || 0) {
|
||
console.log(cindex + '-' + colors.length);
|
||
return imgData;
|
||
}
|
||
var color = colors[cindex];
|
||
if (color) {
|
||
for (var m = 0; m < Math.ceil(per); m++) {
|
||
imgData.data[i + m * 4 + 0] = color[0];
|
||
imgData.data[i + m * 4 + 1] = color[1];
|
||
imgData.data[i + m * 4 + 2] = color[2];
|
||
imgData.data[i + m * 4 + 3] = 255;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//var per = size / bins.length;
|
||
//for (var j = 0; j < bins.length; j++) {
|
||
// var i = Math.floor(j * per)*4;
|
||
// var cindex = this.squeeze(bins[j]);
|
||
// if (cindex > Math.abs(this.min_db) || 0) console.log(cindex + "-" + colors.length);
|
||
// var color = colors[cindex];
|
||
// if (color) {
|
||
// imgData.data[i + 0] = color[0];
|
||
// imgData.data[i + 1] = color[1];
|
||
// imgData.data[i + 2] = color[2];
|
||
// imgData.data[i + 3] = 255;
|
||
// }
|
||
//}
|
||
|
||
return imgData;
|
||
};
|
||
|
||
waterfallwidget.prototype.fitDbRange = function () {
|
||
this.willFitDbRange = true;
|
||
};
|
||
|
||
waterfallwidget.prototype.changeDBRange = function (min_db, max_db, force = false) {
|
||
min_db = Math.max(-200, min_db);
|
||
max_db = Math.min(0, max_db);
|
||
if (this.min_db != min_db || this.max_db != max_db || force == true) {
|
||
this.min_db = min_db;
|
||
this.max_db = max_db;
|
||
|
||
this.drawCoor();
|
||
|
||
this.color_map.setDbRange(max_db - min_db);
|
||
|
||
//this.drawMap();
|
||
//this.drawRuler();
|
||
this.setColorMapGravity(Math.round(this.min_db + (this.max_db - this.min_db) * 0.31415926), this.showRuler);
|
||
|
||
this.drawCarryLine();
|
||
|
||
this.fireGravityEvent();
|
||
}
|
||
};
|
||
|
||
waterfallwidget.prototype.drawCoor = function () {
|
||
var layer = this.layer_coor;
|
||
layer.destroyChildren();
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
width: layer.getWidth(),
|
||
height: layer.getHeight(),
|
||
fill: this.bg_color,
|
||
listening: false,
|
||
}),
|
||
);
|
||
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: this.margin_left,
|
||
y: this.margin_top,
|
||
width: this.getwf_CtWidth(),
|
||
height: this.getwf_CtHeight(),
|
||
stroke: this.fore_color,
|
||
//fill:this.bg_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [this.waterfall_x, this.waterfall_y - 1, this.waterfall_x + this.waterfall_width, this.waterfall_y - 1],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
|
||
var spanSpec = this.spectrogram_height / this.db_counter;
|
||
var span = this.waterfall_height / this.db_counter;
|
||
var spanValue = Math.round((this.max_db - this.min_db) / this.db_counter);
|
||
for (var i = 0; i < this.db_counter; i += 1) {
|
||
if (i < this.db_counter) {
|
||
if (this.spectrogram_height > 0) {
|
||
layer.add(
|
||
new Konva.Text({
|
||
x: 0,
|
||
y: this.spectrogram_y + spanSpec * i - 5,
|
||
text: this.max_db - i * spanValue ? this.max_db - i * spanValue : '0',
|
||
fontSize: 11,
|
||
fontFamily: 'Calibri',
|
||
fill: this.fore_color,
|
||
width: this.margin_left - 30,
|
||
align: 'right',
|
||
listening: false,
|
||
}),
|
||
);
|
||
}
|
||
|
||
if (this.waterfall_height > 0) {
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [
|
||
this.margin_left - 28,
|
||
this.spectrogram_y + spanSpec * i,
|
||
this.margin_left - 23,
|
||
this.spectrogram_y + spanSpec * i,
|
||
],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////
|
||
|
||
layer.add(
|
||
new Konva.Text({
|
||
x: 0,
|
||
y: this.waterfall_y + span * i - 5,
|
||
text: this.max_db - i * spanValue ? this.max_db - i * spanValue : '0',
|
||
fontSize: 11,
|
||
fontFamily: 'Calibri',
|
||
fill: this.fore_color,
|
||
width: this.margin_left - 30,
|
||
align: 'right',
|
||
listening: false,
|
||
}),
|
||
);
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [
|
||
this.margin_left - 28,
|
||
this.waterfall_y + span * i,
|
||
this.margin_left - 23,
|
||
this.waterfall_y + span * i,
|
||
],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
}
|
||
|
||
layer.draw();
|
||
};
|
||
|
||
waterfallwidget.prototype.drawCoorTime = function () {
|
||
if (this.timeQueue.length == 0) return;
|
||
|
||
var layer = this.layer_coor;
|
||
var arrtext = layer.find('.time-text');
|
||
var arrline = layer.find('.time-line');
|
||
for (var i = 0; i < arrtext.length; i++) {
|
||
arrtext[i].destroy();
|
||
}
|
||
for (var i = 0; i < arrline.length; i++) {
|
||
arrline[i].destroy();
|
||
}
|
||
|
||
var timeY = this.waterfall_y;
|
||
var timeValue = '';
|
||
var cIndex = this.timeIndex;
|
||
var timeX = this.stage.getWidth() - this.margin_right + 1;
|
||
|
||
while (cIndex > 0) {
|
||
timeY = cIndex + this.waterfall_y;
|
||
timeValue = this.timeQueue[cIndex];
|
||
cIndex -= this.time_span;
|
||
|
||
layer.add(
|
||
new Konva.Text({
|
||
x: timeX + 8,
|
||
y: timeY - 5,
|
||
text: timeValue,
|
||
fontSize: 11,
|
||
fontFamily: 'Calibri',
|
||
fill: this.fore_color,
|
||
width: 100,
|
||
align: 'left',
|
||
listening: false,
|
||
name: 'time-text',
|
||
}),
|
||
);
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [timeX, timeY, timeX + 5, timeY],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
name: 'time-line',
|
||
}),
|
||
);
|
||
}
|
||
|
||
//var lines = 1000 / this.time_out;
|
||
//var zoom = Math.floor(20 / lines);
|
||
|
||
//while (timeY < this.getwf_CtHeight() + this.margin_top) {
|
||
// layer.add(
|
||
// new Konva.Text({
|
||
// x: timeX + 8,
|
||
// y: timeY - 5,
|
||
// text: (timeValue) + ' s',
|
||
// fontSize: 11,
|
||
// fontFamily: 'Calibri',
|
||
// fill: this.fore_color,
|
||
// width: 100,
|
||
// align: 'left',
|
||
// listening: false,
|
||
// })
|
||
// );
|
||
|
||
// layer.add(
|
||
// new Konva.Line({
|
||
// points: [timeX, timeY, timeX + 5, timeY],
|
||
// stroke: this.fore_color,
|
||
// strokeWidth: 1,
|
||
// listening: false,
|
||
// })
|
||
// );
|
||
// timeValue += zoom;
|
||
// timeY += zoom * lines;
|
||
//}
|
||
layer.draw();
|
||
};
|
||
|
||
waterfallwidget.prototype.drawCoorFreq = function () {
|
||
var layer = this.layer_coorFreq;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var count = this.zoomOption;
|
||
|
||
var freSpan = this.getwf_CtWidth() / count;
|
||
var freValueSpan = Math.round((this.freq_end - this.freq_start) / count);
|
||
|
||
var fre_y = this.margin_top;
|
||
if (this.coorFreqType == 1) {
|
||
fre_y = this.waterfall_y;
|
||
}
|
||
var msFreSpan = freSpan / 10;
|
||
var msFreValueSpan = freValueSpan / 10;
|
||
for (var i = 0; i < count + 1; i++) {
|
||
var v = this.freq_start + i * freValueSpan;
|
||
var dim = 'Hz';
|
||
if (v >= 1000000000) {
|
||
v = v / 1000000000;
|
||
dim = 'G';
|
||
} else if (v >= 1000000) {
|
||
v = v / 1000000;
|
||
dim = 'M';
|
||
} else if (v >= 1000) {
|
||
v = v / 1000;
|
||
dim = 'K';
|
||
}
|
||
if (count <= 8) {
|
||
v = v.toFixed(3);
|
||
} else {
|
||
v = v.toFixed(3);
|
||
}
|
||
|
||
layer.add(
|
||
new Konva.Text({
|
||
x: this.margin_left + i * freSpan - 12,
|
||
y: fre_y - 12,
|
||
text: v + ' ' + dim,
|
||
fontSize: 11,
|
||
fontFamily: 'Calibri',
|
||
fill: this.fore_color,
|
||
width: 100,
|
||
align: 'left',
|
||
listening: false,
|
||
}),
|
||
);
|
||
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [this.margin_left + i * freSpan, fre_y - 22, this.margin_left + i * freSpan, fre_y - 13],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
if (this.show_msFreq && i != count) {
|
||
for (var j = 0; j < 9; j++) {
|
||
var msX = Math.round(this.margin_left + i * freSpan + (j + 1) * msFreSpan);
|
||
layer.add(
|
||
new Konva.Line({
|
||
points: [msX, fre_y - 20, msX, fre_y - 15],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
}),
|
||
);
|
||
|
||
if (count == 1) {
|
||
var msv = this.freq_start + i * freValueSpan + (j + 1) * msFreValueSpan;
|
||
var dimms = 'Hz';
|
||
if (msv >= 1000000000) {
|
||
msv = msv / 1000000000;
|
||
dimms = 'G';
|
||
} else if (msv >= 1000000) {
|
||
msv = msv / 1000000;
|
||
dimms = 'M';
|
||
} else if (msv >= 1000) {
|
||
msv = msv / 1000;
|
||
dimms = 'K';
|
||
}
|
||
|
||
msv = msv.toFixed(3);
|
||
layer.add(
|
||
new Konva.Text({
|
||
x: msX - 12,
|
||
y: fre_y - 12,
|
||
text: msv + ' ' + dimms,
|
||
fontSize: 11,
|
||
fontFamily: 'Calibri',
|
||
fill: this.fore_color,
|
||
width: 100,
|
||
align: 'left',
|
||
listening: false,
|
||
}),
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
layer.batchDraw();
|
||
};
|
||
|
||
waterfallwidget.prototype.setZoomCenter = function (freq, force = true) {
|
||
if (this.freq_start < freq && this.freq_end > freq && force == false) {
|
||
return;
|
||
}
|
||
|
||
var range = this.freq_end - this.freq_start;
|
||
var nstart = freq - range / 2;
|
||
var nend = freq + range / 2;
|
||
if (nstart < this.min_freq || nend > this.max_freq) {
|
||
return;
|
||
}
|
||
this.setFreqZoom(nstart, nend);
|
||
};
|
||
|
||
waterfallwidget.prototype.drawCoorFreqWheel = function () {
|
||
var layer = this.layer_coorFreqWeel;
|
||
//双击频点居中
|
||
layer.on('dblclick', (e) => {
|
||
var x = e.evt.offsetX;
|
||
var freq = this.getFreqByPoint(x);
|
||
this.setZoomCenter(freq);
|
||
});
|
||
|
||
if (this.allowRunMode == 1) {
|
||
this.drawCoorFreqWheel_RT();
|
||
} else if (this.allowRunMode == 0) {
|
||
this.drawCoorFreqWheel_Slide();
|
||
}
|
||
|
||
//左侧增益动作
|
||
var wheelRect = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
width: this.margin_left - 20,
|
||
height: this.stage.getHeight(),
|
||
fill: 'transparent', //
|
||
name: 'wheelReactDbCt',
|
||
});
|
||
|
||
wheelRect.on('wheel', (evt) => {
|
||
var min_db = this.min_db;
|
||
var max_db = this.max_db;
|
||
|
||
if (evt.evt.wheelDelta > 0) {
|
||
if (this.max_db - this.min_db > 30) {
|
||
min_db += 5;
|
||
max_db -= 5;
|
||
} else {
|
||
return;
|
||
}
|
||
} else {
|
||
min_db -= 5;
|
||
max_db += 5;
|
||
}
|
||
this.changeDBRange(min_db, max_db);
|
||
|
||
evt.evt.preventDefault();
|
||
evt.evt.stopPropagation();
|
||
|
||
return false;
|
||
});
|
||
|
||
wheelRect.on('mousedown', (e) => {
|
||
if (e.evt.button === 2) {
|
||
return;
|
||
} else if (e.evt.button === 0) {
|
||
//buttonLR = 'left';
|
||
}
|
||
|
||
var span = this.waterfall_height / this.db_counter;
|
||
var distanceY = e.evt.offsetY;
|
||
var oDbMin = this.min_db;
|
||
var oDbMax = this.max_db;
|
||
|
||
if (distanceY < this.waterfall_y) {
|
||
span = this.spectrogram_height / this.db_counter;
|
||
}
|
||
|
||
this.stage.on('mousemove', (e) => {
|
||
var yy = e.evt.offsetY - distanceY;
|
||
var change = Math.floor(yy / span) * 10;
|
||
|
||
var desMin = oDbMin + change;
|
||
var desMax = oDbMax + change;
|
||
|
||
var min_db = Math.max(-200, desMin);
|
||
var max_db = Math.min(0, desMax);
|
||
|
||
this.changeDBRange(min_db, max_db);
|
||
});
|
||
this.stage.on('mouseup', (e) => {
|
||
this.stage.off('mousemove');
|
||
this.stage.off('mouseup');
|
||
});
|
||
});
|
||
//增益区域鼠标移入鼠标图标变化
|
||
wheelRect.on('mouseover', (e) => {
|
||
this.stage.container().style.cursor = 'pointer';
|
||
});
|
||
wheelRect.on('mouseout', (e) => {
|
||
this.stage.container().style.cursor = 'default';
|
||
});
|
||
//增益动作结束
|
||
|
||
layer.add(wheelRect);
|
||
layer.batchDraw();
|
||
};
|
||
//鼠标操作层 实时模式
|
||
waterfallwidget.prototype.drawCoorFreqWheel_RT = function () {
|
||
var _self = this;
|
||
var layer = this.layer_coorFreqWeel;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var wheelRect = new Konva.Rect({
|
||
x: this.area_x,
|
||
y: this.area_y - 20,
|
||
width: this.area_width,
|
||
height: this.area_height + 20,
|
||
fill: 'transparent',
|
||
name: 'wheelReact',
|
||
});
|
||
var buttonLR;
|
||
|
||
wheelRect.on('mousedown', function (e) {
|
||
var distanceX = e.evt.offsetX;
|
||
var distanceY = e.evt.offsetY;
|
||
_self.hideContextMenu();
|
||
if (e.evt.button === 2) {
|
||
buttonLR = 'right';
|
||
_self.adj_show = true;
|
||
//
|
||
} else if (e.evt.button === 0) {
|
||
buttonLR = 'left';
|
||
}
|
||
var o_start = _self.freq_start;
|
||
|
||
_self.stage.on('mousemove', async function (e) {
|
||
//只有鼠标左键移动
|
||
if (buttonLR === 'left') {
|
||
_self.drawCoverRect(distanceX, distanceY, e.evt.offsetX, e.evt.offsetY);
|
||
} else if (buttonLR === 'right') {
|
||
if (e.evt.offsetX - distanceX > 0) {
|
||
if (this.isUHF) {
|
||
_self.adj_end = _self.getFreqByPoint(e.evt.offsetX);
|
||
_self.drawAdjLocation();
|
||
}
|
||
}
|
||
}
|
||
});
|
||
_self.stage.on('mouseup', async function (e) {
|
||
_self.clearCoverLayer();
|
||
if (buttonLR === 'left') {
|
||
if (_self.disableZoom != true) {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
} else if (dx > distanceX) {
|
||
var freqStart = _self.getFreqByPoint(distanceX);
|
||
var freqend = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freqend - freqStart < 1000) {
|
||
var selectBw = 1000 / 2;
|
||
var selectCenter = Math.round(freqStart + (freqend - freqStart) / 2);
|
||
freqStart = Math.max(selectCenter - selectBw, _self.min_freq);
|
||
freqend = Math.min(selectCenter + selectBw, _self.max_freq);
|
||
}
|
||
_self.setFreqZoomUp(freqStart, freqend);
|
||
} else {
|
||
_self.setFreqZoomDown();
|
||
}
|
||
}
|
||
if (e.evt.altKey) {
|
||
//频率信息标注
|
||
var x = e.evt.offsetX;
|
||
var y = e.evt.offsetY;
|
||
var freq = _self.getFreqByPoint(x);
|
||
if (_self.wfFreqPointLable) {
|
||
_self.AddFreqPointLable(freq);
|
||
return;
|
||
}
|
||
}
|
||
} else if (buttonLR === 'right') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
//右键点击
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
_self.setAdjCenter(_self.getFreqByPoint(distanceX), true);
|
||
}
|
||
}
|
||
|
||
buttonLR = null;
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
});
|
||
});
|
||
|
||
wheelRect.on('mouseenter', (enter) => {
|
||
wheelRect.on('mousemove', async function (move) {
|
||
//显示悬浮信息
|
||
var freq = _self.getFreqByPoint(move.evt.offsetX);
|
||
var db = _self.getDbByPoint(move.evt.offsetY);
|
||
var text = `${(freq / 1000000).toFixed(6)} MHz`;
|
||
if (db) {
|
||
text = text + `\r\n${db} dBm`;
|
||
}
|
||
_self.showInfo(
|
||
{
|
||
x: move.evt.offsetX,
|
||
y: move.evt.offsetY,
|
||
text: text,
|
||
},
|
||
true,
|
||
);
|
||
});
|
||
wheelRect.on('mouseleave', async function (leave) {
|
||
wheelRect.off('mouseleave');
|
||
wheelRect.off('mousemove');
|
||
_self.hideInfo();
|
||
});
|
||
});
|
||
this.drawWheelZoom(wheelRect);
|
||
|
||
layer.add(wheelRect);
|
||
layer.batchDraw();
|
||
};
|
||
//鼠标操作层 侦察模式
|
||
waterfallwidget.prototype.drawCoorFreqWheel_Slide = function () {
|
||
var _self = this;
|
||
var layer = this.layer_coorFreqWeel;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var wheelRect = new Konva.Rect({
|
||
x: this.area_x,
|
||
y: this.area_y - 20,
|
||
width: this.area_width,
|
||
height: this.area_height + 20,
|
||
fill: 'transparent',
|
||
name: 'wheelReact',
|
||
});
|
||
var buttonLR;
|
||
|
||
//放大缩小菜单等
|
||
wheelRect.on('mousedown', function (e) {
|
||
var distanceX = e.evt.offsetX;
|
||
var distanceY = e.evt.offsetY;
|
||
|
||
_self.hideContextMenu();
|
||
if (e.evt.button === 2) {
|
||
buttonLR = 'right';
|
||
_self.adj_show = true;
|
||
_self.adj_start = _self.getFreqByPoint(distanceX);
|
||
} else if (e.evt.button === 0) {
|
||
buttonLR = 'left';
|
||
} else if (e.evt.button === 1) {
|
||
buttonLR = 'center';
|
||
}
|
||
//var o_start = _self.freq_start;
|
||
//多级频点标注功能
|
||
if (e.evt.buttons == 1) {
|
||
if (e.evt.ctrlKey) {
|
||
if (_self.MakeShow.length >= 2) {
|
||
_self.MakeShow.splice(0, 1);
|
||
}
|
||
var freq = _self.getFreqByPoint(e.evt.offsetX);
|
||
_self.MakeShow[_self.MakeShow.length] = freq;
|
||
for (var i = 0; i < _self.MakeShow.length; i++) {
|
||
for (var j = i + 1; j < _self.MakeShow.length; j++) {
|
||
if (_self.MakeShow[i] == _self.MakeShow[j]) {
|
||
_self.MakeShow.splice(j, 1);
|
||
j--;
|
||
}
|
||
}
|
||
}
|
||
} else if (e.evt.altKey) {
|
||
//频率信息标注
|
||
var x = e.evt.offsetX;
|
||
var y = e.evt.offsetY;
|
||
var freq = _self.getFreqByPoint(x);
|
||
if (_self.wfFreqPointLable) {
|
||
_self.AddFreqPointLable(freq);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
if (e.evt.buttons == 2) {
|
||
if (e.evt.ctrlKey) {
|
||
_self.MakeShow.splice(0, _self.MakeShow.length);
|
||
}
|
||
}
|
||
//多级频点标注功能
|
||
_self.stage.on('mousemove', async function (e) {
|
||
//只有鼠标左键移动
|
||
if (buttonLR === 'left') {
|
||
_self.drawCoverRect(distanceX, distanceY, e.evt.offsetX, e.evt.offsetY);
|
||
} else if (buttonLR === 'right') {
|
||
if (_self.adj_show) {
|
||
_self.setCtrFc(_self.adj_start + (_self.adj_end - _self.adj_start) / 2);
|
||
_self.adj_end = _self.getFreqByPoint(e.evt.offsetX);
|
||
_self.drawAdjLocation();
|
||
}
|
||
}
|
||
});
|
||
_self.stage.on('mouseup', async function (e) {
|
||
_self.clearCoverLayer();
|
||
if (buttonLR === 'left') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
} else if (dx > distanceX) {
|
||
var freqStart = _self.getFreqByPoint(distanceX);
|
||
var freqend = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freqend - freqStart < 2000) {
|
||
var selectBw = 2000 / 2;
|
||
var selectCenter = Math.round(freqStart + (freqend - freqStart) / 2);
|
||
freqStart = Math.max(selectCenter - selectBw, _self.min_freq);
|
||
freqend = Math.min(selectCenter + selectBw, _self.max_freq);
|
||
}
|
||
|
||
_self.setFreqZoomUp(freqStart, freqend);
|
||
} else {
|
||
_self.setFreqZoomDown();
|
||
}
|
||
} else if (buttonLR === 'right') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
//右键点击
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
if (_self.adj_show) {
|
||
_self.adj_show = false;
|
||
_self.drawAdjLocation();
|
||
}
|
||
} else {
|
||
if (_self.adj_end - _self.adj_start > 1) {
|
||
_self.setCtrBw(_self.adj_end - _self.adj_start);
|
||
}
|
||
|
||
_self.setParamsToHistory({
|
||
fc: _self.currentFc,
|
||
bw: _self.currentBw,
|
||
});
|
||
if (_self.isUHF) {
|
||
_self.onAutomaticAdjustment();
|
||
_self.gather_show = true;
|
||
_self.drawGather();
|
||
}
|
||
}
|
||
} else if (buttonLR === 'center') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
|
||
if (_self.CarryLineMode == 1) {
|
||
var currectX = _self.getFreqByPoint(dx);
|
||
var currentY = _self.getDbByPoint(dy);
|
||
if (currectX && currentY) {
|
||
var arr = [];
|
||
var bk = false;
|
||
if (dx < 65) {
|
||
//点的特别左边直接取消
|
||
bk = true;
|
||
} else {
|
||
for (var i = 0; i < _self.CarryLineList.length; i += 2) {
|
||
var xx = _self.CarryLineList[i];
|
||
var yy = _self.CarryLineList[i + 1];
|
||
if (xx < currectX) {
|
||
arr.push(xx);
|
||
arr.push(yy);
|
||
} else {
|
||
bk = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!bk) {
|
||
arr.push(currectX);
|
||
arr.push(currentY);
|
||
}
|
||
_self.setCarryLineList(arr);
|
||
}
|
||
}
|
||
}
|
||
|
||
buttonLR = null;
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
});
|
||
});
|
||
|
||
//显示信息
|
||
wheelRect.on('mouseenter', (enter) => {
|
||
wheelRect.on('mousemove', async function (move) {
|
||
if (!_self.adj_show) {
|
||
var freq = _self.getFreqByPoint(move.evt.offsetX);
|
||
var db = _self.getDbByPoint(move.evt.offsetY);
|
||
var text = `${(freq / 1000000).toFixed(6)} MHz`;
|
||
if (db) {
|
||
text = text + `\r\n${db} dBm`;
|
||
}
|
||
_self.showInfo(
|
||
{
|
||
x: move.evt.offsetX,
|
||
y: move.evt.offsetY,
|
||
text: text,
|
||
},
|
||
true,
|
||
);
|
||
}
|
||
// 修改为悬浮在款选带宽内才显示提示
|
||
//else if (_self.alwaysShowAdj) {
|
||
// _self.showAdjInfo(_self.adj_x, _self.adj_y);
|
||
//}
|
||
});
|
||
wheelRect.on('mouseleave', async function (leave) {
|
||
wheelRect.off('mouseleave');
|
||
wheelRect.off('mousemove');
|
||
_self.hideInfo();
|
||
});
|
||
});
|
||
|
||
this.drawWheelZoom(wheelRect);
|
||
|
||
layer.add(wheelRect);
|
||
layer.batchDraw();
|
||
};
|
||
|
||
waterfallwidget.prototype.adj_x = 65;
|
||
waterfallwidget.prototype.adj_y = 25;
|
||
waterfallwidget.prototype.alwaysShowAdj = true;
|
||
|
||
//添加滚轮放大动作
|
||
waterfallwidget.prototype.drawWheelZoom = function (wheelRect) {
|
||
var _self = this;
|
||
wheelRect.on('wheel', (evt) => {
|
||
if (_self.disableZoom) {
|
||
return;
|
||
}
|
||
|
||
var scale = Math.exp((-evt.evt.wheelDelta * 1.0) / 200);
|
||
var freq = this.getFreqByPoint(evt.evt.offsetX);
|
||
|
||
//var range = this.freq_end - this.freq_start;
|
||
//var nrange = range * scale;
|
||
|
||
var start = freq - (freq - this.freq_start) * scale;
|
||
var end = freq + (this.freq_end - freq) * scale;
|
||
|
||
this.throttleSetFreqZoomUp(start, end, false);
|
||
|
||
evt.evt.preventDefault();
|
||
evt.evt.stopPropagation();
|
||
return false;
|
||
});
|
||
};
|
||
|
||
//底部滚动条
|
||
waterfallwidget.prototype.drawBottomScroll = function () {
|
||
var bottom_scroll_height = 15;
|
||
var layer = this.layer_botscroll;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
this._debounceSetStart = _.debounce(() => {
|
||
var x = thunk.x() - this.area_x;
|
||
var freq = this.min_freq + (this.max_freq - this.min_freq) * (x / this.area_width);
|
||
var freqend = freq + (this.freq_end - this.freq_start);
|
||
this.setFreqZoom(freq, freqend);
|
||
}, 100);
|
||
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: this.area_x,
|
||
y: this.area_y + this.area_height - bottom_scroll_height,
|
||
width: this.area_width,
|
||
height: bottom_scroll_height,
|
||
fill: '#fff',
|
||
opacity: 0.9,
|
||
visible: false,
|
||
name: 'bottom-scroll-bg',
|
||
}),
|
||
);
|
||
var thunk = new Konva.Rect({
|
||
x: this.area_x,
|
||
y: this.area_y + this.area_height - bottom_scroll_height,
|
||
width: 1,
|
||
height: bottom_scroll_height,
|
||
fill: '#524E63',
|
||
opacity: 0.7,
|
||
visible: false,
|
||
name: 'bottom-scroll-thunk',
|
||
//draggable: true,
|
||
//dragBoundFunc: (pos) => {
|
||
// var xx = pos.x;
|
||
// if (pos.x < this.area_x) {
|
||
// xx = this.area_x;
|
||
// }
|
||
// else if (pos.x + thunk.width() > this.area_x + this.area_width) {
|
||
// xx = this.area_x + this.area_width - thunk.width();
|
||
// }
|
||
// return {
|
||
// x: xx,
|
||
// y: this.area_y + this.area_height - bottom_scroll_height,
|
||
// }
|
||
//}
|
||
});
|
||
thunk.on('mouseenter', (enter) => {
|
||
thunk.opacity(0.9);
|
||
document.body.style.cursor = 'pointer';
|
||
layer.draw();
|
||
});
|
||
|
||
thunk.on('mouseout', (enter) => {
|
||
thunk.opacity(0.6);
|
||
document.body.style.cursor = 'default';
|
||
layer.draw();
|
||
});
|
||
thunk.on('mousedown', (e) => {
|
||
var ox = e.evt.offsetX;
|
||
var ol = thunk.x();
|
||
|
||
this.stage.on('contentMousemove', (ee) => {
|
||
var xx = ol + (ee.evt.offsetX - ox);
|
||
if (xx < this.area_x) {
|
||
xx = this.area_x;
|
||
} else if (xx + thunk.width() > this.area_x + this.area_width) {
|
||
xx = this.area_x + this.area_width - thunk.width();
|
||
}
|
||
|
||
thunk.x(xx);
|
||
layer.draw();
|
||
this._debounceSetStart();
|
||
});
|
||
this.stage.on('mouseup', (ee) => {
|
||
this.stage.off('contentMousemove');
|
||
this.stage.off('mouseup');
|
||
});
|
||
});
|
||
//thunk.on('dragend', () => {
|
||
// var x = thunk.x() - this.area_x;
|
||
// var freq = this.min_freq+(this.max_freq - this.min_freq) * (x / this.area_width);
|
||
// var freqend = freq + (this.freq_end - this.freq_start);
|
||
// this.setFreqZoom(freq , freqend);
|
||
//});
|
||
|
||
layer.add(thunk);
|
||
layer.batchDraw();
|
||
};
|
||
|
||
waterfallwidget.prototype.drawBottomScrollLocal = function () {
|
||
var range = this.max_freq - this.min_freq;
|
||
var x = ((this.freq_start - this.min_freq) / range) * this.area_width;
|
||
var x2 = ((this.freq_end - this.min_freq) / range) * this.area_width;
|
||
var width = x2 - x;
|
||
|
||
if (width < 10) {
|
||
width = 10;
|
||
}
|
||
|
||
var thunk = this.layer_botscroll.find('.bottom-scroll-thunk');
|
||
thunk.width(width);
|
||
thunk.x(this.area_x + x);
|
||
|
||
if (Math.abs(this.freq_start - this.min_freq) < 0.1 && Math.abs(this.freq_end - this.max_freq) < 0.1) {
|
||
thunk.hide();
|
||
this.layer_botscroll.find('.bottom-scroll-bg').hide();
|
||
} else {
|
||
thunk.show();
|
||
this.layer_botscroll.find('.bottom-scroll-bg').show();
|
||
}
|
||
|
||
this.layer_botscroll.draw();
|
||
};
|
||
|
||
waterfallwidget.prototype.clearCoverLayer = function () {
|
||
var layer = this.layer_cover;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
layer.batchDraw();
|
||
};
|
||
waterfallwidget.prototype.drawCoverRect = function (sx, sy, dx, dy) {
|
||
var layer = this.layer_cover;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var x = sx > dx ? dx : sx;
|
||
var y = sy > dy ? dy : sy;
|
||
var x1 = sx > dx ? sx : dx;
|
||
var y1 = sy > dy ? sy : dy;
|
||
|
||
var minx = this.area_x;
|
||
var maxx = this.area_x + this.area_width;
|
||
var miny = this.area_y;
|
||
var maxy = this.area_y + this.area_height;
|
||
|
||
x = Math.min(x, maxx);
|
||
x = Math.max(x, minx);
|
||
x1 = Math.min(x1, maxx);
|
||
x1 = Math.max(x1, minx);
|
||
y = Math.min(y, maxy);
|
||
y = Math.max(y, miny);
|
||
y1 = Math.min(y1, maxy);
|
||
y1 = Math.max(y1, miny);
|
||
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: x,
|
||
y: y,
|
||
width: x1 - x,
|
||
height: y1 - y,
|
||
fill: '#fff',
|
||
opacity: 0.3,
|
||
name: 'cover-react',
|
||
}),
|
||
);
|
||
|
||
layer.batchDraw();
|
||
};
|
||
|
||
//瞬时带宽
|
||
waterfallwidget.prototype.setInstant = function (start, end) {
|
||
this.instant_start = start;
|
||
this.instant_end = end;
|
||
this.drawInstant();
|
||
};
|
||
waterfallwidget.prototype.clearInstant = function () {
|
||
this.instant_start = 0;
|
||
this.instant_end = 0;
|
||
this.drawInstant();
|
||
};
|
||
waterfallwidget.prototype.openInstant = function () {
|
||
this.instant_show = true;
|
||
this.drawInstant();
|
||
};
|
||
waterfallwidget.prototype.closeInstant = function () {
|
||
this.instant_show = false;
|
||
this.drawInstant();
|
||
};
|
||
waterfallwidget.prototype.drawInstant = function () {
|
||
var layer = this.layer_instant;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
layer.draw();
|
||
if (!this.instant_show) return;
|
||
if (!this.instant_start && !this.instant_end) return;
|
||
|
||
var start = this.getPointByFreq(this.instant_start);
|
||
var end = this.getPointByFreq(this.instant_end);
|
||
|
||
if (end < this.area_x) return;
|
||
if (start > this.area_x + this.area_width) return;
|
||
|
||
var width = end - start;
|
||
if (start < this.area_x) start = this.area_x;
|
||
if (width > this.area_x + this.area_width - start) width = this.area_x + this.area_width - start;
|
||
|
||
//console.log(start + "-" + width);
|
||
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: start,
|
||
y: this.area_y,
|
||
width: width,
|
||
height: this.area_height,
|
||
fill: this.instant_color,
|
||
opacity: 0.05,
|
||
name: 'cover-react',
|
||
}),
|
||
);
|
||
|
||
layer.batchDraw();
|
||
};
|
||
|
||
waterfallwidget.prototype.setChanel = function (start, end) {
|
||
//console.log("setchanel " + start + "-" + end);
|
||
this.chanel_start = start;
|
||
this.chanel_end = end;
|
||
this.drawChanel();
|
||
};
|
||
waterfallwidget.prototype.clearChanel = function () {
|
||
this.chanel_start = 0;
|
||
this.chanel_end = 0;
|
||
this.drawChanel();
|
||
};
|
||
waterfallwidget.prototype.openChanel = function () {
|
||
this.chanel_show = true;
|
||
this.drawChanel();
|
||
};
|
||
waterfallwidget.prototype.closeChanel = function () {
|
||
this.chanel_show = false;
|
||
this.drawChanel();
|
||
};
|
||
waterfallwidget.prototype.drawChanel = function () {
|
||
var layer = this.layer_chanel;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
layer.draw();
|
||
//if (this.showFreqLable) {
|
||
// var context = this.layer_info6.getContext();
|
||
// context.clearRect(0, 0, this.layer_info6.getWidth(), this.layer_info6.getHeight());
|
||
//}
|
||
if (!this.chanel_show) return;
|
||
if (!this.chanel_start && !this.chanel_end) return;
|
||
|
||
var start = this.getPointByFreq(this.chanel_start);
|
||
var end = this.getPointByFreq(this.chanel_end);
|
||
|
||
if (end < this.area_x) return;
|
||
if (start > this.area_x + this.area_width) return;
|
||
|
||
var width = end - start;
|
||
if (start < this.area_x) start = this.area_x;
|
||
if (width > this.area_x + this.area_width - start) width = this.area_x + this.area_width - start;
|
||
|
||
if (width < 2) {
|
||
width = 2;
|
||
}
|
||
|
||
layer.add(
|
||
new Konva.Rect({
|
||
x: start,
|
||
y: this.area_y,
|
||
width: width,
|
||
height: this.area_height,
|
||
fill: this.chanel_color,
|
||
opacity: 0.3,
|
||
name: 'cover-react',
|
||
}),
|
||
);
|
||
|
||
layer.batchDraw();
|
||
//显示频率标签
|
||
//if (this.showFreqLable) {
|
||
// let markfre = (start + end) / 2;
|
||
// var freq = this.getFreqByPoint(markfre);
|
||
// var textfre = `${(freq / 1000000).toFixed(6)} MHz`;
|
||
// context.strokeStyle = this.fore_color;
|
||
// context.font = "13px serif";
|
||
// context.strokeText(textfre, end + 5, this.area_y + 30);
|
||
//}
|
||
};
|
||
|
||
//标尺
|
||
waterfallwidget.prototype.drawMap = function () {
|
||
if (this.waterfall_height == 0) return;
|
||
|
||
var _self = this;
|
||
var layer = this.layer_map;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var rect = new Konva.Rect({
|
||
x: this.margin_left - 15,
|
||
y: this.waterfall_y,
|
||
width: 10,
|
||
height: this.waterfall_height,
|
||
fill: 'transparent',
|
||
//stroke: this.fore_color,
|
||
});
|
||
rect.on('click', function () {
|
||
if (_self.showRuler) {
|
||
_self.showRuler = false;
|
||
_self.layer_mapRuler.findOne('.map_ruler').hide();
|
||
} else {
|
||
_self.showRuler = true;
|
||
_self.layer_mapRuler.findOne('.map_ruler').show();
|
||
}
|
||
_self.layer_mapRuler.batchDraw();
|
||
_self.fireGravityEvent();
|
||
});
|
||
layer.add(rect);
|
||
layer.draw();
|
||
|
||
this.drawMapColor();
|
||
};
|
||
waterfallwidget.prototype.drawMapColor = function () {
|
||
if (this.waterfall_height == 0) return;
|
||
var cx = this.layer_map.getContext();
|
||
cx.clearRect(0, 0, this.layer_map.width, this.layer_map.height);
|
||
|
||
var nwidth = this.getDrawWHByPixelRatio(10);
|
||
var nheight = this.getDrawWHByPixelRatio(this.waterfall_height);
|
||
|
||
var imgData = cx.createImageData(nwidth, nheight);
|
||
|
||
this.color_map.count = nheight; //this.waterfall_height;
|
||
var colors = this.color_map.getColors();
|
||
var colors_len = colors.length;
|
||
if (colors_len != 0) {
|
||
for (var i = 0; i < imgData.data.length; i += 4) {
|
||
var cindex = colors_len - parseInt(i / 4 / nwidth) - 1;
|
||
var color = colors[cindex];
|
||
imgData.data[i + 0] = color[0];
|
||
imgData.data[i + 1] = color[1];
|
||
imgData.data[i + 2] = color[2];
|
||
imgData.data[i + 3] = 255;
|
||
}
|
||
}
|
||
var nx = this.getDrawWHByPixelRatio(this.margin_left - 15);
|
||
var ny = this.getDrawWHByPixelRatio(this.waterfall_y);
|
||
cx.putImageData(imgData, nx, ny);
|
||
};
|
||
waterfallwidget.prototype.drawRuler = function () {
|
||
if (this.waterfall_height == 0) return;
|
||
|
||
var _self = this;
|
||
var layer = this.layer_mapRuler;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
var group = new Konva.Group({
|
||
x: this.margin_left - 15,
|
||
y: this.waterfall_y + (1 - _self.getGravityPerByLocation()) * _self.waterfall_height,
|
||
rotation: 0,
|
||
draggable: true,
|
||
dragBoundFunc: function (pos) {
|
||
var newY = pos.y;
|
||
if (newY < _self.waterfall_y) {
|
||
newY = _self.waterfall_y;
|
||
} else if (newY > _self.waterfall_y + _self.waterfall_height) {
|
||
newY = _self.waterfall_y + _self.waterfall_height;
|
||
}
|
||
|
||
return {
|
||
x: this.getAbsolutePosition().x,
|
||
y: newY,
|
||
};
|
||
},
|
||
shadowOffsetX: 10,
|
||
shadowOffsetY: 15,
|
||
shadowBlur: 40,
|
||
opacity: 0.8,
|
||
visible: _self.showRuler,
|
||
name: 'map_ruler',
|
||
});
|
||
var lastY = -1;
|
||
group.on('dragmove', function (e) {
|
||
var ny = e.target.y() - _self.waterfall_y;
|
||
var nvalue = 1 - ny / _self.waterfall_height;
|
||
var ndb = _self.min_db + (_self.max_db - _self.min_db) * nvalue;
|
||
_self.gravity_location = ndb;
|
||
|
||
if (ny != lastY) {
|
||
lastY = ny;
|
||
_self.color_map.gravity_value = nvalue;
|
||
if (_self.color_map.gravity) {
|
||
_self.drawMapColor();
|
||
}
|
||
}
|
||
_self.fireGravityEvent();
|
||
});
|
||
group.add(
|
||
new Konva.Rect({
|
||
x: 60,
|
||
y: -20,
|
||
width: 80,
|
||
height: 20,
|
||
fill: this.fore_color,
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
cornerRadius: 3,
|
||
}),
|
||
);
|
||
group.add(
|
||
new Konva.Text({
|
||
x: 70,
|
||
y: -15,
|
||
text: 'Gravity',
|
||
fontSize: 12,
|
||
fontFamily: 'Calibri',
|
||
fill: this.bg_color,
|
||
}),
|
||
);
|
||
|
||
var checked = new Konva.Rect({
|
||
x: 120,
|
||
y: -17,
|
||
width: 15,
|
||
height: 15,
|
||
fill: this.bg_color,
|
||
});
|
||
|
||
group.add(
|
||
new Konva.Line({
|
||
points: [0, 0, 60, 0],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
lineCap: 'round',
|
||
lineJoin: 'round',
|
||
}),
|
||
);
|
||
|
||
checked.on('click', function () {
|
||
if (_self.color_map.gravity) {
|
||
layer.findOne('.check_ico').hide();
|
||
_self.color_map.gravity = false;
|
||
} else {
|
||
layer.findOne('.check_ico').show();
|
||
_self.color_map.gravity = true;
|
||
}
|
||
_self.drawMapColor();
|
||
layer.batchDraw();
|
||
_self.fireGravityEvent();
|
||
});
|
||
group.add(checked);
|
||
|
||
//2021-09-10 梁海祥 (瀑布色尺坐标位置地布遮挡问题,坐标整体上移)
|
||
var checkico = new Konva.Line({
|
||
points: [123, -10, 128, -5, 133, -15],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 2,
|
||
lineCap: 'round',
|
||
lineJoin: 'round',
|
||
name: 'check_ico',
|
||
visible: _self.color_map.gravity,
|
||
});
|
||
group.add(checkico);
|
||
|
||
layer.add(group);
|
||
layer.batchDraw();
|
||
};
|
||
waterfallwidget.prototype.setColorMapGravity = function (val, enable) {
|
||
if (this.gravity_location !== val || this.color_map.gravity !== enable) {
|
||
this.gravity_location = val;
|
||
this.showRuler = enable;
|
||
this.color_map.gravity_value = this.getGravityPerByLocation();
|
||
this.color_map.gravity = enable;
|
||
this.drawMap();
|
||
this.drawRuler();
|
||
}
|
||
};
|
||
waterfallwidget.prototype.fireGravityEvent = function () {
|
||
this.fire('gravity-ruler-change', {
|
||
gravityData: {
|
||
enable: this.showRuler,
|
||
checked: this.color_map.gravity,
|
||
val: this.gravity_location,
|
||
min_db: this.min_db,
|
||
max_db: this.max_db,
|
||
},
|
||
});
|
||
};
|
||
//根据重力尺值得到百分比位置
|
||
waterfallwidget.prototype.getGravityPerByLocation = function () {
|
||
if (this.gravity_location == 0) {
|
||
return 0;
|
||
}
|
||
if (this.gravity_location <= this.min_db) {
|
||
return 1;
|
||
} else if (this.gravity_location >= this.max_db) {
|
||
return 0;
|
||
}
|
||
|
||
return (this.min_db - this.gravity_location) / (this.min_db - this.max_db);
|
||
};
|
||
|
||
//2021.05.07 西部需求拖动更改频谱窗口大小,李伟添加;
|
||
|
||
waterfallwidget.prototype.split_draw = function () {
|
||
var _self = this;
|
||
var layer = this.layer_split;
|
||
if (!layer) {
|
||
return;
|
||
}
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
var leftLine = new Konva.Rect({
|
||
x: 0,
|
||
y: 100,
|
||
width: this.area_x,
|
||
height: 10,
|
||
fill: this.adj_color,
|
||
name: 'SplitLine',
|
||
});
|
||
if (this.allowRunMode == 0) {
|
||
leftLine.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
});
|
||
leftLine.on('mouseleave', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'default';
|
||
});
|
||
leftLine.on('mousedown', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - leftLine.x();
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
var freq = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freq < _self.adj_end) {
|
||
_self.adj_start = freq;
|
||
_self.drawAdjLocation();
|
||
}
|
||
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.stage.off('contentMousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.hideInfo();
|
||
|
||
_self.fire('adj-manu-change', { start: _self.adj_start, end: _self.adj_end });
|
||
});
|
||
});
|
||
}
|
||
|
||
/*
|
||
var rightLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: this.adj_color,
|
||
name: 'rightLine',
|
||
});
|
||
if (this.allowRunMode == 0) {
|
||
rightLine.on('mouseenter', e => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
});
|
||
rightLine.on('mouseleave', e => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'default';
|
||
});
|
||
rightLine.on('mousedown', e => {
|
||
if (this.adj_disabled == true) return;
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - rightLine.x();
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
var freq = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freq > _self.adj_start) {
|
||
_self.adj_end = freq;
|
||
_self.drawAdjLocation();
|
||
}
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.stage.off('contentMousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.hideInfo();
|
||
|
||
_self.fire("adj-manu-change", { start: _self.adj_start, end: _self.adj_end });
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: 0,
|
||
height: this.area_height,
|
||
fill: this.adj_color,
|
||
opacity: 0.1,
|
||
name: 'rect'
|
||
});
|
||
if (this.allowRunMode == 0) {
|
||
rect.on("mousedown", function (e) {
|
||
if (e.evt.button === 2) {
|
||
//显示右键菜单
|
||
_self.showContextMenu(e.evt.clientX, e.evt.clientY);
|
||
}
|
||
else {
|
||
_self.hideContextMenu();
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
|
||
//layer.add(rect);
|
||
//layer.add(leftLine);
|
||
//layer.add(rightLine);
|
||
*/
|
||
var group = new Konva.Group({
|
||
x: 0,
|
||
y: 0,
|
||
});
|
||
//group.add(rect);
|
||
group.add(leftLine);
|
||
//group.add(rightLine);
|
||
|
||
//实时模式可拖动
|
||
if (this.allowRunMode == 1) {
|
||
group.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - rightLine.x();
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
group.on('mouseleave', function (e) {
|
||
_self.stage.container().style.cursor = 'default';
|
||
_self.stage.off('contentMousemove');
|
||
group.off('mouseleave');
|
||
_self.hideInfo();
|
||
});
|
||
});
|
||
|
||
group.on('mousedown', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
|
||
if (e.evt.button !== 0) return;
|
||
var distanceX = e.evt.clientX;
|
||
//_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
var freq = _self.getAdjCenter();
|
||
var ncenter = 0;
|
||
_self.stage.on('mousemove', function (e) {
|
||
var xx = e.evt.clientX - distanceX;
|
||
var change = _self.getFreqBySpanPoint(xx);
|
||
ncenter = freq + change;
|
||
_self.setAdjCenter(ncenter, false);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.setAdjCenter(ncenter, true);
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.hideInfo();
|
||
console.log('off');
|
||
});
|
||
});
|
||
} else if (this.allowRunMode == 0) {
|
||
//非实时模式可穿透放大缩小
|
||
var buttonLR = null;
|
||
/*
|
||
rect.on('mousedown', function (e) {
|
||
var distanceX = e.evt.offsetX;
|
||
var distanceY = e.evt.offsetY;
|
||
if (e.evt.button === 0) {
|
||
buttonLR = 'left';
|
||
}
|
||
|
||
_self.stage.on('mousemove', async function (e) {
|
||
//只有鼠标左键移动
|
||
if (buttonLR === 'left') {
|
||
_self.drawCoverRect(distanceX, distanceY, e.evt.offsetX, e.evt.offsetY);
|
||
}
|
||
});
|
||
_self.stage.on('mouseup', async function (e) {
|
||
_self.clearCoverLayer();
|
||
if (buttonLR === "left") {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
|
||
}
|
||
else if (dx > distanceX) {
|
||
var freqStart = _self.getFreqByPoint(distanceX);
|
||
var freqend = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freqend - freqStart < 10000) {
|
||
var selectBw = 10000 / 2
|
||
var selectCenter = Math.round(freqStart + (freqend - freqStart) / 2);
|
||
freqStart = Math.max(selectCenter - selectBw, _self.min_freq);
|
||
freqend = Math.min(selectCenter + selectBw, _self.max_freq);
|
||
}
|
||
|
||
|
||
_self.setFreqZoomUp(freqStart, freqend);
|
||
}
|
||
else {
|
||
_self.setFreqZoomDown();
|
||
}
|
||
}
|
||
|
||
|
||
buttonLR = null;
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
|
||
});
|
||
});
|
||
*/
|
||
}
|
||
|
||
layer.add(group);
|
||
|
||
_self.split_drawLocation();
|
||
};
|
||
waterfallwidget.prototype.split_show = function () {
|
||
this.split_show = true;
|
||
this.split_drawLocation();
|
||
};
|
||
waterfallwidget.prototype.split_hidden = function () {
|
||
this.split_show = false;
|
||
this.split_drawLocation();
|
||
};
|
||
waterfallwidget.prototype.split_enable = function () {
|
||
this.split_disabled = false;
|
||
};
|
||
waterfallwidget.prototype.split_disable = function () {
|
||
this.split_disabled = true;
|
||
};
|
||
|
||
waterfallwidget.prototype.split_drawLocation = function () {
|
||
if (!this.layer_split) {
|
||
return;
|
||
}
|
||
var layer = this.layer_split;
|
||
|
||
var leftLine = layer.findOne('.leftLine');
|
||
var rightLine = layer.findOne('.rightLine');
|
||
var rect = layer.findOne('.rect');
|
||
if (!leftLine || !rightLine || !rect) {
|
||
return;
|
||
}
|
||
|
||
leftLine.visible(this.split_show);
|
||
rightLine.visible(this.split_show);
|
||
rect.visible(this.split_show);
|
||
|
||
if (this.split_show) {
|
||
var left = this.getPointByFreq(this.adj_start);
|
||
var right = this.getPointByFreq(this.adj_end);
|
||
var lineWidth = this.adj_lineWidth;
|
||
|
||
leftLine.x(left - lineWidth);
|
||
rightLine.x(right);
|
||
|
||
rect.x(left);
|
||
rect.width(right - left + lineWidth);
|
||
}
|
||
|
||
layer.batchDraw();
|
||
};
|
||
//2021.05.07 西部需求拖动更改频谱窗口大小,李伟添加 end;
|
||
|
||
waterfallwidget.prototype.showAdjInfo = function (x, y) {
|
||
this.showInfo({
|
||
x: x,
|
||
y: y,
|
||
text: `中心:${((this.adj_start + (this.adj_end - this.adj_start) / 2) / 1000000).toFixed(3)}MHz\r\n起始:${(this.adj_start / 1000000).toFixed(3)} MHz\r\n结束:${(this.adj_end / 1000000).toFixed(3)} MHz\r\n带宽:${((this.adj_end - this.adj_start) / 1000).toFixed(3)} kHz`,
|
||
});
|
||
};
|
||
waterfallwidget.prototype.toHzStr = function (v, d = -1, dw = 'Hz') {
|
||
if (!v) return '';
|
||
if (v >= 1000000000) {
|
||
if (d != -1) {
|
||
v = (v / 1000000000).toFixed(d) + ' G' + dw;
|
||
} else {
|
||
v = (v / 1000000000).toFixed(9) + ' G' + dw;
|
||
}
|
||
} else if (v >= 1000000) {
|
||
if (d != -1) {
|
||
v = (v / 1000000).toFixed(d) + ' M' + dw;
|
||
} else {
|
||
v = (v / 1000000).toFixed(6) + ' M' + dw;
|
||
}
|
||
} else if (v >= 1000) {
|
||
if (d != -1) {
|
||
v = (v / 1000).toFixed(d) + ' K' + dw;
|
||
} else {
|
||
v = (v / 1000).toFixed(3) + ' K' + dw;
|
||
}
|
||
} else {
|
||
v = v.toFixed(0) + dw;
|
||
}
|
||
return v;
|
||
};
|
||
waterfallwidget.prototype.setCtrBw = function (bw, reConn = true, fftmodel = 0) {
|
||
bw = +bw;
|
||
var panelBwText = $('#text_bw');
|
||
if (reConn && bw == this.currentBw) {
|
||
panelBwText.val(this.toHzStr(bw));
|
||
return;
|
||
}
|
||
if (!Number.isFinite(bw)) {
|
||
bootbox.erro('带宽格式不正确');
|
||
panelBwText.val(this.toHzStr(this.currentBw));
|
||
return;
|
||
}
|
||
if (bw < 1) {
|
||
bootbox.erro('带宽不能小于1kHz');
|
||
panelBwText.val(this.toHzStr(this.currentBw));
|
||
return;
|
||
}
|
||
//这里判断currentFc>0是因为在初始化时带宽参数优先初始化
|
||
if (this.currentFc > 0 && this.isAdjCenterInRange(this.currentFc, bw) == false) {
|
||
if (fftmodel == 0) {
|
||
//全景频谱才弹出提示,控守频谱时不管
|
||
bootbox.erro('带宽超出扫频范围');
|
||
}
|
||
panelBwText.val(this.toHzStr(this.currentBw));
|
||
return;
|
||
}
|
||
this.currentBw = bw;
|
||
panelBwText.val(bw);
|
||
};
|
||
waterfallwidget.prototype.setCtrFc = function (fc, reConn = true) {
|
||
var panelFcText = $('#panel-text-freq');
|
||
if (reConn && fc == this.currentFc) {
|
||
panelFcText.val(this.toHzStr(fc));
|
||
return;
|
||
}
|
||
if (isNaN(fc)) {
|
||
panelFcText.val(this.toHzStr(this.currentFc));
|
||
return;
|
||
}
|
||
if (!Number.isFinite(fc)) {
|
||
bootbox.erro('中心频率格式不正确');
|
||
panelFcText.val(this.toHzStr(this.currentFc));
|
||
return;
|
||
}
|
||
this.currentFc = fc;
|
||
panelFcText.val(this.toHzStr(fc));
|
||
};
|
||
waterfallwidget.prototype.setParamsToHistory = function (dto) {
|
||
dto = Object.assign(
|
||
{
|
||
fc: 0,
|
||
bw: 0,
|
||
fs: 0,
|
||
pdem: 0,
|
||
sys: 0,
|
||
},
|
||
dto,
|
||
);
|
||
localStorage.setItem('fc', dto.fc);
|
||
localStorage.setItem('bw', dto.bw);
|
||
};
|
||
|
||
waterfallwidget.prototype.drawAdj = function () {
|
||
var _self = this;
|
||
var layer = this.layer_adj;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var yStart = this.margin_top - 45;
|
||
var leftLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: this.adj_color,
|
||
name: 'leftLine',
|
||
});
|
||
if (this.allowRunMode == 0) {
|
||
leftLine.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
});
|
||
leftLine.on('mouseleave', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'default';
|
||
});
|
||
leftLine.on('mousedown', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - leftLine.x();
|
||
_self.alwaysShowAdj || _self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
var freq = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freq < _self.adj_end) {
|
||
_self.adj_start = freq;
|
||
_self.drawAdjLocation();
|
||
}
|
||
_self.alwaysShowAdj || _self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.stage.off('contentMousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.alwaysShowAdj || _self.hideInfo();
|
||
|
||
_self.fire('adj-manu-change', { start: _self.adj_start, end: _self.adj_end });
|
||
});
|
||
});
|
||
}
|
||
|
||
var rightLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: this.adj_color,
|
||
name: 'rightLine',
|
||
});
|
||
|
||
var centerLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: this.adjcenter_color,
|
||
name: 'centerLine',
|
||
});
|
||
|
||
if (this.allowRunMode == 0) {
|
||
rightLine.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
});
|
||
rightLine.on('mouseleave', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.stage.container().style.cursor = 'default';
|
||
});
|
||
rightLine.on('mousedown', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - rightLine.x();
|
||
_self.alwaysShowAdj || _self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
var freq = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freq > _self.adj_start) {
|
||
_self.adj_end = freq;
|
||
_self.drawAdjLocation();
|
||
}
|
||
_self.alwaysShowAdj || _self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.stage.off('contentMousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.alwaysShowAdj || _self.hideInfo();
|
||
_self.fire('adj-manu-change', { start: _self.adj_start, end: _self.adj_end });
|
||
});
|
||
});
|
||
}
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: 0,
|
||
height: this.area_height,
|
||
fill: this.adj_color,
|
||
opacity: 0.1,
|
||
name: 'rect',
|
||
});
|
||
if (this.allowRunMode == 0) {
|
||
rect
|
||
.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
_self.alwaysShowAdj && _self.showAdjInfo(_self.adj_x, _self.adj_y);
|
||
})
|
||
.on('mouseleave', (e) => {
|
||
_self.hideInfo();
|
||
});
|
||
|
||
rect.on('mousedown', function (e) {
|
||
if (e.evt.button === 2) {
|
||
//显示右键菜单
|
||
_self.showContextMenu(e.evt.clientX, e.evt.clientY);
|
||
} else {
|
||
_self.hideContextMenu();
|
||
}
|
||
});
|
||
}
|
||
|
||
//layer.add(rect);
|
||
//layer.add(leftLine);
|
||
//layer.add(rightLine);
|
||
var group = new Konva.Group({
|
||
x: 0,
|
||
y: 0,
|
||
});
|
||
group.add(rect);
|
||
group.add(leftLine);
|
||
group.add(rightLine);
|
||
if (this.allowRunMode == 1) {
|
||
group.add(centerLine);
|
||
}
|
||
|
||
//实时模式可拖动
|
||
if (this.allowRunMode == 1) {
|
||
group.on('mouseenter', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
|
||
_self.stage.container().style.cursor = 'e-resize';
|
||
var oevent = e.evt;
|
||
var distanceX = oevent.clientX - rightLine.x();
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
_self.stage.on('contentMousemove', function (e) {
|
||
_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
});
|
||
group.on('mouseleave', function (e) {
|
||
_self.stage.container().style.cursor = 'default';
|
||
_self.stage.off('contentMousemove');
|
||
group.off('mouseleave');
|
||
_self.hideInfo();
|
||
});
|
||
});
|
||
|
||
group.on('mousedown', (e) => {
|
||
if (this.adj_disabled == true) return;
|
||
|
||
if (e.evt.button !== 0) return;
|
||
var distanceX = e.evt.clientX;
|
||
//_self.showAdjInfo(e.evt.offsetX, e.evt.offsetY);
|
||
var freq = _self.getAdjCenter();
|
||
var ncenter = 0;
|
||
_self.stage.on('mousemove', function (e) {
|
||
var xx = e.evt.clientX - distanceX;
|
||
var change = _self.getFreqBySpanPoint(xx);
|
||
ncenter = freq + change;
|
||
_self.setAdjCenter(ncenter, false);
|
||
});
|
||
_self.stage.on('mouseup', function (e) {
|
||
_self.setAdjCenter(ncenter, true);
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
_self.hideInfo();
|
||
});
|
||
});
|
||
} else if (this.allowRunMode == 0) {
|
||
//非实时模式可穿透放大缩小
|
||
var buttonLR = null;
|
||
rect.on('mousedown', function (e) {
|
||
var distanceX = e.evt.offsetX;
|
||
var distanceY = e.evt.offsetY;
|
||
if (e.evt.button === 0) {
|
||
buttonLR = 'left';
|
||
}
|
||
|
||
_self.stage.on('mousemove', async function (e) {
|
||
//只有鼠标左键移动
|
||
if (buttonLR === 'left') {
|
||
_self.drawCoverRect(distanceX, distanceY, e.evt.offsetX, e.evt.offsetY);
|
||
}
|
||
});
|
||
_self.stage.on('mouseup', async function (e) {
|
||
_self.clearCoverLayer();
|
||
if (buttonLR === 'left') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
} else if (dx > distanceX) {
|
||
var freqStart = _self.getFreqByPoint(distanceX);
|
||
var freqend = _self.getFreqByPoint(e.evt.offsetX);
|
||
if (freqend - freqStart < 10000) {
|
||
var selectBw = 10000 / 2;
|
||
var selectCenter = Math.round(freqStart + (freqend - freqStart) / 2);
|
||
freqStart = Math.max(selectCenter - selectBw, _self.min_freq);
|
||
freqend = Math.min(selectCenter + selectBw, _self.max_freq);
|
||
}
|
||
|
||
_self.setFreqZoomUp(freqStart, freqend);
|
||
} else {
|
||
_self.setFreqZoomDown();
|
||
}
|
||
}
|
||
|
||
buttonLR = null;
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
});
|
||
});
|
||
}
|
||
|
||
layer.add(group);
|
||
|
||
_self.drawAdjLocation();
|
||
};
|
||
waterfallwidget.prototype.showAdj = function () {
|
||
this.adj_show = true;
|
||
this.drawAdjLocation();
|
||
};
|
||
waterfallwidget.prototype.hiddenAdj = function () {
|
||
this.adj_show = false;
|
||
this.gather_show = false;
|
||
this.drawGatherLocation();
|
||
this.drawAdjLocation();
|
||
};
|
||
waterfallwidget.prototype.enableAdj = function () {
|
||
this.adj_disabled = false;
|
||
};
|
||
waterfallwidget.prototype.disableAdj = function () {
|
||
this.adj_disabled = true;
|
||
};
|
||
|
||
waterfallwidget.prototype.drawAdjLocation = function () {
|
||
var layer = this.layer_adj;
|
||
|
||
var leftLine = layer.findOne('.leftLine');
|
||
var rightLine = layer.findOne('.rightLine');
|
||
var centerLine = layer.findOne('.centerLine');
|
||
|
||
var rect = layer.findOne('.rect');
|
||
if (!leftLine || !rightLine || !rect) {
|
||
return;
|
||
}
|
||
if (this.adj_start > this.adj_end) {
|
||
this.adj_end = this.adj_start;
|
||
}
|
||
leftLine.visible(this.adj_show);
|
||
rightLine.visible(this.adj_show);
|
||
rect.visible(this.adj_show);
|
||
|
||
if (this.adj_show) {
|
||
var left = this.getPointByFreq(this.adj_start);
|
||
var right = this.getPointByFreq(this.adj_end);
|
||
var lineWidth = this.adj_lineWidth;
|
||
leftLine.x(left - lineWidth);
|
||
rightLine.x(right);
|
||
|
||
if (centerLine) {
|
||
if (this.adj_lineType == 0 || !this.adj_lineType) {
|
||
//cener
|
||
centerLine.x((right + left) / 2 - lineWidth / 2);
|
||
} else if (this.adj_lineType == 1) {
|
||
//LSB
|
||
centerLine.x(right);
|
||
} else if (this.adj_lineType == 2) {
|
||
//USB
|
||
centerLine.x(left - lineWidth);
|
||
}
|
||
}
|
||
|
||
this.allowRunMode == 0 && this.alwaysShowAdj && this.showAdjInfo(this.adj_x, this.adj_y);
|
||
|
||
rect.x(left);
|
||
rect.width(right - left + lineWidth);
|
||
}
|
||
|
||
layer.batchDraw();
|
||
};
|
||
waterfallwidget.prototype.getAdjCenter = function () {
|
||
var freq = this.adj_start + (this.adj_end - this.adj_start) / 2;
|
||
|
||
if (this.adj_lineType == 1) {
|
||
freq = this.adj_end;
|
||
} else if (this.adj_lineType == 2) {
|
||
freq = this.adj_start;
|
||
}
|
||
return freq;
|
||
};
|
||
waterfallwidget.prototype.getCDBAdjCenter = function () {
|
||
var freq = this.min_freq + (this.max_freq - this.min_freq) / 2;
|
||
|
||
if (this.adj_lineType == 1) {
|
||
freq = this.max_freq;
|
||
} else if (this.adj_lineType == 2) {
|
||
freq = this.min_freq;
|
||
}
|
||
return freq;
|
||
};
|
||
waterfallwidget.prototype.getAdjBw = function () {
|
||
return this.adj_end - this.adj_start;
|
||
};
|
||
waterfallwidget.prototype.setAdjCenter = function (freq, fireEvent = false) {
|
||
var adjbw = this.getAdjBw();
|
||
var adjcenter = freq;
|
||
|
||
if (fireEvent) {
|
||
//修正adjcenter
|
||
if (this.adj_step > 0) {
|
||
adjcenter = Math.round(adjcenter / this.adj_step) * this.adj_step;
|
||
}
|
||
}
|
||
|
||
if (this.validataAdj(adjcenter, adjbw, this.adj_lineType) == false) {
|
||
return { result: false, message: '频点超出范围' };
|
||
}
|
||
|
||
this.setAdjLeftRight(adjcenter, adjbw, this.adj_lineType);
|
||
|
||
if (fireEvent) {
|
||
this.fire('pointer-change', { fc: adjcenter });
|
||
}
|
||
this.drawAdjLocation();
|
||
return { result: true };
|
||
};
|
||
waterfallwidget.prototype.isAdjCenterInRange = function (freq, bw) {
|
||
var _self = this;
|
||
var adjbw = Math.min(bw, _self.adj_maxbw);
|
||
|
||
var adjcenter = freq;
|
||
var left = adjcenter - adjbw / 2;
|
||
var right = adjcenter + adjbw / 2;
|
||
console.log(
|
||
'freq=' +
|
||
freq +
|
||
'_____bw=' +
|
||
bw +
|
||
'___adjbw=' +
|
||
adjbw +
|
||
'____self.adj_maxbw=' +
|
||
_self.adj_maxbw +
|
||
'__left=' +
|
||
left +
|
||
'__right=' +
|
||
right +
|
||
'__this.min_freq=' +
|
||
this.min_freq +
|
||
'___this.max_freq=' +
|
||
this.max_freq,
|
||
);
|
||
|
||
if (left < this.min_freq || left > this.max_freq || right < this.min_freq || right > this.max_freq) {
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
waterfallwidget.prototype.setAdjBand = function (bw) {
|
||
var _self = this;
|
||
var point = this.getAdjCenter();
|
||
var adjbw = Math.min(bw, _self.adj_maxbw);
|
||
if (this.validataAdj(point, adjbw, this.adj_lineType) == false) {
|
||
return { result: false, message: '频点超出范围' };
|
||
}
|
||
this.setAdjLeftRight(point, adjbw, this.adj_lineType);
|
||
|
||
this.drawAdjLocation();
|
||
return { result: true };
|
||
};
|
||
//0正常 1 LSB 2 USB
|
||
waterfallwidget.prototype.setAdjPointType = function (adjlinetype = 0) {
|
||
var bw = this.adj_end - this.adj_start;
|
||
var point = this.adj_start + bw / 2;
|
||
|
||
if (this.validataAdj(point, bw, adjlinetype) == false) {
|
||
return { result: false, message: '频点超出范围' };
|
||
}
|
||
|
||
this.adj_lineType = adjlinetype;
|
||
|
||
this.drawAdjLocation();
|
||
|
||
return { result: true };
|
||
};
|
||
waterfallwidget.prototype.validataAdj = function (pointer, bw, type) {
|
||
var arr = this.getAdjLeftRight(pointer, bw, type);
|
||
var left = arr[0];
|
||
var right = arr[1];
|
||
|
||
if (left < this.min_freq || left > this.max_freq || right < this.min_freq || right > this.max_freq) {
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
};
|
||
waterfallwidget.prototype.getAdjLeftRight = function (pointer, bw, type) {
|
||
var left = pointer - bw / 2;
|
||
var right = pointer + bw / 2;
|
||
if (type == 2) {
|
||
left = pointer;
|
||
right = pointer + bw;
|
||
} else if (type == 1) {
|
||
right = pointer;
|
||
left = pointer - bw;
|
||
}
|
||
return [left, right];
|
||
};
|
||
waterfallwidget.prototype.setAdjLeftRight = function (pointer, bw, type) {
|
||
var arr = this.getAdjLeftRight(pointer, bw, type);
|
||
var left = arr[0];
|
||
var right = arr[1];
|
||
this.adj_start = left;
|
||
this.adj_end = right;
|
||
};
|
||
|
||
waterfallwidget.prototype.drawGather = function () {
|
||
var _self = this;
|
||
var layer = this.layer_gather;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
_self.gather_fc = this.adj_start + (this.adj_end - this.adj_start) / 2;
|
||
var leftLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: '#F37570',
|
||
name: 'leftLine',
|
||
});
|
||
var rightLine = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: this.adj_lineWidth,
|
||
height: this.area_height,
|
||
fill: '#F37570',
|
||
name: 'rightLine',
|
||
});
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: this.area_y,
|
||
width: 0,
|
||
height: this.area_height,
|
||
fill: '#F37570',
|
||
opacity: 0.1,
|
||
name: 'rect',
|
||
});
|
||
var group = new Konva.Group({
|
||
x: 0,
|
||
y: 0,
|
||
});
|
||
group.add(rect);
|
||
group.add(leftLine);
|
||
group.add(rightLine);
|
||
layer.add(group);
|
||
};
|
||
waterfallwidget.prototype.drawGatherLocation = function () {
|
||
var layer = this.layer_gather;
|
||
var _self = this;
|
||
var leftLine = layer.findOne('.leftLine');
|
||
var rightLine = layer.findOne('.rightLine');
|
||
|
||
var rect = layer.findOne('.rect');
|
||
if (!leftLine || !rightLine) {
|
||
return;
|
||
}
|
||
|
||
leftLine.visible(this.gather_show);
|
||
rightLine.visible(this.gather_show);
|
||
rect.visible(this.gather_show);
|
||
if (this.gather_show) {
|
||
var left = this.getPointByFreq(this.gather_fc + _self.gather_bw / 2);
|
||
var right = this.getPointByFreq(this.gather_fc - _self.gather_bw / 2);
|
||
var lineWidth = this.adj_lineWidth;
|
||
leftLine.x(left - lineWidth);
|
||
rightLine.x(right);
|
||
rect.x(left);
|
||
rect.width(right - left + lineWidth);
|
||
}
|
||
layer.batchDraw();
|
||
};
|
||
waterfallwidget.prototype.setGatherBwFc = function (bw, fc) {
|
||
var _self = this;
|
||
_self.gather_show = true;
|
||
_self.gather_bw = bw;
|
||
_self.gather_fc = fc;
|
||
_self.drawGatherLocation();
|
||
};
|
||
waterfallwidget.prototype.hiddenGather = function () {
|
||
this.gather_show = false;
|
||
_self.drawGatherLocation();
|
||
};
|
||
/*像素单位转css单位,该函数返回当前浏览器缩放比例所影响的 x y width height 的绘图位置
|
||
仅适用putImageData getImageData等函数*/
|
||
waterfallwidget.prototype.getDrawWHByPixelRatio = function (xory) {
|
||
if (xory == 0) return 0;
|
||
if (!xory) return xory;
|
||
var ret = Math.ceil(window.devicePixelRatio * xory);
|
||
//console.log(`xory=${xory} ratio=${window.devicePixelRatio} ret=${ret}`);
|
||
return ret;
|
||
};
|
||
|
||
waterfallwidget.prototype.getwf_CtWidth = function () {
|
||
return this.stage.getWidth() - this.margin_left - this.margin_right;
|
||
};
|
||
waterfallwidget.prototype.getwf_CtHeight = function () {
|
||
return this.stage.getHeight() - this.margin_top - this.margin_bottom;
|
||
};
|
||
|
||
waterfallwidget.prototype.setFreqZoomDown = function () {
|
||
if (this.zoomQueue.length > 0) {
|
||
var d = this.zoomQueue.shift();
|
||
|
||
this.setFreqZoom(d.start, d.end);
|
||
|
||
return true;
|
||
} else {
|
||
this.setFreqZoom(this.min_freq, this.max_freq);
|
||
}
|
||
};
|
||
waterfallwidget.prototype.setFreqZoomUp = function (start, end, record = true) {
|
||
//if (this.allowRunMode == 1 && this.adj_show && end - start < this.getAdjBw() * 1.5) {
|
||
// return false;
|
||
//}
|
||
if (record) {
|
||
this.zoomQueue.unshift({ start: this.freq_start, end: this.freq_end });
|
||
}
|
||
this.setFreqZoom(start, end);
|
||
|
||
return true;
|
||
};
|
||
waterfallwidget.prototype.setFreqZoom = function (start, end) {
|
||
if (!start && !end) {
|
||
start = this.min_freq;
|
||
end = this.max_freq;
|
||
}
|
||
//if (this.adj_show) {
|
||
// var adjBand = this.getAdjBw();
|
||
// if (end - start < adjBand * 1.5) {
|
||
// var adjCenter = this.getAdjCenter();
|
||
// var nstart = adjCenter - adjBand * 0.8;
|
||
// var nend = adjCenter + adjBand * 0.8;
|
||
// start = nstart;
|
||
// end = nend;
|
||
// }
|
||
//}
|
||
|
||
setTimeout(() => {
|
||
this.SpectrogramBuff = [];
|
||
this.SpectrogramMinBuff = [];
|
||
this.SpectrogramMaxBuff = [];
|
||
this.CompareCurLineBuff = null;
|
||
this.afterglowBuff = [];
|
||
}, 200);
|
||
|
||
this.changeStart(start, end, true); //o_zoom >= 0代表不是第一次显示
|
||
this.drawInstant();
|
||
this.drawAdjLocation();
|
||
this.drawGatherLocation();
|
||
this.drawChanel();
|
||
|
||
this.drawCarryLine();
|
||
this.drawFreqPointLables();
|
||
return true;
|
||
};
|
||
|
||
waterfallwidget.prototype.clearSpectrogram = function () {
|
||
setTimeout(() => {
|
||
this.SpectrogramBuff = [];
|
||
this.SpectrogramMinBuff = [];
|
||
this.SpectrogramMaxBuff = [];
|
||
this.CompareCurLineBuff = null;
|
||
this.afterglowBuff = [];
|
||
}, 200);
|
||
};
|
||
|
||
waterfallwidget.prototype.changeStart = async function (start, end, reDrawLabel = true) {
|
||
var lastStart = this.freq_start;
|
||
var lastEnd = this.freq_end;
|
||
|
||
var changeUi = true;
|
||
|
||
if (start < this.min_freq) start = this.min_freq;
|
||
if (end > this.max_freq) end = this.max_freq;
|
||
|
||
this.freq_start = Math.floor(start);
|
||
this.freq_end = Math.floor(end);
|
||
|
||
if (lastStart !== this.freq_start || lastEnd !== this.freq_end) {
|
||
if (changeUi) {
|
||
this.drawCoorFreq();
|
||
//this.drawAdjLocation();
|
||
this.drawBottomScrollLocal();
|
||
|
||
this.drawWFOffset(lastStart, lastEnd);
|
||
|
||
//await this.drawWfBuff();
|
||
}
|
||
if (reDrawLabel) {
|
||
// var ret = await $.post('/setting/getIsShowLabelMasker'); // 注释掉接口请求
|
||
this.darwLabel(true); // 使用模拟数据 true
|
||
this.drawWhiteList();
|
||
this.zoomChange();
|
||
}
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
};
|
||
//将当前的画布做缩放重新绘制
|
||
waterfallwidget.prototype.drawWFOffset = function (lastStart, lastEnd) {
|
||
var size = this.visual_MapLen;
|
||
var row = this.waterfall_height;
|
||
if (row == 0) return;
|
||
|
||
var newStart = this.getPointByFreq(lastStart, true);
|
||
var newWidth = size;
|
||
if (lastEnd) {
|
||
var newEnd = this.getPointByFreq(lastEnd, true);
|
||
newWidth = Math.round(newEnd - newStart);
|
||
}
|
||
|
||
if (this.ctx_wf.canvas.width != size || this.ctx_wf.canvas.height != row) {
|
||
this.ctx_wf.canvas.width = size;
|
||
this.ctx_wf.canvas.height = row;
|
||
}
|
||
|
||
// Copy scaled FFT canvas to screen
|
||
var width = this.waterfall_width;
|
||
var height = this.waterfall_height;
|
||
|
||
var temp = document.createElement('canvas');
|
||
temp.height = row;
|
||
temp.width = size;
|
||
var ctx_temp = temp.getContext('2d');
|
||
ctx_temp.drawImage(this.ctx_wf.canvas, 0, 0, size, row - 1, 0, 0, size, row - 1);
|
||
|
||
this.ctx_wf.fillRect(0, 0, size, row);
|
||
|
||
this.ctx_wf.drawImage(ctx_temp.canvas, 0, 0, size, row - 1, newStart, 0, newWidth, row - 1);
|
||
|
||
this.layer_wf
|
||
.getContext()
|
||
.drawImage(this.ctx_wf.canvas, 0, 0, size, row, this.waterfall_x, this.waterfall_y, width, height);
|
||
};
|
||
|
||
waterfallwidget.prototype.drawWfBuff = async function () {
|
||
//console.log("drawWfBuff");
|
||
|
||
if (this.fucFFTBuff) {
|
||
var buff = await this.fucFFTBuff(
|
||
this.freq_start,
|
||
this.freq_end,
|
||
this.waterfall_height,
|
||
this.unitBuffId,
|
||
this.fftModelId,
|
||
);
|
||
if (buff) {
|
||
if (buff.length == 0) return;
|
||
|
||
var colors = this.color_map.getMapColors();
|
||
var size = this.visual_MapLen;
|
||
var imgData = this.ctx_wf.createImageData(size, buff.length);
|
||
|
||
//var spectrumBuff = null;
|
||
for (var row = 0; row < buff.length; row++) {
|
||
var bins = buff[row];
|
||
var per = bins.length / size;
|
||
var rowImgIndex = size * row * 4;
|
||
|
||
if (per > 1) {
|
||
var binVal = 0;
|
||
for (var p = 0; p < size; p++) {
|
||
var binStart = Math.floor(p * per);
|
||
var binEnd = Math.min(Math.floor(p * per + per), bins.length - 1);
|
||
|
||
if (binEnd - binStart <= 1) {
|
||
binVal = bins[binStart];
|
||
} else {
|
||
var vals = [];
|
||
for (var q = binStart; q < binEnd; q++) {
|
||
vals.push(bins[q]);
|
||
}
|
||
binVal = Math.max(...vals);
|
||
}
|
||
//解决雪花问题 太小最后反而变为0导致
|
||
if (binVal >= 200) {
|
||
for (var qq = binStart; qq < Math.min(binStart + 10, bins.length); qq++) {
|
||
if (bins[qq] < 200 && bins[qq] > 10) {
|
||
binVal = bins[qq];
|
||
}
|
||
}
|
||
}
|
||
|
||
var cindex = this.squeeze(binVal - 200);
|
||
if (cindex > Math.abs(this.min_db) || 0) {
|
||
console.log(cindex + '-' + colors.length);
|
||
return imgData;
|
||
}
|
||
var color = colors[cindex];
|
||
|
||
var i = p * 4;
|
||
if (color) {
|
||
imgData.data[rowImgIndex + i + 0] = color[0];
|
||
imgData.data[rowImgIndex + i + 1] = color[1];
|
||
imgData.data[rowImgIndex + i + 2] = color[2];
|
||
imgData.data[rowImgIndex + i + 3] = 255;
|
||
}
|
||
}
|
||
} else {
|
||
per = size / bins.length;
|
||
for (var j = 0; j < bins.length; j++) {
|
||
var i = Math.floor(j * per) * 4;
|
||
var cindex = this.squeeze(bins[j] - 200);
|
||
if (cindex > Math.abs(this.min_db) || 0) {
|
||
console.log(cindex + '-' + colors.length);
|
||
return imgData;
|
||
}
|
||
|
||
var color = colors[cindex];
|
||
if (color) {
|
||
for (var m = 0; m < Math.ceil(per); m++) {
|
||
imgData.data[rowImgIndex + i + m * 4 + 0] = color[0];
|
||
imgData.data[rowImgIndex + i + m * 4 + 1] = color[1];
|
||
imgData.data[rowImgIndex + i + m * 4 + 2] = color[2];
|
||
imgData.data[rowImgIndex + i + m * 4 + 3] = 255;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
this.ctx_wf.putImageData(imgData, 0, 0);
|
||
// Copy scaled FFT canvas to screen
|
||
this.layer_wf
|
||
.getContext()
|
||
.drawImage(
|
||
this.ctx_wf.canvas,
|
||
0,
|
||
0,
|
||
size,
|
||
this.waterfall_height,
|
||
this.waterfall_x,
|
||
this.waterfall_y,
|
||
this.waterfall_width,
|
||
this.waterfall_height,
|
||
);
|
||
|
||
//if (spectrumBuff) {
|
||
// this.drawAllSpectrogram(spectrumBuff);
|
||
//}
|
||
}
|
||
}
|
||
};
|
||
//标签
|
||
waterfallwidget.prototype.darwLabel = async function (status) {
|
||
if (!this.options.label_manager) return; //this.unitBuffId
|
||
|
||
var start = this.freq_start;
|
||
var end = this.freq_end;
|
||
|
||
var layer = this.layer_label;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
var _self = this;
|
||
var rowCount = 2;
|
||
var rowHeight = 12;
|
||
var opaNormal = 0.5;
|
||
var opaSelected = 0.9;
|
||
var opaLine = 0.5;
|
||
|
||
var row = 0;
|
||
var rowStart = this.spectrogram_y + 1;
|
||
|
||
var labels = await this.options.label_manager.load(start, end);
|
||
if (!status) {
|
||
labels = [];
|
||
}
|
||
for (var i = 0; i < labels.length; i++) {
|
||
var label = labels[i];
|
||
|
||
var text = new Konva.Text({
|
||
x: 2,
|
||
y: 2,
|
||
text: label.name,
|
||
fontSize: 10,
|
||
fill: '#B3BAC5', //label.fore_color
|
||
});
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: label.bg_color, //'#686A78',
|
||
width: text.width() > 0 ? text.width() + 4 : 0,
|
||
height: text.height() > 0 ? text.height() + 4 : 0,
|
||
cornerRadius: 0,
|
||
//stroke: label.bg_color,
|
||
strokeWidth: 0,
|
||
name: 'rect',
|
||
});
|
||
|
||
var bw = label.bw;
|
||
var bwWidth = this.getWidthByBw(bw);
|
||
var line = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: label.bg_color, //'#B3BAC5',
|
||
width: bwWidth,
|
||
height: this.area_height,
|
||
cornerRadius: 0,
|
||
name: 'line',
|
||
opacity: opaLine,
|
||
});
|
||
|
||
var group = new Konva.Group({
|
||
x: _self.getPointByFreq(label.location - bw / 2),
|
||
y: rowStart, //+ row * rowHeight,
|
||
opacity: opaNormal,
|
||
});
|
||
|
||
group.label = label;
|
||
|
||
group.add(line);
|
||
//group.add(rect);//信号标签标题
|
||
//group.add(text);
|
||
|
||
layer.add(group);
|
||
|
||
if (this.currentLabel && label.id === this.currentLabel.label.id) {
|
||
group.opacity = opaNormal;
|
||
}
|
||
row++;
|
||
if (row > rowCount - 1) {
|
||
row = 0;
|
||
}
|
||
}
|
||
layer.batchDraw();
|
||
|
||
layer.find('Group').on('click', (evt) => {
|
||
var current = evt.currentTarget.label;
|
||
|
||
this.label_manager.onclick(current);
|
||
});
|
||
|
||
layer.find('Group').on('mouseenter', (evt) => {
|
||
evt.currentTarget.opacity(opaSelected);
|
||
layer.draw();
|
||
|
||
evt.currentTarget.on('mouseleave', (evt2) => {
|
||
var label = evt2.currentTarget.label;
|
||
|
||
if (!this.currentLabel || this.currentLabel.label.id !== label.id) {
|
||
evt2.currentTarget.opacity(opaNormal);
|
||
}
|
||
evt2.currentTarget.off('mouseleave');
|
||
|
||
layer.draw();
|
||
});
|
||
|
||
//鼠标滚动放大缩小
|
||
evt.currentTarget.on('wheel', (evt) => {
|
||
if (_self.disableZoom) {
|
||
return;
|
||
}
|
||
|
||
var scale = Math.exp((-evt.evt.wheelDelta * 1.0) / 200);
|
||
var freq = this.getFreqByPoint(evt.evt.offsetX);
|
||
|
||
//var range = this.freq_end - this.freq_start;
|
||
//var nrange = range * scale;
|
||
|
||
var start = freq - (freq - this.freq_start) * scale;
|
||
var end = freq + (this.freq_end - freq) * scale;
|
||
|
||
this.throttleSetFreqZoomUp(start, end, false);
|
||
|
||
evt.evt.preventDefault();
|
||
evt.evt.stopPropagation();
|
||
return false;
|
||
});
|
||
|
||
//鼠标左键
|
||
var buttonLR;
|
||
|
||
//放大缩小菜单等
|
||
evt.currentTarget.on('mousedown', function (e) {
|
||
var distanceX = e.evt.offsetX;
|
||
var distanceY = e.evt.offsetY;
|
||
|
||
_self.hideContextMenu();
|
||
if (e.evt.button === 2) {
|
||
buttonLR = 'right';
|
||
_self.adj_show = true;
|
||
_self.adj_start = _self.getFreqByPoint(distanceX);
|
||
} else if (e.evt.button === 0) {
|
||
buttonLR = 'left';
|
||
}
|
||
_self.stage.on('mousemove', async function (e) {
|
||
//只有鼠标右键键移动
|
||
if (buttonLR === 'right') {
|
||
if (_self.adj_show && e.evt.offsetX - distanceX > 0) {
|
||
_self.adj_end = _self.getFreqByPoint(e.evt.offsetX);
|
||
_self.drawAdjLocation();
|
||
}
|
||
//_self.stage.off('mouseup');
|
||
}
|
||
});
|
||
_self.stage.on('mouseup', async function (e) {
|
||
_self.clearCoverLayer();
|
||
if (buttonLR === 'right') {
|
||
var dx = e.evt.offsetX;
|
||
var dy = e.evt.offsetY;
|
||
if (!_self.adj_show || e.evt.offsetX - distanceX <= 0) {
|
||
//_self.showLabelsMenu(e);//信号标签右键菜单
|
||
}
|
||
|
||
//右键点击
|
||
if (Math.abs(dx - distanceX) < 10) {
|
||
if (_self.adj_show) {
|
||
_self.adj_show = false;
|
||
_self.drawAdjLocation();
|
||
}
|
||
}
|
||
}
|
||
buttonLR = null;
|
||
_self.stage.off('mousemove');
|
||
_self.stage.off('mouseup');
|
||
});
|
||
});
|
||
});
|
||
|
||
//layer.find('Group').on('click', evt => {
|
||
|
||
// //_self._setAdjPointer(evt.currentTarget.label.location, true);
|
||
|
||
// //移除以往
|
||
// if (this.currentLabel && this.currentLabel.label.id !== evt.currentTarget.label.id) {
|
||
// //判断是因为有可能因为缩放原因,虽然保留引用但是实际已消失了
|
||
// //if (this.currentLabel.findOne('.rect')) {
|
||
// // this.currentLabel.findOne('.rect').stroke(this.currentLabel.label.bg_color);
|
||
// // this.currentLabel.findOne('.line').fill(this.currentLabel.label.bg_color);
|
||
// //}
|
||
// this.currentLabel.attrs.opacity = 0.4;
|
||
// }
|
||
// evt.currentTarget.attrs.opacity = 0.8;
|
||
// //evt.currentTarget.findOne('.rect').stroke(this.fore_color);
|
||
// //evt.currentTarget.findOne('.line').fill(this.fore_color);
|
||
// layer.draw();
|
||
// if (!this.currentLabel || this.currentLabel.label.id !== evt.currentTarget.label.id) {
|
||
// _self.fire('label-change', evt.currentTarget.label);
|
||
// }
|
||
|
||
// this.currentLabel = evt.currentTarget;
|
||
|
||
//});
|
||
};
|
||
|
||
waterfallwidget.prototype.getDbByPoint = function (point) {
|
||
if (point > this.spectrogram_y + this.spectrogram_height) {
|
||
return null;
|
||
}
|
||
var perPoint = (this.max_db - this.min_db) / this.spectrogram_height;
|
||
|
||
var db = Number(this.max_db - (point - this.spectrogram_y) * perPoint);
|
||
|
||
return Math.floor(db);
|
||
};
|
||
waterfallwidget.prototype.getPointByDb = function (db) {
|
||
var perPoint = (this.max_db - this.min_db) / this.spectrogram_height;
|
||
|
||
var h = (this.max_db - db) / perPoint;
|
||
|
||
var point = Number(this.spectrogram_y + h);
|
||
|
||
return Math.floor(point);
|
||
};
|
||
|
||
waterfallwidget.prototype.getPointByFreq = function (freq, visual) {
|
||
if (visual) {
|
||
var perPoint = (this.freq_end - this.freq_start) / this.visual_MapLen;
|
||
var point = (freq - this.freq_start) / perPoint;
|
||
return point;
|
||
} else {
|
||
var per = (this.freq_end - this.freq_start) / this.waterfall_width;
|
||
var pointr = (freq - this.freq_start) / per;
|
||
return this.margin_left + pointr + 1;
|
||
}
|
||
};
|
||
waterfallwidget.prototype.getFreqByPoint = function (point) {
|
||
var perPoint = (this.freq_end - this.freq_start) / this.waterfall_width;
|
||
var freq = Number(this.freq_start + (point - this.margin_left - 1) * perPoint);
|
||
freq = Math.min(freq, this.freq_end);
|
||
freq = Math.max(freq, this.freq_start);
|
||
return Math.floor(freq);
|
||
};
|
||
waterfallwidget.prototype.getFreqBySpanPoint = function (span) {
|
||
var perPoint = (this.freq_end - this.freq_start) / this.waterfall_width;
|
||
return Math.floor(perPoint * span);
|
||
};
|
||
|
||
waterfallwidget.prototype.getWidthByBw = function (bw, visual) {
|
||
if (visual) {
|
||
var perPoint = (this.freq_end - this.freq_start) / this.visual_MapLen;
|
||
var point = bw / perPoint;
|
||
return point;
|
||
} else {
|
||
var per = (this.freq_end - this.freq_start) / this.waterfall_width;
|
||
var pointr = bw / per;
|
||
return pointr + 1;
|
||
}
|
||
};
|
||
|
||
waterfallwidget.prototype.getFreqByPointInZoom = function (point) {
|
||
var count = this.zoomOption[this.freq_zoom].count;
|
||
var per = this.zoomPer;
|
||
var perPoint = (count * per) / this.waterfall_width;
|
||
|
||
return perPoint * point;
|
||
};
|
||
waterfallwidget.prototype.getPointByBand = function (hz) {
|
||
//200p --4000hz
|
||
//return hz / (4000*1.0/200);
|
||
|
||
//按真实比例来算
|
||
var count = this.zoomOption[this.freq_zoom].count;
|
||
var per = this.zoomPer;
|
||
var perPoint = (count * per) / this.waterfall_width;
|
||
|
||
return (hz * 0.001) / perPoint;
|
||
};
|
||
waterfallwidget.prototype.getBandByPoint = function (p) {
|
||
//200p --4000hz
|
||
return p * ((4000 * 1.0) / 200);
|
||
};
|
||
|
||
waterfallwidget.prototype._showInfo = function (opt) {
|
||
if (this.info_Position < 0) return;
|
||
|
||
var layer = this.layer_info;
|
||
var textInfo = (opt && opt.text) || 'message';
|
||
var x = (opt && opt.x) || 0;
|
||
var y = (opt && opt.y) || 0;
|
||
var centerp = (opt && opt.centerp) || false;
|
||
var textcolor = (opt && opt.textcolor) || this.info_Position == 0 ? this.bg_color : this.fore_color;
|
||
var bgcolor = (opt && opt.bgcolor) || this.info_Position == 0 ? this.fore_color : this.bg_color;
|
||
|
||
var text = new Konva.Text({
|
||
x: 10,
|
||
y: 10,
|
||
text: textInfo,
|
||
fontSize: 13,
|
||
fill: textcolor,
|
||
});
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: bgcolor,
|
||
width: text.width() + 20,
|
||
height: text.height() + 20,
|
||
cornerRadius: 5,
|
||
shadowColor: this.bg_color,
|
||
shadowBlur: 10,
|
||
shadowOffset: [10, 10],
|
||
shadowOpacity: 0.2,
|
||
stroke: this.bg_color,
|
||
strokeWidth: 2,
|
||
});
|
||
var group = new Konva.Group({
|
||
x: 0,
|
||
y: 0,
|
||
});
|
||
|
||
group.add(rect);
|
||
group.add(text);
|
||
|
||
if (x == 0 && y == 0) {
|
||
x = this.stage.getWidth() / 2 - rect.getWidth() / 2;
|
||
y = this.stage.getHeight() / 2 - rect.getHeight() / 2;
|
||
} else if (centerp) {
|
||
x = x - rect.width() / 2;
|
||
}
|
||
|
||
group.x(x);
|
||
group.y(y);
|
||
layer.add(group);
|
||
|
||
layer.draw();
|
||
};
|
||
waterfallwidget.prototype.showInfoAuto = function (opt) {
|
||
var delay = (opt && opt.delay) || 1000;
|
||
var _self = this;
|
||
_self.hideInfo();
|
||
_self.showInfo(opt);
|
||
|
||
_self.infoTimeout = setTimeout(function () {
|
||
_self.hideInfo();
|
||
}, delay);
|
||
};
|
||
waterfallwidget.prototype.hideInfo = function () {
|
||
var layer = this.layer_info;
|
||
var layer5 = this.layer_info5;
|
||
if (this.infoTimeout) {
|
||
clearTimeout(this.infoTimeout);
|
||
this.infoTimeout = null;
|
||
}
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
layer.draw();
|
||
};
|
||
waterfallwidget.prototype.showInfo = function (opt, canSetting = false) {
|
||
if (this.infoTimeout) {
|
||
clearTimeout(this.infoTimeout);
|
||
this.infoTimeout = null;
|
||
}
|
||
var _self = this;
|
||
var layer = this.layer_info;
|
||
var message = (opt && opt.text) || 'message';
|
||
var x = (opt && opt.x) || 0;
|
||
var y = (opt && opt.y) || 0;
|
||
var curX = x;
|
||
var curY = y;
|
||
if (canSetting && this.info_Position == 1) {
|
||
x = this.container.clientWidth - this.margin_right - 140;
|
||
y = this.margin_top + 2;
|
||
opt.x = x;
|
||
opt.y = y;
|
||
}
|
||
|
||
var centerp = (opt && opt.centerp) || false;
|
||
|
||
var text = layer.findOne('Text');
|
||
|
||
if (!text) {
|
||
_self._showInfo(opt);
|
||
} else {
|
||
var rect = layer.findOne('Rect');
|
||
var group = layer.findOne('Group');
|
||
text.text(message);
|
||
rect.width(text.width() + 20);
|
||
rect.height(text.height() + 20);
|
||
|
||
if (x == 0 && y == 0) {
|
||
x = this.stage.getWidth() / 2 - rect.getWidth() / 2;
|
||
y = this.stage.getHeight() / 2 - rect.getHeight() / 2;
|
||
} else if (centerp) {
|
||
x = x - rect.width() / 2;
|
||
}
|
||
group.x(x);
|
||
group.y(y);
|
||
|
||
if (this.showCurLine) {
|
||
var linex = layer.findOne('.linex');
|
||
if (linex) {
|
||
linex.remove();
|
||
}
|
||
var liney = layer.findOne('.liney');
|
||
if (liney) {
|
||
liney.remove();
|
||
}
|
||
linex = new Konva.Line({
|
||
points: [this.waterfall_x, curY, this.waterfall_x + this.waterfall_width, curY],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
name: 'linex',
|
||
});
|
||
liney = new Konva.Line({
|
||
points: [curX, this.margin_top, curX, this.stage.getHeight() - this.margin_bottom],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
name: 'liney',
|
||
});
|
||
|
||
layer.add(linex);
|
||
layer.add(liney);
|
||
}
|
||
|
||
layer.draw();
|
||
}
|
||
};
|
||
|
||
waterfallwidget.prototype.showInfoMakeDb = function () {
|
||
if (this.infoTimeout) {
|
||
clearTimeout(this.infoTimeout);
|
||
this.infoTimeout = null;
|
||
}
|
||
var layer5 = this.layer_info5;
|
||
//Mak频差 和 电平差动态改变 所属参数不能为空值
|
||
if (this.MakeShow != null && this.MakeShow.length == 2) {
|
||
var text1 = layer5.findOne('Text');
|
||
var info =
|
||
'频差:' +
|
||
Math.ceil(Math.abs(this.MakeShow[0] - this.MakeShow[1]) / 1000000) +
|
||
'MHz\n电平差:' +
|
||
Math.abs(this.MakeDb - this.MakeDb1) +
|
||
'dBm';
|
||
if (!text1) {
|
||
////Mak频差 和 电平差 模型初始化
|
||
if (this.MakeShow != null && this.MakeShow.length == 2) {
|
||
var layer5 = this.layer_info5;
|
||
var text1 = new Konva.Text({
|
||
x: 10,
|
||
y: 10,
|
||
text: info,
|
||
fontSize: 13,
|
||
fill: this.info_Position == 0 ? this.bg_color : this.fore_color,
|
||
});
|
||
var rect1 = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: this.info_Position == 0 ? this.fore_color : this.bg_color,
|
||
width: text1.width() + 20,
|
||
height: text1.height() + 20,
|
||
cornerRadius: 5,
|
||
shadowColor: this.bg_color,
|
||
shadowBlur: 10,
|
||
shadowOffset: [10, 10],
|
||
shadowOpacity: 0.2,
|
||
stroke: this.bg_color,
|
||
strokeWidth: 2,
|
||
});
|
||
var group1 = new Konva.Group({
|
||
x: 0,
|
||
y: 0,
|
||
});
|
||
|
||
group1.add(rect1);
|
||
group1.add(text1);
|
||
group1.x(70);
|
||
group1.y(22);
|
||
layer5.add(group1);
|
||
layer5.draw();
|
||
}
|
||
} else {
|
||
var rect1 = layer5.findOne('Rect');
|
||
var group1 = layer5.findOne('Group');
|
||
rect1.width(text1.width() + 20);
|
||
rect1.height(text1.height() + 20);
|
||
text1.text(info);
|
||
group1.x(this.margin_left + 10);
|
||
group1.y(22);
|
||
|
||
if (this.showCurLine) {
|
||
var linex = layer5.findOne('.linex');
|
||
if (linex) {
|
||
linex.remove();
|
||
}
|
||
var liney = layer5.findOne('.liney');
|
||
if (liney) {
|
||
liney.remove();
|
||
}
|
||
linex = new Konva.Line({
|
||
points: [this.waterfall_x, curY, this.waterfall_x + this.waterfall_width, curY],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
name: 'linex',
|
||
});
|
||
liney = new Konva.Line({
|
||
points: [curX, this.margin_top, curX, this.stage.getHeight() - this.margin_bottom],
|
||
stroke: this.fore_color,
|
||
strokeWidth: 1,
|
||
listening: false,
|
||
name: 'liney',
|
||
});
|
||
|
||
layer5.add(linex);
|
||
layer5.add(liney);
|
||
}
|
||
|
||
layer5.draw();
|
||
}
|
||
} else {
|
||
layer5.destroyChildren();
|
||
layer5.removeChildren();
|
||
layer5.draw();
|
||
}
|
||
};
|
||
waterfallwidget.prototype.showFreqInfo = function (p, auto) {
|
||
//var _self = this;
|
||
//p = p || 'pointer';
|
||
//var x = _self.getPointByFreq(_self.adj_Pointer);
|
||
//var y = _self.margin_top - 80;
|
||
//var text = _self.adj_Pointer + "kHz";
|
||
//if (p == 'band') {
|
||
// text = "BAND:" + _self.adj_Band + "Hz";
|
||
//}
|
||
//var d = {
|
||
// text: text,
|
||
// y: y,
|
||
// x: x,
|
||
// centerp: true
|
||
//};
|
||
//if (auto) {
|
||
// _self.showInfoAuto(d);
|
||
//}
|
||
//else {
|
||
// _self.showInfo(d);
|
||
//}
|
||
};
|
||
|
||
waterfallwidget.prototype.initContextMenu = function () {
|
||
var p0 = `<div id='warterfall-contextmenu' class="dropdown bootstrapMenu" style="z-index: 10000; position: absolute; display: none;">
|
||
<ul class="dropdown-menu" style="position:static;display:block;font-size:0.9em;">`;
|
||
|
||
var p1 = '';
|
||
if (this.allowRunMode === 0) {
|
||
p1 = `<li class='ddc-item-click ddc-item' ><a href="javascript:void(0);"><span>单次侦察</span></a></li><li class='divider ddc-item' ></li>`;
|
||
}
|
||
var p1_1 = '';
|
||
if (this.allowRunMode === 0) {
|
||
p1_1 = `<li class='item-loop-ana ddc-item' ><a href="javascript:void(0);"><span>持续侦察</span></a></li><li class='divider ddc-item' ></li>`;
|
||
}
|
||
//备份
|
||
var p1_1_1 = '';
|
||
if (this.allowRunMode === 0) {
|
||
p1_1_1 =
|
||
`<li class="dropdown-submenu action-info ddc-item">
|
||
<a class="dropdown-item dropdown-toggle" data-toggle="dropdown" data-stopPropagation="true">持续侦察</a>
|
||
<ul class="dropdown-menu">
|
||
<li class='ddc-item-click-loop ddc-item' ><a href="javascript:void(0);"><span>循环检测</span></a></li>
|
||
|
||
|
||
<li class='ddc-item-click-loop ddc-item d-none' ><a href="javascript:void(0);"><span>数据采集</span></a></li>
|
||
<li class='ddc-item-click-loop ddc-item d-none' ><a href="javascript:void(0);"><span>体制识别</span></a></li>
|
||
<li class='ddc-item-click-loop ddc-item d-none' ><a href="javascript:void(0);"><span>信号解调</span></a></li>
|
||
<li class='ddc-item-click-loop ddc-item d-none' ><a href="javascript:void(0);"><span>编码识别</span></a></li>
|
||
<li class='ddc-item-click-loop ddc-item d-none' ><a href="javascript:void(0);"><span>协议识别</span></a></li>` +
|
||
(this.menuDoppler
|
||
? `<li class='ddc-item-click ddc-item d-none' ><a href="javascript:void(0);"><span>多普勒估计</span></a></li>`
|
||
: ``) +
|
||
`
|
||
|
||
</ul>
|
||
</li>
|
||
<li class='divider ddc-item' ></li>`;
|
||
}
|
||
|
||
var p2 = '';
|
||
if (this.allowRunMode == 1) {
|
||
p2 = `
|
||
<li class="dropdown-submenu action-info ddc-item">
|
||
<a class="dropdown-item dropdown-toggle" data-toggle="dropdown">实时监视</a>
|
||
<ul class="dropdown-menu">
|
||
|
||
|
||
<li data-action="downloadpcm" class="action-info item-sound-add ddc-item">
|
||
<a href="javascript:void(0);" ><span class="actionName">音频数据(AM/FM)</span></a>
|
||
</li>
|
||
|
||
<li data-action="downloadfft" class="action-info item-adsb-add ddc-item">
|
||
<a href="javascript:void(0);" role="menuitem"><span class="actionName">态势(ADS-B)</span></a>
|
||
</li>
|
||
<li data-action="downloadfft" class="action-info item-acxx-add ddc-item">
|
||
<a href="javascript:void(0);" role="menuitem"><span class="actionName">态势(ACXX)</span></a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class='divider ddc-item' ></li>`;
|
||
}
|
||
|
||
var p3 = `<li class='ddc-item-click-addExcludes ddc-item' ><a href="javascript:void(0);"><span>添加到黑名单</span></a></li>`;
|
||
var p4 = ``;
|
||
if (this.allowRunMode === 0) {
|
||
p4 = `<li class='divider ddc-item' ></li><li class="dropdown-submenu action-info ddc-item">
|
||
<a class="dropdown-item dropdown-toggle" data-toggle="dropdown" href="javascript:void(0);">数据采集</a>
|
||
<ul class="dropdown-menu">`;
|
||
if (this.isADGather == true) {
|
||
p4 += `<li class='ddc-item-click-adnarrowband ddc-item' ><a href="javascript:void(0);"><span>窄带AD采集</span></a></li>
|
||
<li class='ddc-item-click-broadband ddc-item' ><a href="javascript:void(0);"><span>宽带AD采集</span></a></li>`;
|
||
}
|
||
// p4 += `<li class='ddc-item-click-ddc ddc-item' ><a href="javascript:void(0);"><span>单路持续采集</span></a></li>
|
||
//<li class='ddc-item-click-ddc-mut ddc-item ' ><a href="javascript:void(0);"><span>多路持续采集</span></a></li>
|
||
//<li class='ddc-item-click-loop-ddc ddc-item' ><a href="javascript:void(0);"><span>能量触发采集</span></a></li>
|
||
//<li class='ddc-item-click-loop-ddc-xl ddc-item ' ><a href="javascript:void(0);"><span>同步序列触发采集</span></a></li>
|
||
// </ul>
|
||
// </li>`;
|
||
p4 += `<li class='ddc-item-click-ddc ddc-item' ><a href="javascript:void(0);"><span>单路持续采集</span></a></li>
|
||
<li class='ddc-item-click-ddc-mut ddc-item ' ><a href="javascript:void(0);"><span>多路持续采集</span></a></li>
|
||
</ul>
|
||
</li>`;
|
||
}
|
||
|
||
//短波
|
||
var p10 = '';
|
||
if (this.isHF) {
|
||
p10 = `<li class='ddc-item-click ddc-item' ><a href="javascript:void(0);"><span>单次侦察</span></a></li><li class='divider ddc-item' ></li>`;
|
||
}
|
||
var p9 = `<li class='ddc-item ddc-item-disable' ><a href="javascript:void(0);"><span>${this.menuDisableText}</span></a></li>
|
||
</ul></div>`;
|
||
var p11 = '';
|
||
if (this.showCheckSignal) {
|
||
p11 = `<li class='ddc-item-click-addSignal'><a href="javascript:void(0);"><span>识别选中信号</span></a></li><li class='divider' ></li>`;
|
||
}
|
||
var p12 = '';
|
||
if (this.showHoppingDetect) {
|
||
p12 = `<li class='ddc-item-click-hoppdetect'><a href="javascript:void(0);"><span>跳频检测</span></a></li><li class='divider ddc-item' ></li>`;
|
||
}
|
||
|
||
if (this.isHF) {
|
||
this.contextMenu = $(p0 + p1 + p1_1 + p2 + p11 + p3 + p4 + p9);
|
||
} else if (this.isUHF) {
|
||
this.contextMenu = $(p0 + p1 + p1_1 + p2 + p11 + p12 + p3 + p9); //+ p5
|
||
} else {
|
||
this.contextMenu = $(p0 + p1 + p1_1 + p2 + p11 + p12 + p3 + p4 + p9); //p1_1_2 + p5
|
||
}
|
||
$('body').append(this.contextMenu);
|
||
this.contextMenu.on('click', 'a', (e) => {
|
||
var li = $(e.currentTarget).closest('li');
|
||
if (li.hasClass('ddc-item-click')) {
|
||
this.fire('context-click', { action: $(e.currentTarget).text() });
|
||
}
|
||
//else if (li.hasClass('ddc-item-click-loop')) {
|
||
// this.fire("context-loop-click", { action: $(e.currentTarget).text() });
|
||
//}
|
||
else if (li.hasClass('ddc-item-click-loop-ddc')) {
|
||
this.fire('context-loop-ddc-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-loop-ddc-xl')) {
|
||
this.fire('context-loop-xl-ddc-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-addExcludes')) {
|
||
this.fire('context-addExcludes-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-ddc')) {
|
||
this.fire('context-ddc-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-adnarrowband')) {
|
||
this.fire('context-adnarrowband-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-broadband')) {
|
||
this.fire('context-broadband-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-ddc-mut')) {
|
||
this.fire('context-ddc-mut-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('item-sound-add')) {
|
||
this.fire('context-sound-add-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('item-adsb-add')) {
|
||
this.fire('context-adsb-add-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('item-acxx-add')) {
|
||
this.fire('context-acxx-add-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('item-loop-ana')) {
|
||
this.fire('context-loop-ana-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('realtime-monitor')) {
|
||
this.fire('context-realtime-monitor', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-addSignal')) {
|
||
this.fire('context-addSignal-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-hoppdetect')) {
|
||
this.fire('ddc-item-click-hoppdetect', { action: $(e.currentTarget).text() });
|
||
}
|
||
//else if (li.hasClass('item-loop-control')) {
|
||
// this.fire("context-loop-control-click", { action: $(e.currentTarget).text() });
|
||
//}
|
||
|
||
this.hideContextMenu();
|
||
});
|
||
//屏蔽区域内的右键菜单功能20210916 liujg
|
||
this.contextMenu.on('contextmenu', (e) => {
|
||
window.event.returnValue = false;
|
||
});
|
||
//鼠标离开菜单元素后自动隐藏功能菜单
|
||
this.contextMenu.on('mouseleave', (e) => {
|
||
this.hideContextMenu();
|
||
});
|
||
};
|
||
|
||
waterfallwidget.prototype.initLabelsMenu = function () {
|
||
_self = this;
|
||
var p0 = `<div id='warterfall-labelsmenu' class="dropdown bootstrapMenu" style="z-index: 10000; position: absolute; display: none;">
|
||
<ul class="dropdown-menu" style="position:static;display:block;font-size:0.9em;">`;
|
||
|
||
var p1 = '';
|
||
if (this.allowRunMode === 0) {
|
||
p1 = `<li class="dropdown-submenu action-info ddc-item">
|
||
<a class="dropdown-item dropdown-toggle" data-toggle="dropdown" data-stopPropagation="true">重新分析</a>
|
||
<ul class="dropdown-menu">
|
||
<li class='item-resysidentity-ana ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>体制识别</span></a></li>
|
||
<li class='item-redemodsig-ana ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>信号解调</span></a></li>
|
||
<li class='item-reencodefy-ana ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>编码识别</span></a></li>
|
||
<li class='item-redoprotocol-ana ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>协议识别</span></a></li>
|
||
|
||
<li class='item-redoppler-ana ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>多普勒估计</span></a></li>
|
||
</ul>
|
||
</li>
|
||
<li class='divider ddc-item' ></li>`;
|
||
}
|
||
var p2 = '';
|
||
p2 += `<li class='item-setcolor-ana ddc-item'><a class='label-menu-item' href="javascript:void(0);" id="specColor" name="specColor"><span>颜色标注</span></a></li><li class='divider ddc-item' ></li>`;
|
||
|
||
var p3 = `<li class='ddc-item-click-addExcludes ddc-item label-menu-ite' ><a class='label-menu-item' href="javascript:void(0);"><span>添加到黑名单</span></a></li>`;
|
||
var p4 = ``;
|
||
if (this.allowRunMode === 0) {
|
||
p4 = `<li class='divider ddc-item' ></li><li class="dropdown-submenu action-info ddc-item">
|
||
<a class="dropdown-item dropdown-toggle" data-toggle="dropdown" href="javascript:void(0);">下载数据</a>
|
||
<ul class="dropdown-menu">`;
|
||
|
||
p4 += `<li class='ddc-item-click-adnarrowband ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>下载DDC/模采数据</span></a></li>
|
||
<li class='ddc-item-click-broadband ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>下载解调数据</span></a></li>`;
|
||
|
||
p4 += `<li class='ddc-item-click-ddc ddc-item' ><a class='label-menu-item' href="javascript:void(0);"><span>下载解码数据</span></a></li>
|
||
</ul>
|
||
</li>`;
|
||
}
|
||
var p9 = `<li class='ddc-item ddc-item-disable' ><a href="javascript:void(0);"><span></span></a></li>
|
||
</ul></div>`;
|
||
|
||
this.labelsMenu = $(p0 + p1 + p2 + p3 + p4 + p9);
|
||
|
||
$('body').append(this.labelsMenu);
|
||
|
||
this.labelsMenu.on('click', 'a', (e) => {
|
||
var li = $(e.currentTarget).closest('li');
|
||
if (li.hasClass('ddc-item-click')) {
|
||
this.fire('context-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('item-setcolor-ana')) {
|
||
this.fire('context-setcolor-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('item-resysidentity-ana')) {
|
||
this.fire('context-resysidentity-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('item-redemodsig-ana')) {
|
||
this.fire('context-redemodsig-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('item-reencodefy-ana')) {
|
||
this.fire('context-reencodefy-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('item-redoprotocol-ana')) {
|
||
this.fire('context-redoprotocol-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('item-redoppler-ana')) {
|
||
this.fire('context-redoppler-click', { action: $(e.currentTarget) });
|
||
} else if (li.hasClass('ddc-item-click-addExcludes')) {
|
||
this.fire('context-addExcludes-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-loop-ddc')) {
|
||
this.fire('context-loop-ddc-click', { action: $(e.currentTarget).text() });
|
||
} else if (li.hasClass('ddc-item-click-loop-ddc-xl')) {
|
||
this.fire('context-loop-xl-ddc-click', { action: $(e.currentTarget).text() });
|
||
}
|
||
this.hideContextMenu();
|
||
});
|
||
//屏蔽区域内的右键菜单功能20210916 liujg
|
||
this.labelsMenu.on('contextmenu', (e) => {
|
||
window.event.returnValue = false;
|
||
});
|
||
//鼠标离开菜单元素后自动隐藏功能菜单
|
||
this.labelsMenu.on('mouseleave', (e) => {
|
||
this.hideContextMenu();
|
||
});
|
||
};
|
||
waterfallwidget.prototype.destroryContextMenu = function () {
|
||
this.contextMenu.remove();
|
||
//this.labelsMenu.remove();
|
||
};
|
||
waterfallwidget.prototype.showLabelsMenu = function (el) {
|
||
if (el) {
|
||
createAttribute(el, 'label-menu-item');
|
||
}
|
||
this.labelsMenu.css('left', el.evt.clientX).css('top', el.evt.clientY);
|
||
|
||
setTimeout((ee) => {
|
||
//this.labelsMenu.show();
|
||
}, 200);
|
||
};
|
||
|
||
createAttribute = function (el, itemId) {
|
||
var menuItems = document.getElementsByClassName(itemId);
|
||
|
||
if (menuItems.length <= 0) return;
|
||
|
||
for (var i = 0; i < menuItems.length; i++) {
|
||
var attr = document.createAttribute('label-id');
|
||
attr.nodeValue = el.target.parent.label.id;
|
||
menuItems[i].attributes.setNamedItem(attr);
|
||
}
|
||
};
|
||
waterfallwidget.prototype.showContextMenu = function (x, y) {
|
||
this.contextMenu.css('left', x).css('top', y);
|
||
if (this.adj_show) {
|
||
this.contextMenu.find('.ddc-item').removeClass('disabled');
|
||
} else {
|
||
this.contextMenu.find('.ddc-item').addClass('disabled');
|
||
}
|
||
|
||
var enable = this.menuEnableHandle ? !this.menuEnableHandle() : false;
|
||
if (enable) {
|
||
this.contextMenu.find('.ddc-item').show();
|
||
this.contextMenu.find('.ddc-item-disable').hide();
|
||
} else {
|
||
this.contextMenu.find('.ddc-item').hide();
|
||
this.contextMenu.find('.ddc-item-disable').show();
|
||
}
|
||
|
||
setTimeout((ee) => {
|
||
this.contextMenu.show();
|
||
}, 200);
|
||
};
|
||
waterfallwidget.prototype.hideContextMenu = function () {
|
||
this.contextMenu.hide();
|
||
//this.labelsMenu.hide();
|
||
};
|
||
|
||
waterfallwidget.prototype.zoomChange = function () {
|
||
this.fire('zoom-change', { start: this.freq_start, end: this.freq_end });
|
||
};
|
||
|
||
waterfallwidget.prototype.setFreqRange = function (min, max) {
|
||
this.min_freq = min;
|
||
this.max_freq = max;
|
||
|
||
//this.adj_Pointer = (this.max_freq - this.min_freq) / 2;
|
||
this.zoomPer = (this.max_freq - this.min_freq) / this.zoomOption;
|
||
this.setFreqZoom();
|
||
this.zoomQueue = [];
|
||
};
|
||
|
||
waterfallwidget.prototype.setShowSpectrogramAvg = function (val) {
|
||
this.showSpectrogramAvg = val;
|
||
this.SpectrogramBuff = [];
|
||
};
|
||
waterfallwidget.prototype.setShowSpectrogramMin = function (val) {
|
||
this.showSpectrogramMin = val;
|
||
this.SpectrogramMinBuff = [];
|
||
};
|
||
waterfallwidget.prototype.setShowSpectrogramMax = function (val) {
|
||
this.showSpectrogramMax = val;
|
||
this.SpectrogramMaxBuff = [];
|
||
};
|
||
waterfallwidget.prototype.setShowPeakMarker = function (val) {
|
||
this.showPeakMarker = val;
|
||
if (this.showPeakMarker == false) {
|
||
var context = this.layer_info2.getContext();
|
||
context.clearRect(0, 0, this.layer_info2.getWidth(), this.layer_info2.getHeight());
|
||
//清除Make功能图像
|
||
var context2 = this.layer_info3.getContext();
|
||
context2.clearRect(0, 0, this.layer_info3.getWidth(), this.layer_info3.getHeight());
|
||
|
||
var context3 = this.layer_info4.getContext();
|
||
context3.clearRect(0, 0, this.layer_info4.getWidth(), this.layer_info4.getHeight());
|
||
|
||
var context = this.layer_info5.getContext();
|
||
context.clearRect(0, 0, this.layer_info5.getWidth(), this.layer_info5.getHeight());
|
||
|
||
//var context = this.layer_info6.getContext();
|
||
//context.clearRect(0, 0, this.layer_info6.getWidth(), this.layer_info6.getHeight())
|
||
|
||
//var context = this.layer_info7.getContext();
|
||
//context.clearRect(0, 0, this.layer_info7.getWidth(), this.layer_info7.getHeight())
|
||
this.MakeShow = [];
|
||
}
|
||
};
|
||
|
||
//JC添加多点标注功能 20210110
|
||
waterfallwidget.prototype.setShowMake = function (bins, val, index) {
|
||
var top = this.spectrogram_y;
|
||
var left = this.spectrogram_x;
|
||
var width = this.spectrogram_width;
|
||
var height = this.spectrogram_height;
|
||
if (this.MakeShow.length <= 0 || this.MakeShow == null) {
|
||
var context = val.getContext();
|
||
context.clearRect(0, 0, val.getWidth(), val.getHeight());
|
||
return;
|
||
}
|
||
if (this.MakeShow[index] > this.freq_start && this.MakeShow[index] < this.freq_end) {
|
||
var band = this.max_db - this.min_db;
|
||
var peakMarkIndex = Math.ceil(
|
||
(this.MakeShow[index] - this.freq_start) / ((this.freq_end - this.freq_start) / bins.length),
|
||
);
|
||
var markv = bins[peakMarkIndex];
|
||
var marky = top + height - ((markv - this.min_db) / band) * height;
|
||
var markx = left + width * (peakMarkIndex / bins.length);
|
||
var markfre = this.getFreqByPoint(markx);
|
||
var textfre = `${(markfre / 1000000).toFixed(3)} MHz`;
|
||
var context = val.getContext();
|
||
context.clearRect(0, 0, val.getWidth(), val.getHeight());
|
||
context.beginPath();
|
||
context.moveTo(markx - 3, marky - 15);
|
||
context.lineTo(markx + 3, marky - 15);
|
||
context.lineTo(markx, marky - 5);
|
||
context.fillStyle = '#ff0000';
|
||
context.fill();
|
||
|
||
context.strokeStyle = this.fore_color;
|
||
context.font = '13px serif';
|
||
context.strokeText(textfre, markx + 5, marky - 15);
|
||
context.strokeText(markv.toFixed(2) + ' dBm', markx + 5, marky - 1);
|
||
if (index == 0) {
|
||
this.MakeDb = markv.toFixed(2);
|
||
} else {
|
||
this.MakeDb1 = markv.toFixed(2);
|
||
}
|
||
} else {
|
||
var context = val.getContext();
|
||
context.clearRect(0, 0, val.getWidth(), val.getHeight());
|
||
}
|
||
};
|
||
|
||
//载波检测线
|
||
waterfallwidget.prototype.setCarryLineMode = function (val) {
|
||
console.log('setCarryLineMode:' + val);
|
||
this.CarryLineMode = val;
|
||
this.drawCarryLine();
|
||
};
|
||
waterfallwidget.prototype.setCarryLineList = function (val, fired = true) {
|
||
//console.log("setCarryLineList:" + val);
|
||
this.CarryLineList = val;
|
||
this.drawCarryLine();
|
||
if (fired) {
|
||
this.throttleFireCarryLineChange(val);
|
||
}
|
||
};
|
||
waterfallwidget.prototype.initCarryLine = function () {
|
||
//必须在init调用一次 否则resize会出问题
|
||
var layer = this.layer_carryline;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
this.throttleFireCarryLineChange = _.throttle((vals) => {
|
||
this.fire('carry-line-change', { list: vals });
|
||
}, 100);
|
||
|
||
var groupLine = new Konva.Group({
|
||
x: this.area_x,
|
||
y: 0,
|
||
name: 'line-g',
|
||
visible: false,
|
||
});
|
||
groupLine.add(
|
||
new Konva.Line({
|
||
points: [0, -10, this.area_width, 0],
|
||
stroke: 'transparent',
|
||
strokeWidth: 20,
|
||
lineCap: 'round',
|
||
lineJoin: 'round',
|
||
visible: true,
|
||
//dash:[10,4]
|
||
}),
|
||
);
|
||
groupLine.add(
|
||
new Konva.Line({
|
||
points: [0, 0, this.area_width, 0],
|
||
stroke: '#1d8cf8',
|
||
strokeWidth: 2,
|
||
lineCap: 'round',
|
||
lineJoin: 'round',
|
||
visible: true,
|
||
//dash: [10, 4]
|
||
}),
|
||
);
|
||
groupLine.add(
|
||
new Konva.Circle({
|
||
x: this.area_width,
|
||
y: 0,
|
||
fill: '#1d8cf8',
|
||
radius: 3,
|
||
}),
|
||
);
|
||
groupLine.add(
|
||
new Konva.Circle({
|
||
x: 0,
|
||
y: 0,
|
||
fill: '#1d8cf8',
|
||
radius: 3,
|
||
}),
|
||
);
|
||
|
||
groupLine.on('mousedown', (e) => {
|
||
console.log(e.evt.button);
|
||
if (e.evt.button != 0) {
|
||
return;
|
||
}
|
||
this.stage.on('mousemove', (e) => {
|
||
var ndb = this.getDbByPoint(e.evt.offsetY);
|
||
if (ndb < this.min_db) {
|
||
ndb = this.min_db;
|
||
}
|
||
if (ndb > this.max_db) {
|
||
ndb = this.max_db;
|
||
}
|
||
|
||
this.setCarryLineList([ndb]);
|
||
});
|
||
this.stage.on('mouseup', (e) => {
|
||
this.stage.off('mousemove');
|
||
this.stage.off('mouseup');
|
||
});
|
||
});
|
||
//增益区域鼠标移入鼠标图标变化
|
||
groupLine.on('mouseover', (e) => {
|
||
this.stage.container().style.cursor = 'row-resize';
|
||
});
|
||
groupLine.on('mouseout', (e) => {
|
||
this.stage.container().style.cursor = 'default';
|
||
});
|
||
|
||
layer.add(groupLine);
|
||
|
||
this.drawCarryLine();
|
||
};
|
||
waterfallwidget.prototype.clearCarryLine = function () {
|
||
var layer = this.layer_carryline;
|
||
var groupLine1 = layer.findOne('.carryline');
|
||
if (groupLine1) {
|
||
groupLine1.remove();
|
||
}
|
||
var nodes = layer.find('.carryline-node');
|
||
if (nodes) {
|
||
for (item of nodes) {
|
||
item.remove();
|
||
}
|
||
}
|
||
|
||
var groupLine = layer.findOne('.line-g');
|
||
if (groupLine) {
|
||
groupLine.visible(false);
|
||
}
|
||
|
||
layer.batchDraw();
|
||
};
|
||
waterfallwidget.prototype.drawCarryLine = function () {
|
||
if (this.CarryLineMode == 1) {
|
||
this.drawCarryLine1();
|
||
} else if (this.CarryLineMode == 2) {
|
||
this.drawCarryLine2();
|
||
} else {
|
||
this.clearCarryLine();
|
||
}
|
||
};
|
||
//折线
|
||
waterfallwidget.prototype.drawCarryLine1 = function () {
|
||
if (!this.CarryLineList) {
|
||
this.CarryLineList = [];
|
||
}
|
||
if (this.CarryLineList.length == 1) {
|
||
//代表是模式2的单值方式
|
||
this.CarryLineList = [];
|
||
}
|
||
var arr = [];
|
||
for (var i = 0; i < this.CarryLineList.length; i += 2) {
|
||
arr.push(this.getPointByFreq(this.CarryLineList[i]));
|
||
arr.push(this.getPointByDb(this.CarryLineList[i + 1]));
|
||
}
|
||
|
||
var layer = this.layer_carryline;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
|
||
var line = new Konva.Line({
|
||
points: arr,
|
||
stroke: '#1d8cf8',
|
||
strokeWidth: 2,
|
||
lineCap: 'round',
|
||
lineJoin: 'round',
|
||
name: 'carryline',
|
||
visible: true,
|
||
});
|
||
layer.add(line);
|
||
for (var i = 0; i < arr.length; i += 2) {
|
||
let circle = new Konva.Circle({
|
||
x: arr[i],
|
||
y: arr[i + 1],
|
||
fill: '#1d8cf8',
|
||
radius: 3,
|
||
name: 'carryline-node',
|
||
});
|
||
layer.add(circle);
|
||
}
|
||
layer.batchDraw();
|
||
};
|
||
//直线
|
||
waterfallwidget.prototype.drawCarryLine2 = function () {
|
||
if (!this.CarryLineList) {
|
||
this.CarryLineList = [-80];
|
||
}
|
||
if (this.CarryLineList.length != 1) {
|
||
this.CarryLineList = [-80];
|
||
}
|
||
|
||
var val = this.CarryLineList[0];
|
||
|
||
var layer = this.layer_carryline;
|
||
|
||
var groupLine = layer.findOne('.line-g');
|
||
|
||
//console.log("drawCarryLine2", val, groupLine);
|
||
|
||
groupLine.visible(true);
|
||
groupLine.y(this.getPointByDb(val));
|
||
|
||
layer.batchDraw();
|
||
};
|
||
|
||
//频率标注
|
||
waterfallwidget.prototype.drawFreqPointLableItem = function (item) {
|
||
if (!item) return;
|
||
var layer = this.layer_freqpointlable;
|
||
var textfre = `${(item.freq / 1000000).toFixed(6)} MHz`;
|
||
var id = item.id;
|
||
var color = item.txtColor;
|
||
var info = item.lableInfo;
|
||
var freq = item.freq;
|
||
var txt = item.lableType;
|
||
let _x = this.getPointByFreq(freq);
|
||
if (_x > this.area_x + this.area_width - 5) return;
|
||
_x = _x - 9;
|
||
let _y = this.waterfall_y - 30;
|
||
var fontSize = 18;
|
||
if (txt == '1') {
|
||
txt = '▼';
|
||
_y = _y - 2;
|
||
} else if (txt == '2') {
|
||
txt = '◎';
|
||
_y = _y - 5;
|
||
fontSize = 26;
|
||
} else if (txt == '3') {
|
||
txt = '◆';
|
||
_y = _y - 6;
|
||
fontSize = 30;
|
||
} else if (txt == '4') {
|
||
txt = '■';
|
||
_y = _y - 7;
|
||
fontSize = 24;
|
||
} else if (txt == '5') {
|
||
txt = '★';
|
||
_y = _y - 5;
|
||
fontSize = 22;
|
||
}
|
||
var abcRect = new Konva.Text({
|
||
x: _x,
|
||
y: _y,
|
||
fontSize: fontSize,
|
||
text: txt,
|
||
name: id,
|
||
align: 'center',
|
||
fontFamily: 'Calibri',
|
||
fill: color,
|
||
});
|
||
var _self = this;
|
||
abcRect.on('mousedown', function (e) {
|
||
var id = e.target.attrs.name;
|
||
console.log('mousedown', e.evt);
|
||
if (e.evt.button == 0) {
|
||
//左键编辑
|
||
_self.UpdateFreqPointLable(id);
|
||
} else if (e.evt.button == 2) {
|
||
console.log('id', e.target.attrs);
|
||
//右键删除
|
||
_self.RemoveFreqPointLable(id);
|
||
}
|
||
});
|
||
//增益区域鼠标移入鼠标图标变化
|
||
abcRect.on('mouseover', (e) => {
|
||
this.stage.container().style.cursor = 'pointer';
|
||
_self._showInfo(
|
||
{
|
||
x: e.evt.offsetX - 30,
|
||
y: e.evt.offsetY - 70,
|
||
textcolor: this.fore_color,
|
||
bgcolor: this.bg_color,
|
||
text: '频点:' + textfre + '\r\n' + '标注信息:' + info,
|
||
},
|
||
true,
|
||
);
|
||
});
|
||
abcRect.on('mouseout', (e) => {
|
||
this.stage.container().style.cursor = 'default';
|
||
_self.hideInfo();
|
||
});
|
||
layer.add(abcRect);
|
||
};
|
||
//新增频点标注
|
||
waterfallwidget.prototype.AddFreqPointLable = function (freq) {
|
||
this.fire('freqPointLable-add-click', { freq });
|
||
};
|
||
//修改频点标注
|
||
waterfallwidget.prototype.UpdateFreqPointLable = function (id) {
|
||
this.fire('freqPointLable-update-click', { id });
|
||
};
|
||
//删除频点标注
|
||
waterfallwidget.prototype.RemoveFreqPointLable = function (id) {
|
||
if (this.wfFreqPointLableArray.length == 0) return;
|
||
this.fire('freqPointLable-remove-click', { id });
|
||
this.drawFreqPointLables();
|
||
};
|
||
//绘制所有频点标注
|
||
waterfallwidget.prototype.drawFreqPointLables = function () {
|
||
if (this.wfFreqPointLable == false || !this.wfFreqPointLableArray) return;
|
||
var layer = this.layer_freqpointlable;
|
||
layer.removeChildren();
|
||
for (let i = 0; i < this.wfFreqPointLableArray.length; i++) {
|
||
let item = this.wfFreqPointLableArray[i];
|
||
this.drawFreqPointLableItem(item);
|
||
}
|
||
layer.batchDraw();
|
||
};
|
||
|
||
//初始化频点标注
|
||
waterfallwidget.prototype.InitFreqPointLables = function () {
|
||
if (this.wfFreqPointLable == false) return;
|
||
if (this.wfFreqPointLableList && this.wfFreqPointLableList.length > 0) {
|
||
this.wfFreqPointLableArray = this.wfFreqPointLableList;
|
||
this.drawFreqPointLables();
|
||
}
|
||
};
|
||
//重新设置频点标注数据
|
||
waterfallwidget.prototype.SetFreqPointLablesData = function (list) {
|
||
if (this.wfFreqPointLable == false) return;
|
||
//console.log("SetFreqPointLablesData",list);
|
||
if (list) {
|
||
this.wfFreqPointLableArray = list;
|
||
}
|
||
this.drawFreqPointLables();
|
||
};
|
||
//黑名单
|
||
waterfallwidget.prototype.drawWhiteList = async function () {
|
||
var _self = this;
|
||
if (this.showWhitelist) {
|
||
var layer = this.layer_white;
|
||
var opaLine = 0.3;
|
||
var opaNormal = 0.5;
|
||
var opaSelected = 0.9;
|
||
var rowStart = this.spectrogram_y + 1;
|
||
layer.destroyChildren();
|
||
layer.removeChildren();
|
||
var ret = await $.post('/setting/GetWhiteList');
|
||
for (var i = 0; i < ret.data.length; i++) {
|
||
var data = ret.data[i];
|
||
var text = data.name;
|
||
if (data.end <= _self.min_freq || data.start >= _self.max_freq) {
|
||
continue;
|
||
}
|
||
var bw = data.end - data.start;
|
||
var fc = data.start;
|
||
if (fc <= 0 || bw <= 0) {
|
||
continue;
|
||
}
|
||
var text = new Konva.Text({
|
||
x: 2,
|
||
y: 2,
|
||
text: text,
|
||
fontSize: 10,
|
||
fill: '#B3BAC5',
|
||
});
|
||
var rect = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: 'transparent',
|
||
width: text.width() > 0 ? text.width() + 4 : 0,
|
||
height: text.height() > 0 ? text.height() + 4 : 0,
|
||
cornerRadius: 0,
|
||
strokeWidth: 0,
|
||
name: 'rect',
|
||
});
|
||
var line = new Konva.Rect({
|
||
x: 0,
|
||
y: 0,
|
||
fill: '#f4f5f7',
|
||
width: _self.getWidthByBw(bw),
|
||
height: this.area_height,
|
||
cornerRadius: 0,
|
||
name: 'line',
|
||
opacity: opaLine,
|
||
});
|
||
|
||
var group = new Konva.Group({
|
||
x: _self.getPointByFreq(fc),
|
||
y: rowStart,
|
||
opacity: opaNormal,
|
||
});
|
||
group.add(line);
|
||
group.add(rect);
|
||
group.add(text);
|
||
layer.add(group);
|
||
}
|
||
layer.batchDraw();
|
||
}
|
||
};
|
||
|
||
waterfallwidget.prototype.init = function () {
|
||
if (!this.stage) return; //防止已经销毁但是仍然响应了大小变化事件
|
||
|
||
this.stage.setWidth(this.container.clientWidth);
|
||
this.stage.setHeight(this.container.clientHeight);
|
||
//确定位置和大小
|
||
this.area_x = this.margin_left;
|
||
this.area_y = this.margin_top;
|
||
this.area_width = this.stage.getWidth() - this.margin_left - this.margin_right - 2;
|
||
this.area_height = this.stage.getHeight() - this.margin_top - this.margin_bottom - 2;
|
||
this.spectrogram_y = this.margin_top;
|
||
this.spectrogram_x = this.margin_left + 1;
|
||
this.spectrogram_width = this.area_width;
|
||
this.spectrogram_height = Math.floor(this.area_height * this.spec_per) - 1; //分割线
|
||
this.waterfall_y = this.margin_top + this.spectrogram_height + 1;
|
||
this.waterfall_x = this.margin_left + 1;
|
||
this.waterfall_width = this.area_width;
|
||
this.waterfall_height = Math.floor(this.area_height * (1 - this.spec_per));
|
||
|
||
this.wf = document.createElement('canvas');
|
||
this.wf.height = this.waterfall_height;
|
||
this.wf.width = this.visual_MapLen;
|
||
this.ctx_wf = this.wf.getContext('2d');
|
||
this.ctx_wf.fillStyle = this.bg_color;
|
||
|
||
this.spec = document.createElement('canvas');
|
||
this.spec.height = this.spectrogram_height;
|
||
this.spec.width = this.visual_MapLen;
|
||
this.ctx_spec = this.spec.getContext('2d');
|
||
this.ctx_spec.fillStyle = this.bg_color;
|
||
this.ctx_spec.strokeStyle = this.wave_color;
|
||
this.ctx_spec.lineWidth = 1;
|
||
|
||
this.drawCoor();
|
||
|
||
this.setFreqZoom();
|
||
this.drawCoorFreq();
|
||
this.drawCoorFreqWheel();
|
||
|
||
this.drawBottomScroll();
|
||
|
||
this.drawMap();
|
||
|
||
this.drawRuler();
|
||
this.drawAdj();
|
||
//if (this.allowRunMode == 0) { this.drawAdj(); }
|
||
if (this.isUHF) {
|
||
this.drawGather();
|
||
this.drawGatherLocation();
|
||
}
|
||
this.split_draw();
|
||
this.darwLabel();
|
||
this.initCarryLine();
|
||
this.InitFreqPointLables(); //频点标注信息
|
||
this.drawWhiteList();
|
||
};
|
||
waterfallwidget.prototype.destroy = function () {
|
||
this._events = [];
|
||
this.container.oncontextmenu = null;
|
||
this.container = null;
|
||
this.stage.destroy();
|
||
this.stage = null;
|
||
this.color_map = null;
|
||
this.wf = null;
|
||
this.ctx_wf = null;
|
||
this.label_manager = null;
|
||
|
||
this.CompareCurLineBuff = [];
|
||
this.wfFreqPointLableArray = [];
|
||
this.layer_coor.destroy();
|
||
this.layer_coorFreq.destroy();
|
||
this.layer_coorFreqWeel.destroy();
|
||
this.layer_wf.destroy();
|
||
this.layer_map.destroy();
|
||
this.layer_mapRuler.destroy();
|
||
//20211228焦超 添加make功能
|
||
this.layer_info3.destroy();
|
||
this.layer_info4.destroy();
|
||
//this.layer_info6.destroy();
|
||
//this.layer_info5.destroy();
|
||
//this.layer_info6.destroy();
|
||
//this.layer_info7.destroy();
|
||
this.layer_adj.destroy();
|
||
this.layer_label.destroy();
|
||
this.layer_labelActive.destroy();
|
||
|
||
if (this.layer_split) {
|
||
this.layer_split.destroy(); //2021.05.07 西部需要拖动修改频谱图大小,李伟添加
|
||
}
|
||
this.layer_freqpointlable.destroy();
|
||
this.layer_instant.destroy();
|
||
this.layer_chanel.destroy();
|
||
this.layer_botscroll.destroy();
|
||
this.layer_cover.destroy();
|
||
this.layer_info.destroy();
|
||
this.layer_info2.destroy();
|
||
this.layer_white.destroy();
|
||
this.destroryContextMenu();
|
||
|
||
console.log('warterfall destory...............');
|
||
};
|
||
waterfallwidget.prototype.initResize = function () {
|
||
var _self = this;
|
||
$(this.container).resize(function () {
|
||
var target = this;
|
||
if (target.resizeFlag) {
|
||
clearTimeout(target.resizeFlag);
|
||
}
|
||
target.resizeFlag = setTimeout(function () {
|
||
_self.init();
|
||
target.resizeFlag = null;
|
||
}, 100);
|
||
});
|
||
};
|
||
|
||
function waterfallwidget(id, options) {
|
||
this.options = options;
|
||
this.SpectrogramBuff = [];
|
||
this.SpectrogramBuffCount = 10;
|
||
this.SpectrogramMinBuff = [];
|
||
this.SpectrogramMaxBuff = [];
|
||
this.CompareCurLineBuff = [];
|
||
this.wfFreqPointLableArray = []; //频点标注信息
|
||
this.MakeShow = []; //Make 存储用户选择的频点
|
||
this.MakeDb; //存储用户选择的频点的电平值
|
||
this.MakeDb1; //存储用户选择的频点的电平值
|
||
|
||
this.showScrollLocal = options && !options.showScrollLocal ? true : false;
|
||
|
||
this.showSpectrogramAvg =
|
||
options && (options.showSpectrogramAvg === false || options.showSpectrogramAvg === true)
|
||
? options.showSpectrogramAvg
|
||
: false;
|
||
this.showSpectrogramMin =
|
||
options && (options.showSpectrogramMin === false || options.showSpectrogramMin === true)
|
||
? options.showSpectrogramMin
|
||
: false;
|
||
this.showSpectrogramMax =
|
||
options && (options.showSpectrogramMax === false || options.showSpectrogramMax === true)
|
||
? options.showSpectrogramMax
|
||
: false;
|
||
this.showPeakMarker =
|
||
options && (options.showPeakMarker === false || options.showPeakMarker === true) ? options.showPeakMarker : false;
|
||
|
||
this._events = {};
|
||
var enentNames = [
|
||
'adj-change',
|
||
'pointer-change',
|
||
'band-change',
|
||
'pointer-type-change',
|
||
'zoom-change',
|
||
'label-change',
|
||
'context-click',
|
||
'context-ddc-click',
|
||
'gravity-ruler-change',
|
||
];
|
||
this.on = function (type, fn, scope) {
|
||
if (type + '' !== type) {
|
||
console && console.error && console.error('the first argument type is requird as string');
|
||
return this;
|
||
}
|
||
if (typeof fn != 'function') {
|
||
console && console.error && console.error('the second argument fn is requird as function');
|
||
return this;
|
||
}
|
||
type = type.toLowerCase();
|
||
|
||
if (!this._events[type]) {
|
||
this._events[type] = [];
|
||
}
|
||
this._events[type].push(scope ? [fn, scope] : [fn]);
|
||
|
||
return this;
|
||
};
|
||
this.fire = async function (type, data) {
|
||
type = type.toLowerCase();
|
||
var eventArr = this._events[type];
|
||
var fn,
|
||
scope,
|
||
event = Object.assign(
|
||
{
|
||
// 事件类型
|
||
type: type,
|
||
// 绑定的源
|
||
origin: this,
|
||
// scope 为 this 或用户指定的上下文,
|
||
// 是否取消
|
||
cancel: false,
|
||
},
|
||
data,
|
||
);
|
||
|
||
if (!eventArr) return event;
|
||
for (var i = 0, l = eventArr.length; i < l; ++i) {
|
||
fn = eventArr[i][0];
|
||
scope = eventArr[i][1];
|
||
if (scope) {
|
||
event.scope = scope;
|
||
fn.call(scope, event);
|
||
} else {
|
||
event.scope = this;
|
||
fn(event);
|
||
}
|
||
}
|
||
return event;
|
||
};
|
||
this.off = function (type, fn) {
|
||
type = type.toLowerCase();
|
||
var eventArr = this._events[type];
|
||
if (!eventArr || !eventArr.length) return this;
|
||
if (!fn) {
|
||
this._events[type] = eventArr = [];
|
||
} else {
|
||
for (var i = 0; i < eventArr.length; ++i) {
|
||
if (fn === eventArr[i][0]) {
|
||
eventArr.splice(i, 1);
|
||
// 1、找到后不能立即 break 可能存在一个事件一个函数绑定多次的情况
|
||
// 删除后数组改变,下一个仍然需要遍历处理!
|
||
--i;
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
this.one = function (type, fn, scope) {
|
||
var that = this;
|
||
|
||
function nfn() {
|
||
// 执行时 先取消绑定
|
||
that.off(type, nfn);
|
||
// 再执行函数
|
||
fn.apply(scope || that, arguments);
|
||
}
|
||
this.on(type, nfn, scope);
|
||
return this;
|
||
};
|
||
|
||
this.coorFreqType = options && options.coorFreqType ? options.coorFreqType : 0;
|
||
this.menuEnableHandle = options && options.menuEnableHandle ? options.menuEnableHandle : null;
|
||
this.menuDisableText = options && options.menuDisableText ? options.menuDisableText : '菜单禁止使用';
|
||
|
||
this.allowRunMode = options && options.allowRunMode != undefined ? options.allowRunMode : 0;
|
||
this.isADGather = options && options.isADGather != undefined ? options.isADGather : false; //是否开启AD采集
|
||
this.isHF = options && options.isHF != undefined ? options.isHF : false; //是否短波界面
|
||
this.isUHF = options && options.isUHF != undefined ? options.isUHF : false; //是否超短波界面
|
||
//this.allowCycleControl = (options && (options.allowCycleControl === false || options.allowCycleControl === true)) ? options.allowCycleControl : false;;//侦察控守
|
||
|
||
this.showCheckSignal = options && options.showCheckSignal != undefined ? options.showCheckSignal : false; //是否显示右键 识别选中信号
|
||
this.showHoppingDetect = options && options.showHoppingDetect != undefined ? options.showHoppingDetect : false; //是否显示超短 跳频检测
|
||
|
||
this.min_band = options && options.min_band ? options.min_band : 500;
|
||
this.max_band = options && options.max_band ? options.max_band : 200000;
|
||
|
||
//这是整体的频谱大小 hz
|
||
this.min_freq = options && options.min_freq ? options.min_freq : 0;
|
||
this.max_freq = options && options.max_freq ? options.max_freq : 40000;
|
||
|
||
//这是当前缩放尺度的大小
|
||
this.freq_start = 0;
|
||
this.freq_end = 0;
|
||
|
||
this.disableZoom = options && options.disableZoom ? options.disableZoom : false;
|
||
this.zoomOption = options && options.zoomOption ? options.zoomOption : 16;
|
||
this.zoomPer = (this.max_freq - this.min_freq) / this.zoomOption;
|
||
this.zoomQueue = [];
|
||
|
||
this.fucFFTBuff = options && options.fucFFTBuff ? options.fucFFTBuff : null;
|
||
this.unitBuffId = options && options.unitBuffId ? options.unitBuffId : 0;
|
||
this.fftModelId = options && options.fftModelId ? options.fftModelId : 0;
|
||
|
||
this.visual_MapLen = 2000;
|
||
// Handle options
|
||
this.min_db = options && options.min_db ? options.min_db : -200;
|
||
this.max_db = options && options.max_db ? options.max_db : 0;
|
||
this.db_counter = options && options.db_counter ? options.db_counter : 10;
|
||
this.onAutomaticAdjustment = options.onAutomaticAdjustment;
|
||
|
||
this.info_Position = options && options.info_Position ? options.info_Position : 0; //跟随鼠标 1:右上角
|
||
|
||
this.freq_zoom = options && options.freq_zoom ? options.freq_zoom : -1;
|
||
this.show_msFreq =
|
||
options && (options.show_msFreq === false || options.show_msFreq === true) ? options.show_msFreq : true;
|
||
|
||
this.showFreqLable =
|
||
options && (options.showFreqLable === false || options.showFreqLable === true) ? options.showFreqLable : true;
|
||
this.wfFreqPointLable =
|
||
options && (options.wfFreqPointLable === false || options.wfFreqPointLable === true)
|
||
? options.wfFreqPointLable
|
||
: false; //频点标注
|
||
this.wfFreqPointLableList = options && options.wfFreqPointLable === true ? options.wfFreqPointLableList : []; //频点标注数据
|
||
//this.adj_Pointer = (options && options.adj_Pointer) ? options.adj_Pointer : (this.max_freq - this.min_freq) / 2;
|
||
//this.adj_Type = (options && options.adj_Type) ? options.adj_Type : 'center';
|
||
//this.adj_Band = (options && options.adj_Band) ? options.adj_Band : 3600;
|
||
|
||
//余晖图
|
||
//this.enableAfterglow = (options && (options.enableAfterglow === false || options.enableAfterglow === true)) ? options.enableAfterglow : false;
|
||
this.delayAfterglow = options && options.delayAfterglow ? options.delayAfterglow : 0; //3秒
|
||
this.isBwFc = options && (options.isBwFc === false || options.isBwFc === true) ? options.show_msFreq : false;
|
||
if (options.adj_show === false) {
|
||
this.adj_show = false;
|
||
} else if (options.adj_show === true) {
|
||
this.adj_show = true;
|
||
} else {
|
||
this.adj_show = this.allowRunMode == 1 ? true : false;
|
||
}
|
||
this.gather_show = this.allowRunMode == 0 ? true : false;
|
||
this.split_show = true; //2021.05.07 西部需求拖动更改频谱窗口大小,李伟添加;
|
||
|
||
this.adj_defaultbw = 1;
|
||
this.adj_maxbw = options && options.adj_maxbw ? options.adj_maxbw : 90000000;
|
||
|
||
this.adj_lineWidth = this.allowRunMode == 0 ? 1 : 2; //4 : 2
|
||
if (this.adj_lineType == undefined) {
|
||
this.adj_lineType = 0;
|
||
}
|
||
|
||
this.adj_color = options && options.adj_color ? options.adj_color : this.allowRunMode == 0 ? '#6CE26C' : '#F37570';
|
||
this.adjcenter_color =
|
||
options && options.adjcenter_color ? options.adjcenter_color : this.allowRunMode == 0 ? '#007ACC' : '#007ACC';
|
||
|
||
this.adj_start = options.adj_start;
|
||
this.adj_end = options.adj_end;
|
||
|
||
if (!this.adj_start) {
|
||
this.adj_start = this.min_freq + (this.max_freq - this.min_freq) / 2;
|
||
}
|
||
if (!this.adj_end) {
|
||
this.adj_end = this.adj_start + this.adj_defaultbw;
|
||
}
|
||
this.gather_fc = 0;
|
||
this.gather_bw = 0;
|
||
this.adj_step = options && options.adj_step ? options.adj_step : 0;
|
||
|
||
this.wf_size = options && options.wf_size ? options.wf_size : 1000;
|
||
this.wf_rows = options && options.wf_rows ? options.wf_rows : 1024;
|
||
|
||
this.timeQueue = [];
|
||
this.timeIndex = 0;
|
||
this.time_span = 20; //每20像素画一个时间
|
||
//this.time_out = (options && options.time_out) ? options.time_out : 100; //代表一提供数据的时间单位是 ms 废弃
|
||
|
||
this.showCurLine = options && options.showCurLine ? options.showCurLine : false;
|
||
//对比谱线
|
||
this.showCompareCurLine = options && options.showCompareCurLine ? options.showCompareCurLine : false;
|
||
|
||
this.time_rate = options && options.time_rate ? options.time_rate : 1; //代表速度(暂未实现) 比如0-1
|
||
//this.bg_color = (options && options.bg_color) ? options.bg_color : '#27293D';
|
||
this.bg_color = options && options.bg_color ? options.bg_color : '#37384B';
|
||
this.fore_color = options && options.bg_color ? options.bg_color : '#CCCCFF';
|
||
this.wave_color = options && options.wave_color ? options.wave_color : '#4BF3A7'; //'#296FF5';
|
||
this.wave_color_avg = options && options.wave_color_avg ? options.wave_color_avg : '#FC6945';
|
||
this.wave_color_max = options && options.wave_color_max ? options.wave_color_max : '#ffff00'; //'#296FF5';//'#00BF9A';
|
||
this.wave_color_min = options && options.wave_color_min ? options.wave_color_min : '#fff';
|
||
this.wave_color_compare = options && options.wave_color_compare ? options.wave_color_compare : '#f5365c';
|
||
|
||
this.waveAfterglow_color = options && options.waveAfterglow_color ? options.waveAfterglow_color : '#BCF90A'; //'#296FF5';
|
||
|
||
this.instant_color = options && options.instant_color ? options.instant_color : '#f8ffed';
|
||
this.instant_show =
|
||
options && (options.instant_show === false || options.instant_show === true) ? options.instant_show : true;
|
||
|
||
this.chanel_color = options && options.chanel_color ? options.chanel_color : '#ffffff';
|
||
this.chanel_show =
|
||
options && (options.chanel_show === false || options.chanel_show === true) ? options.chanel_show : true;
|
||
|
||
this.spec_per = options && (options.spec_per === 0 || options.spec_per) ? options.spec_per : 0.5;
|
||
this.labelMode = options && (options.labelMode === false || options.labelMode === true) ? options.labelMode : true;
|
||
|
||
this.showWhitelist = options && options.showWhitelist ? options.showWhitelist : false;
|
||
|
||
this.label_manager =
|
||
options && options.label_manager
|
||
? options.label_manager
|
||
: {
|
||
labels: [
|
||
{
|
||
name: 'FM',
|
||
id: 'id1',
|
||
bg_color: '#2bffc6',
|
||
fore_color: '#000',
|
||
location: 80000000,
|
||
},
|
||
{
|
||
name: 'AM',
|
||
id: 'id2',
|
||
bg_color: '#2bffc6',
|
||
fore_color: '#000',
|
||
location: 90000000,
|
||
},
|
||
{
|
||
name: 'USB',
|
||
id: 'id3',
|
||
bg_color: '#fd5d93',
|
||
fore_color: '#fff',
|
||
location: 100000000,
|
||
},
|
||
{
|
||
name: 'FSK',
|
||
id: 'id4',
|
||
bg_color: '#ff8d72',
|
||
fore_color: '#fff',
|
||
location: 110000000,
|
||
},
|
||
{
|
||
name: 'QPSK',
|
||
id: 'id5',
|
||
bg_color: '#5603ad',
|
||
fore_color: '#fff',
|
||
location: 120000000,
|
||
},
|
||
{
|
||
name: '4FSK',
|
||
id: 'id6',
|
||
bg_color: '#5603ad',
|
||
fore_color: '#fff',
|
||
location: 130000000,
|
||
},
|
||
{
|
||
name: 'USB',
|
||
id: 'id7',
|
||
bg_color: '#fd5d93',
|
||
fore_color: '#fff',
|
||
location: 140000000,
|
||
},
|
||
{
|
||
name: '2FSK',
|
||
id: 'id8',
|
||
bg_color: '#ff8d72',
|
||
fore_color: '#fff',
|
||
location: 150000000,
|
||
},
|
||
{
|
||
name: 'LSB',
|
||
id: 'id8',
|
||
bg_color: '#ff8d72',
|
||
fore_color: '#fff',
|
||
location: 160000000,
|
||
},
|
||
{
|
||
name: 'QPSK',
|
||
id: 'id9',
|
||
bg_color: '#5603ad',
|
||
fore_color: '#fff',
|
||
location: 170000000,
|
||
},
|
||
],
|
||
onclick: function (e) {},
|
||
load: function (start, end) {
|
||
return this.labels.filter((x) => x.location <= end && x.location >= start);
|
||
},
|
||
onRemove: function (id) {
|
||
console.log('label delete' + id);
|
||
},
|
||
};
|
||
//this.label_manager = null;
|
||
this.currentLabel = null;
|
||
|
||
this.margin_top = 20;
|
||
if (this.labelMode) {
|
||
this.margin_top = 140;
|
||
}
|
||
this.margin_bottom = 5;
|
||
this.margin_left = 60;
|
||
this.margin_right = 80; // Increased right margin to move content left
|
||
|
||
if (!this.options) {
|
||
this.options = {};
|
||
}
|
||
if (!this.options.wfOption) {
|
||
this.options.wfOption = {
|
||
wfRulerEnable: true,
|
||
wfTheme: 'default',
|
||
wfRulerGravity: true,
|
||
wfRulerLocation: -100,
|
||
};
|
||
}
|
||
this.gravity_location = this.options.wfOption.wfRulerLocation;
|
||
this.showRuler = this.options.wfOption.wfRulerEnable;
|
||
//console.log(`option gravity location=${this.gravity_location} gravity_value = ${this.getGravityPerByLocation()}`)
|
||
this.color_map = new colormapwidget({
|
||
name: this.options.wfOption.wfTheme,
|
||
gravity: this.options.wfOption.wfRulerGravity,
|
||
gravity_value: this.getGravityPerByLocation(),
|
||
count: this.max_db - this.min_db,
|
||
mapCount: this.max_db - this.min_db,
|
||
});
|
||
|
||
this.container = document.getElementById(id);
|
||
//屏蔽右键菜单
|
||
this.container.oncontextmenu = function () {
|
||
return false;
|
||
};
|
||
|
||
this.throttleSetFreqZoomUp = _.throttle((start, end, record) => {
|
||
this.setFreqZoomUp(start, end, record);
|
||
}, 100);
|
||
|
||
this.stage = new Konva.Stage({
|
||
container: id, // id of container <div>
|
||
width: this.container.clientWidth || 500,
|
||
height: this.container.clientHeight || 500,
|
||
});
|
||
|
||
this.layer_coor = new Konva.Layer();
|
||
this.layer_coor.hitGraphEnabled(false);
|
||
this.layer_coorFreq = new Konva.Layer();
|
||
this.layer_coorFreq.hitGraphEnabled(false);
|
||
|
||
this.layer_coorFreqWeel = new Konva.Layer();
|
||
|
||
this.layer_wf = new Konva.Layer();
|
||
this.layer_wf.hitGraphEnabled(false);
|
||
this.layer_map = new Konva.Layer();
|
||
this.layer_mapRuler = new Konva.Layer();
|
||
//绿色,在侦察模型下 能右键选中的区域。
|
||
this.layer_adj = new Konva.Layer();
|
||
//this.layer_split = new Konva.Layer();//2021.05.07 西部需要拖动修改频谱图大小,李伟添加
|
||
|
||
this.layer_label = new Konva.Layer();
|
||
this.layer_labelActive = new Konva.Layer();
|
||
|
||
this.layer_info = new Konva.Layer();
|
||
this.layer_info.hitGraphEnabled(false);
|
||
|
||
this.layer_info2 = new Konva.Layer();
|
||
this.layer_info2.hitGraphEnabled(false);
|
||
|
||
this.layer_instant = new Konva.Layer();
|
||
this.layer_instant.hitGraphEnabled(false);
|
||
|
||
this.layer_chanel = new Konva.Layer();
|
||
this.layer_chanel.hitGraphEnabled(false);
|
||
|
||
this.layer_cover = new Konva.Layer();
|
||
this.layer_cover.hitGraphEnabled(false);
|
||
|
||
this.layer_carryline = new Konva.Layer();
|
||
//this.layer_carryline.hitGraphEnabled(false);
|
||
|
||
this.layer_botscroll = new Konva.Layer();
|
||
|
||
//多点标记功能
|
||
this.layer_info3 = new Konva.Layer();
|
||
this.layer_info3.hitGraphEnabled(false);
|
||
|
||
this.layer_info4 = new Konva.Layer();
|
||
this.layer_info4.hitGraphEnabled(false);
|
||
|
||
this.layer_info5 = new Konva.Layer();
|
||
this.layer_info5.hitGraphEnabled(false);
|
||
//该层是砖红色的,在超短波模式下代表当前通道真实带宽。
|
||
this.layer_gather = new Konva.Layer();
|
||
this.layer_gather.hitGraphEnabled(false);
|
||
|
||
//this.layer_info6 = new Konva.Layer();
|
||
//this.layer_info6.hitGraphEnabled(false);
|
||
|
||
//this.layer_info7 = new Konva.Layer();
|
||
//this.layer_info7.hitGraphEnabled(false);
|
||
//频点标记 频率尺 标记 三角形 圆形 菱形 dhj 20241215
|
||
this.layer_freqpointlable = new Konva.Layer();
|
||
this.layer_freqpointlable.hitGraphEnabled(true);
|
||
|
||
this.layer_white = new Konva.Layer();
|
||
this.layer_white.hitGraphEnabled(true);
|
||
|
||
this.stage.add(this.layer_coor);
|
||
this.stage.add(this.layer_wf);
|
||
this.stage.add(this.layer_coorFreq);
|
||
this.stage.add(this.layer_labelActive);
|
||
|
||
this.stage.add(this.layer_coorFreqWeel);
|
||
|
||
this.stage.add(this.layer_label);
|
||
|
||
this.stage.add(this.layer_map);
|
||
this.stage.add(this.layer_mapRuler);
|
||
|
||
this.stage.add(this.layer_adj);
|
||
this.stage.add(this.layer_gather);
|
||
this.stage.add(this.layer_white);
|
||
//this.stage.add(this.layer_split);//2021.05.07 西部需要拖动修改频谱图大小,李伟添加
|
||
this.stage.add(this.layer_instant);
|
||
this.stage.add(this.layer_chanel);
|
||
this.stage.add(this.layer_botscroll);
|
||
this.stage.add(this.layer_cover);
|
||
this.stage.add(this.layer_carryline);
|
||
this.stage.add(this.layer_info);
|
||
this.stage.add(this.layer_info2);
|
||
|
||
//JC添加make功能
|
||
this.stage.add(this.layer_info3);
|
||
this.stage.add(this.layer_info4);
|
||
this.stage.add(this.layer_info5);
|
||
//this.stage.add(this.layer_info6);
|
||
this.stage.add(this.layer_freqpointlable);
|
||
//this.stage.add(this.layer_info7);
|
||
this.initContextMenu();
|
||
// this.initLabelsMenu();
|
||
this.init();
|
||
|
||
this.initResize();
|
||
}
|