!(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; });