首次提交
This commit is contained in:
Vendored
+517
@@ -0,0 +1,517 @@
|
||||
|
||||
!(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) {
|
||||
|
||||
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
|
||||
} = 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(12))
|
||||
}
|
||||
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)
|
||||
/*
|
||||
var displayPosition = position;
|
||||
position = this.$chart.Display2Default(position);
|
||||
const target = window.marker = this.target = this.$line.target.addMarker(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) })));
|
||||
|
||||
|
||||
/*
|
||||
let keydown = false;
|
||||
let checkPosition = (current)=>{
|
||||
if(current.x != position.x){
|
||||
position = this.$chart.Display2Default(displayPosition);
|
||||
target.setPosition(position)
|
||||
}
|
||||
};
|
||||
target.getPointMarker().onMouseDown(function(){
|
||||
keydown = true;
|
||||
});
|
||||
target.getPointMarker().onMouseUp(function(){
|
||||
keydown = false;
|
||||
});
|
||||
target.onPositionChange((sender,current)=>{
|
||||
if(keydown){
|
||||
document.title = current.x;
|
||||
displayPosition = this.$chart.Default2Display(current);
|
||||
return;
|
||||
}
|
||||
checkPosition(current);
|
||||
})
|
||||
*/
|
||||
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);
|
||||
/*
|
||||
var dest = this.$chart.Display2Default(this.target.getPosition());
|
||||
var
|
||||
original.y = data[Math.floor(dest.x)];
|
||||
if(original.y === undefined){
|
||||
debugger;
|
||||
}
|
||||
// chartMarker.getResultTable().setContent([[["X:",original.x,"Y:",original.y].join("")]]);
|
||||
|
||||
|
||||
// this.target.setPosition(this.target.getPosition());
|
||||
*/
|
||||
}
|
||||
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;
|
||||
// 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);
|
||||
})
|
||||
};
|
||||
Line.prototype.AddMarker = function (opts) {
|
||||
var marker = this.$chart.target.addChartMarkerXY()
|
||||
.setPosition({ x: 60, y: -80 })
|
||||
var table = marker.getResultTable();
|
||||
marker.onPositionChange(function (target, position) {
|
||||
table.setContent([[Object.values(position).join(",")], ["X:1", "Y:2"]])
|
||||
});
|
||||
}
|
||||
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: 5, y: 5 }))
|
||||
.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: [],
|
||||
};
|
||||
let _expose = {};
|
||||
let _Methods = {};
|
||||
// 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窗体内的鼠标的滚动开启
|
||||
//_Chart.setMouseInteractionRectangleZoom(true);//设置窗体内的框选开启
|
||||
// _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);
|
||||
// let _DisplayAxisX = _DefaultAxisX;
|
||||
_Chart.onSeriesBackgroundSelect && _Chart.onSeriesBackgroundSelect(function () {
|
||||
});
|
||||
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;
|
||||
},
|
||||
AddData(name, data) {
|
||||
var _Line = _Context.Lines[name];
|
||||
if (_Line) { _Line.Data = data; }
|
||||
},
|
||||
});
|
||||
Object.assign(_Methods, {
|
||||
SetRangeX(start, end) {
|
||||
_DisplayAxisX.setInterval(start, end, false, true,);
|
||||
},
|
||||
SetRangeY(start, end) {
|
||||
_DefaultAxisY.setInterval(end, start, false, true);
|
||||
}
|
||||
});
|
||||
//#region 设置 展示X轴
|
||||
const _DisplayAxisXScaleChange = (initial) => {
|
||||
vm.setFFTPixEtracteParam();//设置扫频的抽取的截止频率
|
||||
requestAnimationFrame(() => {
|
||||
let { start, end } = _DisplayAxisX.getInterval();
|
||||
// if(start<600000000){
|
||||
// _DisplayAxisX.setInterval(600000000, end, false, true,);
|
||||
// }
|
||||
// if(end>40000000000){
|
||||
// _DisplayAxisX.setInterval(start, 40000000000, false, true,);
|
||||
// }
|
||||
|
||||
});
|
||||
};
|
||||
_DisplayAxisX.onAxisInteractionAreaMouseDoubleClick(function (e) {
|
||||
// e.setInterval(...e.range(), false, true);
|
||||
});
|
||||
_DisplayAxisX.onScaleChange(_DisplayAxisXScaleChange);
|
||||
_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, {
|
||||
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: 280 };//此处为设置数据刷新率 数值越大刷新越低
|
||||
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) {
|
||||
if (_Context.Divide !== 1) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
data[i] = data[i] / _Context.Divide;
|
||||
}
|
||||
}
|
||||
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;
|
||||
const _DefaultAxisXScaleChange = (sender, width, height, engineWidth) => {
|
||||
requestAnimationFrame(() => {
|
||||
var clientPixel = Math.floor(engineWidth - _DefaultAxisY.getHeight());
|
||||
_DefaultAxisX.setInterval(0, clientPixel, false, true);
|
||||
});
|
||||
vm.setFFTPixEtracteParam();//设置扫频的抽取的截止频率
|
||||
};
|
||||
_Chart.onResize(_DefaultAxisXScaleChange);
|
||||
//#endregion
|
||||
_Methods.SetRangeY(127, -127);
|
||||
}
|
||||
|
||||
{
|
||||
_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(10).setStyle('normal').setFamily('Arial').setVariant(true))
|
||||
}
|
||||
|
||||
[_DefaultAxisY, _DisplayAxisX].map(_Axis => {
|
||||
_Axis.setTickStrategy(AxisTickStrategies.Numeric, (strategy) => {
|
||||
return strategy
|
||||
.setMajorTickStyle(SetTickStyle)
|
||||
.setMinorTickStyle(SetTickStyle)
|
||||
});
|
||||
})
|
||||
|
||||
_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;
|
||||
});
|
||||
Reference in New Issue
Block a user