@perses-dev/stat-chart-plugin 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mf/js/{435.f40076fc.js → 435.0060dd2f.js} +1 -1
- package/__mf/js/{StatChart.b0400032.js → StatChart.3d66ae68.js} +3 -3
- package/__mf/js/async/{877.0e870142.js → 236.f47b54b8.js} +1 -1
- package/__mf/js/async/331.faa6f9eb.js +2 -0
- package/__mf/js/async/{870.3ed3413d.js.LICENSE.txt → 331.faa6f9eb.js.LICENSE.txt} +1 -39
- package/__mf/js/async/360.e3f25d30.js +29 -0
- package/__mf/js/async/360.e3f25d30.js.LICENSE.txt +37 -0
- package/__mf/js/async/{610.dad41cbd.js → 610.e2fe79a3.js} +1 -1
- package/__mf/js/async/83.0215bc58.js +1 -0
- package/__mf/js/async/{318.98a6e364.js → 90.defedb11.js} +10 -10
- package/__mf/js/async/954.f8bb1788.js +2 -0
- package/__mf/js/async/__federation_expose_StatChart.60147471.js +1 -0
- package/__mf/js/main.0ffda506.js +1 -0
- package/lib/StatChartBase.d.ts +20 -0
- package/lib/StatChartBase.d.ts.map +1 -0
- package/lib/StatChartBase.js +189 -0
- package/lib/StatChartBase.js.map +1 -0
- package/lib/StatChartPanel.d.ts.map +1 -1
- package/lib/StatChartPanel.js +3 -2
- package/lib/StatChartPanel.js.map +1 -1
- package/lib/cjs/StatChartBase.js +202 -0
- package/lib/cjs/StatChartPanel.js +2 -1
- package/lib/cjs/index.js +13 -0
- package/lib/cjs/utils/calculate-font-size.js +55 -0
- package/lib/cjs/utils/format-stat-chart-value.js +34 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +13 -0
- package/lib/index.js.map +1 -1
- package/lib/utils/calculate-font-size.d.ts +16 -0
- package/lib/utils/calculate-font-size.d.ts.map +1 -0
- package/lib/utils/calculate-font-size.js +49 -0
- package/lib/utils/calculate-font-size.js.map +1 -0
- package/lib/utils/format-stat-chart-value.d.ts +3 -0
- package/lib/utils/format-stat-chart-value.d.ts.map +1 -0
- package/lib/utils/format-stat-chart-value.js +26 -0
- package/lib/utils/format-stat-chart-value.js.map +1 -0
- package/mf-manifest.json +17 -15
- package/mf-stats.json +17 -15
- package/package.json +1 -1
- package/__mf/js/async/298.0f019169.js +0 -1
- package/__mf/js/async/870.3ed3413d.js +0 -29
- package/__mf/js/async/996.7e490e79.js +0 -2
- package/__mf/js/async/__federation_expose_StatChart.0d43d15e.js +0 -1
- package/__mf/js/main.628b2309.js +0 -1
- /package/__mf/js/async/{318.98a6e364.js.LICENSE.txt → 90.defedb11.js.LICENSE.txt} +0 -0
- /package/__mf/js/async/{996.7e490e79.js.LICENSE.txt → 954.f8bb1788.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkStatChart=self.webpackChunkStatChart||[]).push([["29"],{14046:function(e,t,n){n.d(t,{K2:()=>l,c7:()=>r,gO:()=>i});let l="last",r={first:function(e){return a(e,"first")},last:function(e){return a(e,"last")},"first-number":function(e){return a(e,"first-number")},"last-number":function(e){return a(e,"last-number")},mean:function(e){return a(e,"mean")},sum:function(e){return a(e,"sum")},min:function(e){return a(e,"min")},max:function(e){return a(e,"max")}},i={first:{label:"First",description:"First value"},last:{label:"Last",description:"Last value"},"first-number":{label:"First *",description:"First numeric value"},"last-number":{label:"Last *",description:"Last numeric value"},mean:{label:"Avg",description:"Average value excluding nulls"},sum:{label:"Sum",description:"The sum of all values"},min:{label:"Min",description:"Minimum value"},max:{label:"Max",description:"Maximum value"}};function a(e,t){return function(e,t){let n=t.reduce((e,t)=>(e[t]=void 0,e),{}),l=0,r=0;return e.forEach((t,i)=>{let a=t[1];0===i&&"first"in n&&(n.first=a),i===e.length-1&&"last"in n&&(n.last=a),"number"==typeof a&&(l+=1,r+=a,"first-number"in n&&void 0===n["first-number"]&&(n["first-number"]=a),"last-number"in n&&(n["last-number"]=a),"min"in n&&("number"!=typeof n.min?n.min=a:n.min=Math.min(n.min,a)),"max"in n&&("number"!=typeof n.max?n.max=a:n.max=Math.max(n.max,a)))}),l>0&&"sum"in n&&(n.sum=r),l>0&&"mean"in n&&(n.mean=r/l),n}(e,[t])[t]}},61033:function(e,t,n){let l;n.r(t),n.d(t,{StatChart:()=>I});var r=n(24246),i=n(83941),a=n(87895),o=n(27463),u=n(75586),s=n(15409),c=n.n(s);let d={unit:"percent-decimal"};var h=n(25283),m=n(52054),f=n(54538);function p(e){if(!e)throw Error("Input string cannot be empty");if(!e?.startsWith("/"))return RegExp(`^${e}$`);let t=e.match(/^\/(.+)\/([gimy]*)$/);if(!t)throw Error(`Invalid regular expression format: ${e}`);let[,n="",l=""]=t;try{return new RegExp(n,l)}catch(e){throw Error(`Failed to create RegExp ${e}`)}}function v(e,t=[]){if(!t.length)return{value:e};let n={value:e};return t.forEach(t=>{switch(t.kind){case"Value":{let l=t.spec;String(l.value)===String(e)&&(n.value=l.result.value||n.value,n.color=l.result.color);break}case"Range":{let l=t.spec;if(void 0===l.from&&void 0===l.to)break;let r=void 0!==l.from?l.from:-1/0,i=void 0!==l.to?l.to:1/0;e>=r&&e<=i&&(n.value=l.result.value||n.value,n.color=l.result.color);break}case"Regex":{let l=t.spec,r=e.toString();if(!l.pattern)break;let i=p(l.pattern);r.match(i)&&null!==l.result.value&&(n.value=r.replace(i,l.result.value.toString()||"")||n.value,n.color=l.result.color);break}case"Misc":{let l=t.spec;(function(e,t){switch(e){case"empty":return""===t;case"null":return null==t;case"NaN":return Number.isNaN(t);case"true":return!0===t;case"false":return!1===t;default:return!1}})(l.value,e)&&(n.value=l.result.value||n.value,n.color=l.result.color)}}}),n}var g=n(14046);let x=(e,t)=>(void 0===g.c7[e]&&console.warn(`Invalid StatChart panel calculation ${e}, fallback to ${g.K2}`),(g.c7[e]??g.c7[g.K2])(t.values));var b=n(36372),w=n(12709),y=n(36232),S=n(44811),C=n(65201),j=n(99635),k=n(23709),E=n(67745),M=n(50378);function $(e){let{text:t,fontWeight:n,width:r,height:a,lineHeight:o,maxSize:u,fontSizeOverride:s}=e,c=function(){if(!l&&null===(l=document.createElement("canvas").getContext("2d")))throw Error("Canvas context is null.");return l}(),{echartsTheme:d}=(0,i.useChartsTheme)();if(void 0!==s)return Number(s);let h=d.textStyle,m=Number(null==h?void 0:h.fontSize)??12,f=(null==h?void 0:h.fontFamily)??"Lato",p=`${n} ${m}px ${f}`;c.font=p;let v=Math.min(a/o,r/c.measureText(t).width*m);return u?Math.min(v,u):v}var N=n(74664);let z=(e,t)=>null===e?"null":"number"==typeof e?(0,N.Bw)(e,t):void 0===e?"":e;(0,y.D)([S.N,C.N,j.N,k.N,E.N,M.N]);let F=e=>{var t,n;let{width:l,height:a,data:o,sparkline:u,showSeriesName:s,format:d,valueFontSize:h}=e,m=(0,i.useChartsTheme)(),p=o.color,v=z(o.calculatedValue,d),g=m.container.padding.default,x=$({text:(null==o?void 0:null===(t=o.seriesData)||void 0===t?void 0:t.name)??"",fontWeight:400,width:l,height:.125*a,lineHeight:1.2,maxSize:30}),w=s?1.2*x+g:0,y=l-2*g,S=a-w,C=$({text:v,fontSizeOverride:h,fontWeight:700,width:u?y:.5*y,height:u?.25*S:.9*S,lineHeight:1.2}),j=1.2*C;x=Math.min(.7*C,x);let k=(0,f.useMemo)(()=>{if(void 0===o.seriesData)return m.noDataOption;let e=o.seriesData,t=[];if(void 0!==u){let n={type:"line",name:e.name,data:e.values,zlevel:1,symbol:"none",animation:!1,silent:!0},l=c()(n,u);t.push(l)}return{title:{show:!1},grid:{show:!1,top:"35%",right:0,bottom:0,left:0,containLabel:!1},xAxis:{type:"time",show:!1,boundaryGap:!1},yAxis:{type:"value",show:!1,min:e=>e.min>=0&&e.min<=1?0:e.min},tooltip:{show:!1},series:t}},[o,m,u]),E=u?"auto":"center";return(0,r.jsxs)(b.Z,{sx:{height:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:E,alignItems:E},children:[s&&(0,r.jsx)(O,{padding:g,fontSize:x,children:null===(n=o.seriesData)||void 0===n?void 0:n.name}),(0,r.jsx)(D,{variant:"h3",color:p,fontSize:C,padding:g,children:v}),void 0!==u&&(0,r.jsx)(i.EChart,{sx:{width:"100%"},style:{height:Math.floor(a-w-j)},option:k,theme:m.echartsTheme,renderer:"svg"})]})},O=(0,w.ZP)(m.Z,{shouldForwardProp:e=>"padding"!==e&&"fontSize"!==e})(e=>{let{theme:t,padding:n,fontSize:l}=e;return{color:t.palette.text.secondary,padding:`${n}px`,fontSize:`${l}px`,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),D=(0,w.ZP)(m.Z,{shouldForwardProp:e=>"color"!==e&&"padding"!==e&&"fontSize"!==e&&"sparkline"!==e})(e=>{let{theme:t,color:n,padding:l,fontSize:r,sparkline:i}=e;return{color:n??t.palette.text.primary,fontSize:`${r}px`,padding:i?`${l}px ${l}px 0 ${l}px`:` 0 ${l}px`,whiteSpace:"nowrap",lineHeight:1.2}}),L=(e,t,n)=>(0,f.useMemo)(()=>{let{calculation:l,mappings:r,metricLabel:i}=t,a=[];for(let o of e)for(let e of o.data.series){let o=x(l,e),u=T(o,r,Z(i,e.labels)),s=function(e,t,n){let{mappings:l,thresholds:r}=t??{},i=(null==r?void 0:r.defaultColor)??e.thresholds.defaultColor;if(!n||!(null==r?void 0:r.steps)&&!l)return i;if(null==l?void 0:l.length){let e=function(e,t){if((null==t?void 0:t.length)&&e){let{color:n}=v(e,t);return n||null}return null}(n,l);if(e)return e}if(r){let t=function(e,t,n,l){if((null==t?void 0:t.steps)&&"number"==typeof e){let r=t.steps.map((t,r)=>e>=t.value?t.color??n.thresholds.palette[r]??l:null).filter(e=>null!==e);return r[r.length-1]??null}return null}(n,r,e,i);if(t)return t}return i}(n,t,o),c={name:e.formattedName??"",values:e.values};a.push({calculatedValue:u,seriesData:c,color:s})}return a},[e,t,n]),T=(e,t,n)=>n||((null==t?void 0:t.length)&&null!=e?v(e,t).value:e),Z=(e,t)=>{if(t&&e){for(let[n,l]of Object.entries(t))if(p(e).test(n))return l}},I={PanelComponent:e=>{let{spec:t,contentDimensions:n,queryResults:l}=e,{format:a,sparkline:o,valueFontSize:u}=t,s=(0,i.useChartsTheme)(),c=L(l,t,s),d=c.length>1;if(void 0===n)return null;let f=2*(c.length-1),p=(n.width-f)/c.length;d&&p<100&&(p=100);let v=s.noDataOption.title.textStyle;return(0,r.jsx)(h.Z,{height:n.height,width:n.width,spacing:"2px",direction:"row",justifyContent:d?"left":"center",alignItems:"center",sx:{overflowX:d?"scroll":"auto"},children:c.length?c.map((e,t)=>{let l=function(e,t,n){if(void 0!==n)return{lineStyle:{width:n.width??e.sparkline.width,color:t,opacity:1},areaStyle:{color:t,opacity:.4}}}(s,e.color,o);return(0,r.jsx)(F,{width:p,height:n.height,data:e,format:a,sparkline:l,showSeriesName:d,valueFontSize:u},t)}):(0,r.jsx)(m.Z,{sx:{...v},children:"No data"})})},supportedQueryTypes:["TimeSeriesQuery"],panelOptionsEditorComponents:[{label:"Settings",content:function(e){let{onChange:t,value:n}=e,l=c()({},d,n.format);return(0,r.jsxs)(i.OptionsEditorGrid,{children:[(0,r.jsx)(i.OptionsEditorColumn,{children:(0,r.jsxs)(i.OptionsEditorGroup,{title:"Misc",children:[(0,r.jsx)(i.OptionsEditorControl,{label:"Sparkline",control:(0,r.jsx)(a.Z,{checked:!!n.sparkline,onChange:(e,l)=>{t((0,u.Uy)(n,e=>{e.sparkline=l?{}:void 0}))}})}),(0,r.jsx)(i.FormatControls,{value:l,onChange:e=>{t((0,u.Uy)(n,t=>{t.format=e}))}}),(0,r.jsx)(o.CalculationSelector,{value:n.calculation,onChange:e=>{t((0,u.Uy)(n,t=>{t.calculation=e}))}}),(0,r.jsx)(o.MetricLabelInput,{value:n.metricLabel,onChange:e=>{t((0,u.Uy)(n,t=>{t.metricLabel=e}))}}),(0,r.jsx)(i.FontSizeSelector,{value:n.valueFontSize,onChange:e=>{t((0,u.Uy)(n,t=>{t.valueFontSize=e}))}})]})}),(0,r.jsx)(i.OptionsEditorColumn,{children:(0,r.jsx)(i.ThresholdsEditor,{disablePercentMode:!0,thresholds:n.thresholds,onChange:e=>{t((0,u.Uy)(n,t=>{t.thresholds=e}))}})})]})}},{label:"Value mapping",content:e=>{let{onChange:t,value:n}=e;return(0,r.jsx)(i.ValueMappingsEditor,{mappings:n.mappings??[],onChange:function(e){t({...n,mappings:e})}})}}],createInitialOptions:function(){return{calculation:"last-number",format:{unit:"decimal"},sparkline:{}}}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{var e={5311:function(e,r,t){Promise.all([t.e("677"),t.e("179"),t.e("620")]).then(t.bind(t,29161))}},r={};function t(n){var o=r[n];if(void 0!==o)return o.exports;var a=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}t.m=e,t.c=r,t.federation||(t.federation={chunkMatcher:function(e){return!/^(1(57|61|79)|23|263|494|677|759|946)$/.test(e)}}),t.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return t.d(r,{a:r}),r},t.d=(e,r)=>{for(var n in r)t.o(r,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce((r,n)=>(t.f[n](e,r),r),[])),t.u=e=>"__mf/js/async/"+("118"===e?"lib-router":e)+"."+({118:"3a3f0205",162:"6eaaf026",173:"b6c742e7",214:"60d550e8",224:"978cad14",236:"f47b54b8",238:"6c65e7fc",292:"4573cfd2",331:"faa6f9eb",360:"e3f25d30",610:"e2fe79a3",620:"415051b8",651:"4eb924e1",656:"dbf72cfa",694:"5088b7d2",738:"5905ca00",740:"6ca05ea5",75:"fb6da1e8",770:"0eef8b15",83:"0215bc58",90:"defedb11",954:"f8bb1788",960:"b6b50cb1",964:"f3efac0a",981:"0942fcbb"})[e]+".js",t.miniCssF=e=>"__mf/css/async/"+e+"."+({263:"1ed8bb01",759:"1ed8bb01"})[e]+".css",t.h=()=>"337be35138bdf307",(()=>{t.g=(()=>{if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}})()})(),t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={},r="StatChart:";t.l=function(n,o,a,i){if(e[n]){e[n].push(o);return}if(void 0!==a)for(var s,l,d=document.getElementsByTagName("script"),c=0;c<d.length;c++){var u=d[c];if(u.getAttribute("src")==n||u.getAttribute("data-webpack")==r+a){s=u;break}}s||(l=!0,(s=document.createElement("script")).charset="utf-8",s.timeout=120,t.nc&&s.setAttribute("nonce",t.nc),s.setAttribute("data-webpack",r+a),s.src=n),e[n]=[o];var f=function(r,t){s.onerror=s.onload=null,clearTimeout(h);var o=e[n];if(delete e[n],s.parentNode&&s.parentNode.removeChild(s),o&&o.forEach(function(e){return e(t)}),r)return r(t)},h=setTimeout(f.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=f.bind(null,s.onerror),s.onload=f.bind(null,s.onload),l&&document.head.appendChild(s)}})(),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),t.nc=void 0,(()=>{var e=[];t.O=(r,n,o,a)=>{if(n){a=a||0;for(var i=e.length;i>0&&e[i-1][2]>a;i--)e[i]=e[i-1];e[i]=[n,o,a];return}for(var s=1/0,i=0;i<e.length;i++){for(var[n,o,a]=e[i],l=!0,d=0;d<n.length;d++)(!1&a||s>=a)&&Object.keys(t.O).every(e=>t.O[e](n[d]))?n.splice(d--,1):(l=!1,a<s&&(s=a));if(l){e.splice(i--,1);var c=o();void 0!==c&&(r=c)}}return r}})(),t.p="/plugins/StatChart/",t.rv=()=>"1.2.8",t.j="909",t.S={},t.initializeSharingData={scopeToSharingDataMapping:{default:[{name:"@emotion/react",version:"11.14.0",factory:()=>Promise.all([t.e("960"),t.e("677"),t.e("651")]).then(()=>()=>t(96434)),eager:0,singleton:1,requiredVersion:"^11.11.3"},{name:"@emotion/styled",version:"11.14.0",factory:()=>Promise.all([t.e("677"),t.e("157"),t.e("694")]).then(()=>()=>t(51958)),eager:0,singleton:1},{name:"@hookform/resolvers",version:"3.10.0",factory:()=>Promise.all([t.e("292"),t.e("677"),t.e("214")]).then(()=>()=>t(81228)),eager:0,singleton:1},{name:"@perses-dev/components",version:"0.51.0-beta.1",factory:()=>Promise.all([t.e("238"),t.e("224"),t.e("292"),t.e("954"),t.e("236"),t.e("83"),t.e("360"),t.e("90"),t.e("331"),t.e("677"),t.e("179"),t.e("161"),t.e("157"),t.e("946"),t.e("759")]).then(()=>()=>t(13425)),eager:0,singleton:1},{name:"@perses-dev/plugin-system",version:"0.51.0-beta.1",factory:()=>Promise.all([t.e("118"),t.e("292"),t.e("236"),t.e("90"),t.e("162"),t.e("677"),t.e("179"),t.e("161"),t.e("157"),t.e("946"),t.e("23"),t.e("656")]).then(()=>()=>t(57910)),eager:0,singleton:1},{name:"date-fns",version:"4.1.0",factory:()=>Promise.all([t.e("238"),t.e("224"),t.e("75")]).then(()=>()=>t(99657)),eager:0,singleton:1},{name:"echarts",version:"5.5.0",factory:()=>Promise.all([t.e("954"),t.e("83"),t.e("610")]).then(()=>()=>t(2138)),eager:0,singleton:1},{name:"lodash",version:"4.17.21",factory:()=>t.e("981").then(()=>()=>t(98784)),eager:0,singleton:1},{name:"react-dom",version:"18.3.1",factory:()=>Promise.all([t.e("173"),t.e("677")]).then(()=>()=>t(31542)),eager:0,singleton:1,requiredVersion:"18.2.0"},{name:"react",version:"18.3.1",factory:()=>t.e("964").then(()=>()=>t(27378)),eager:0,singleton:1,requiredVersion:"18.2.0"}]},uniqueName:"StatChart"},t.I=t.I||function(){throw Error("should have __webpack_require__.I")},t.consumesLoadingData={chunkMapping:{161:["4665","20461"],494:["57871"],946:["45913"],179:["6085"],157:["72116"],23:["84275","74614","30156","3553","55922","57751","68393"],677:["54538"]},moduleIdToConsumeDataMapping:{45913:{shareScope:"default",shareKey:"@emotion/styled",import:"@emotion/styled",requiredVersion:"^11.3.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("770").then(()=>()=>t(51958))},57751:{shareScope:"default",shareKey:"@perses-dev/plugin-system",import:"@perses-dev/plugin-system",requiredVersion:"*",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>()=>t(57910)},68393:{shareScope:"default",shareKey:"@perses-dev/components",import:"@perses-dev/components",requiredVersion:"0.51.0-beta.1",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>Promise.all([t.e("238"),t.e("224"),t.e("954"),t.e("83"),t.e("360"),t.e("331"),t.e("263")]).then(()=>()=>t(13425))},30156:{shareScope:"default",shareKey:"echarts",import:"echarts",requiredVersion:"*",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>Promise.all([t.e("954"),t.e("83"),t.e("610")]).then(()=>()=>t(2138))},6085:{shareScope:"default",shareKey:"react-dom",import:"react-dom",requiredVersion:"18.2.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("173").then(()=>()=>t(31542))},72116:{shareScope:"default",shareKey:"@emotion/react",import:"@emotion/react",requiredVersion:"^11.11.3",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("960").then(()=>()=>t(96434))},57871:{shareScope:"default",shareKey:"date-fns",import:"date-fns",requiredVersion:"^3.0.0 || ^4.0.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>Promise.all([t.e("238"),t.e("75")]).then(()=>()=>t(99657))},84275:{shareScope:"default",shareKey:"@hookform/resolvers",import:"@hookform/resolvers",requiredVersion:"^2.0.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("738").then(()=>()=>t(81228))},74614:{shareScope:"default",shareKey:"lodash",import:"lodash",requiredVersion:"*",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("981").then(()=>()=>t(98784))},4665:{shareScope:"default",shareKey:"date-fns-tz",import:"date-fns-tz",requiredVersion:"^3.2.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>Promise.all([t.e("224"),t.e("740"),t.e("494")]).then(()=>()=>t(48872))},54538:{shareScope:"default",shareKey:"react",import:"react",requiredVersion:"18.2.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("964").then(()=>()=>t(27378))},3553:{shareScope:"default",shareKey:"@perses-dev/plugin-system",import:"@perses-dev/plugin-system",requiredVersion:"0.51.0-beta.1",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>()=>t(57910)},55922:{shareScope:"default",shareKey:"@emotion/styled",import:"@emotion/styled",requiredVersion:"*",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>t.e("770").then(()=>()=>t(51958))},20461:{shareScope:"default",shareKey:"date-fns",import:"date-fns",requiredVersion:"^4.1.0",strictVersion:!1,singleton:!0,eager:!1,fallback:()=>Promise.all([t.e("238"),t.e("224"),t.e("75")]).then(()=>()=>t(99657))}},initialConsumes:[]},t.f.consumes=t.f.consumes||function(){throw Error("should have __webpack_require__.f.consumes")},(()=>{if("undefined"!=typeof document){var e=function(e,r,n,o,a){var i=document.createElement("link");return i.rel="stylesheet",i.type="text/css",t.nc&&(i.nonce=t.nc),i.onerror=i.onload=function(t){if(i.onerror=i.onload=null,"load"===t.type)o();else{var n=t&&("load"===t.type?"missing":t.type),s=t&&t.target&&t.target.href||r,l=Error("Loading CSS chunk "+e+" failed.\\n("+s+")");l.code="CSS_CHUNK_LOAD_FAILED",l.type=n,l.request=s,i.parentNode&&i.parentNode.removeChild(i),a(l)}},i.href=r,n?n.parentNode.insertBefore(i,n.nextSibling):document.head.appendChild(i),i},r=function(e,r){for(var t=document.getElementsByTagName("link"),n=0;n<t.length;n++){var o=t[n],a=o.getAttribute("data-href")||o.getAttribute("href");if("stylesheet"===o.rel&&(a===e||a===r))return o}for(var i=document.getElementsByTagName("style"),n=0;n<i.length;n++){var o=i[n],a=o.getAttribute("data-href");if(a===e||a===r)return o}},n={909:0};t.f.miniCss=function(o,a){if(n[o])a.push(n[o]);else if(0!==n[o]&&({263:1,759:1})[o])a.push(n[o]=new Promise(function(n,a){var i=t.miniCssF(o),s=t.p+i;if(r(i,s))return n();e(o,s,null,n,a)}).then(function(){n[o]=0},function(e){throw delete n[o],e}))}}})(),(()=>{var e={909:0};t.f.j=function(r,n){var o=t.o(e,r)?e[r]:void 0;if(0!==o){if(o)n.push(o[2]);else if(/^(1(57|61|79)|23|263|494|677|759|946)$/.test(r))e[r]=0;else{var a=new Promise((t,n)=>o=e[r]=[t,n]);n.push(o[2]=a);var i=t.p+t.u(r),s=Error();t.l(i,function(n){if(t.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var a=n&&("load"===n.type?"missing":n.type),i=n&&n.target&&n.target.src;s.message="Loading chunk "+r+" failed.\n("+a+": "+i+")",s.name="ChunkLoadError",s.type=a,s.request=i,o[1](s)}},"chunk-"+r,r)}}},t.O.j=r=>0===e[r];var r=(r,n)=>{var o,a,[i,s,l]=n,d=0;if(i.some(r=>0!==e[r])){for(o in s)t.o(s,o)&&(t.m[o]=s[o]);if(l)var c=l(t)}for(r&&r(n);d<i.length;d++)a=i[d],t.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return t.O(c)},n=self.webpackChunkStatChart=self.webpackChunkStatChart||[];n.forEach(r.bind(null,0)),n.push=r.bind(null,n.push.bind(n))})(),t.ruid="bundler=rspack@1.2.8",t.O(void 0,["435"],function(){return t(82837)});var n=t.O(void 0,["435"],function(){return t(5311)});n=t.O(n)})();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { FormatOptions } from '@perses-dev/core';
|
|
3
|
+
import { LineSeriesOption } from 'echarts/charts';
|
|
4
|
+
import { FontSizeOption, GraphSeries } from '@perses-dev/components';
|
|
5
|
+
export interface StatChartData {
|
|
6
|
+
color: string;
|
|
7
|
+
calculatedValue?: string | number | null;
|
|
8
|
+
seriesData?: GraphSeries;
|
|
9
|
+
}
|
|
10
|
+
export interface StatChartProps {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
data: StatChartData;
|
|
14
|
+
format?: FormatOptions;
|
|
15
|
+
sparkline?: LineSeriesOption;
|
|
16
|
+
showSeriesName?: boolean;
|
|
17
|
+
valueFontSize?: FontSizeOption;
|
|
18
|
+
}
|
|
19
|
+
export declare const StatChartBase: FC<StatChartProps>;
|
|
20
|
+
//# sourceMappingURL=StatChartBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatChartBase.d.ts","sourceRoot":"","sources":["../../src/StatChartBase.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,EAAE,EAAW,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,OAAO,EAAiC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGjF,OAAO,EAAU,cAAc,EAAE,WAAW,EAAkB,MAAM,wBAAwB,CAAC;AAW7F,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,cAAc,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,cAAc,CAsI5C,CAAC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Copyright 2023 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { useMemo } from 'react';
|
|
15
|
+
import { Box, Typography, styled } from '@mui/material';
|
|
16
|
+
import merge from 'lodash/merge';
|
|
17
|
+
import { use } from 'echarts/core';
|
|
18
|
+
import { LineChart as EChartsLineChart } from 'echarts/charts';
|
|
19
|
+
import { GridComponent, DatasetComponent, TitleComponent, TooltipComponent } from 'echarts/components';
|
|
20
|
+
import { CanvasRenderer } from 'echarts/renderers';
|
|
21
|
+
import { EChart, useChartsTheme } from '@perses-dev/components';
|
|
22
|
+
import { useOptimalFontSize } from './utils/calculate-font-size';
|
|
23
|
+
import { formatStatChartValue } from './utils/format-stat-chart-value';
|
|
24
|
+
use([
|
|
25
|
+
EChartsLineChart,
|
|
26
|
+
GridComponent,
|
|
27
|
+
DatasetComponent,
|
|
28
|
+
TitleComponent,
|
|
29
|
+
TooltipComponent,
|
|
30
|
+
CanvasRenderer
|
|
31
|
+
]);
|
|
32
|
+
const LINE_HEIGHT = 1.2;
|
|
33
|
+
const SERIES_NAME_MAX_FONT_SIZE = 30;
|
|
34
|
+
const SERIES_NAME_FONT_WEIGHT = 400;
|
|
35
|
+
const VALUE_FONT_WEIGHT = 700;
|
|
36
|
+
export const StatChartBase = (props)=>{
|
|
37
|
+
const { width, height, data, sparkline, showSeriesName, format, valueFontSize } = props;
|
|
38
|
+
const chartsTheme = useChartsTheme();
|
|
39
|
+
const color = data.color;
|
|
40
|
+
const formattedValue = formatStatChartValue(data.calculatedValue, format);
|
|
41
|
+
const containerPadding = chartsTheme.container.padding.default;
|
|
42
|
+
// calculate series name font size and height
|
|
43
|
+
let seriesNameFontSize = useOptimalFontSize({
|
|
44
|
+
text: data?.seriesData?.name ?? '',
|
|
45
|
+
fontWeight: SERIES_NAME_FONT_WEIGHT,
|
|
46
|
+
width,
|
|
47
|
+
height: height * 0.125,
|
|
48
|
+
lineHeight: LINE_HEIGHT,
|
|
49
|
+
maxSize: SERIES_NAME_MAX_FONT_SIZE
|
|
50
|
+
});
|
|
51
|
+
const seriesNameHeight = showSeriesName ? seriesNameFontSize * LINE_HEIGHT + containerPadding : 0;
|
|
52
|
+
// calculate value font size and height
|
|
53
|
+
const availableWidth = width - containerPadding * 2;
|
|
54
|
+
const availableHeight = height - seriesNameHeight;
|
|
55
|
+
const optimalValueFontSize = useOptimalFontSize({
|
|
56
|
+
text: formattedValue,
|
|
57
|
+
// override the font size if user selects it in the settings
|
|
58
|
+
fontSizeOverride: valueFontSize,
|
|
59
|
+
fontWeight: VALUE_FONT_WEIGHT,
|
|
60
|
+
// without sparkline, use only 50% of the available width so it looks better for multiseries
|
|
61
|
+
width: sparkline ? availableWidth : availableWidth * 0.5,
|
|
62
|
+
// with sparkline, use only 25% of available height to leave room for chart
|
|
63
|
+
// without sparkline, value should take up 90% of available space
|
|
64
|
+
height: sparkline ? availableHeight * 0.25 : availableHeight * 0.9,
|
|
65
|
+
lineHeight: LINE_HEIGHT
|
|
66
|
+
});
|
|
67
|
+
const valueFontHeight = optimalValueFontSize * LINE_HEIGHT;
|
|
68
|
+
// make sure the series name font size is slightly smaller than value font size
|
|
69
|
+
seriesNameFontSize = Math.min(optimalValueFontSize * 0.7, seriesNameFontSize);
|
|
70
|
+
const option = useMemo(()=>{
|
|
71
|
+
if (data.seriesData === undefined) return chartsTheme.noDataOption;
|
|
72
|
+
const series = data.seriesData;
|
|
73
|
+
const statSeries = [];
|
|
74
|
+
if (sparkline !== undefined) {
|
|
75
|
+
const lineSeries = {
|
|
76
|
+
type: 'line',
|
|
77
|
+
name: series.name,
|
|
78
|
+
data: series.values,
|
|
79
|
+
zlevel: 1,
|
|
80
|
+
symbol: 'none',
|
|
81
|
+
animation: false,
|
|
82
|
+
silent: true
|
|
83
|
+
};
|
|
84
|
+
const mergedSeries = merge(lineSeries, sparkline);
|
|
85
|
+
statSeries.push(mergedSeries);
|
|
86
|
+
}
|
|
87
|
+
const option = {
|
|
88
|
+
title: {
|
|
89
|
+
show: false
|
|
90
|
+
},
|
|
91
|
+
grid: {
|
|
92
|
+
show: false,
|
|
93
|
+
top: '35%',
|
|
94
|
+
right: 0,
|
|
95
|
+
bottom: 0,
|
|
96
|
+
left: 0,
|
|
97
|
+
containLabel: false
|
|
98
|
+
},
|
|
99
|
+
xAxis: {
|
|
100
|
+
type: 'time',
|
|
101
|
+
show: false,
|
|
102
|
+
boundaryGap: false
|
|
103
|
+
},
|
|
104
|
+
yAxis: {
|
|
105
|
+
type: 'value',
|
|
106
|
+
show: false,
|
|
107
|
+
min: (value)=>{
|
|
108
|
+
if (value.min >= 0 && value.min <= 1) {
|
|
109
|
+
// helps with percent-decimal units, or datasets that return 0 or 1 booleans
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
return value.min;
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
tooltip: {
|
|
116
|
+
show: false
|
|
117
|
+
},
|
|
118
|
+
series: statSeries
|
|
119
|
+
};
|
|
120
|
+
return option;
|
|
121
|
+
}, [
|
|
122
|
+
data,
|
|
123
|
+
chartsTheme,
|
|
124
|
+
sparkline
|
|
125
|
+
]);
|
|
126
|
+
const textAlignment = sparkline ? 'auto' : 'center';
|
|
127
|
+
const textStyles = {
|
|
128
|
+
display: 'flex',
|
|
129
|
+
flexDirection: 'column',
|
|
130
|
+
justifyContent: textAlignment,
|
|
131
|
+
alignItems: textAlignment
|
|
132
|
+
};
|
|
133
|
+
return /*#__PURE__*/ _jsxs(Box, {
|
|
134
|
+
sx: {
|
|
135
|
+
height: '100%',
|
|
136
|
+
width: '100%',
|
|
137
|
+
...textStyles
|
|
138
|
+
},
|
|
139
|
+
children: [
|
|
140
|
+
showSeriesName && /*#__PURE__*/ _jsx(SeriesName, {
|
|
141
|
+
padding: containerPadding,
|
|
142
|
+
fontSize: seriesNameFontSize,
|
|
143
|
+
children: data.seriesData?.name
|
|
144
|
+
}),
|
|
145
|
+
/*#__PURE__*/ _jsx(Value, {
|
|
146
|
+
variant: "h3",
|
|
147
|
+
color: color,
|
|
148
|
+
fontSize: optimalValueFontSize,
|
|
149
|
+
padding: containerPadding,
|
|
150
|
+
children: formattedValue
|
|
151
|
+
}),
|
|
152
|
+
sparkline !== undefined && /*#__PURE__*/ _jsx(EChart, {
|
|
153
|
+
sx: {
|
|
154
|
+
width: '100%'
|
|
155
|
+
},
|
|
156
|
+
// @ts-expect-error: Perses need to be released
|
|
157
|
+
style: {
|
|
158
|
+
// ECharts rounds the height to the nearest integer by default.
|
|
159
|
+
// This can cause unneccessary scrollbars when the total height of this chart exceeds the 'height' prop.
|
|
160
|
+
height: Math.floor(height - seriesNameHeight - valueFontHeight)
|
|
161
|
+
},
|
|
162
|
+
option: option,
|
|
163
|
+
theme: chartsTheme.echartsTheme,
|
|
164
|
+
renderer: "svg"
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
const SeriesName = styled(Typography, {
|
|
170
|
+
shouldForwardProp: (prop)=>prop !== 'padding' && prop !== 'fontSize'
|
|
171
|
+
})(({ theme, padding, fontSize })=>({
|
|
172
|
+
color: theme.palette.text.secondary,
|
|
173
|
+
padding: `${padding}px`,
|
|
174
|
+
fontSize: `${fontSize}px`,
|
|
175
|
+
overflow: 'hidden',
|
|
176
|
+
textOverflow: 'ellipsis',
|
|
177
|
+
whiteSpace: 'nowrap'
|
|
178
|
+
}));
|
|
179
|
+
const Value = styled(Typography, {
|
|
180
|
+
shouldForwardProp: (prop)=>prop !== 'color' && prop !== 'padding' && prop !== 'fontSize' && prop !== 'sparkline'
|
|
181
|
+
})(({ theme, color, padding, fontSize, sparkline })=>({
|
|
182
|
+
color: color ?? theme.palette.text.primary,
|
|
183
|
+
fontSize: `${fontSize}px`,
|
|
184
|
+
padding: sparkline ? `${padding}px ${padding}px 0 ${padding}px` : ` 0 ${padding}px`,
|
|
185
|
+
whiteSpace: 'nowrap',
|
|
186
|
+
lineHeight: LINE_HEIGHT
|
|
187
|
+
}));
|
|
188
|
+
|
|
189
|
+
//# sourceMappingURL=StatChartBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/StatChartBase.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FC, useMemo } from 'react';\nimport { FormatOptions } from '@perses-dev/core';\nimport { Box, Typography, styled } from '@mui/material';\nimport merge from 'lodash/merge';\nimport { use, EChartsCoreOption } from 'echarts/core';\nimport { LineChart as EChartsLineChart, LineSeriesOption } from 'echarts/charts';\nimport { GridComponent, DatasetComponent, TitleComponent, TooltipComponent } from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { EChart, FontSizeOption, GraphSeries, useChartsTheme } from '@perses-dev/components';\nimport { useOptimalFontSize } from './utils/calculate-font-size';\nimport { formatStatChartValue } from './utils/format-stat-chart-value';\n\nuse([EChartsLineChart, GridComponent, DatasetComponent, TitleComponent, TooltipComponent, CanvasRenderer]);\n\nconst LINE_HEIGHT = 1.2;\nconst SERIES_NAME_MAX_FONT_SIZE = 30;\nconst SERIES_NAME_FONT_WEIGHT = 400;\nconst VALUE_FONT_WEIGHT = 700;\n\nexport interface StatChartData {\n color: string;\n calculatedValue?: string | number | null;\n seriesData?: GraphSeries;\n}\n\nexport interface StatChartProps {\n width: number;\n height: number;\n data: StatChartData;\n format?: FormatOptions;\n sparkline?: LineSeriesOption;\n showSeriesName?: boolean;\n valueFontSize?: FontSizeOption;\n}\n\nexport const StatChartBase: FC<StatChartProps> = (props) => {\n const { width, height, data, sparkline, showSeriesName, format, valueFontSize } = props;\n const chartsTheme = useChartsTheme();\n const color = data.color;\n\n const formattedValue = formatStatChartValue(data.calculatedValue, format);\n\n const containerPadding = chartsTheme.container.padding.default;\n\n // calculate series name font size and height\n let seriesNameFontSize = useOptimalFontSize({\n text: data?.seriesData?.name ?? '',\n fontWeight: SERIES_NAME_FONT_WEIGHT,\n width,\n height: height * 0.125, // assume series name will take 12.5% of available height\n lineHeight: LINE_HEIGHT,\n maxSize: SERIES_NAME_MAX_FONT_SIZE,\n });\n\n const seriesNameHeight = showSeriesName ? seriesNameFontSize * LINE_HEIGHT + containerPadding : 0;\n\n // calculate value font size and height\n const availableWidth = width - containerPadding * 2;\n const availableHeight = height - seriesNameHeight;\n const optimalValueFontSize = useOptimalFontSize({\n text: formattedValue,\n // override the font size if user selects it in the settings\n fontSizeOverride: valueFontSize,\n fontWeight: VALUE_FONT_WEIGHT,\n // without sparkline, use only 50% of the available width so it looks better for multiseries\n width: sparkline ? availableWidth : availableWidth * 0.5,\n // with sparkline, use only 25% of available height to leave room for chart\n // without sparkline, value should take up 90% of available space\n height: sparkline ? availableHeight * 0.25 : availableHeight * 0.9,\n lineHeight: LINE_HEIGHT,\n });\n const valueFontHeight = optimalValueFontSize * LINE_HEIGHT;\n\n // make sure the series name font size is slightly smaller than value font size\n seriesNameFontSize = Math.min(optimalValueFontSize * 0.7, seriesNameFontSize);\n\n const option: EChartsCoreOption = useMemo(() => {\n if (data.seriesData === undefined) return chartsTheme.noDataOption;\n\n const series = data.seriesData;\n const statSeries: LineSeriesOption[] = [];\n\n if (sparkline !== undefined) {\n const lineSeries = {\n type: 'line',\n name: series.name,\n data: series.values,\n zlevel: 1,\n symbol: 'none',\n animation: false,\n silent: true,\n };\n const mergedSeries = merge(lineSeries, sparkline);\n statSeries.push(mergedSeries);\n }\n\n const option = {\n title: {\n show: false,\n },\n grid: {\n show: false,\n top: '35%', // adds space above sparkline\n right: 0,\n bottom: 0,\n left: 0,\n containLabel: false,\n },\n xAxis: {\n type: 'time',\n show: false,\n boundaryGap: false,\n },\n yAxis: {\n type: 'value',\n show: false,\n min: (value: { min: number; max: number }): number => {\n if (value.min >= 0 && value.min <= 1) {\n // helps with percent-decimal units, or datasets that return 0 or 1 booleans\n return 0;\n }\n return value.min;\n },\n },\n tooltip: {\n show: false,\n },\n series: statSeries,\n };\n\n return option;\n }, [data, chartsTheme, sparkline]);\n\n const textAlignment = sparkline ? 'auto' : 'center';\n const textStyles = {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: textAlignment,\n alignItems: textAlignment,\n };\n\n return (\n <Box sx={{ height: '100%', width: '100%', ...textStyles }}>\n {showSeriesName && (\n <SeriesName padding={containerPadding} fontSize={seriesNameFontSize}>\n {data.seriesData?.name}\n </SeriesName>\n )}\n <Value variant=\"h3\" color={color} fontSize={optimalValueFontSize} padding={containerPadding}>\n {formattedValue}\n </Value>\n {sparkline !== undefined && (\n <EChart\n sx={{\n width: '100%',\n }}\n // @ts-expect-error: Perses need to be released\n style={{\n // ECharts rounds the height to the nearest integer by default.\n // This can cause unneccessary scrollbars when the total height of this chart exceeds the 'height' prop.\n height: Math.floor(height - seriesNameHeight - valueFontHeight),\n }}\n option={option}\n theme={chartsTheme.echartsTheme}\n renderer=\"svg\"\n />\n )}\n </Box>\n );\n};\n\nconst SeriesName = styled(Typography, {\n shouldForwardProp: (prop) => prop !== 'padding' && prop !== 'fontSize',\n})<{ padding?: number; fontSize?: number; textAlignment?: string }>(({ theme, padding, fontSize }) => ({\n color: theme.palette.text.secondary,\n padding: `${padding}px`,\n fontSize: `${fontSize}px`,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n}));\n\nconst Value = styled(Typography, {\n shouldForwardProp: (prop) => prop !== 'color' && prop !== 'padding' && prop !== 'fontSize' && prop !== 'sparkline',\n})<{ color?: string; padding?: number; fontSize?: number; sparkline?: boolean }>(\n ({ theme, color, padding, fontSize, sparkline }) => ({\n color: color ?? theme.palette.text.primary,\n fontSize: `${fontSize}px`,\n padding: sparkline ? `${padding}px ${padding}px 0 ${padding}px` : ` 0 ${padding}px`,\n whiteSpace: 'nowrap',\n lineHeight: LINE_HEIGHT,\n })\n);\n"],"names":["useMemo","Box","Typography","styled","merge","use","LineChart","EChartsLineChart","GridComponent","DatasetComponent","TitleComponent","TooltipComponent","CanvasRenderer","EChart","useChartsTheme","useOptimalFontSize","formatStatChartValue","LINE_HEIGHT","SERIES_NAME_MAX_FONT_SIZE","SERIES_NAME_FONT_WEIGHT","VALUE_FONT_WEIGHT","StatChartBase","props","width","height","data","sparkline","showSeriesName","format","valueFontSize","chartsTheme","color","formattedValue","calculatedValue","containerPadding","container","padding","default","seriesNameFontSize","text","seriesData","name","fontWeight","lineHeight","maxSize","seriesNameHeight","availableWidth","availableHeight","optimalValueFontSize","fontSizeOverride","valueFontHeight","Math","min","option","undefined","noDataOption","series","statSeries","lineSeries","type","values","zlevel","symbol","animation","silent","mergedSeries","push","title","show","grid","top","right","bottom","left","containLabel","xAxis","boundaryGap","yAxis","value","tooltip","textAlignment","textStyles","display","flexDirection","justifyContent","alignItems","sx","SeriesName","fontSize","Value","variant","style","floor","theme","echartsTheme","renderer","shouldForwardProp","prop","palette","secondary","overflow","textOverflow","whiteSpace","primary"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatChartPanel.d.ts","sourceRoot":"","sources":["../../src/StatChartPanel.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,EAAE,EAAW,MAAM,OAAO,CAAC;AACpC,OAAO,EAAoD,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAClH,OAAO,EAAE,UAAU,EAAa,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"StatChartPanel.d.ts","sourceRoot":"","sources":["../../src/StatChartPanel.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAE,EAAE,EAAW,MAAM,OAAO,CAAC;AACpC,OAAO,EAAoD,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAClH,OAAO,EAAE,UAAU,EAAa,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAStD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;AAE/E,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAsDlD,CAAC"}
|
package/lib/StatChartPanel.js
CHANGED
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
-
import {
|
|
14
|
+
import { useChartsTheme } from '@perses-dev/components';
|
|
15
15
|
import { Stack, Typography } from '@mui/material';
|
|
16
16
|
import { useMemo } from 'react';
|
|
17
17
|
import { applyValueMapping, createRegexFromString } from '@perses-dev/core';
|
|
18
18
|
import { convertSparkline } from './utils/data-transform';
|
|
19
19
|
import { calculateValue } from './utils/calculate-value';
|
|
20
20
|
import { getStatChartColor } from './utils/get-color';
|
|
21
|
+
import { StatChartBase } from './StatChartBase';
|
|
21
22
|
const MIN_WIDTH = 100;
|
|
22
23
|
const SPACING = 2;
|
|
23
24
|
export const StatChartPanel = (props)=>{
|
|
@@ -46,7 +47,7 @@ export const StatChartPanel = (props)=>{
|
|
|
46
47
|
},
|
|
47
48
|
children: statChartData.length ? statChartData.map((series, index)=>{
|
|
48
49
|
const sparklineConfig = convertSparkline(chartsTheme, series.color, sparkline);
|
|
49
|
-
return /*#__PURE__*/ _jsx(
|
|
50
|
+
return /*#__PURE__*/ _jsx(StatChartBase, {
|
|
50
51
|
width: chartWidth,
|
|
51
52
|
height: contentDimensions.height,
|
|
52
53
|
data: series,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/StatChartPanel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TitleComponentOption } from 'echarts';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/StatChartPanel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { TitleComponentOption } from 'echarts';\nimport { useChartsTheme, GraphSeries, PersesChartsTheme } from '@perses-dev/components';\nimport { Stack, Typography, SxProps } from '@mui/material';\nimport { FC, useMemo } from 'react';\nimport { applyValueMapping, Labels, createRegexFromString, TimeSeriesData, ValueMapping } from '@perses-dev/core';\nimport { PanelProps, PanelData } from '@perses-dev/plugin-system';\nimport { StatChartOptions } from './stat-chart-model';\nimport { convertSparkline } from './utils/data-transform';\nimport { calculateValue } from './utils/calculate-value';\nimport { getStatChartColor } from './utils/get-color';\nimport { StatChartBase, StatChartData } from './StatChartBase';\n\nconst MIN_WIDTH = 100;\nconst SPACING = 2;\n\nexport type StatChartPanelProps = PanelProps<StatChartOptions, TimeSeriesData>;\n\nexport const StatChartPanel: FC<StatChartPanelProps> = (props) => {\n const { spec, contentDimensions, queryResults } = props;\n\n const { format, sparkline, valueFontSize: valueFontSize } = spec;\n const chartsTheme = useChartsTheme();\n const statChartData = useStatChartData(queryResults, spec, chartsTheme);\n\n const isMultiSeries = statChartData.length > 1;\n\n if (contentDimensions === undefined) return null;\n\n // Calculates chart width\n const spacing = SPACING * (statChartData.length - 1);\n let chartWidth = (contentDimensions.width - spacing) / statChartData.length;\n if (isMultiSeries && chartWidth < MIN_WIDTH) {\n chartWidth = MIN_WIDTH;\n }\n\n const noDataTextStyle = (chartsTheme.noDataOption.title as TitleComponentOption).textStyle;\n\n return (\n <Stack\n height={contentDimensions.height}\n width={contentDimensions.width}\n spacing={`${SPACING}px`}\n direction=\"row\"\n justifyContent={isMultiSeries ? 'left' : 'center'}\n alignItems=\"center\"\n sx={{\n overflowX: isMultiSeries ? 'scroll' : 'auto',\n }}\n >\n {statChartData.length ? (\n statChartData.map((series, index) => {\n const sparklineConfig = convertSparkline(chartsTheme, series.color, sparkline);\n\n return (\n <StatChartBase\n key={index}\n width={chartWidth}\n height={contentDimensions.height}\n data={series}\n format={format}\n sparkline={sparklineConfig}\n showSeriesName={isMultiSeries}\n valueFontSize={valueFontSize}\n />\n );\n })\n ) : (\n <Typography sx={{ ...noDataTextStyle } as SxProps}>No data</Typography>\n )}\n </Stack>\n );\n};\n\nconst useStatChartData = (\n queryResults: Array<PanelData<TimeSeriesData>>,\n spec: StatChartOptions,\n chartsTheme: PersesChartsTheme\n): StatChartData[] => {\n return useMemo(() => {\n const { calculation, mappings, metricLabel } = spec;\n\n const statChartData: StatChartData[] = [];\n for (const result of queryResults) {\n for (const seriesData of result.data.series) {\n const calculatedValue = calculateValue(calculation, seriesData);\n\n // get label metric value\n const labelValue = getLabelValue(metricLabel, seriesData.labels);\n\n // get actual value to display\n const displayValue = getValueOrLabel(calculatedValue, mappings, labelValue);\n\n const color = getStatChartColor(chartsTheme, spec, calculatedValue);\n\n const series: GraphSeries = {\n name: seriesData.formattedName ?? '',\n values: seriesData.values,\n };\n\n statChartData.push({ calculatedValue: displayValue, seriesData: series, color });\n }\n }\n return statChartData;\n }, [queryResults, spec, chartsTheme]);\n};\n\nconst getValueOrLabel = (\n value?: number | null,\n mappings?: ValueMapping[],\n label?: string\n): string | number | undefined | null => {\n if (label) {\n return label;\n }\n if (mappings?.length && value !== undefined && value !== null) {\n return applyValueMapping(value, mappings).value;\n } else {\n return value;\n }\n};\n\nconst getLabelValue = (fieldLabel?: string, labels?: Labels): string | undefined => {\n if (!labels || !fieldLabel) {\n return undefined;\n }\n for (const [key, value] of Object.entries(labels)) {\n const regex = createRegexFromString(fieldLabel);\n if (regex.test(key)) {\n return value;\n }\n }\n return undefined;\n};\n"],"names":["useChartsTheme","Stack","Typography","useMemo","applyValueMapping","createRegexFromString","convertSparkline","calculateValue","getStatChartColor","StatChartBase","MIN_WIDTH","SPACING","StatChartPanel","props","spec","contentDimensions","queryResults","format","sparkline","valueFontSize","chartsTheme","statChartData","useStatChartData","isMultiSeries","length","undefined","spacing","chartWidth","width","noDataTextStyle","noDataOption","title","textStyle","height","direction","justifyContent","alignItems","sx","overflowX","map","series","index","sparklineConfig","color","data","showSeriesName","calculation","mappings","metricLabel","result","seriesData","calculatedValue","labelValue","getLabelValue","labels","displayValue","getValueOrLabel","name","formattedName","values","push","value","label","fieldLabel","key","Object","entries","regex","test"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,cAAc,QAAwC,yBAAyB;AACxF,SAASC,KAAK,EAAEC,UAAU,QAAiB,gBAAgB;AAC3D,SAAaC,OAAO,QAAQ,QAAQ;AACpC,SAASC,iBAAiB,EAAUC,qBAAqB,QAAsC,mBAAmB;AAGlH,SAASC,gBAAgB,QAAQ,yBAAyB;AAC1D,SAASC,cAAc,QAAQ,0BAA0B;AACzD,SAASC,iBAAiB,QAAQ,oBAAoB;AACtD,SAASC,aAAa,QAAuB,kBAAkB;AAE/D,MAAMC,YAAY;AAClB,MAAMC,UAAU;AAIhB,OAAO,MAAMC,iBAA0C,CAACC;IACtD,MAAM,EAAEC,IAAI,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGH;IAElD,MAAM,EAAEI,MAAM,EAAEC,SAAS,EAAEC,eAAeA,aAAa,EAAE,GAAGL;IAC5D,MAAMM,cAAcpB;IACpB,MAAMqB,gBAAgBC,iBAAiBN,cAAcF,MAAMM;IAE3D,MAAMG,gBAAgBF,cAAcG,MAAM,GAAG;IAE7C,IAAIT,sBAAsBU,WAAW,OAAO;IAE5C,yBAAyB;IACzB,MAAMC,UAAUf,UAAWU,CAAAA,cAAcG,MAAM,GAAG,CAAA;IAClD,IAAIG,aAAa,AAACZ,CAAAA,kBAAkBa,KAAK,GAAGF,OAAM,IAAKL,cAAcG,MAAM;IAC3E,IAAID,iBAAiBI,aAAajB,WAAW;QAC3CiB,aAAajB;IACf;IAEA,MAAMmB,kBAAkB,AAACT,YAAYU,YAAY,CAACC,KAAK,CAA0BC,SAAS;IAE1F,qBACE,KAAC/B;QACCgC,QAAQlB,kBAAkBkB,MAAM;QAChCL,OAAOb,kBAAkBa,KAAK;QAC9BF,SAAS,GAAGf,QAAQ,EAAE,CAAC;QACvBuB,WAAU;QACVC,gBAAgBZ,gBAAgB,SAAS;QACzCa,YAAW;QACXC,IAAI;YACFC,WAAWf,gBAAgB,WAAW;QACxC;kBAECF,cAAcG,MAAM,GACnBH,cAAckB,GAAG,CAAC,CAACC,QAAQC;YACzB,MAAMC,kBAAkBpC,iBAAiBc,aAAaoB,OAAOG,KAAK,EAAEzB;YAEpE,qBACE,KAACT;gBAECmB,OAAOD;gBACPM,QAAQlB,kBAAkBkB,MAAM;gBAChCW,MAAMJ;gBACNvB,QAAQA;gBACRC,WAAWwB;gBACXG,gBAAgBtB;gBAChBJ,eAAeA;eAPVsB;QAUX,mBAEA,KAACvC;YAAWmC,IAAI;gBAAE,GAAGR,eAAe;YAAC;sBAAc;;;AAI3D,EAAE;AAEF,MAAMP,mBAAmB,CACvBN,cACAF,MACAM;IAEA,OAAOjB,QAAQ;QACb,MAAM,EAAE2C,WAAW,EAAEC,QAAQ,EAAEC,WAAW,EAAE,GAAGlC;QAE/C,MAAMO,gBAAiC,EAAE;QACzC,KAAK,MAAM4B,UAAUjC,aAAc;YACjC,KAAK,MAAMkC,cAAcD,OAAOL,IAAI,CAACJ,MAAM,CAAE;gBAC3C,MAAMW,kBAAkB5C,eAAeuC,aAAaI;gBAEpD,yBAAyB;gBACzB,MAAME,aAAaC,cAAcL,aAAaE,WAAWI,MAAM;gBAE/D,8BAA8B;gBAC9B,MAAMC,eAAeC,gBAAgBL,iBAAiBJ,UAAUK;gBAEhE,MAAMT,QAAQnC,kBAAkBY,aAAaN,MAAMqC;gBAEnD,MAAMX,SAAsB;oBAC1BiB,MAAMP,WAAWQ,aAAa,IAAI;oBAClCC,QAAQT,WAAWS,MAAM;gBAC3B;gBAEAtC,cAAcuC,IAAI,CAAC;oBAAET,iBAAiBI;oBAAcL,YAAYV;oBAAQG;gBAAM;YAChF;QACF;QACA,OAAOtB;IACT,GAAG;QAACL;QAAcF;QAAMM;KAAY;AACtC;AAEA,MAAMoC,kBAAkB,CACtBK,OACAd,UACAe;IAEA,IAAIA,OAAO;QACT,OAAOA;IACT;IACA,IAAIf,UAAUvB,UAAUqC,UAAUpC,aAAaoC,UAAU,MAAM;QAC7D,OAAOzD,kBAAkByD,OAAOd,UAAUc,KAAK;IACjD,OAAO;QACL,OAAOA;IACT;AACF;AAEA,MAAMR,gBAAgB,CAACU,YAAqBT;IAC1C,IAAI,CAACA,UAAU,CAACS,YAAY;QAC1B,OAAOtC;IACT;IACA,KAAK,MAAM,CAACuC,KAAKH,MAAM,IAAII,OAAOC,OAAO,CAACZ,QAAS;QACjD,MAAMa,QAAQ9D,sBAAsB0D;QACpC,IAAII,MAAMC,IAAI,CAACJ,MAAM;YACnB,OAAOH;QACT;IACF;IACA,OAAOpC;AACT"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Copyright 2023 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
"use strict";
|
|
14
|
+
Object.defineProperty(exports, "__esModule", {
|
|
15
|
+
value: true
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(exports, "StatChartBase", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function() {
|
|
20
|
+
return StatChartBase;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const _jsxruntime = require("react/jsx-runtime");
|
|
24
|
+
const _react = require("react");
|
|
25
|
+
const _material = require("@mui/material");
|
|
26
|
+
const _merge = /*#__PURE__*/ _interop_require_default(require("lodash/merge"));
|
|
27
|
+
const _core = require("echarts/core");
|
|
28
|
+
const _charts = require("echarts/charts");
|
|
29
|
+
const _components = require("echarts/components");
|
|
30
|
+
const _renderers = require("echarts/renderers");
|
|
31
|
+
const _components1 = require("@perses-dev/components");
|
|
32
|
+
const _calculatefontsize = require("./utils/calculate-font-size");
|
|
33
|
+
const _formatstatchartvalue = require("./utils/format-stat-chart-value");
|
|
34
|
+
function _interop_require_default(obj) {
|
|
35
|
+
return obj && obj.__esModule ? obj : {
|
|
36
|
+
default: obj
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
(0, _core.use)([
|
|
40
|
+
_charts.LineChart,
|
|
41
|
+
_components.GridComponent,
|
|
42
|
+
_components.DatasetComponent,
|
|
43
|
+
_components.TitleComponent,
|
|
44
|
+
_components.TooltipComponent,
|
|
45
|
+
_renderers.CanvasRenderer
|
|
46
|
+
]);
|
|
47
|
+
const LINE_HEIGHT = 1.2;
|
|
48
|
+
const SERIES_NAME_MAX_FONT_SIZE = 30;
|
|
49
|
+
const SERIES_NAME_FONT_WEIGHT = 400;
|
|
50
|
+
const VALUE_FONT_WEIGHT = 700;
|
|
51
|
+
const StatChartBase = (props)=>{
|
|
52
|
+
const { width, height, data, sparkline, showSeriesName, format, valueFontSize } = props;
|
|
53
|
+
const chartsTheme = (0, _components1.useChartsTheme)();
|
|
54
|
+
const color = data.color;
|
|
55
|
+
const formattedValue = (0, _formatstatchartvalue.formatStatChartValue)(data.calculatedValue, format);
|
|
56
|
+
const containerPadding = chartsTheme.container.padding.default;
|
|
57
|
+
// calculate series name font size and height
|
|
58
|
+
let seriesNameFontSize = (0, _calculatefontsize.useOptimalFontSize)({
|
|
59
|
+
text: data?.seriesData?.name ?? '',
|
|
60
|
+
fontWeight: SERIES_NAME_FONT_WEIGHT,
|
|
61
|
+
width,
|
|
62
|
+
height: height * 0.125,
|
|
63
|
+
lineHeight: LINE_HEIGHT,
|
|
64
|
+
maxSize: SERIES_NAME_MAX_FONT_SIZE
|
|
65
|
+
});
|
|
66
|
+
const seriesNameHeight = showSeriesName ? seriesNameFontSize * LINE_HEIGHT + containerPadding : 0;
|
|
67
|
+
// calculate value font size and height
|
|
68
|
+
const availableWidth = width - containerPadding * 2;
|
|
69
|
+
const availableHeight = height - seriesNameHeight;
|
|
70
|
+
const optimalValueFontSize = (0, _calculatefontsize.useOptimalFontSize)({
|
|
71
|
+
text: formattedValue,
|
|
72
|
+
// override the font size if user selects it in the settings
|
|
73
|
+
fontSizeOverride: valueFontSize,
|
|
74
|
+
fontWeight: VALUE_FONT_WEIGHT,
|
|
75
|
+
// without sparkline, use only 50% of the available width so it looks better for multiseries
|
|
76
|
+
width: sparkline ? availableWidth : availableWidth * 0.5,
|
|
77
|
+
// with sparkline, use only 25% of available height to leave room for chart
|
|
78
|
+
// without sparkline, value should take up 90% of available space
|
|
79
|
+
height: sparkline ? availableHeight * 0.25 : availableHeight * 0.9,
|
|
80
|
+
lineHeight: LINE_HEIGHT
|
|
81
|
+
});
|
|
82
|
+
const valueFontHeight = optimalValueFontSize * LINE_HEIGHT;
|
|
83
|
+
// make sure the series name font size is slightly smaller than value font size
|
|
84
|
+
seriesNameFontSize = Math.min(optimalValueFontSize * 0.7, seriesNameFontSize);
|
|
85
|
+
const option = (0, _react.useMemo)(()=>{
|
|
86
|
+
if (data.seriesData === undefined) return chartsTheme.noDataOption;
|
|
87
|
+
const series = data.seriesData;
|
|
88
|
+
const statSeries = [];
|
|
89
|
+
if (sparkline !== undefined) {
|
|
90
|
+
const lineSeries = {
|
|
91
|
+
type: 'line',
|
|
92
|
+
name: series.name,
|
|
93
|
+
data: series.values,
|
|
94
|
+
zlevel: 1,
|
|
95
|
+
symbol: 'none',
|
|
96
|
+
animation: false,
|
|
97
|
+
silent: true
|
|
98
|
+
};
|
|
99
|
+
const mergedSeries = (0, _merge.default)(lineSeries, sparkline);
|
|
100
|
+
statSeries.push(mergedSeries);
|
|
101
|
+
}
|
|
102
|
+
const option = {
|
|
103
|
+
title: {
|
|
104
|
+
show: false
|
|
105
|
+
},
|
|
106
|
+
grid: {
|
|
107
|
+
show: false,
|
|
108
|
+
top: '35%',
|
|
109
|
+
right: 0,
|
|
110
|
+
bottom: 0,
|
|
111
|
+
left: 0,
|
|
112
|
+
containLabel: false
|
|
113
|
+
},
|
|
114
|
+
xAxis: {
|
|
115
|
+
type: 'time',
|
|
116
|
+
show: false,
|
|
117
|
+
boundaryGap: false
|
|
118
|
+
},
|
|
119
|
+
yAxis: {
|
|
120
|
+
type: 'value',
|
|
121
|
+
show: false,
|
|
122
|
+
min: (value)=>{
|
|
123
|
+
if (value.min >= 0 && value.min <= 1) {
|
|
124
|
+
// helps with percent-decimal units, or datasets that return 0 or 1 booleans
|
|
125
|
+
return 0;
|
|
126
|
+
}
|
|
127
|
+
return value.min;
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
tooltip: {
|
|
131
|
+
show: false
|
|
132
|
+
},
|
|
133
|
+
series: statSeries
|
|
134
|
+
};
|
|
135
|
+
return option;
|
|
136
|
+
}, [
|
|
137
|
+
data,
|
|
138
|
+
chartsTheme,
|
|
139
|
+
sparkline
|
|
140
|
+
]);
|
|
141
|
+
const textAlignment = sparkline ? 'auto' : 'center';
|
|
142
|
+
const textStyles = {
|
|
143
|
+
display: 'flex',
|
|
144
|
+
flexDirection: 'column',
|
|
145
|
+
justifyContent: textAlignment,
|
|
146
|
+
alignItems: textAlignment
|
|
147
|
+
};
|
|
148
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Box, {
|
|
149
|
+
sx: {
|
|
150
|
+
height: '100%',
|
|
151
|
+
width: '100%',
|
|
152
|
+
...textStyles
|
|
153
|
+
},
|
|
154
|
+
children: [
|
|
155
|
+
showSeriesName && /*#__PURE__*/ (0, _jsxruntime.jsx)(SeriesName, {
|
|
156
|
+
padding: containerPadding,
|
|
157
|
+
fontSize: seriesNameFontSize,
|
|
158
|
+
children: data.seriesData?.name
|
|
159
|
+
}),
|
|
160
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(Value, {
|
|
161
|
+
variant: "h3",
|
|
162
|
+
color: color,
|
|
163
|
+
fontSize: optimalValueFontSize,
|
|
164
|
+
padding: containerPadding,
|
|
165
|
+
children: formattedValue
|
|
166
|
+
}),
|
|
167
|
+
sparkline !== undefined && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components1.EChart, {
|
|
168
|
+
sx: {
|
|
169
|
+
width: '100%'
|
|
170
|
+
},
|
|
171
|
+
// @ts-expect-error: Perses need to be released
|
|
172
|
+
style: {
|
|
173
|
+
// ECharts rounds the height to the nearest integer by default.
|
|
174
|
+
// This can cause unneccessary scrollbars when the total height of this chart exceeds the 'height' prop.
|
|
175
|
+
height: Math.floor(height - seriesNameHeight - valueFontHeight)
|
|
176
|
+
},
|
|
177
|
+
option: option,
|
|
178
|
+
theme: chartsTheme.echartsTheme,
|
|
179
|
+
renderer: "svg"
|
|
180
|
+
})
|
|
181
|
+
]
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
const SeriesName = (0, _material.styled)(_material.Typography, {
|
|
185
|
+
shouldForwardProp: (prop)=>prop !== 'padding' && prop !== 'fontSize'
|
|
186
|
+
})(({ theme, padding, fontSize })=>({
|
|
187
|
+
color: theme.palette.text.secondary,
|
|
188
|
+
padding: `${padding}px`,
|
|
189
|
+
fontSize: `${fontSize}px`,
|
|
190
|
+
overflow: 'hidden',
|
|
191
|
+
textOverflow: 'ellipsis',
|
|
192
|
+
whiteSpace: 'nowrap'
|
|
193
|
+
}));
|
|
194
|
+
const Value = (0, _material.styled)(_material.Typography, {
|
|
195
|
+
shouldForwardProp: (prop)=>prop !== 'color' && prop !== 'padding' && prop !== 'fontSize' && prop !== 'sparkline'
|
|
196
|
+
})(({ theme, color, padding, fontSize, sparkline })=>({
|
|
197
|
+
color: color ?? theme.palette.text.primary,
|
|
198
|
+
fontSize: `${fontSize}px`,
|
|
199
|
+
padding: sparkline ? `${padding}px ${padding}px 0 ${padding}px` : ` 0 ${padding}px`,
|
|
200
|
+
whiteSpace: 'nowrap',
|
|
201
|
+
lineHeight: LINE_HEIGHT
|
|
202
|
+
}));
|
|
@@ -28,6 +28,7 @@ const _core = require("@perses-dev/core");
|
|
|
28
28
|
const _datatransform = require("./utils/data-transform");
|
|
29
29
|
const _calculatevalue = require("./utils/calculate-value");
|
|
30
30
|
const _getcolor = require("./utils/get-color");
|
|
31
|
+
const _StatChartBase = require("./StatChartBase");
|
|
31
32
|
const MIN_WIDTH = 100;
|
|
32
33
|
const SPACING = 2;
|
|
33
34
|
const StatChartPanel = (props)=>{
|
|
@@ -56,7 +57,7 @@ const StatChartPanel = (props)=>{
|
|
|
56
57
|
},
|
|
57
58
|
children: statChartData.length ? statChartData.map((series, index)=>{
|
|
58
59
|
const sparklineConfig = (0, _datatransform.convertSparkline)(chartsTheme, series.color, sparkline);
|
|
59
|
-
return /*#__PURE__*/ (0, _jsxruntime.jsx)(
|
|
60
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_StatChartBase.StatChartBase, {
|
|
60
61
|
width: chartWidth,
|
|
61
62
|
height: contentDimensions.height,
|
|
62
63
|
data: series,
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
// Copyright 2025 The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
1
13
|
"use strict";
|
|
2
14
|
Object.defineProperty(exports, "__esModule", {
|
|
3
15
|
value: true
|
|
@@ -14,6 +26,7 @@ _export_star(require("./StatChart"), exports);
|
|
|
14
26
|
_export_star(require("./StatChartOptionsEditorSettings"), exports);
|
|
15
27
|
_export_star(require("./StatChartPanel"), exports);
|
|
16
28
|
_export_star(require("./StatChartValueMappingEditor"), exports);
|
|
29
|
+
_export_star(require("./StatChartBase"), exports);
|
|
17
30
|
function _export_star(from, to) {
|
|
18
31
|
Object.keys(from).forEach(function(k) {
|
|
19
32
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|