@kodiak-finance/orderly-chart 2.8.18-rc.1 → 2.8.19-rc.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/dist/index.mjs CHANGED
@@ -1,2 +1,2258 @@
1
- import {useMemo,useRef,useId}from'react';import {ResponsiveContainer,BarChart,Tooltip,CartesianGrid,ReferenceLine,Bar,Cell,YAxis,XAxis,LineChart,Line,AreaChart,Area,ComposedChart,Cross}from'recharts';export{Area,AreaChart,Bar,BarChart,Cell,Line,LineChart}from'recharts';import {useTranslation}from'@kodiak-finance/orderly-i18n';import {cn,useScreen,Box,Flex,BarChartIcon,Text}from'@kodiak-finance/orderly-ui';import {numberToHumanStyle}from'@kodiak-finance/orderly-utils';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var Kt=Object.create;var mt=Object.defineProperty;var zt=Object.getOwnPropertyDescriptor;var _t=Object.getOwnPropertyNames;var Gt=Object.getPrototypeOf,$t=Object.prototype.hasOwnProperty;var J=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Et=(t,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of _t(e))!$t.call(t,r)&&r!==o&&mt(t,r,{get:()=>e[r],enumerable:!(a=zt(e,r))||a.enumerable});return t};var Wt=(t,e,o)=>(o=t!=null?Kt(Gt(t)):{},Et(!t||!t.__esModule?mt(o,"default",{value:t,enumerable:true}):o,t));var Ot=J(it=>{Object.defineProperty(it,"__esModule",{value:true});Object.defineProperty(it,"default",{enumerable:true,get:function(){return Fr}});function Dt(t,e){return {handler:t,config:e}}Dt.withOptions=function(t,e=()=>({})){let o=function(a){return {__options:a,handler:t(a),config:e(a)}};return o.__isOptionsFunction=true,o.__pluginFunction=t,o.__configFunction=e,o};var Fr=Dt;});var St=J(nt=>{Object.defineProperty(nt,"__esModule",{value:true});Object.defineProperty(nt,"default",{enumerable:true,get:function(){return Ar}});var kr=Pr(Ot());function Pr(t){return t&&t.__esModule?t:{default:t}}var Ar=kr.default;});var Vt=J((Hn,It)=>{var st=St();It.exports=(st.__esModule?st:{default:st}).default;});var O=t=>{let e=Math.abs(t),o=e===0?0:e<=10?2:e<=100?1:0,a=numberToHumanStyle(e,o);return t<0?`-${a}`:a};var w=t=>{let{label:e,value:o,prefix:a,unit:r="USDC",coloring:i=false,dp:n,rm:s}=t;return jsxs(Box,{intensity:600,p:3,r:"md",children:[jsxs(Flex,{direction:"row",className:t.titleClassName,children:[a,jsx(Text.numeral,{unit:r,as:"div",size:"sm",coloring:i,showIdentifier:i,unitClassName:"oui-text-base-contrast-54 oui-ml-1",weight:"semibold",rm:s,dp:n,children:o})]}),jsx(Text,{size:"2xs",intensity:54,weight:"semibold",children:e})]})};var ft=()=>{let t=document.documentElement,e=getComputedStyle(t);return {primary:K(e.getPropertyValue("--oui-color-primary")),primaryLight:K(e.getPropertyValue("--oui-color-primary-light")),secondary:K(e.getPropertyValue("--oui-color-secondary")),success:K(e.getPropertyValue("--oui-color-success")),warning:K(e.getPropertyValue("--oui-color-warning")),danger:K(e.getPropertyValue("--oui-color-danger")),info:K(e.getPropertyValue("--oui-color-info")),loss:K(e.getPropertyValue("--oui-color-trading-loss")),profit:K(e.getPropertyValue("--oui-color-trading-profit"))}},K=t=>`rgb(${t.split(" ").join(",")})`;var p=t=>useMemo(()=>{let o=ft();return {profit:t?.profit||o.profit,loss:t?.loss||o.loss,primary:o.primary,primaryLight:o.primaryLight}},[t]);var ne=t=>{let{fill:e,x:o,y:a,width:r,height:i}=t,n=Math.abs(i);return jsx("rect",{rx:2,x:o,y:i>0?a:a+i,width:r,height:n,stroke:"none",fill:e})},se=t=>{let{x:e,y:o,stroke:a,payload:r,index:i,width:n,containerWidth:s}=t,{t:c}=useTranslation(),l=i===0?48:s>0?s-10:n+r.offset;return jsx("g",{transform:`translate(${l},${o-6})`,children:jsx("text",{x:0,y:0,dy:16,textAnchor:i===0?"start":"end",fontSize:10,fill:"rgba(255,255,255,0.54)",children:i===0?r.value:c("chart.now")})})},le=t=>{let{width:e,height:o,stroke:a,fill:r}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},ce=t=>{let{active:e,payload:o,label:a}=t,r=useRef(new Date().toISOString().split("T")[0]),{t:i}=useTranslation();return e&&o&&o.length?jsx(w,{label:a===r.current?i("chart.now"):a,value:o[0].value,coloring:true}):null},me=t=>{let{invisible:e,data:o,responsiveContainerProps:a}=t,r=p(t.colors),i=useRef(0);return jsx(ResponsiveContainer,{className:cn(e&&"chart-invisible"),onResize:n=>{i.current=n;},...a,children:jsxs(BarChart,{data:o,margin:{left:-10,top:10,right:10,bottom:30},children:[!e&&jsx(Tooltip,{cursor:jsx(le,{}),content:jsx(ce,{})}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(ReferenceLine,{y:0,stroke:"rgba(0,0,0,0.04)"}),!e&&jsx(Bar,{dataKey:"pnl",shape:jsx(ne,{}),children:o.map((n,s)=>jsx(Cell,{fill:n.pnl>0?r.profit:r.loss},`cell-${s}`))}),jsx(YAxis,{tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickFormatter:n=>O(n),tickLine:false,axisLine:false,dataKey:"pnl"}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:o.length-2,height:1,tick:jsx(se,{containerWidth:i.current}),stroke:"#FFFFFF",strokeOpacity:.04})]})})};var z=t=>{let{x:e,y:o,stroke:a,payload:r,index:i}=t,{t:n}=useTranslation();return jsx("g",{transform:`translate(${e},${o-6})`,children:jsx("text",{x:0,y:0,dy:16,textAnchor:"end",fontSize:10,fill:"rgba(255,255,255,0.54)",children:i===0?r.value:n("chart.now")})})};var Pe=t=>{let{active:e,payload:o,label:a}=t,r=useRef(new Date().toISOString().split("T")[0]),{t:i}=useTranslation();return e&&o&&o.length?jsx(w,{label:a===r.current?i("chart.now"):a,value:o[0].value,coloring:true}):null},Ae=t=>{let e=[];return t?.reduce((o,a)=>(o+=a.pnl,e.push({...a,pnl:o,_pnl:a.pnl}),o),0),e},Re=t=>{let{responsiveContainerProps:e}=t,o=p(t.colors),{isMobile:a}=useScreen(),r=useMemo(()=>Ae(t.data),[t.data]),i=jsxs(LineChart,{data:r,margin:{top:20,right:10,left:-10,bottom:0},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",interval:t.data.length-2,tick:jsx(z,{}),stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{dataKey:"pnl",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:O}),!t.invisible&&jsx(Tooltip,{cursor:{strokeDasharray:"3 2",strokeOpacity:.16},content:jsx(Pe,{})}),!t.invisible&&jsx(Line,{type:"natural",dataKey:"pnl",stroke:o.primary,strokeWidth:a?1.5:2,dot:false,isAnimationActive:false})]});return jsx(ResponsiveContainer,{className:t.invisible?"chart-invisible":void 0,...e,children:i})};var _e=t=>{let{active:e,payload:o,label:a}=t,r=useRef(new Date().toISOString().split("T")[0]),{t:i}=useTranslation();return e&&o&&o.length?jsx(w,{label:a===r.current?i("chart.now"):a,value:o[0].value,coloring:true}):null},Ge=t=>{let e=[];return t?.reduce((o,a)=>(o+=a.pnl,e.push({...a,pnl:o,_pnl:a.pnl}),o),0),e},$e=t=>{let{responsiveContainerProps:e}=t,o=p(t.colors),{isMobile:a}=useScreen(),r=useId(),i=useMemo(()=>Ge(t.data),[t.data]),n=jsxs(AreaChart,{data:i,margin:{top:20,right:10,left:-10,bottom:0},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",interval:t.data.length-2,tick:jsx(z,{}),stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{dataKey:"pnl",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:O}),!t.invisible&&jsx(Tooltip,{cursor:{strokeDasharray:"3 2",strokeOpacity:.16},content:jsx(_e,{})}),!t.invisible&&jsxs(Fragment,{children:[jsx("defs",{children:jsxs("linearGradient",{id:r,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{stopColor:"#608CFF",offset:"0%",stopOpacity:.5}),jsx("stop",{stopColor:"#608CFF",offset:"100%",stopOpacity:0})]})}),jsx(Area,{type:"natural",dataKey:"pnl",stroke:o.primary,strokeWidth:a?1.5:2,dot:false,isAnimationActive:false,fill:`url(#${r})`})]})]});return jsx(ResponsiveContainer,{className:t.invisible?"chart-invisible":void 0,...e,children:n})};var G=({title:t="No Data Available",description:e="No data to display for the selected period",height:o="300px",className:a})=>jsx(Box,{className:cn("oui-w-full oui-flex oui-items-center oui-justify-center oui-bg-base-8",a),style:{height:o},children:jsxs(Flex,{direction:"column",itemAlign:"center",gap:3,className:"oui-text-center",children:[jsx(BarChartIcon,{}),jsx(Text,{as:"div",size:"sm",weight:"semibold",className:"oui-text-base-contrast-100",children:t}),jsx(Text,{as:"div",size:"xs",className:"oui-text-base-contrast-54",children:e})]})});var lo=t=>{let{fill:e,x:o,y:a,width:r,height:i}=t,n=Math.abs(i);return jsx("rect",{rx:2,x:o,y:i>0?a:a+i,width:r,height:n,stroke:"none",fill:e})},co=t=>{let{width:e,height:o}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},xt=t=>`${t>0?"+":""}${t.toFixed(2)}`,mo=(t,e)=>t===0?"inherit":t>0?e.profit:e.loss,uo=t=>e=>{let{active:o,payload:a,label:r}=e,i=p();if(o&&a&&a.length>=1){let s=a.find(x=>x.dataKey==="pnl")?.value??0,c=r,l=mo(s,i);return jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsxs("span",{className:"oui-text-base-contrast-54",children:[c,":"]}),jsxs("span",{className:"oui-font-semibold",style:{color:l},children:[xt(s)," USDC"]})]}),t&&jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Cumulative:"}),jsxs("span",{className:"oui-font-semibold",children:[(()=>{let P=a.find(m=>m.dataKey==="cumulativePnL")?.value??0;return xt(P)})()," ","USDC"]})]})]})}return null},po=(t,e,o=false)=>{if(t<=12&&!o)return 0;let a;t>500||t>200?a=6:t>100?a=7:t>50?a=8:a=12,o&&(a=Math.ceil(a/2));let r=Math.ceil(t/a);if(e==="15m")return r>=96?Math.ceil(r/56)*56:r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/16)*16:Math.max(8,Math.ceil(r/4)*4);if(e==="1h")return r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/12)*12:Math.max(4,Math.ceil(r/4)*4);if(e==="1d"){if(r>=14)return Math.ceil(r/14)*14;if(r>=3)return Math.ceil(r/7)*7}return r},fo=t=>{let e=0;return t.map(o=>(e+=o.pnl,{...o,cumulativePnL:e}))},ho=t=>{let{data:e,aggregationWindow:o="1d",isMobile:a=false,invisible:r,responsiveContainerProps:i,className:n,showCumulative:s=true}=t,c=p(t.colors),l=useMemo(()=>fo(e),[e]),x=useMemo(()=>po(l.length,o,a),[l.length,o,a]),P=useMemo(()=>{if(l.length===0)return [0,1];let m=l.map(I=>I.pnl),g=s?l.map(I=>I.cumulativePnL):[],D=s?[...m,...g,0]:[...m,0],R=Math.min(...D),E=Math.max(...D),A=E-R;if(A===0)return [0,1];let F=A*.1,S=R-F,V=E+F,M=Math.pow(10,Math.floor(Math.log10(A))),T=Math.ceil((V-S)/5/M)*M,k=Math.floor(S/T)*T,Y=Math.ceil(V/T)*T;return [k,Y]},[l,s]);return r||l.length===0?jsx(G,{title:"No P&L Data",description:"No profit and loss data available for the selected period",height:"100%",className:n}):jsx(Box,{className:cn("oui-w-full oui-h-full",n),children:jsx(ResponsiveContainer,{width:"100%",height:"100%",...i,children:jsxs(ComposedChart,{data:l,margin:{left:45,top:10,right:50,bottom:20},syncId:"symbol-performance",children:[jsx("defs",{children:jsxs("linearGradient",{id:"cumulativeGradient",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{offset:"5%",stopColor:"#608CFF",stopOpacity:.4}),jsx("stop",{offset:"95%",stopColor:"#608CFF",stopOpacity:0})]})}),jsx(Tooltip,{cursor:jsx(co,{}),content:uo(s)}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(ReferenceLine,{y:0,stroke:"rgba(255,255,255,0.3)",strokeWidth:2,strokeDasharray:"4 4"}),jsx(YAxis,{domain:P,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:m=>yo(m),width:45}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:x,minTickGap:30,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"#FFFFFF",strokeOpacity:.04}),jsx(Bar,{dataKey:"pnl",shape:jsx(lo,{}),minPointSize:1,isAnimationActive:false,children:l.map((m,g)=>jsx(Cell,{fill:m.pnl===0?"rgba(255,255,255,0.2)":m.pnl>0?c.profit:c.loss},`cell-${g}`))}),s&&jsx(Area,{type:"natural",dataKey:"cumulativePnL",fill:"url(#cumulativeGradient)",stroke:"none",isAnimationActive:false}),s&&jsx(Line,{type:"natural",dataKey:"cumulativePnL",stroke:c.primary,strokeWidth:2,dot:false,isAnimationActive:false,strokeLinecap:"round",strokeLinejoin:"round"})]})})})};function yo(t){let e=["","K","M","B","T"],o=0,a=Math.abs(t);for(;a>=1e3&&o<e.length-1;)a/=1e3,o++;let r=t<0?"-":"",i=a<=10?1:0,n=a.toFixed(i);return `${r}${n}${e[o]}`}var No=t=>{let{fill:e,x:o,y:a,width:r,height:i}=t,n=Math.abs(i);return jsx("rect",{rx:2,x:o,y:i>0?a:a+i,width:r,height:n,stroke:"none",fill:e})},Lo=t=>{let{width:e,height:o}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},vt=t=>`${t>0?"+":""}${t}`,Do=t=>e=>{let{active:o,payload:a,label:r}=e;if(o&&a&&a.length>=1){let n=a.find(c=>c.dataKey==="volume")?.value??0;return jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsxs("span",{className:"oui-text-base-contrast-54",children:[r,":"]}),jsxs("span",{className:"oui-font-semibold",children:[vt(n)," USDC"]})]}),t&&jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Cumulative:"}),jsxs("span",{className:"oui-font-semibold",children:[(()=>{let l=a.find(x=>x.dataKey==="cumulativeVolume")?.value??0;return vt(l)})()," ","USDC"]})]})]})}return null},Oo=(t,e,o=false)=>{if(t<=12&&!o)return 0;let a;t>500||t>200?a=6:t>100?a=7:t>50?a=8:a=12,o&&(a=Math.ceil(a/2));let r=Math.ceil(t/a);if(e==="15m")return r>=96?Math.ceil(r/56)*56:r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/16)*16:Math.max(8,Math.ceil(r/4)*4);if(e==="1h")return r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/12)*12:Math.max(4,Math.ceil(r/4)*4);if(e==="1d"){if(r>=14)return Math.ceil(r/14)*14;if(r>=3)return Math.ceil(r/7)*7}return r},So=t=>{let e=0;return t.map(o=>(e+=o.volume,{...o,cumulativeVolume:e}))},Io=t=>{let{data:e,aggregationWindow:o="1d",isMobile:a=false,invisible:r,responsiveContainerProps:i,className:n,showCumulative:s=false}=t,c=p(t.colors?{profit:t.colors.fill,loss:t.colors.fill}:void 0),l=useMemo(()=>So(e),[e]),x=useMemo(()=>Oo(l.length,o,a),[l.length,o,a]),P=useMemo(()=>{if(l.length===0)return [0,1];let m=l.map(M=>M.volume),g=s?l.map(M=>M.cumulativeVolume):[],D=Math.max(...s?[...m,...g]:m,0),R=D;if(R===0)return [0,1];let E=R*.1,A=D+E,F=Math.pow(10,Math.floor(Math.log10(R))),S=Math.ceil(A/5/F)*F;return [0,Math.ceil(A/S)*S]},[l,s]);return r||l.length===0?jsx(G,{title:"No Volume Data",description:"No trading volume data available for the selected period",height:"100%",className:n}):jsx(Box,{className:cn("oui-w-full oui-h-full",n),children:jsx(ResponsiveContainer,{width:"100%",height:"100%",...i,children:jsxs(ComposedChart,{data:l,margin:{left:45,top:10,right:50,bottom:20},syncId:"symbol-performance",children:[jsx("defs",{children:jsxs("linearGradient",{id:"volumeGradient",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{offset:"5%",stopColor:"#00B49E",stopOpacity:.4}),jsx("stop",{offset:"95%",stopColor:"#00B49E",stopOpacity:0})]})}),jsx(Tooltip,{cursor:jsx(Lo,{}),content:Do(s)}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(ReferenceLine,{y:0,stroke:"rgba(0,0,0,0.04)"}),jsx(YAxis,{domain:P,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:m=>Vo(m),width:45}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:x,minTickGap:30,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"#FFFFFF",strokeOpacity:.04}),jsx(Bar,{dataKey:"volume",shape:jsx(No,{}),minPointSize:1,isAnimationActive:false,children:l.map((m,g)=>jsx(Cell,{fill:m.volume===0?"rgba(255,255,255,0.2)":c.profit,opacity:.8},`cell-${g}`))}),s&&jsx(Area,{type:"natural",dataKey:"cumulativeVolume",fill:"url(#volumeGradient)",stroke:"none",isAnimationActive:false}),s&&jsx(Line,{type:"natural",dataKey:"cumulativeVolume",stroke:c.profit,strokeWidth:2,dot:false,isAnimationActive:false,strokeLinecap:"round",strokeLinejoin:"round"})]})})})};function Vo(t){let e=["","K","M","B","T"],o=0,a=Math.abs(t);for(;a>=1e3&&o<e.length-1;)a/=1e3,o++;let r=t<0?"-":"",i=a<=10?1:0,n=a.toFixed(i);return `${r}${n}${e[o]}`}var Qo=t=>{let{fill:e,x:o,y:a,width:r,height:i}=t,n=Math.abs(i);return jsx("rect",{rx:2,x:o,y:i>0?a:a+i,width:r,height:n,stroke:"none",fill:e})},Jo=t=>{let{width:e,height:o}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},kt=t=>`${t>0?"+":""}${t.toFixed(2)}`,Zo=t=>e=>{let{active:o,payload:a,label:r}=e;if(o&&a&&a.length>=1){let n=a.find(c=>c.dataKey==="fees")?.value??0;return jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsxs("span",{className:"oui-text-base-contrast-54",children:[r,":"]}),jsxs("span",{className:"oui-font-semibold",children:[kt(n)," USDC"]})]}),t&&jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Cumulative:"}),jsxs("span",{className:"oui-font-semibold",children:[(()=>{let l=a.find(x=>x.dataKey==="cumulativeFees")?.value??0;return kt(l)})()," ","USDC"]})]})]})}return null},jo=(t,e,o=false)=>{if(t<=12&&!o)return 0;let a;t>500||t>200?a=6:t>100?a=7:t>50?a=8:a=12,o&&(a=Math.ceil(a/2));let r=Math.ceil(t/a);if(e==="15m")return r>=96?Math.ceil(r/56)*56:r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/16)*16:Math.max(8,Math.ceil(r/4)*4);if(e==="1h")return r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/12)*12:Math.max(4,Math.ceil(r/4)*4);if(e==="1d"){if(r>=14)return Math.ceil(r/14)*14;if(r>=3)return Math.ceil(r/7)*7}return r},ta=t=>{let e=0;return t.map(o=>(e+=o.fees,{...o,cumulativeFees:e}))},ea=t=>{let{data:e,aggregationWindow:o="1d",isMobile:a=false,invisible:r,responsiveContainerProps:i,className:n,showCumulative:s=false}=t,c=p(t.colors?{profit:t.colors.fill,loss:t.colors.fill}:void 0),l=useMemo(()=>ta(e),[e]),x=useMemo(()=>jo(l.length,o,a),[l.length,o,a]),P=useMemo(()=>{if(l.length===0)return {domain:[0,1],ticks:[0,1]};let m=l.map(B=>B.fees),g=s?l.map(B=>B.cumulativeFees):[],D=s?[...m,...g,0]:[...m,0],R=Math.min(...D),A=Math.max(...D)-R;if(A===0)return {domain:[0,1],ticks:[0,1]};let F=A*.1,S=R-F,V=0,M=Math.pow(10,Math.floor(Math.log10(A))),T=M,k=Math.abs(V-S);for(let B of [1,2,2.5,5]){let lt=M*B,ct=Math.ceil(k/lt);if(ct>=4&&ct<=6){T=lt;break}}let Y=Math.floor(S/T)*T,I=[];for(let B=Y;B<V;B+=T)I.push(Number(B.toFixed(10)));return I.push(0),{domain:[Y,0],ticks:I}},[l,s]);return r||l.length===0?jsx(G,{title:"No Fees Data",description:"No fees data available for the selected period",height:"100%",className:n}):jsx(Box,{className:cn("oui-w-full oui-h-full",n),children:jsx(ResponsiveContainer,{width:"100%",height:"100%",...i,children:jsxs(ComposedChart,{data:l,margin:{left:45,top:10,right:50,bottom:20},syncId:"symbol-performance",children:[jsx("defs",{children:jsxs("linearGradient",{id:"feesGradient",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{offset:"5%",stopColor:"#FF6B6B",stopOpacity:.4}),jsx("stop",{offset:"95%",stopColor:"#FF6B6B",stopOpacity:0})]})}),jsx(Tooltip,{cursor:jsx(Jo,{}),content:Zo(s)}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(ReferenceLine,{y:0,stroke:"rgba(0,0,0,0.04)"}),jsx(YAxis,{domain:P.domain,ticks:P.ticks,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:m=>oa(m),width:45}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:x,minTickGap:30,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"#FFFFFF",strokeOpacity:.04}),jsx(Bar,{dataKey:"fees",shape:jsx(Qo,{}),minPointSize:1,isAnimationActive:false,children:l.map((m,g)=>jsx(Cell,{fill:m.fees===0?"rgba(255,255,255,0.2)":c.loss,opacity:.8},`cell-${g}`))}),s&&jsx(Area,{type:"natural",dataKey:"cumulativeFees",fill:"url(#feesGradient)",stroke:"none",isAnimationActive:false}),s&&jsx(Line,{type:"natural",dataKey:"cumulativeFees",stroke:c.loss,strokeWidth:2,dot:false,isAnimationActive:false,strokeLinecap:"round",strokeLinejoin:"round"})]})})})};function oa(t){let e=["","K","M","B","T"],o=0,a=Math.abs(t);for(;a>=1e3&&o<e.length-1;)a/=1e3,o++;let r=t<0?"-":"",i=a<=10?1:0,n=a.toFixed(i);return `${r}${n}${e[o]}`}var da=t=>{let{width:e,height:o}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},fa=t=>{let{active:e,payload:o,label:a}=t;if(e&&o&&o.length>=1){let r=o[0].payload;return r.close!==null&&r.close!==void 0?jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Open:"}),jsx("span",{className:"oui-font-semibold",children:r.open?.toFixed(2)??"--"})]}),jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"High:"}),jsx("span",{className:"oui-font-semibold",children:r.high?.toFixed(2)??"--"})]}),jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Low:"}),jsx("span",{className:"oui-font-semibold",children:r.low?.toFixed(2)??"--"})]}),jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Close:"}),jsx("span",{className:"oui-font-semibold",children:r.close.toFixed(2)})]}),jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2 oui-mt-1 oui-pt-2 oui-border-t oui-border-base-contrast-16",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Time:"}),jsx("span",{className:"oui-font-semibold",children:a})]})]}):jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsx("div",{className:"oui-text-xs oui-text-base-contrast-54",children:"Price data unavailable"}),jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2 oui-mt-1 oui-pt-2 oui-border-t oui-border-base-contrast-16",children:[jsx("span",{className:"oui-text-base-contrast-54",children:"Time:"}),jsx("span",{className:"oui-font-semibold",children:a})]})]})}return null},ha=(t,e,o=false)=>{if(t<=12&&!o)return 0;let a;t>500||t>200?a=6:t>100?a=7:t>50?a=8:a=12,o&&(a=Math.ceil(a/2));let r=Math.ceil(t/a);if(e==="15m")return r>=96?Math.ceil(r/56)*56:r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/16)*16:Math.max(8,Math.ceil(r/4)*4);if(e==="1h")return r>=48?Math.ceil(r/28)*28:r>=24?Math.ceil(r/12)*12:Math.max(4,Math.ceil(r/4)*4);if(e==="1d"){if(r>=14)return Math.ceil(r/14)*14;if(r>=3)return Math.ceil(r/7)*7}return r};function ya(t){return t.toFixed(2)}var Ca=t=>{let {data:e,aggregationWindow:o="1d",isMobile:a=false,invisible:r,responsiveContainerProps:i,className:n}=t;p();let c=useMemo(()=>ha(e.length,o,a),[e.length,o,a]),l=useMemo(()=>{if(e.length===0)return {domain:[0,1],ticks:[0,1]};let x=e.map(k=>k.close).filter(k=>k!=null);if(x.length===0)return {domain:[0,1],ticks:[0,1]};let P=Math.min(...x),m=Math.max(...x),g=m-P;if(g===0)return {domain:[P-1,m+1],ticks:[P-1,m+1]};let D=g*.1,R=P-D,E=m+D,A=Math.pow(10,Math.floor(Math.log10(g))),F=A,S=E-R;for(let k of [1,2,2.5,5]){let Y=A*k,I=Math.ceil(S/Y);if(I>=4&&I<=6){F=Y;break}}let V=Math.floor(R/F)*F,M=Math.ceil(E/F)*F,T=[];for(let k=V;k<=M;k+=F)T.push(Number(k.toFixed(10)));return {domain:[V,M],ticks:T}},[e]);return r||e.length===0?jsx(G,{title:"No Price Data",description:"No price data available for the selected period",height:"100%",className:n}):jsx(Box,{className:cn("oui-w-full oui-h-full",n),children:jsx(ResponsiveContainer,{width:"100%",height:"100%",...i,children:jsxs(ComposedChart,{data:e,margin:{left:45,top:10,right:50,bottom:20},syncId:"symbol-performance",children:[jsx(Tooltip,{cursor:jsx(da,{}),content:jsx(fa,{})}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(ReferenceLine,{y:0,stroke:"rgba(0,0,0,0.04)"}),jsx(YAxis,{domain:l.domain,ticks:l.ticks,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:ya,width:50}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:c,minTickGap:50,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"#FFFFFF",strokeOpacity:.04}),jsx(Line,{type:"natural",dataKey:"close",stroke:"#00B49E",strokeWidth:2,dot:false,isAnimationActive:false,strokeLinecap:"round",strokeLinejoin:"round"})]})})})};var Ta=t=>{let{active:e,payload:o,label:a}=t,r=useRef(new Date().toISOString().split("T")[0]),{t:i}=useTranslation();return e&&o&&o.length?jsx(w,{label:a===r.current?i("chart.now"):a,value:o[0].value}):null},wa=t=>{let{responsiveContainerProps:e}=t,o=p(t.colors),a=useId(),{isMobile:r}=useScreen(),i=r?jsxs(AreaChart,{width:530,height:180,data:t.data,margin:{top:20,right:10,left:-20,bottom:-10},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",interval:t.data.length-2,tick:jsx(z,{}),stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{dataKey:"account_value",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:n=>O(n)}),!t.invisible&&jsxs(Fragment,{children:[jsx("defs",{children:jsxs("linearGradient",{id:a,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{stopColor:"#00B49E",offset:"0%",stopOpacity:.5}),jsx("stop",{stopColor:"#00B49E",offset:"100%",stopOpacity:0})]})}),jsx(Area,{type:"natural",dataKey:"account_value",stroke:o.profit,strokeWidth:r?1.5:2,dot:false,isAnimationActive:false,fill:`url(#${a})`})]})]}):jsxs(LineChart,{width:530,height:180,data:t.data,margin:{top:20,right:10,left:-20,bottom:-10},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",interval:t.data.length-2,tick:jsx(z,{}),stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{dataKey:"account_value",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:O}),!t.invisible&&jsx(Tooltip,{cursor:{strokeDasharray:"3 2",strokeOpacity:.16},content:jsx(Ta,{})}),!t.invisible&&jsx(Line,{type:"natural",dataKey:"account_value",stroke:o.profit,strokeWidth:r?1.5:2,dot:false,isAnimationActive:false})]});return jsx(ResponsiveContainer,{className:t.invisible?"chart-invisible":void 0,...e,children:i})};var $a=t=>{let{active:e,payload:o,label:a}=t,r=useRef(new Date().toISOString().split("T")[0]),{t:i}=useTranslation();return e&&o&&o.length?jsx(w,{label:a===r.current?i("chart.now"):a,value:o[0].value}):null},Ea=t=>{let{responsiveContainerProps:e}=t,o=p(t.colors),a=useId(),{isMobile:r}=useScreen(),i=jsxs(AreaChart,{width:530,height:180,data:t.data,margin:{top:20,right:10,left:-20,bottom:-10},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",interval:t.data.length-2,tick:jsx(z,{}),stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{dataKey:"account_value",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,tickFormatter:O}),!t.invisible&&jsx(Tooltip,{cursor:{strokeDasharray:"3 2",strokeOpacity:.16},content:jsx($a,{})}),!t.invisible&&jsxs(Fragment,{children:[jsx("defs",{children:jsxs("linearGradient",{id:a,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx("stop",{stopColor:"#00B49E",offset:"0%",stopOpacity:.5}),jsx("stop",{stopColor:"#00B49E",offset:"100%",stopOpacity:0})]})}),jsx(Area,{type:"natural",dataKey:"account_value",stroke:o.profit,strokeWidth:r?1.5:2,dot:false,isAnimationActive:false,fill:`url(#${a})`})]})]});return jsx(ResponsiveContainer,{className:t.invisible?"chart-invisible":void 0,...e,children:i})};var ar=t=>{let{fill:e,x:o,y:a,width:r,height:i,opacity:n}=t,s=Math.abs(i);return jsx("rect",{rx:2,x:o,y:i>0?a:a+i,width:r,height:s,stroke:"none",fill:e,opacity:n})},rr=t=>{let{width:e,height:o,payload:a,stroke:r,fill:i}=t;return a?.[0]?.value===0?null:jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},ir=t=>{let{active:e,payload:o,label:a,tooltip:r}=t;return o?.[0]?.value===0?null:e&&o&&o.length?jsx(w,{label:a,value:o[0].value,titleClassName:"oui-gap-4",rm:r?.rm,dp:r?.dp}):null},nr=t=>{let e=p(t.colors?.fill?{profit:t.colors?.fill,loss:t.colors?.fill}:void 0),o=t.data?.reduce((i,n)=>i+n.volume,0)===0,a=t.data?.reduce((i,n)=>i>n.volume?i:n.volume,0),r=a<=10?2:a<=100?1:0;return jsx(Box,{className:cn(t.className),children:jsx(ResponsiveContainer,{children:jsxs(BarChart,{data:t.data,margin:{left:-0,top:6,right:0,bottom:20},children:[jsx(Tooltip,{cursor:jsx(rr,{}),content:jsx(ir,{tooltip:t.tooltip})}),jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.08,repeatCount:6}),jsx(ReferenceLine,{y:0,stroke:"#000"}),jsx(Bar,{dataKey:"volume",shape:jsx(ar,{}),minPointSize:1,children:t.data.map((i,n)=>jsx(Cell,{fill:i.volume>0?e.profit:e.loss,opacity:i.opacity},`cell-${n}`))}),jsx(YAxis,{tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,dataKey:"volume",tickFormatter:(i,n)=>o?`${n*100}`:sr(i,r),width:45}),jsx(XAxis,{dataKey:"date",tickLine:false,interval:t.data.length-2,height:1,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"rgb(229, 231, 235)",strokeOpacity:.2})]})})})};function sr(t,e=0){let o=["","K","M","B","T"],a=0;for(;t>=1e3&&a<o.length-1;)t/=1e3,a++;return `${lr(t,e)}${o[a]}`}function lr(t,e){let o=t.toString(),a=o.indexOf(".");if(a===-1||e===0)return o.split(".")[0];let r=a+e+1;return o.slice(0,r)}var xr=t=>{let{width:e,height:o}=t;return jsx(Cross,{x:t.x+t.width/2,top:t.top,height:o,width:1,stroke:"rgba(255,255,255,0.16)",strokeDasharray:"3 2",fill:"none"})},gr=t=>{let{active:e,payload:o,label:a}=t;return e&&o&&o.length>0?jsxs(Box,{intensity:600,p:3,r:"md",className:"oui-flex oui-flex-col oui-gap-2",children:[jsx("div",{className:"oui-text-xs oui-font-semibold",children:a}),o.map((r,i)=>jsxs("div",{className:"oui-text-xs oui-flex oui-gap-2",children:[jsxs("span",{style:{color:r.color},className:"oui-font-semibold",children:[r.name,":"]}),jsx("span",{children:r.value?.toFixed(2)||0})]},i))]}):null},vr=({volumeData:t,feesData:e,priceData:o,aggregationWindow:a,includeFees:r,className:i})=>{let n=useMemo(()=>{let s=new Map;return t.forEach(c=>{s.set(c.date,{...s.get(c.date),date:c.date,volume:c.volume});}),e.forEach(c=>{s.set(c.date,{...s.get(c.date),date:c.date,fees:c.fees});}),o.forEach(c=>{s.set(c.date,{...s.get(c.date),date:c.date,open:c.open,high:c.high,low:c.low,close:c.close});}),Array.from(s.values())},[t,e,o]);return n.length===0?jsx(Box,{className:cn("oui-w-full oui-h-full",i),children:jsx("div",{className:"oui-text-center oui-text-base-contrast-54 oui-py-10",children:"No data available"})}):jsx(Box,{className:cn("oui-w-full oui-h-full",i),children:jsx(ResponsiveContainer,{width:"100%",height:"100%",children:jsxs(ComposedChart,{data:n,margin:{left:0,top:10,right:10,bottom:20},children:[jsx(CartesianGrid,{vertical:false,stroke:"#FFFFFF",strokeOpacity:.04}),jsx(XAxis,{dataKey:"date",tickLine:false,tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},stroke:"#FFFFFF",strokeOpacity:.04}),jsx(YAxis,{yAxisId:"left",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,width:45,label:{value:"Volume / Fees",angle:-90,position:"insideLeft"}}),jsx(YAxis,{yAxisId:"right",orientation:"right",tick:{fontSize:10,fill:"rgba(255,255,255,0.54)"},tickLine:false,axisLine:false,width:50,label:{value:"Price",angle:90,position:"insideRight"}}),jsx(Tooltip,{cursor:jsx(xr,{}),content:jsx(gr,{})}),jsx(ReferenceLine,{y:0,stroke:"rgba(0,0,0,0.04)"}),jsx(Bar,{yAxisId:"left",dataKey:"volume",fill:"rgba(0, 180, 158, 0.6)",name:"Volume"}),jsx(Bar,{yAxisId:"left",dataKey:"fees",fill:"rgba(255, 107, 107, 0.6)",name:"Fees"}),jsx(Line,{yAxisId:"right",type:"natural",dataKey:"close",stroke:"#00B49E",strokeWidth:2,dot:false,isAnimationActive:false,name:"Price",strokeLinecap:"round",strokeLinejoin:"round"})]})})})};var Bt=Wt(Vt()),Rr=()=>(0, Bt.default)(function({addComponents:t,addBase:e}){t({".xAxis":{".recharts-cartesian-axis-tick:first-child text":{"text-anchor":"start"},".recharts-cartesian-axis-tick:last-child text":{"text-anchor":"end"}}},{respectPrefix:false});});export{Ea as AssetAreaChart,wa as AssetLineChart,G as ChartEmptyState,ea as CombinedFeesChart,ho as CombinedPnLChart,Ca as CombinedPriceChart,Io as CombinedVolumeChart,me as PnLBarChart,$e as PnlAreaChart,Re as PnlLineChart,vr as UnifiedSymbolPerformanceChart,nr as VolBarChart,Rr as chartPlugin};//# sourceMappingURL=index.mjs.map
1
+ import { useRef, useMemo, useId } from 'react';
2
+ import { ResponsiveContainer, BarChart, Tooltip, CartesianGrid, ReferenceLine, Bar, Cell, YAxis, XAxis, LineChart, Line, AreaChart, Area, ComposedChart, Cross } from 'recharts';
3
+ export { Area, AreaChart, Bar, BarChart, Cell, Line, LineChart } from 'recharts';
4
+ import { useTranslation } from '@kodiak-finance/orderly-i18n';
5
+ import { cn, useScreen, Box, Flex, BarChartIcon, Text } from '@kodiak-finance/orderly-ui';
6
+ import { numberToHumanStyle } from '@kodiak-finance/orderly-utils';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ var __create = Object.create;
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __getProtoOf = Object.getPrototypeOf;
14
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
15
+ var __commonJS = (cb, mod) => function __require() {
16
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
34
+
35
+ // ../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/lib/util/createPlugin.js
36
+ var require_createPlugin = __commonJS({
37
+ "../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/lib/util/createPlugin.js"(exports) {
38
+ Object.defineProperty(exports, "__esModule", {
39
+ value: true
40
+ });
41
+ Object.defineProperty(exports, "default", {
42
+ enumerable: true,
43
+ get: function() {
44
+ return _default;
45
+ }
46
+ });
47
+ function createPlugin(plugin2, config) {
48
+ return {
49
+ handler: plugin2,
50
+ config
51
+ };
52
+ }
53
+ createPlugin.withOptions = function(pluginFunction, configFunction = () => ({})) {
54
+ const optionsFunction = function(options) {
55
+ return {
56
+ __options: options,
57
+ handler: pluginFunction(options),
58
+ config: configFunction(options)
59
+ };
60
+ };
61
+ optionsFunction.__isOptionsFunction = true;
62
+ optionsFunction.__pluginFunction = pluginFunction;
63
+ optionsFunction.__configFunction = configFunction;
64
+ return optionsFunction;
65
+ };
66
+ var _default = createPlugin;
67
+ }
68
+ });
69
+
70
+ // ../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/lib/public/create-plugin.js
71
+ var require_create_plugin = __commonJS({
72
+ "../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/lib/public/create-plugin.js"(exports) {
73
+ Object.defineProperty(exports, "__esModule", {
74
+ value: true
75
+ });
76
+ Object.defineProperty(exports, "default", {
77
+ enumerable: true,
78
+ get: function() {
79
+ return _default;
80
+ }
81
+ });
82
+ var _createPlugin = /* @__PURE__ */ _interop_require_default(require_createPlugin());
83
+ function _interop_require_default(obj) {
84
+ return obj && obj.__esModule ? obj : {
85
+ default: obj
86
+ };
87
+ }
88
+ var _default = _createPlugin.default;
89
+ }
90
+ });
91
+
92
+ // ../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/plugin.js
93
+ var require_plugin = __commonJS({
94
+ "../../node_modules/.pnpm/tailwindcss@3.4.17_ts-node@10.9.2_@swc+core@1.13.2_@swc+helpers@0.5.17__@types+node@24.3.1_typescript@5.8.3_/node_modules/tailwindcss/plugin.js"(exports, module) {
95
+ var createPlugin = require_create_plugin();
96
+ module.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default;
97
+ }
98
+ });
99
+ var tickFormatter = (value) => {
100
+ const absValue = Math.abs(value);
101
+ const dp = absValue === 0 ? 0 : absValue <= 10 ? 2 : absValue <= 100 ? 1 : 0;
102
+ const formatted = numberToHumanStyle(absValue, dp);
103
+ return value < 0 ? `-${formatted}` : formatted;
104
+ };
105
+ var OrderlyChartTooltip = (props) => {
106
+ const {
107
+ label,
108
+ value,
109
+ prefix,
110
+ unit = "USDC",
111
+ coloring = false,
112
+ dp,
113
+ rm
114
+ } = props;
115
+ return /* @__PURE__ */ jsxs(Box, { intensity: 600, p: 3, r: "md", children: [
116
+ /* @__PURE__ */ jsxs(Flex, { direction: "row", className: props.titleClassName, children: [
117
+ prefix,
118
+ /* @__PURE__ */ jsx(
119
+ Text.numeral,
120
+ {
121
+ unit,
122
+ as: "div",
123
+ size: "sm",
124
+ coloring,
125
+ showIdentifier: coloring,
126
+ unitClassName: "oui-text-base-contrast-54 oui-ml-1",
127
+ weight: "semibold",
128
+ rm,
129
+ dp,
130
+ children: value
131
+ }
132
+ )
133
+ ] }),
134
+ /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 54, weight: "semibold", children: label })
135
+ ] });
136
+ };
137
+
138
+ // src/utils/theme.ts
139
+ var getThemeColors = () => {
140
+ const root = document.documentElement;
141
+ const computedStyle = getComputedStyle(root);
142
+ const colors = {
143
+ primary: convertToRGB(
144
+ computedStyle.getPropertyValue("--oui-color-primary")
145
+ ),
146
+ primaryLight: convertToRGB(
147
+ computedStyle.getPropertyValue("--oui-color-primary-light")
148
+ ),
149
+ secondary: convertToRGB(
150
+ computedStyle.getPropertyValue("--oui-color-secondary")
151
+ ),
152
+ success: convertToRGB(
153
+ computedStyle.getPropertyValue("--oui-color-success")
154
+ ),
155
+ warning: convertToRGB(
156
+ computedStyle.getPropertyValue("--oui-color-warning")
157
+ ),
158
+ danger: convertToRGB(computedStyle.getPropertyValue("--oui-color-danger")),
159
+ info: convertToRGB(computedStyle.getPropertyValue("--oui-color-info")),
160
+ loss: convertToRGB(
161
+ computedStyle.getPropertyValue("--oui-color-trading-loss")
162
+ ),
163
+ profit: convertToRGB(
164
+ computedStyle.getPropertyValue("--oui-color-trading-profit")
165
+ )
166
+ };
167
+ return colors;
168
+ };
169
+ var convertToRGB = (color) => {
170
+ return `rgb(${color.split(" ").join(",")})`;
171
+ };
172
+
173
+ // src/orderly/useColors.ts
174
+ var useColors = (colors) => {
175
+ const _colors = useMemo(() => {
176
+ const themeColors = getThemeColors();
177
+ return {
178
+ profit: colors?.profit || themeColors.profit,
179
+ loss: colors?.loss || themeColors.loss,
180
+ primary: themeColors.primary,
181
+ primaryLight: themeColors.primaryLight
182
+ };
183
+ }, [colors]);
184
+ return _colors;
185
+ };
186
+ var RoundedRectangle = (props) => {
187
+ const { fill, x, y, width, height } = props;
188
+ const absHeight = Math.abs(height);
189
+ return /* @__PURE__ */ jsx(
190
+ "rect",
191
+ {
192
+ rx: 2,
193
+ x,
194
+ y: height > 0 ? y : y + height,
195
+ width,
196
+ height: absHeight,
197
+ stroke: "none",
198
+ fill
199
+ }
200
+ );
201
+ };
202
+ var XAxisLabel = (props) => {
203
+ const { x, y, stroke, payload, index, width, containerWidth } = props;
204
+ const { t } = useTranslation();
205
+ const _x = index === 0 ? 48 : containerWidth > 0 ? containerWidth - 10 : width + payload.offset;
206
+ return /* @__PURE__ */ jsx("g", { transform: `translate(${_x},${y - 6})`, children: /* @__PURE__ */ jsx(
207
+ "text",
208
+ {
209
+ x: 0,
210
+ y: 0,
211
+ dy: 16,
212
+ textAnchor: index === 0 ? "start" : "end",
213
+ fontSize: 10,
214
+ fill: "rgba(255,255,255,0.54)",
215
+ children: index === 0 ? payload.value : t("chart.now")
216
+ }
217
+ ) });
218
+ };
219
+ var CustomizedCross = (props) => {
220
+ const { width, height, stroke, fill } = props;
221
+ return /* @__PURE__ */ jsx(
222
+ Cross,
223
+ {
224
+ x: props.x + props.width / 2,
225
+ top: props.top,
226
+ height,
227
+ width: 1,
228
+ stroke: "rgba(255,255,255,0.16)",
229
+ strokeDasharray: "3 2",
230
+ fill: "none"
231
+ }
232
+ );
233
+ };
234
+ var CustomTooltip = (props) => {
235
+ const { active, payload, label } = props;
236
+ const todayStr = useRef((/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
237
+ const { t } = useTranslation();
238
+ if (active && payload && payload.length) {
239
+ return /* @__PURE__ */ jsx(
240
+ OrderlyChartTooltip,
241
+ {
242
+ label: label === todayStr.current ? t("chart.now") : label,
243
+ value: payload[0].value,
244
+ coloring: true
245
+ }
246
+ );
247
+ }
248
+ return null;
249
+ };
250
+ var PnLBarChart = (props) => {
251
+ const { invisible, data, responsiveContainerProps } = props;
252
+ const colors = useColors(props.colors);
253
+ const widthRef = useRef(0);
254
+ return /* @__PURE__ */ jsx(
255
+ ResponsiveContainer,
256
+ {
257
+ className: cn(invisible && "chart-invisible"),
258
+ onResize: (width) => {
259
+ widthRef.current = width;
260
+ },
261
+ ...responsiveContainerProps,
262
+ children: /* @__PURE__ */ jsxs(
263
+ BarChart,
264
+ {
265
+ data,
266
+ margin: { left: -10, top: 10, right: 10, bottom: 30 },
267
+ children: [
268
+ !invisible && /* @__PURE__ */ jsx(
269
+ Tooltip,
270
+ {
271
+ cursor: /* @__PURE__ */ jsx(CustomizedCross, {}),
272
+ content: /* @__PURE__ */ jsx(CustomTooltip, {})
273
+ }
274
+ ),
275
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
276
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "rgba(0,0,0,0.04)" }),
277
+ !invisible && /* @__PURE__ */ jsx(Bar, { dataKey: "pnl", shape: /* @__PURE__ */ jsx(RoundedRectangle, {}), children: data.map((entry, index) => {
278
+ return /* @__PURE__ */ jsx(
279
+ Cell,
280
+ {
281
+ fill: entry.pnl > 0 ? colors.profit : colors.loss
282
+ },
283
+ `cell-${index}`
284
+ );
285
+ }) }),
286
+ /* @__PURE__ */ jsx(
287
+ YAxis,
288
+ {
289
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
290
+ tickFormatter: (value) => tickFormatter(value),
291
+ tickLine: false,
292
+ axisLine: false,
293
+ dataKey: "pnl"
294
+ }
295
+ ),
296
+ /* @__PURE__ */ jsx(
297
+ XAxis,
298
+ {
299
+ dataKey: "date",
300
+ tickLine: false,
301
+ interval: data.length - 2,
302
+ height: 1,
303
+ tick: /* @__PURE__ */ jsx(XAxisLabel, { containerWidth: widthRef.current }),
304
+ stroke: "#FFFFFF",
305
+ strokeOpacity: 0.04
306
+ }
307
+ )
308
+ ]
309
+ }
310
+ )
311
+ }
312
+ );
313
+ };
314
+ var XAxisLabel2 = (props) => {
315
+ const { x, y, stroke, payload, index } = props;
316
+ const { t } = useTranslation();
317
+ return /* @__PURE__ */ jsx("g", { transform: `translate(${x},${y - 6})`, children: /* @__PURE__ */ jsx(
318
+ "text",
319
+ {
320
+ x: 0,
321
+ y: 0,
322
+ dy: 16,
323
+ textAnchor: "end",
324
+ fontSize: 10,
325
+ fill: "rgba(255,255,255,0.54)",
326
+ children: index === 0 ? payload.value : t("chart.now")
327
+ }
328
+ ) });
329
+ };
330
+ var CustomTooltip2 = (props) => {
331
+ const { active, payload, label } = props;
332
+ const todayStr = useRef((/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
333
+ const { t } = useTranslation();
334
+ if (active && payload && payload.length) {
335
+ return /* @__PURE__ */ jsx(
336
+ OrderlyChartTooltip,
337
+ {
338
+ label: label === todayStr.current ? t("chart.now") : label,
339
+ value: payload[0].value,
340
+ coloring: true
341
+ }
342
+ );
343
+ }
344
+ return null;
345
+ };
346
+ var dataTransfer = (data) => {
347
+ const series = [];
348
+ data?.reduce((acc, item) => {
349
+ acc += item.pnl;
350
+ series.push({ ...item, pnl: acc, _pnl: item.pnl });
351
+ return acc;
352
+ }, 0);
353
+ return series;
354
+ };
355
+ var PnlLineChart = (props) => {
356
+ const { responsiveContainerProps } = props;
357
+ const colors = useColors(props.colors);
358
+ const { isMobile } = useScreen();
359
+ const data = useMemo(() => dataTransfer(props.data), [props.data]);
360
+ const chartComponent = /* @__PURE__ */ jsxs(
361
+ LineChart,
362
+ {
363
+ data,
364
+ margin: { top: 20, right: 10, left: -10, bottom: 0 },
365
+ children: [
366
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
367
+ /* @__PURE__ */ jsx(
368
+ XAxis,
369
+ {
370
+ dataKey: "date",
371
+ interval: props.data.length - 2,
372
+ tick: /* @__PURE__ */ jsx(XAxisLabel2, {}),
373
+ stroke: "#FFFFFF",
374
+ strokeOpacity: 0.04
375
+ }
376
+ ),
377
+ /* @__PURE__ */ jsx(
378
+ YAxis,
379
+ {
380
+ dataKey: "pnl",
381
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
382
+ tickLine: false,
383
+ axisLine: false,
384
+ tickFormatter
385
+ }
386
+ ),
387
+ !props.invisible && /* @__PURE__ */ jsx(
388
+ Tooltip,
389
+ {
390
+ cursor: { strokeDasharray: "3 2", strokeOpacity: 0.16 },
391
+ content: /* @__PURE__ */ jsx(CustomTooltip2, {})
392
+ }
393
+ ),
394
+ !props.invisible && /* @__PURE__ */ jsx(
395
+ Line,
396
+ {
397
+ type: "natural",
398
+ dataKey: "pnl",
399
+ stroke: colors.primary,
400
+ strokeWidth: isMobile ? 1.5 : 2,
401
+ dot: false,
402
+ isAnimationActive: false
403
+ }
404
+ )
405
+ ]
406
+ }
407
+ );
408
+ return /* @__PURE__ */ jsx(
409
+ ResponsiveContainer,
410
+ {
411
+ className: props.invisible ? "chart-invisible" : void 0,
412
+ ...responsiveContainerProps,
413
+ children: chartComponent
414
+ }
415
+ );
416
+ };
417
+ var CustomTooltip3 = (props) => {
418
+ const { active, payload, label } = props;
419
+ const todayStr = useRef((/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
420
+ const { t } = useTranslation();
421
+ if (active && payload && payload.length) {
422
+ return /* @__PURE__ */ jsx(
423
+ OrderlyChartTooltip,
424
+ {
425
+ label: label === todayStr.current ? t("chart.now") : label,
426
+ value: payload[0].value,
427
+ coloring: true
428
+ }
429
+ );
430
+ }
431
+ return null;
432
+ };
433
+ var dataTransfer2 = (data) => {
434
+ const series = [];
435
+ data?.reduce((acc, item) => {
436
+ acc += item.pnl;
437
+ series.push({ ...item, pnl: acc, _pnl: item.pnl });
438
+ return acc;
439
+ }, 0);
440
+ return series;
441
+ };
442
+ var PnlAreaChart = (props) => {
443
+ const { responsiveContainerProps } = props;
444
+ const colors = useColors(props.colors);
445
+ const { isMobile } = useScreen();
446
+ const colorId = useId();
447
+ const data = useMemo(() => dataTransfer2(props.data), [props.data]);
448
+ const baseValue = useMemo(
449
+ () => data.map((item) => item.pnl).sort((a, b) => a - b)[0] || 0,
450
+ [data]
451
+ );
452
+ const chartComponent = /* @__PURE__ */ jsxs(
453
+ AreaChart,
454
+ {
455
+ data,
456
+ margin: { top: 20, right: 10, left: -10, bottom: 0 },
457
+ children: [
458
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
459
+ /* @__PURE__ */ jsx(
460
+ XAxis,
461
+ {
462
+ dataKey: "date",
463
+ interval: props.data.length - 2,
464
+ tick: /* @__PURE__ */ jsx(XAxisLabel2, {}),
465
+ stroke: "#FFFFFF",
466
+ strokeOpacity: 0.04
467
+ }
468
+ ),
469
+ /* @__PURE__ */ jsx(
470
+ YAxis,
471
+ {
472
+ dataKey: "pnl",
473
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
474
+ tickLine: false,
475
+ axisLine: false,
476
+ tickFormatter
477
+ }
478
+ ),
479
+ !props.invisible && /* @__PURE__ */ jsx(
480
+ Tooltip,
481
+ {
482
+ cursor: { strokeDasharray: "3 2", strokeOpacity: 0.16 },
483
+ content: /* @__PURE__ */ jsx(CustomTooltip3, {})
484
+ }
485
+ ),
486
+ !props.invisible && /* @__PURE__ */ jsxs(Fragment, { children: [
487
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: colorId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
488
+ /* @__PURE__ */ jsx("stop", { stopColor: colors.primary, offset: "0%", stopOpacity: 0.5 }),
489
+ /* @__PURE__ */ jsx("stop", { stopColor: colors.primary, offset: "100%", stopOpacity: 0 })
490
+ ] }) }),
491
+ /* @__PURE__ */ jsx(
492
+ Area,
493
+ {
494
+ type: "natural",
495
+ dataKey: "pnl",
496
+ stroke: colors.primary,
497
+ strokeWidth: isMobile ? 1.5 : 2,
498
+ dot: false,
499
+ isAnimationActive: false,
500
+ fill: `url(#${colorId})`,
501
+ baseValue: baseValue || 0
502
+ }
503
+ )
504
+ ] })
505
+ ]
506
+ }
507
+ );
508
+ return /* @__PURE__ */ jsx(
509
+ ResponsiveContainer,
510
+ {
511
+ className: props.invisible ? "chart-invisible" : void 0,
512
+ ...responsiveContainerProps,
513
+ children: chartComponent
514
+ }
515
+ );
516
+ };
517
+ var ChartEmptyState = ({
518
+ title = "No Data Available",
519
+ description = "No data to display for the selected period",
520
+ height = "300px",
521
+ className
522
+ }) => {
523
+ return /* @__PURE__ */ jsx(
524
+ Box,
525
+ {
526
+ className: cn(
527
+ "oui-w-full oui-flex oui-items-center oui-justify-center oui-bg-base-8",
528
+ className
529
+ ),
530
+ style: { height },
531
+ children: /* @__PURE__ */ jsxs(
532
+ Flex,
533
+ {
534
+ direction: "column",
535
+ itemAlign: "center",
536
+ gap: 3,
537
+ className: "oui-text-center",
538
+ children: [
539
+ /* @__PURE__ */ jsx(BarChartIcon, {}),
540
+ /* @__PURE__ */ jsx(
541
+ Text,
542
+ {
543
+ as: "div",
544
+ size: "sm",
545
+ weight: "semibold",
546
+ className: "oui-text-base-contrast-100",
547
+ children: title
548
+ }
549
+ ),
550
+ /* @__PURE__ */ jsx(Text, { as: "div", size: "xs", className: "oui-text-base-contrast-54", children: description })
551
+ ]
552
+ }
553
+ )
554
+ }
555
+ );
556
+ };
557
+ var RoundedRectangle2 = (props) => {
558
+ const { fill, x, y, width, height } = props;
559
+ const absHeight = Math.abs(height);
560
+ return /* @__PURE__ */ jsx(
561
+ "rect",
562
+ {
563
+ rx: 2,
564
+ x,
565
+ y: height > 0 ? y : y + height,
566
+ width,
567
+ height: absHeight,
568
+ stroke: "none",
569
+ fill
570
+ }
571
+ );
572
+ };
573
+ var CustomizedCross2 = (props) => {
574
+ const { width, height } = props;
575
+ return /* @__PURE__ */ jsx(
576
+ Cross,
577
+ {
578
+ x: props.x + props.width / 2,
579
+ top: props.top,
580
+ height,
581
+ width: 1,
582
+ stroke: "rgba(255,255,255,0.16)",
583
+ strokeDasharray: "3 2",
584
+ fill: "none"
585
+ }
586
+ );
587
+ };
588
+ var formatValueWithSign = (value) => {
589
+ const sign = value > 0 ? "+" : "";
590
+ return `${sign}${value.toFixed(2)}`;
591
+ };
592
+ var getValueColor = (value, colors) => {
593
+ if (value === 0) return "inherit";
594
+ return value > 0 ? colors.profit : colors.loss;
595
+ };
596
+ var createCustomTooltip = (showCumulative) => {
597
+ return (props) => {
598
+ const { active, payload, label } = props;
599
+ const colors = useColors();
600
+ if (active && payload && payload.length >= 1) {
601
+ const barData = payload.find((p) => p.dataKey === "pnl");
602
+ const barValue = barData?.value ?? 0;
603
+ const formattedDate = label;
604
+ const barColor = getValueColor(barValue, colors);
605
+ return /* @__PURE__ */ jsxs(
606
+ Box,
607
+ {
608
+ intensity: 600,
609
+ p: 3,
610
+ r: "md",
611
+ className: "oui-flex oui-flex-col oui-gap-2",
612
+ children: [
613
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
614
+ /* @__PURE__ */ jsxs("span", { className: "oui-text-base-contrast-54", children: [
615
+ formattedDate,
616
+ ":"
617
+ ] }),
618
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", style: { color: barColor }, children: [
619
+ formatValueWithSign(barValue),
620
+ " USDC"
621
+ ] })
622
+ ] }),
623
+ showCumulative && /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
624
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Cumulative:" }),
625
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", children: [
626
+ (() => {
627
+ const lineData = payload.find(
628
+ (p) => p.dataKey === "cumulativePnL"
629
+ );
630
+ const cumulativeValue = lineData?.value ?? 0;
631
+ return formatValueWithSign(cumulativeValue);
632
+ })(),
633
+ " ",
634
+ "USDC"
635
+ ] })
636
+ ] })
637
+ ]
638
+ }
639
+ );
640
+ }
641
+ return null;
642
+ };
643
+ };
644
+ var calculateOptimalInterval = (dataLength, aggregationWindow, isMobile = false) => {
645
+ if (dataLength <= 12 && !isMobile) return 0;
646
+ let targetLabels;
647
+ if (dataLength > 500) {
648
+ targetLabels = 6;
649
+ } else if (dataLength > 200) {
650
+ targetLabels = 6;
651
+ } else if (dataLength > 100) {
652
+ targetLabels = 7;
653
+ } else if (dataLength > 50) {
654
+ targetLabels = 8;
655
+ } else {
656
+ targetLabels = 12;
657
+ }
658
+ if (isMobile) {
659
+ targetLabels = Math.ceil(targetLabels / 2);
660
+ }
661
+ const baseInterval = Math.ceil(dataLength / targetLabels);
662
+ if (aggregationWindow === "15m") {
663
+ if (baseInterval >= 96) return Math.ceil(baseInterval / 56) * 56;
664
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
665
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 16) * 16;
666
+ return Math.max(8, Math.ceil(baseInterval / 4) * 4);
667
+ }
668
+ if (aggregationWindow === "1h") {
669
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
670
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 12) * 12;
671
+ return Math.max(4, Math.ceil(baseInterval / 4) * 4);
672
+ }
673
+ if (aggregationWindow === "1d") {
674
+ if (baseInterval >= 14) return Math.ceil(baseInterval / 14) * 14;
675
+ if (baseInterval >= 3) return Math.ceil(baseInterval / 7) * 7;
676
+ }
677
+ return baseInterval;
678
+ };
679
+ var transformToCumulative = (data) => {
680
+ let cumulative = 0;
681
+ return data.map((item) => {
682
+ cumulative += item.pnl;
683
+ return {
684
+ ...item,
685
+ cumulativePnL: cumulative
686
+ };
687
+ });
688
+ };
689
+ var CombinedPnLChart = (props) => {
690
+ const {
691
+ data,
692
+ aggregationWindow = "1d",
693
+ isMobile = false,
694
+ invisible,
695
+ responsiveContainerProps,
696
+ className,
697
+ showCumulative = true
698
+ } = props;
699
+ const colors = useColors(props.colors);
700
+ const transformedData = useMemo(() => transformToCumulative(data), [data]);
701
+ const xAxisInterval = useMemo(() => {
702
+ return calculateOptimalInterval(
703
+ transformedData.length,
704
+ aggregationWindow,
705
+ isMobile
706
+ );
707
+ }, [transformedData.length, aggregationWindow, isMobile]);
708
+ const yAxisDomain = useMemo(() => {
709
+ if (transformedData.length === 0) return [0, 1];
710
+ const pnlValues = transformedData.map((item) => item.pnl);
711
+ const cumulativeValues = showCumulative ? transformedData.map((item) => item.cumulativePnL) : [];
712
+ const valuesToConsider = showCumulative ? [...pnlValues, ...cumulativeValues, 0] : [...pnlValues, 0];
713
+ const minValue = Math.min(...valuesToConsider);
714
+ const maxValue = Math.max(...valuesToConsider);
715
+ const range = maxValue - minValue;
716
+ if (range === 0) return [0, 1];
717
+ const padding = range * 0.1;
718
+ const lower = minValue - padding;
719
+ const upper = maxValue + padding;
720
+ const magnitude = Math.pow(10, Math.floor(Math.log10(range)));
721
+ const step = Math.ceil((upper - lower) / 5 / magnitude) * magnitude;
722
+ const roundedLower = Math.floor(lower / step) * step;
723
+ const roundedUpper = Math.ceil(upper / step) * step;
724
+ return [roundedLower, roundedUpper];
725
+ }, [transformedData, showCumulative]);
726
+ if (invisible || transformedData.length === 0) {
727
+ return /* @__PURE__ */ jsx(
728
+ ChartEmptyState,
729
+ {
730
+ title: "No P&L Data",
731
+ description: "No profit and loss data available for the selected period",
732
+ height: "100%",
733
+ className
734
+ }
735
+ );
736
+ }
737
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx(
738
+ ResponsiveContainer,
739
+ {
740
+ width: "100%",
741
+ height: "100%",
742
+ ...responsiveContainerProps,
743
+ children: /* @__PURE__ */ jsxs(
744
+ ComposedChart,
745
+ {
746
+ data: transformedData,
747
+ margin: { left: 45, top: 10, right: 50, bottom: 20 },
748
+ syncId: "symbol-performance",
749
+ children: [
750
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "cumulativeGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
751
+ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#608CFF", stopOpacity: 0.4 }),
752
+ /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#608CFF", stopOpacity: 0 })
753
+ ] }) }),
754
+ /* @__PURE__ */ jsx(
755
+ Tooltip,
756
+ {
757
+ cursor: /* @__PURE__ */ jsx(CustomizedCross2, {}),
758
+ content: createCustomTooltip(showCumulative)
759
+ }
760
+ ),
761
+ /* @__PURE__ */ jsx(
762
+ CartesianGrid,
763
+ {
764
+ vertical: false,
765
+ stroke: "#FFFFFF",
766
+ strokeOpacity: 0.04
767
+ }
768
+ ),
769
+ /* @__PURE__ */ jsx(
770
+ ReferenceLine,
771
+ {
772
+ y: 0,
773
+ stroke: "rgba(255,255,255,0.3)",
774
+ strokeWidth: 2,
775
+ strokeDasharray: "4 4"
776
+ }
777
+ ),
778
+ /* @__PURE__ */ jsx(
779
+ YAxis,
780
+ {
781
+ domain: yAxisDomain,
782
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
783
+ tickLine: false,
784
+ axisLine: false,
785
+ tickFormatter: (value) => tickFormatter2(value),
786
+ width: 45
787
+ }
788
+ ),
789
+ /* @__PURE__ */ jsx(
790
+ XAxis,
791
+ {
792
+ dataKey: "date",
793
+ tickLine: false,
794
+ interval: xAxisInterval,
795
+ minTickGap: 30,
796
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
797
+ stroke: "#FFFFFF",
798
+ strokeOpacity: 0.04
799
+ }
800
+ ),
801
+ /* @__PURE__ */ jsx(
802
+ Bar,
803
+ {
804
+ dataKey: "pnl",
805
+ shape: /* @__PURE__ */ jsx(RoundedRectangle2, {}),
806
+ minPointSize: 1,
807
+ isAnimationActive: false,
808
+ children: transformedData.map((entry, index) => /* @__PURE__ */ jsx(
809
+ Cell,
810
+ {
811
+ fill: entry.pnl === 0 ? "rgba(255,255,255,0.2)" : entry.pnl > 0 ? colors.profit : colors.loss
812
+ },
813
+ `cell-${index}`
814
+ ))
815
+ }
816
+ ),
817
+ showCumulative && /* @__PURE__ */ jsx(
818
+ Area,
819
+ {
820
+ type: "natural",
821
+ dataKey: "cumulativePnL",
822
+ fill: "url(#cumulativeGradient)",
823
+ stroke: "none",
824
+ isAnimationActive: false
825
+ }
826
+ ),
827
+ showCumulative && /* @__PURE__ */ jsx(
828
+ Line,
829
+ {
830
+ type: "natural",
831
+ dataKey: "cumulativePnL",
832
+ stroke: colors.primary,
833
+ strokeWidth: 2,
834
+ dot: false,
835
+ isAnimationActive: false,
836
+ strokeLinecap: "round",
837
+ strokeLinejoin: "round"
838
+ }
839
+ )
840
+ ]
841
+ }
842
+ )
843
+ }
844
+ ) });
845
+ };
846
+ function tickFormatter2(value) {
847
+ const abbreviations = ["", "K", "M", "B", "T"];
848
+ let index = 0;
849
+ let num = Math.abs(value);
850
+ while (num >= 1e3 && index < abbreviations.length - 1) {
851
+ num /= 1e3;
852
+ index++;
853
+ }
854
+ const sign = value < 0 ? "-" : "";
855
+ const decimalPlaces = num <= 10 ? 1 : 0;
856
+ const rounded = num.toFixed(decimalPlaces);
857
+ return `${sign}${rounded}${abbreviations[index]}`;
858
+ }
859
+ var RoundedRectangle3 = (props) => {
860
+ const { fill, x, y, width, height } = props;
861
+ const absHeight = Math.abs(height);
862
+ return /* @__PURE__ */ jsx(
863
+ "rect",
864
+ {
865
+ rx: 2,
866
+ x,
867
+ y: height > 0 ? y : y + height,
868
+ width,
869
+ height: absHeight,
870
+ stroke: "none",
871
+ fill
872
+ }
873
+ );
874
+ };
875
+ var CustomizedCross3 = (props) => {
876
+ const { width, height } = props;
877
+ return /* @__PURE__ */ jsx(
878
+ Cross,
879
+ {
880
+ x: props.x + props.width / 2,
881
+ top: props.top,
882
+ height,
883
+ width: 1,
884
+ stroke: "rgba(255,255,255,0.16)",
885
+ strokeDasharray: "3 2",
886
+ fill: "none"
887
+ }
888
+ );
889
+ };
890
+ var formatValueWithSign2 = (value) => {
891
+ const sign = value > 0 ? "+" : "";
892
+ return `${sign}${value}`;
893
+ };
894
+ var createCustomTooltip2 = (showCumulative) => {
895
+ return (props) => {
896
+ const { active, payload, label } = props;
897
+ if (active && payload && payload.length >= 1) {
898
+ const volumeData = payload.find((p) => p.dataKey === "volume");
899
+ const volumeValue = volumeData?.value ?? 0;
900
+ const formattedDate = label;
901
+ return /* @__PURE__ */ jsxs(
902
+ Box,
903
+ {
904
+ intensity: 600,
905
+ p: 3,
906
+ r: "md",
907
+ className: "oui-flex oui-flex-col oui-gap-2",
908
+ children: [
909
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
910
+ /* @__PURE__ */ jsxs("span", { className: "oui-text-base-contrast-54", children: [
911
+ formattedDate,
912
+ ":"
913
+ ] }),
914
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", children: [
915
+ formatValueWithSign2(volumeValue),
916
+ " USDC"
917
+ ] })
918
+ ] }),
919
+ showCumulative && /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
920
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Cumulative:" }),
921
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", children: [
922
+ (() => {
923
+ const cumulativeData = payload.find(
924
+ (p) => p.dataKey === "cumulativeVolume"
925
+ );
926
+ const cumulativeValue = cumulativeData?.value ?? 0;
927
+ return formatValueWithSign2(cumulativeValue);
928
+ })(),
929
+ " ",
930
+ "USDC"
931
+ ] })
932
+ ] })
933
+ ]
934
+ }
935
+ );
936
+ }
937
+ return null;
938
+ };
939
+ };
940
+ var calculateOptimalInterval2 = (dataLength, aggregationWindow, isMobile = false) => {
941
+ if (dataLength <= 12 && !isMobile) return 0;
942
+ let targetLabels;
943
+ if (dataLength > 500) {
944
+ targetLabels = 6;
945
+ } else if (dataLength > 200) {
946
+ targetLabels = 6;
947
+ } else if (dataLength > 100) {
948
+ targetLabels = 7;
949
+ } else if (dataLength > 50) {
950
+ targetLabels = 8;
951
+ } else {
952
+ targetLabels = 12;
953
+ }
954
+ if (isMobile) {
955
+ targetLabels = Math.ceil(targetLabels / 2);
956
+ }
957
+ const baseInterval = Math.ceil(dataLength / targetLabels);
958
+ if (aggregationWindow === "15m") {
959
+ if (baseInterval >= 96) return Math.ceil(baseInterval / 56) * 56;
960
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
961
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 16) * 16;
962
+ return Math.max(8, Math.ceil(baseInterval / 4) * 4);
963
+ }
964
+ if (aggregationWindow === "1h") {
965
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
966
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 12) * 12;
967
+ return Math.max(4, Math.ceil(baseInterval / 4) * 4);
968
+ }
969
+ if (aggregationWindow === "1d") {
970
+ if (baseInterval >= 14) return Math.ceil(baseInterval / 14) * 14;
971
+ if (baseInterval >= 3) return Math.ceil(baseInterval / 7) * 7;
972
+ }
973
+ return baseInterval;
974
+ };
975
+ var transformToCumulative2 = (data) => {
976
+ let cumulative = 0;
977
+ return data.map((item) => {
978
+ cumulative += item.volume;
979
+ return {
980
+ ...item,
981
+ cumulativeVolume: cumulative
982
+ };
983
+ });
984
+ };
985
+ var CombinedVolumeChart = (props) => {
986
+ const {
987
+ data,
988
+ aggregationWindow = "1d",
989
+ isMobile = false,
990
+ invisible,
991
+ responsiveContainerProps,
992
+ className,
993
+ showCumulative = false
994
+ } = props;
995
+ const colors = useColors(
996
+ props.colors ? { profit: props.colors.fill, loss: props.colors.fill } : void 0
997
+ );
998
+ const transformedData = useMemo(() => transformToCumulative2(data), [data]);
999
+ const xAxisInterval = useMemo(
1000
+ () => calculateOptimalInterval2(
1001
+ transformedData.length,
1002
+ aggregationWindow,
1003
+ isMobile
1004
+ ),
1005
+ [transformedData.length, aggregationWindow, isMobile]
1006
+ );
1007
+ const yAxisDomain = useMemo(() => {
1008
+ if (transformedData.length === 0) return [0, 1];
1009
+ const volumeValues = transformedData.map((item) => item.volume);
1010
+ const cumulativeValues = showCumulative ? transformedData.map((item) => item.cumulativeVolume) : [];
1011
+ const maxValue = Math.max(
1012
+ ...showCumulative ? [...volumeValues, ...cumulativeValues] : volumeValues,
1013
+ 0
1014
+ );
1015
+ const range = maxValue;
1016
+ if (range === 0) return [0, 1];
1017
+ const padding = range * 0.1;
1018
+ const upper = maxValue + padding;
1019
+ const magnitude = Math.pow(10, Math.floor(Math.log10(range)));
1020
+ const step = Math.ceil(upper / 5 / magnitude) * magnitude;
1021
+ const roundedUpper = Math.ceil(upper / step) * step;
1022
+ return [0, roundedUpper];
1023
+ }, [transformedData, showCumulative]);
1024
+ if (invisible || transformedData.length === 0) {
1025
+ return /* @__PURE__ */ jsx(
1026
+ ChartEmptyState,
1027
+ {
1028
+ title: "No Volume Data",
1029
+ description: "No trading volume data available for the selected period",
1030
+ height: "100%",
1031
+ className
1032
+ }
1033
+ );
1034
+ }
1035
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx(
1036
+ ResponsiveContainer,
1037
+ {
1038
+ width: "100%",
1039
+ height: "100%",
1040
+ ...responsiveContainerProps,
1041
+ children: /* @__PURE__ */ jsxs(
1042
+ ComposedChart,
1043
+ {
1044
+ data: transformedData,
1045
+ margin: { left: 45, top: 10, right: 50, bottom: 20 },
1046
+ syncId: "symbol-performance",
1047
+ children: [
1048
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "volumeGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
1049
+ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#00B49E", stopOpacity: 0.4 }),
1050
+ /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#00B49E", stopOpacity: 0 })
1051
+ ] }) }),
1052
+ /* @__PURE__ */ jsx(
1053
+ Tooltip,
1054
+ {
1055
+ cursor: /* @__PURE__ */ jsx(CustomizedCross3, {}),
1056
+ content: createCustomTooltip2(showCumulative)
1057
+ }
1058
+ ),
1059
+ /* @__PURE__ */ jsx(
1060
+ CartesianGrid,
1061
+ {
1062
+ vertical: false,
1063
+ stroke: "#FFFFFF",
1064
+ strokeOpacity: 0.04
1065
+ }
1066
+ ),
1067
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "rgba(0,0,0,0.04)" }),
1068
+ /* @__PURE__ */ jsx(
1069
+ YAxis,
1070
+ {
1071
+ domain: yAxisDomain,
1072
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1073
+ tickLine: false,
1074
+ axisLine: false,
1075
+ tickFormatter: (value) => tickFormatter3(value),
1076
+ width: 45
1077
+ }
1078
+ ),
1079
+ /* @__PURE__ */ jsx(
1080
+ XAxis,
1081
+ {
1082
+ dataKey: "date",
1083
+ tickLine: false,
1084
+ interval: xAxisInterval,
1085
+ minTickGap: 30,
1086
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1087
+ stroke: "#FFFFFF",
1088
+ strokeOpacity: 0.04
1089
+ }
1090
+ ),
1091
+ /* @__PURE__ */ jsx(
1092
+ Bar,
1093
+ {
1094
+ dataKey: "volume",
1095
+ shape: /* @__PURE__ */ jsx(RoundedRectangle3, {}),
1096
+ minPointSize: 1,
1097
+ isAnimationActive: false,
1098
+ children: transformedData.map((entry, index) => /* @__PURE__ */ jsx(
1099
+ Cell,
1100
+ {
1101
+ fill: entry.volume === 0 ? "rgba(255,255,255,0.2)" : colors.profit,
1102
+ opacity: 0.8
1103
+ },
1104
+ `cell-${index}`
1105
+ ))
1106
+ }
1107
+ ),
1108
+ showCumulative && /* @__PURE__ */ jsx(
1109
+ Area,
1110
+ {
1111
+ type: "natural",
1112
+ dataKey: "cumulativeVolume",
1113
+ fill: "url(#volumeGradient)",
1114
+ stroke: "none",
1115
+ isAnimationActive: false
1116
+ }
1117
+ ),
1118
+ showCumulative && /* @__PURE__ */ jsx(
1119
+ Line,
1120
+ {
1121
+ type: "natural",
1122
+ dataKey: "cumulativeVolume",
1123
+ stroke: colors.profit,
1124
+ strokeWidth: 2,
1125
+ dot: false,
1126
+ isAnimationActive: false,
1127
+ strokeLinecap: "round",
1128
+ strokeLinejoin: "round"
1129
+ }
1130
+ )
1131
+ ]
1132
+ }
1133
+ )
1134
+ }
1135
+ ) });
1136
+ };
1137
+ function tickFormatter3(value) {
1138
+ const abbreviations = ["", "K", "M", "B", "T"];
1139
+ let index = 0;
1140
+ let num = Math.abs(value);
1141
+ while (num >= 1e3 && index < abbreviations.length - 1) {
1142
+ num /= 1e3;
1143
+ index++;
1144
+ }
1145
+ const sign = value < 0 ? "-" : "";
1146
+ const decimalPlaces = num <= 10 ? 1 : 0;
1147
+ const rounded = num.toFixed(decimalPlaces);
1148
+ return `${sign}${rounded}${abbreviations[index]}`;
1149
+ }
1150
+ var RoundedRectangle4 = (props) => {
1151
+ const { fill, x, y, width, height } = props;
1152
+ const absHeight = Math.abs(height);
1153
+ return /* @__PURE__ */ jsx(
1154
+ "rect",
1155
+ {
1156
+ rx: 2,
1157
+ x,
1158
+ y: height > 0 ? y : y + height,
1159
+ width,
1160
+ height: absHeight,
1161
+ stroke: "none",
1162
+ fill
1163
+ }
1164
+ );
1165
+ };
1166
+ var CustomizedCross4 = (props) => {
1167
+ const { width, height } = props;
1168
+ return /* @__PURE__ */ jsx(
1169
+ Cross,
1170
+ {
1171
+ x: props.x + props.width / 2,
1172
+ top: props.top,
1173
+ height,
1174
+ width: 1,
1175
+ stroke: "rgba(255,255,255,0.16)",
1176
+ strokeDasharray: "3 2",
1177
+ fill: "none"
1178
+ }
1179
+ );
1180
+ };
1181
+ var formatValueWithSign3 = (value) => {
1182
+ const sign = value > 0 ? "+" : "";
1183
+ return `${sign}${value.toFixed(2)}`;
1184
+ };
1185
+ var createCustomTooltip3 = (showCumulative) => {
1186
+ return (props) => {
1187
+ const { active, payload, label } = props;
1188
+ if (active && payload && payload.length >= 1) {
1189
+ const feesData = payload.find((p) => p.dataKey === "fees");
1190
+ const feesValue = feesData?.value ?? 0;
1191
+ const formattedDate = label;
1192
+ return /* @__PURE__ */ jsxs(
1193
+ Box,
1194
+ {
1195
+ intensity: 600,
1196
+ p: 3,
1197
+ r: "md",
1198
+ className: "oui-flex oui-flex-col oui-gap-2",
1199
+ children: [
1200
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1201
+ /* @__PURE__ */ jsxs("span", { className: "oui-text-base-contrast-54", children: [
1202
+ formattedDate,
1203
+ ":"
1204
+ ] }),
1205
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", children: [
1206
+ formatValueWithSign3(feesValue),
1207
+ " USDC"
1208
+ ] })
1209
+ ] }),
1210
+ showCumulative && /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1211
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Cumulative:" }),
1212
+ /* @__PURE__ */ jsxs("span", { className: "oui-font-semibold", children: [
1213
+ (() => {
1214
+ const cumulativeData = payload.find(
1215
+ (p) => p.dataKey === "cumulativeFees"
1216
+ );
1217
+ const cumulativeValue = cumulativeData?.value ?? 0;
1218
+ return formatValueWithSign3(cumulativeValue);
1219
+ })(),
1220
+ " ",
1221
+ "USDC"
1222
+ ] })
1223
+ ] })
1224
+ ]
1225
+ }
1226
+ );
1227
+ }
1228
+ return null;
1229
+ };
1230
+ };
1231
+ var calculateOptimalInterval3 = (dataLength, aggregationWindow, isMobile = false) => {
1232
+ if (dataLength <= 12 && !isMobile) return 0;
1233
+ let targetLabels;
1234
+ if (dataLength > 500) {
1235
+ targetLabels = 6;
1236
+ } else if (dataLength > 200) {
1237
+ targetLabels = 6;
1238
+ } else if (dataLength > 100) {
1239
+ targetLabels = 7;
1240
+ } else if (dataLength > 50) {
1241
+ targetLabels = 8;
1242
+ } else {
1243
+ targetLabels = 12;
1244
+ }
1245
+ if (isMobile) {
1246
+ targetLabels = Math.ceil(targetLabels / 2);
1247
+ }
1248
+ const baseInterval = Math.ceil(dataLength / targetLabels);
1249
+ if (aggregationWindow === "15m") {
1250
+ if (baseInterval >= 96) return Math.ceil(baseInterval / 56) * 56;
1251
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
1252
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 16) * 16;
1253
+ return Math.max(8, Math.ceil(baseInterval / 4) * 4);
1254
+ }
1255
+ if (aggregationWindow === "1h") {
1256
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
1257
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 12) * 12;
1258
+ return Math.max(4, Math.ceil(baseInterval / 4) * 4);
1259
+ }
1260
+ if (aggregationWindow === "1d") {
1261
+ if (baseInterval >= 14) return Math.ceil(baseInterval / 14) * 14;
1262
+ if (baseInterval >= 3) return Math.ceil(baseInterval / 7) * 7;
1263
+ }
1264
+ return baseInterval;
1265
+ };
1266
+ var transformToCumulative3 = (data) => {
1267
+ let cumulative = 0;
1268
+ return data.map((item) => {
1269
+ cumulative += item.fees;
1270
+ return {
1271
+ ...item,
1272
+ cumulativeFees: cumulative
1273
+ };
1274
+ });
1275
+ };
1276
+ var CombinedFeesChart = (props) => {
1277
+ const {
1278
+ data,
1279
+ aggregationWindow = "1d",
1280
+ isMobile = false,
1281
+ invisible,
1282
+ responsiveContainerProps,
1283
+ className,
1284
+ showCumulative = false
1285
+ } = props;
1286
+ const colors = useColors(
1287
+ props.colors ? { profit: props.colors.fill, loss: props.colors.fill } : void 0
1288
+ );
1289
+ const transformedData = useMemo(() => transformToCumulative3(data), [data]);
1290
+ const xAxisInterval = useMemo(
1291
+ () => calculateOptimalInterval3(
1292
+ transformedData.length,
1293
+ aggregationWindow,
1294
+ isMobile
1295
+ ),
1296
+ [transformedData.length, aggregationWindow, isMobile]
1297
+ );
1298
+ const yAxisDomainAndTicks = useMemo(() => {
1299
+ if (transformedData.length === 0) return { domain: [0, 1], ticks: [0, 1] };
1300
+ const feesValues = transformedData.map((item) => item.fees);
1301
+ const cumulativeValues = showCumulative ? transformedData.map((item) => item.cumulativeFees) : [];
1302
+ const valuesToConsider = showCumulative ? [...feesValues, ...cumulativeValues, 0] : [...feesValues, 0];
1303
+ const minValue = Math.min(...valuesToConsider);
1304
+ const maxValue = Math.max(...valuesToConsider);
1305
+ const range = maxValue - minValue;
1306
+ if (range === 0) return { domain: [0, 1], ticks: [0, 1] };
1307
+ const padding = range * 0.1;
1308
+ const lower = minValue - padding;
1309
+ const upper = 0;
1310
+ const magnitude = Math.pow(10, Math.floor(Math.log10(range)));
1311
+ let step = magnitude;
1312
+ const rangeWidth = Math.abs(upper - lower);
1313
+ for (const divisor of [1, 2, 2.5, 5]) {
1314
+ const candidate = magnitude * divisor;
1315
+ const tickCount = Math.ceil(rangeWidth / candidate);
1316
+ if (tickCount >= 4 && tickCount <= 6) {
1317
+ step = candidate;
1318
+ break;
1319
+ }
1320
+ }
1321
+ const roundedLower = Math.floor(lower / step) * step;
1322
+ const ticks = [];
1323
+ for (let tick = roundedLower; tick < upper; tick += step) {
1324
+ ticks.push(Number(tick.toFixed(10)));
1325
+ }
1326
+ ticks.push(0);
1327
+ return { domain: [roundedLower, 0], ticks };
1328
+ }, [transformedData, showCumulative]);
1329
+ if (invisible || transformedData.length === 0) {
1330
+ return /* @__PURE__ */ jsx(
1331
+ ChartEmptyState,
1332
+ {
1333
+ title: "No Fees Data",
1334
+ description: "No fees data available for the selected period",
1335
+ height: "100%",
1336
+ className
1337
+ }
1338
+ );
1339
+ }
1340
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx(
1341
+ ResponsiveContainer,
1342
+ {
1343
+ width: "100%",
1344
+ height: "100%",
1345
+ ...responsiveContainerProps,
1346
+ children: /* @__PURE__ */ jsxs(
1347
+ ComposedChart,
1348
+ {
1349
+ data: transformedData,
1350
+ margin: { left: 45, top: 10, right: 50, bottom: 20 },
1351
+ syncId: "symbol-performance",
1352
+ children: [
1353
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "feesGradient", x1: "0", y1: "0", x2: "0", y2: "1", children: [
1354
+ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#FF6B6B", stopOpacity: 0.4 }),
1355
+ /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#FF6B6B", stopOpacity: 0 })
1356
+ ] }) }),
1357
+ /* @__PURE__ */ jsx(
1358
+ Tooltip,
1359
+ {
1360
+ cursor: /* @__PURE__ */ jsx(CustomizedCross4, {}),
1361
+ content: createCustomTooltip3(showCumulative)
1362
+ }
1363
+ ),
1364
+ /* @__PURE__ */ jsx(
1365
+ CartesianGrid,
1366
+ {
1367
+ vertical: false,
1368
+ stroke: "#FFFFFF",
1369
+ strokeOpacity: 0.04
1370
+ }
1371
+ ),
1372
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "rgba(0,0,0,0.04)" }),
1373
+ /* @__PURE__ */ jsx(
1374
+ YAxis,
1375
+ {
1376
+ domain: yAxisDomainAndTicks.domain,
1377
+ ticks: yAxisDomainAndTicks.ticks,
1378
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1379
+ tickLine: false,
1380
+ axisLine: false,
1381
+ tickFormatter: (value) => tickFormatter4(value),
1382
+ width: 45
1383
+ }
1384
+ ),
1385
+ /* @__PURE__ */ jsx(
1386
+ XAxis,
1387
+ {
1388
+ dataKey: "date",
1389
+ tickLine: false,
1390
+ interval: xAxisInterval,
1391
+ minTickGap: 30,
1392
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1393
+ stroke: "#FFFFFF",
1394
+ strokeOpacity: 0.04
1395
+ }
1396
+ ),
1397
+ /* @__PURE__ */ jsx(
1398
+ Bar,
1399
+ {
1400
+ dataKey: "fees",
1401
+ shape: /* @__PURE__ */ jsx(RoundedRectangle4, {}),
1402
+ minPointSize: 1,
1403
+ isAnimationActive: false,
1404
+ children: transformedData.map((entry, index) => /* @__PURE__ */ jsx(
1405
+ Cell,
1406
+ {
1407
+ fill: entry.fees === 0 ? "rgba(255,255,255,0.2)" : colors.loss,
1408
+ opacity: 0.8
1409
+ },
1410
+ `cell-${index}`
1411
+ ))
1412
+ }
1413
+ ),
1414
+ showCumulative && /* @__PURE__ */ jsx(
1415
+ Area,
1416
+ {
1417
+ type: "natural",
1418
+ dataKey: "cumulativeFees",
1419
+ fill: "url(#feesGradient)",
1420
+ stroke: "none",
1421
+ isAnimationActive: false
1422
+ }
1423
+ ),
1424
+ showCumulative && /* @__PURE__ */ jsx(
1425
+ Line,
1426
+ {
1427
+ type: "natural",
1428
+ dataKey: "cumulativeFees",
1429
+ stroke: colors.loss,
1430
+ strokeWidth: 2,
1431
+ dot: false,
1432
+ isAnimationActive: false,
1433
+ strokeLinecap: "round",
1434
+ strokeLinejoin: "round"
1435
+ }
1436
+ )
1437
+ ]
1438
+ }
1439
+ )
1440
+ }
1441
+ ) });
1442
+ };
1443
+ function tickFormatter4(value) {
1444
+ const abbreviations = ["", "K", "M", "B", "T"];
1445
+ let index = 0;
1446
+ let num = Math.abs(value);
1447
+ while (num >= 1e3 && index < abbreviations.length - 1) {
1448
+ num /= 1e3;
1449
+ index++;
1450
+ }
1451
+ const sign = value < 0 ? "-" : "";
1452
+ const decimalPlaces = num <= 10 ? 1 : 0;
1453
+ const rounded = num.toFixed(decimalPlaces);
1454
+ return `${sign}${rounded}${abbreviations[index]}`;
1455
+ }
1456
+ var CustomizedCross5 = (props) => {
1457
+ const { width, height } = props;
1458
+ return /* @__PURE__ */ jsx(
1459
+ Cross,
1460
+ {
1461
+ x: props.x + props.width / 2,
1462
+ top: props.top,
1463
+ height,
1464
+ width: 1,
1465
+ stroke: "rgba(255,255,255,0.16)",
1466
+ strokeDasharray: "3 2",
1467
+ fill: "none"
1468
+ }
1469
+ );
1470
+ };
1471
+ var CustomTooltip4 = (props) => {
1472
+ const { active, payload, label } = props;
1473
+ if (active && payload && payload.length >= 1) {
1474
+ const data = payload[0].payload;
1475
+ const hasPrice = data.close !== null && data.close !== void 0;
1476
+ if (!hasPrice) {
1477
+ return /* @__PURE__ */ jsxs(
1478
+ Box,
1479
+ {
1480
+ intensity: 600,
1481
+ p: 3,
1482
+ r: "md",
1483
+ className: "oui-flex oui-flex-col oui-gap-2",
1484
+ children: [
1485
+ /* @__PURE__ */ jsx("div", { className: "oui-text-xs oui-text-base-contrast-54", children: "Price data unavailable" }),
1486
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2 oui-mt-1 oui-pt-2 oui-border-t oui-border-base-contrast-16", children: [
1487
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Time:" }),
1488
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: label })
1489
+ ] })
1490
+ ]
1491
+ }
1492
+ );
1493
+ }
1494
+ return /* @__PURE__ */ jsxs(
1495
+ Box,
1496
+ {
1497
+ intensity: 600,
1498
+ p: 3,
1499
+ r: "md",
1500
+ className: "oui-flex oui-flex-col oui-gap-2",
1501
+ children: [
1502
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1503
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Open:" }),
1504
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: data.open?.toFixed(2) ?? "--" })
1505
+ ] }),
1506
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1507
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "High:" }),
1508
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: data.high?.toFixed(2) ?? "--" })
1509
+ ] }),
1510
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1511
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Low:" }),
1512
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: data.low?.toFixed(2) ?? "--" })
1513
+ ] }),
1514
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
1515
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Close:" }),
1516
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: data.close.toFixed(2) })
1517
+ ] }),
1518
+ /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2 oui-mt-1 oui-pt-2 oui-border-t oui-border-base-contrast-16", children: [
1519
+ /* @__PURE__ */ jsx("span", { className: "oui-text-base-contrast-54", children: "Time:" }),
1520
+ /* @__PURE__ */ jsx("span", { className: "oui-font-semibold", children: label })
1521
+ ] })
1522
+ ]
1523
+ }
1524
+ );
1525
+ }
1526
+ return null;
1527
+ };
1528
+ var calculateOptimalInterval4 = (dataLength, aggregationWindow, isMobile = false) => {
1529
+ if (dataLength <= 12 && !isMobile) return 0;
1530
+ let targetLabels;
1531
+ if (dataLength > 500) {
1532
+ targetLabels = 6;
1533
+ } else if (dataLength > 200) {
1534
+ targetLabels = 6;
1535
+ } else if (dataLength > 100) {
1536
+ targetLabels = 7;
1537
+ } else if (dataLength > 50) {
1538
+ targetLabels = 8;
1539
+ } else {
1540
+ targetLabels = 12;
1541
+ }
1542
+ if (isMobile) {
1543
+ targetLabels = Math.ceil(targetLabels / 2);
1544
+ }
1545
+ const baseInterval = Math.ceil(dataLength / targetLabels);
1546
+ if (aggregationWindow === "15m") {
1547
+ if (baseInterval >= 96) return Math.ceil(baseInterval / 56) * 56;
1548
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
1549
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 16) * 16;
1550
+ return Math.max(8, Math.ceil(baseInterval / 4) * 4);
1551
+ }
1552
+ if (aggregationWindow === "1h") {
1553
+ if (baseInterval >= 48) return Math.ceil(baseInterval / 28) * 28;
1554
+ if (baseInterval >= 24) return Math.ceil(baseInterval / 12) * 12;
1555
+ return Math.max(4, Math.ceil(baseInterval / 4) * 4);
1556
+ }
1557
+ if (aggregationWindow === "1d") {
1558
+ if (baseInterval >= 14) return Math.ceil(baseInterval / 14) * 14;
1559
+ if (baseInterval >= 3) return Math.ceil(baseInterval / 7) * 7;
1560
+ }
1561
+ return baseInterval;
1562
+ };
1563
+ function tickFormatter5(value) {
1564
+ return value.toFixed(2);
1565
+ }
1566
+ var CombinedPriceChart = (props) => {
1567
+ const {
1568
+ data,
1569
+ aggregationWindow = "1d",
1570
+ isMobile = false,
1571
+ invisible,
1572
+ responsiveContainerProps,
1573
+ className
1574
+ } = props;
1575
+ useColors();
1576
+ const xAxisInterval = useMemo(
1577
+ () => calculateOptimalInterval4(data.length, aggregationWindow, isMobile),
1578
+ [data.length, aggregationWindow, isMobile]
1579
+ );
1580
+ const yAxisDomainAndTicks = useMemo(() => {
1581
+ if (data.length === 0) return { domain: [0, 1], ticks: [0, 1] };
1582
+ const closePrices = data.map((item) => item.close).filter((price) => price !== null && price !== void 0);
1583
+ if (closePrices.length === 0) return { domain: [0, 1], ticks: [0, 1] };
1584
+ const minPrice = Math.min(...closePrices);
1585
+ const maxPrice = Math.max(...closePrices);
1586
+ const range = maxPrice - minPrice;
1587
+ if (range === 0)
1588
+ return {
1589
+ domain: [minPrice - 1, maxPrice + 1],
1590
+ ticks: [minPrice - 1, maxPrice + 1]
1591
+ };
1592
+ const padding = range * 0.1;
1593
+ const lower = minPrice - padding;
1594
+ const upper = maxPrice + padding;
1595
+ const magnitude = Math.pow(10, Math.floor(Math.log10(range)));
1596
+ let step = magnitude;
1597
+ const rangeWidth = upper - lower;
1598
+ for (const divisor of [1, 2, 2.5, 5]) {
1599
+ const candidate = magnitude * divisor;
1600
+ const tickCount = Math.ceil(rangeWidth / candidate);
1601
+ if (tickCount >= 4 && tickCount <= 6) {
1602
+ step = candidate;
1603
+ break;
1604
+ }
1605
+ }
1606
+ const roundedLower = Math.floor(lower / step) * step;
1607
+ const roundedUpper = Math.ceil(upper / step) * step;
1608
+ const ticks = [];
1609
+ for (let tick = roundedLower; tick <= roundedUpper; tick += step) {
1610
+ ticks.push(Number(tick.toFixed(10)));
1611
+ }
1612
+ return { domain: [roundedLower, roundedUpper], ticks };
1613
+ }, [data]);
1614
+ if (invisible || data.length === 0) {
1615
+ return /* @__PURE__ */ jsx(
1616
+ ChartEmptyState,
1617
+ {
1618
+ title: "No Price Data",
1619
+ description: "No price data available for the selected period",
1620
+ height: "100%",
1621
+ className
1622
+ }
1623
+ );
1624
+ }
1625
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx(
1626
+ ResponsiveContainer,
1627
+ {
1628
+ width: "100%",
1629
+ height: "100%",
1630
+ ...responsiveContainerProps,
1631
+ children: /* @__PURE__ */ jsxs(
1632
+ ComposedChart,
1633
+ {
1634
+ data,
1635
+ margin: { left: 45, top: 10, right: 50, bottom: 20 },
1636
+ syncId: "symbol-performance",
1637
+ children: [
1638
+ /* @__PURE__ */ jsx(Tooltip, { cursor: /* @__PURE__ */ jsx(CustomizedCross5, {}), content: /* @__PURE__ */ jsx(CustomTooltip4, {}) }),
1639
+ /* @__PURE__ */ jsx(
1640
+ CartesianGrid,
1641
+ {
1642
+ vertical: false,
1643
+ stroke: "#FFFFFF",
1644
+ strokeOpacity: 0.04
1645
+ }
1646
+ ),
1647
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "rgba(0,0,0,0.04)" }),
1648
+ /* @__PURE__ */ jsx(
1649
+ YAxis,
1650
+ {
1651
+ domain: yAxisDomainAndTicks.domain,
1652
+ ticks: yAxisDomainAndTicks.ticks,
1653
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1654
+ tickLine: false,
1655
+ axisLine: false,
1656
+ tickFormatter: tickFormatter5,
1657
+ width: 50
1658
+ }
1659
+ ),
1660
+ /* @__PURE__ */ jsx(
1661
+ XAxis,
1662
+ {
1663
+ dataKey: "date",
1664
+ tickLine: false,
1665
+ interval: xAxisInterval,
1666
+ minTickGap: 50,
1667
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1668
+ stroke: "#FFFFFF",
1669
+ strokeOpacity: 0.04
1670
+ }
1671
+ ),
1672
+ /* @__PURE__ */ jsx(
1673
+ Line,
1674
+ {
1675
+ type: "natural",
1676
+ dataKey: "close",
1677
+ stroke: "#00B49E",
1678
+ strokeWidth: 2,
1679
+ dot: false,
1680
+ isAnimationActive: false,
1681
+ strokeLinecap: "round",
1682
+ strokeLinejoin: "round"
1683
+ }
1684
+ )
1685
+ ]
1686
+ }
1687
+ )
1688
+ }
1689
+ ) });
1690
+ };
1691
+ var CustomTooltip5 = (props) => {
1692
+ const { active, payload, label } = props;
1693
+ const todayStr = useRef((/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
1694
+ const { t } = useTranslation();
1695
+ if (active && payload && payload.length) {
1696
+ return /* @__PURE__ */ jsx(
1697
+ OrderlyChartTooltip,
1698
+ {
1699
+ label: label === todayStr.current ? t("chart.now") : label,
1700
+ value: payload[0].value
1701
+ }
1702
+ );
1703
+ }
1704
+ return null;
1705
+ };
1706
+ var AssetLineChart = (props) => {
1707
+ const { responsiveContainerProps } = props;
1708
+ const colors = useColors(props.colors);
1709
+ const colorId = useId();
1710
+ const { isMobile } = useScreen();
1711
+ const chartComponent = isMobile ? /* @__PURE__ */ jsxs(
1712
+ AreaChart,
1713
+ {
1714
+ width: 530,
1715
+ height: 180,
1716
+ data: props.data,
1717
+ margin: { top: 20, right: 10, left: -20, bottom: -10 },
1718
+ children: [
1719
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
1720
+ /* @__PURE__ */ jsx(
1721
+ XAxis,
1722
+ {
1723
+ dataKey: "date",
1724
+ interval: props.data.length - 2,
1725
+ tick: /* @__PURE__ */ jsx(XAxisLabel2, {}),
1726
+ stroke: "#FFFFFF",
1727
+ strokeOpacity: 0.04
1728
+ }
1729
+ ),
1730
+ /* @__PURE__ */ jsx(
1731
+ YAxis,
1732
+ {
1733
+ dataKey: "account_value",
1734
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1735
+ tickLine: false,
1736
+ axisLine: false,
1737
+ tickFormatter: (value) => tickFormatter(value)
1738
+ }
1739
+ ),
1740
+ !props.invisible && /* @__PURE__ */ jsxs(Fragment, { children: [
1741
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: colorId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1742
+ /* @__PURE__ */ jsx("stop", { stopColor: "#00B49E", offset: "0%", stopOpacity: 0.5 }),
1743
+ /* @__PURE__ */ jsx("stop", { stopColor: "#00B49E", offset: "100%", stopOpacity: 0 })
1744
+ ] }) }),
1745
+ /* @__PURE__ */ jsx(
1746
+ Area,
1747
+ {
1748
+ type: "natural",
1749
+ dataKey: "account_value",
1750
+ stroke: colors.profit,
1751
+ strokeWidth: isMobile ? 1.5 : 2,
1752
+ dot: false,
1753
+ isAnimationActive: false,
1754
+ fill: `url(#${colorId})`
1755
+ }
1756
+ )
1757
+ ] })
1758
+ ]
1759
+ }
1760
+ ) : /* @__PURE__ */ jsxs(
1761
+ LineChart,
1762
+ {
1763
+ width: 530,
1764
+ height: 180,
1765
+ data: props.data,
1766
+ margin: { top: 20, right: 10, left: -20, bottom: -10 },
1767
+ children: [
1768
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
1769
+ /* @__PURE__ */ jsx(
1770
+ XAxis,
1771
+ {
1772
+ dataKey: "date",
1773
+ interval: props.data.length - 2,
1774
+ tick: /* @__PURE__ */ jsx(XAxisLabel2, {}),
1775
+ stroke: "#FFFFFF",
1776
+ strokeOpacity: 0.04
1777
+ }
1778
+ ),
1779
+ /* @__PURE__ */ jsx(
1780
+ YAxis,
1781
+ {
1782
+ dataKey: "account_value",
1783
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1784
+ tickLine: false,
1785
+ axisLine: false,
1786
+ tickFormatter
1787
+ }
1788
+ ),
1789
+ !props.invisible && /* @__PURE__ */ jsx(
1790
+ Tooltip,
1791
+ {
1792
+ cursor: { strokeDasharray: "3 2", strokeOpacity: 0.16 },
1793
+ content: /* @__PURE__ */ jsx(CustomTooltip5, {})
1794
+ }
1795
+ ),
1796
+ !props.invisible && /* @__PURE__ */ jsx(
1797
+ Line,
1798
+ {
1799
+ type: "natural",
1800
+ dataKey: "account_value",
1801
+ stroke: colors.profit,
1802
+ strokeWidth: isMobile ? 1.5 : 2,
1803
+ dot: false,
1804
+ isAnimationActive: false
1805
+ }
1806
+ )
1807
+ ]
1808
+ }
1809
+ );
1810
+ return /* @__PURE__ */ jsx(
1811
+ ResponsiveContainer,
1812
+ {
1813
+ className: props.invisible ? "chart-invisible" : void 0,
1814
+ ...responsiveContainerProps,
1815
+ children: chartComponent
1816
+ }
1817
+ );
1818
+ };
1819
+ var CustomTooltip6 = (props) => {
1820
+ const { active, payload, label } = props;
1821
+ const todayStr = useRef((/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
1822
+ const { t } = useTranslation();
1823
+ if (active && payload && payload.length) {
1824
+ return /* @__PURE__ */ jsx(
1825
+ OrderlyChartTooltip,
1826
+ {
1827
+ label: label === todayStr.current ? t("chart.now") : label,
1828
+ value: payload[0].value
1829
+ }
1830
+ );
1831
+ }
1832
+ return null;
1833
+ };
1834
+ var AssetAreaChart = (props) => {
1835
+ const { responsiveContainerProps } = props;
1836
+ const colors = useColors(props.colors);
1837
+ const colorId = useId();
1838
+ const { isMobile } = useScreen();
1839
+ const chartComponent = /* @__PURE__ */ jsxs(
1840
+ AreaChart,
1841
+ {
1842
+ width: 530,
1843
+ height: 180,
1844
+ data: props.data,
1845
+ margin: { top: 20, right: 10, left: -20, bottom: -10 },
1846
+ children: [
1847
+ /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "#FFFFFF", strokeOpacity: 0.04 }),
1848
+ /* @__PURE__ */ jsx(
1849
+ XAxis,
1850
+ {
1851
+ dataKey: "date",
1852
+ interval: props.data.length - 2,
1853
+ tick: /* @__PURE__ */ jsx(XAxisLabel2, {}),
1854
+ stroke: "#FFFFFF",
1855
+ strokeOpacity: 0.04
1856
+ }
1857
+ ),
1858
+ /* @__PURE__ */ jsx(
1859
+ YAxis,
1860
+ {
1861
+ dataKey: "account_value",
1862
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
1863
+ tickLine: false,
1864
+ axisLine: false,
1865
+ tickFormatter
1866
+ }
1867
+ ),
1868
+ !props.invisible && /* @__PURE__ */ jsx(
1869
+ Tooltip,
1870
+ {
1871
+ cursor: { strokeDasharray: "3 2", strokeOpacity: 0.16 },
1872
+ content: /* @__PURE__ */ jsx(CustomTooltip6, {})
1873
+ }
1874
+ ),
1875
+ !props.invisible && /* @__PURE__ */ jsxs(Fragment, { children: [
1876
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: colorId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1877
+ /* @__PURE__ */ jsx("stop", { stopColor: "#00B49E", offset: "0%", stopOpacity: 0.5 }),
1878
+ /* @__PURE__ */ jsx("stop", { stopColor: "#00B49E", offset: "100%", stopOpacity: 0 })
1879
+ ] }) }),
1880
+ /* @__PURE__ */ jsx(
1881
+ Area,
1882
+ {
1883
+ type: "natural",
1884
+ dataKey: "account_value",
1885
+ stroke: colors.profit,
1886
+ strokeWidth: isMobile ? 1.5 : 2,
1887
+ dot: false,
1888
+ isAnimationActive: false,
1889
+ fill: `url(#${colorId})`
1890
+ }
1891
+ )
1892
+ ] })
1893
+ ]
1894
+ }
1895
+ );
1896
+ return /* @__PURE__ */ jsx(
1897
+ ResponsiveContainer,
1898
+ {
1899
+ className: props.invisible ? "chart-invisible" : void 0,
1900
+ ...responsiveContainerProps,
1901
+ children: chartComponent
1902
+ }
1903
+ );
1904
+ };
1905
+ var RoundedRectangle5 = (props) => {
1906
+ const { fill, x, y, width, height, opacity } = props;
1907
+ const absHeight = Math.abs(height);
1908
+ return /* @__PURE__ */ jsx(
1909
+ "rect",
1910
+ {
1911
+ rx: 2,
1912
+ x,
1913
+ y: height > 0 ? y : y + height,
1914
+ width,
1915
+ height: absHeight,
1916
+ stroke: "none",
1917
+ fill,
1918
+ opacity
1919
+ }
1920
+ );
1921
+ };
1922
+ var CustomizedCross6 = (props) => {
1923
+ const { width, height, payload, stroke, fill } = props;
1924
+ if (payload?.[0]?.value === 0) {
1925
+ return null;
1926
+ }
1927
+ return (
1928
+ // @ts-ignore
1929
+ /* @__PURE__ */ jsx(
1930
+ Cross,
1931
+ {
1932
+ x: props.x + props.width / 2,
1933
+ top: props.top,
1934
+ height,
1935
+ width: 1,
1936
+ stroke: "rgba(255,255,255,0.16)",
1937
+ strokeDasharray: "3 2",
1938
+ fill: "none"
1939
+ }
1940
+ )
1941
+ );
1942
+ };
1943
+ var CustomTooltip7 = (props) => {
1944
+ const { active, payload, label, tooltip } = props;
1945
+ if (payload?.[0]?.value === 0) {
1946
+ return null;
1947
+ }
1948
+ if (active && payload && payload.length) {
1949
+ return /* @__PURE__ */ jsx(
1950
+ OrderlyChartTooltip,
1951
+ {
1952
+ label,
1953
+ value: payload[0].value,
1954
+ titleClassName: "oui-gap-4",
1955
+ rm: tooltip?.rm,
1956
+ dp: tooltip?.dp
1957
+ }
1958
+ );
1959
+ }
1960
+ return null;
1961
+ };
1962
+ var VolBarChart = (props) => {
1963
+ const colors = useColors(
1964
+ props.colors?.fill ? { profit: props.colors?.fill, loss: props.colors?.fill } : void 0
1965
+ );
1966
+ const isEmpty = props.data?.reduce((pre, cur) => pre + cur.volume, 0) === 0;
1967
+ const maxVolume = props.data?.reduce(
1968
+ (pre, cur) => pre > cur.volume ? pre : cur.volume,
1969
+ 0
1970
+ );
1971
+ const decimal = maxVolume <= 10 ? 2 : maxVolume <= 100 ? 1 : 0;
1972
+ return (
1973
+ // @ts-ignore
1974
+ /* @__PURE__ */ jsx(Box, { className: cn(props.className), children: /* @__PURE__ */ jsx(ResponsiveContainer, { children: /* @__PURE__ */ jsxs(
1975
+ BarChart,
1976
+ {
1977
+ data: props.data,
1978
+ margin: { left: -0, top: 6, right: 0, bottom: 20 },
1979
+ children: [
1980
+ /* @__PURE__ */ jsx(
1981
+ Tooltip,
1982
+ {
1983
+ cursor: /* @__PURE__ */ jsx(CustomizedCross6, {}),
1984
+ content: /* @__PURE__ */ jsx(CustomTooltip7, { tooltip: props.tooltip })
1985
+ }
1986
+ ),
1987
+ /* @__PURE__ */ jsx(
1988
+ CartesianGrid,
1989
+ {
1990
+ vertical: false,
1991
+ stroke: "#FFFFFF",
1992
+ strokeOpacity: 0.08,
1993
+ repeatCount: 6
1994
+ }
1995
+ ),
1996
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "#000" }),
1997
+ /* @__PURE__ */ jsx(Bar, { dataKey: "volume", shape: /* @__PURE__ */ jsx(RoundedRectangle5, {}), minPointSize: 1, children: props.data.map((entry, index) => {
1998
+ return (
1999
+ // @ts-ignore
2000
+ /* @__PURE__ */ jsx(
2001
+ Cell,
2002
+ {
2003
+ fill: entry.volume > 0 ? colors.profit : colors.loss,
2004
+ opacity: entry.opacity
2005
+ },
2006
+ `cell-${index}`
2007
+ )
2008
+ );
2009
+ }) }),
2010
+ /* @__PURE__ */ jsx(
2011
+ YAxis,
2012
+ {
2013
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
2014
+ tickLine: false,
2015
+ axisLine: false,
2016
+ dataKey: "volume",
2017
+ tickFormatter: (value, index) => {
2018
+ if (isEmpty) return `${index * 100}`;
2019
+ return numberToHumanStyle2(value, decimal);
2020
+ },
2021
+ width: 45
2022
+ }
2023
+ ),
2024
+ /* @__PURE__ */ jsx(
2025
+ XAxis,
2026
+ {
2027
+ dataKey: "date",
2028
+ tickLine: false,
2029
+ interval: props.data.length - 2,
2030
+ height: 1,
2031
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
2032
+ stroke: "rgb(229, 231, 235)",
2033
+ strokeOpacity: 0.2
2034
+ }
2035
+ )
2036
+ ]
2037
+ }
2038
+ ) }) })
2039
+ );
2040
+ };
2041
+ function numberToHumanStyle2(number, decimalPlaces = 0) {
2042
+ const abbreviations = ["", "K", "M", "B", "T"];
2043
+ let index = 0;
2044
+ while (number >= 1e3 && index < abbreviations.length - 1) {
2045
+ number /= 1e3;
2046
+ index++;
2047
+ }
2048
+ const roundedNumber = toFixedWithoutRounding(number, decimalPlaces);
2049
+ return `${roundedNumber}${abbreviations[index]}`;
2050
+ }
2051
+ function toFixedWithoutRounding(num, fix) {
2052
+ const numStr = num.toString();
2053
+ const decimalIndex = numStr.indexOf(".");
2054
+ if (decimalIndex === -1 || fix === 0) {
2055
+ return numStr.split(".")[0];
2056
+ }
2057
+ const cutoffIndex = decimalIndex + fix + 1;
2058
+ return numStr.slice(0, cutoffIndex);
2059
+ }
2060
+ var CustomizedCross7 = (props) => {
2061
+ const { width, height } = props;
2062
+ return /* @__PURE__ */ jsx(
2063
+ Cross,
2064
+ {
2065
+ x: props.x + props.width / 2,
2066
+ top: props.top,
2067
+ height,
2068
+ width: 1,
2069
+ stroke: "rgba(255,255,255,0.16)",
2070
+ strokeDasharray: "3 2",
2071
+ fill: "none"
2072
+ }
2073
+ );
2074
+ };
2075
+ var UnifiedChartTooltip = (props) => {
2076
+ const { active, payload, label } = props;
2077
+ if (active && payload && payload.length > 0) {
2078
+ return /* @__PURE__ */ jsxs(
2079
+ Box,
2080
+ {
2081
+ intensity: 600,
2082
+ p: 3,
2083
+ r: "md",
2084
+ className: "oui-flex oui-flex-col oui-gap-2",
2085
+ children: [
2086
+ /* @__PURE__ */ jsx("div", { className: "oui-text-xs oui-font-semibold", children: label }),
2087
+ payload.map((entry, index) => /* @__PURE__ */ jsxs("div", { className: "oui-text-xs oui-flex oui-gap-2", children: [
2088
+ /* @__PURE__ */ jsxs("span", { style: { color: entry.color }, className: "oui-font-semibold", children: [
2089
+ entry.name,
2090
+ ":"
2091
+ ] }),
2092
+ /* @__PURE__ */ jsx("span", { children: entry.value?.toFixed(2) || 0 })
2093
+ ] }, index))
2094
+ ]
2095
+ }
2096
+ );
2097
+ }
2098
+ return null;
2099
+ };
2100
+ var UnifiedSymbolPerformanceChart = ({
2101
+ volumeData,
2102
+ feesData,
2103
+ priceData,
2104
+ aggregationWindow,
2105
+ includeFees,
2106
+ className
2107
+ }) => {
2108
+ const mergedData = useMemo(() => {
2109
+ const dataMap = /* @__PURE__ */ new Map();
2110
+ volumeData.forEach((item) => {
2111
+ dataMap.set(item.date, {
2112
+ ...dataMap.get(item.date),
2113
+ date: item.date,
2114
+ volume: item.volume
2115
+ });
2116
+ });
2117
+ feesData.forEach((item) => {
2118
+ dataMap.set(item.date, {
2119
+ ...dataMap.get(item.date),
2120
+ date: item.date,
2121
+ fees: item.fees
2122
+ });
2123
+ });
2124
+ priceData.forEach((item) => {
2125
+ dataMap.set(item.date, {
2126
+ ...dataMap.get(item.date),
2127
+ date: item.date,
2128
+ open: item.open,
2129
+ high: item.high,
2130
+ low: item.low,
2131
+ close: item.close
2132
+ });
2133
+ });
2134
+ return Array.from(dataMap.values());
2135
+ }, [volumeData, feesData, priceData]);
2136
+ if (mergedData.length === 0) {
2137
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx("div", { className: "oui-text-center oui-text-base-contrast-54 oui-py-10", children: "No data available" }) });
2138
+ }
2139
+ return /* @__PURE__ */ jsx(Box, { className: cn("oui-w-full oui-h-full", className), children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
2140
+ ComposedChart,
2141
+ {
2142
+ data: mergedData,
2143
+ margin: { left: 0, top: 10, right: 10, bottom: 20 },
2144
+ children: [
2145
+ /* @__PURE__ */ jsx(
2146
+ CartesianGrid,
2147
+ {
2148
+ vertical: false,
2149
+ stroke: "#FFFFFF",
2150
+ strokeOpacity: 0.04
2151
+ }
2152
+ ),
2153
+ /* @__PURE__ */ jsx(
2154
+ XAxis,
2155
+ {
2156
+ dataKey: "date",
2157
+ tickLine: false,
2158
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
2159
+ stroke: "#FFFFFF",
2160
+ strokeOpacity: 0.04
2161
+ }
2162
+ ),
2163
+ /* @__PURE__ */ jsx(
2164
+ YAxis,
2165
+ {
2166
+ yAxisId: "left",
2167
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
2168
+ tickLine: false,
2169
+ axisLine: false,
2170
+ width: 45,
2171
+ label: {
2172
+ value: "Volume / Fees",
2173
+ angle: -90,
2174
+ position: "insideLeft"
2175
+ }
2176
+ }
2177
+ ),
2178
+ /* @__PURE__ */ jsx(
2179
+ YAxis,
2180
+ {
2181
+ yAxisId: "right",
2182
+ orientation: "right",
2183
+ tick: { fontSize: 10, fill: "rgba(255,255,255,0.54)" },
2184
+ tickLine: false,
2185
+ axisLine: false,
2186
+ width: 50,
2187
+ label: { value: "Price", angle: 90, position: "insideRight" }
2188
+ }
2189
+ ),
2190
+ /* @__PURE__ */ jsx(
2191
+ Tooltip,
2192
+ {
2193
+ cursor: /* @__PURE__ */ jsx(CustomizedCross7, {}),
2194
+ content: /* @__PURE__ */ jsx(UnifiedChartTooltip, {})
2195
+ }
2196
+ ),
2197
+ /* @__PURE__ */ jsx(ReferenceLine, { y: 0, stroke: "rgba(0,0,0,0.04)" }),
2198
+ /* @__PURE__ */ jsx(
2199
+ Bar,
2200
+ {
2201
+ yAxisId: "left",
2202
+ dataKey: "volume",
2203
+ fill: "rgba(0, 180, 158, 0.6)",
2204
+ name: "Volume"
2205
+ }
2206
+ ),
2207
+ /* @__PURE__ */ jsx(
2208
+ Bar,
2209
+ {
2210
+ yAxisId: "left",
2211
+ dataKey: "fees",
2212
+ fill: "rgba(255, 107, 107, 0.6)",
2213
+ name: "Fees"
2214
+ }
2215
+ ),
2216
+ /* @__PURE__ */ jsx(
2217
+ Line,
2218
+ {
2219
+ yAxisId: "right",
2220
+ type: "natural",
2221
+ dataKey: "close",
2222
+ stroke: "#00B49E",
2223
+ strokeWidth: 2,
2224
+ dot: false,
2225
+ isAnimationActive: false,
2226
+ name: "Price",
2227
+ strokeLinecap: "round",
2228
+ strokeLinejoin: "round"
2229
+ }
2230
+ )
2231
+ ]
2232
+ }
2233
+ ) }) });
2234
+ };
2235
+
2236
+ // src/tailwindcss/theme.ts
2237
+ var import_plugin = __toESM(require_plugin());
2238
+ var chartPlugin = () => (0, import_plugin.default)(function({ addComponents, addBase }) {
2239
+ addComponents(
2240
+ {
2241
+ ".xAxis": {
2242
+ ".recharts-cartesian-axis-tick:first-child text": {
2243
+ "text-anchor": "start"
2244
+ },
2245
+ ".recharts-cartesian-axis-tick:last-child text": {
2246
+ "text-anchor": "end"
2247
+ }
2248
+ }
2249
+ },
2250
+ {
2251
+ respectPrefix: false
2252
+ }
2253
+ );
2254
+ });
2255
+
2256
+ export { AssetAreaChart, AssetLineChart, ChartEmptyState, CombinedFeesChart, CombinedPnLChart, CombinedPriceChart, CombinedVolumeChart, PnLBarChart, PnlAreaChart, PnlLineChart, UnifiedSymbolPerformanceChart, VolBarChart, chartPlugin };
2257
+ //# sourceMappingURL=index.mjs.map
2
2258
  //# sourceMappingURL=index.mjs.map