if(globalThis.Charts = globalThis.Charts || {}); globalThis.Charts.WaterFallChart = (function (lcjs) { const RANGE_TIME_MS = 10 * 1000; //#region 瀑布图 function WaterFallChart({ texts, board, container,btns, } = { texts: {},btns : [] }) { var DefaultAxisYThickness = 65; let { UseChartExtra } = globalThis.Charts; let { AxisScrollStrategies, AxisTickStrategies, TimeFormattingFunctions, emptyLine, emptyFill, lightningChart } = lcjs; let { ColorHSV, LUT, PalettedFill, ColorCSS } = arctionJS.lcjs; // Initialize chart. let chart = null; if (board) { chart = board.createChartXY({ columnIndex: 0, rowIndex: 1, columnSpan: 1, rowSpan: 1, }); } if (container) { chart = lightningChart({ overrideInteractionMouseButtons:{ axisXYZoomMouseButton:2,// 右键框选放大 chartXYPanMouseButton:2,// 邮件按住移动 chartXYRectangleZoomFitMouseButton:0,// 左键按住框选(已屏蔽) axisXYPanMouseButton:0, // 左键拖动XY轴 } }).ChartXY({ container }); } chart .setTitle(false) .setSeriesBackgroundFillStyle(emptyFill) .setSeriesBackgroundFillStyle(emptyFill) .setPadding(5) .setPadding({ top: 0 }) .disableAnimations(); btns = btns||[]; let [_Context, _Events, _Methods, _EventsMapToMethods, _UIElements] = UseChartExtra(chart); let _DefaultAxisX = chart.getDefaultAxisX(); let _DefaultAxisY = chart.getDefaultAxisY(); let _DisplayAxisX = chart.addAxisX({ type: 'linear-highPrecision',}).setInterval(0,0,false,true); Object.assign(_Context, { period:100, last:[], cache: [], resolution: 1920, series: null, updater:{ last:0, timeout:100 } }); Object.assign(_Methods, { addData: (data) => { if (_Context.paused) { return; } _Context.updater.last = window.performance.now(); _Context.cache.push(data); }, }); Object.assign(_Events, { RESOLUTION_CHANGE: new EventHandle({ resolution: (val) => (_Context.resolution = val), }), }); _EventsMapToMethods(); //#region 设置 默认X轴 _DefaultAxisX .setMouseInteractions(false) .setTickStrategy(AxisTickStrategies.Empty); //#endregion //#region 设置 展示X轴 const _DefaultAxisXScaleChange = () => { requestAnimationFrame(() => { const _Chart = chart; let { start, end } = _DefaultAxisX.getInterval(); _Methods.resolution((_Context.resolution = end - start)); }); }; _DefaultAxisX.onScaleChange(_DefaultAxisXScaleChange); _Events["RESOLUTION_CHANGE"].on( (val) => _Context.series != null && (_Context.series.Vm.resolution = val) ); //#endregion //#region 设置 默认Y轴 _DefaultAxisY .setScrollStrategy(AxisScrollStrategies.progressive) .setTickStrategy(AxisTickStrategies.Numeric, (strategy) => strategy .setMajorFormattingFunction((val) => TimeFormattingFunctions.hhmmss(val) ) .setMinorFormattingFunction((val) => TimeFormattingFunctions.hhmmss(val) ) .setMajorTickStyle((style) => strategy.getMinorTickStyle()) ) .setInterval( -RANGE_TIME_MS,0) .setThickness(DefaultAxisYThickness) ; //#endregion //#region 设置 数值对应的颜色 var defaultMaxDb = 120; var defaultMinDb = -20; function SetColorStyle(min,max){ if(!_Context.series)return; var range = max - min; var colors = globalThis.Charts.WaterFallChart.Colors; var valueColors = []; for(var i = 0 ; i < range ; i ++){ valueColors.push({value:i+min,color:colors[Math.floor(i / range * 256)]}); } var steps = valueColors.map(({ value, color }) => ({ value: value, label: value, color: ColorCSS(color), })); const lut = new LUT({ steps: steps, units: "dB", interpolate: false, }); const paletteFill = new PalettedFill({ lut, lookUpProperty: "value" }); _Context.series.setFillStyle(paletteFill) } Object.assign(_Methods, { SetColorStyle }); _Context.SetColorStyle = SetColorStyle; //#endregion function _CreateSeries() { if (_Context.series != null) { chart.getSeries()[0].dispose(); } var { start } = _DefaultAxisY.getInterval(); _Context.series = chart .addHeatmapScrollingGridSeries({ scrollDimension: "rows", resolution: _Context.resolution, start: { x: 0, y: 0 }, step: { x: 1, y: _Context.period }, }) .setWireframeStyle(emptyLine) .setMouseInteractions(false) .setDataCleaning({ minDataPointCount: 0 }); _Methods.SetColorStyle(defaultMinDb,defaultMaxDb); _DefaultAxisY .setScrollStrategy(AxisScrollStrategies.progressive) .setTickStrategy(AxisTickStrategies.Numeric, (strategy) => strategy //.setFormattingOffset(0) .setMajorFormattingFunction((val) => TimeFormattingFunctions.hhmmss(val) ) .setMinorFormattingFunction((val) => TimeFormattingFunctions.hhmmss(val) ) .setMajorTickStyle((style) => strategy.getMinorTickStyle()) ); //.setInterval(0, -10 * 1000) } _Methods.reset = _CreateSeries; window._Context = _Context; _Events["PERIOD_CHANGE"].on((val) => { _CreateSeries(); }); function spreadData(source, count) { var length = source.length; var multiple = Math.floor(count / length); var remain = length - (count % length); var target = []; for (var i = 0; i < source.length; i++) { var val = source[i]; for (var m = 0; m < multiple; m++) { target.push(val); } if (i > remain) { target.push(val); } } return target; } //#region 添加 UI 组件 //#region 添加 名称 { let element = _Methods.addText({ text: texts.title, bgcolor: false, name: "Title", }); _UIElements.TopLeft.push(element); } //#endregion //#region 添加 单位 { let element = _Methods.addText({ text: texts.unit, bgcolor: false, name: "Unit", }); _UIElements.TopRight.push(element); } //#endregion //#region 添加 暂停 if(btns.indexOf("pause") > -1){ let _PauseEl = _Methods.addButton({ text: "暂停", name: "Pause", handle() { _Context.paused ? _Methods.play() : _Methods.pause(); }, }); _Methods.onPausedChange((val) => { val?_PauseEl.set("继续","#409eff"):_PauseEl.set("暂停","#113665"); }); _UIElements.RightTop.push(_PauseEl); } //#endregion // 尺寸变化时 //fallChart.chart.getDefaultAxisY().getHeight() + 10;; chart.onResize(() => _UIElements.LayoutUIElements()); requestAnimationFrame(() => { _UIElements.LayoutUIElements(true); }); //#endregion var _count = 0; var _RenderWorker = new WebWorker({ methods:{ start:(ctx,payload)=>{ ctx.last = performance.now(); let offset = 0; ctx.period = payload.period; function rAF() { let now = performance.now(); let span = now - ctx.last; let interval = ctx.period; if (span > interval) { ctx.last = now - span % interval; let count = Math.floor(span / interval); callback('render',{count}); } requestAnimationFrame(rAF); } requestAnimationFrame(rAF); }, addtime:(ctx,payload)=>{ ctx.addtime = performance.now(); } }, callback(name,payload){ switch(name){ case 'render':{ let { count } = payload; let values = _Context.cache.splice(0,count); if (values.length == 0) { values.push(_Context.last); } else { _Context.last = values.slice(-1)[0]; } let now = performance.now(); if(now - _Context.updater.last < _Context.updater.timeout){ if (_Context.last.length > 1) { if (values.length < count) { values = spreadData(values, count); } _Context.series.addIntensityValues(values); } } } break; } } }) //#region 按刷新率渲染 let _Render = ()=>{ let period = _Context.period; _RenderWorker.call("start",{period}) //let intervalId = setTimeout(rAF,1000/60); } //#endregion requestAnimationFrame(() => { _DefaultAxisXScaleChange(); _CreateSeries(); // _Context.series.addIntensityValues((Array[])) _Render(); }); let _expose = { chart }; { _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, }); return _expose; } //#endregion return WaterFallChart; })(arctionJS.lcjs); globalThis.Charts.WaterFallChart.Colors = "#000000,#000008,#000010,#000018,#000020,#000029,#000031,#000039,#000041,#00004a,#000052,#00005a,#000062,#00006a,#000073,#00007b,#000083,#00008b,#000094,#00009c,#0000a4,#0000ac,#0000b4,#0000bd,#0000c5,#0000cd,#0000d5,#0000de,#0000e6,#0000ee,#0000f6,#0000ff,#0000ff,#0006ff,#000dff,#0013ff,#001aff,#0020ff,#0027ff,#002dff,#0034ff,#003aff,#0041ff,#0047ff,#004eff,#0055ff,#005bff,#0062ff,#0068ff,#006fff,#0075ff,#007cff,#0082ff,#0089ff,#008fff,#0096ff,#009cff,#00a3ff,#00aaff,#00b0ff,#00b7ff,#00bdff,#00c4ff,#00caff,#00d1ff,#00d7ff,#00deff,#00e4ff,#00ebff,#00f1ff,#00f8ff,#00ffff,#00ffff,#00fff3,#00ffe8,#00ffdd,#00ffd2,#00ffc7,#00ffbc,#00ffb1,#00ffa6,#00ff9b,#00ff90,#00ff85,#00ff79,#00ff6e,#00ff63,#00ff58,#00ff4d,#00ff42,#00ff37,#00ff2c,#00ff21,#00ff16,#00ff0b,#00ff00,#00ff00,#0dff00,#1aff00,#28ff00,#35ff00,#43ff00,#50ff00,#5dff00,#6bff00,#78ff00,#86ff00,#93ff00,#a1ff00,#aeff00,#bbff00,#c9ff00,#d6ff00,#e4ff00,#f1ff00,#ffff00,#ffff00,#fffb00,#fff700,#fff300,#ffef00,#ffeb00,#ffe800,#ffe400,#ffe000,#ffdc00,#ffd800,#ffd500,#ffd100,#ffcd00,#ffc900,#ffc500,#ffc200,#ffbe00,#ffba00,#ffb600,#ffb200,#ffaf00,#ffab00,#ffa700,#ffa300,#ff9f00,#ff9c00,#ff9800,#ff9400,#ff9000,#ff8c00,#ff8900,#ff8500,#ff8100,#ff7d00,#ff7900,#ff7500,#ff7200,#ff6e00,#ff6a00,#ff6600,#ff6200,#ff5f00,#ff5b00,#ff5700,#ff5300,#ff4f00,#ff4c00,#ff4800,#ff4400,#ff4000,#ff3c00,#ff3900,#ff3500,#ff3100,#ff2d00,#ff2900,#ff2600,#ff2200,#ff1e00,#ff1a00,#ff1600,#ff1300,#ff0f00,#ff0b00,#ff0700,#ff0300,#ff0000,#ff0000,#ff0001,#ff0003,#ff0005,#ff0007,#ff0009,#ff000a,#ff000c,#ff000e,#ff0010,#ff0012,#ff0014,#ff0015,#ff0017,#ff0019,#ff001b,#ff001d,#ff001f,#ff0020,#ff0022,#ff0024,#ff0026,#ff0028,#ff002a,#ff002b,#ff002d,#ff002f,#ff0031,#ff0033,#ff0035,#ff0036,#ff0038,#ff003a,#ff003c,#ff003e,#ff0040,#ff0041,#ff0043,#ff0045,#ff0047,#ff0049,#ff004a,#ff004c,#ff004e,#ff0050,#ff0052,#ff0054,#ff0055,#ff0057,#ff0059,#ff005b,#ff005d,#ff005f,#ff0060,#ff0062,#ff0064,#ff0066,#ff0068,#ff006a,#ff006b,#ff006d,#ff006f,#ff0071,#ff0073,#ff0075,#ff0076,#ff0078,#ff007a,#ff007c,#ff007e,#ff0080,#ff0081".split(",");