Files
pyMC_Repeater/repeater/web/html/assets/Statistics-whPbwjoX.js
T
2026-06-23 16:35:02 +01:00

1 line
16 KiB
JavaScript

import{C as e,D as t,K as n,N as r,P as i,T as a,U as o,V as s,_t as c,gt as l,h as u,l as d,m as f,o as p,r as m,s as h,u as g,x as ee,y as _,z as v}from"./runtime-core.esm-bundler-CINEgm0a.js";import{a as te}from"./runtime-dom.esm-bundler-B3VeUO8l.js";import{t as ne}from"./packets-DVGync2A.js";import{_ as re,a as ie,c as ae,d as oe,f as se,g as ce,i as le,l as ue,m as de,n as y,o as fe,p as pe,r as me,s as b,t as x,u as he,v as ge,y as _e}from"./ChartCard-Cb2qelXJ.js";import"./chartjs-adapter-date-fns.esm-Bq5A--VJ.js";import{t as S}from"./Sparkline-Dvj_QJyT.js";var ve={class:`p-3 sm:p-6 space-y-4 sm:space-y-6`},ye={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3`},be={class:`flex items-center gap-2 sm:gap-3`},xe=[`value`],Se={class:`grid grid-cols-1 sm:grid-cols-3 gap-4`},Ce={class:`glass-card rounded-[15px] p-3 sm:p-6`},we={class:`flex items-center gap-3 sm:gap-6 mb-3 sm:mb-4`},Te={class:`flex items-center gap-2`},Ee={class:`flex items-center gap-2`},De={class:`grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6 items-stretch`},Oe={class:`glass-card rounded-[15px] p-3 sm:p-6 flex flex-col`},ke={class:`glass-card rounded-[15px] p-3 sm:p-6 flex flex-col`},Ae={class:`w-28 sm:w-32 text-sm text-content-primary dark:text-content-primary truncate`},je={class:`flex-1 h-12 bg-background-mute dark:bg-stroke/10 rounded overflow-hidden`},Me={class:`w-20 text-sm text-content-secondary dark:text-content-muted text-right tabular-nums`},C=20,w=u({name:`StatisticsView`,__name:`Statistics`,setup(u){b.register(fe,oe,se,he,ue,le,ae,pe,ge,_e,re,me,ie,ce,de);let w=ne(),T=e=>e>48?{unit:`day`,displayFormats:{day:`EEE MMM d`}}:e>24?{unit:`hour`,displayFormats:{hour:`EEE HH:mm`}}:{unit:`hour`,displayFormats:{hour:`HH:mm`}},E=s({packetRate:`Connecting...`,noiseFloor:`Connecting...`,routePie:`Connecting...`}),D=(e,t)=>typeof window>`u`?t:window.getComputedStyle(document.documentElement).getPropertyValue(e).trim()||t,O=()=>({gridColor:D(`--color-border-subtle`,`lightgray`),tickColor:D(`--color-text-secondary`,`gray`),legendColor:D(`--color-text-primary`,`white`),titleColor:D(`--color-text-primary`,`white`),tooltipBg:D(`--color-surface-elevated`,`black`),tooltipTitle:D(`--color-heading`,`white`),tooltipBody:D(`--color-text-primary`,`white`),tooltipBorder:D(`--color-border-subtle`,`gray`)}),k={tx:D(`--color-accent-red`,`tomato`),rx:D(`--color-secondary`,`violet`),noiseFloor:D(`--color-primary`,`deepskyblue`),noiseFloorFill:D(`--color-primary`,`deepskyblue`),noiseFloorGrid:D(`--color-border-hover`,`gray`),totalRx:D(`--color-accent-cyan`,`cyan`),totalTx:D(`--color-accent-green`,`limegreen`),crcErrors:D(`--color-accent-red`,`tomato`),packetTypes:[D(`--openhop-blue-light`,`lightskyblue`),D(`--color-accent-green`,`limegreen`),D(`--color-primary-bg`,`khaki`),D(`--openhop-purple-light`,`violet`),D(`--color-accent-red`,`tomato`),D(`--color-accent-cyan`,`cyan`),D(`--color-accent-green-bg`,`lightgreen`),D(`--color-accent-purple`,`orchid`),D(`--color-accent-green`,`limegreen`)],routes:[D(`--color-primary`,`deepskyblue`),D(`--color-accent-green`,`limegreen`),D(`--color-accent-cyan`,`cyan`),D(`--color-secondary`,`violet`),D(`--color-accent-red`,`tomato`)]},A=o(24),Ne=[{value:1,label:`1 Hour`},{value:6,label:`6 Hours`},{value:12,label:`12 Hours`},{value:24,label:`24 Hours`},{value:48,label:`2 Days`},{value:168,label:`1 Week`}],j=o(null),M=o(null),N=o(null),P=o([]),F=o([]),I=o(!0),L=o(null),R=o({packetRate:!0,noiseFloor:!1,routePie:!0,sparklineMetrics:!0,sparklineCrc:!0}),z=o(null),B=o(null),V=o(null),H=o(null),U=o(null),W=o(null),G=o(null),K=o(null),q=o({totalRx:0,totalTx:0}),J=(e,t)=>{if(e.length===0)return[];let n=Math.round(t*60*60*1e3/72),r=new Map;return e.forEach(([e,t])=>{let i=e;e>0x38d7ea4c68000?i=e/1e3:e>1e9&&e<0xe8d4a51000&&(i=e*1e3);let a=Math.floor(i/n)*n;r.has(a)||r.set(a,[]),r.get(a).push(t)}),Array.from(r.entries()).sort((e,t)=>e[0]-t[0]).map(([,e])=>e.reduce((e,t)=>e+t,0)/e.length)},Y=p(()=>{let e=[],t=[];if(j.value?.series){let n=j.value.series.find(e=>e.type===`rx_count`),r=j.value.series.find(e=>e.type===`tx_count`);n?.data&&(e=J(n.data.map(([e,t])=>[e,t>C?0:t]),A.value)),r?.data&&(t=J(r.data.map(([e,t])=>[e,t>C?0:t]),A.value))}return{totalPackets:e,transmittedPackets:t,droppedPackets:[],crcErrors:J(F.value.map(e=>[e.timestamp>0xe8d4a51000?e.timestamp:e.timestamp*1e3,e.count]),A.value)}}),X=async()=>{try{I.value=!0,L.value=null;let e=await y(`/packet_stats`,{hours:A.value});q.value={totalRx:e.data?.total_packets||0,totalTx:e.data?.transmitted_packets||0},I.value=!1}catch(e){L.value=e instanceof Error?e.message:`Failed to fetch data`,I.value=!1}Pe()},Pe=async()=>{R.value={packetRate:!0,noiseFloor:!0,routePie:!0,sparklineMetrics:!0,sparklineCrc:!0},w.metricsGraphData&&(j.value=w.metricsGraphData),w.crcErrorHistory.length>0&&(F.value=[...w.crcErrorHistory]),w.noiseFloorHistory.length>0&&(M.value={chart_data:w.noiseFloorHistory.map(e=>({timestamp:e.timestamp,noise_floor_dbm:e.noise_floor_dbm}))},$()),Z(),Q(),Fe(),Ie()},Z=async()=>{E.packetRate=`Connecting...`,z.value=null;try{let e=await y(`/metrics_graph_data`,{hours:A.value,resolution:`average`,metrics:`rx_count,tx_count`},{onPhaseChange:e=>{E.packetRate=e===`receiving`?`Receiving data...`:`Connecting...`}});e?.success&&(j.value=e.data)}catch(e){z.value=e instanceof Error?e.message:`Failed to load`,j.value=null}finally{R.value.packetRate=!1,R.value.sparklineMetrics=!1,z.value||(await _(),ze())}},Q=async()=>{E.routePie=`Connecting...`,B.value=null;try{let e=await y(`/route_stats`,{hours:A.value},{onPhaseChange:e=>{E.routePie=e===`receiving`?`Receiving data...`:`Connecting...`}});e?.success&&e.data&&(N.value=e.data)}catch(e){N.value=null,B.value=e instanceof Error?e.message:`Failed to load`}finally{R.value.routePie=!1}},Fe=async()=>{E.noiseFloor=`Connecting...`,V.value=null;try{let e=A.value*120,t=await y(`/noise_floor_history`,{hours:A.value,limit:e},{idleTimeoutMs:3e4,onPhaseChange:e=>{E.noiseFloor=e===`receiving`?`Receiving data...`:`Connecting...`}});if(t.success&&t.data){let e=t.data.history||[];if(Array.isArray(e)&&e.length>0){let t=e;if(e.length>1500){let n=Math.ceil(e.length/1500);t=e.filter((e,t)=>t%n===0)}M.value={chart_data:t.map(e=>({timestamp:e.timestamp||Date.now()/1e3,noise_floor_dbm:e.noise_floor_dbm||e.noise_floor||-120}))},$()}}}catch(e){M.value={chart_data:[]},V.value=e instanceof Error?e.message:`Failed to load`}finally{R.value.noiseFloor=!1,V.value||(await _(),Be())}},Ie=async()=>{H.value=null;try{let e=await y(`/crc_error_history`,{hours:A.value});e?.success&&e.data&&(F.value=e.data.history||[])}catch(e){F.value=[],H.value=e instanceof Error?e.message:`Failed to load`}finally{R.value.sparklineCrc=!1}},Le=()=>{R.value={packetRate:!0,noiseFloor:!0,routePie:!0,sparklineMetrics:!0,sparklineCrc:!0},Re(),z.value=null,B.value=null,V.value=null,X()},$=()=>{P.value=[],M.value?.chart_data&&M.value.chart_data.length>0&&(P.value=M.value.chart_data.map(e=>({timestamp:e.timestamp*1e3,snr:null,rssi:null,noiseFloor:e.noise_floor_dbm})))},Re=()=>{try{U.value&&=(U.value.destroy(),null),W.value&&=(W.value.destroy(),null)}catch(e){console.error(`Error destroying charts:`,e)}},ze=()=>{if(!G.value)return;let e=G.value.getContext(`2d`);if(!e)return;let t=[],n=[];if(j.value?.series){let e=j.value.series.find(e=>e.type===`rx_count`),r=j.value.series.find(e=>e.type===`tx_count`);e?.data&&(t=e.data.map(([e,t])=>{let n=e;return n=e>0x38d7ea4c68000?e/1e3:e>0xe8d4a51000?e:e>1e9?e*1e3:Date.now(),{x:n,y:t>C?0:t*3600}})),r?.data&&(n=r.data.map(([e,t])=>{let n=e;return n=e>0x38d7ea4c68000?e/1e3:e>0xe8d4a51000?e:e>1e9?e*1e3:Date.now(),{x:n,y:t>C?0:t*3600}}))}if(t.length===0&&n.length===0){z.value=`No data available for the selected time range`;return}z.value=null,U.value&&=(U.value.destroy(),null);let r=Math.round(A.value*60*60*1e3/72),i=e=>{if(e.length===0)return[];let t=new Map;return e.forEach(e=>{let n=Math.floor(e.x/r)*r;t.has(n)||t.set(n,[]),t.get(n).push(e.y)}),Array.from(t.entries()).map(([e,t])=>({x:e,y:t.reduce((e,t)=>e+t,0)/t.length})).sort((e,t)=>e.x-t.x)},a=(e,t=3)=>{if(e.length<t)return e;let n=[];for(let r=0;r<e.length;r++){let i=Math.max(0,r-Math.floor(t/2)),a=Math.min(e.length,r+Math.ceil(t/2)),o=e.slice(i,a),s=o.reduce((e,t)=>e+t.y,0)/o.length;n.push({x:e[r].x,y:s})}return n},o=a(i(t)),s=a(i(n)),c=[...o.map(e=>e.y),...s.map(e=>e.y)],l=Math.min(...c),u=Math.max(...c),d=u-l||u*.1||.001,f=Math.max(0,l-d*.05),p=u+d*.05;try{let t=JSON.parse(JSON.stringify(o));U.value=v(new b(e,{type:`line`,data:{datasets:[{label:`TX/hr`,data:JSON.parse(JSON.stringify(s)),borderColor:k.tx,backgroundColor:k.tx,borderWidth:2,fill:`origin`,tension:.4,pointRadius:0,pointHoverRadius:3,order:1},{label:`RX/hr`,data:t,borderColor:k.rx,backgroundColor:k.rx,borderWidth:2,fill:`origin`,tension:.4,pointRadius:0,pointHoverRadius:3,order:2}]},options:{responsive:!0,maintainAspectRatio:!1,animation:{duration:0},interaction:{mode:`index`,intersect:!1},plugins:{legend:{display:!1},title:{display:!1},tooltip:{enabled:!0,backgroundColor:O().tooltipBg,titleColor:O().tooltipTitle,bodyColor:O().tooltipBody,borderColor:O().tooltipBorder,borderWidth:1,padding:12,displayColors:!0,callbacks:{title:function(e){let t=e[0]?.parsed?.x;return t==null?``:new Date(t).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})},label:function(e){let t=e.dataset?.label||``,n=e.parsed?.y;return n==null?t:`${t}: ${n.toFixed(1)}`}}}},scales:{x:{type:`time`,time:T(A.value),min:Date.now()-A.value*3600*1e3,max:Date.now(),grid:{color:O().gridColor},ticks:{color:O().tickColor,maxTicksLimit:8}},y:{beginAtZero:!1,title:{display:!0,text:`Packets / Hour`,color:O().tickColor},grid:{color:O().gridColor},ticks:{color:O().tickColor,callback:function(e){return typeof e==`number`?e.toFixed(1):e}},min:f,max:p}}}}))}catch(e){console.error(`Error creating packet rate chart:`,e),z.value=`Failed to render chart`}},Be=()=>{if(!K.value)return;let e=K.value.getContext(`2d`);if(!e)return;let t=P.value.map(e=>({x:e.timestamp,y:e.noiseFloor})).filter(e=>e.y!==null&&e.y!==void 0),r=t.map(e=>e.y),i=r.length>0?Math.min(...r):-120,a=r.length>0?Math.max(...r):-110,o=a-i||1,s=i-o*.05,c=a+o*.05;if(W.value)try{let e=n(W.value),r=JSON.parse(JSON.stringify(t));e.data.datasets[0]&&(e.data.datasets[0].data=r),e.options?.scales?.x&&(e.options.scales.x.min=Date.now()-A.value*3600*1e3,e.options.scales.x.max=Date.now(),e.options.scales.x.time=T(A.value)),e.options?.scales?.y?.ticks&&(e.options.scales.y.ticks.color=O().tickColor),e.options?.plugins?.legend?.labels&&(e.options.plugins.legend.labels.color=O().legendColor),e.update();return}catch{W.value.destroy(),W.value=null}W.value=v(new b(e,{type:`scatter`,data:{datasets:[{label:`Noise Floor (dBm)`,data:JSON.parse(JSON.stringify(t)),borderWidth:0,backgroundColor:k.noiseFloorFill,pointRadius:3,pointHoverRadius:5,pointStyle:`circle`}]},options:{responsive:!0,maintainAspectRatio:!1,animation:{duration:0},interaction:{mode:`index`,intersect:!1},plugins:{legend:{display:!0,position:`top`,labels:{color:O().legendColor,usePointStyle:!0,padding:20}},tooltip:{enabled:!0,backgroundColor:O().tooltipBg,titleColor:O().tooltipTitle,bodyColor:O().tooltipBody,borderColor:O().tooltipBorder,borderWidth:1,padding:12,displayColors:!0,callbacks:{title:function(e){let t=e[0]?.parsed?.x;return t==null?``:new Date(t).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})},label:function(e){let t=e.dataset?.label||``,n=e.parsed?.y;return n==null?t:`${t}: ${n.toFixed(1)} dBm`}}}},scales:{x:{type:`time`,time:T(A.value),min:Date.now()-A.value*3600*1e3,max:Date.now(),grid:{color:O().gridColor},ticks:{color:O().tickColor,maxTicksLimit:8}},y:{type:`linear`,display:!0,title:{display:!0,text:`Noise Floor (dBm)`,color:O().titleColor},grid:{color:k.noiseFloorGrid},ticks:{color:O().tickColor,callback:function(e){return typeof e==`number`?e.toFixed(1):e}},min:s,max:c}}}}))};return e(async()=>{await _(),X(),window.addEventListener(`resize`,()=>{setTimeout(()=>{n(U.value)?.resize(),n(W.value)?.resize()},100)})}),ee(()=>{U.value?.destroy(),W.value?.destroy(),window.removeEventListener(`resize`,()=>{})}),(e,n)=>(a(),g(`div`,ve,[h(`div`,ye,[n[8]||=h(`h2`,{class:`text-xl sm:text-2xl font-bold text-content-primary dark:text-content-primary`},` Statistics `,-1),h(`div`,be,[n[7]||=h(`label`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Time Range:`,-1),i(h(`select`,{"onUpdate:modelValue":n[0]||=e=>A.value=e,onChange:Le,class:`modal-select w-auto`},[(a(),g(m,null,t(Ne,e=>h(`option`,{key:e.value,value:e.value,class:`bg-surface text-content-primary`},c(e.label),9,xe)),64))],544),[[te,A.value]])])]),h(`div`,Se,[f(S,{title:`Total RX`,value:q.value.totalRx,color:k.totalRx,data:Y.value.totalPackets,loading:R.value.sparklineMetrics,error:z.value,variant:`classic`,onRetry:n[1]||=()=>{R.value.sparklineMetrics=!0,R.value.packetRate=!0,z.value=null,Z()}},null,8,[`value`,`color`,`data`,`loading`,`error`]),f(S,{title:`Total TX`,value:q.value.totalTx,color:k.totalTx,data:Y.value.transmittedPackets,loading:R.value.sparklineMetrics,error:z.value,variant:`classic`,onRetry:n[2]||=()=>{R.value.sparklineMetrics=!0,R.value.packetRate=!0,z.value=null,Z()}},null,8,[`value`,`color`,`data`,`loading`,`error`]),f(S,{title:`CRC Errors`,value:F.value.reduce((e,t)=>e+t.count,0),color:k.crcErrors,data:Y.value.crcErrors,loading:R.value.sparklineCrc,error:H.value,variant:`classic`,onRetry:n[3]||=()=>{R.value.sparklineCrc=!0,H.value=null,Ie()}},null,8,[`value`,`color`,`data`,`loading`,`error`])]),h(`div`,Ce,[n[12]||=h(`h3`,{class:`text-content-primary dark:text-content-primary text-lg sm:text-xl font-semibold mb-3 sm:mb-4`},` Performance Metrics `,-1),h(`div`,null,[n[11]||=h(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm uppercase tracking-wide mb-2`},` Packet Rate (RX/TX PER HOUR) `,-1),h(`div`,we,[h(`div`,Te,[h(`div`,{class:`w-3 h-3 rounded-full`,style:l({backgroundColor:k.rx})},null,4),n[9]||=h(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`RX/hr`,-1)]),h(`div`,Ee,[h(`div`,{class:`w-3 h-3 rounded-full`,style:l({backgroundColor:k.tx})},null,4),n[10]||=h(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`TX/hr`,-1)])]),f(x,{class:`h-40 sm:h-48 rounded-lg p-2 sm:p-4`,"is-loading":R.value.packetRate,error:z.value,status:E.packetRate,onRetry:n[4]||=()=>{R.value.packetRate=!0,z.value=null,Z()}},{default:r(()=>[h(`canvas`,{ref_key:`packetRateCanvasRef`,ref:G,class:`w-full h-full relative z-10`},null,512)]),_:1},8,[`is-loading`,`error`,`status`])])]),h(`div`,De,[h(`div`,Oe,[n[13]||=h(`h3`,{class:`text-content-primary dark:text-content-primary text-lg sm:text-xl font-semibold mb-3 sm:mb-4`},` Noise Floor Over Time `,-1),f(x,{class:`flex-1 min-h-[12rem] sm:min-h-[16rem] rounded-lg`,"is-loading":R.value.noiseFloor,error:V.value,status:E.noiseFloor,onRetry:n[5]||=()=>{R.value.noiseFloor=!0,V.value=null,Fe()}},{default:r(()=>[h(`canvas`,{ref_key:`signalMetricsCanvasRef`,ref:K,class:`absolute inset-0 w-full h-full`},null,512)]),_:1},8,[`is-loading`,`error`,`status`])]),h(`div`,ke,[n[14]||=h(`h3`,{class:`text-content-primary dark:text-content-primary text-lg sm:text-xl font-semibold mb-3 sm:mb-4`},` Route Distribution `,-1),f(x,{class:`flex-1 flex flex-col justify-evenly min-h-[8rem]`,"is-loading":R.value.routePie,error:B.value,status:E.routePie,onRetry:n[6]||=()=>{R.value.routePie=!0,B.value=null,Q()}},{default:r(()=>[N.value?.route_totals?(a(!0),g(m,{key:0},t(N.value.route_totals,(e,t,n)=>(a(),g(`div`,{key:t,class:`flex items-center gap-3`},[h(`div`,Ae,c(t),1),h(`div`,je,[h(`div`,{class:`h-full rounded transition-all duration-300`,style:l({width:`${e/Math.max(...Object.values(N.value.route_totals))*100}%`,backgroundColor:k.routes[n%k.routes.length]})},null,4)]),h(`div`,Me,c(e.toLocaleString()),1)]))),128)):d(``,!0)]),_:1},8,[`is-loading`,`error`,`status`])])])]))}});export{w as default};