@graphysdk/geom-boxplot 0.1.1-beta.1794327284843 → 0.1.1-beta.1794385976422

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.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let a=require("@graphysdk/react"),S=require("react"),f=require("react/jsx-runtime");var x={q1:"boxplotQ1",median:"boxplotMedian",q3:"boxplotQ3",lowerWhisker:"boxplotLowerWhisker",upperWhisker:"boxplotUpperWhisker",count:"boxplotCount",mean:"boxplotMean",notchLower:"boxplotNotchLower",notchUpper:"boxplotNotchUpper",relativeWidth:"boxplotRelativeWidth",outlier:"boxplotOutlier"},B=e=>(e.start+e.end)/2,$=(e,t)=>{const r=t==="x"?(0,a.getXMin)(e):(0,a.getYMin)(e),o=t==="x"?(0,a.getXMax)(e):(0,a.getYMax)(e),n=t==="x"?(0,a.getYMin)(e):(0,a.getXMin)(e),s=t==="x"?(0,a.getYMax)(e):(0,a.getXMax)(e),i=(0,a.getScaledAesthetic)(e,"q1"),u=(0,a.getScaledAesthetic)(e,"median"),c=(0,a.getScaledAesthetic)(e,"q3");if(r===null||o===null||n===null||s===null||u===null||i===null||c===null)return null;const l=T(e,"notchLower"),d=T(e,"notchUpper"),[m,k]=ne(r,o,e);return{observation:e,start:m,end:k,lowerWhisker:n,q1:i,median:u,q3:c,upperWhisker:s,mean:T(e,"mean"),notch:l===null||d===null?null:{lower:l,upper:d}}},X=(e,t)=>{const r=t==="x"?(0,a.getXMin)(e):(0,a.getYMin)(e),o=t==="x"?(0,a.getXMax)(e):(0,a.getYMax)(e),n=(0,a.getScaledAesthetic)(e,"outlier");return r===null||o===null||n===null?null:{observation:e,band:B({start:r,end:o}),value:n}},W=(e,t)=>{const r=[],o=[];for(const n of e){const s=$(n,t);if(s!==null){r.push(s);continue}const i=X(n,t);i!==null&&o.push(i)}return{boxes:r,outliers:o}},T=(e,t)=>(0,a.getScaledAesthetic)(e,t)??null,ne=(e,t,r)=>{const o=r[x.relativeWidth];if(typeof o!="number")return[e,t];const n=(e+t)/2,s=(t-e)*o/2;return[n-s,n+s]},b=1.5,F=e=>e==="min-max"||typeof e=="number"&&Number.isFinite(e)&&e>=0,ae=1.58,se=(e,t)=>{if(e.length===0)return null;const r=[...e].sort((m,k)=>m-k),o=_(r,.25),n=_(r,.5),s=_(r,.75),i=t==="min-max"?1/0:t*(s-o),u=o-i,c=s+i,l=r.filter(m=>m>=u&&m<=c),d=ae*(s-o)/Math.sqrt(e.length);return{lowerWhisker:Math.min(l[0]??o,o),q1:o,median:n,q3:s,upperWhisker:Math.max(l[l.length-1]??s,s),count:e.length,mean:r.reduce((m,k)=>m+k,0)/r.length,notchLower:n-d,notchUpper:n+d}},_=(e,t)=>{const r=(e.length-1)*t,o=Math.floor(r),n=e[o]??0;return n+((e[o+1]??n)-n)*(r-o)},H={q1:x.q1,median:x.median,q3:x.q3,lowerWhisker:x.lowerWhisker,upperWhisker:x.upperWhisker,count:x.count,outlier:x.outlier},z=new Set([...Object.keys(H),"mean","notchLower","notchUpper"]),ie=class extends a.Stat{constructor(...e){super(...e),this.type="boxplot",this.computedAesthetics=z}computeStat({data:e,mapping:t,params:r}){const o=(0,a.readVariableName)(t.x),n=(0,a.readVariableName)(t.y);if(o===null||n===null||!e.hasVariable(o)||!e.hasVariable(n))return{data:e,mapping:{}};if(e.size()>0&&e.getType(n)!=="numeric"){const i=e.getType(n);throw new a.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'boxplot' stat requires a numeric 'y' (got '${i}' for variable '${n}')`,context:{aesthetic:"y",variableName:n,variableType:i},suggestion:"Map the raw values to 'y', or summarised columns under stat 'identity'."})}const s=r?.extent;return{data:le({data:e,xVariable:o,yVariable:n,groupVariables:(0,a.getGroupVariables)(e,t).filter(i=>i!==o),extent:F(s)?s:b}),mapping:H}}},le=({data:e,xVariable:t,yVariable:r,groupVariables:o,extent:n})=>{const s=ue(e,t,r,o),i=e.getVariableNames(),u=new Map(i.map(p=>[p,e.getValues(p)])),c=new Map(i.map(p=>[p,[]])),l={q1:[],median:[],q3:[],lowerWhisker:[],upperWhisker:[],count:[],mean:[],notchLower:[],notchUpper:[],outlier:[]},d=[];for(const p of s){const v=se(p.values,n);if(v===null)continue;for(const h of i)c.get(h)?.push(ce(u.get(h)??[],p.indices));l.q1.push(v.q1),l.median.push(v.median),l.q3.push(v.q3),l.lowerWhisker.push(v.lowerWhisker),l.upperWhisker.push(v.upperWhisker),l.count.push(v.count),l.mean.push(v.mean),l.notchLower.push(v.notchLower),l.notchUpper.push(v.notchUpper),l.outlier.push(null);const w={low:v.lowerWhisker,high:v.upperWhisker};p.indices.forEach((h,y)=>{const M=p.values[y];M!==void 0&&(M<w.low||M>w.high)&&d.push({index:h,value:M})})}for(const{index:p,value:v}of d){for(const w of i)c.get(w)?.push(u.get(w)?.[p]??null);l.q1.push(null),l.median.push(null),l.q3.push(null),l.lowerWhisker.push(null),l.upperWhisker.push(null),l.count.push(null),l.mean.push(null),l.notchLower.push(null),l.notchUpper.push(null),l.outlier.push(v)}const m=e.getValueFormat(r),k=Object.fromEntries(i.map(p=>[p,{type:e.getType(p),values:c.get(p)??[],valueFormat:e.getValueFormat(p)}]));for(const[p,v]of Object.entries(l)){const w=x[p];k[w]=p==="count"?{type:"numeric",values:v}:{type:"numeric",values:v,valueFormat:m}}return new a.Dataset(k,e.parsingLocale)},ue=(e,t,r,o)=>{const n=[t,...o].map(u=>e.getValues(u)),s=e.getValues(r,{type:"numeric"}),i=new Map;return s.forEach((u,c)=>{if(u===null||!Number.isFinite(u))return;const l=n.map(m=>V(m[c]??null)).join("\0"),d=i.get(l)??{indices:[],values:[]};d.indices.push(c),d.values.push(u),i.set(l,d)}),[...i.values()]},ce=(e,t)=>{const r=e[t[0]??-1]??null,o=V(r);return t.every(n=>V(e[n]??null)===o)?r:null},V=e=>e===null?"\0null":e instanceof Date?`date:${e.getTime()}`:`${typeof e}:${String(e)}`,Y=.6,he=1,de=2,pe=1.5,me=7,ve=1,ge=7,fe=1.5,ke=["q1","median","q3"],ye={strokeWidth:"pixels"},q={stroke:"color",alpha:"unitInterval",strokeWidth:"pixels",dashArray:"dashArray"},C={fill:"color",fillAlpha:"unitInterval",stroke:"color",alpha:"unitInterval",size:"pixels",strokeWidth:"pixels",symbol:"pointSymbol"},Q=class extends a.Geom{constructor(...e){super(...e),this.type="boxplot",this.defaultParams={extent:b,outliers:!0,notch:!1,showMean:!1,varwidth:!1},this.defaultStat=new ie,this.derivedVariables=Object.values(x),this.positionRoles=[{axis:"x",role:"point",valueKind:"value"},{axis:"y",role:"min",valueKind:"value",aesthetic:"lowerWhisker"},{axis:"y",role:"max",valueKind:"value",aesthetic:"upperWhisker"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"q1"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"median"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"q3"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"outlier"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"mean"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"notchLower"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"notchUpper"}],this.aesthetics=[{kind:"visual",name:"color"},{kind:"data",name:"y"},{kind:"data",name:"count"}],this.defaultPosition="dodge",this.supportedPositions=["identity","dodge"],this.supportedCoordTypes=["cartesian","flip"],this.scaleConstraints={requireMainAxisBands:!0},this.grid={cartesian:{hideGridX:!0},flip:{hideGridX:!0}},this.legend={suppressWhenSingleItem:!0},this.spatialKind="rects",this.highlightStrategy="observationRerender",this.tooltip=[{key:"Upper whisker",aesthetic:"upperWhisker",optional:!0},{key:"Q3",aesthetic:"q3",optional:!0},{key:"Median",aesthetic:"median",optional:!0},{key:"Q1",aesthetic:"q1",optional:!0},{key:"Lower whisker",aesthetic:"lowerWhisker",optional:!0},{key:"Count",aesthetic:"count",optional:!0},{key:"Mean",aesthetic:"mean",optional:!0},{key:"Outlier",aesthetic:"outlier",optional:!0}],this.styleTarget=(0,a.defineGeomStyleTarget)({observation:{vocabulary:ye,aesthetics:{fill:"color"},rest:{fill:(0,a.token)("geom"),fillAlpha:1,stroke:(0,a.token)("geomBorder"),strokeWidth:he}},parts:{median:{vocabulary:q,rest:{stroke:(0,a.token)("graphBackground"),alpha:1,strokeWidth:de,dashArray:[]}},whisker:{vocabulary:q,aesthetics:{stroke:"color"},rest:{stroke:(0,a.token)("geom"),alpha:1,strokeWidth:pe,dashArray:[]}},cap:{vocabulary:q,aesthetics:{stroke:"color"},rest:{stroke:(0,a.token)("geom"),alpha:1,strokeWidth:0,dashArray:[]}},outlier:{vocabulary:C,aesthetics:{fill:"color"},rest:{fill:(0,a.token)("geom"),fillAlpha:1,stroke:(0,a.token)("graphBackground"),alpha:1,size:me,strokeWidth:ve}},mean:{vocabulary:C,aesthetics:{stroke:"color"},rest:{fill:(0,a.token)("graphBackground"),fillAlpha:1,stroke:(0,a.token)("geom"),alpha:1,size:ge,strokeWidth:fe}}}}),this.resolveBandFraction=t=>R(t),this.resolveValueSource=t=>t.median??{variable:x.median},this.validateMapping=({mapping:t,computedAesthetics:r})=>r.has("y")?[{code:"CONFLICTING_STAT_MAPPING",message:"boxplot geom draws a summary, not a single 'y'; use the 'boxplot' stat or 'identity'"}]:r.has("median")?[...[...z].filter(o=>t[o]!==void 0).map(o=>({code:"CONFLICTING_STAT_MAPPING",message:`boxplot stat computes '${o}' from 'y'; remove its mapping, or set the layer's stat to 'identity'`})),...t.y===void 0?[{code:"MISSING_AESTHETIC",message:"boxplot stat summarises 'y'; map it to the raw values"}]:[]]:ke.filter(o=>t[o]===void 0).map(o=>({code:"MISSING_AESTHETIC",message:`boxplot geom requires '${o}' when its data is already summarised`,context:{aesthetic:o}})),this.resolveAnchorPosition=(t,{coordSystem:r})=>{const o=(0,a.readMainAxis)(r),n=xe(t,o);return n===null?null:o==="x"?{x:n.band,y:n.value}:{x:n.value,y:n.band}}}resolveParams(e){const{extent:t,width:r,...o}=super.resolveParams(e);return{...o,extent:this.resolveExtent(t,e.diagnostics),...this.resolveWidth(r,e.diagnostics)}}compile({data:e,mapping:t,params:r}){const o=P(e,t.lowerWhisker),n=P(e,t.upperWhisker);if(o===null||n===null)return{data:e,mapping:{}};const{outliers:s,notch:i,showMean:u,varwidth:c}=r,l=P(e,t.outlier),d=s===!1&&l!==null?Se(e,l):e,m=P(d,t.count),k=R(r)/2;return{data:d.addVariable(x.relativeWidth,"numeric",c===!0&&m!==null?we(d,m):Me(d)).addVariable(a.POSITION_VARIABLES.yMin,"numeric",D(d,o,l)).addVariable(a.POSITION_VARIABLES.yMax,"numeric",D(d,n,l)).addConstantVariable(a.POSITION_VARIABLES.xMin,"numeric",-k).addConstantVariable(a.POSITION_VARIABLES.xMax,"numeric",k),mapping:{...t.y===void 0&&{y:t.median},...u===!0&&t.mean===void 0&&d.hasVariable(x.mean)&&{mean:x.mean},...i===!0&&t.notchLower===void 0&&d.hasVariable(x.notchLower)&&{notchLower:x.notchLower,notchUpper:x.notchUpper}}}}resolveExtent(e,t){return F(e)?e:(t?.addWarning({code:"INVALID_GEOM_PARAM",message:`Boxplot extent must be a non-negative number or 'min-max', got ${String(e)}; falling back to ${b}.`,context:{geom:this.type,param:"extent",expected:"extent >= 0 or 'min-max'",actual:String(e)},suggestion:"Set params.extent to a number of interquartile ranges, or 'min-max'."}),b)}resolveWidth(e,t){if(e===void 0)return{};const r=typeof e=="number"&&Number.isFinite(e)?e:null;if(r!==null&&r>0&&r<=1)return{width:r};const o=r!==null&&r>1?1:void 0;return t?.addWarning({code:"INVALID_GEOM_PARAM",message:`Boxplot width must be a fraction in (0, 1], got ${String(e)}; falling back to ${o??Y}.`,context:{geom:this.type,param:"width",expected:"0 < width <= 1",actual:r??String(e)},suggestion:"Set params.width to a fraction of the category band in (0, 1]."}),o!==void 0?{width:o}:{}}},xe=(e,t)=>{const r=$(e,t);if(r!==null)return{band:B(r),value:r.median};const o=X(e,t);return o===null?null:{band:o.band,value:o.value}},R=({width:e})=>e??Y,we=(e,t)=>{const r=e.getValues(t,{type:"numeric"}),o=Math.max(0,...r.map(n=>n??0));return r.map(n=>n===null||o===0?null:Math.sqrt(n/o))},Me=e=>Array.from({length:e.size()},()=>null),D=(e,t,r)=>{const o=r===null?[]:e.getValues(r,{type:"numeric"});return e.getValues(t,{type:"numeric"}).map((n,s)=>n??o[s]??null)},Se=(e,t)=>{const r=e.getValues(t,{type:"numeric"});return e.take(r.flatMap((o,n)=>o===null?[n]:[]))},P=(e,t)=>{const r=(0,a.readVariableName)(t);return r!==null&&e.hasVariable(r)?r:null},We=5e-4,Ie=.5,Oe=.5,Z=(e,t)=>{const r=(e.q1+e.q3)/2,o=Math.max(Math.abs(e.q3-e.q1),We)/2,n=g(t,e.start,r-o),s=g(t,e.end,r+o),[i,u]=K(n.x,s.x),[c,l]=K(n.y,s.y);return{x:i,y:c,width:u-i,height:l-c}},J=(e,t)=>{if(e.notch===null)return null;const{lower:r,upper:o}=e.notch,[n,s]=te(e);return[g(t,e.start,e.q1),g(t,e.start,r),g(t,n,e.median),g(t,e.start,o),g(t,e.start,e.q3),g(t,e.end,e.q3),g(t,e.end,o),g(t,s,e.median),g(t,e.end,r),g(t,e.end,e.q1)]},Pe=(e,t)=>{const[r,o]=e.notch===null?[e.start,e.end]:te(e);return{from:g(t,r,e.median),to:g(t,o,e.median)}},ee=(e,t)=>e.mean===null?null:g(t,B(e),e.mean),te=e=>{const t=(e.end-e.start)*(1-Oe)/2;return[e.start+t,e.end-t]},re=(e,t)=>{const r=B(e),o=(e.end-e.start)*Ie/2;return[{side:"lower",quartile:e.q1,reach:e.lowerWhisker},{side:"upper",quartile:e.q3,reach:e.upperWhisker}].filter(({quartile:n,reach:s})=>n!==s).map(({side:n,quartile:s,reach:i})=>({side:n,stem:{from:g(t,r,s),to:g(t,r,i)},cap:{from:g(t,r-o,i),to:g(t,r+o,i)}}))},g=(e,t,r)=>{const o=(0,a.composePoint)(e,{main:t,cross:r});return{x:(0,a.toViewBoxX)(o.x),y:(0,a.toViewBoxY)(o.y)}},K=(e,t)=>e<=t?[e,t]:[t,e],O=(e,t)=>({x:e.x*t.width,y:e.y*t.height}),N=(e,t)=>`${e.map((r,o)=>{const{x:n,y:s}=O(r,t);return`${o===0?"M":"L"}${n},${s}`}).join("")}Z`,be=(e,t)=>N([{x:e.x,y:e.y},{x:e.x+e.width,y:e.y},{x:e.x+e.width,y:e.y+e.height},{x:e.x,y:e.y+e.height}],t),Be=(e,t)=>{const r=O(e.from,t),o=O(e.to,t);return`M${r.x},${r.y}L${o.x},${o.y}`},Ee=({layer:e,coordSystem:t,panelRect:r,styleReaders:o})=>{const n=(0,a.readMainAxis)(t),{boxes:s,outliers:i}=W(e.data,n),u=s.map(h=>{const y=J(h,n);return y!==null?{kind:"region",pathData:N(y,r)}:{kind:"region",pathData:be(Z(h,n),r)}}),c=o.part("whisker"),l=o.part("cap"),d=s.flatMap(h=>re(h,n).flatMap(y=>[{segment:y.stem,readers:c},{segment:y.cap,readers:l}].flatMap(({segment:M,readers:E})=>{const I=E?.get("strokeWidth",h.observation)??0;return I>0?[{kind:"stroke",pathData:Be(M,r),width:I}]:[]}))),m=o.part("outlier"),k=m===void 0?[]:i.map(h=>({center:O(g(n,h.band,h.value),r),size:j(m,h.observation)})),p=o.part("mean"),v=p===void 0?[]:s.flatMap(h=>{const y=ee(h,n);return y===null?[]:[{center:O(y,r),size:j(p,h.observation)}]}),w=(0,a.buildDotsEditOutlineShapes)([...k,...v]);return[...d,...u,...w]},j=(e,t)=>(e.get("size",t)??0)+(e.get("strokeWidth",t)??0),A=e=>{const t=(0,a.createStableKeyGenerator)(e.data,e.mapping,e.id),r=(0,a.readVariableName)(e.mapping.outlier),o=n=>`${t(n.observation)}-outlier-${String(r===null?n.value:n.observation[r])}`;return{readBoxKey:t,readOutlierKeys:n=>{const s=new Map;return n.map(i=>{const u=o(i),c=s.get(u)??0;return s.set(u,c+1),c===0?u:`${u}-${c}`})}}},Te=(e,t,r)=>{const o=e.data.getVariableNames(),n=i=>JSON.stringify(o.map(u=>i.observation[u]??null)),s=new Set(r.map(n));return t.filter(i=>s.has(n(i)))},oe=(e,t,r)=>{const o=new Set(t.map(n=>r(n.observation)));return e.filter(n=>o.has(r(n.observation)))},L=({boxes:e,outliers:t,mainAxis:r,panelSize:o,source:n,styleReaders:s,keys:i,hovered:u,animateTransitions:c=!1})=>{const l=u===void 0?void 0:"hovered",d=s.part("whisker"),m=s.part("cap"),k=s.part("median"),p=s.part("mean"),v=s.part("outlier"),w=i.readOutlierKeys(t);return(0,f.jsxs)(f.Fragment,{children:[e.flatMap(h=>re(h,r).flatMap(y=>[{piece:"stem",testId:"boxplot-whisker",readers:d},{piece:"cap",testId:"boxplot-cap",readers:m}].map(({piece:M,testId:E,readers:I})=>I===void 0?null:(0,f.jsx)(G,{testId:E,segment:y[M],observation:h.observation,readers:I,state:l,animateTransitions:c},`${i.readBoxKey(h.observation)}-${y.side}-${M}`)))),(0,f.jsx)(a.GeomOverpaint,{styleReaders:s,state:l,children:e.map(h=>(0,f.jsx)(_e,{box:h,mainAxis:r,panelSize:o,source:n,styleReaders:s,state:l,animateTransitions:c},i.readBoxKey(h.observation)))}),k&&e.map(h=>(0,f.jsx)(G,{testId:"boxplot-median",segment:Pe(h,r),observation:h.observation,readers:k,state:l,animateTransitions:c},i.readBoxKey(h.observation))),p&&e.map(h=>{const y=ee(h,r);return y===null?null:(0,f.jsx)(U,{testId:"boxplot-mean",centre:y,observation:h.observation,readers:p,state:l,animateTransitions:c},i.readBoxKey(h.observation))}),v&&t.map((h,y)=>(0,f.jsx)(U,{testId:"boxplot-outlier",centre:g(r,h.band,h.value),observation:h.observation,readers:v,state:l,animateTransitions:c},w[y]))]})},G=({testId:e,segment:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const i=o.get("strokeWidth",r,n)??0,u=o.get("stroke",r,n);return(0,f.jsx)(a.GeomLine,{"data-testid":e,x1:(0,a.toPercent)(t.from.x),y1:(0,a.toPercent)(t.from.y),x2:(0,a.toPercent)(t.to.x),y2:(0,a.toPercent)(t.to.y),stroke:u===void 0?void 0:(0,a.toPaintColor)(u),strokeOpacity:o.get("alpha",r,n),strokeWidth:i,strokeDasharray:(0,a.toStrokeDasharray)(o.get("dashArray",r,n),i),animateTransitions:s})},_e=({box:e,mainAxis:t,panelSize:r,source:o,styleReaders:n,state:s,animateTransitions:i})=>{const u=n.get("fill",e.observation,s),c=n.get("stroke",e.observation,s),l={fill:u===void 0?void 0:(0,a.toPaintColor)(u),opacity:n.get("alpha",e.observation,s),fillOpacity:n.get("fillAlpha",e.observation,s),stroke:c===void 0?void 0:(0,a.toPaintColor)(c),strokeOpacity:n.get("strokeAlpha",e.observation,s),strokeWidth:n.get("strokeWidth",e.observation,s),effects:(0,a.readGeomEffects)(n,e.observation,s),animateTransitions:i},d=J(e,t);if(d!==null)return(0,f.jsx)(a.GeomPath,{"data-testid":"boxplot-box",d:N(d,r),source:o,...l});const m=Z(e,t);return(0,f.jsx)(a.GeomRect,{"data-testid":"boxplot-box",x:(0,a.toPercent)(m.x),y:(0,a.toPercent)(m.y),width:(0,a.toPercent)(m.width),height:(0,a.toPercent)(m.height),cornerRadius:n.get("cornerRadius",e.observation,s),...l})},U=({testId:e,centre:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const i=o.get("fill",r,n),u=o.get("stroke",r,n);return(0,f.jsx)(a.GeomCircle,{"data-testid":e,cx:(0,a.toPercent)(t.x),cy:(0,a.toPercent)(t.y),r:(o.get("size",r,n)??0)/2,fill:i===void 0?void 0:(0,a.toPaintColor)(i),opacity:o.get("alpha",r,n),fillOpacity:o.get("fillAlpha",r,n),stroke:u===void 0?void 0:(0,a.toPaintColor)(u),strokeWidth:o.get("strokeWidth",r,n),symbol:o.get("symbol",r,n),animateTransitions:s})},qe=({layer:e,sourceLayer:t,mainAxis:r,styleReaders:o})=>{const n=(0,a.useGeomPanelSize)(),s=(0,S.useMemo)(()=>A(t),[t]),i=(0,S.useMemo)(()=>W(t.data,r).outliers,[t.data,r]),{boxes:u,outliers:c}=(0,S.useMemo)(()=>{const l=W(e.data,r),d=new Set(Te(t,i,l.outliers)),m=new Set(oe(i,l.boxes,s.readBoxKey)),k=i.filter(p=>m.has(p)||d.has(p));return{boxes:l.boxes,outliers:k}},[e.data,r,t,i,s]);return(0,f.jsx)(L,{boxes:u,outliers:c,mainAxis:r,panelSize:n,source:t,styleReaders:o,keys:s})},Ve=({layer:e,primary:t,mainAxis:r,styleReaders:o})=>{const n=(0,a.useGeomPanelSize)(),s=(0,S.useMemo)(()=>W(e.data,r).outliers,[e.data,r]),i=(0,S.useMemo)(()=>A(e),[e]),{boxes:u,outliers:c}=W([t.observation],r);return(0,f.jsx)("g",{"data-testid":"hovered-boxes",children:(0,f.jsx)(L,{boxes:u,outliers:u.length>0?oe(s,u,i.readBoxKey):c,mainAxis:r,panelSize:n,source:e,styleReaders:o,keys:i,hovered:t.observation})})},Ne=({layer:e,mainAxis:t,styleReaders:r,animateTransitions:o,intro:n})=>{const s=(0,a.useGeomPanelSize)(),{boxes:i,outliers:u}=(0,S.useMemo)(()=>W(e.data,t),[e.data,t]),c=(0,f.jsx)(L,{boxes:i,outliers:u,mainAxis:t,panelSize:s,source:e,styleReaders:r,keys:(0,S.useMemo)(()=>A(e),[e]),animateTransitions:o});return n==null?c:(0,f.jsx)(a.IntroFade,{intro:{type:"fade",layerId:n.layerId,durationSeconds:n.durationSeconds},children:c})},Ae=(0,a.defineGeomRenderer)(new Q,{coord:"cartesian",swatchShape:"square",overpaintPlacement:"manual",guideMode:"band",render:({layer:e,coordSystem:t,styleReaders:r,animateTransitions:o,intro:n})=>(0,f.jsx)(Ne,{layer:e,mainAxis:(0,a.readMainAxis)(t),styleReaders:r,animateTransitions:o,intro:n}),renderHighlight:({layer:e,sourceLayer:t,coordSystem:r,styleReaders:o})=>(0,f.jsx)(qe,{layer:e,sourceLayer:t,mainAxis:(0,a.readMainAxis)(r),styleReaders:o}),renderHover:({layer:e,primary:t,coordSystem:r,styleReaders:o})=>(0,f.jsx)(Ve,{layer:e,primary:t,mainAxis:(0,a.readMainAxis)(r),styleReaders:o}),getEditOutlineShapes:Ee});exports.BOXPLOT_VARIABLES=x;exports.BoxplotGeom=Q;exports.boxplot=Ae;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let a=require("@graphysdk/react"),M=require("react"),g=require("react/jsx-runtime");var y={q1:"boxplotQ1",median:"boxplotMedian",q3:"boxplotQ3",lowerWhisker:"boxplotLowerWhisker",upperWhisker:"boxplotUpperWhisker",count:"boxplotCount",mean:"boxplotMean",notchLower:"boxplotNotchLower",notchUpper:"boxplotNotchUpper",relativeWidth:"boxplotRelativeWidth",outlier:"boxplotOutlier"},b=e=>(e.start+e.end)/2,U=(e,t)=>{const r=t==="x"?(0,a.getXMin)(e):(0,a.getYMin)(e),o=t==="x"?(0,a.getXMax)(e):(0,a.getYMax)(e),n=t==="x"?(0,a.getYMin)(e):(0,a.getXMin)(e),s=t==="x"?(0,a.getYMax)(e):(0,a.getXMax)(e),i=(0,a.getScaledAesthetic)(e,"q1"),c=(0,a.getScaledAesthetic)(e,"median"),u=(0,a.getScaledAesthetic)(e,"q3");if(r===null||o===null||n===null||s===null||c===null||i===null||u===null)return null;const l=oe(i,u,t),d=T(e,"notchLower"),m=T(e,"notchUpper"),[f,p]=ne(r,o,e);return{observation:e,start:f,end:p,lowerWhisker:l?n:s,q1:i,median:c,q3:u,upperWhisker:l?s:n,mean:T(e,"mean"),notch:d===null||m===null?null:{lower:d,upper:m}}},$=(e,t)=>{const r=t==="x"?(0,a.getXMin)(e):(0,a.getYMin)(e),o=t==="x"?(0,a.getXMax)(e):(0,a.getYMax)(e),n=(0,a.getScaledAesthetic)(e,"outlier");return r===null||o===null||n===null?null:{observation:e,band:b({start:r,end:o}),value:n}},P=(e,t)=>{const r=[],o=[];for(const n of e){const s=U(n,t);if(s!==null){r.push(s);continue}const i=$(n,t);i!==null&&o.push(i)}return{boxes:r,outliers:o}},oe=(e,t,r)=>e===t?r==="y":e<t,T=(e,t)=>(0,a.getScaledAesthetic)(e,t)??null,ne=(e,t,r)=>{const o=r[y.relativeWidth];if(typeof o!="number")return[e,t];const n=(e+t)/2,s=(t-e)*o/2;return[n-s,n+s]},O=1.5,X=e=>e==="min-max"||typeof e=="number"&&Number.isFinite(e)&&e>=0,ae=1.58,se=(e,t)=>{if(e.length===0)return null;const r=[...e].sort((m,f)=>m-f),o=_(r,.25),n=_(r,.5),s=_(r,.75),i=t==="min-max"?1/0:t*(s-o),c=o-i,u=s+i,l=r.filter(m=>m>=c&&m<=u),d=ae*(s-o)/Math.sqrt(e.length);return{lowerWhisker:Math.min(l[0]??o,o),q1:o,median:n,q3:s,upperWhisker:Math.max(l[l.length-1]??s,s),count:e.length,mean:r.reduce((m,f)=>m+f,0)/r.length,notchLower:n-d,notchUpper:n+d}},_=(e,t)=>{const r=(e.length-1)*t,o=Math.floor(r),n=e[o]??0;return n+((e[o+1]??n)-n)*(r-o)},F={q1:y.q1,median:y.median,q3:y.q3,lowerWhisker:y.lowerWhisker,upperWhisker:y.upperWhisker,count:y.count,outlier:y.outlier},H=new Set([...Object.keys(F),"mean","notchLower","notchUpper"]),ie=class extends a.Stat{constructor(...e){super(...e),this.type="boxplot",this.computedAesthetics=H}computeStat({data:e,mapping:t,params:r}){const o=(0,a.readVariableName)(t.x),n=(0,a.readVariableName)(t.y);if(o===null||n===null||!e.hasVariable(o)||!e.hasVariable(n))return{data:e,mapping:{}};if(e.size()>0&&e.getType(n)!=="numeric"){const i=e.getType(n);throw new a.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'boxplot' stat requires a numeric 'y' (got '${i}' for variable '${n}')`,context:{aesthetic:"y",variableName:n,variableType:i},suggestion:"Map the raw values to 'y', or summarised columns under stat 'identity'."})}const s=r?.extent;return{data:le({data:e,xVariable:o,yVariable:n,groupVariables:(0,a.getGroupVariables)(e,t).filter(i=>i!==o),extent:X(s)?s:O}),mapping:F}}},le=({data:e,xVariable:t,yVariable:r,groupVariables:o,extent:n})=>{const s=ce(e,t,r,o),i=e.getVariableNames(),c=new Map(i.map(p=>[p,e.getValues(p)])),u=new Map(i.map(p=>[p,[]])),l={q1:[],median:[],q3:[],lowerWhisker:[],upperWhisker:[],count:[],mean:[],notchLower:[],notchUpper:[],outlier:[]},d=[];for(const p of s){const v=se(p.values,n);if(v===null)continue;for(const h of i)u.get(h)?.push(ue(c.get(h)??[],p.indices));l.q1.push(v.q1),l.median.push(v.median),l.q3.push(v.q3),l.lowerWhisker.push(v.lowerWhisker),l.upperWhisker.push(v.upperWhisker),l.count.push(v.count),l.mean.push(v.mean),l.notchLower.push(v.notchLower),l.notchUpper.push(v.notchUpper),l.outlier.push(null);const x={low:v.lowerWhisker,high:v.upperWhisker};p.indices.forEach((h,k)=>{const w=p.values[k];w!==void 0&&(w<x.low||w>x.high)&&d.push({index:h,value:w})})}for(const{index:p,value:v}of d){for(const x of i)u.get(x)?.push(c.get(x)?.[p]??null);l.q1.push(null),l.median.push(null),l.q3.push(null),l.lowerWhisker.push(null),l.upperWhisker.push(null),l.count.push(null),l.mean.push(null),l.notchLower.push(null),l.notchUpper.push(null),l.outlier.push(v)}const m=e.getValueFormat(r),f=Object.fromEntries(i.map(p=>[p,{type:e.getType(p),values:u.get(p)??[],valueFormat:e.getValueFormat(p)}]));for(const[p,v]of Object.entries(l)){const x=y[p];f[x]=p==="count"?{type:"numeric",values:v}:{type:"numeric",values:v,valueFormat:m}}return new a.Dataset(f,e.parsingLocale)},ce=(e,t,r,o)=>{const n=[t,...o].map(c=>e.getValues(c)),s=e.getValues(r,{type:"numeric"}),i=new Map;return s.forEach((c,u)=>{if(c===null||!Number.isFinite(c))return;const l=n.map(m=>q(m[u]??null)).join("\0"),d=i.get(l)??{indices:[],values:[]};d.indices.push(u),d.values.push(c),i.set(l,d)}),[...i.values()]},ue=(e,t)=>{const r=e[t[0]??-1]??null,o=q(r);return t.every(n=>q(e[n]??null)===o)?r:null},q=e=>e===null?"\0null":e instanceof Date?`date:${e.getTime()}`:`${typeof e}:${String(e)}`,z=.6,he=1,de=2,pe=1.5,me=7,ve=1,ge=7,fe=1.5,ke=["q1","median","q3"],ye={strokeWidth:"pixels"},B={stroke:"color",alpha:"unitInterval",strokeWidth:"pixels",dashArray:"dashArray"},L={fill:"color",fillAlpha:"unitInterval",stroke:"color",alpha:"unitInterval",size:"pixels",strokeWidth:"pixels",symbol:"pointSymbol"},Y=class extends a.Geom{constructor(...e){super(...e),this.type="boxplot",this.defaultParams={extent:O,outliers:!0,notch:!1,showMean:!1,varwidth:!1},this.defaultStat=new ie,this.derivedVariables=Object.values(y),this.positionRoles=[{axis:"x",role:"point",valueKind:"value"},{axis:"y",role:"min",valueKind:"value",aesthetic:"lowerWhisker"},{axis:"y",role:"max",valueKind:"value",aesthetic:"upperWhisker"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"q1"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"median"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"q3"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"outlier"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"mean"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"notchLower"},{axis:"y",role:"scalar",valueKind:"value",aesthetic:"notchUpper"}],this.aesthetics=[{kind:"visual",name:"color"},{kind:"data",name:"y"},{kind:"data",name:"count"}],this.defaultPosition="dodge",this.supportedPositions=["identity","dodge"],this.supportedCoordTypes=["cartesian","flip"],this.scaleConstraints={requireMainAxisBands:!0},this.grid={cartesian:{hideGridX:!0},flip:{hideGridX:!0}},this.legend={suppressWhenSingleItem:!0},this.spatialKind="rects",this.highlightStrategy="observationRerender",this.tooltip=[{key:"Upper whisker",aesthetic:"upperWhisker",optional:!0},{key:"Q3",aesthetic:"q3",optional:!0},{key:"Median",aesthetic:"median",optional:!0},{key:"Q1",aesthetic:"q1",optional:!0},{key:"Lower whisker",aesthetic:"lowerWhisker",optional:!0},{key:"Count",aesthetic:"count",optional:!0},{key:"Mean",aesthetic:"mean",optional:!0},{key:"Outlier",aesthetic:"outlier",optional:!0}],this.styleTarget=(0,a.defineGeomStyleTarget)({observation:{vocabulary:ye,aesthetics:{fill:"color"},rest:{fill:(0,a.token)("geom"),fillAlpha:1,stroke:(0,a.token)("geomBorder"),strokeWidth:he}},parts:{median:{vocabulary:B,rest:{stroke:(0,a.token)("graphBackground"),alpha:1,strokeWidth:de,dashArray:[]}},whisker:{vocabulary:B,aesthetics:{stroke:"color"},rest:{stroke:(0,a.token)("geom"),alpha:1,strokeWidth:pe,dashArray:[]}},cap:{vocabulary:B,aesthetics:{stroke:"color"},rest:{stroke:(0,a.token)("geom"),alpha:1,strokeWidth:0,dashArray:[]}},outlier:{vocabulary:L,aesthetics:{fill:"color"},rest:{fill:(0,a.token)("geom"),fillAlpha:1,stroke:(0,a.token)("graphBackground"),alpha:1,size:me,strokeWidth:ve}},mean:{vocabulary:L,aesthetics:{stroke:"color"},rest:{fill:(0,a.token)("graphBackground"),fillAlpha:1,stroke:(0,a.token)("geom"),alpha:1,size:ge,strokeWidth:fe}}}}),this.resolveBandFraction=t=>C(t),this.resolveValueSource=t=>t.median??{variable:y.median},this.validateMapping=({mapping:t,computedAesthetics:r})=>r.has("y")?[{code:"CONFLICTING_STAT_MAPPING",message:"boxplot geom draws a summary, not a single 'y'; use the 'boxplot' stat or 'identity'"}]:r.has("median")?[...[...H].filter(o=>t[o]!==void 0).map(o=>({code:"CONFLICTING_STAT_MAPPING",message:`boxplot stat computes '${o}' from 'y'; remove its mapping, or set the layer's stat to 'identity'`})),...t.y===void 0?[{code:"MISSING_AESTHETIC",message:"boxplot stat summarises 'y'; map it to the raw values"}]:[]]:ke.filter(o=>t[o]===void 0).map(o=>({code:"MISSING_AESTHETIC",message:`boxplot geom requires '${o}' when its data is already summarised`,context:{aesthetic:o}})),this.resolveAnchorPosition=(t,{coordSystem:r})=>{const o=(0,a.readMainAxis)(r),n=xe(t,o);return n===null?null:o==="x"?{x:n.band,y:n.value}:{x:n.value,y:n.band}}}resolveParams(e){const{extent:t,width:r,...o}=super.resolveParams(e);return{...o,extent:this.resolveExtent(t,e.diagnostics),...this.resolveWidth(r,e.diagnostics)}}compile({data:e,mapping:t,params:r}){const o=I(e,t.lowerWhisker),n=I(e,t.upperWhisker);if(o===null||n===null)return{data:e,mapping:{}};const{outliers:s,notch:i,showMean:c,varwidth:u}=r,l=I(e,t.outlier),d=s===!1&&l!==null?Pe(e,l):e,m=I(d,t.count),f=C(r)/2;return{data:d.addVariable(y.relativeWidth,"numeric",u===!0&&m!==null?we(d,m):Me(d)).addVariable(a.POSITION_VARIABLES.yMin,"numeric",R(d,o,l)).addVariable(a.POSITION_VARIABLES.yMax,"numeric",R(d,n,l)).addConstantVariable(a.POSITION_VARIABLES.xMin,"numeric",-f).addConstantVariable(a.POSITION_VARIABLES.xMax,"numeric",f),mapping:{...t.y===void 0&&{y:t.median},...c===!0&&t.mean===void 0&&d.hasVariable(y.mean)&&{mean:y.mean},...i===!0&&t.notchLower===void 0&&d.hasVariable(y.notchLower)&&{notchLower:y.notchLower,notchUpper:y.notchUpper}}}}resolveExtent(e,t){return X(e)?e:(t?.addWarning({code:"INVALID_GEOM_PARAM",message:`Boxplot extent must be a non-negative number or 'min-max', got ${String(e)}; falling back to ${O}.`,context:{geom:this.type,param:"extent",expected:"extent >= 0 or 'min-max'",actual:String(e)},suggestion:"Set params.extent to a number of interquartile ranges, or 'min-max'."}),O)}resolveWidth(e,t){if(e===void 0)return{};const r=typeof e=="number"&&Number.isFinite(e)?e:null;if(r!==null&&r>0&&r<=1)return{width:r};const o=r!==null&&r>1?1:void 0;return t?.addWarning({code:"INVALID_GEOM_PARAM",message:`Boxplot width must be a fraction in (0, 1], got ${String(e)}; falling back to ${o??z}.`,context:{geom:this.type,param:"width",expected:"0 < width <= 1",actual:r??String(e)},suggestion:"Set params.width to a fraction of the category band in (0, 1]."}),o!==void 0?{width:o}:{}}},xe=(e,t)=>{const r=U(e,t);if(r!==null)return{band:b(r),value:r.median};const o=$(e,t);return o===null?null:{band:o.band,value:o.value}},C=({width:e})=>e??z,we=(e,t)=>{const r=e.getValues(t,{type:"numeric"}),o=Math.max(0,...r.map(n=>n??0));return r.map(n=>n===null||o===0?null:Math.sqrt(n/o))},Me=e=>Array.from({length:e.size()},()=>null),R=(e,t,r)=>{const o=r===null?[]:e.getValues(r,{type:"numeric"});return e.getValues(t,{type:"numeric"}).map((n,s)=>n??o[s]??null)},Pe=(e,t)=>{const r=e.getValues(t,{type:"numeric"});return e.take(r.flatMap((o,n)=>o===null?[n]:[]))},I=(e,t)=>{const r=(0,a.readVariableName)(t);return r!==null&&e.hasVariable(r)?r:null},Se=5e-4,We=.5,Ie=.5,Q=(e,t)=>{const r=(e.q1+e.q3)/2,o=Math.max(Math.abs(e.q3-e.q1),Se)/2,n=(0,a.composePoint)(t,{main:e.start,cross:r-o}),s=(0,a.composePoint)(t,{main:e.end,cross:r+o}),[i,c]=D(n.x,s.x),[u,l]=D(n.y,s.y);return{x:i,y:u,width:c-i,height:l-u}},Z=(e,t)=>{if(e.notch===null)return null;const{lower:r,upper:o}=e.notch,[n,s]=ee(e);return[(0,a.composePoint)(t,{main:e.start,cross:e.q1}),(0,a.composePoint)(t,{main:e.start,cross:r}),(0,a.composePoint)(t,{main:n,cross:e.median}),(0,a.composePoint)(t,{main:e.start,cross:o}),(0,a.composePoint)(t,{main:e.start,cross:e.q3}),(0,a.composePoint)(t,{main:e.end,cross:e.q3}),(0,a.composePoint)(t,{main:e.end,cross:o}),(0,a.composePoint)(t,{main:s,cross:e.median}),(0,a.composePoint)(t,{main:e.end,cross:r}),(0,a.composePoint)(t,{main:e.end,cross:e.q1})]},Oe=(e,t)=>{const[r,o]=e.notch===null?[e.start,e.end]:ee(e);return{from:(0,a.composePoint)(t,{main:r,cross:e.median}),to:(0,a.composePoint)(t,{main:o,cross:e.median})}},J=(e,t)=>e.mean===null?null:(0,a.composePoint)(t,{main:b(e),cross:e.mean}),ee=e=>{const t=(e.end-e.start)*(1-Ie)/2;return[e.start+t,e.end-t]},te=(e,t)=>{const r=b(e),o=(e.end-e.start)*We/2;return[{side:"lower",quartile:e.q1,reach:e.lowerWhisker},{side:"upper",quartile:e.q3,reach:e.upperWhisker}].filter(({quartile:n,reach:s})=>n!==s).map(({side:n,quartile:s,reach:i})=>({side:n,stem:{from:(0,a.composePoint)(t,{main:r,cross:s}),to:(0,a.composePoint)(t,{main:r,cross:i})},cap:{from:(0,a.composePoint)(t,{main:r-o,cross:i}),to:(0,a.composePoint)(t,{main:r+o,cross:i})}}))},D=(e,t)=>e<=t?[e,t]:[t,e],W=(e,t)=>({x:e.x*t.width,y:e.y*t.height}),A=(e,t)=>`${e.map((r,o)=>{const{x:n,y:s}=W(r,t);return`${o===0?"M":"L"}${n},${s}`}).join("")}Z`,be=(e,t)=>A([{x:e.x,y:e.y},{x:e.x+e.width,y:e.y},{x:e.x+e.width,y:e.y+e.height},{x:e.x,y:e.y+e.height}],t),Ee=(e,t)=>{const r=W(e.from,t),o=W(e.to,t);return`M${r.x},${r.y}L${o.x},${o.y}`},Te=({layer:e,coordSystem:t,panelRect:r,styleReaders:o})=>{const n=(0,a.readMainAxis)(t),{boxes:s,outliers:i}=P(e.data,n),c=s.map(h=>{const k=Z(h,n);return k!==null?{kind:"region",pathData:A(k,r)}:{kind:"region",pathData:be(Q(h,n),r)}}),u=o.part("whisker"),l=o.part("cap"),d=s.flatMap(h=>te(h,n).flatMap(k=>[{segment:k.stem,readers:u},{segment:k.cap,readers:l}].flatMap(({segment:w,readers:E})=>{const S=E?.get("strokeWidth",h.observation)??0;return S>0?[{kind:"stroke",pathData:Ee(w,r),width:S}]:[]}))),m=o.part("outlier"),f=m===void 0?[]:i.map(h=>({center:W((0,a.composePoint)(n,{main:h.band,cross:h.value}),r),size:K(m,h.observation)})),p=o.part("mean"),v=p===void 0?[]:s.flatMap(h=>{const k=J(h,n);return k===null?[]:[{center:W(k,r),size:K(p,h.observation)}]}),x=(0,a.buildDotsEditOutlineShapes)([...f,...v]);return[...d,...c,...x]},K=(e,t)=>(e.get("size",t)??0)+(e.get("strokeWidth",t)??0),N=e=>{const t=(0,a.createStableKeyGenerator)(e.data,e.mapping,e.id),r=(0,a.readVariableName)(e.mapping.outlier),o=n=>`${t(n.observation)}-outlier-${String(r===null?n.value:n.observation[r])}`;return{readBoxKey:t,readOutlierKeys:n=>{const s=new Map;return n.map(i=>{const c=o(i),u=s.get(c)??0;return s.set(c,u+1),u===0?c:`${c}-${u}`})}}},_e=(e,t,r)=>{const o=e.data.getVariableNames(),n=i=>JSON.stringify(o.map(c=>i.observation[c]??null)),s=new Set(r.map(n));return t.filter(i=>s.has(n(i)))},re=(e,t,r)=>{const o=new Set(t.map(n=>r(n.observation)));return e.filter(n=>o.has(r(n.observation)))},V=({boxes:e,outliers:t,mainAxis:r,panelSize:o,source:n,styleReaders:s,keys:i,hovered:c,animateTransitions:u=!1})=>{const l=c===void 0?void 0:"hovered",d=s.part("whisker"),m=s.part("cap"),f=s.part("median"),p=s.part("mean"),v=s.part("outlier"),x=i.readOutlierKeys(t);return(0,g.jsxs)(g.Fragment,{children:[e.flatMap(h=>te(h,r).flatMap(k=>[{piece:"stem",testId:"boxplot-whisker",readers:d},{piece:"cap",testId:"boxplot-cap",readers:m}].map(({piece:w,testId:E,readers:S})=>S===void 0?null:(0,g.jsx)(j,{testId:E,segment:k[w],observation:h.observation,readers:S,state:l,animateTransitions:u},`${i.readBoxKey(h.observation)}-${k.side}-${w}`)))),(0,g.jsx)(a.GeomOverpaint,{styleReaders:s,state:l,children:e.map(h=>(0,g.jsx)(Be,{box:h,mainAxis:r,panelSize:o,source:n,styleReaders:s,state:l,animateTransitions:u},i.readBoxKey(h.observation)))}),f&&e.map(h=>(0,g.jsx)(j,{testId:"boxplot-median",segment:Oe(h,r),observation:h.observation,readers:f,state:l,animateTransitions:u},i.readBoxKey(h.observation))),p&&e.map(h=>{const k=J(h,r);return k===null?null:(0,g.jsx)(G,{testId:"boxplot-mean",centre:k,observation:h.observation,readers:p,state:l,animateTransitions:u},i.readBoxKey(h.observation))}),v&&t.map((h,k)=>(0,g.jsx)(G,{testId:"boxplot-outlier",centre:(0,a.composePoint)(r,{main:h.band,cross:h.value}),observation:h.observation,readers:v,state:l,animateTransitions:u},x[k]))]})},j=({testId:e,segment:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const i=o.get("strokeWidth",r,n)??0,c=o.get("stroke",r,n);return(0,g.jsx)(a.GeomLine,{"data-testid":e,x1:(0,a.toPercent)(t.from.x),y1:(0,a.toPercent)(t.from.y),x2:(0,a.toPercent)(t.to.x),y2:(0,a.toPercent)(t.to.y),stroke:c===void 0?void 0:(0,a.toPaintColor)(c),strokeOpacity:o.get("alpha",r,n),strokeWidth:i,strokeDasharray:(0,a.toStrokeDasharray)(o.get("dashArray",r,n),i),animateTransitions:s})},Be=({box:e,mainAxis:t,panelSize:r,source:o,styleReaders:n,state:s,animateTransitions:i})=>{const c=n.get("fill",e.observation,s),u=n.get("stroke",e.observation,s),l={fill:c===void 0?void 0:(0,a.toPaintColor)(c),opacity:n.get("alpha",e.observation,s),fillOpacity:n.get("fillAlpha",e.observation,s),stroke:u===void 0?void 0:(0,a.toPaintColor)(u),strokeOpacity:n.get("strokeAlpha",e.observation,s),strokeWidth:n.get("strokeWidth",e.observation,s),effects:(0,a.readGeomEffects)(n,e.observation,s),animateTransitions:i},d=Z(e,t);if(d!==null)return(0,g.jsx)(a.GeomPath,{"data-testid":"boxplot-box",d:A(d,r),source:o,...l});const m=Q(e,t);return(0,g.jsx)(a.GeomRect,{"data-testid":"boxplot-box",x:(0,a.toPercent)(m.x),y:(0,a.toPercent)(m.y),width:(0,a.toPercent)(m.width),height:(0,a.toPercent)(m.height),cornerRadius:n.get("cornerRadius",e.observation,s),...l})},G=({testId:e,centre:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const i=o.get("fill",r,n),c=o.get("stroke",r,n);return(0,g.jsx)(a.GeomCircle,{"data-testid":e,cx:(0,a.toPercent)(t.x),cy:(0,a.toPercent)(t.y),r:(o.get("size",r,n)??0)/2,fill:i===void 0?void 0:(0,a.toPaintColor)(i),opacity:o.get("alpha",r,n),fillOpacity:o.get("fillAlpha",r,n),stroke:c===void 0?void 0:(0,a.toPaintColor)(c),strokeWidth:o.get("strokeWidth",r,n),symbol:o.get("symbol",r,n),animateTransitions:s})},qe=({layer:e,sourceLayer:t,mainAxis:r,styleReaders:o})=>{const n=(0,a.useGeomPanelSize)(),s=(0,M.useMemo)(()=>N(t),[t]),i=(0,M.useMemo)(()=>P(t.data,r).outliers,[t.data,r]),{boxes:c,outliers:u}=(0,M.useMemo)(()=>{const l=P(e.data,r),d=new Set(_e(t,i,l.outliers)),m=new Set(re(i,l.boxes,s.readBoxKey)),f=i.filter(p=>m.has(p)||d.has(p));return{boxes:l.boxes,outliers:f}},[e.data,r,t,i,s]);return(0,g.jsx)(V,{boxes:c,outliers:u,mainAxis:r,panelSize:n,source:t,styleReaders:o,keys:s})},Ae=({layer:e,primary:t,mainAxis:r,styleReaders:o})=>{const n=(0,a.useGeomPanelSize)(),s=(0,M.useMemo)(()=>P(e.data,r).outliers,[e.data,r]),i=(0,M.useMemo)(()=>N(e),[e]),{boxes:c,outliers:u}=P([t.observation],r);return(0,g.jsx)("g",{"data-testid":"hovered-boxes",children:(0,g.jsx)(V,{boxes:c,outliers:c.length>0?re(s,c,i.readBoxKey):u,mainAxis:r,panelSize:n,source:e,styleReaders:o,keys:i,hovered:t.observation})})},Ne=({layer:e,mainAxis:t,styleReaders:r,animateTransitions:o,intro:n})=>{const s=(0,a.useGeomPanelSize)(),{boxes:i,outliers:c}=(0,M.useMemo)(()=>P(e.data,t),[e.data,t]),u=(0,g.jsx)(V,{boxes:i,outliers:c,mainAxis:t,panelSize:s,source:e,styleReaders:r,keys:(0,M.useMemo)(()=>N(e),[e]),animateTransitions:o});return n==null?u:(0,g.jsx)(a.IntroFade,{intro:{type:"fade",layerId:n.layerId,durationSeconds:n.durationSeconds},children:u})},Ve=(0,a.defineGeomRenderer)(new Y,{coord:"cartesian",swatchShape:"square",overpaintPlacement:"manual",guideMode:"band",render:({layer:e,coordSystem:t,styleReaders:r,animateTransitions:o,intro:n})=>(0,g.jsx)(Ne,{layer:e,mainAxis:(0,a.readMainAxis)(t),styleReaders:r,animateTransitions:o,intro:n}),renderHighlight:({layer:e,sourceLayer:t,coordSystem:r,styleReaders:o})=>(0,g.jsx)(qe,{layer:e,sourceLayer:t,mainAxis:(0,a.readMainAxis)(r),styleReaders:o}),renderHover:({layer:e,primary:t,coordSystem:r,styleReaders:o})=>(0,g.jsx)(Ae,{layer:e,primary:t,mainAxis:(0,a.readMainAxis)(r),styleReaders:o}),getEditOutlineShapes:Te});exports.BOXPLOT_VARIABLES=y;exports.BoxplotGeom=Y;exports.boxplot=Ve;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { Dataset as me, Geom as ve, GeomCircle as ge, GeomLine as fe, GeomOverpaint as ye, GeomPath as ke, GeomRect as we, IntroFade as xe, POSITION_VARIABLES as _, Stat as We, UserInputError as Me, buildDotsEditOutlineShapes as Se, composePoint as Ie, createStableKeyGenerator as Oe, defineGeomRenderer as be, defineGeomStyleTarget as Ee, getGroupVariables as Be, getScaledAesthetic as b, getXMax as A, getXMin as K, getYMax as U, getYMin as $, readGeomEffects as Te, readMainAxis as E, readVariableName as V, toPaintColor as B, toPercent as x, toStrokeDasharray as _e, toViewBoxX as qe, toViewBoxY as Pe, token as M, useGeomPanelSize as F } from "@graphysdk/react";
1
+ import { Dataset as me, Geom as ve, GeomCircle as ge, GeomLine as fe, GeomOverpaint as ye, GeomPath as ke, GeomRect as we, IntroFade as xe, POSITION_VARIABLES as _, Stat as We, UserInputError as Me, buildDotsEditOutlineShapes as Se, composePoint as v, createStableKeyGenerator as Ie, defineGeomRenderer as Oe, defineGeomStyleTarget as be, getGroupVariables as Ee, getScaledAesthetic as b, getXMax as R, getXMin as K, getYMax as U, getYMin as $, readGeomEffects as Te, readMainAxis as E, readVariableName as N, toPaintColor as T, toPercent as x, toStrokeDasharray as Be, token as M, useGeomPanelSize as F } from "@graphysdk/react";
2
2
  import { useMemo as S } from "react";
3
- import { Fragment as Ve, jsx as y, jsxs as Ne } from "react/jsx-runtime";
3
+ import { Fragment as _e, jsx as y, jsxs as qe } from "react/jsx-runtime";
4
4
  var k = {
5
5
  q1: "boxplotQ1",
6
6
  median: "boxplotMedian",
@@ -13,30 +13,30 @@ var k = {
13
13
  notchUpper: "boxplotNotchUpper",
14
14
  relativeWidth: "boxplotRelativeWidth",
15
15
  outlier: "boxplotOutlier"
16
- }, N = (e) => (e.start + e.end) / 2, re = (e, t) => {
17
- const r = t === "x" ? K(e) : $(e), o = t === "x" ? A(e) : U(e), n = t === "x" ? $(e) : K(e), a = t === "x" ? U(e) : A(e), s = b(e, "q1"), i = b(e, "median"), u = b(e, "q3");
18
- if (r === null || o === null || n === null || a === null || i === null || s === null || u === null) return null;
19
- const l = C(e, "notchLower"), h = C(e, "notchUpper"), [p, g] = Le(r, o, e);
16
+ }, V = (e) => (e.start + e.end) / 2, re = (e, t) => {
17
+ const r = t === "x" ? K(e) : $(e), o = t === "x" ? R(e) : U(e), n = t === "x" ? $(e) : K(e), a = t === "x" ? U(e) : R(e), s = b(e, "q1"), l = b(e, "median"), u = b(e, "q3");
18
+ if (r === null || o === null || n === null || a === null || l === null || s === null || u === null) return null;
19
+ const i = Pe(s, u, t), h = C(e, "notchLower"), p = C(e, "notchUpper"), [g, d] = Ne(r, o, e);
20
20
  return {
21
21
  observation: e,
22
- start: p,
23
- end: g,
24
- lowerWhisker: n,
22
+ start: g,
23
+ end: d,
24
+ lowerWhisker: i ? n : a,
25
25
  q1: s,
26
- median: i,
26
+ median: l,
27
27
  q3: u,
28
- upperWhisker: a,
28
+ upperWhisker: i ? a : n,
29
29
  mean: C(e, "mean"),
30
- notch: l === null || h === null ? null : {
31
- lower: l,
32
- upper: h
30
+ notch: h === null || p === null ? null : {
31
+ lower: h,
32
+ upper: p
33
33
  }
34
34
  };
35
35
  }, oe = (e, t) => {
36
- const r = t === "x" ? K(e) : $(e), o = t === "x" ? A(e) : U(e), n = b(e, "outlier");
36
+ const r = t === "x" ? K(e) : $(e), o = t === "x" ? R(e) : U(e), n = b(e, "outlier");
37
37
  return r === null || o === null || n === null ? null : {
38
38
  observation: e,
39
- band: N({
39
+ band: V({
40
40
  start: r,
41
41
  end: o
42
42
  }),
@@ -57,20 +57,20 @@ var k = {
57
57
  boxes: r,
58
58
  outliers: o
59
59
  };
60
- }, C = (e, t) => b(e, t) ?? null, Le = (e, t, r) => {
60
+ }, Pe = (e, t, r) => e === t ? r === "y" : e < t, C = (e, t) => b(e, t) ?? null, Ne = (e, t, r) => {
61
61
  const o = r[k.relativeWidth];
62
62
  if (typeof o != "number") return [e, t];
63
63
  const n = (e + t) / 2, a = (t - e) * o / 2;
64
64
  return [n - a, n + a];
65
- }, P = 1.5, ne = (e) => e === "min-max" || typeof e == "number" && Number.isFinite(e) && e >= 0, Ce = 1.58, De = (e, t) => {
65
+ }, P = 1.5, ne = (e) => e === "min-max" || typeof e == "number" && Number.isFinite(e) && e >= 0, Ve = 1.58, Le = (e, t) => {
66
66
  if (e.length === 0) return null;
67
- const r = [...e].sort((p, g) => p - g), o = D(r, 0.25), n = D(r, 0.5), a = D(r, 0.75), s = t === "min-max" ? 1 / 0 : t * (a - o), i = o - s, u = a + s, l = r.filter((p) => p >= i && p <= u), h = Ce * (a - o) / Math.sqrt(e.length);
67
+ const r = [...e].sort((p, g) => p - g), o = D(r, 0.25), n = D(r, 0.5), a = D(r, 0.75), s = t === "min-max" ? 1 / 0 : t * (a - o), l = o - s, u = a + s, i = r.filter((p) => p >= l && p <= u), h = Ve * (a - o) / Math.sqrt(e.length);
68
68
  return {
69
- lowerWhisker: Math.min(l[0] ?? o, o),
69
+ lowerWhisker: Math.min(i[0] ?? o, o),
70
70
  q1: o,
71
71
  median: n,
72
72
  q3: a,
73
- upperWhisker: Math.max(l[l.length - 1] ?? a, a),
73
+ upperWhisker: Math.max(i[i.length - 1] ?? a, a),
74
74
  count: e.length,
75
75
  mean: r.reduce((p, g) => p + g, 0) / r.length,
76
76
  notchLower: n - h,
@@ -92,12 +92,12 @@ var k = {
92
92
  "mean",
93
93
  "notchLower",
94
94
  "notchUpper"
95
- ]), Re = class extends We {
95
+ ]), Ce = class extends We {
96
96
  constructor(...e) {
97
97
  super(...e), this.type = "boxplot", this.computedAesthetics = se;
98
98
  }
99
99
  computeStat({ data: e, mapping: t, params: r }) {
100
- const o = V(t.x), n = V(t.y);
100
+ const o = N(t.x), n = N(t.y);
101
101
  if (o === null || n === null || !e.hasVariable(o) || !e.hasVariable(n)) return {
102
102
  data: e,
103
103
  mapping: {}
@@ -117,18 +117,18 @@ var k = {
117
117
  }
118
118
  const a = r?.extent;
119
119
  return {
120
- data: Ae({
120
+ data: De({
121
121
  data: e,
122
122
  xVariable: o,
123
123
  yVariable: n,
124
- groupVariables: Be(e, t).filter((s) => s !== o),
124
+ groupVariables: Ee(e, t).filter((s) => s !== o),
125
125
  extent: ne(a) ? a : P
126
126
  }),
127
127
  mapping: ae
128
128
  };
129
129
  }
130
- }, Ae = ({ data: e, xVariable: t, yVariable: r, groupVariables: o, extent: n }) => {
131
- const a = Ke(e, t, r, o), s = e.getVariableNames(), i = new Map(s.map((d) => [d, e.getValues(d)])), u = new Map(s.map((d) => [d, []])), l = {
130
+ }, De = ({ data: e, xVariable: t, yVariable: r, groupVariables: o, extent: n }) => {
131
+ const a = Ae(e, t, r, o), s = e.getVariableNames(), l = new Map(s.map((d) => [d, e.getValues(d)])), u = new Map(s.map((d) => [d, []])), i = {
132
132
  q1: [],
133
133
  median: [],
134
134
  q3: [],
@@ -141,10 +141,10 @@ var k = {
141
141
  outlier: []
142
142
  }, h = [];
143
143
  for (const d of a) {
144
- const m = De(d.values, n);
144
+ const m = Le(d.values, n);
145
145
  if (m === null) continue;
146
- for (const c of s) u.get(c)?.push(Ue(i.get(c) ?? [], d.indices));
147
- l.q1.push(m.q1), l.median.push(m.median), l.q3.push(m.q3), l.lowerWhisker.push(m.lowerWhisker), l.upperWhisker.push(m.upperWhisker), l.count.push(m.count), l.mean.push(m.mean), l.notchLower.push(m.notchLower), l.notchUpper.push(m.notchUpper), l.outlier.push(null);
146
+ for (const c of s) u.get(c)?.push(Re(l.get(c) ?? [], d.indices));
147
+ i.q1.push(m.q1), i.median.push(m.median), i.q3.push(m.q3), i.lowerWhisker.push(m.lowerWhisker), i.upperWhisker.push(m.upperWhisker), i.count.push(m.count), i.mean.push(m.mean), i.notchLower.push(m.notchLower), i.notchUpper.push(m.notchUpper), i.outlier.push(null);
148
148
  const w = {
149
149
  low: m.lowerWhisker,
150
150
  high: m.upperWhisker
@@ -158,15 +158,15 @@ var k = {
158
158
  });
159
159
  }
160
160
  for (const { index: d, value: m } of h) {
161
- for (const w of s) u.get(w)?.push(i.get(w)?.[d] ?? null);
162
- l.q1.push(null), l.median.push(null), l.q3.push(null), l.lowerWhisker.push(null), l.upperWhisker.push(null), l.count.push(null), l.mean.push(null), l.notchLower.push(null), l.notchUpper.push(null), l.outlier.push(m);
161
+ for (const w of s) u.get(w)?.push(l.get(w)?.[d] ?? null);
162
+ i.q1.push(null), i.median.push(null), i.q3.push(null), i.lowerWhisker.push(null), i.upperWhisker.push(null), i.count.push(null), i.mean.push(null), i.notchLower.push(null), i.notchUpper.push(null), i.outlier.push(m);
163
163
  }
164
164
  const p = e.getValueFormat(r), g = Object.fromEntries(s.map((d) => [d, {
165
165
  type: e.getType(d),
166
166
  values: u.get(d) ?? [],
167
167
  valueFormat: e.getValueFormat(d)
168
168
  }]));
169
- for (const [d, m] of Object.entries(l)) {
169
+ for (const [d, m] of Object.entries(i)) {
170
170
  const w = k[d];
171
171
  g[w] = d === "count" ? {
172
172
  type: "numeric",
@@ -178,29 +178,29 @@ var k = {
178
178
  };
179
179
  }
180
180
  return new me(g, e.parsingLocale);
181
- }, Ke = (e, t, r, o) => {
182
- const n = [t, ...o].map((i) => e.getValues(i)), a = e.getValues(r, { type: "numeric" }), s = /* @__PURE__ */ new Map();
183
- return a.forEach((i, u) => {
184
- if (i === null || !Number.isFinite(i)) return;
185
- const l = n.map((p) => G(p[u] ?? null)).join("\0"), h = s.get(l) ?? {
181
+ }, Ae = (e, t, r, o) => {
182
+ const n = [t, ...o].map((l) => e.getValues(l)), a = e.getValues(r, { type: "numeric" }), s = /* @__PURE__ */ new Map();
183
+ return a.forEach((l, u) => {
184
+ if (l === null || !Number.isFinite(l)) return;
185
+ const i = n.map((p) => G(p[u] ?? null)).join("\0"), h = s.get(i) ?? {
186
186
  indices: [],
187
187
  values: []
188
188
  };
189
- h.indices.push(u), h.values.push(i), s.set(l, h);
189
+ h.indices.push(u), h.values.push(l), s.set(i, h);
190
190
  }), [...s.values()];
191
- }, Ue = (e, t) => {
191
+ }, Re = (e, t) => {
192
192
  const r = e[t[0] ?? -1] ?? null, o = G(r);
193
193
  return t.every((n) => G(e[n] ?? null) === o) ? r : null;
194
- }, G = (e) => e === null ? "\0null" : e instanceof Date ? `date:${e.getTime()}` : `${typeof e}:${String(e)}`, le = 0.6, $e = 1, Ge = 2, Fe = 1.5, Xe = 7, He = 1, ze = 7, Ye = 1.5, je = [
194
+ }, G = (e) => e === null ? "\0null" : e instanceof Date ? `date:${e.getTime()}` : `${typeof e}:${String(e)}`, ie = 0.6, Ke = 1, Ue = 2, $e = 1.5, Ge = 7, Fe = 1, He = 7, Xe = 1.5, ze = [
195
195
  "q1",
196
196
  "median",
197
197
  "q3"
198
- ], Qe = { strokeWidth: "pixels" }, R = {
198
+ ], je = { strokeWidth: "pixels" }, A = {
199
199
  stroke: "color",
200
200
  alpha: "unitInterval",
201
201
  strokeWidth: "pixels",
202
202
  dashArray: "dashArray"
203
- }, Y = {
203
+ }, j = {
204
204
  fill: "color",
205
205
  fillAlpha: "unitInterval",
206
206
  stroke: "color",
@@ -208,7 +208,7 @@ var k = {
208
208
  size: "pixels",
209
209
  strokeWidth: "pixels",
210
210
  symbol: "pointSymbol"
211
- }, Ze = class extends ve {
211
+ }, Ye = class extends ve {
212
212
  constructor(...e) {
213
213
  super(...e), this.type = "boxplot", this.defaultParams = {
214
214
  extent: P,
@@ -216,7 +216,7 @@ var k = {
216
216
  notch: !1,
217
217
  showMean: !1,
218
218
  varwidth: !1
219
- }, this.defaultStat = new Re(), this.derivedVariables = Object.values(k), this.positionRoles = [
219
+ }, this.defaultStat = new Ce(), this.derivedVariables = Object.values(k), this.positionRoles = [
220
220
  {
221
221
  axis: "x",
222
222
  role: "point",
@@ -333,39 +333,39 @@ var k = {
333
333
  aesthetic: "outlier",
334
334
  optional: !0
335
335
  }
336
- ], this.styleTarget = Ee({
336
+ ], this.styleTarget = be({
337
337
  observation: {
338
- vocabulary: Qe,
338
+ vocabulary: je,
339
339
  aesthetics: { fill: "color" },
340
340
  rest: {
341
341
  fill: M("geom"),
342
342
  fillAlpha: 1,
343
343
  stroke: M("geomBorder"),
344
- strokeWidth: $e
344
+ strokeWidth: Ke
345
345
  }
346
346
  },
347
347
  parts: {
348
348
  median: {
349
- vocabulary: R,
349
+ vocabulary: A,
350
350
  rest: {
351
351
  stroke: M("graphBackground"),
352
352
  alpha: 1,
353
- strokeWidth: Ge,
353
+ strokeWidth: Ue,
354
354
  dashArray: []
355
355
  }
356
356
  },
357
357
  whisker: {
358
- vocabulary: R,
358
+ vocabulary: A,
359
359
  aesthetics: { stroke: "color" },
360
360
  rest: {
361
361
  stroke: M("geom"),
362
362
  alpha: 1,
363
- strokeWidth: Fe,
363
+ strokeWidth: $e,
364
364
  dashArray: []
365
365
  }
366
366
  },
367
367
  cap: {
368
- vocabulary: R,
368
+ vocabulary: A,
369
369
  aesthetics: { stroke: "color" },
370
370
  rest: {
371
371
  stroke: M("geom"),
@@ -375,31 +375,31 @@ var k = {
375
375
  }
376
376
  },
377
377
  outlier: {
378
- vocabulary: Y,
378
+ vocabulary: j,
379
379
  aesthetics: { fill: "color" },
380
380
  rest: {
381
381
  fill: M("geom"),
382
382
  fillAlpha: 1,
383
383
  stroke: M("graphBackground"),
384
384
  alpha: 1,
385
- size: Xe,
386
- strokeWidth: He
385
+ size: Ge,
386
+ strokeWidth: Fe
387
387
  }
388
388
  },
389
389
  mean: {
390
- vocabulary: Y,
390
+ vocabulary: j,
391
391
  aesthetics: { stroke: "color" },
392
392
  rest: {
393
393
  fill: M("graphBackground"),
394
394
  fillAlpha: 1,
395
395
  stroke: M("geom"),
396
396
  alpha: 1,
397
- size: ze,
398
- strokeWidth: Ye
397
+ size: He,
398
+ strokeWidth: Xe
399
399
  }
400
400
  }
401
401
  }
402
- }), this.resolveBandFraction = (t) => j(t), this.resolveValueSource = (t) => t.median ?? { variable: k.median }, this.validateMapping = ({ mapping: t, computedAesthetics: r }) => r.has("y") ? [{
402
+ }), this.resolveBandFraction = (t) => Y(t), this.resolveValueSource = (t) => t.median ?? { variable: k.median }, this.validateMapping = ({ mapping: t, computedAesthetics: r }) => r.has("y") ? [{
403
403
  code: "CONFLICTING_STAT_MAPPING",
404
404
  message: "boxplot geom draws a summary, not a single 'y'; use the 'boxplot' stat or 'identity'"
405
405
  }] : r.has("median") ? [...[...se].filter((o) => t[o] !== void 0).map((o) => ({
@@ -408,12 +408,12 @@ var k = {
408
408
  })), ...t.y === void 0 ? [{
409
409
  code: "MISSING_AESTHETIC",
410
410
  message: "boxplot stat summarises 'y'; map it to the raw values"
411
- }] : []] : je.filter((o) => t[o] === void 0).map((o) => ({
411
+ }] : []] : ze.filter((o) => t[o] === void 0).map((o) => ({
412
412
  code: "MISSING_AESTHETIC",
413
413
  message: `boxplot geom requires '${o}' when its data is already summarised`,
414
414
  context: { aesthetic: o }
415
415
  })), this.resolveAnchorPosition = (t, { coordSystem: r }) => {
416
- const o = E(r), n = Je(t, o);
416
+ const o = E(r), n = Qe(t, o);
417
417
  return n === null ? null : o === "x" ? {
418
418
  x: n.band,
419
419
  y: n.value
@@ -437,12 +437,12 @@ var k = {
437
437
  data: e,
438
438
  mapping: {}
439
439
  };
440
- const { outliers: a, notch: s, showMean: i, varwidth: u } = r, l = q(e, t.outlier), h = a === !1 && l !== null ? rt(e, l) : e, p = q(h, t.count), g = j(r) / 2;
440
+ const { outliers: a, notch: s, showMean: l, varwidth: u } = r, i = q(e, t.outlier), h = a === !1 && i !== null ? et(e, i) : e, p = q(h, t.count), g = Y(r) / 2;
441
441
  return {
442
- data: h.addVariable(k.relativeWidth, "numeric", u === !0 && p !== null ? et(h, p) : tt(h)).addVariable(_.yMin, "numeric", Q(h, o, l)).addVariable(_.yMax, "numeric", Q(h, n, l)).addConstantVariable(_.xMin, "numeric", -g).addConstantVariable(_.xMax, "numeric", g),
442
+ data: h.addVariable(k.relativeWidth, "numeric", u === !0 && p !== null ? Ze(h, p) : Je(h)).addVariable(_.yMin, "numeric", Q(h, o, i)).addVariable(_.yMax, "numeric", Q(h, n, i)).addConstantVariable(_.xMin, "numeric", -g).addConstantVariable(_.xMax, "numeric", g),
443
443
  mapping: {
444
444
  ...t.y === void 0 && { y: t.median },
445
- ...i === !0 && t.mean === void 0 && h.hasVariable(k.mean) && { mean: k.mean },
445
+ ...l === !0 && t.mean === void 0 && h.hasVariable(k.mean) && { mean: k.mean },
446
446
  ...s === !0 && t.notchLower === void 0 && h.hasVariable(k.notchLower) && {
447
447
  notchLower: k.notchLower,
448
448
  notchUpper: k.notchUpper
@@ -470,7 +470,7 @@ var k = {
470
470
  const o = r !== null && r > 1 ? 1 : void 0;
471
471
  return t?.addWarning({
472
472
  code: "INVALID_GEOM_PARAM",
473
- message: `Boxplot width must be a fraction in (0, 1], got ${String(e)}; falling back to ${o ?? le}.`,
473
+ message: `Boxplot width must be a fraction in (0, 1], got ${String(e)}; falling back to ${o ?? ie}.`,
474
474
  context: {
475
475
  geom: this.type,
476
476
  param: "width",
@@ -480,10 +480,10 @@ var k = {
480
480
  suggestion: "Set params.width to a fraction of the category band in (0, 1]."
481
481
  }), o !== void 0 ? { width: o } : {};
482
482
  }
483
- }, Je = (e, t) => {
483
+ }, Qe = (e, t) => {
484
484
  const r = re(e, t);
485
485
  if (r !== null) return {
486
- band: N(r),
486
+ band: V(r),
487
487
  value: r.median
488
488
  };
489
489
  const o = oe(e, t);
@@ -491,52 +491,97 @@ var k = {
491
491
  band: o.band,
492
492
  value: o.value
493
493
  };
494
- }, j = ({ width: e }) => e ?? le, et = (e, t) => {
494
+ }, Y = ({ width: e }) => e ?? ie, Ze = (e, t) => {
495
495
  const r = e.getValues(t, { type: "numeric" }), o = Math.max(0, ...r.map((n) => n ?? 0));
496
496
  return r.map((n) => n === null || o === 0 ? null : Math.sqrt(n / o));
497
- }, tt = (e) => Array.from({ length: e.size() }, () => null), Q = (e, t, r) => {
497
+ }, Je = (e) => Array.from({ length: e.size() }, () => null), Q = (e, t, r) => {
498
498
  const o = r === null ? [] : e.getValues(r, { type: "numeric" });
499
499
  return e.getValues(t, { type: "numeric" }).map((n, a) => n ?? o[a] ?? null);
500
- }, rt = (e, t) => {
500
+ }, et = (e, t) => {
501
501
  const r = e.getValues(t, { type: "numeric" });
502
502
  return e.take(r.flatMap((o, n) => o === null ? [n] : []));
503
503
  }, q = (e, t) => {
504
- const r = V(t);
504
+ const r = N(t);
505
505
  return r !== null && e.hasVariable(r) ? r : null;
506
- }, ot = 5e-4, nt = 0.5, at = 0.5, ie = (e, t) => {
507
- const r = (e.q1 + e.q3) / 2, o = Math.max(Math.abs(e.q3 - e.q1), ot) / 2, n = v(t, e.start, r - o), a = v(t, e.end, r + o), [s, i] = Z(n.x, a.x), [u, l] = Z(n.y, a.y);
506
+ }, tt = 5e-4, rt = 0.5, ot = 0.5, le = (e, t) => {
507
+ const r = (e.q1 + e.q3) / 2, o = Math.max(Math.abs(e.q3 - e.q1), tt) / 2, n = v(t, {
508
+ main: e.start,
509
+ cross: r - o
510
+ }), a = v(t, {
511
+ main: e.end,
512
+ cross: r + o
513
+ }), [s, l] = Z(n.x, a.x), [u, i] = Z(n.y, a.y);
508
514
  return {
509
515
  x: s,
510
516
  y: u,
511
- width: i - s,
512
- height: l - u
517
+ width: l - s,
518
+ height: i - u
513
519
  };
514
520
  }, ue = (e, t) => {
515
521
  if (e.notch === null) return null;
516
522
  const { lower: r, upper: o } = e.notch, [n, a] = he(e);
517
523
  return [
518
- v(t, e.start, e.q1),
519
- v(t, e.start, r),
520
- v(t, n, e.median),
521
- v(t, e.start, o),
522
- v(t, e.start, e.q3),
523
- v(t, e.end, e.q3),
524
- v(t, e.end, o),
525
- v(t, a, e.median),
526
- v(t, e.end, r),
527
- v(t, e.end, e.q1)
524
+ v(t, {
525
+ main: e.start,
526
+ cross: e.q1
527
+ }),
528
+ v(t, {
529
+ main: e.start,
530
+ cross: r
531
+ }),
532
+ v(t, {
533
+ main: n,
534
+ cross: e.median
535
+ }),
536
+ v(t, {
537
+ main: e.start,
538
+ cross: o
539
+ }),
540
+ v(t, {
541
+ main: e.start,
542
+ cross: e.q3
543
+ }),
544
+ v(t, {
545
+ main: e.end,
546
+ cross: e.q3
547
+ }),
548
+ v(t, {
549
+ main: e.end,
550
+ cross: o
551
+ }),
552
+ v(t, {
553
+ main: a,
554
+ cross: e.median
555
+ }),
556
+ v(t, {
557
+ main: e.end,
558
+ cross: r
559
+ }),
560
+ v(t, {
561
+ main: e.end,
562
+ cross: e.q1
563
+ })
528
564
  ];
529
- }, st = (e, t) => {
565
+ }, nt = (e, t) => {
530
566
  const [r, o] = e.notch === null ? [e.start, e.end] : he(e);
531
567
  return {
532
- from: v(t, r, e.median),
533
- to: v(t, o, e.median)
568
+ from: v(t, {
569
+ main: r,
570
+ cross: e.median
571
+ }),
572
+ to: v(t, {
573
+ main: o,
574
+ cross: e.median
575
+ })
534
576
  };
535
- }, ce = (e, t) => e.mean === null ? null : v(t, N(e), e.mean), he = (e) => {
536
- const t = (e.end - e.start) * (1 - at) / 2;
577
+ }, ce = (e, t) => e.mean === null ? null : v(t, {
578
+ main: V(e),
579
+ cross: e.mean
580
+ }), he = (e) => {
581
+ const t = (e.end - e.start) * (1 - ot) / 2;
537
582
  return [e.start + t, e.end - t];
538
583
  }, de = (e, t) => {
539
- const r = N(e), o = (e.end - e.start) * nt / 2;
584
+ const r = V(e), o = (e.end - e.start) * rt / 2;
540
585
  return [{
541
586
  side: "lower",
542
587
  quartile: e.q1,
@@ -548,30 +593,33 @@ var k = {
548
593
  }].filter(({ quartile: n, reach: a }) => n !== a).map(({ side: n, quartile: a, reach: s }) => ({
549
594
  side: n,
550
595
  stem: {
551
- from: v(t, r, a),
552
- to: v(t, r, s)
596
+ from: v(t, {
597
+ main: r,
598
+ cross: a
599
+ }),
600
+ to: v(t, {
601
+ main: r,
602
+ cross: s
603
+ })
553
604
  },
554
605
  cap: {
555
- from: v(t, r - o, s),
556
- to: v(t, r + o, s)
606
+ from: v(t, {
607
+ main: r - o,
608
+ cross: s
609
+ }),
610
+ to: v(t, {
611
+ main: r + o,
612
+ cross: s
613
+ })
557
614
  }
558
615
  }));
559
- }, v = (e, t, r) => {
560
- const o = Ie(e, {
561
- main: t,
562
- cross: r
563
- });
564
- return {
565
- x: qe(o.x),
566
- y: Pe(o.y)
567
- };
568
- }, Z = (e, t) => e <= t ? [e, t] : [t, e], T = (e, t) => ({
616
+ }, Z = (e, t) => e <= t ? [e, t] : [t, e], B = (e, t) => ({
569
617
  x: e.x * t.width,
570
618
  y: e.y * t.height
571
- }), X = (e, t) => `${e.map((r, o) => {
572
- const { x: n, y: a } = T(r, t);
619
+ }), H = (e, t) => `${e.map((r, o) => {
620
+ const { x: n, y: a } = B(r, t);
573
621
  return `${o === 0 ? "M" : "L"}${n},${a}`;
574
- }).join("")}Z`, lt = (e, t) => X([
622
+ }).join("")}Z`, at = (e, t) => H([
575
623
  {
576
624
  x: e.x,
577
625
  y: e.y
@@ -588,68 +636,71 @@ var k = {
588
636
  x: e.x,
589
637
  y: e.y + e.height
590
638
  }
591
- ], t), it = (e, t) => {
592
- const r = T(e.from, t), o = T(e.to, t);
639
+ ], t), st = (e, t) => {
640
+ const r = B(e.from, t), o = B(e.to, t);
593
641
  return `M${r.x},${r.y}L${o.x},${o.y}`;
594
- }, ut = ({ layer: e, coordSystem: t, panelRect: r, styleReaders: o }) => {
595
- const n = E(t), { boxes: a, outliers: s } = I(e.data, n), i = a.map((c) => {
642
+ }, it = ({ layer: e, coordSystem: t, panelRect: r, styleReaders: o }) => {
643
+ const n = E(t), { boxes: a, outliers: s } = I(e.data, n), l = a.map((c) => {
596
644
  const f = ue(c, n);
597
645
  return f !== null ? {
598
646
  kind: "region",
599
- pathData: X(f, r)
647
+ pathData: H(f, r)
600
648
  } : {
601
649
  kind: "region",
602
- pathData: lt(ie(c, n), r)
650
+ pathData: at(le(c, n), r)
603
651
  };
604
- }), u = o.part("whisker"), l = o.part("cap"), h = a.flatMap((c) => de(c, n).flatMap((f) => [{
652
+ }), u = o.part("whisker"), i = o.part("cap"), h = a.flatMap((c) => de(c, n).flatMap((f) => [{
605
653
  segment: f.stem,
606
654
  readers: u
607
655
  }, {
608
656
  segment: f.cap,
609
- readers: l
657
+ readers: i
610
658
  }].flatMap(({ segment: W, readers: L }) => {
611
659
  const O = L?.get("strokeWidth", c.observation) ?? 0;
612
660
  return O > 0 ? [{
613
661
  kind: "stroke",
614
- pathData: it(W, r),
662
+ pathData: st(W, r),
615
663
  width: O
616
664
  }] : [];
617
665
  }))), p = o.part("outlier"), g = p === void 0 ? [] : s.map((c) => ({
618
- center: T(v(n, c.band, c.value), r),
666
+ center: B(v(n, {
667
+ main: c.band,
668
+ cross: c.value
669
+ }), r),
619
670
  size: J(p, c.observation)
620
671
  })), d = o.part("mean"), m = d === void 0 ? [] : a.flatMap((c) => {
621
672
  const f = ce(c, n);
622
673
  return f === null ? [] : [{
623
- center: T(f, r),
674
+ center: B(f, r),
624
675
  size: J(d, c.observation)
625
676
  }];
626
677
  }), w = Se([...g, ...m]);
627
678
  return [
628
679
  ...h,
629
- ...i,
680
+ ...l,
630
681
  ...w
631
682
  ];
632
- }, J = (e, t) => (e.get("size", t) ?? 0) + (e.get("strokeWidth", t) ?? 0), H = (e) => {
633
- const t = Oe(e.data, e.mapping, e.id), r = V(e.mapping.outlier), o = (n) => `${t(n.observation)}-outlier-${String(r === null ? n.value : n.observation[r])}`;
683
+ }, J = (e, t) => (e.get("size", t) ?? 0) + (e.get("strokeWidth", t) ?? 0), X = (e) => {
684
+ const t = Ie(e.data, e.mapping, e.id), r = N(e.mapping.outlier), o = (n) => `${t(n.observation)}-outlier-${String(r === null ? n.value : n.observation[r])}`;
634
685
  return {
635
686
  readBoxKey: t,
636
687
  readOutlierKeys: (n) => {
637
688
  const a = /* @__PURE__ */ new Map();
638
689
  return n.map((s) => {
639
- const i = o(s), u = a.get(i) ?? 0;
640
- return a.set(i, u + 1), u === 0 ? i : `${i}-${u}`;
690
+ const l = o(s), u = a.get(l) ?? 0;
691
+ return a.set(l, u + 1), u === 0 ? l : `${l}-${u}`;
641
692
  });
642
693
  }
643
694
  };
644
- }, ct = (e, t, r) => {
645
- const o = e.data.getVariableNames(), n = (s) => JSON.stringify(o.map((i) => s.observation[i] ?? null)), a = new Set(r.map(n));
695
+ }, lt = (e, t, r) => {
696
+ const o = e.data.getVariableNames(), n = (s) => JSON.stringify(o.map((l) => s.observation[l] ?? null)), a = new Set(r.map(n));
646
697
  return t.filter((s) => a.has(n(s)));
647
698
  }, pe = (e, t, r) => {
648
699
  const o = new Set(t.map((n) => r(n.observation)));
649
700
  return e.filter((n) => o.has(r(n.observation)));
650
- }, z = ({ boxes: e, outliers: t, mainAxis: r, panelSize: o, source: n, styleReaders: a, keys: s, hovered: i, animateTransitions: u = !1 }) => {
651
- const l = i === void 0 ? void 0 : "hovered", h = a.part("whisker"), p = a.part("cap"), g = a.part("median"), d = a.part("mean"), m = a.part("outlier"), w = s.readOutlierKeys(t);
652
- return /* @__PURE__ */ Ne(Ve, { children: [
701
+ }, z = ({ boxes: e, outliers: t, mainAxis: r, panelSize: o, source: n, styleReaders: a, keys: s, hovered: l, animateTransitions: u = !1 }) => {
702
+ const i = l === void 0 ? void 0 : "hovered", h = a.part("whisker"), p = a.part("cap"), g = a.part("median"), d = a.part("mean"), m = a.part("outlier"), w = s.readOutlierKeys(t);
703
+ return /* @__PURE__ */ qe(_e, { children: [
653
704
  e.flatMap((c) => de(c, r).flatMap((f) => [{
654
705
  piece: "stem",
655
706
  testId: "boxplot-whisker",
@@ -663,28 +714,28 @@ var k = {
663
714
  segment: f[W],
664
715
  observation: c.observation,
665
716
  readers: O,
666
- state: l,
717
+ state: i,
667
718
  animateTransitions: u
668
719
  }, `${s.readBoxKey(c.observation)}-${f.side}-${W}`)))),
669
720
  /* @__PURE__ */ y(ye, {
670
721
  styleReaders: a,
671
- state: l,
672
- children: e.map((c) => /* @__PURE__ */ y(ht, {
722
+ state: i,
723
+ children: e.map((c) => /* @__PURE__ */ y(ut, {
673
724
  box: c,
674
725
  mainAxis: r,
675
726
  panelSize: o,
676
727
  source: n,
677
728
  styleReaders: a,
678
- state: l,
729
+ state: i,
679
730
  animateTransitions: u
680
731
  }, s.readBoxKey(c.observation)))
681
732
  }),
682
733
  g && e.map((c) => /* @__PURE__ */ y(ee, {
683
734
  testId: "boxplot-median",
684
- segment: st(c, r),
735
+ segment: nt(c, r),
685
736
  observation: c.observation,
686
737
  readers: g,
687
- state: l,
738
+ state: i,
688
739
  animateTransitions: u
689
740
  }, s.readBoxKey(c.observation))),
690
741
  d && e.map((c) => {
@@ -694,39 +745,42 @@ var k = {
694
745
  centre: f,
695
746
  observation: c.observation,
696
747
  readers: d,
697
- state: l,
748
+ state: i,
698
749
  animateTransitions: u
699
750
  }, s.readBoxKey(c.observation));
700
751
  }),
701
752
  m && t.map((c, f) => /* @__PURE__ */ y(te, {
702
753
  testId: "boxplot-outlier",
703
- centre: v(r, c.band, c.value),
754
+ centre: v(r, {
755
+ main: c.band,
756
+ cross: c.value
757
+ }),
704
758
  observation: c.observation,
705
759
  readers: m,
706
- state: l,
760
+ state: i,
707
761
  animateTransitions: u
708
762
  }, w[f]))
709
763
  ] });
710
764
  }, ee = ({ testId: e, segment: t, observation: r, readers: o, state: n, animateTransitions: a }) => {
711
- const s = o.get("strokeWidth", r, n) ?? 0, i = o.get("stroke", r, n);
765
+ const s = o.get("strokeWidth", r, n) ?? 0, l = o.get("stroke", r, n);
712
766
  return /* @__PURE__ */ y(fe, {
713
767
  "data-testid": e,
714
768
  x1: x(t.from.x),
715
769
  y1: x(t.from.y),
716
770
  x2: x(t.to.x),
717
771
  y2: x(t.to.y),
718
- stroke: i === void 0 ? void 0 : B(i),
772
+ stroke: l === void 0 ? void 0 : T(l),
719
773
  strokeOpacity: o.get("alpha", r, n),
720
774
  strokeWidth: s,
721
- strokeDasharray: _e(o.get("dashArray", r, n), s),
775
+ strokeDasharray: Be(o.get("dashArray", r, n), s),
722
776
  animateTransitions: a
723
777
  });
724
- }, ht = ({ box: e, mainAxis: t, panelSize: r, source: o, styleReaders: n, state: a, animateTransitions: s }) => {
725
- const i = n.get("fill", e.observation, a), u = n.get("stroke", e.observation, a), l = {
726
- fill: i === void 0 ? void 0 : B(i),
778
+ }, ut = ({ box: e, mainAxis: t, panelSize: r, source: o, styleReaders: n, state: a, animateTransitions: s }) => {
779
+ const l = n.get("fill", e.observation, a), u = n.get("stroke", e.observation, a), i = {
780
+ fill: l === void 0 ? void 0 : T(l),
727
781
  opacity: n.get("alpha", e.observation, a),
728
782
  fillOpacity: n.get("fillAlpha", e.observation, a),
729
- stroke: u === void 0 ? void 0 : B(u),
783
+ stroke: u === void 0 ? void 0 : T(u),
730
784
  strokeOpacity: n.get("strokeAlpha", e.observation, a),
731
785
  strokeWidth: n.get("strokeWidth", e.observation, a),
732
786
  effects: Te(n, e.observation, a),
@@ -734,11 +788,11 @@ var k = {
734
788
  }, h = ue(e, t);
735
789
  if (h !== null) return /* @__PURE__ */ y(ke, {
736
790
  "data-testid": "boxplot-box",
737
- d: X(h, r),
791
+ d: H(h, r),
738
792
  source: o,
739
- ...l
793
+ ...i
740
794
  });
741
- const p = ie(e, t);
795
+ const p = le(e, t);
742
796
  return /* @__PURE__ */ y(we, {
743
797
  "data-testid": "boxplot-box",
744
798
  x: x(p.x),
@@ -746,28 +800,28 @@ var k = {
746
800
  width: x(p.width),
747
801
  height: x(p.height),
748
802
  cornerRadius: n.get("cornerRadius", e.observation, a),
749
- ...l
803
+ ...i
750
804
  });
751
805
  }, te = ({ testId: e, centre: t, observation: r, readers: o, state: n, animateTransitions: a }) => {
752
- const s = o.get("fill", r, n), i = o.get("stroke", r, n);
806
+ const s = o.get("fill", r, n), l = o.get("stroke", r, n);
753
807
  return /* @__PURE__ */ y(ge, {
754
808
  "data-testid": e,
755
809
  cx: x(t.x),
756
810
  cy: x(t.y),
757
811
  r: (o.get("size", r, n) ?? 0) / 2,
758
- fill: s === void 0 ? void 0 : B(s),
812
+ fill: s === void 0 ? void 0 : T(s),
759
813
  opacity: o.get("alpha", r, n),
760
814
  fillOpacity: o.get("fillAlpha", r, n),
761
- stroke: i === void 0 ? void 0 : B(i),
815
+ stroke: l === void 0 ? void 0 : T(l),
762
816
  strokeWidth: o.get("strokeWidth", r, n),
763
817
  symbol: o.get("symbol", r, n),
764
818
  animateTransitions: a
765
819
  });
766
- }, dt = ({ layer: e, sourceLayer: t, mainAxis: r, styleReaders: o }) => {
767
- const n = F(), a = S(() => H(t), [t]), s = S(() => I(t.data, r).outliers, [t.data, r]), { boxes: i, outliers: u } = S(() => {
768
- const l = I(e.data, r), h = new Set(ct(t, s, l.outliers)), p = new Set(pe(s, l.boxes, a.readBoxKey)), g = s.filter((d) => p.has(d) || h.has(d));
820
+ }, ct = ({ layer: e, sourceLayer: t, mainAxis: r, styleReaders: o }) => {
821
+ const n = F(), a = S(() => X(t), [t]), s = S(() => I(t.data, r).outliers, [t.data, r]), { boxes: l, outliers: u } = S(() => {
822
+ const i = I(e.data, r), h = new Set(lt(t, s, i.outliers)), p = new Set(pe(s, i.boxes, a.readBoxKey)), g = s.filter((d) => p.has(d) || h.has(d));
769
823
  return {
770
- boxes: l.boxes,
824
+ boxes: i.boxes,
771
825
  outliers: g
772
826
  };
773
827
  }, [
@@ -778,7 +832,7 @@ var k = {
778
832
  a
779
833
  ]);
780
834
  return /* @__PURE__ */ y(z, {
781
- boxes: i,
835
+ boxes: l,
782
836
  outliers: u,
783
837
  mainAxis: r,
784
838
  panelSize: n,
@@ -786,13 +840,13 @@ var k = {
786
840
  styleReaders: o,
787
841
  keys: a
788
842
  });
789
- }, pt = ({ layer: e, primary: t, mainAxis: r, styleReaders: o }) => {
790
- const n = F(), a = S(() => I(e.data, r).outliers, [e.data, r]), s = S(() => H(e), [e]), { boxes: i, outliers: u } = I([t.observation], r);
843
+ }, ht = ({ layer: e, primary: t, mainAxis: r, styleReaders: o }) => {
844
+ const n = F(), a = S(() => I(e.data, r).outliers, [e.data, r]), s = S(() => X(e), [e]), { boxes: l, outliers: u } = I([t.observation], r);
791
845
  return /* @__PURE__ */ y("g", {
792
846
  "data-testid": "hovered-boxes",
793
847
  children: /* @__PURE__ */ y(z, {
794
- boxes: i,
795
- outliers: i.length > 0 ? pe(a, i, s.readBoxKey) : u,
848
+ boxes: l,
849
+ outliers: l.length > 0 ? pe(a, l, s.readBoxKey) : u,
796
850
  mainAxis: r,
797
851
  panelSize: n,
798
852
  source: e,
@@ -801,15 +855,15 @@ var k = {
801
855
  hovered: t.observation
802
856
  })
803
857
  });
804
- }, mt = ({ layer: e, mainAxis: t, styleReaders: r, animateTransitions: o, intro: n }) => {
805
- const a = F(), { boxes: s, outliers: i } = S(() => I(e.data, t), [e.data, t]), u = /* @__PURE__ */ y(z, {
858
+ }, dt = ({ layer: e, mainAxis: t, styleReaders: r, animateTransitions: o, intro: n }) => {
859
+ const a = F(), { boxes: s, outliers: l } = S(() => I(e.data, t), [e.data, t]), u = /* @__PURE__ */ y(z, {
806
860
  boxes: s,
807
- outliers: i,
861
+ outliers: l,
808
862
  mainAxis: t,
809
863
  panelSize: a,
810
864
  source: e,
811
865
  styleReaders: r,
812
- keys: S(() => H(e), [e]),
866
+ keys: S(() => X(e), [e]),
813
867
  animateTransitions: o
814
868
  });
815
869
  return n == null ? u : /* @__PURE__ */ y(xe, {
@@ -820,34 +874,34 @@ var k = {
820
874
  },
821
875
  children: u
822
876
  });
823
- }, yt = be(new Ze(), {
877
+ }, gt = Oe(new Ye(), {
824
878
  coord: "cartesian",
825
879
  swatchShape: "square",
826
880
  overpaintPlacement: "manual",
827
881
  guideMode: "band",
828
- render: ({ layer: e, coordSystem: t, styleReaders: r, animateTransitions: o, intro: n }) => /* @__PURE__ */ y(mt, {
882
+ render: ({ layer: e, coordSystem: t, styleReaders: r, animateTransitions: o, intro: n }) => /* @__PURE__ */ y(dt, {
829
883
  layer: e,
830
884
  mainAxis: E(t),
831
885
  styleReaders: r,
832
886
  animateTransitions: o,
833
887
  intro: n
834
888
  }),
835
- renderHighlight: ({ layer: e, sourceLayer: t, coordSystem: r, styleReaders: o }) => /* @__PURE__ */ y(dt, {
889
+ renderHighlight: ({ layer: e, sourceLayer: t, coordSystem: r, styleReaders: o }) => /* @__PURE__ */ y(ct, {
836
890
  layer: e,
837
891
  sourceLayer: t,
838
892
  mainAxis: E(r),
839
893
  styleReaders: o
840
894
  }),
841
- renderHover: ({ layer: e, primary: t, coordSystem: r, styleReaders: o }) => /* @__PURE__ */ y(pt, {
895
+ renderHover: ({ layer: e, primary: t, coordSystem: r, styleReaders: o }) => /* @__PURE__ */ y(ht, {
842
896
  layer: e,
843
897
  primary: t,
844
898
  mainAxis: E(r),
845
899
  styleReaders: o
846
900
  }),
847
- getEditOutlineShapes: ut
901
+ getEditOutlineShapes: it
848
902
  });
849
903
  export {
850
904
  k as BOXPLOT_VARIABLES,
851
- Ze as BoxplotGeom,
852
- yt as boxplot
905
+ Ye as BoxplotGeom,
906
+ gt as boxplot
853
907
  };
@@ -32,5 +32,3 @@ export declare const readMedianSegment: (box: Box, mainAxis: MainAxis) => ViewBo
32
32
  export declare const readMeanPoint: (box: Box, mainAxis: MainAxis) => XYPoint | null;
33
33
  /** The whiskers that reach past the box; one that ends on its quartile draws nothing. */
34
34
  export declare const readWhiskers: (box: Box, mainAxis: MainAxis) => Whisker[];
35
- /** A point placed by its main-axis and value-axis fractions, in the view box. */
36
- export declare const toViewBox: (mainAxis: MainAxis, main: number, cross: number) => XYPoint;
@@ -18,7 +18,7 @@ export interface Box {
18
18
  upper: number;
19
19
  } | null;
20
20
  }
21
- /** A value past its box's whiskers, standing on the box's centre line. */
21
+ /** A value past its box's whiskers, standing on the box's center line. */
22
22
  export interface Outlier {
23
23
  observation: Observation;
24
24
  /** The centre of its box's share of the band. */
@@ -29,7 +29,7 @@ export interface Boxplot {
29
29
  boxes: Box[];
30
30
  outliers: Outlier[];
31
31
  }
32
- /** The centre line a box's whiskers and outliers stand on. */
32
+ /** The center line a box's whiskers and outliers stand on. */
33
33
  export declare const readBoxCentre: (box: Pick<Box, "start" | "end">) => number;
34
34
  /**
35
35
  * Reads where a box sits. The flip is already baked into the position columns, so under `coord.flip()` the
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "boxplot",
14
14
  "box-plot"
15
15
  ],
16
- "version": "0.1.1-beta.1794327284843",
16
+ "version": "0.1.1-beta.1794385976422",
17
17
  "type": "module",
18
18
  "sideEffects": false,
19
19
  "types": "./dist/index.d.ts",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^19.0.0",
35
- "@graphysdk/react": "^1.9.0-beta.1794327284843"
35
+ "@graphysdk/react": "^1.9.0-beta.1794385976422"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@testing-library/react": "^16.3.1",
@@ -44,8 +44,8 @@
44
44
  "vite": "^8.1.5",
45
45
  "vite-plugin-dts": "^4.5.4",
46
46
  "vitest": "^4.1.11",
47
- "@graphysdk/react": "1.9.0-beta.1794327284843",
48
- "@graphysdk/viz-engine": "1.9.0-beta.1794327284843",
47
+ "@graphysdk/react": "1.9.0-beta.1794385976422",
48
+ "@graphysdk/viz-engine": "1.9.0-beta.1794385976422",
49
49
  "@graphytools/eslint-config": "0.0.1",
50
50
  "@graphytools/typescript-config": "0.0.1",
51
51
  "@graphytools/vitest-config": "1.0.0"