mirror of https://github.com/speeduino/Airbear.git
8 lines
13 KiB
JavaScript
8 lines
13 KiB
JavaScript
/*!
|
|
* chartjs-plugin-streaming v2.0.0
|
|
* https://nagix.github.io/chartjs-plugin-streaming
|
|
* (c) 2017-2021 Akihiko Kusanagi
|
|
* Released under the MIT license
|
|
*/
|
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["chart.js","chart.js/helpers"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).ChartStreaming=t(e.Chart,e.Chart.helpers)}(this,(function(e,t){"use strict";function o(e,t,o){return Math.min(Math.max(e,t),o)}function n(e,o){const n=e.options.realtime,a=e.chart.options.plugins.streaming;return t.valueOrDefault(n[o],a[o])}function a(e,{x:o,y:n},{xAxisID:a,yAxisID:i}){const s={};return t.each(o,(e=>{s[e]={axisId:a}})),t.each(n,(e=>{s[e]={axisId:i}})),s}const i="undefined"==typeof window?t.noop:window.cancelAnimationFrame;function s(e){const t=e.frameRequestID;t&&(i.call(window,t),delete e.frameRequestID)}function r(e){const t=e.refreshTimerID;t&&(clearInterval(t),delete e.refreshTimerID,delete e.refreshInterval)}function l(e,o,n){e.refreshTimerID||(e.refreshTimerID=setInterval((()=>{const n=t.callback(o);e.refreshInterval===n||isNaN(n)||(r(e),l(e,o,n))}),n||0),e.refreshInterval=n||0)}function c(e,o,n){return o="number"==typeof o?o:e.parse(o),t.isFinite(o)?{value:e.getPixelForValue(o),transitionable:!0}:{value:n}}function d(){const t=e.registry.getElement("boxAnnotation"),o=e.registry.getElement("lineAnnotation"),n=e.registry.getElement("pointAnnotation"),a=t.prototype.resolveElementProperties,i=o.prototype.resolveElementProperties,s=n.prototype.resolveElementProperties;t.prototype.resolveElementProperties=function(e,t){return function(e,t,o){const{scales:n,chartArea:a}=t,{xScaleID:i,yScaleID:s,xMin:r,xMax:l,yMin:d,yMax:u}=o,m=n[i],p=n[s],{top:f,left:h,bottom:g,right:y}=a,x=e.$streaming={};if(m){const e=c(m,r,h),t=c(m,l,y),o=e.value>t.value;e.transitionable&&(x[o?"x2":"x"]={axisId:i}),t.transitionable&&(x[o?"x":"x2"]={axisId:i}),e.transitionable!==t.transitionable&&(x.width={axisId:i,reverse:e.transitionable})}if(p){const e=c(p,d,f),t=c(p,u,g),o=e.value>t.value;e.transitionable&&(x[o?"y2":"y"]={axisId:s}),t.transitionable&&(x[o?"y":"y2"]={axisId:s}),e.transitionable!==t.transitionable&&(x.height={axisId:s,reverse:e.transitionable})}}(this,e,t),a.call(this,e,t)},o.prototype.resolveElementProperties=function(e,t){const o=e.chartArea;e.chartArea=function(e,t,o){const{scales:n,chartArea:a}=t,{scaleID:i,value:s}=o,r=n[i],{top:l,left:d,bottom:u,right:m}=a,p=e.$streaming={};if(r){const e=r.isHorizontal();return c(r,s).transitionable&&(p[e?"x":"y"]={axisId:i},p[e?"x2":"y2"]={axisId:i}),e?{top:l,bottom:u}:{left:d,right:m}}const{xScaleID:f,yScaleID:h,xMin:g,xMax:y,yMin:x,yMax:b}=o,v=n[f],I=n[h],D={};if(v){const e=c(v,g),t=c(v,y);e.transitionable?p.x={axisId:f}:D.left=d,t.transitionable?p.x2={axisId:f}:D.right=m}if(I){const e=c(I,x),t=c(I,b);e.transitionable?p.y={axisId:h}:D.top=l,t.transitionable?p.y2={axisId:h}:D.bottom=u}return D}(this,e,t);const n=i.call(this,e,t);return e.chartArea=o,n},n.prototype.resolveElementProperties=function(e,t){return function(e,t,o){const n=t.scales,{xScaleID:a,yScaleID:i,xValue:s,yValue:r}=o,l=n[a],d=n[i],u=e.$streaming={};l&&c(l,s).transitionable&&(u.x={axisId:a});d&&c(d,r).transitionable&&(u.y={axisId:i})}(this,e,t),s.call(this,e,t)}}const u={x:["x","caretX"],y:["y","caretY"]};function m(...e){const t=this,o=t.getActiveElements()[0];if(o){const e=t._chart.getDatasetMeta(o.datasetIndex);t.$streaming=a(0,u,e)}else t.$streaming={};t.constructor.prototype.update.call(t,...e)}const p=new WeakMap;function f(e){const{originalScaleOptions:o}=function(e){let t=p.get(e);return t||(t={originalScaleOptions:{}},p.set(e,t)),t}(e),a=e.scales;return t.each(a,(e=>{const t=e.id;o[t]||(o[t]={duration:n(e,"duration"),delay:n(e,"delay")})})),t.each(o,((e,t)=>{a[t]||delete o[t]})),o}function h(e,t,a,i){const{chart:s,axis:r}=e,{minDuration:l=0,maxDuration:c=1/0,minDelay:d=-1/0,maxDelay:u=1/0}=i&&i[r]||{},m=e.options.realtime,p=n(e,"duration"),h=n(e,"delay"),g=o(p*(2-t),l,c);let y,x;return f(s),y=e.isHorizontal()?(e.right-a.x)/(e.right-e.left):(e.bottom-a.y)/(e.bottom-e.top),x=h+y*(p-g),m.duration=g,m.delay=o(x,d,u),g!==e.max-e.min}function g(e,t,a){const{chart:i,axis:s}=e,{minDelay:r=-1/0,maxDelay:l=1/0}=a&&a[s]||{},c=n(e,"delay")+(e.getValueForPixel(t)-e.getValueForPixel(0));return f(i),e.options.realtime.delay=o(c,r,l),!0}function y(e,o){const n=o.$streaming;if(n.zoomPlugin!==e){const a=n.resetZoom=o.resetZoom;!function(e){e.zoomFunctions.realtime=h,e.panFunctions.realtime=g}(e),o.resetZoom=e=>{!function(e){const o=f(e);t.each(e.scales,(e=>{const t=e.options.realtime;if(t){const n=o[e.id];n?(t.duration=n.duration,t.delay=n.delay):(delete t.duration,delete t.delay)}}))}(o),a(e)},n.zoomPlugin=e}}function x(e){const t=e.$streaming;t.zoomPlugin&&(e.resetZoom=t.resetZoom,function(e){p.delete(e)}(e),delete t.resetZoom,delete t.zoomPlugin)}const b={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,15,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,15,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},v=Object.keys(b);function I(e,o,n){if(n){if(n.length){const{lo:a,hi:i}=t._lookup(n,o);e[n[a]>=o?n[a]:n[i]]=!0}}else e[o]=!0}const D=["pointBackgroundColor","pointBorderColor","pointBorderWidth","pointRadius","pointRotation","pointStyle","pointHitRadius","pointHoverBackgroundColor","pointHoverBorderColor","pointHoverBorderWidth","pointHoverRadius","backgroundColor","borderColor","borderSkipped","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","radius","rotation"];function k(e,o,n){const a=e.$animations||{};t.each(e.$streaming,((i,s)=>{if(i.axisId===o){const o=i.reverse?-n:n,r=a[s];t.isFinite(e[s])&&(e[s]-=o),r&&(r._from-=o,r._to-=o)}}))}class w extends e.TimeScale{constructor(e){super(e),this.$realtime=this.$realtime||{}}init(e,o){const a=this;super.init(e,o),l(a.$realtime,(()=>{const e=a.chart,o=n(a,"onRefresh");return t.callback(o,[e],a),function(e){const{chart:o,id:a,max:i}=e,s=n(e,"duration"),r=n(e,"delay"),l=n(e,"ttl"),c=n(e,"pause"),d=Date.now()-(isNaN(l)?s+r:l);let u,m,p,f;t.each(o.data.datasets,((e,n)=>{const s=o.getDatasetMeta(n),r=a===s.xAxisID?"x":a===s.yAxisID&&"y";if(r){const a=s.controller,h=e.data,g=h.length;if(c){for(u=0;u<g;++u){const e=a.getParsed(u);if(e&&!(e[r]<i))break}m=u+2}else m=0;for(u=m;u<g;++u){const e=a.getParsed(u);if(!(e&&e[r]<=d))break}p=u-m,isNaN(l)&&(p=Math.max(p-2,0)),h.splice(m,p),t.each(D,(o=>{t.isArray(e[o])&&e[o].splice(m,p)})),t.each(e.datalabels,(e=>{t.isArray(e)&&e.splice(m,p)})),"object"!=typeof h[0]&&(f={start:m,count:p}),t.each(o._active,((e,t)=>{e.datasetIndex===n&&e.index>=m&&(e.index>=m+p?e.index-=p:o._active.splice(t,1))}),null,!0)}})),f&&o.data.labels.splice(f.start,f.count)}(a),e.update("quiet"),n(a,"refresh")}))}update(e,o,a){const i=this,{$realtime:r,options:l}=i,{bounds:c,offset:d,ticks:u}=l,{autoSkip:m,source:p,major:f}=u,h=f.enabled;n(i,"pause")?s(r):(r.frameRequestID||(r.head=Date.now()),function(e,o){if(!e.frameRequestID){const n=()=>{const a=e.nextRefresh||0,i=Date.now();if(a<=i){const n=t.callback(o),a=1e3/(Math.max(n,0)||30),s=e.nextRefresh+a||0;e.nextRefresh=s>i?s:i+a}e.frameRequestID=t.requestAnimFrame.call(window,n)};e.frameRequestID=t.requestAnimFrame.call(window,n)}}(r,(()=>{const e=i.chart,o=e.$streaming;return function(e){const{chart:o,id:a,$realtime:i}=e,s=n(e,"duration"),r=n(e,"delay"),l=e.isHorizontal(),c=l?e.width:e.height,d=Date.now(),u=o.tooltip,m=function(e){const t=e.$streaming.annotationPlugin;if(t){const o=t._getState(e);return o&&o.elements||[]}return[]}(o);let p=c*(d-i.head)/s;l===!!e.options.reverse&&(p=-p),t.each(o.data.datasets,((e,t)=>{const n=o.getDatasetMeta(t),{data:i=[],dataset:s}=n;for(let e=0,t=i.length;e<t;++e)k(i[e],a,p);s&&(k(s,a,p),delete s._path)}));for(let e=0,t=m.length;e<t;++e)k(m[e],a,p);u&&k(u,a,p),e.max=d-r,e.min=e.max-s,i.head=d}(i),o&&t.callback(o.render,[e]),n(i,"frameRate")}))),l.bounds=void 0,l.offset=!1,u.autoSkip=!1,u.source="auto"===p?"":p,f.enabled=!0,super.update(e,o,a),l.bounds=c,l.offset=d,u.autoSkip=m,u.source=p,f.enabled=h}buildTicks(){const e=this,o=n(e,"duration"),a=n(e,"delay"),i=e.$realtime.head-a,s=i-o,r=[1e15,i],l=[-1e15,s];Object.defineProperty(e,"min",{get:()=>l.shift(),set:t.noop}),Object.defineProperty(e,"max",{get:()=>r.shift(),set:t.noop});const c=super.buildTicks();return delete e.min,delete e.max,e.min=s,e.max=i,c}calculateLabelRotation(){const e=this.options.ticks,t=e.maxRotation;e.maxRotation=e.minRotation||0,super.calculateLabelRotation(),e.maxRotation=t}fit(){const e=this,t=e.options;super.fit(),t.ticks.display&&t.display&&e.isHorizontal()&&(e.paddingLeft=3,e.paddingRight=3,e._handleMargins())}draw(e){const o=this,{chart:n,ctx:a}=o,i=o.isHorizontal()?{left:e.left,top:0,right:e.right,bottom:n.height}:{left:0,top:e.top,right:n.width,bottom:e.bottom};o._gridLineItems=null,o._labelItems=null,t.clipArea(a,i),super.draw(e),t.unclipArea(a)}destroy(){const e=this.$realtime;s(e),r(e)}_generate(){const e=this,o=e._adapter,a=n(e,"duration"),i=n(e,"delay"),s=n(e,"refresh"),r=e.$realtime.head-i,l=r-a,c=e._getLabelCapacity(l),{time:d,ticks:u}=e.options,m=d.unit||function(e,t,o,n){const a=o-t,i=v.length;for(let t=v.indexOf(e);t<i-1;++t){const{common:e,size:o,steps:i}=b[v[t]],s=i?i[i.length-1]:Number.MAX_SAFE_INTEGER;if(e&&Math.ceil(a/(s*o))<=n)return v[t]}return v[i-1]}(d.minUnit,l,r,c),p=function(e){for(let t=v.indexOf(e)+1,o=v.length;t<o;++t)if(b[v[t]].common)return v[t]}(m),f=d.stepSize||function(e,t,o,n){const a=t-e,{size:i,steps:s}=b[o];let r;if(!s)return Math.ceil(a/(n*i));for(let e=0,t=s.length;e<t&&(r=s[e],!(Math.ceil(a/(i*r))<=n));++e);return r}(l,r,m,c),h="week"===m&&d.isoWeekday,g=u.major.enabled,y=t.isNumber(h)||!0===h,x=b[m],D={};let k,w,R=l;if(y&&(R=+o.startOf(R,"isoWeek",h)),R=+o.startOf(R,y?"day":m),o.diff(r,l,m)>1e5*f)throw new Error(l+" and "+r+" are too far apart with stepSize of "+f+" "+m);k=R,g&&p&&!y&&!d.round&&(k=+o.startOf(k,p),k=+o.add(k,~~((R-k)/(x.size*f))*f,m));const $="data"===u.source&&e.getDataTimestamps();for(w=0;k<r+s;k=+o.add(k,f,m),w++)I(D,k,$);return k!==r+s&&1!==w||I(D,k,$),Object.keys(D).sort(((e,t)=>e-t)).map((e=>+e))}}w.id="realtime",w.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},realtime:{},ticks:{autoSkip:!1,source:"auto",major:{enabled:!0}}},e.defaults.describe("scale.realtime",{_scriptable:e=>"onRefresh"!==e});e.defaults.set("transitions",{quiet:{animation:{duration:0}}});const R={x:["x","cp1x","cp2x"],y:["y","cp1y","cp2y"]};function $(o){const n=this;"quiet"===o&&t.each(n.data.datasets,((t,o)=>{n.getDatasetMeta(o).controller._setStyle=function(t,o,n,a){e.DatasetController.prototype._setStyle.call(this,t,o,"quiet",a)}})),e.Chart.prototype.update.call(n,o),"quiet"===o&&t.each(n.data.datasets,((e,t)=>{delete n.getDatasetMeta(t).controller._setStyle}))}function E(e){const t=e.$streaming;e.render(),t.lastMouseEvent&&setTimeout((()=>{const o=t.lastMouseEvent;o&&e._eventHandler(o)}),0)}const M=[{id:"streaming",version:"2.0.0",beforeInit(e){const o=e.$streaming=e.$streaming||{render:E},n=o.canvas=e.canvas,a=o.mouseEventListener=n=>{const a=t.getRelativePosition(n,e);o.lastMouseEvent={type:"mousemove",chart:e,native:n,x:a.x,y:a.y}};n.addEventListener("mousedown",a),n.addEventListener("mouseup",a)},afterInit(e){e.update=$},beforeUpdate(o){const{scales:n,elements:a}=o.options,i=o.tooltip;t.each(n,(({type:e})=>{"realtime"===e&&(a.line.capBezierPoints=!1)})),i&&(i.update=m);try{!function(e,t){const o=t.$streaming;if(o.annotationPlugin!==e){const t=e.afterUpdate;d(),o.annotationPlugin=e,e.afterUpdate=(e,o,n)=>{const a=o.mode,i=n.animation;"quiet"===a&&(n.animation=!1),t.call(this,e,o,n),"quiet"===a&&(n.animation=i)}}}(e.registry.getPlugin("annotation"),o)}catch(e){!function(e){delete e.$streaming.annotationPlugin}(o)}try{y(e.registry.getPlugin("zoom"),o)}catch(e){x(o)}},beforeDatasetUpdate(e,o){const{meta:n,mode:a}=o;if("quiet"===a){const{controller:e,$animations:o}=n;o&&o.visible&&o.visible._active&&(e.updateElement=t.noop,e.updateSharedOptions=t.noop)}},afterDatasetUpdate(e,t){const{meta:o,mode:n}=t,{data:i=[],dataset:s,controller:r}=o;for(let e=0,t=i.length;e<t;++e)i[e].$streaming=a(i[e],R,o);s&&(s.$streaming=a(0,R,o)),"quiet"===n&&(delete r.updateElement,delete r.updateSharedOptions)},beforeDatasetDraw(e,o){const{ctx:n,chartArea:a,width:i,height:s}=e,{xAxisID:r,yAxisID:l,controller:c}=o.meta,d={left:0,top:0,right:i,bottom:s};r&&c.getScaleForId(r)instanceof w&&(d.left=a.left,d.right=a.right),l&&c.getScaleForId(l)instanceof w&&(d.top=a.top,d.bottom=a.bottom),t.clipArea(n,d)},afterDatasetDraw(e){t.unclipArea(e.ctx)},beforeEvent(e,t){const o=e.$streaming,n=t.event;"mousemove"===n.type?o.lastMouseEvent=n:"mouseout"===n.type&&delete o.lastMouseEvent},destroy(e){const{scales:o,$streaming:n,tooltip:a}=e,{canvas:i,mouseEventListener:s}=n;delete e.update,a&&delete a.update,i.removeEventListener("mousedown",s),i.removeEventListener("mouseup",s),t.each(o,(e=>{e instanceof w&&e.destroy()}))},defaults:{duration:1e4,delay:0,frameRate:30,refresh:1e3,onRefresh:null,pause:!1,ttl:void 0},descriptors:{_scriptable:e=>"onRefresh"!==e}},w];return e.Chart.register(M),M}));
|