757 lines
28 KiB
JavaScript
757 lines
28 KiB
JavaScript
!(function (e, t) {
|
|
"object" == typeof exports && "undefined" != typeof module
|
|
? (module.exports = t(e))
|
|
: "function" == typeof define && define.amd
|
|
? define(t, e)
|
|
: ((e = "undefined" != typeof globalThis ? globalThis : e || self).lineChart =
|
|
t(e));
|
|
})(this, function (scope) {
|
|
if (!scope.settings) {
|
|
scope.require("/settings.js");
|
|
};
|
|
|
|
const jiaozhun=settings.jiaozhun;
|
|
function DataExtract() {
|
|
let _ctx = this.$ctx = {
|
|
paused: false,
|
|
sourceMin: 0,
|
|
sourceMax: 1920,
|
|
currentMin: 0,
|
|
currentMax: 1920,
|
|
clientPixel: 1920,
|
|
pixelScale: 1,
|
|
displayPoints: [],
|
|
}
|
|
}
|
|
// const SampleFreqs = [78125, 156250, 312500, 625000, 1250000, 2500000, 5000000, 10000000, 20000000, 40000000, 80000000];
|
|
//const SampleFreqs = [240000, 480000, 960000, 1920000, 3840000, 7680000, 15360000, 30720000, 61440000];
|
|
const SampleFreqs = 61440000;//固定带宽 采样率
|
|
const fixedSourceSpan = 30000000;
|
|
DataExtract.prototype.update = function (options) {
|
|
let _ctx = this.$ctx;
|
|
if (vm.WorkParamsMode == 1) {//切换到扫频工作模式后
|
|
return false;
|
|
}
|
|
|
|
if (options.hasOwnProperty("paused")) _ctx.paused = options.paused;
|
|
if (options.hasOwnProperty("sourceMin")) _ctx.sourceMin = options.sourceMin;
|
|
if (options.hasOwnProperty("sourceMax")) _ctx.sourceMax = options.sourceMax;
|
|
if (options.hasOwnProperty("currentMin")) _ctx.currentMin = options.currentMin;
|
|
if (options.hasOwnProperty("currentMax")) _ctx.currentMax = options.currentMax;
|
|
if (options.hasOwnProperty("clientPixel")) _ctx.clientPixel = options.clientPixel;
|
|
if (options.hasOwnProperty("displayPoints")) _ctx.displayPoints = options.displayPoints;
|
|
}
|
|
|
|
DataExtract.prototype.take = function (current, data, cache) {
|
|
// if (this.$ctx.paused) return [];
|
|
// let { sourceMin, sourceMax, currentMin, currentMax, clientPixel, displayPoints } = this.$ctx;
|
|
|
|
// if (data) {
|
|
// // 源点
|
|
// var points = displayPoints;
|
|
// var targetMinHz = currentMin;
|
|
// // 图表带宽范围
|
|
// var scaleMinHz = currentMin;
|
|
// var scaleMaxHz = currentMax;
|
|
// var scaleSpanHz = scaleMaxHz - scaleMinHz;
|
|
// // 多少Hz一个像素
|
|
// var pixelScale = scaleSpanHz / clientPixel;
|
|
|
|
// var markerPosHz = current;
|
|
// // 当前频点 据 开始频点 多少hz
|
|
// var markerSpanHz = markerPosHz - targetMinHz;
|
|
// // 跳过按照前面的频率跳过相应的点
|
|
// var markerPixel = Math.ceil(markerSpanHz / pixelScale);
|
|
// return points[markerPixel];
|
|
// }
|
|
}
|
|
/*
|
|
// 按照真实点的数值获取
|
|
// data = new Uint16Array(data.buffer);//Array.from(,x=>x/256);
|
|
var sourceSpan = sourceMax - sourceMin;
|
|
var sampleFreq = SampleFreqs.find(item=>item > sourceSpan);
|
|
if(sampleFreq === void(0))sampleFreq = SampleFreqs.slice(-1)[0];
|
|
var offset = Math.floor( ( sampleFreq - sourceSpan ) / ( sampleFreq / data.length ) / 2 );
|
|
data = data.slice(offset,data.length - offset );
|
|
var displaySpan = currentMax - currentMin;
|
|
// 源点偏移
|
|
// 算算前面多少频率
|
|
let currentSpan = current - sourceMin;
|
|
// 多少频率一个点
|
|
var pointScale = sourceSpan / data.length ;
|
|
var pixelScale = clientPixel / displaySpan;
|
|
// 跳过按照前面的频率跳过相应的点
|
|
var pointOffset = Math.ceil(currentSpan / pointScale);
|
|
return data[pointOffset];
|
|
*/
|
|
DataExtract.prototype.fill = function (data) {
|
|
if (this.$ctx.paused) return [];
|
|
let { sourceMin, sourceMax, currentMin, currentMax, clientPixel, displayPoints } = this.$ctx;
|
|
|
|
if (vm.datatype == 3) {
|
|
if (displayPoints.length != clientPixel) {
|
|
this.$ctx.displayPoints.length = clientPixel;
|
|
}
|
|
displayPoints.fill(NaN);//清空数据
|
|
if (data) {
|
|
if (currentMin < 0 && currentMax < 0) {
|
|
return [];
|
|
};
|
|
// data = new Uint16Array(data.buffer);//Array.from(,x=>x/256);
|
|
// var sourceSpan = sourceMax - sourceMin;
|
|
var sourceSpan = fixedSourceSpan;
|
|
//此处无需匹配
|
|
var sampleFreq = SampleFreqs;
|
|
// var sampleFreq = SampleFreqs.find(item => item > sourceSpan);
|
|
// if (sampleFreq === void (0)) sampleFreq = SampleFreqs.slice(-1)[0]
|
|
var offset = Math.floor((sampleFreq - sourceSpan) / (sampleFreq / data.length) / 2);
|
|
//采样频率-带宽=需要去除的两端的频谱
|
|
//采样率/fft点数=每个点需要的频率数
|
|
//两者相除得出需要去掉的总点数
|
|
//总点数/2=单侧需要去掉的点数也就是offset
|
|
data = data.slice(offset, data.length - offset);//取出偏移量后的数据
|
|
// 源点
|
|
var points = displayPoints;
|
|
|
|
// 源数据范围
|
|
var sourceMinHz = sourceMin;//图表显示的
|
|
var sourceSpanHz = sourceSpan;//图表显示的
|
|
var targetMinHz = currentMin;//输入框中的最小
|
|
var targetMaxHz = currentMax;//输入框中的最大值
|
|
var targetSpanHz = targetMaxHz - targetMinHz;
|
|
|
|
// 图表带宽范围
|
|
var scaleMinHz = currentMin;
|
|
var scaleMaxHz = currentMax;
|
|
var scaleSpanHz = scaleMaxHz - scaleMinHz;
|
|
// 如果 x 轴最大值 小于 源最大值 按照 x 轴的最大值算
|
|
if (scaleMaxHz < targetMaxHz) {
|
|
targetMaxHz = scaleMaxHz;
|
|
}
|
|
// 如果 x 轴最小值 大于 源最小值 按 x 轴的最小值算
|
|
if (scaleMinHz > targetMinHz) {
|
|
targetMinHz = scaleMinHz;
|
|
}
|
|
targetSpanHz = targetMaxHz - targetMinHz;
|
|
var pointScale = sourceSpanHz / data.length; // 多少Hz一个点
|
|
var pixelScale = this.$ctx.pixelScale = scaleSpanHz / clientPixel; // 多少Hz一个像素
|
|
var offsetHz = (sourceMinHz - scaleMinHz); // 左边隐藏了多少Hz
|
|
var offsetPixel = 0; // 向左偏移多少像素
|
|
let offsetPoint = 0; // 向右偏移了多少点
|
|
// 如果左边有隐藏的频率
|
|
if (offsetHz > 0) {
|
|
offsetPixel = Math.abs(Math.ceil(offsetHz / pixelScale));// 垫上一定的像素
|
|
|
|
|
|
} else {
|
|
offsetPoint = Math.abs(Math.round(Math.abs(offsetHz) / pointScale));// 刨除出一定的点
|
|
}
|
|
if (offsetPixel > 0) {
|
|
points.fill(NaN, 0, offsetPixel);
|
|
}
|
|
if (offsetPoint > 0) {
|
|
data = data.slice(offsetPoint);
|
|
}
|
|
var i = 0;
|
|
// 当前FFT点数
|
|
var pointPixel = targetSpanHz / pixelScale;
|
|
var targetCount = targetSpanHz / pointScale;
|
|
var array = [];
|
|
if (targetCount > points.length) {//抽帧
|
|
var start = 0;
|
|
for (i = offsetPixel; i < clientPixel; i++) {
|
|
var _offset = i - offsetPixel;
|
|
var _temp = (_offset) * pixelScale;
|
|
let end = Math.ceil(_temp / pointScale);
|
|
var partial = data.slice(start, end);
|
|
start = end;
|
|
if (partial.length > 0) {
|
|
var val = NaN;
|
|
try {
|
|
val = Math.max(...partial);//数组解构 取出最大值
|
|
} catch (e) {
|
|
console.warn(e);
|
|
}
|
|
points[i] = val;
|
|
} else {
|
|
points[i] = NaN;
|
|
|
|
}
|
|
}
|
|
} else {
|
|
// 补帧
|
|
for (i = 0; i < clientPixel - offsetPixel; i++) {
|
|
let dataIndex = Math.ceil(i * pixelScale / pointScale);
|
|
var val = data[dataIndex];
|
|
if (val == -Infinity || isNaN(val) || val === undefined) {
|
|
break;
|
|
} else {
|
|
points[offsetPixel + i] = val;
|
|
}
|
|
}
|
|
//补帧
|
|
}
|
|
return points;
|
|
}
|
|
}
|
|
else if (vm.datatype == 5) {
|
|
if (displayPoints.length != clientPixel) {
|
|
this.$ctx.displayPoints.length = clientPixel;
|
|
}
|
|
displayPoints.fill(NaN);//清空数据
|
|
var points;
|
|
if (data) {
|
|
displayPoints = [...data];
|
|
points = displayPoints;
|
|
}
|
|
return points;
|
|
}
|
|
}
|
|
let {
|
|
AutoCursorModes,
|
|
AxisTickStrategies,
|
|
lightningChart,
|
|
emptyLine,
|
|
emptyFill,
|
|
emptyTick,
|
|
UIDirections,
|
|
UIElementBuilders,
|
|
MarkerBuilders,
|
|
transparentFill,
|
|
UIVisibilityModes,
|
|
ColorRGBA,
|
|
ColorHEX,
|
|
UIButtonPictures,
|
|
ColorHSV,
|
|
UIDraggingModes,
|
|
UILayoutBuilders,
|
|
UIBackgrounds,
|
|
SolidFill,
|
|
SolidLine,
|
|
LegendBoxBuilders,
|
|
translatePoint,
|
|
PointMarkers,
|
|
MouseStyles,
|
|
UIOrigins,
|
|
synchronizeAxisIntervals,
|
|
PalettedFill,
|
|
LUT,
|
|
} = lcjs;
|
|
const Marker = (function () {
|
|
let MarkerXYBuilder = MarkerBuilders.XY.setPointMarker(UIBackgrounds.Diamond).setResultTableBackground(UIBackgrounds.Pointer)
|
|
.addStyler(marker => {
|
|
marker.setPointMarker(point => point.setSize({ x: 10, y: 10 })
|
|
.setFillStyle(new SolidFill({ color: ColorHEX("#F00") }))
|
|
.setFillStyleHighlight(new SolidFill({ color: ColorHEX("#F00") }))
|
|
.setHighlighted(false)
|
|
)
|
|
.setGridStrokeXCut(true)
|
|
.setGridStrokeYCut(false)
|
|
.setResultTable(table => {
|
|
return table.setOrigin(UIOrigins.CenterBottom).setMargin({ bottom: 5 })
|
|
.setBackground(bg => bg.setDirection(UIDirections.Down).setPointerAngle(80).setPointerLength(10))//.setFillStyle(emptyFill).setStrokeStyle(emptyLine))
|
|
});
|
|
let TickStyle = tick => {
|
|
return tick.setTextFillStyle(new SolidFill({ color: ColorHEX('#FFF') })).setTextFont(fontSettings => fontSettings.setSize(10))
|
|
}
|
|
let StrokeStyle = new SolidLine({ thickness: .5, fillStyle: new SolidFill({ color: ColorHEX('#FFF') }) });
|
|
marker
|
|
.setTickMarkerX(TickStyle).setTickMarkerY(TickStyle)
|
|
.setGridStrokeXStyle(StrokeStyle).setGridStrokeYStyle(StrokeStyle);
|
|
return marker;
|
|
});
|
|
function Marker(line, opts) {
|
|
let { name, label, color, } = opts;
|
|
this.name = name;
|
|
this.$opts = opts;
|
|
this.$line = line;
|
|
this.$chart = this.$line.$chart;
|
|
|
|
var { start, end } = this.$chart.DisplayAxisX.getInterval();
|
|
var interval = this.$chart.DefaultAxisY.getInterval();
|
|
var position = { x: start + (end - start) / 2, y: interval.end - Math.abs(interval.end - interval.start) / 2 };
|
|
|
|
const target = this.target = this.$chart.target.addChartMarkerXY(MarkerXYBuilder, this.$chart.DisplayAxisX, this.$chart.DefaultAxisY).setPosition(position)
|
|
target.getResultTable().setContent([[label]]);
|
|
target.$owner = this;
|
|
target.setPointMarker(point => point.setFillStyle(new SolidFill({ color: ColorHEX(opts.color) })));
|
|
target.setGridStrokeXVisibility(UIVisibilityModes.never)
|
|
.setGridStrokeYVisibility(UIVisibilityModes.never)
|
|
.setTickMarkerXVisibility(UIVisibilityModes.always)
|
|
.setTickMarkerYVisibility(UIVisibilityModes.never);
|
|
}
|
|
Marker.prototype.update = function (data, cache) {
|
|
var original = this.target.getPosition();
|
|
var value = this.$chart.TakeData(original.x, data, cache);
|
|
if (value) {
|
|
original.y = value;
|
|
}
|
|
this.target.setPosition(original);
|
|
}
|
|
return Marker;
|
|
})();
|
|
const Line = (function () {
|
|
function Line(opts, chart) {
|
|
let { name, label, color } = opts;
|
|
let target = chart.target.addLineSeries({ allowDataGrouping: true }).setName(label);
|
|
target.setStrokeStyle(stroke => {
|
|
return stroke.setThickness(2).setFillStyle(new SolidFill({ color: ColorHEX(color) }))
|
|
});
|
|
this.name = name;
|
|
this.$opts = opts;
|
|
this.$markers = [];
|
|
this.$chart = chart;
|
|
this.target = target;
|
|
this.$data = [];
|
|
}
|
|
Line.prototype.update = function (data) {
|
|
this.target.clear();
|
|
this.target.addArrayY(data);
|
|
this.$data = data;
|
|
var extract = this.$chart.DataExtract;
|
|
let { clientPixel, currentMin, pixelScale } = extract.$ctx;
|
|
this.$markers.forEach(marker => {
|
|
var original = marker.target.getPosition();
|
|
// 当前频点 据 开始频点 多少hz
|
|
var spanHz = original.x - currentMin;
|
|
// 跳过按照前面的频率跳过相应的点
|
|
var index = Math.ceil(spanHz / pixelScale);
|
|
var value = data[index];
|
|
if (value != undefined && !isNaN(value)) {
|
|
original.y = value;
|
|
marker.target.setPosition(original);
|
|
}
|
|
})
|
|
}
|
|
Line.prototype.AddMarker = function (opts) {
|
|
var marker = new Marker(this, opts)
|
|
this.$markers.push(marker);
|
|
return marker;
|
|
};
|
|
Line.prototype.AddRelatedMarkers = function (...arr) {
|
|
return arr.map(opts => {
|
|
return this.AddMarker(opts);
|
|
})
|
|
};
|
|
return Line;
|
|
})();
|
|
UIElementBuilders.CheckBox = UIElementBuilders.CheckBox
|
|
.setPictureOff(UIButtonPictures.Rectangle)
|
|
.setPictureOn(UIButtonPictures.Rectangle)
|
|
.addStyler((checkBox) => checkBox.setOn(false).setPadding(5));
|
|
const MarkerBuilder = MarkerBuilders.XY
|
|
.setPointMarker(UIBackgrounds.Diamond)
|
|
.setResultTableBackground(UIBackgrounds.Diamond)
|
|
.addStyler(marker =>
|
|
marker.setPointMarker(point => point.setSize({ x: 10, y: 10 }))
|
|
.setResultTable(table => table.setOrigin(UIOrigins.CenterBottom).setMargin({ bottom: 0 }).setBackground(arrow => arrow.setDirection(UIDirections.Down)))
|
|
.setGridStrokeXCut(true).setAutoFitStrategy(undefined)
|
|
)
|
|
//#region 折线图
|
|
function LineChart(opts) {
|
|
opts = opts || {};
|
|
let { container } = opts;
|
|
let _Context = {
|
|
Divide: 1,
|
|
Lines: {},
|
|
Cache: [],
|
|
Data: [],
|
|
dataExtractSwitch: false,//数据抽取开关
|
|
workmode: null,//工作模式
|
|
strictInterval: null,//设置输入的起始范围
|
|
xAxisBand: null,
|
|
};
|
|
let _expose = {};
|
|
let _Methods = {};
|
|
var _DataExtract = _expose.DataExtract = new DataExtract();
|
|
// Initialize _Chart.
|
|
let _Chart = lightningChart({
|
|
// 0 左键 1 中间 2 右键
|
|
// overrideInteractionMouseButtons: {
|
|
// axisXYZoomMouseButton: 2, // 框选放大
|
|
// chartXYPanMouseButton: 2, // 按住移动
|
|
// chartXYRectangleZoomFitMouseButton: 0, // 按住框选
|
|
// axisXYPanMouseButton: 0, // 拖动XY轴
|
|
// },
|
|
}).ChartXY({ container });
|
|
_Chart
|
|
.setTitle(false)
|
|
.disableAnimations()
|
|
//.setAutoCursorMode(AutoCursorModes.onHover).setSeriesBackgroundFillStyle(emptyFill)
|
|
.setPadding({ left: 0, top: 0, right: 5, bottom: 5 });
|
|
_Chart.setMouseInteractionPan(false);
|
|
_Chart.setMouseInteractionWheelZoom(false);
|
|
_Chart.setMouseInteractionRectangleZoom(false);
|
|
_Chart.setMouseInteractionRectangleFit(false);
|
|
_Chart.setZoomingRectangleFillStyle(new SolidFill({ color: ColorRGBA( 0, 255, 10,100 ) }));
|
|
let _DefaultAxisX = _Chart.getDefaultAxisX();
|
|
let _DefaultAxisY = _Chart.getDefaultAxisY();
|
|
let _DisplayAxisX = _Chart.addAxisX({ type: "linear-highPrecision" }).setInterval(0, 0, false, true);
|
|
|
|
|
|
|
|
_Chart.onSeriesBackgroundSelect && _Chart.onSeriesBackgroundSelect(function () {
|
|
console.log("select", arguments);
|
|
});
|
|
const _DefaultAxes = { x: _DefaultAxisX, y: _DefaultAxisY };
|
|
const _DisplayAxes = { x: _DisplayAxisX, y: _DefaultAxisY };
|
|
Object.assign(_expose, { target: _Chart });
|
|
Object.assign(_Methods, {
|
|
AddLine(opts) {
|
|
let { name } = opts;
|
|
var line = new Line(opts, _expose);
|
|
_Context.Lines[name] = (line);
|
|
return line;
|
|
},
|
|
AddCheckBoxGroup(items, handle) {
|
|
const group = _Chart.addUIElement(UILayoutBuilders.Row.setBackground(UIBackgrounds.Rectangle))
|
|
.setDraggingMode(UIDraggingModes.notDraggable).setOrigin(UIOrigins.RightTop)
|
|
.setPosition({ x: 99, y: 99 }).setBackground(bg => bg.setStrokeStyle(emptyLine).setFillStyle(emptyFill));
|
|
items.forEach(opts => {
|
|
let { name, label, color } = opts;
|
|
var checkbox = group.addElement(UIElementBuilders.CheckBox).setText(label);
|
|
checkbox.onSwitch(handle);
|
|
});
|
|
return group;
|
|
},
|
|
AddLegendBox(handle, events = false) {
|
|
const group = _Chart.addUIElement(UILayoutBuilders.Row.setBackground(UIBackgrounds.Rectangle))
|
|
.setDraggingMode(UIDraggingModes.notDraggable).setOrigin(UIOrigins.RightTop)
|
|
.setPosition({ x: 99, y: 99 }).setBackground(bg => bg.setStrokeStyle(emptyLine)); //.setFillStyle(emptyFill)
|
|
Object.entries(_Context.Lines).forEach(([name, line], index) => {
|
|
var line = _Context.Lines[name];
|
|
var checkbox = group.addElement(UIElementBuilders.CheckBox).setText(line.target.getName());
|
|
checkbox.setOn(!line.target.isDisposed());
|
|
if (index == 0) {
|
|
checkbox.setMouseInteractions(false);
|
|
} else {
|
|
checkbox.setMouseInteractions(events);
|
|
}
|
|
checkbox.onSwitch((target, state) => {
|
|
if (handle && handle(checkbox, line)) {
|
|
return;
|
|
}
|
|
if (state) {
|
|
line.target.restore();
|
|
} else {
|
|
line.target.dispose();
|
|
}
|
|
});
|
|
});
|
|
|
|
return group;
|
|
}
|
|
})
|
|
Object.assign(_Methods, {
|
|
Divide(value) {
|
|
if (value != undefined) _Context.Divide = value;
|
|
return _Context.Divide;
|
|
},
|
|
DataSwitch(value) {
|
|
if (value != undefined) _Context.dataExtractSwitch = value;
|
|
return _Context.dataExtractSwitch;
|
|
},
|
|
AddData(name, data) {
|
|
var _Line = _Context.Lines[name];
|
|
if (_Line) { _Line.Data = data; }
|
|
},
|
|
WorkParamsMode(value) {//设置工作模式
|
|
if (value != undefined) _Context.workmode = value;
|
|
return _Context.workmode;
|
|
},
|
|
strictInterval(value) {//设置输入的起始截止范围
|
|
if (value != undefined) _Context.strictInterval = value;
|
|
return _Context.strictInterval;
|
|
},
|
|
addNarrowBand(value,_mode) {
|
|
if (_Context.xAxisBand != undefined && _Context.xAxisBand != null) {
|
|
_Context.xAxisBand.dispose();
|
|
}
|
|
if (value != undefined&&_mode==0 ) {
|
|
_Context.xAxisBand = _DisplayAxisX.addBand();
|
|
_Context.xAxisBand.setValueStart(value.start)
|
|
.setValueEnd(value.end)
|
|
.setName('窄带')
|
|
.setStrokeStyleHighlight(new SolidLine({ thickness: 2, fillStyle: new SolidFill({ color: ColorHEX('#F00') }) }))
|
|
}
|
|
},
|
|
addBand(value) {
|
|
const colorDefault = ColorRGBA(1, 220, 1);
|
|
const colorNormal = colorDefault;
|
|
const colorHighlight = ColorRGBA(1, 220, 1);
|
|
const xPalette = new PalettedFill({
|
|
lookUpProperty: 'x',
|
|
lut: new LUT({
|
|
interpolate: false,
|
|
steps: [
|
|
{ value: 0, color: colorNormal },
|
|
{ value: value.start, color: colorHighlight },
|
|
{ value: value.end, color: colorNormal },
|
|
],
|
|
}),
|
|
})
|
|
_DisplayAxisX.setStrokeStyle((stroke) => stroke.setFillStyle(xPalette))
|
|
|
|
}
|
|
});
|
|
Object.assign(_Methods, {
|
|
SetRangeX(start, end) {
|
|
_DisplayAxisX.setInterval(start, end, false, true,);
|
|
// _DataExtract.update({ sourceMin: sourceMin, sourceMax: sourceMax, currentMin: start, currentMax: end });
|
|
},
|
|
SetRangeY(start, end) {
|
|
_DefaultAxisY.setInterval(end, start, false, true);
|
|
}
|
|
});
|
|
//#region 设置 展示X轴
|
|
const _DisplayAxisXScaleChange = (initial) => {
|
|
let { start, end } = _DisplayAxisX.getInterval();
|
|
// _DisplayAxisX.setMouseInteractions(false);
|
|
// _DisplayAxisX.setChartInteractionZoomByWheel(false);
|
|
// _DisplayAxisX.setInterval(1000,2000);
|
|
requestAnimationFrame(() => {
|
|
if (_Context.strictInterval != null) {
|
|
if (start < _Context.strictInterval.start) {
|
|
_DisplayAxisX.setChartInteractionZoomByWheel(false);
|
|
start = _Context.strictInterval.start;
|
|
_DisplayAxisX.setInterval(start, end);
|
|
};
|
|
if (end > _Context.strictInterval.end) {
|
|
_DisplayAxisX.setChartInteractionZoomByWheel(false);
|
|
end = _Context.strictInterval.end;
|
|
_DisplayAxisX.setInterval(start, end);
|
|
};
|
|
}
|
|
_DataExtract.update({ currentMin: start, currentMax: end });
|
|
_DisplayAxisX.setChartInteractionZoomByWheel(true);
|
|
if (_Context.dataExtractSwitch && _Context.workmode == 1) {
|
|
vm.setFFTPixEtracteParamForExtract();//设置扫频的抽取的截止频率
|
|
}
|
|
});
|
|
};
|
|
|
|
//#region 设置 展示X轴
|
|
const _DisplayAxisYScaleChange = (initial) => {
|
|
let { start, end } = _DefaultAxisY.getInterval();
|
|
requestAnimationFrame(() => {
|
|
if (start < -170) {
|
|
_DefaultAxisY.setChartInteractionZoomByWheel(false);
|
|
_DefaultAxisY.setInterval(-170, end,false, true);
|
|
};
|
|
if (end > 20) {
|
|
_DefaultAxisY.setChartInteractionZoomByWheel(false);
|
|
_DefaultAxisY.setInterval(start, 20,false, true);
|
|
};
|
|
_DefaultAxisY.setChartInteractionZoomByWheel(true);
|
|
});
|
|
};
|
|
|
|
|
|
_DisplayAxisX.onAxisInteractionAreaMouseDoubleClick(function (e) {
|
|
// e.setInterval(...e.range(), false, true);
|
|
});
|
|
_DisplayAxisX.onScaleChange(_DisplayAxisXScaleChange);
|
|
_DefaultAxisY.onScaleChange(_DisplayAxisYScaleChange);
|
|
_DisplayAxisX.setAnimationScroll(false);
|
|
//#endregion
|
|
var _ClientToDefault = function ({ x, y }) {
|
|
return _Chart.engine.clientLocation2Engine(x, y);
|
|
};
|
|
var _Default2Display = function ({ x, y }, scale) {
|
|
if (!scale) scale = _Chart.pixelScale;
|
|
return translatePoint({ x, y }, scale, _DisplayAxes);
|
|
};
|
|
var _Display2Default = function ({ x, y }, scale) {
|
|
if (!scale) scale = _Chart.pixelScale;// _DefaultAxes;//
|
|
return translatePoint({ x, y }, _DisplayAxes, scale);
|
|
};
|
|
var _Client2Display = function ({ x, y }) {
|
|
var enginePoint = _Chart.engine.clientLocation2Engine(x, y);
|
|
return translatePoint(enginePoint, _Chart.pixelScale, _DisplayAxes);
|
|
};
|
|
Object.assign(_Methods, {
|
|
TakeData(freq, data, cache,) {
|
|
return _DataExtract.take(freq, data, cache);
|
|
},
|
|
Client2Default: _ClientToDefault,
|
|
Default2Display: _Default2Display,
|
|
Client2Display: _Client2Display,
|
|
Display2Default: _Display2Default
|
|
});
|
|
//#region 设置 默认Y轴
|
|
_DefaultAxisY
|
|
.setTickStrategy(AxisTickStrategies.Numeric, (strategy) =>
|
|
strategy
|
|
.setCursorFormatter((value) => value.toFixed(3))
|
|
.setMajorTickStyle((style) => strategy.getMinorTickStyle())
|
|
);
|
|
// .setThickness(DefaultAxisYThickness);
|
|
//#endregion
|
|
//#region 添加 UI 组件
|
|
//#region 按刷新率渲染
|
|
let _Render = () => {
|
|
let ctx = { last: performance.now(), offset: 0, period: 50 };
|
|
function rAF() {
|
|
let now = performance.now();
|
|
let span = now - ctx.last;
|
|
if (span > ctx.period) {
|
|
ctx.offset = span % ctx.period;
|
|
ctx.last = now - ctx.offset;
|
|
Object.keys(_Context.Lines).forEach(name => {
|
|
let line = _Context.Lines[name];
|
|
let data = line.Data;
|
|
// delete line.Data;
|
|
|
|
if (data) {
|
|
data = _DataExtract.fill(data);
|
|
if (_Context.Divide !== 1) {
|
|
for (var i = 0; i < data.length; i++) {
|
|
// data[i] = data[i] / _Context.Divide; 数据需要校准-150
|
|
data[i] = data[i] / _Context.Divide - jiaozhun;
|
|
}
|
|
}
|
|
line.update(data);
|
|
|
|
return;
|
|
for (var i = 0; i < data.length; i++) {
|
|
line.target.add({ x: i, y: _Context.Cache[i] });
|
|
}
|
|
}
|
|
});
|
|
}
|
|
requestAnimationFrame(rAF);
|
|
}
|
|
requestAnimationFrame(rAF);
|
|
};
|
|
//#endregion
|
|
_Render();
|
|
{
|
|
//#region 设置 默认X轴
|
|
_DefaultAxisX
|
|
.setMouseInteractions(false)
|
|
.setChartInteractionPanByDrag(false)
|
|
.setChartInteractionZoomByWheel(false)
|
|
.setChartInteractionZoomByDrag(false)
|
|
.setChartInteractionFitByDrag(false)
|
|
.setAnimationScroll(false)
|
|
.setThickness(0)
|
|
.setStrokeStyle(emptyLine)
|
|
.setTickStrategy(AxisTickStrategies.Numeric, (strategy) => {
|
|
return strategy
|
|
.setCursorFormatter(function (value, range) {
|
|
var point = translatePoint(
|
|
{ x: value, y: 0 },
|
|
_DefaultAxes,
|
|
_DisplayAxes
|
|
);
|
|
return Math.floor(point.x).toLocaleString();
|
|
})
|
|
.setMajorTickStyle((major) =>
|
|
major.setGridStrokeStyle(emptyLine)
|
|
.setLabelFillStyle(transparentFill)
|
|
.setTickStyle(emptyLine)
|
|
)
|
|
.setMinorTickStyle((minor) =>
|
|
minor
|
|
.setGridStrokeStyle(emptyLine)
|
|
.setLabelFillStyle(transparentFill)
|
|
.setTickStyle(emptyLine)
|
|
)
|
|
});
|
|
_DefaultAxisX.zoom = false;
|
|
// _DefaultAxisX.disableAnimations();
|
|
const _DefaultAxisXScaleChange = (sender, width, height, engineWidth) => {
|
|
requestAnimationFrame(() => {
|
|
var clientPixel = Math.floor(engineWidth - _DefaultAxisY.getHeight());
|
|
let Ptn = window.innerWidth;//取点点数
|
|
_DefaultAxisX.setInterval(0, clientPixel, false, true);
|
|
_DataExtract.update({ clientPixel });
|
|
if (_Context.dataExtractSwitch && _Context.workmode == 1) {
|
|
vm.setFFTPixEtracteParamForExtract();//设置扫频的抽取的截止频率
|
|
}
|
|
});
|
|
};
|
|
//此处需要注意,scale的使用会导致下发抽取参数
|
|
_Chart.onResize(_DefaultAxisXScaleChange);
|
|
//#endregion
|
|
// _Methods.SetRangeY(127, -127);
|
|
_Methods.SetRangeY(20, -170);
|
|
|
|
}
|
|
{
|
|
_expose.Context = {};
|
|
Object.keys(_Context).forEach((key) => {
|
|
Object.defineProperty(_expose.Context, key, {
|
|
enumerable: true,
|
|
get() {
|
|
return _Context[key];
|
|
},
|
|
});
|
|
});
|
|
}
|
|
Object.keys(_Methods).forEach((key) => {
|
|
Object.defineProperty(_expose, key, {
|
|
enumerable: true,
|
|
get() {
|
|
return _Methods[key];
|
|
},
|
|
});
|
|
});
|
|
Object.assign(_expose, {
|
|
DisplayAxisX: _DisplayAxisX,
|
|
DefaultAxisX: _DefaultAxisX,
|
|
DefaultAxisY: _DefaultAxisY,
|
|
});
|
|
requestAnimationFrame(function () {
|
|
let range = _Chart.engine.scale.getInnerIntervalPixels();
|
|
_DefaultAxisX.setInterval(0, range.x, false, true);
|
|
_DisplayAxisX.setInterval(0, range.x, false, true);
|
|
});
|
|
/*
|
|
*/
|
|
function SetTickStyle(tick) {
|
|
return tick.setLabelFont((font) => font.setWeight('normal').setSize(12).setStyle('normal').setFamily('Arial').setVariant(true))
|
|
}
|
|
[_DefaultAxisY].map(_Axis => {
|
|
_Axis.setTickStrategy(AxisTickStrategies.Numeric, (strategy) => {
|
|
return strategy
|
|
.setMajorTickStyle(SetTickStyle)
|
|
.setMinorTickStyle(SetTickStyle)
|
|
.setFormattingFunction((value) => `${value.toFixed(0)}dB`)
|
|
|
|
});
|
|
});
|
|
[_DisplayAxisX].map(_Axis => {
|
|
_Axis.setTickStrategy(AxisTickStrategies.Numeric, (strategy) => {
|
|
return strategy
|
|
.setMajorTickStyle(SetTickStyle)
|
|
.setMinorTickStyle(SetTickStyle)
|
|
.setFormattingFunction((value) => `${(value / 1e9).toFixed(3)}GHz`)
|
|
|
|
});
|
|
});
|
|
// SlicedCharts.setLabelFormatter(SliceLabelFormatters.NamePlusRelativeValue)
|
|
|
|
// _expose.DargRectangle = () => {
|
|
// _Chart.onSeriesBackgroundMouseDragStart(function (obj, event, button) {
|
|
// console.log('series mouse drag start', arguments);
|
|
// })
|
|
// _Chart.onSeriesBackgroundMouseDragStop(function (obj, event, button, start) {
|
|
// console.log('series mouse drag stop', arguments);
|
|
// })
|
|
// _Chart.onSeriesBackgroundMouseDrag(function (obj, event, button, start, delta) {
|
|
// console.log('series mouse drag ',arguments);
|
|
// })
|
|
// }
|
|
// _Chart.onSeriesBackgroundMouseDragStop(function (obj, event, button, start) {
|
|
// if (button == 2) {
|
|
// if (event.x == start.x && event.y == start.y) {
|
|
// console.log('contextmenu');
|
|
// }
|
|
// }
|
|
// })
|
|
// _expose.DargRectangle();
|
|
return _expose;
|
|
}
|
|
return LineChart;
|
|
}); |