@graphysdk/geom-boxplot 0.1.1-beta.1793880532798 → 0.1.1-beta.1793882432228
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 +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -4
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,G=(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),l=(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||l===null||c===null)return null;const i=T(e,"notchLower"),d=T(e,"notchUpper"),[m,k]=ne(r,o,e);return{observation:e,start:m,end:k,lowerWhisker:n,q1:l,median:u,q3:c,upperWhisker:s,mean:T(e,"mean"),notch:i===null||d===null?null:{lower:i,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=G(n,t);if(s!==null){r.push(s);continue}const l=X(n,t);l!==null&&o.push(l)}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),l=t==="min-max"?1/0:t*(s-o),u=o-l,c=s+l,i=r.filter(m=>m>=u&&m<=c),d=ae*(s-o)/Math.sqrt(e.length);return{lowerWhisker:Math.min(i[0]??o,o),q1:o,median:n,q3:s,upperWhisker:Math.max(i[i.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"]),le=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 l=e.getType(n);throw new a.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'boxplot' stat requires a numeric 'y' (got '${l}' for variable '${n}')`,context:{aesthetic:"y",variableName:n,variableType:l},suggestion:"Map the raw values to 'y', or summarised columns under stat 'identity'."})}const s=r?.extent;return{data:ie({data:e,xVariable:o,yVariable:n,groupVariables:(0,a.getGroupVariables)(e,t).filter(l=>l!==o),extent:F(s)?s:b}),mapping:H}}},ie=({data:e,xVariable:t,yVariable:r,groupVariables:o,extent:n})=>{const s=ue(e,t,r,o),l=e.getVariableNames(),u=new Map(l.map(p=>[p,e.getValues(p)])),c=new Map(l.map(p=>[p,[]])),i={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 l)c.get(h)?.push(ce(u.get(h)??[],p.indices));i.q1.push(v.q1),i.median.push(v.median),i.q3.push(v.q3),i.lowerWhisker.push(v.lowerWhisker),i.upperWhisker.push(v.upperWhisker),i.count.push(v.count),i.mean.push(v.mean),i.notchLower.push(v.notchLower),i.notchUpper.push(v.notchUpper),i.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 l)c.get(w)?.push(u.get(w)?.[p]??null);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(v)}const m=e.getValueFormat(r),k=Object.fromEntries(l.map(p=>[p,{type:e.getType(p),values:c.get(p)??[],valueFormat:e.getValueFormat(p)}]));for(const[p,v]of Object.entries(i)){const w=x[p];k[w]=p==="count"?{type:"numeric",values:v}:{type:"numeric",values:v,valueFormat:m}}return new a.Dataset(k)},ue=(e,t,r,o)=>{const n=[t,...o].map(u=>e.getValues(u)),s=e.getValues(r,{type:"numeric"}),l=new Map;return s.forEach((u,c)=>{if(u===null||!Number.isFinite(u))return;const i=n.map(m=>V(m[c]??null)).join("\0"),d=l.get(i)??{indices:[],values:[]};d.indices.push(c),d.values.push(u),l.set(i,d)}),[...l.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 le,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.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:l,showMean:u,varwidth:c}=r,i=P(e,t.outlier),d=s===!1&&i!==null?Se(e,i):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,i)).addVariable(a.POSITION_VARIABLES.yMax,"numeric",D(d,n,i)).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},...l===!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=G(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),[l,u]=K(n.x,s.x),[c,i]=K(n.y,s.y);return{x:l,y:c,width:u-l,height:i-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:l})=>({side:n,stem:{from:g(t,r,s),to:g(t,r,l)},cap:{from:g(t,r-o,l),to:g(t,r+o,l)}}))},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:l}=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"),i=o.part("cap"),d=s.flatMap(h=>re(h,n).flatMap(y=>[{segment:y.stem,readers:c},{segment:y.cap,readers:i}].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?[]:l.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(l=>{const u=o(l),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=l=>JSON.stringify(o.map(u=>l.observation[u]??null)),s=new Set(r.map(n));return t.filter(l=>s.has(n(l)))},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:l,hovered:u,animateTransitions:c=!1})=>{const i=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=l.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)(U,{testId:E,segment:y[M],observation:h.observation,readers:I,state:i,animateTransitions:c},`${l.readBoxKey(h.observation)}-${y.side}-${M}`)))),(0,f.jsx)(a.GeomOverpaint,{styleReaders:s,state:i,children:e.map(h=>(0,f.jsx)(_e,{box:h,mainAxis:r,panelSize:o,source:n,styleReaders:s,state:i,animateTransitions:c},l.readBoxKey(h.observation)))}),k&&e.map(h=>(0,f.jsx)(U,{testId:"boxplot-median",segment:Pe(h,r),observation:h.observation,readers:k,state:i,animateTransitions:c},l.readBoxKey(h.observation))),p&&e.map(h=>{const y=ee(h,r);return y===null?null:(0,f.jsx)($,{testId:"boxplot-mean",centre:y,observation:h.observation,readers:p,state:i,animateTransitions:c},l.readBoxKey(h.observation))}),v&&t.map((h,y)=>(0,f.jsx)($,{testId:"boxplot-outlier",centre:g(r,h.band,h.value),observation:h.observation,readers:v,state:i,animateTransitions:c},w[y]))]})},U=({testId:e,segment:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const l=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:l,strokeDasharray:(0,a.toStrokeDasharray)(o.get("dashArray",r,n),l),animateTransitions:s})},_e=({box:e,mainAxis:t,panelSize:r,source:o,styleReaders:n,state:s,animateTransitions:l})=>{const u=n.get("fill",e.observation,s),c=n.get("stroke",e.observation,s),i={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:l},d=J(e,t);if(d!==null)return(0,f.jsx)(a.GeomPath,{"data-testid":"boxplot-box",d:N(d,r),source:o,...i});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),...i})},$=({testId:e,centre:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const l=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:l===void 0?void 0:(0,a.toPaintColor)(l),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]),l=(0,S.useMemo)(()=>W(t.data,r).outliers,[t.data,r]),{boxes:u,outliers:c}=(0,S.useMemo)(()=>{const i=W(e.data,r),d=new Set(Te(t,l,i.outliers)),m=new Set(oe(l,i.boxes,s.readBoxKey)),k=l.filter(p=>m.has(p)||d.has(p));return{boxes:i.boxes,outliers:k}},[e.data,r,t,l,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]),l=(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,l.readBoxKey):c,mainAxis:r,panelSize:n,source:e,styleReaders:o,keys:l,hovered:t.observation})})},Ne=({layer:e,mainAxis:t,styleReaders:r,animateTransitions:o,intro:n})=>{const s=(0,a.useGeomPanelSize)(),{boxes:l,outliers:u}=(0,S.useMemo)(()=>W(e.data,t),[e.data,t]),c=(0,f.jsx)(L,{boxes:l,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"),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,G=(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),l=(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||l===null||c===null)return null;const i=T(e,"notchLower"),d=T(e,"notchUpper"),[m,k]=ne(r,o,e);return{observation:e,start:m,end:k,lowerWhisker:n,q1:l,median:u,q3:c,upperWhisker:s,mean:T(e,"mean"),notch:i===null||d===null?null:{lower:i,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=G(n,t);if(s!==null){r.push(s);continue}const l=X(n,t);l!==null&&o.push(l)}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),l=t==="min-max"?1/0:t*(s-o),u=o-l,c=s+l,i=r.filter(m=>m>=u&&m<=c),d=ae*(s-o)/Math.sqrt(e.length);return{lowerWhisker:Math.min(i[0]??o,o),q1:o,median:n,q3:s,upperWhisker:Math.max(i[i.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"]),le=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 l=e.getType(n);throw new a.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'boxplot' stat requires a numeric 'y' (got '${l}' for variable '${n}')`,context:{aesthetic:"y",variableName:n,variableType:l},suggestion:"Map the raw values to 'y', or summarised columns under stat 'identity'."})}const s=r?.extent;return{data:ie({data:e,xVariable:o,yVariable:n,groupVariables:(0,a.getGroupVariables)(e,t).filter(l=>l!==o),extent:F(s)?s:b}),mapping:H}}},ie=({data:e,xVariable:t,yVariable:r,groupVariables:o,extent:n})=>{const s=ue(e,t,r,o),l=e.getVariableNames(),u=new Map(l.map(p=>[p,e.getValues(p)])),c=new Map(l.map(p=>[p,[]])),i={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 l)c.get(h)?.push(ce(u.get(h)??[],p.indices));i.q1.push(v.q1),i.median.push(v.median),i.q3.push(v.q3),i.lowerWhisker.push(v.lowerWhisker),i.upperWhisker.push(v.upperWhisker),i.count.push(v.count),i.mean.push(v.mean),i.notchLower.push(v.notchLower),i.notchUpper.push(v.notchUpper),i.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 l)c.get(w)?.push(u.get(w)?.[p]??null);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(v)}const m=e.getValueFormat(r),k=Object.fromEntries(l.map(p=>[p,{type:e.getType(p),values:c.get(p)??[],valueFormat:e.getValueFormat(p)}]));for(const[p,v]of Object.entries(i)){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"}),l=new Map;return s.forEach((u,c)=>{if(u===null||!Number.isFinite(u))return;const i=n.map(m=>V(m[c]??null)).join("\0"),d=l.get(i)??{indices:[],values:[]};d.indices.push(c),d.values.push(u),l.set(i,d)}),[...l.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 le,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.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:l,showMean:u,varwidth:c}=r,i=P(e,t.outlier),d=s===!1&&i!==null?Se(e,i):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,i)).addVariable(a.POSITION_VARIABLES.yMax,"numeric",D(d,n,i)).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},...l===!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=G(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),[l,u]=K(n.x,s.x),[c,i]=K(n.y,s.y);return{x:l,y:c,width:u-l,height:i-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:l})=>({side:n,stem:{from:g(t,r,s),to:g(t,r,l)},cap:{from:g(t,r-o,l),to:g(t,r+o,l)}}))},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:l}=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"),i=o.part("cap"),d=s.flatMap(h=>re(h,n).flatMap(y=>[{segment:y.stem,readers:c},{segment:y.cap,readers:i}].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?[]:l.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(l=>{const u=o(l),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=l=>JSON.stringify(o.map(u=>l.observation[u]??null)),s=new Set(r.map(n));return t.filter(l=>s.has(n(l)))},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:l,hovered:u,animateTransitions:c=!1})=>{const i=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=l.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)(U,{testId:E,segment:y[M],observation:h.observation,readers:I,state:i,animateTransitions:c},`${l.readBoxKey(h.observation)}-${y.side}-${M}`)))),(0,f.jsx)(a.GeomOverpaint,{styleReaders:s,state:i,children:e.map(h=>(0,f.jsx)(_e,{box:h,mainAxis:r,panelSize:o,source:n,styleReaders:s,state:i,animateTransitions:c},l.readBoxKey(h.observation)))}),k&&e.map(h=>(0,f.jsx)(U,{testId:"boxplot-median",segment:Pe(h,r),observation:h.observation,readers:k,state:i,animateTransitions:c},l.readBoxKey(h.observation))),p&&e.map(h=>{const y=ee(h,r);return y===null?null:(0,f.jsx)($,{testId:"boxplot-mean",centre:y,observation:h.observation,readers:p,state:i,animateTransitions:c},l.readBoxKey(h.observation))}),v&&t.map((h,y)=>(0,f.jsx)($,{testId:"boxplot-outlier",centre:g(r,h.band,h.value),observation:h.observation,readers:v,state:i,animateTransitions:c},w[y]))]})},U=({testId:e,segment:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const l=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:l,strokeDasharray:(0,a.toStrokeDasharray)(o.get("dashArray",r,n),l),animateTransitions:s})},_e=({box:e,mainAxis:t,panelSize:r,source:o,styleReaders:n,state:s,animateTransitions:l})=>{const u=n.get("fill",e.observation,s),c=n.get("stroke",e.observation,s),i={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:l},d=J(e,t);if(d!==null)return(0,f.jsx)(a.GeomPath,{"data-testid":"boxplot-box",d:N(d,r),source:o,...i});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),...i})},$=({testId:e,centre:t,observation:r,readers:o,state:n,animateTransitions:s})=>{const l=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:l===void 0?void 0:(0,a.toPaintColor)(l),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]),l=(0,S.useMemo)(()=>W(t.data,r).outliers,[t.data,r]),{boxes:u,outliers:c}=(0,S.useMemo)(()=>{const i=W(e.data,r),d=new Set(Te(t,l,i.outliers)),m=new Set(oe(l,i.boxes,s.readBoxKey)),k=l.filter(p=>m.has(p)||d.has(p));return{boxes:i.boxes,outliers:k}},[e.data,r,t,l,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]),l=(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,l.readBoxKey):c,mainAxis:r,panelSize:n,source:e,styleReaders:o,keys:l,hovered:t.observation})})},Ne=({layer:e,mainAxis:t,styleReaders:r,animateTransitions:o,intro:n})=>{const s=(0,a.useGeomPanelSize)(),{boxes:l,outliers:u}=(0,S.useMemo)(()=>W(e.data,t),[e.data,t]),c=(0,f.jsx)(L,{boxes:l,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;
|
package/dist/index.mjs
CHANGED
|
@@ -177,7 +177,7 @@ var k = {
|
|
|
177
177
|
valueFormat: p
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
|
-
return new me(g);
|
|
180
|
+
return new me(g, e.parsingLocale);
|
|
181
181
|
}, Ke = (e, t, r, o) => {
|
|
182
182
|
const n = [t, ...o].map((i) => e.getValues(i)), a = e.getValues(r, { type: "numeric" }), s = /* @__PURE__ */ new Map();
|
|
183
183
|
return a.forEach((i, u) => {
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"boxplot",
|
|
14
14
|
"box-plot"
|
|
15
15
|
],
|
|
16
|
-
"version": "0.1.1-beta.
|
|
16
|
+
"version": "0.1.1-beta.1793882432228",
|
|
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.
|
|
35
|
+
"@graphysdk/react": "^1.9.0-beta.1793882432228"
|
|
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.
|
|
48
|
-
"@graphysdk/viz-engine": "1.9.0-beta.
|
|
47
|
+
"@graphysdk/react": "1.9.0-beta.1793882432228",
|
|
48
|
+
"@graphysdk/viz-engine": "1.9.0-beta.1793882432228",
|
|
49
49
|
"@graphytools/eslint-config": "0.0.1",
|
|
50
50
|
"@graphytools/typescript-config": "0.0.1",
|
|
51
51
|
"@graphytools/vitest-config": "1.0.0"
|