vmui: optimize render (#1852)

* feat: change duration by "enter"

* fix: optimize data processing for chart

* feat: set minimum step to 1ms

* update dependencies

* update package-lock

* app/vmselect/vmui: `make vmui-update`

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Yury Molodov 2021-11-30 01:56:48 +03:00 committed by Aliaksandr Valialkin
parent 975498d402
commit 500945499f
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
17 changed files with 626 additions and 329 deletions

View file

@ -1,19 +1,19 @@
{
"files": {
"main.css": "./static/css/main.674f8c98.chunk.css",
"main.js": "./static/js/main.e591a3b4.chunk.js",
"runtime-main.js": "./static/js/runtime-main.d808bb43.js",
"main.js": "./static/js/main.43993c5c.chunk.js",
"runtime-main.js": "./static/js/runtime-main.f698388d.js",
"static/css/2.77671664.chunk.css": "./static/css/2.77671664.chunk.css",
"static/js/2.66bd79b7.chunk.js": "./static/js/2.66bd79b7.chunk.js",
"static/js/3.e04f34ff.chunk.js": "./static/js/3.e04f34ff.chunk.js",
"static/js/2.bfcf9c30.chunk.js": "./static/js/2.bfcf9c30.chunk.js",
"static/js/3.e51afffb.chunk.js": "./static/js/3.e51afffb.chunk.js",
"index.html": "./index.html",
"static/js/2.66bd79b7.chunk.js.LICENSE.txt": "./static/js/2.66bd79b7.chunk.js.LICENSE.txt"
"static/js/2.bfcf9c30.chunk.js.LICENSE.txt": "./static/js/2.bfcf9c30.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.d808bb43.js",
"static/js/runtime-main.f698388d.js",
"static/css/2.77671664.chunk.css",
"static/js/2.66bd79b7.chunk.js",
"static/js/2.bfcf9c30.chunk.js",
"static/css/main.674f8c98.chunk.css",
"static/js/main.e591a3b4.chunk.js"
"static/js/main.43993c5c.chunk.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="./static/css/2.77671664.chunk.css" rel="stylesheet"><link href="./static/css/main.674f8c98.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);p.length;)p.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"e04f34ff"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpvmui=this.webpackJsonpvmui||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([])</script><script src="./static/js/2.66bd79b7.chunk.js"></script><script src="./static/js/main.e591a3b4.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="./static/css/2.77671664.chunk.css" rel="stylesheet"><link href="./static/css/main.674f8c98.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);p.length;)p.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"e51afffb"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpvmui=this.webpackJsonpvmui||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([])</script><script src="./static/js/2.bfcf9c30.chunk.js"></script><script src="./static/js/main.43993c5c.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -12,34 +12,6 @@ object-assign
* http://adamwdraper.github.com/Numeral-js/
*/
/*! exports provided: default */
/*! exports provided: optionsUpdateState, dataMatch */
/*! no static exports found */
/*! react */
/*! uplot */
/*! uplot-wrappers-common */
/*!*************************!*\
!*** ./common/index.ts ***!
\*************************/
/*!*******************************!*\
!*** ./react/uplot-react.tsx ***!
\*******************************/
/*!**************************************************************************************!*\
!*** external {"amd":"react","commonjs":"react","commonjs2":"react","root":"React"} ***!
\**************************************************************************************/
/*!**************************************************************************************!*\
!*** external {"amd":"uplot","commonjs":"uplot","commonjs2":"uplot","root":"uPlot"} ***!
\**************************************************************************************/
/**
* A better abstraction over CSS.
*

View file

@ -1 +1 @@
(this.webpackJsonpvmui=this.webpackJsonpvmui||[]).push([[3],{342:function(e,t,n){"use strict";n.r(t),n.d(t,"getCLS",(function(){return y})),n.d(t,"getFCP",(function(){return g})),n.d(t,"getFID",(function(){return C})),n.d(t,"getLCP",(function(){return k})),n.d(t,"getTTFB",(function(){return D}));var i,r,a,o,u=function(e,t){return{name:e,value:void 0===t?-1:t,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var n=new PerformanceObserver((function(e){return e.getEntries().map(t)}));return n.observe({type:e,buffered:!0}),n}}catch(e){}},f=function(e,t){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),t&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},s=function(e){addEventListener("pageshow",(function(t){t.persisted&&e(t)}),!0)},m=function(e,t,n){var i;return function(r){t.value>=0&&(r||n)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},v=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},d=function(){f((function(e){var t=e.timeStamp;v=t}),!0)},l=function(){return v<0&&(v=p(),d(),s((function(){setTimeout((function(){v=p(),d()}),0)}))),{get firstHiddenTime(){return v}}},g=function(e,t){var n,i=l(),r=u("FCP"),a=function(e){"first-contentful-paint"===e.name&&(f&&f.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=e.startTime,r.entries.push(e),n(!0)))},o=window.performance&&performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],f=o?null:c("paint",a);(o||f)&&(n=m(e,r,t),o&&a(o),s((function(i){r=u("FCP"),n=m(e,r,t),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,n(!0)}))}))})))},h=!1,T=-1,y=function(e,t){h||(g((function(e){T=e.value})),h=!0);var n,i=function(t){T>-1&&e(t)},r=u("CLS",0),a=0,o=[],v=function(e){if(!e.hadRecentInput){var t=o[0],i=o[o.length-1];a&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(a+=e.value,o.push(e)):(a=e.value,o=[e]),a>r.value&&(r.value=a,r.entries=o,n())}},p=c("layout-shift",v);p&&(n=m(i,r,t),f((function(){p.takeRecords().map(v),n(!0)})),s((function(){a=0,T=-1,r=u("CLS",0),n=m(i,r,t)})))},E={passive:!0,capture:!0},w=new Date,L=function(e,t){i||(i=t,r=e,a=new Date,F(removeEventListener),S())},S=function(){if(r>=0&&r<a-w){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+r};o.forEach((function(t){t(e)})),o=[]}},b=function(e){if(e.cancelable){var t=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){L(e,t),r()},i=function(){r()},r=function(){removeEventListener("pointerup",n,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",n,E),addEventListener("pointercancel",i,E)}(t,e):L(t,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,b,E)}))},C=function(e,t){var n,a=l(),v=u("FID"),p=function(e){e.startTime<a.firstHiddenTime&&(v.value=e.processingStart-e.startTime,v.entries.push(e),n(!0))},d=c("first-input",p);n=m(e,v,t),d&&f((function(){d.takeRecords().map(p),d.disconnect()}),!0),d&&s((function(){var a;v=u("FID"),n=m(e,v,t),o=[],r=-1,i=null,F(addEventListener),a=p,o.push(a),S()}))},P={},k=function(e,t){var n,i=l(),r=u("LCP"),a=function(e){var t=e.startTime;t<i.firstHiddenTime&&(r.value=t,r.entries.push(e)),n()},o=c("largest-contentful-paint",a);if(o){n=m(e,r,t);var v=function(){P[r.id]||(o.takeRecords().map(a),o.disconnect(),P[r.id]=!0,n(!0))};["keydown","click"].forEach((function(e){addEventListener(e,v,{once:!0,capture:!0})})),f(v,!0),s((function(i){r=u("LCP"),n=m(e,r,t),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,P[r.id]=!0,n(!0)}))}))}))}},D=function(e){var t,n=u("TTFB");t=function(){try{var t=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,t={entryType:"navigation",startTime:0};for(var n in e)"navigationStart"!==n&&"toJSON"!==n&&(t[n]=Math.max(e[n]-e.navigationStart,0));return t}();if(n.value=n.delta=t.responseStart,n.value<0||n.value>performance.now())return;n.entries=[t],e(n)}catch(e){}},"complete"===document.readyState?setTimeout(t,0):addEventListener("pageshow",t)}}}]);
(this.webpackJsonpvmui=this.webpackJsonpvmui||[]).push([[3],{351:function(e,t,n){"use strict";n.r(t),n.d(t,"getCLS",(function(){return y})),n.d(t,"getFCP",(function(){return g})),n.d(t,"getFID",(function(){return C})),n.d(t,"getLCP",(function(){return k})),n.d(t,"getTTFB",(function(){return D}));var i,r,a,o,u=function(e,t){return{name:e,value:void 0===t?-1:t,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var n=new PerformanceObserver((function(e){return e.getEntries().map(t)}));return n.observe({type:e,buffered:!0}),n}}catch(e){}},f=function(e,t){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),t&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},s=function(e){addEventListener("pageshow",(function(t){t.persisted&&e(t)}),!0)},m=function(e,t,n){var i;return function(r){t.value>=0&&(r||n)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},v=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},d=function(){f((function(e){var t=e.timeStamp;v=t}),!0)},l=function(){return v<0&&(v=p(),d(),s((function(){setTimeout((function(){v=p(),d()}),0)}))),{get firstHiddenTime(){return v}}},g=function(e,t){var n,i=l(),r=u("FCP"),a=function(e){"first-contentful-paint"===e.name&&(f&&f.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=e.startTime,r.entries.push(e),n(!0)))},o=window.performance&&performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],f=o?null:c("paint",a);(o||f)&&(n=m(e,r,t),o&&a(o),s((function(i){r=u("FCP"),n=m(e,r,t),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,n(!0)}))}))})))},h=!1,T=-1,y=function(e,t){h||(g((function(e){T=e.value})),h=!0);var n,i=function(t){T>-1&&e(t)},r=u("CLS",0),a=0,o=[],v=function(e){if(!e.hadRecentInput){var t=o[0],i=o[o.length-1];a&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(a+=e.value,o.push(e)):(a=e.value,o=[e]),a>r.value&&(r.value=a,r.entries=o,n())}},p=c("layout-shift",v);p&&(n=m(i,r,t),f((function(){p.takeRecords().map(v),n(!0)})),s((function(){a=0,T=-1,r=u("CLS",0),n=m(i,r,t)})))},E={passive:!0,capture:!0},w=new Date,L=function(e,t){i||(i=t,r=e,a=new Date,F(removeEventListener),S())},S=function(){if(r>=0&&r<a-w){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+r};o.forEach((function(t){t(e)})),o=[]}},b=function(e){if(e.cancelable){var t=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){L(e,t),r()},i=function(){r()},r=function(){removeEventListener("pointerup",n,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",n,E),addEventListener("pointercancel",i,E)}(t,e):L(t,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,b,E)}))},C=function(e,t){var n,a=l(),v=u("FID"),p=function(e){e.startTime<a.firstHiddenTime&&(v.value=e.processingStart-e.startTime,v.entries.push(e),n(!0))},d=c("first-input",p);n=m(e,v,t),d&&f((function(){d.takeRecords().map(p),d.disconnect()}),!0),d&&s((function(){var a;v=u("FID"),n=m(e,v,t),o=[],r=-1,i=null,F(addEventListener),a=p,o.push(a),S()}))},P={},k=function(e,t){var n,i=l(),r=u("LCP"),a=function(e){var t=e.startTime;t<i.firstHiddenTime&&(r.value=t,r.entries.push(e)),n()},o=c("largest-contentful-paint",a);if(o){n=m(e,r,t);var v=function(){P[r.id]||(o.takeRecords().map(a),o.disconnect(),P[r.id]=!0,n(!0))};["keydown","click"].forEach((function(e){addEventListener(e,v,{once:!0,capture:!0})})),f(v,!0),s((function(i){r=u("LCP"),n=m(e,r,t),requestAnimationFrame((function(){requestAnimationFrame((function(){r.value=performance.now()-i.timeStamp,P[r.id]=!0,n(!0)}))}))}))}},D=function(e){var t,n=u("TTFB");t=function(){try{var t=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,t={entryType:"navigation",startTime:0};for(var n in e)"navigationStart"!==n&&"toJSON"!==n&&(t[n]=Math.max(e[n]-e.navigationStart,0));return t}();if(n.value=n.delta=t.responseStart,n.value<0||n.value>performance.now())return;n.entries=[t],e(n)}catch(e){}},"complete"===document.readyState?setTimeout(t,0):addEventListener("pageshow",t)}}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);p.length;)p.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"e04f34ff"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpvmui=this.webpackJsonpvmui||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([]);
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);p.length;)p.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"e51afffb"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpvmui=this.webpackJsonpvmui||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([]);

View file

@ -27,6 +27,7 @@
"@types/jest": "^27.0.3",
"@types/lodash.debounce": "^4.0.6",
"@types/lodash.get": "^4.4.6",
"@types/lodash.throttle": "^4.1.6",
"@types/node": "^16.11.10",
"@types/numeral": "^2.0.2",
"@types/qs": "^6.9.7",
@ -37,6 +38,7 @@
"dayjs": "^1.10.7",
"lodash.debounce": "^4.0.8",
"lodash.get": "^4.4.2",
"lodash.throttle": "^4.1.1",
"numeral": "^2.0.6",
"qs": "^6.10.1",
"react": "^17.0.2",
@ -45,12 +47,11 @@
"react-scripts": "4.0.3",
"typescript": "~4.5.2",
"uplot": "^1.6.17",
"uplot-react": "^1.1.1",
"web-vitals": "^2.1.2"
},
"devDependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"customize-cra": "^1.0.0",
"eslint-plugin-react": "^7.27.1",
@ -1808,9 +1809,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
"integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
@ -2151,11 +2152,6 @@
}
}
},
"node_modules/@date-io/date-fns/node_modules/@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
},
"node_modules/@date-io/dayjs": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.11.0.tgz",
@ -2188,11 +2184,6 @@
}
}
},
"node_modules/@date-io/luxon/node_modules/@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
},
"node_modules/@date-io/moment": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.11.0.tgz",
@ -2209,11 +2200,6 @@
}
}
},
"node_modules/@date-io/moment/node_modules/@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
},
"node_modules/@emotion/babel-plugin": {
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz",
@ -3143,6 +3129,17 @@
}
}
},
"node_modules/@mui/base/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/icons-material": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.2.0.tgz",
@ -3164,6 +3161,17 @@
}
}
},
"node_modules/@mui/icons-material/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/lab": {
"version": "5.0.0-alpha.58",
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.58.tgz",
@ -3214,6 +3222,17 @@
}
}
},
"node_modules/@mui/lab/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/material": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.2.2.tgz",
@ -3258,6 +3277,17 @@
}
}
},
"node_modules/@mui/material/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/private-theming": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.2.2.tgz",
@ -3284,6 +3314,17 @@
}
}
},
"node_modules/@mui/private-theming/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/styled-engine": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.2.0.tgz",
@ -3314,6 +3355,17 @@
}
}
},
"node_modules/@mui/styled-engine/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/styles": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.2.2.tgz",
@ -3354,6 +3406,17 @@
}
}
},
"node_modules/@mui/styles/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/system": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.2.2.tgz",
@ -3393,6 +3456,17 @@
}
}
},
"node_modules/@mui/system/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mui/types": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.0.tgz",
@ -3424,6 +3498,17 @@
"react": "^17.0.2"
}
},
"node_modules/@mui/utils/node_modules/@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -3557,9 +3642,9 @@
}
},
"node_modules/@popperjs/core": {
"version": "2.10.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
"integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
@ -4088,6 +4173,14 @@
"@types/lodash": "*"
}
},
"node_modules/@types/lodash.throttle": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.6.tgz",
"integrity": "sha512-/UIH96i/sIRYGC60NoY72jGkCJtFN5KVPhEMMMTjol65effe1gPn0tycJqV5tlSwMTzX8FqzB5yAj0rfGHTPNg==",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/minimatch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
@ -4264,12 +4357,12 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz",
"integrity": "sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz",
"integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==",
"dependencies": {
"@typescript-eslint/experimental-utils": "5.3.0",
"@typescript-eslint/scope-manager": "5.3.0",
"@typescript-eslint/experimental-utils": "5.4.0",
"@typescript-eslint/scope-manager": "5.4.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@ -4295,14 +4388,14 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz",
"integrity": "sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz",
"integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==",
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.3.0",
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/typescript-estree": "5.3.0",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@ -4318,12 +4411,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz",
"integrity": "sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz",
"integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==",
"dependencies": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/visitor-keys": "5.3.0"
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -4334,9 +4427,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.0.tgz",
"integrity": "sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz",
"integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@ -4346,12 +4439,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz",
"integrity": "sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz",
"integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==",
"dependencies": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/visitor-keys": "5.3.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@ -4372,11 +4465,11 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz",
"integrity": "sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz",
"integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==",
"dependencies": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/types": "5.4.0",
"eslint-visitor-keys": "^3.0.0"
},
"engines": {
@ -4388,9 +4481,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz",
"integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz",
"integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
@ -5953,7 +6046,6 @@
},
"node_modules/bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"dependencies": {
@ -7793,9 +7885,9 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"node_modules/diff-sequences": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
"integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==",
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
@ -12093,14 +12185,29 @@
}
},
"node_modules/jest-diff": {
"version": "27.3.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz",
"integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==",
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.0.tgz",
"integrity": "sha512-fdXgpnyQH4LNSnYgRfHN/g413bqbPspWIAZPlXrdNISehDih1VNDtuRvlzGQJ4Go+fur1HKB2IyI25t6cWi5EA==",
"dependencies": {
"chalk": "^4.0.0",
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.3.1",
"pretty-format": "^27.3.1"
"diff-sequences": "^27.4.0",
"jest-get-type": "^27.4.0",
"pretty-format": "^27.4.0"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/jest-diff/node_modules/@jest/types": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.0.tgz",
"integrity": "sha512-jIsLdASXMf8GS7P7oGFGwobNse/6Ewq3GBPHoo0i6XRmja+NrUoDqJm4a1ffF2bHGleKJizxokcp1sCqSktP3g==",
"dependencies": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
"@types/yargs": "^16.0.0",
"chalk": "^4.0.0"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
@ -12121,6 +12228,31 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/jest-diff/node_modules/pretty-format": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.0.tgz",
"integrity": "sha512-n0QR6hMREfp6nLzfVksXMAfIxk1ffOOfbb/FzKHFmRtn9iJKaZXB8WMzLr8a72IASShEAhqK06nlwp1gVWgqKg==",
"dependencies": {
"@jest/types": "^27.4.0",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/jest-docblock": {
"version": "26.0.0",
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
@ -12317,9 +12449,9 @@
}
},
"node_modules/jest-get-type": {
"version": "27.3.1",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz",
"integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==",
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
"integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==",
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
@ -13907,6 +14039,11 @@
"lodash._reinterpolate": "^3.0.0"
}
},
"node_modules/lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
},
"node_modules/lodash.truncate": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
@ -14407,7 +14544,6 @@
},
"node_modules/nan": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"optional": true
},
@ -20350,18 +20486,6 @@
"resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.17.tgz",
"integrity": "sha512-WHNHvDCXURn+Qwb3QUUzP6rOxx+3kUZUspREyhkqmXCxFIND99l5z9intTh+uPEt+/EEu7lCaMjSd1uTfuTXfg=="
},
"node_modules/uplot-react": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/uplot-react/-/uplot-react-1.1.1.tgz",
"integrity": "sha512-zCvwyZVm4nfYDi+KjaK0FppqftGzga/x+u0h2baRWj1vXMB9/hfJ1qb9gXAdXMfp17C9Rk57HoZDE9MewNWLfg==",
"engines": {
"node": ">=8.10"
},
"peerDependencies": {
"react": ">=16.8.6",
"uplot": "^1.6.7"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -23552,9 +23676,9 @@
}
},
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
"integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@ -23861,13 +23985,6 @@
"integrity": "sha512-mPQ71plBeFrArvBSHtjWMHXA89IUbZ6kuo2dsjlRC/1uNOybo91spIb+wTu03NxKTl8ut07s0jJ9svF71afpRg==",
"requires": {
"@date-io/core": "^2.11.0"
},
"dependencies": {
"@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
}
}
},
"@date-io/dayjs": {
@ -23884,13 +24001,6 @@
"integrity": "sha512-JUXo01kdPQxLORxqdENrgdUhooKgDUggsNRSdi2BcUhASIY2KGwwWXu8ikVHHGkw+DUF4FOEKGfkQd0RHSvX6g==",
"requires": {
"@date-io/core": "^2.11.0"
},
"dependencies": {
"@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
}
}
},
"@date-io/moment": {
@ -23899,13 +24009,6 @@
"integrity": "sha512-QSL+83qezQ9Ty0dtFgAkk6eC0GMl/lgYfDajeVUDB3zVA2A038hzczRLBg29ifnBGhQMPABxuOafgWwhDjlarg==",
"requires": {
"@date-io/core": "^2.11.0"
},
"dependencies": {
"@date-io/core": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz",
"integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw=="
}
}
},
"@emotion/babel-plugin": {
@ -24652,6 +24755,16 @@
"clsx": "^1.1.1",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/icons-material": {
@ -24660,6 +24773,16 @@
"integrity": "sha512-NvyrVaGKpP4R1yFw8BCnE0QcsQ67RtpgxPr4FtH8q60MDYPuPVczLOn5Ash5CFavoDWur/NfM/4DpT54yf3InA==",
"requires": {
"@babel/runtime": "^7.16.3"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/lab": {
@ -24680,6 +24803,16 @@
"react-is": "^17.0.2",
"react-transition-group": "^4.4.2",
"rifm": "^0.12.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/material": {
@ -24699,6 +24832,16 @@
"prop-types": "^15.7.2",
"react-is": "^17.0.2",
"react-transition-group": "^4.4.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/private-theming": {
@ -24709,6 +24852,16 @@
"@babel/runtime": "^7.16.3",
"@mui/utils": "^5.2.2",
"prop-types": "^15.7.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/styled-engine": {
@ -24719,6 +24872,16 @@
"@babel/runtime": "^7.16.3",
"@emotion/cache": "^11.6.0",
"prop-types": "^15.7.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/styles": {
@ -24743,6 +24906,16 @@
"jss-plugin-rule-value-function": "^10.8.2",
"jss-plugin-vendor-prefixer": "^10.8.2",
"prop-types": "^15.7.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/system": {
@ -24758,6 +24931,16 @@
"clsx": "^1.1.1",
"csstype": "^3.0.10",
"prop-types": "^15.7.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@mui/types": {
@ -24776,6 +24959,16 @@
"@types/react-is": "^16.7.1 || ^17.0.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.16.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz",
"integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"@nodelib/fs.scandir": {
@ -24857,9 +25050,9 @@
}
},
"@popperjs/core": {
"version": "2.10.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
"integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ=="
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ=="
},
"@rollup/plugin-node-resolve": {
"version": "7.1.3",
@ -25241,6 +25434,14 @@
"@types/lodash": "*"
}
},
"@types/lodash.throttle": {
"version": "4.1.6",
"resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.6.tgz",
"integrity": "sha512-/UIH96i/sIRYGC60NoY72jGkCJtFN5KVPhEMMMTjol65effe1gPn0tycJqV5tlSwMTzX8FqzB5yAj0rfGHTPNg==",
"requires": {
"@types/lodash": "*"
}
},
"@types/minimatch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
@ -25416,12 +25617,12 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
},
"@typescript-eslint/eslint-plugin": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz",
"integrity": "sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz",
"integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==",
"requires": {
"@typescript-eslint/experimental-utils": "5.3.0",
"@typescript-eslint/scope-manager": "5.3.0",
"@typescript-eslint/experimental-utils": "5.4.0",
"@typescript-eslint/scope-manager": "5.4.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@ -25431,39 +25632,39 @@
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz",
"integrity": "sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz",
"integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==",
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.3.0",
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/typescript-estree": "5.3.0",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz",
"integrity": "sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz",
"integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==",
"requires": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/visitor-keys": "5.3.0"
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0"
}
},
"@typescript-eslint/types": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.0.tgz",
"integrity": "sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg=="
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz",
"integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA=="
},
"@typescript-eslint/typescript-estree": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz",
"integrity": "sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz",
"integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==",
"requires": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/visitor-keys": "5.3.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@ -25472,18 +25673,18 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz",
"integrity": "sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz",
"integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==",
"requires": {
"@typescript-eslint/types": "5.3.0",
"@typescript-eslint/types": "5.4.0",
"eslint-visitor-keys": "^3.0.0"
}
},
"eslint-visitor-keys": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz",
"integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q=="
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz",
"integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA=="
},
"semver": {
"version": "7.3.5",
@ -26687,8 +26888,6 @@
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
@ -28169,9 +28368,9 @@
}
},
"diff-sequences": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ=="
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
"integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww=="
},
"diffie-hellman": {
"version": "5.0.3",
@ -31474,16 +31673,28 @@
}
},
"jest-diff": {
"version": "27.3.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz",
"integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==",
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.0.tgz",
"integrity": "sha512-fdXgpnyQH4LNSnYgRfHN/g413bqbPspWIAZPlXrdNISehDih1VNDtuRvlzGQJ4Go+fur1HKB2IyI25t6cWi5EA==",
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.3.1",
"pretty-format": "^27.3.1"
"diff-sequences": "^27.4.0",
"jest-get-type": "^27.4.0",
"pretty-format": "^27.4.0"
},
"dependencies": {
"@jest/types": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.0.tgz",
"integrity": "sha512-jIsLdASXMf8GS7P7oGFGwobNse/6Ewq3GBPHoo0i6XRmja+NrUoDqJm4a1ffF2bHGleKJizxokcp1sCqSktP3g==",
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
"@types/yargs": "^16.0.0",
"chalk": "^4.0.0"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@ -31492,6 +31703,24 @@
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"pretty-format": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.0.tgz",
"integrity": "sha512-n0QR6hMREfp6nLzfVksXMAfIxk1ffOOfbb/FzKHFmRtn9iJKaZXB8WMzLr8a72IASShEAhqK06nlwp1gVWgqKg==",
"requires": {
"@jest/types": "^27.4.0",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
},
"dependencies": {
"ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="
}
}
}
}
},
@ -31652,9 +31881,9 @@
}
},
"jest-get-type": {
"version": "27.3.1",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz",
"integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg=="
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
"integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ=="
},
"jest-haste-map": {
"version": "26.6.2",
@ -32884,6 +33113,11 @@
"lodash._reinterpolate": "^3.0.0"
}
},
"lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
},
"lodash.truncate": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
@ -33280,8 +33514,6 @@
},
"nan": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"optional": true
},
"nanoid": {
@ -37985,12 +38217,6 @@
"resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.17.tgz",
"integrity": "sha512-WHNHvDCXURn+Qwb3QUUzP6rOxx+3kUZUspREyhkqmXCxFIND99l5z9intTh+uPEt+/EEu7lCaMjSd1uTfuTXfg=="
},
"uplot-react": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/uplot-react/-/uplot-react-1.1.1.tgz",
"integrity": "sha512-zCvwyZVm4nfYDi+KjaK0FppqftGzga/x+u0h2baRWj1vXMB9/hfJ1qb9gXAdXMfp17C9Rk57HoZDE9MewNWLfg==",
"requires": {}
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

View file

@ -23,6 +23,7 @@
"@types/jest": "^27.0.3",
"@types/lodash.debounce": "^4.0.6",
"@types/lodash.get": "^4.4.6",
"@types/lodash.throttle": "^4.1.6",
"@types/node": "^16.11.10",
"@types/numeral": "^2.0.2",
"@types/qs": "^6.9.7",
@ -33,6 +34,7 @@
"dayjs": "^1.10.7",
"lodash.debounce": "^4.0.8",
"lodash.get": "^4.4.2",
"lodash.throttle": "^4.1.1",
"numeral": "^2.0.6",
"qs": "^6.10.1",
"react": "^17.0.2",
@ -41,7 +43,6 @@
"react-scripts": "4.0.3",
"typescript": "~4.5.2",
"uplot": "^1.6.17",
"uplot-react": "^1.1.1",
"web-vitals": "^2.1.2"
},
"scripts": {
@ -72,7 +73,7 @@
},
"devDependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"customize-cra": "^1.0.0",
"eslint-plugin-react": "^7.27.1",

View file

@ -51,6 +51,13 @@ export const TimeSelector: FC<TimeSelectorProps> = ({setDuration}) => {
setAnchorEl(null);
};
const onKeyUp = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") return;
const target = event.target as HTMLInputElement;
target.blur();
setDurationString(target.value);
};
const open = Boolean(anchorEl);
return <Box m={1} flexDirection="row" display="flex">
@ -59,13 +66,10 @@ export const TimeSelector: FC<TimeSelectorProps> = ({setDuration}) => {
<Box>
<TextField label="Duration" value={durationString} onChange={handleDurationChange}
variant="standard"
fullWidth={true}
onBlur={() => {
setFocused(false);
}}
onFocus={() => {
setFocused(true);
}}
fullWidth={true}
onKeyUp={onKeyUp}
onBlur={() => {setFocused(false);}}
onFocus={() => {setFocused(true);}}
/>
</Box>
<Box my={2}>

View file

@ -3,60 +3,31 @@ import {MetricResult} from "../../../api/types";
import LineChart from "../../LineChart/LineChart";
import {AlignedData as uPlotData, Series as uPlotSeries} from "uplot";
import {Legend, LegendItem} from "../../Legend/Legend";
import {useAppState} from "../../../state/common/StateContext";
import {getNameForMetric} from "../../../utils/metric";
import {getColorFromString} from "../../../utils/color";
import {useGraphDispatch, useGraphState} from "../../../state/graph/GraphStateContext";
import {getHideSeries} from "../../../utils/uPlot";
import {getHideSeries, getLegendItem, getLimitsYAxis, getSeriesItem, getTimeSeries} from "../../../utils/uPlot";
export interface GraphViewProps {
data?: MetricResult[];
}
const GraphView: FC<GraphViewProps> = ({data = []}) => {
const {time: {period}} = useAppState();
const { yaxis } = useGraphState();
const graphDispatch = useGraphDispatch();
const [timeArray, setTimeArray] = useState<number[]>([]);
const [dataChart, setDataChart] = useState<uPlotData>([[]]);
const [series, setSeries] = useState<uPlotSeries[]>([]);
const [legend, setLegend] = useState<LegendItem[]>([]);
const [hideSeries, setHideSeries] = useState<string[]>([]);
const setTimes = (times: number[]) => {
const allTimes = times.sort((a,b) => a-b);
const startTime = allTimes[0] || 0;
const endTime = allTimes[allTimes.length - 1] || 0;
const step = period.step || 1;
const length = Math.round((endTime - startTime) / step);
setTimeArray(new Array(length).fill(0).map((d, i) => startTime + (step * i)));
};
const [valuesLimit, setValuesLimit] = useState<[number, number]>([0, 1]);
const setLimitsYaxis = (values: number[]) => {
if (!yaxis.limits.enable || (yaxis.limits.range.every(item => !item))) {
const allValues = values.flat().sort((a,b) => a-b);
graphDispatch({type: "SET_YAXIS_LIMITS", payload: [allValues[0], allValues[allValues.length - 1]]});
const limits = getLimitsYAxis(values);
setValuesLimit(limits);
graphDispatch({type: "SET_YAXIS_LIMITS", payload: limits});
}
};
const getSeriesItem = (d: MetricResult) => {
const label = getNameForMetric(d);
return {
label,
width: 1.5,
stroke: getColorFromString(label),
show: !hideSeries.includes(label)
};
};
const getLegendItem = (s: uPlotSeries): LegendItem => ({
label: s.label || "",
color: s.stroke as string,
checked: s.show || false
});
const onChangeLegend = (label: string, metaKey: boolean) => {
setHideSeries(getHideSeries({hideSeries, label, metaKey, series}));
};
@ -68,27 +39,34 @@ const GraphView: FC<GraphViewProps> = ({data = []}) => {
const tempSeries: uPlotSeries[] = [];
data?.forEach(d => {
const seriesItem = getSeriesItem(d);
const seriesItem = getSeriesItem(d, hideSeries);
tempSeries.push(seriesItem);
tempLegend.push(getLegendItem(seriesItem));
d.values.forEach(v => {
if (tempTimes.indexOf(v[0]) === -1) tempTimes.push(v[0]);
tempTimes.push(v[0]);
tempValues.push(+v[1]);
});
});
setTimes(tempTimes);
const timeSeries = getTimeSeries(tempTimes);
setDataChart([timeSeries, ...data.map(d => {
return new Array(timeSeries.length).fill(1).map((v, i) => d.values[i] ? +d.values[i][1] : null);
})] as uPlotData);
setLimitsYaxis(tempValues);
setSeries([{}, ...tempSeries]);
setLegend(tempLegend);
const newSeries = [{}, ...tempSeries];
if (JSON.stringify(newSeries) !== JSON.stringify(series)) {
setSeries(newSeries);
setLegend(tempLegend);
}
}, [data]);
useEffect(() => {
const tempLegend: LegendItem[] = [];
const tempSeries: uPlotSeries[] = [];
data?.forEach(d => {
const seriesItem = getSeriesItem(d);
const seriesItem = getSeriesItem(d, hideSeries);
tempSeries.push(seriesItem);
tempLegend.push(getLegendItem(seriesItem));
});
@ -96,17 +74,10 @@ const GraphView: FC<GraphViewProps> = ({data = []}) => {
setLegend(tempLegend);
}, [hideSeries]);
useEffect(() => {
setDataChart([timeArray, ...data.map(d => timeArray.map(t => {
const v = d.values.find(v => v[0] === t);
return v ? +v[1] : null;
}))]);
}, [timeArray]);
return <>
{(data.length > 0)
? <div>
<LineChart data={dataChart} series={series} metrics={data}/>
<LineChart data={dataChart} series={series} metrics={data} limits={valuesLimit}/>
<Legend labels={legend} onChange={onChangeLegend}/>
</div>
: <div style={{textAlign: "center"}}>No data to show</div>}

View file

@ -1,60 +1,63 @@
import React, {FC, useRef, useState} from "react";
import React, {FC, useCallback, useEffect, useRef, useState} from "react";
import {useAppDispatch, useAppState} from "../../state/common/StateContext";
import uPlot, {AlignedData as uPlotData, Options as uPlotOptions, Series as uPlotSeries} from "uplot";
import UplotReact from "uplot-react";
import "uplot/dist/uPlot.min.css";
import numeral from "numeral";
import "./tooltip.css";
import uPlot, {AlignedData as uPlotData, Options as uPlotOptions, Series as uPlotSeries, Range} from "uplot";
import {useGraphState} from "../../state/graph/GraphStateContext";
import {setTooltip } from "../../utils/uPlot";
import {defaultOptions, dragChart, setTooltip} from "../../utils/uPlot";
import {MetricResult} from "../../api/types";
import {limitsDurations} from "../../utils/time";
import throttle from "lodash.throttle";
import "uplot/dist/uPlot.min.css";
import "./tooltip.css";
export interface LineChartProps {
metrics: MetricResult[]
data: uPlotData;
series: uPlotSeries[]
series: uPlotSeries[],
limits: [number, number]
}
const LineChart: FC<LineChartProps> = ({data, series, metrics = []}) => {
enum typeChartUpdate { xRange = "xRange", yRange = "yRange", data = "data" }
const LineChart: FC<LineChartProps> = ({data, series, metrics = [], limits}) => {
const dispatch = useAppDispatch();
const {time: {period}} = useAppState();
const { yaxis } = useGraphState();
const refContainer = useRef<HTMLDivElement>(null);
const [isPanning, setIsPanning] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const uPlotRef = useRef<HTMLDivElement>(null);
const [isPanning, setPanning] = useState(false);
const [zoomPos, setZoomPos] = useState(0);
const tooltipIdx = { seriesIdx: 1, dataIdx: 0 };
const tooltipOffset = { left: 0, top: 0 };
const [xRange, setXRange] = useState({ min: period.start, max: period.end });
const [uPlotInst, setUPlotInst] = useState<uPlot>();
const tooltip = document.createElement("div");
tooltip.className = "u-tooltip";
const tooltipIdx = { seriesIdx: 1, dataIdx: 0 };
const tooltipOffset = { left: 0, top: 0 };
const setScale = ({min, max}: {min: number, max: number}): void => {
dispatch({type: "SET_PERIOD", payload: {from: new Date(min * 1000), to: new Date(max * 1000)}});
};
const throttledSetScale = useCallback(throttle(setScale, 500), []);
const setPlotScale = ({u, min, max}: {u: uPlot, min: number, max: number}) => {
const delta = (max - min) * 1000;
if ((delta < limitsDurations.min) || (delta > limitsDurations.max)) return;
u.setScale("x", {min, max});
setXRange({min, max});
throttledSetScale({min, max});
};
const onReadyChart = (u: uPlot) => {
const factor = 0.85;
tooltipOffset.left = parseFloat(u.over.style.left);
tooltipOffset.top = parseFloat(u.over.style.top);
u.root.querySelector(".u-wrap")?.appendChild(tooltip);
// wheel drag pan
u.over.addEventListener("mousedown", e => {
if (e.button !== 0) return;
setIsPanning(true);
e.preventDefault();
const left0 = e.clientX;
const onmove = (e: MouseEvent) => {
e.preventDefault();
const dx = (u.posToVal(1, "x") - u.posToVal(0, "x")) * (e.clientX - left0);
const min = (u.scales.x.min || 1) - dx;
const max = (u.scales.x.max || 1) - dx;
u.setScale("x", {min, max});
setScale({min, max});
};
const onup = () => {
setIsPanning(false);
document.removeEventListener("mousemove", onmove);
document.removeEventListener("mouseup", onup);
};
document.addEventListener("mousemove", onmove);
document.addEventListener("mouseup", onup);
dragChart({u, e, setPanning, setPlotScale, factor});
});
// wheel scroll zoom
u.over.addEventListener("wheel", e => {
if (!e.ctrlKey && !e.metaKey) return;
@ -66,10 +69,7 @@ const LineChart: FC<LineChartProps> = ({data, series, metrics = []}) => {
const nxRange = e.deltaY < 0 ? oxRange * factor : oxRange / factor;
const min = xVal - (zoomPos/width) * nxRange;
const max = min + nxRange;
u.batch(() => {
u.setScale("x", {min, max});
setScale({min, max});
});
u.batch(() => setPlotScale({u, min, max}));
});
};
@ -89,43 +89,58 @@ const LineChart: FC<LineChartProps> = ({data, series, metrics = []}) => {
: tooltip.style.display = "none";
};
const setScale = ({min, max}: {min: number, max: number}): void => {
dispatch({type: "SET_PERIOD", payload: {from: new Date(min * 1000), to: new Date(max * 1000)}});
const getRangeY = (u: uPlot, min = 0, max = 1): Range.MinMax => {
if (yaxis.limits.enable) return yaxis.limits.range;
return min && max ? [min - (min * 0.05), max + (max * 0.05)] : limits;
};
const getRangeX = (): Range.MinMax => {
return [xRange.min, xRange.max];
};
const options: uPlotOptions = {
width: refContainer.current ? refContainer.current.offsetWidth : 400, height: 500, series: series,
...defaultOptions,
width: containerRef.current ? containerRef.current.offsetWidth : 400,
series,
plugins: [{ hooks: { ready: onReadyChart, setCursor, setSeries: seriesFocus }}],
cursor: {
drag: { x: false, y: false },
focus: { prox: 30 },
bind: {
mouseup: () => null,
mousedown: () => null,
click: () => null,
dblclick: () => null,
mouseenter: () => null,
}
},
legend: { show: false },
axes: [
{ space: 80 },
{ show: true, font: "10px Arial",
values: (self, ticks) => ticks.map(n => n > 1000 ? numeral(n).format("0.0a") : n) }
],
scales: {
x: { range: () => [period.start, period.end] },
y: {
range: (self, min, max) => {
const offsetFactor = 0.05; // 5%
return yaxis.limits.enable ? yaxis.limits.range : [min - (min * offsetFactor), max + (max * offsetFactor)];
}
}
x: { range: getRangeX },
y: { range: getRangeY }
}
};
return <div ref={refContainer} style={{pointerEvents: isPanning ? "none" : "auto", height: "500px"}}>
<UplotReact options={options} data={data}/>
const updateChart = (type: typeChartUpdate): void => {
if (!uPlotInst) return;
switch (type) {
case typeChartUpdate.xRange:
uPlotInst.scales.x.range = getRangeX;
break;
case typeChartUpdate.yRange:
uPlotInst.scales.y.range = getRangeY;
break;
case typeChartUpdate.data:
uPlotInst.setData(data);
break;
}
uPlotInst.redraw();
};
useEffect(() => setXRange({ min: period.start, max: period.end }), [period]);
useEffect(() => {
if (!uPlotRef.current) return;
const u = new uPlot(options, data, uPlotRef.current);
setUPlotInst(u);
setXRange({ min: period.start, max: period.end });
return u.destroy;
}, [uPlotRef.current, series]);
useEffect(() => updateChart(typeChartUpdate.data), [data]);
useEffect(() => updateChart(typeChartUpdate.xRange), [xRange]);
useEffect(() => updateChart(typeChartUpdate.yRange), [yaxis]);
return <div ref={containerRef} style={{pointerEvents: isPanning ? "none" : "auto", height: "500px"}}>
<div ref={uPlotRef}/>
</div>;
};

View file

@ -0,0 +1,17 @@
export const getMaxFromArray = (arr: number[]): number => {
let len = arr.length;
let max = -Infinity;
while (len--) {
if (arr[len] > max) max = arr[len];
}
return max;
};
export const getMinFromArray = (arr: number[]): number => {
let len = arr.length;
let min = Infinity;
while (len--) {
if (arr[len] < min) min = arr[len];
}
return min;
};

View file

@ -1,15 +1,15 @@
import {TimeParams, TimePeriod} from "../types";
import dayjs, {UnitTypeShort} from "dayjs";
import duration from "dayjs/plugin/duration";
import utc from "dayjs/plugin/utc";
import numeral from "numeral";
dayjs.extend(duration);
dayjs.extend(utc);
const MAX_ITEMS_PER_CHART = window.screen.availWidth / 2;
const MAX_ITEMS_PER_CHART = window.innerWidth / 2;
export const limitsDurations = {min: 1000, max: 1.578e+11}; // min: 1 seconds, max: 5 years
export const limitsDurations = {min: 1, max: 1.578e+11}; // min: 1 ms, max: 5 years
export const dateIsoFormat = "YYYY-MM-DD[T]HH:mm:ss";
@ -26,6 +26,8 @@ export const supportedDurations = [
const shortDurations = supportedDurations.map(d => d.short);
export const roundTimeSeconds = (num: number): number => +(numeral(num).format("0.000"));
export const isSupportedDuration = (str: string): Partial<Record<UnitTypeShort, string>> | undefined => {
const digits = str.match(/\d+/g);
@ -57,7 +59,7 @@ export const getTimeperiodForDuration = (dur: string, date?: Date): TimeParams =
}, {});
const delta = dayjs.duration(durObject).asSeconds();
const step = Math.ceil(delta / MAX_ITEMS_PER_CHART);
const step = roundTimeSeconds(delta / MAX_ITEMS_PER_CHART) || 0.001;
return {
start: n - delta,

View file

@ -1,7 +1,12 @@
import uPlot, {Series} from "uplot";
import uPlot, {Series as uPlotSeries, Series} from "uplot";
import {getColorFromString} from "./color";
import dayjs from "dayjs";
import {MetricResult} from "../api/types";
import {LegendItem} from "../components/Legend/Legend";
import {getNameForMetric} from "./metric";
import {getMaxFromArray, getMinFromArray} from "./math";
import {roundTimeSeconds} from "./time";
import numeral from "numeral";
interface SetupTooltip {
u: uPlot,
@ -19,6 +24,34 @@ interface HideSeriesArgs {
series: Series[]
}
interface DragArgs {
e: MouseEvent,
u: uPlot,
factor: number,
setPanning: (enable: boolean) => void,
setPlotScale: ({u, min, max}: {u: uPlot, min: number, max: number}) => void
}
const stub = (): null => null;
export const defaultOptions = {
height: 500,
legend: { show: false },
axes: [
{ space: 80 },
{
show: true,
font: "10px Arial",
values: (self: uPlot, ticks: number[]): (string | number)[] => ticks.map(n => n > 1000 ? numeral(n).format("0.0a") : n)
}
],
cursor: {
drag: { x: false, y: false },
focus: { prox: 30 },
bind: { mouseup: stub, mousedown: stub, click: stub, dblclick: stub, mouseenter: stub }
},
};
export const setTooltip = ({ u, tooltipIdx, metrics, series, tooltip, tooltipOffset }: SetupTooltip) : void => {
const {seriesIdx, dataIdx} = tooltipIdx;
const dataSeries = u.data[seriesIdx][dataIdx];
@ -55,4 +88,60 @@ export const getHideSeries = ({hideSeries, label, metaKey, series}: HideSeriesAr
return hideSeries.length === series.length - 2 ? [] : [...labels.filter(l => l !== label)];
}
return include ? hideSeries.filter(l => l !== label) : [...hideSeries, label];
};
export const getTimeSeries = (times: number[]): number[] => {
const allTimes = Array.from(new Set(times)).sort((a,b) => a-b);
const step = getMinFromArray(allTimes.map((t, i) => allTimes[i + 1] - t));
const length = allTimes.length;
const startTime = allTimes[0] || 0;
return new Array(length).fill(startTime).map((d, i) => roundTimeSeconds(d + (step * i)));
};
export const getLimitsYAxis = (values: number[]): [number, number] => {
const min = getMinFromArray(values);
const max = getMaxFromArray(values);
return [min - (min * 0.05), max + (max * 0.05)];
};
export const getSeriesItem = (d: MetricResult, hideSeries: string[]): Series => {
const label = getNameForMetric(d);
return {
label,
width: 1.5,
stroke: getColorFromString(label),
show: !hideSeries.includes(label),
scale: "y"
};
};
export const getLegendItem = (s: uPlotSeries): LegendItem => ({
label: s.label || "",
color: s.stroke as string,
checked: s.show || false
});
export const dragChart = ({e, factor = 0.85, u, setPanning, setPlotScale}: DragArgs): void => {
if (e.button !== 0) return;
e.preventDefault();
setPanning(true);
const leftStart = e.clientX;
const xUnitsPerPx = u.posToVal(1, "x") - u.posToVal(0, "x");
const scXMin = u.scales.x.min || 0;
const scXMax = u.scales.x.max || 0;
const mouseMove = (e: MouseEvent) => {
e.preventDefault();
const dx = xUnitsPerPx * ((e.clientX - leftStart) * factor);
setPlotScale({u, min: scXMin - dx, max: scXMax - dx});
};
const mouseUp = () => {
setPanning(false);
document.removeEventListener("mousemove", mouseMove);
document.removeEventListener("mouseup", mouseUp);
};
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);
};