PageSourceSearch

https://datahub-pro-production.up.railway.app/assets/Forecasting-yBDmij6o.js

js datahub-pro-production.up.railway.app collected 2026-10-03 12:12:54 UTC 13,922 bytes, 1 lines download raw bytes

1import{r as s,J as ee,j as e,x as te,H as N,aV as ae,B as re,bQ as se,y as oe,aa as le,b9 as ie,ab as ne,ac as de,ad as ce,ae as E,af as pe,ag as me,ai as he,ba as ge,bB as y,aX as m,C as H,a9 as M,aP as R,aj as ue,a1 as O}from"./index-BACUqBz4.js";import{D as xe}from"./DateRangePicker-B4UuHqRU.js";import{N as fe}from"./NextStepChips-u7Xcd5Pc.js";import"./ExplainThis-BeAxgNI8.js";import{A as ye}from"./AiTrio-CvYhPv-6.js";import{C as be}from"./ChartAnnotations-qRF2igM2.js";import{i as ve,n as je,d as Se,b as Ce,f as ke}from"./series-6vDvXsE1.js";import{P as Ae}from"./Pill-DScCZ4qx.js";import{F as g,S as b}from"./Field-CXV1wLbO.js";import"./send-C8h3E7md.js";import"./trash-2-BnqHyW3k.js";const G=[{value:"auto",label:"Auto-pick",desc:"Let the backtest choose"},{value:"holt_winters",label:"Holt-Winters",desc:"Trend + seasonality"},{value:"holt",label:"Holt",desc:"Linear trend"},{value:"ses",label:"Exponential",desc:"Flat + recency-weighted"},{value:"linear",label:"Linear regression",desc:"Simple line fit"}],we=[{value:"auto",label:"Auto"},{value:"daily",label:"Daily"},{value:"weekly",label:"Weekly"},{value:"monthly",label:"Monthly"},{value:"quarterly",label:"Quarterly"}],n=h=>Number(h).toLocaleString(void 0,{maximumFractionDigits:2});function Ee(){const[h,j]=s.useState([]),[i,u]=s.useState(""),[d,_]=s.useState([]),[c,B]=s.useState([]),[x,T]=s.useState(""),[l,F]=s.useState(null),S=(l==null?void 0:l.date_column)||"",[W,V]=s.useState("auto"),[z,K]=s.useState("auto"),[C,$]=s.useState(6),[k,X]=s.useState(!0),[p,I]=s.useState(!1),[A,f]=s.useState(""),[a,w]=s.useState(null);s.useEffect(()=>{ee.list().then(t=>j(t.data||[])).catch(()=>{})},[]);function Q(t){if(u(t),w(null),T(""),F(null),f(""),!t){_([]),B([]);return}O.preview(t).then(o=>{_(o.data.headers||[]),B(o.data.rows||[])}).catch(()=>f("Could not load file preview"))}const{numericCols:D,dateCols:Y}=s.useMemo(()=>c.length?{numericCols:je(c,d),dateCols:d.filter(t=>ve(c,t))}:{numericCols:[],dateCols:[]},[d,c]);async function q(){var t,o;if(!(!i||!x||p)){I(!0),f(""),w(null);try{const r=await O.forecast(i,{value_column:x,date_column:S||null,from:(l==null?void 0:l.from)||null,to:(l==null?void 0:l.to)||null,periods:C,method:W,aggregation:z});w(r.data)}catch(r){f(((o=(t=r==null?void 0:r.response)==null?void 0:t.data)==null?void 0:o.detail)||r.message||"Forecast failed")}finally{I(!1)}}}const J=s.useMemo(()=>{if(!a)return[];const t=a.historical.map(r=>({label:r.label,actual:r.value})),o=a.forecast.map(r=>({label:r.label,forecast:r.forecast,band80:[r.lower_80,r.upper_80],band95:[r.lower_95,r.upper_95]}));return t.length&&o.length&&(t[t.length-1].forecast=t[t.length-1].actual),[...t,...o]},[a]);a&&a.historical.length-1;const U=S||Se(c,d),P=Ce(c,U);return e.jsxs(te,{children:[e.jsx(N,{eyebrow:"Forward looking",title:e.jsx(e.Fragment,{children:e.jsx(N.Accent,{children:"Forecasting"})}),description:"Project future values with seasonality-aware models and proper 80% / 95% confidence intervals.",slot:e.jsx(Ae,{tone:"brand",variant:"solid",children:"Holt-Winters · CI bands"})}),e.jsxs(ae,{padding:"lg",style:{marginBottom:16},children:[e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(220px,1fr))",gap:14,marginBottom:14},children:[e.jsx(g,{label:"Dataset",children:e.jsxs(b,{value:i,onChange:t=>Q(t.target.value),children:[e.jsx("option",{value:"",children:"— Choose a file —"}),h.map(t=>e.jsx("option",{value:t.id,children:t.filename},t.id))]})}),e.jsx(g,{label:"Value column",children:e.jsxs(b,{value:x,onChange:t=>T(t.target.value),disabled:!D.length,children:[e.jsx("option",{value:"",children:"— Numeric column —"}),D.map(t=>e.jsx("option",{value:t,children:t},t))]})}),e.jsx(g,{label:"Aggregation",children:e.jsx(b,{value:z,onChange:t=>K(t.target.value),disabled:!S,children:we.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))})})]}),d.length>0&&e.jsx("div",{style:{marginBottom:12},children:e.jsx(xe,{columns:d,dateColumns:Y,value:l,onChange:F,storageKey:"forecasting.dateRange"})}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(200px,1fr))",gap:14,alignItems:"end"},children:[e.jsx(g,{label:"Method",children:e.jsx(b,{value:W,onChange:t=>V(t.target.value),children:G.map(t=>e.jsx("option",{value:t.value,title:t.desc,children:t.label},t.value))})}),e.jsx(g,{label:`Periods ahead: ${C}`,children:e.jsx("input",{type:"range",min:1,max:24,value:C,onChange:t=>$(parseInt(t.target.value,10)),style:{width:"100%",accentColor:"var(--color-violet-500)",height:38}})}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,fontSize:"0.82rem",color:"var(--fg-secondary)",fontWeight:600,height:38},children:[e.jsx("input",{type:"checkbox",checked:k,onChange:t=>X(t.target.checked),style:{accentColor:"var(--color-violet-500)"}}),"Show confidence bands"]}),e.jsx(re,{onClick:q,disabled:!x,loading:p,leftIcon:se,children:p?"Forecasting…":"Generate forecast"})]})]}),A&&e.jsx("div",{style:{background:"#fef2f2",border:"1px solid #fecaca",color:"#991b1b",padding:"10px 14px",borderRadius:8,marginBottom:14,fontSize:"0.85rem"},children:A}),p&&e.jsxs("div",{style:{textAlign:"center",padding:50,color:"var(--fg-tertiary)"},children:[e.jsx("div",{style:{fontSize:"0.95rem",fontWeight:700,color:"var(--fg-primary)"},children:"Fitting models…"}),e.jsx("div",{style:{fontSize:"0.82rem",marginTop:4},children:"Backtesting 3–4 methods to pick the best."})]}),a&&!p&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(180px, 1fr))",gap:14,marginBottom:18},children:[e.jsx(v,{label:"Last actual",value:n(a.summary.last_actual),color:"#0c1446"}),e.jsx(v,{label:"Next forecast",value:n(a.summary.next_forecast),color:"#e91e8c"}),e.jsx(v,{label:"Backtest MAPE",value:a.summary.mape===1/0||!isFinite(a.summary.mape)?"—":a.summary.mape+"%",color:"#06b6d4",hint:`Hold-out: last ${a.hold_out} periods`}),e.jsx(v,{label:"Model",value:a.method_label,color:"#7c3aed",hint:a.season_length?`Season length: ${a.season_length}
1`:a.aggregation!=="index"?`Aggregation: ${a.aggregation}`:""})]}),e.jsxs("div",{style:{background:"var(--bg-raised)",border:"1px solid var(--border-default)",borderRadius:12,padding:20,marginBottom:16},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline",marginBottom:14,gap:12,flexWrap:"wrap"},children:[e.jsxs("div",{children:[e.jsxs("div",{style:{fontWeight:800,color:"var(--fg-primary)",fontSize:"1.02rem"},children:["Historical + ",a.periods,"-period forecast"]}),P&&e.jsx("div",{style:{fontSize:"0.68rem",color:"var(--fg-tertiary)",fontWeight:600,marginBottom:8},children:P})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"},children:[e.jsxs("div",{style:{fontSize:"0.78rem",color:"var(--fg-tertiary)"},children:["n = ",a.n_points," · trend ",a.summary.trend_direction," (",a.summary.trend_pct>0?"+":"",a.summary.trend_pct,"%)"]}),e.jsx(ye,{fileId:i,what:`${a.method_label} forecast`,pivot:"the next period",context:{method:a.method_label,periods:a.periods,last_actual:a.summary.last_actual,next_forecast:a.summary.next_forecast,mape:a.summary.mape,trend_direction:a.summary.trend_direction,trend_pct:a.summary.trend_pct,aggregation:a.aggregation}}),e.jsx(be,{fileId:i,chartKey:`forecasting:${a.method_label||"auto"}`,xValue:a.method_label||"forecast"})]})]}),e.jsx(oe,{width:"100%",height:360,children:e.jsxs(le,{data:J,margin:{top:8,right:24,bottom:8,left:0},children:[ie("forecasting-hero"),e.jsx(ne,{...de}),e.jsx(ce,{...E,dataKey:"label",interval:"preserveStartEnd",minTickGap:20}),e.jsx(pe,{...E,tickFormatter:ke}),e.jsx(me,{...he,formatter:t=>typeof t=="number"?n(t):t}),e.jsx(ge,{wrapperStyle:{fontSize:12,fontWeight:500,color:"var(--fg-secondary)",paddingTop:8},iconType:"circle",iconSize:8}),e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"forecast-band-95",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:y,stopOpacity:.18}),e.jsx("stop",{offset:"100%",stopColor:m,stopOpacity:.06})]}),e.jsxs("linearGradient",{id:"forecast-band-80",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:y,stopOpacity:.3}),e.jsx("stop",{offset:"100%",stopColor:m,stopOpacity:.12})]})]}),k&&e.jsx(H,{type:"monotone",dataKey:"band95",name:"95% CI",stroke:"none",fill:"url(#forecast-band-95)",isAnimationActive:!1}),k&&e.jsx(H,{type:"monotone",dataKey:"band80",name:"80% CI",stroke:"none",fill:"url(#forecast-band-80)",isAnimationActive:!1}),e.jsx(M,{type:"monotone",dataKey:"actual",name:"Actual",stroke:y,strokeWidth:2.4,dot:{r:2.5,fill:y},connectNulls:!1,...R(0)}),e.jsx(M,{type:"monotone",dataKey:"forecast",name:"Forecast",stroke:m,strokeWidth:2.4,dot:{r:3,fill:m},strokeDasharray:"6 4",connectNulls:!1,...R(1)}),a.historical.length>0&&e.jsx(ue,{x:a.historical[a.historical.length-1].label,stroke:m,strokeWidth:1.8,strokeDasharray:"5 4",label:{value:"▲ Forecast starts",position:"top",fontSize:10,fontWeight:700,fill:m,letterSpacing:"0.02em"}})]})})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1.3fr 1fr",gap:16},children:[e.jsxs("div",{style:{background:"var(--bg-raised)",border:"1px solid var(--border-default)",borderRadius:12,padding:16},children:[e.jsx("div",{style:{fontWeight:800,color:"var(--fg-primary)",marginBottom:10},children:"Model comparison"}),e.jsxs("div",{style:{fontSize:"0.78rem",color:"var(--fg-tertiary)",marginBottom:8},children:["Backtested by withholding the last ",a.hold_out," periods, training on the rest, and measuring error. Lower MAPE is better."]}),e.jsx("div",{style:{overflowX:"auto"},children:e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"0.85rem"},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{textAlign:"left",color:"var(--fg-tertiary)",fontSize:"0.72rem",letterSpacing:.6,textTransform:"uppercase"},children:[e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4"},children:"Method"}),e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4",textAlign:"right"},children:"MAPE"}),e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4",textAlign:"right"},children:"RMSE"})]})}),e.jsx("tbody",{children:Object.entries(a.backtest).map(([t,o])=>{var L;const r=t===a.method;return e.jsxs("tr",{style:{background:r?"#fdf2f8":"transparent"},children:[e.jsxs("td",{style:{padding:"7px 8px",fontWeight:r?800:500,color:r?"#e91e8c":"#0c1446"},children:[((L=G.find(Z=>Z.value===t))==null?void 0:L.label)||t,r&&e.jsx("span",{style:{marginLeft:6,fontSize:"0.7rem"},children:"✓ chosen"})]}),e.jsx("td",{style:{padding:"7px 8px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:isFinite(o.mape)?o.mape+"%":"—"}),e.jsx("td",{style:{padding:"7px 8px",textAlign:"right",fontVariantNumeric:"tabular-nums",color:"var(--fg-tertiary)"},children:isFinite(o.rmse)?n(o.rmse):"—"})]},t)})})]})})]}),e.jsxs("div",{style:{background:"var(--bg-raised)",border:"1px solid var(--border-default)",borderRadius:12,padding:16},children:[e.jsxs("div",{style:{fontWeight:800,color:"var(--fg-primary)",marginBottom:10},children:["Next ",a.periods," periods"]}),e.jsx("div",{style:{maxHeight:220,overflowY:"auto"},children:e.jsx("div",{style:{overflowX:"auto"},children:e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"0.82rem"},children:[e.jsx("thead",{style:{position:"sticky",top:0,background:"var(--bg-raised)"},children:e.jsxs("tr",{style:{textAlign:"left",color:"var(--fg-tertiary)",fontSize:"0.7rem",letterSpacing:.6,textTransform:"uppercase"},children:[e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4"},children:"Period"}),e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4",textAlign:"right"},children:"Forecast"}),e.jsx("th",{style:{padding:"6px 8px",borderBottom:"1px solid #e8eaf4",textAlign:"right"},children:"80% range"})]})}),e.jsx("tbody",{children:a.forecast.map((t,o)=>e.jsxs("tr",{children:[e.jsx("td",{style:{padding:"6px 8px",color:"var(--fg-secondary)"},children:t.label}),e.jsx("td",{style:{padding:"6px 8px",textAlign:"right",fontWeight:700,color:"#e91e8c",fontVariantNumeric:"tabular-nums"},children:n(t.forecast)}),e.jsxs("td",{style:{padding:"6px 8px",textAlign:"right",color:"var(--fg-tertiary)",fontVariantNumeric:"tabular-nums",fontSize:"0.78rem"}
1,children:[n(t.lower_80)," – ",n(t.upper_80)]})]},o))})]})})})]})]}),e.jsx(fe,{fileId:i,suggestions:[{label:"Why this trend?",path:"/trend-analysis",icon:"📈",description:"Decompose the historical signal"},{label:"Sense-check anomalies",path:"/anomaly-detection",icon:"⚠️",description:"Confirm the model isn't reacting to outliers"},{label:"Compare to a goal",path:"/goal-tracker",icon:"🎯",description:"Will the forecast hit your target?"},{label:"Stress-test with What-If",path:"/what-if",icon:"🤔",description:"See how the forecast moves under different assumptions"}]})]}),!a&&!p&&!A&&e.jsxs("div",{style:{textAlign:"center",padding:60,color:"var(--fg-tertiary)"},children:[e.jsx("div",{style:{fontSize:"2rem",marginBottom:12},children:"📈"}),e.jsxs("div",{children:["Pick a file and a numeric value column, then click ",e.jsx("strong",{children:"Generate forecast"}),"."]}),e.jsx("div",{style:{fontSize:"0.8rem",marginTop:6},children:"Add a date column for seasonality-aware modelling."})]})]})}function v({label:h,value:j,color:i,hint:u}){return e.jsxs("div",{style:{background:"var(--bg-raised)",border:"1px solid var(--border-default)",borderRadius:12,padding:14,borderTop:`4px solid ${i}`},children:[e.jsx("div",{style:{fontSize:"0.72rem",color:"var(--fg-tertiary)",marginBottom:4,textTransform:"uppercase",letterSpacing:.6,fontWeight:700},children:h}),e.jsx("div",{style:{fontSize:"1.3rem",fontWeight:800,color:i,lineHeight:1.25},children:j}),u&&e.jsx("div",{style:{fontSize:"0.72rem",color:"var(--fg-tertiary)",marginTop:3},children:u})]})}export{Ee as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.