@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.
Files changed (47) hide show
  1. package/__mf/js/{435.f40076fc.js → 435.0060dd2f.js} +1 -1
  2. package/__mf/js/{StatChart.b0400032.js → StatChart.3d66ae68.js} +3 -3
  3. package/__mf/js/async/{877.0e870142.js → 236.f47b54b8.js} +1 -1
  4. package/__mf/js/async/331.faa6f9eb.js +2 -0
  5. package/__mf/js/async/{870.3ed3413d.js.LICENSE.txt → 331.faa6f9eb.js.LICENSE.txt} +1 -39
  6. package/__mf/js/async/360.e3f25d30.js +29 -0
  7. package/__mf/js/async/360.e3f25d30.js.LICENSE.txt +37 -0
  8. package/__mf/js/async/{610.dad41cbd.js → 610.e2fe79a3.js} +1 -1
  9. package/__mf/js/async/83.0215bc58.js +1 -0
  10. package/__mf/js/async/{318.98a6e364.js → 90.defedb11.js} +10 -10
  11. package/__mf/js/async/954.f8bb1788.js +2 -0
  12. package/__mf/js/async/__federation_expose_StatChart.60147471.js +1 -0
  13. package/__mf/js/main.0ffda506.js +1 -0
  14. package/lib/StatChartBase.d.ts +20 -0
  15. package/lib/StatChartBase.d.ts.map +1 -0
  16. package/lib/StatChartBase.js +189 -0
  17. package/lib/StatChartBase.js.map +1 -0
  18. package/lib/StatChartPanel.d.ts.map +1 -1
  19. package/lib/StatChartPanel.js +3 -2
  20. package/lib/StatChartPanel.js.map +1 -1
  21. package/lib/cjs/StatChartBase.js +202 -0
  22. package/lib/cjs/StatChartPanel.js +2 -1
  23. package/lib/cjs/index.js +13 -0
  24. package/lib/cjs/utils/calculate-font-size.js +55 -0
  25. package/lib/cjs/utils/format-stat-chart-value.js +34 -0
  26. package/lib/index.d.ts +1 -0
  27. package/lib/index.d.ts.map +1 -1
  28. package/lib/index.js +13 -0
  29. package/lib/index.js.map +1 -1
  30. package/lib/utils/calculate-font-size.d.ts +16 -0
  31. package/lib/utils/calculate-font-size.d.ts.map +1 -0
  32. package/lib/utils/calculate-font-size.js +49 -0
  33. package/lib/utils/calculate-font-size.js.map +1 -0
  34. package/lib/utils/format-stat-chart-value.d.ts +3 -0
  35. package/lib/utils/format-stat-chart-value.d.ts.map +1 -0
  36. package/lib/utils/format-stat-chart-value.js +26 -0
  37. package/lib/utils/format-stat-chart-value.js.map +1 -0
  38. package/mf-manifest.json +17 -15
  39. package/mf-stats.json +17 -15
  40. package/package.json +1 -1
  41. package/__mf/js/async/298.0f019169.js +0 -1
  42. package/__mf/js/async/870.3ed3413d.js +0 -29
  43. package/__mf/js/async/996.7e490e79.js +0 -2
  44. package/__mf/js/async/__federation_expose_StatChart.0d43d15e.js +0 -1
  45. package/__mf/js/main.628b2309.js +0 -1
  46. /package/__mf/js/async/{318.98a6e364.js.LICENSE.txt → 90.defedb11.js.LICENSE.txt} +0 -0
  47. /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;AAQtD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;AAE/E,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAsDlD,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"}
@@ -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 { StatChart, useChartsTheme } from '@perses-dev/components';
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(StatChart, {
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 { StatChart, StatChartData, 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';\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 <StatChart\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":["StatChart","useChartsTheme","Stack","Typography","useMemo","applyValueMapping","createRegexFromString","convertSparkline","calculateValue","getStatChartColor","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":"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"}
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":"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"}
@@ -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)(_components.StatChart, {
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)) {