@graphysdk/geom-sankey 0.1.0 → 0.1.1-beta.1792404455940
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/engine/sankey.geom.d.ts +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +151 -140
- package/dist/renderer/paint/sankey-flows.d.ts +5 -4
- package/dist/renderer/paint/sankey-labels.d.ts +4 -3
- package/dist/renderer/paint/sankey-nodes.d.ts +5 -4
- package/dist/renderer/paint/sankey-paint.d.ts +5 -4
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let y=require("@graphysdk/react"),S=require("d3-sankey"),O=require("react"),v=require("react/jsx-runtime");var i={kind:"sankeyKind",nodeName:"sankeyNodeName",observationKey:"sankeyObservationKey",nodeKey:"sankeyNodeKey",targetKey:"sankeyTargetKey",x0:"sankeyX0",x1:"sankeyX1",y0:"sankeyY0",y1:"sankeyY1",targetY0:"sankeyTargetY0",targetY1:"sankeyTargetY1"},k=(e,t)=>{const a=e[t];return typeof a=="number"&&Number.isFinite(a)?a:null},K=e=>{const t=e[i.observationKey],a=e[i.nodeKey],n=k(e,i.x0),o=k(e,i.x1),r=k(e,i.y0),s=k(e,i.y1);if(typeof t!="string"||typeof a!="string"||n===null||o===null||r===null||s===null)return null;switch(e[i.kind]){case"node":return{kind:"node",observation:e,key:t,nodeKey:a,x0:n,x1:o,y0:r,y1:s};case"flow":{const l=k(e,i.targetY0),u=k(e,i.targetY1),c=e[i.targetKey];return l===null||u===null||typeof c!="string"?null:{kind:"flow",observation:e,key:t,nodeKey:a,targetKey:c,x0:n,x1:o,y0:r,y1:s,targetY0:l,targetY1:u}}default:return null}},C=new WeakMap,N=e=>{const t=C.get(e);if(t!==void 0)return t;const a=[],n=[];for(const r of e){const s=K(r);s?.kind==="node"&&a.push(s),s?.kind==="flow"&&n.push(s)}const o={nodes:a,flows:n};return C.set(e,o),o},V=(e,t)=>e.nodeKey===t.nodeKey||e.targetKey===t.nodeKey,I=e=>e*e*(3-2*e),F=(e,t)=>{const a=I(t);return{top:e.y0+(e.targetY0-e.y0)*a,bottom:e.y1+(e.targetY1-e.y1)*a}},W=(e,t)=>{const a=e.x1-e.x0;if(a<=0||t.x<e.x0||t.x>e.x1)return!1;const{top:n,bottom:o}=F(e,(t.x-e.x0)/a);return t.y>=n&&t.y<=o},_=(e,t)=>{const a=u=>u*t.width,n=u=>u*t.height,o=a(e.x0),r=a(e.x1),s=a(e.x0+(e.x1-e.x0)/3),l=a(e.x0+(e.x1-e.x0)*2/3);return[`M${o},${n(e.y0)}`,`C${s},${n(e.y0)} ${l},${n(e.targetY0)} ${r},${n(e.targetY0)}`,`L${r},${n(e.targetY1)}`,`C${l},${n(e.targetY1)} ${s},${n(e.y1)} ${o},${n(e.y1)}`,"Z"].join("")},D=.018,G=.03,w={justify:S.sankeyJustify,left:S.sankeyLeft,right:S.sankeyRight,center:S.sankeyCenter},H=(e,t)=>{const a=B(e);if(a.length===0)return{nodes:[],flows:[]};const n=[...new Set(a.flatMap(r=>[r.source,r.target]))],o=(0,S.sankey)().nodeId(r=>r.key).nodeAlign(w[t]).nodeWidth(D).nodePadding(G).extent([[0,0],[1,1]])({nodes:n.map(r=>({key:r})),links:a.map(r=>({source:r.source,target:r.target,value:r.value,link:r}))});return{nodes:o.nodes.map(r=>({key:r.key,value:r.value??0,x0:p(r.x0),x1:p(r.x1),y0:p(r.y0),y1:p(r.y1)})),flows:o.links.map(r=>{const s=r.source,l=r.target,u=(r.width??0)/2;return{link:r.link,x0:p(s.x1),x1:p(l.x0),y0:p((r.y0??0)-u),y1:p((r.y0??0)+u),targetY0:p((r.y1??0)-u),targetY1:p((r.y1??0)+u)}})}},p=e=>Math.min(1,Math.max(0,e??0)),B=e=>{const t=new Map,a=(n,o)=>{const r=new Set,s=[n];for(;s.length>0;){const l=s.pop();if(l===o)return!0;r.has(l)||(r.add(l),s.push(...t.get(l)??[]))}return!1};return e.filter(n=>t.get(n.source)?.has(n.target)===!0?!0:a(n.target,n.source)?!1:(t.set(n.source,(t.get(n.source)??new Set).add(n.target)),!0))},E=new Set(["node"]),j=["color","alpha"],U=["justify","left","right","center"],X=class extends y.Stat{constructor(...e){super(...e),this.type="sankey",this.computedVariables=E}computeStat({data:e,mapping:t,params:a}){const n=Q(e,t);return n===null?{data:e,mapping:{}}:(Z(e,n),{data:ae(e,n,J(a)),mapping:{node:i.nodeName,...R(t,n)}})}},R=(e,t)=>{const a={};for(const n of j){const o=q(n,e[n],t);o!==null&&(a[n]=o)}return a},q=(e,t,{sourceVariable:a,targetVariable:n})=>{if(t===void 0)return e==="color"?i.nodeKey:null;const o=(0,y.readVariableName)(t);return o===a?i.nodeKey:o===n?i.targetKey:null},z=e=>U.includes(e),J=e=>{const t=e?.align;return z(t)?t:"justify"},L=(e,t)=>e===null?null:e instanceof Date?t.type==="year"?String(e.getUTCFullYear()):e.toISOString():String(e),Z=(e,{valueVariable:t})=>{const a=e.getType(t);if(!(e.size()===0||a==="numeric"))throw new y.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'sankey' stat requires a numeric 'value' (got '${a}' for variable '${t}')`,context:{aesthetic:"value",variableName:t,variableType:a},suggestion:"Map each flow's amount to 'value', declaring the column numeric if it holds whole years."})},Q=(e,t)=>{const a=(0,y.readVariableName)(t.source),n=(0,y.readVariableName)(t.target),o=(0,y.readVariableName)(t.value);return a===null||n===null||o===null||![a,n,o].every(r=>e.hasVariable(r))?null:{sourceVariable:a,targetVariable:n,valueVariable:o}},ee=(e,{sourceVariable:t,targetVariable:a,valueVariable:n})=>{const o=e.getValues(t),r=e.getValues(a),s=e.getValues(n,{type:"numeric"}),l=e.getValueFormat(t),u=e.getValueFormat(a),c=new Map,g=new Map,d=[];return o.forEach((h,m)=>{const b=r[m]??null,f=L(h,l),x=L(b,u);if(f===null||x===null)return;g.set(f,h),g.set(x,b);const P=JSON.stringify([f,x]),Y=c.get(P)??0;c.set(P,Y+1);const A=s[m];typeof A!="number"||!Number.isFinite(A)||A<=0||d.push({source:f,target:x,value:A,row:m,occurrence:Y})}),{links:d,names:g}},$=(e,{sourceVariable:t,targetVariable:a})=>e.getType(t)===e.getType(a),te=(e,t,a,n)=>{const o=e.getType(t.sourceVariable);return $(e,t)?{type:o,values:a.map(r=>n.get(r)??null),valueFormat:e.getValueFormat(t.sourceVariable)}:{type:"categorical",values:[...a]}},re=(e,t,a,n,o)=>e===a.valueVariable?n.nodes.map(r=>r.value):e===a.sourceVariable&&$(t,a)?n.nodes.map(r=>o.get(r.key)??null):null,ae=(e,t,a)=>{const{links:n,names:o}=ee(e,t),r=H(n,a),s=r.nodes.length,l=d=>[...d,...Array.from({length:s},()=>null)],u=e.getVariableNames(),c=Object.fromEntries(u.map(d=>{const h=e.getValues(d),m=r.flows.map(({link:x})=>h[x.row]??null),b=re(d,e,t,r,o),f=b===null?l(m):[...m,...b];return[d,{type:e.getType(d),values:f,valueFormat:e.getValueFormat(d)}]})),g=[...r.flows.map(({link:d})=>d.source),...r.nodes.map(({key:d})=>d)];return new y.Dataset({...c,...ne(r),[i.nodeName]:te(e,t,g,o)})},ne=e=>{const t=e.flows.map(({link:l,...u})=>({[i.kind]:"flow",[i.observationKey]:JSON.stringify(["flow",l.source,l.target,l.occurrence]),[i.nodeKey]:l.source,[i.targetKey]:l.target,[i.x0]:u.x0,[i.x1]:u.x1,[i.y0]:u.y0,[i.y1]:u.y1,[i.targetY0]:u.targetY0,[i.targetY1]:u.targetY1})),a=e.nodes.map(l=>({[i.kind]:"node",[i.observationKey]:JSON.stringify(["node",l.key]),[i.nodeKey]:l.key,[i.targetKey]:l.key,[i.x0]:l.x0,[i.x1]:l.x1,[i.y0]:l.y0,[i.y1]:l.y1,[i.targetY0]:null,[i.targetY1]:null})),n=[...t,...a],o=l=>n.map(u=>u[l]),r=l=>({type:"categorical",values:o(l)}),s=l=>({type:"numeric",values:o(l)});return{[i.kind]:r(i.kind),[i.observationKey]:r(i.observationKey),[i.nodeKey]:r(i.nodeKey),[i.targetKey]:r(i.targetKey),[i.x0]:s(i.x0),[i.x1]:s(i.x1),[i.y0]:s(i.y0),[i.y1]:s(i.y1),[i.targetY0]:s(i.targetY0),[i.targetY1]:s(i.targetY1)}},oe=.4,se=.65,ie=12,le=3,ue={},ce={fill:"paint",fillAlpha:"unitInterval",alpha:"unitInterval",stroke:"color",strokeWidth:"pixels"},ye={fontFamily:"fontFamily",fontSize:"pixels",fontWeight:"fontWeight",textColor:"color",textOutlineColor:"color",textOutlineWidth:"pixels"},M=class extends y.Geom{constructor(...e){super(...e),this.type="sankey",this.defaultParams={align:"justify"},this.defaultStat=new X,this.aesthetics=[{kind:"data",name:"source",required:!0},{kind:"data",name:"target",required:!0},{kind:"data",name:"value",required:!0},{kind:"data",name:"node"},{kind:"visual",name:"color"},{kind:"visual",name:"alpha"}],this.identityKey={variable:i.observationKey},this.supportedPositions=["identity"],this.supportedCoordTypes=["cartesian"],this.legend={defaultPosition:"none"},this.spatialKind="render-hit-test",this.highlightStrategy="observation-rerender",this.tooltip=[{aes:"node",heading:!0},{aes:"target"},{aes:"value"}],this.styleTarget=(0,y.defineGeomStyleTarget)({observation:{vocabulary:ue,aesthetics:{fill:"color",alpha:"alpha"},rest:{fill:(0,y.token)("geom"),fillAlpha:oe},hovered:{fillAlpha:se}},parts:{node:{vocabulary:ce,aesthetics:{fill:"color",alpha:"alpha"},rest:{fill:(0,y.token)("geom"),fillAlpha:1,alpha:1,stroke:(0,y.token)("graphBackground"),strokeWidth:0}},label:{vocabulary:ye,rest:{fontSize:ie,fontWeight:500,textColor:(0,y.token)("textPrimary"),textOutlineColor:(0,y.token)("graphBackground"),textOutlineWidth:le}}}}),this.resolveValueSource=t=>t.value??null,this.validateMapping=({mapping:t,computedVariables:a})=>{if(!a.has("node"))return[{code:"MISSING_STAT_OUTPUT",message:"sankey geom lays its flows out in the 'sankey' stat; remove the layer's stat"}];const n=[...E].filter(s=>t[s]!==void 0).map(s=>({code:"CONFLICTING_STAT_MAPPING",message:`sankey stat computes '${s}' from 'source' and 'target'; remove its mapping`})),o=[(0,y.readVariableName)(t.source),(0,y.readVariableName)(t.target)],r=j.flatMap(s=>{const l=(0,y.readVariableName)(t[s]);return l===null||o.includes(l)?[]:[{code:"UNSUPPORTED_MAPPING",message:`sankey geom scales '${s}' by node; map it to the source or target column rather than '${l}'`}]});return[...n,...r]},this.resolveAnchorPosition=t=>{const a=K(t);if(a===null)return null;if(a.kind==="node")return{x:(a.x0+a.x1)/2,y:1-(a.y0+a.y1)/2};const{top:n,bottom:o}=F(a,.5);return{x:(a.x0+a.x1)/2,y:1-(n+o)/2}}}compile({data:e}){return{data:e,mapping:{}}}},de=({layer:e,panelRect:t})=>{const{nodes:a,flows:n}=N(e.data),o=s=>s*t.width,r=s=>s*t.height;return[...n.map(s=>({kind:"region",pathData:_(s,t)})),...a.map(s=>({kind:"region",pathData:`M${o(s.x0)},${r(s.y0)}H${o(s.x1)}V${r(s.y1)}H${o(s.x0)}Z`}))]},ge=({flows:e,size:t,source:a,styleReaders:n,isHovered:o=!1,shouldAnimateTransitions:r=!1})=>{const s=o?"hovered":void 0,l=(0,O.useMemo)(()=>e.map(g=>n.get("fill",g.observation,s)??"transparent"),[e,n,s]),{fillFor:u,defs:c}=(0,y.usePaintDefs)({paints:l});return(0,v.jsxs)(v.Fragment,{children:[c,e.map((g,d)=>{const h=l[d],m=n.get("stroke",g.observation,s);return(0,v.jsx)(y.GeomPath,{"data-testid":"sankey-flow",d:_(g,t),source:a,fill:h===void 0?void 0:u(h),opacity:n.get("alpha",g.observation,s),fillOpacity:n.get("fillAlpha",g.observation,s),stroke:m===void 0?void 0:(0,y.toPaintColor)(m),strokeOpacity:n.get("strokeAlpha",g.observation,s),shouldAnimateTransitions:r},g.key)})]})},ve=6,he=e=>{const t=(e.y0+e.y1)/2;return(e.x0+e.x1)/2<.5?{x:e.x1,y:t,offsetX:ve,textAnchor:"start"}:{x:e.x0,y:t,offsetX:-6,textAnchor:"end"}},me=({nodes:e,valueFormat:t,styleReaders:a,isHovered:n=!1})=>{const o=n?"hovered":void 0,r=a.part("label"),s=(0,y.useGraphLocale)(),l=(0,y.useSceneSelector)(c=>c.config.numberFormat),u=(0,O.useMemo)(()=>(0,y.createValueFormatter)({valueFormat:t,locale:s,numberFormat:l}),[t,s,l]);return(0,v.jsx)("g",{pointerEvents:"none",children:e.map(c=>{const g=c.observation[i.nodeName];if(g==null)return null;const d=he(c),h=r?.get("textColor",c.observation,o),m=r?.get("textOutlineColor",c.observation,o);return(0,v.jsx)("text",{"data-testid":"sankey-label",x:(0,y.toPercent)(d.x),y:(0,y.toPercent)(d.y),dx:d.offsetX,textAnchor:d.textAnchor,dominantBaseline:"central",fontFamily:r?.get("fontFamily",c.observation,o),fontSize:r?.get("fontSize",c.observation,o),fontWeight:r?.get("fontWeight",c.observation,o),fill:h===void 0?void 0:(0,y.toPaintColor)(h),stroke:m===void 0?void 0:(0,y.toPaintColor)(m),strokeWidth:r?.get("textOutlineWidth",c.observation,o),strokeLinejoin:"round",paintOrder:"stroke",children:u(g,c.observation)},c.key)})})},pe=({nodes:e,styleReaders:t,isHovered:a=!1,shouldAnimateTransitions:n=!1})=>{const o=a?"hovered":void 0,r=t.part("node"),s=(0,O.useMemo)(()=>e.map(c=>r?.get("fill",c.observation,o)??"transparent"),[e,r,o]),{fillFor:l,defs:u}=(0,y.usePaintDefs)({paints:s});return(0,v.jsxs)(v.Fragment,{children:[u,e.map((c,g)=>{const d=s[g],h=r?.get("stroke",c.observation,o);return(0,v.jsx)(y.GeomRect,{"data-testid":"sankey-node",x:(0,y.toPercent)(c.x0),y:(0,y.toPercent)(c.y0),width:(0,y.toPercent)(c.x1-c.x0),height:(0,y.toPercent)(c.y1-c.y0),fill:d===void 0?void 0:l(d),opacity:r?.get("alpha",c.observation,o),fillOpacity:r?.get("fillAlpha",c.observation,o),stroke:h===void 0?void 0:(0,y.toPaintColor)(h),strokeWidth:r?.get("strokeWidth",c.observation,o),shouldAnimateTransitions:n},c.key)})]})},fe={type:"text"},T=({observations:e,layer:t,size:a,styleReaders:n,isHovered:o=!1,shouldAnimateTransitions:r=!1})=>(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(ge,{flows:e.flows,size:a,source:t,styleReaders:n,isHovered:o,shouldAnimateTransitions:r}),(0,v.jsx)(pe,{nodes:e.nodes,styleReaders:n,isHovered:o,shouldAnimateTransitions:r}),(0,v.jsx)(me,{nodes:e.nodes,valueFormat:t.data.hasVariable(i.nodeName)?t.data.getValueFormat(i.nodeName):fe,styleReaders:n,isHovered:o})]}),xe=({layer:e,size:t,styleReaders:a})=>(0,v.jsx)(T,{observations:N(e.data),layer:e,size:t,styleReaders:a}),ke=({layer:e})=>{const{nodes:t,flows:a}=N(e.data),n=[...t].reverse(),o=[...a].reverse();return r=>{const s=n.find(u=>r.x>=u.x0&&r.x<=u.x1&&r.y>=u.y0&&r.y<=u.y1);if(s!==void 0)return{key:s.key};const l=o.find(u=>W(u,r));return l===void 0?null:{key:l.key}}},be=({layer:e,primary:t,size:a,styleReaders:n})=>{const o=N(e.data),r=t.observation;return(0,v.jsx)("g",{"data-testid":"hovered-observations",children:(0,v.jsx)(T,{observations:(0,O.useMemo)(()=>Se(o,r),[o,r]),layer:e,size:a,styleReaders:n,isHovered:!0})})},Se=(e,t)=>{const a=K(t);if(a===null)return{nodes:[],flows:[]};if(a.kind==="node"){const n=e.flows.filter(r=>V(r,a)),o=new Set(n.flatMap(r=>[r.nodeKey,r.targetKey]));return{nodes:e.nodes.filter(r=>o.has(r.nodeKey)),flows:n}}return{nodes:e.nodes.filter(n=>V(a,n)),flows:[a]}},Ne=({layer:e,size:t,styleReaders:a,shouldAnimateTransitions:n})=>(0,v.jsx)(T,{observations:N(e.data),layer:e,size:t,styleReaders:a,shouldAnimateTransitions:n}),Ae=(0,y.defineGeomRenderer)(new M,{coord:"cartesian",swatchShape:"square",render:({layer:e,panelRect:t,styleReaders:a,shouldAnimateTransitions:n})=>(0,v.jsx)(Ne,{layer:e,size:t,styleReaders:a,shouldAnimateTransitions:n}),renderHighlight:({layer:e,panelRect:t,styleReaders:a})=>(0,v.jsx)(xe,{layer:e,size:t,styleReaders:a}),renderHover:({layer:e,primary:t,panelRect:a,styleReaders:n})=>(0,v.jsx)(be,{layer:e,primary:t,size:a,styleReaders:n}),renderHoverCompanions:()=>null,hitTest:ke,getEditOutlineShapes:de});exports.SankeyGeom=M;exports.sankey=Ae;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let u=require("@graphysdk/react"),S=require("d3-sankey"),O=require("react"),g=require("react/jsx-runtime");var i={kind:"sankeyKind",nodeName:"sankeyNodeName",observationKey:"sankeyObservationKey",nodeKey:"sankeyNodeKey",targetKey:"sankeyTargetKey",x0:"sankeyX0",x1:"sankeyX1",y0:"sankeyY0",y1:"sankeyY1",targetY0:"sankeyTargetY0",targetY1:"sankeyTargetY1"},k=(e,t)=>{const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null},K=e=>{const t=e[i.observationKey],n=e[i.nodeKey],a=k(e,i.x0),o=k(e,i.x1),r=k(e,i.y0),s=k(e,i.y1);if(typeof t!="string"||typeof n!="string"||a===null||o===null||r===null||s===null)return null;switch(e[i.kind]){case"node":return{kind:"node",observation:e,key:t,nodeKey:n,x0:a,x1:o,y0:r,y1:s};case"flow":{const l=k(e,i.targetY0),c=k(e,i.targetY1),d=e[i.targetKey];return l===null||c===null||typeof d!="string"?null:{kind:"flow",observation:e,key:t,nodeKey:n,targetKey:d,x0:a,x1:o,y0:r,y1:s,targetY0:l,targetY1:c}}default:return null}},C=new WeakMap,N=e=>{const t=C.get(e);if(t!==void 0)return t;const n=[],a=[];for(const r of e){const s=K(r);s?.kind==="node"&&n.push(s),s?.kind==="flow"&&a.push(s)}const o={nodes:n,flows:a};return C.set(e,o),o},V=(e,t)=>e.nodeKey===t.nodeKey||e.targetKey===t.nodeKey,I=e=>e*e*(3-2*e),E=(e,t)=>{const n=I(t);return{top:e.y0+(e.targetY0-e.y0)*n,bottom:e.y1+(e.targetY1-e.y1)*n}},W=(e,t)=>{const n=e.x1-e.x0;if(n<=0||t.x<e.x0||t.x>e.x1)return!1;const{top:a,bottom:o}=E(e,(t.x-e.x0)/n);return t.y>=a&&t.y<=o},F=(e,t)=>{const n=c=>c*t.width,a=c=>c*t.height,o=n(e.x0),r=n(e.x1),s=n(e.x0+(e.x1-e.x0)/3),l=n(e.x0+(e.x1-e.x0)*2/3);return[`M${o},${a(e.y0)}`,`C${s},${a(e.y0)} ${l},${a(e.targetY0)} ${r},${a(e.targetY0)}`,`L${r},${a(e.targetY1)}`,`C${l},${a(e.targetY1)} ${s},${a(e.y1)} ${o},${a(e.y1)}`,"Z"].join("")},G=.018,D=.03,H={justify:S.sankeyJustify,left:S.sankeyLeft,right:S.sankeyRight,center:S.sankeyCenter},w=(e,t)=>{const n=B(e);if(n.length===0)return{nodes:[],flows:[]};const a=[...new Set(n.flatMap(r=>[r.source,r.target]))],o=(0,S.sankey)().nodeId(r=>r.key).nodeAlign(H[t]).nodeWidth(G).nodePadding(D).extent([[0,0],[1,1]])({nodes:a.map(r=>({key:r})),links:n.map(r=>({source:r.source,target:r.target,value:r.value,link:r}))});return{nodes:o.nodes.map(r=>({key:r.key,value:r.value??0,x0:p(r.x0),x1:p(r.x1),y0:p(r.y0),y1:p(r.y1)})),flows:o.links.map(r=>{const s=r.source,l=r.target,c=(r.width??0)/2;return{link:r.link,x0:p(s.x1),x1:p(l.x0),y0:p((r.y0??0)-c),y1:p((r.y0??0)+c),targetY0:p((r.y1??0)-c),targetY1:p((r.y1??0)+c)}})}},p=e=>Math.min(1,Math.max(0,e??0)),B=e=>{const t=new Map,n=(a,o)=>{const r=new Set,s=[a];for(;s.length>0;){const l=s.pop();if(l===o)return!0;r.has(l)||(r.add(l),s.push(...t.get(l)??[]))}return!1};return e.filter(a=>t.get(a.source)?.has(a.target)===!0?!0:n(a.target,a.source)?!1:(t.set(a.source,(t.get(a.source)??new Set).add(a.target)),!0))},_=new Set(["node"]),j=["color","alpha"],U=["justify","left","right","center"],X=class extends u.Stat{constructor(...e){super(...e),this.type="sankey",this.computedVariables=_}computeStat({data:e,mapping:t,params:n}){const a=Q(e,t);return a===null?{data:e,mapping:{}}:(Z(e,a),{data:ne(e,a,J(n)),mapping:{node:i.nodeName,...q(t,a)}})}},q=(e,t)=>{const n={};for(const a of j){const o=R(a,e[a],t);o!==null&&(n[a]=o)}return n},R=(e,t,{sourceVariable:n,targetVariable:a})=>{if(t===void 0)return e==="color"?i.nodeKey:null;const o=(0,u.readVariableName)(t);return o===n?i.nodeKey:o===a?i.targetKey:null},z=e=>U.includes(e),J=e=>{const t=e?.align;return z(t)?t:"justify"},L=(e,t)=>e===null?null:e instanceof Date?t.type==="year"?String(e.getUTCFullYear()):e.toISOString():String(e),Z=(e,{valueVariable:t})=>{const n=e.getType(t);if(!(e.size()===0||n==="numeric"))throw new u.UserInputError({code:"INCOMPATIBLE_TYPE",message:`'sankey' stat requires a numeric 'value' (got '${n}' for variable '${t}')`,context:{aesthetic:"value",variableName:t,variableType:n},suggestion:"Map each flow's amount to 'value', declaring the column numeric if it holds whole years."})},Q=(e,t)=>{const n=(0,u.readVariableName)(t.source),a=(0,u.readVariableName)(t.target),o=(0,u.readVariableName)(t.value);return n===null||a===null||o===null||![n,a,o].every(r=>e.hasVariable(r))?null:{sourceVariable:n,targetVariable:a,valueVariable:o}},ee=(e,{sourceVariable:t,targetVariable:n,valueVariable:a})=>{const o=e.getValues(t),r=e.getValues(n),s=e.getValues(a,{type:"numeric"}),l=e.getValueFormat(t),c=e.getValueFormat(n),d=new Map,v=new Map,y=[];return o.forEach((h,m)=>{const b=r[m]??null,f=L(h,l),x=L(b,c);if(f===null||x===null)return;v.set(f,h),v.set(x,b);const P=JSON.stringify([f,x]),Y=d.get(P)??0;d.set(P,Y+1);const A=s[m];typeof A!="number"||!Number.isFinite(A)||A<=0||y.push({source:f,target:x,value:A,row:m,occurrence:Y})}),{links:y,names:v}},$=(e,{sourceVariable:t,targetVariable:n})=>e.getType(t)===e.getType(n),te=(e,t,n,a)=>{const o=e.getType(t.sourceVariable);return $(e,t)?{type:o,values:n.map(r=>a.get(r)??null),valueFormat:e.getValueFormat(t.sourceVariable)}:{type:"categorical",values:[...n]}},re=(e,t,n,a,o)=>e===n.valueVariable?a.nodes.map(r=>r.value):e===n.sourceVariable&&$(t,n)?a.nodes.map(r=>o.get(r.key)??null):null,ne=(e,t,n)=>{const{links:a,names:o}=ee(e,t),r=w(a,n),s=r.nodes.length,l=y=>[...y,...Array.from({length:s},()=>null)],c=e.getVariableNames(),d=Object.fromEntries(c.map(y=>{const h=e.getValues(y),m=r.flows.map(({link:x})=>h[x.row]??null),b=re(y,e,t,r,o),f=b===null?l(m):[...m,...b];return[y,{type:e.getType(y),values:f,valueFormat:e.getValueFormat(y)}]})),v=[...r.flows.map(({link:y})=>y.source),...r.nodes.map(({key:y})=>y)];return new u.Dataset({...d,...ae(r),[i.nodeName]:te(e,t,v,o)})},ae=e=>{const t=e.flows.map(({link:l,...c})=>({[i.kind]:"flow",[i.observationKey]:JSON.stringify(["flow",l.source,l.target,l.occurrence]),[i.nodeKey]:l.source,[i.targetKey]:l.target,[i.x0]:c.x0,[i.x1]:c.x1,[i.y0]:c.y0,[i.y1]:c.y1,[i.targetY0]:c.targetY0,[i.targetY1]:c.targetY1})),n=e.nodes.map(l=>({[i.kind]:"node",[i.observationKey]:JSON.stringify(["node",l.key]),[i.nodeKey]:l.key,[i.targetKey]:l.key,[i.x0]:l.x0,[i.x1]:l.x1,[i.y0]:l.y0,[i.y1]:l.y1,[i.targetY0]:null,[i.targetY1]:null})),a=[...t,...n],o=l=>a.map(c=>c[l]),r=l=>({type:"categorical",values:o(l)}),s=l=>({type:"numeric",values:o(l)});return{[i.kind]:r(i.kind),[i.observationKey]:r(i.observationKey),[i.nodeKey]:r(i.nodeKey),[i.targetKey]:r(i.targetKey),[i.x0]:s(i.x0),[i.x1]:s(i.x1),[i.y0]:s(i.y0),[i.y1]:s(i.y1),[i.targetY0]:s(i.targetY0),[i.targetY1]:s(i.targetY1)}},oe=.4,se=.65,ie=12,le=3,ue={},ce={fill:"paint",fillAlpha:"unitInterval",alpha:"unitInterval",stroke:"color",strokeWidth:"pixels",overpaint:"overpaint"},de={fontFamily:"fontFamily",fontSize:"pixels",fontWeight:"fontWeight",textColor:"color",textOutlineColor:"color",textOutlineWidth:"pixels"},M=class extends u.Geom{constructor(...e){super(...e),this.type="sankey",this.defaultParams={align:"justify"},this.defaultStat=new X,this.aesthetics=[{kind:"data",name:"source",required:!0},{kind:"data",name:"target",required:!0},{kind:"data",name:"value",required:!0},{kind:"data",name:"node"},{kind:"visual",name:"color"},{kind:"visual",name:"alpha"}],this.identityKey={variable:i.observationKey},this.supportedPositions=["identity"],this.supportedCoordTypes=["cartesian"],this.legend={defaultPosition:"none"},this.spatialKind="render-hit-test",this.highlightStrategy="observation-rerender",this.tooltip=[{aes:"node",heading:!0},{aes:"target"},{aes:"value"}],this.styleTarget=(0,u.defineGeomStyleTarget)({observation:{vocabulary:ue,aesthetics:{fill:"color",alpha:"alpha"},rest:{fill:(0,u.token)("geom"),fillAlpha:oe},hovered:{fillAlpha:se}},parts:{node:{vocabulary:ce,aesthetics:{fill:"color",alpha:"alpha"},rest:{fill:(0,u.token)("geom"),fillAlpha:1,alpha:1,stroke:(0,u.token)("graphBackground"),strokeWidth:0}},label:{vocabulary:de,rest:{fontSize:ie,fontWeight:500,textColor:(0,u.token)("textPrimary"),textOutlineColor:(0,u.token)("graphBackground"),textOutlineWidth:le}}}}),this.resolveValueSource=t=>t.value??null,this.validateMapping=({mapping:t,computedVariables:n})=>{if(!n.has("node"))return[{code:"MISSING_STAT_OUTPUT",message:"sankey geom lays its flows out in the 'sankey' stat; remove the layer's stat"}];const a=[..._].filter(s=>t[s]!==void 0).map(s=>({code:"CONFLICTING_STAT_MAPPING",message:`sankey stat computes '${s}' from 'source' and 'target'; remove its mapping`})),o=[(0,u.readVariableName)(t.source),(0,u.readVariableName)(t.target)],r=j.flatMap(s=>{const l=(0,u.readVariableName)(t[s]);return l===null||o.includes(l)?[]:[{code:"UNSUPPORTED_MAPPING",message:`sankey geom scales '${s}' by node; map it to the source or target column rather than '${l}'`}]});return[...a,...r]},this.resolveAnchorPosition=t=>{const n=K(t);if(n===null)return null;if(n.kind==="node")return{x:(n.x0+n.x1)/2,y:1-(n.y0+n.y1)/2};const{top:a,bottom:o}=E(n,.5);return{x:(n.x0+n.x1)/2,y:1-(a+o)/2}}}compile({data:e}){return{data:e,mapping:{}}}},ye=({layer:e,panelRect:t})=>{const{nodes:n,flows:a}=N(e.data),o=s=>s*t.width,r=s=>s*t.height;return[...a.map(s=>({kind:"region",pathData:F(s,t)})),...n.map(s=>({kind:"region",pathData:`M${o(s.x0)},${r(s.y0)}H${o(s.x1)}V${r(s.y1)}H${o(s.x0)}Z`}))]},ge=({flows:e,size:t,source:n,styleReaders:a,hovered:o,shouldAnimateTransitions:r=!1})=>{const s=o===void 0?void 0:"hovered",l=(0,O.useMemo)(()=>e.map(v=>a.get("fill",v.observation,s)??"transparent"),[e,a,s]),{fillFor:c,defs:d}=(0,u.usePaintDefs)({paints:l});return(0,g.jsxs)(g.Fragment,{children:[d,(0,g.jsx)(u.GeomOverpaint,{styleReaders:a,state:s,children:e.map((v,y)=>{const h=l[y],m=a.get("stroke",v.observation,s);return(0,g.jsx)(u.GeomPath,{"data-testid":"sankey-flow",d:F(v,t),source:n,fill:h===void 0?void 0:c(h),opacity:a.get("alpha",v.observation,s),fillOpacity:a.get("fillAlpha",v.observation,s),stroke:m===void 0?void 0:(0,u.toPaintColor)(m),strokeOpacity:a.get("strokeAlpha",v.observation,s),shouldAnimateTransitions:r},v.key)})})]})},ve=6,he=e=>{const t=(e.y0+e.y1)/2;return(e.x0+e.x1)/2<.5?{x:e.x1,y:t,offsetX:ve,textAnchor:"start"}:{x:e.x0,y:t,offsetX:-6,textAnchor:"end"}},me=({nodes:e,valueFormat:t,styleReaders:n,hovered:a})=>{const o=a===void 0?void 0:"hovered",r=n.part("label"),s=(0,u.useGraphLocale)(),l=(0,u.useSceneSelector)(d=>d.config.numberFormat),c=(0,O.useMemo)(()=>(0,u.createValueFormatter)({valueFormat:t,locale:s,numberFormat:l}),[t,s,l]);return(0,g.jsx)("g",{pointerEvents:"none",children:e.map(d=>{const v=d.observation[i.nodeName];if(v==null)return null;const y=he(d),h=r?.get("textColor",d.observation,o),m=r?.get("textOutlineColor",d.observation,o);return(0,g.jsx)("text",{"data-testid":"sankey-label",x:(0,u.toPercent)(y.x),y:(0,u.toPercent)(y.y),dx:y.offsetX,textAnchor:y.textAnchor,dominantBaseline:"central",fontFamily:r?.get("fontFamily",d.observation,o),fontSize:r?.get("fontSize",d.observation,o),fontWeight:r?.get("fontWeight",d.observation,o),fill:h===void 0?void 0:(0,u.toPaintColor)(h),stroke:m===void 0?void 0:(0,u.toPaintColor)(m),strokeWidth:r?.get("textOutlineWidth",d.observation,o),strokeLinejoin:"round",paintOrder:"stroke",children:c(v,d.observation)},d.key)})})},pe=({nodes:e,styleReaders:t,hovered:n,shouldAnimateTransitions:a=!1})=>{const o=n===void 0?void 0:"hovered",r=t.part("node"),s=(0,O.useMemo)(()=>e.map(d=>r?.get("fill",d.observation,o)??"transparent"),[e,r,o]),{fillFor:l,defs:c}=(0,u.usePaintDefs)({paints:s});return(0,g.jsxs)(g.Fragment,{children:[c,(0,g.jsx)(u.GeomOverpaint,{styleReaders:r?.get("overpaint",void 0,o)===void 0?t:r,state:o,children:e.map((d,v)=>{const y=s[v],h=r?.get("stroke",d.observation,o);return(0,g.jsx)(u.GeomRect,{"data-testid":"sankey-node",x:(0,u.toPercent)(d.x0),y:(0,u.toPercent)(d.y0),width:(0,u.toPercent)(d.x1-d.x0),height:(0,u.toPercent)(d.y1-d.y0),fill:y===void 0?void 0:l(y),opacity:r?.get("alpha",d.observation,o),fillOpacity:r?.get("fillAlpha",d.observation,o),stroke:h===void 0?void 0:(0,u.toPaintColor)(h),strokeWidth:r?.get("strokeWidth",d.observation,o),effects:(0,u.readGeomEffects)(t,d.observation,o),shouldAnimateTransitions:a},d.key)})})]})},fe={type:"text"},T=({observations:e,layer:t,size:n,styleReaders:a,hovered:o,shouldAnimateTransitions:r=!1})=>(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(ge,{flows:e.flows,size:n,source:t,styleReaders:a,hovered:o,shouldAnimateTransitions:r}),(0,g.jsx)(pe,{nodes:e.nodes,styleReaders:a,hovered:o,shouldAnimateTransitions:r}),(0,g.jsx)(me,{nodes:e.nodes,valueFormat:t.data.hasVariable(i.nodeName)?t.data.getValueFormat(i.nodeName):fe,styleReaders:a,hovered:o})]}),xe=({layer:e,size:t,styleReaders:n})=>(0,g.jsx)(T,{observations:N(e.data),layer:e,size:t,styleReaders:n}),ke=({layer:e})=>{const{nodes:t,flows:n}=N(e.data),a=[...t].reverse(),o=[...n].reverse();return r=>{const s=a.find(c=>r.x>=c.x0&&r.x<=c.x1&&r.y>=c.y0&&r.y<=c.y1);if(s!==void 0)return{key:s.key};const l=o.find(c=>W(c,r));return l===void 0?null:{key:l.key}}},be=({layer:e,primary:t,size:n,styleReaders:a})=>{const o=N(e.data),r=t.observation;return(0,g.jsx)("g",{"data-testid":"hovered-observations",children:(0,g.jsx)(T,{observations:(0,O.useMemo)(()=>Se(o,r),[o,r]),layer:e,size:n,styleReaders:a,hovered:r})})},Se=(e,t)=>{const n=K(t);if(n===null)return{nodes:[],flows:[]};if(n.kind==="node"){const a=e.flows.filter(r=>V(r,n)),o=new Set(a.flatMap(r=>[r.nodeKey,r.targetKey]));return{nodes:e.nodes.filter(r=>o.has(r.nodeKey)),flows:a}}return{nodes:e.nodes.filter(a=>V(n,a)),flows:[n]}},Ne=({layer:e,size:t,styleReaders:n,shouldAnimateTransitions:a})=>(0,g.jsx)(T,{observations:N(e.data),layer:e,size:t,styleReaders:n,shouldAnimateTransitions:a}),Ae=(0,u.defineGeomRenderer)(new M,{coord:"cartesian",swatchShape:"square",overpaintPlacement:"manual",render:({layer:e,panelRect:t,styleReaders:n,shouldAnimateTransitions:a})=>(0,g.jsx)(Ne,{layer:e,size:t,styleReaders:n,shouldAnimateTransitions:a}),renderHighlight:({layer:e,panelRect:t,styleReaders:n})=>(0,g.jsx)(xe,{layer:e,size:t,styleReaders:n}),renderHover:({layer:e,primary:t,panelRect:n,styleReaders:a})=>(0,g.jsx)(be,{layer:e,primary:t,size:n,styleReaders:a}),renderHoverCompanions:()=>null,hitTest:ke,getEditOutlineShapes:ye});exports.SankeyGeom=M;exports.sankey=Ae;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Dataset as
|
|
2
|
-
import { sankey as
|
|
1
|
+
import { Dataset as B, Geom as U, GeomOverpaint as I, GeomPath as X, GeomRect as j, Stat as R, UserInputError as z, createValueFormatter as q, defineGeomRenderer as J, defineGeomStyleTarget as Z, readGeomEffects as Q, readVariableName as m, toPaintColor as K, toPercent as b, token as N, useGraphLocale as ee, usePaintDefs as M, useSceneSelector as te } from "@graphysdk/react";
|
|
2
|
+
import { sankey as re, sankeyCenter as ne, sankeyJustify as ae, sankeyLeft as oe, sankeyRight as se } from "d3-sankey";
|
|
3
3
|
import { useMemo as T } from "react";
|
|
4
4
|
import { Fragment as Y, jsx as g, jsxs as C } from "react/jsx-runtime";
|
|
5
5
|
var i = {
|
|
@@ -64,18 +64,18 @@ var i = {
|
|
|
64
64
|
flows: a
|
|
65
65
|
};
|
|
66
66
|
return P.set(e, o), o;
|
|
67
|
-
}, _ = (e, t) => e.nodeKey === t.nodeKey || e.targetKey === t.nodeKey,
|
|
68
|
-
const n =
|
|
67
|
+
}, _ = (e, t) => e.nodeKey === t.nodeKey || e.targetKey === t.nodeKey, ie = (e) => e * e * (3 - 2 * e), W = (e, t) => {
|
|
68
|
+
const n = ie(t);
|
|
69
69
|
return {
|
|
70
70
|
top: e.y0 + (e.targetY0 - e.y0) * n,
|
|
71
71
|
bottom: e.y1 + (e.targetY1 - e.y1) * n
|
|
72
72
|
};
|
|
73
|
-
},
|
|
73
|
+
}, le = (e, t) => {
|
|
74
74
|
const n = e.x1 - e.x0;
|
|
75
75
|
if (n <= 0 || t.x < e.x0 || t.x > e.x1) return !1;
|
|
76
|
-
const { top: a, bottom: o } =
|
|
76
|
+
const { top: a, bottom: o } = W(e, (t.x - e.x0) / n);
|
|
77
77
|
return t.y >= a && t.y <= o;
|
|
78
|
-
},
|
|
78
|
+
}, G = (e, t) => {
|
|
79
79
|
const n = (u) => u * t.width, a = (u) => u * t.height, o = n(e.x0), r = n(e.x1), s = n(e.x0 + (e.x1 - e.x0) / 3), l = n(e.x0 + (e.x1 - e.x0) * 2 / 3);
|
|
80
80
|
return [
|
|
81
81
|
`M${o},${a(e.y0)}`,
|
|
@@ -84,18 +84,18 @@ var i = {
|
|
|
84
84
|
`C${l},${a(e.targetY1)} ${s},${a(e.y1)} ${o},${a(e.y1)}`,
|
|
85
85
|
"Z"
|
|
86
86
|
].join("");
|
|
87
|
-
},
|
|
88
|
-
justify:
|
|
89
|
-
left:
|
|
90
|
-
right:
|
|
91
|
-
center:
|
|
92
|
-
},
|
|
93
|
-
const n =
|
|
87
|
+
}, ue = 0.018, ce = 0.03, de = {
|
|
88
|
+
justify: ae,
|
|
89
|
+
left: oe,
|
|
90
|
+
right: se,
|
|
91
|
+
center: ne
|
|
92
|
+
}, ye = (e, t) => {
|
|
93
|
+
const n = ge(e);
|
|
94
94
|
if (n.length === 0) return {
|
|
95
95
|
nodes: [],
|
|
96
96
|
flows: []
|
|
97
97
|
};
|
|
98
|
-
const a = [...new Set(n.flatMap((r) => [r.source, r.target]))], o =
|
|
98
|
+
const a = [...new Set(n.flatMap((r) => [r.source, r.target]))], o = re().nodeId((r) => r.key).nodeAlign(de[t]).nodeWidth(ue).nodePadding(ce).extent([[0, 0], [1, 1]])({
|
|
99
99
|
nodes: a.map((r) => ({ key: r })),
|
|
100
100
|
links: n.map((r) => ({
|
|
101
101
|
source: r.source,
|
|
@@ -126,7 +126,7 @@ var i = {
|
|
|
126
126
|
};
|
|
127
127
|
})
|
|
128
128
|
};
|
|
129
|
-
}, p = (e) => Math.min(1, Math.max(0, e ?? 0)),
|
|
129
|
+
}, p = (e) => Math.min(1, Math.max(0, e ?? 0)), ge = (e) => {
|
|
130
130
|
const t = /* @__PURE__ */ new Map(), n = (a, o) => {
|
|
131
131
|
const r = /* @__PURE__ */ new Set(), s = [a];
|
|
132
132
|
for (; s.length > 0; ) {
|
|
@@ -137,46 +137,46 @@ var i = {
|
|
|
137
137
|
return !1;
|
|
138
138
|
};
|
|
139
139
|
return e.filter((a) => t.get(a.source)?.has(a.target) === !0 ? !0 : n(a.target, a.source) ? !1 : (t.set(a.source, (t.get(a.source) ?? /* @__PURE__ */ new Set()).add(a.target)), !0));
|
|
140
|
-
}, D = /* @__PURE__ */ new Set(["node"]),
|
|
140
|
+
}, D = /* @__PURE__ */ new Set(["node"]), H = ["color", "alpha"], ve = [
|
|
141
141
|
"justify",
|
|
142
142
|
"left",
|
|
143
143
|
"right",
|
|
144
144
|
"center"
|
|
145
|
-
],
|
|
145
|
+
], he = class extends R {
|
|
146
146
|
constructor(...e) {
|
|
147
147
|
super(...e), this.type = "sankey", this.computedVariables = D;
|
|
148
148
|
}
|
|
149
149
|
computeStat({ data: e, mapping: t, params: n }) {
|
|
150
|
-
const a =
|
|
150
|
+
const a = be(e, t);
|
|
151
151
|
return a === null ? {
|
|
152
152
|
data: e,
|
|
153
153
|
mapping: {}
|
|
154
|
-
} : (
|
|
155
|
-
data:
|
|
154
|
+
} : (ke(e, a), {
|
|
155
|
+
data: Oe(e, a, xe(n)),
|
|
156
156
|
mapping: {
|
|
157
157
|
node: i.nodeName,
|
|
158
|
-
...
|
|
158
|
+
...pe(t, a)
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
},
|
|
162
|
+
}, pe = (e, t) => {
|
|
163
163
|
const n = {};
|
|
164
|
-
for (const a of
|
|
165
|
-
const o =
|
|
164
|
+
for (const a of H) {
|
|
165
|
+
const o = me(a, e[a], t);
|
|
166
166
|
o !== null && (n[a] = o);
|
|
167
167
|
}
|
|
168
168
|
return n;
|
|
169
|
-
},
|
|
169
|
+
}, me = (e, t, { sourceVariable: n, targetVariable: a }) => {
|
|
170
170
|
if (t === void 0) return e === "color" ? i.nodeKey : null;
|
|
171
171
|
const o = m(t);
|
|
172
172
|
return o === n ? i.nodeKey : o === a ? i.targetKey : null;
|
|
173
|
-
},
|
|
173
|
+
}, fe = (e) => ve.includes(e), xe = (e) => {
|
|
174
174
|
const t = e?.align;
|
|
175
|
-
return
|
|
176
|
-
}, $ = (e, t) => e === null ? null : e instanceof Date ? t.type === "year" ? String(e.getUTCFullYear()) : e.toISOString() : String(e),
|
|
175
|
+
return fe(t) ? t : "justify";
|
|
176
|
+
}, $ = (e, t) => e === null ? null : e instanceof Date ? t.type === "year" ? String(e.getUTCFullYear()) : e.toISOString() : String(e), ke = (e, { valueVariable: t }) => {
|
|
177
177
|
const n = e.getType(t);
|
|
178
178
|
if (!(e.size() === 0 || n === "numeric"))
|
|
179
|
-
throw new
|
|
179
|
+
throw new z({
|
|
180
180
|
code: "INCOMPATIBLE_TYPE",
|
|
181
181
|
message: `'sankey' stat requires a numeric 'value' (got '${n}' for variable '${t}')`,
|
|
182
182
|
context: {
|
|
@@ -186,7 +186,7 @@ var i = {
|
|
|
186
186
|
},
|
|
187
187
|
suggestion: "Map each flow's amount to 'value', declaring the column numeric if it holds whole years."
|
|
188
188
|
});
|
|
189
|
-
},
|
|
189
|
+
}, be = (e, t) => {
|
|
190
190
|
const n = m(t.source), a = m(t.target), o = m(t.value);
|
|
191
191
|
return n === null || a === null || o === null || ![
|
|
192
192
|
n,
|
|
@@ -197,27 +197,27 @@ var i = {
|
|
|
197
197
|
targetVariable: a,
|
|
198
198
|
valueVariable: o
|
|
199
199
|
};
|
|
200
|
-
},
|
|
201
|
-
const o = e.getValues(t), r = e.getValues(n), s = e.getValues(a, { type: "numeric" }), l = e.getValueFormat(t), u = e.getValueFormat(n), c = /* @__PURE__ */ new Map(),
|
|
200
|
+
}, Se = (e, { sourceVariable: t, targetVariable: n, valueVariable: a }) => {
|
|
201
|
+
const o = e.getValues(t), r = e.getValues(n), s = e.getValues(a, { type: "numeric" }), l = e.getValueFormat(t), u = e.getValueFormat(n), c = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), d = [];
|
|
202
202
|
return o.forEach((v, h) => {
|
|
203
203
|
const S = r[h] ?? null, f = $(v, l), x = $(S, u);
|
|
204
204
|
if (f === null || x === null) return;
|
|
205
|
-
|
|
205
|
+
y.set(f, v), y.set(x, S);
|
|
206
206
|
const F = JSON.stringify([f, x]), V = c.get(F) ?? 0;
|
|
207
207
|
c.set(F, V + 1);
|
|
208
|
-
const
|
|
209
|
-
typeof
|
|
208
|
+
const O = s[h];
|
|
209
|
+
typeof O != "number" || !Number.isFinite(O) || O <= 0 || d.push({
|
|
210
210
|
source: f,
|
|
211
211
|
target: x,
|
|
212
|
-
value:
|
|
212
|
+
value: O,
|
|
213
213
|
row: h,
|
|
214
214
|
occurrence: V
|
|
215
215
|
});
|
|
216
216
|
}), {
|
|
217
|
-
links:
|
|
218
|
-
names:
|
|
217
|
+
links: d,
|
|
218
|
+
names: y
|
|
219
219
|
};
|
|
220
|
-
}, w = (e, { sourceVariable: t, targetVariable: n }) => e.getType(t) === e.getType(n),
|
|
220
|
+
}, w = (e, { sourceVariable: t, targetVariable: n }) => e.getType(t) === e.getType(n), Ne = (e, t, n, a) => {
|
|
221
221
|
const o = e.getType(t.sourceVariable);
|
|
222
222
|
return w(e, t) ? {
|
|
223
223
|
type: o,
|
|
@@ -227,21 +227,21 @@ var i = {
|
|
|
227
227
|
type: "categorical",
|
|
228
228
|
values: [...n]
|
|
229
229
|
};
|
|
230
|
-
},
|
|
231
|
-
const { links: a, names: o } =
|
|
232
|
-
const v = e.getValues(
|
|
233
|
-
return [
|
|
234
|
-
type: e.getType(
|
|
230
|
+
}, Ae = (e, t, n, a, o) => e === n.valueVariable ? a.nodes.map((r) => r.value) : e === n.sourceVariable && w(t, n) ? a.nodes.map((r) => o.get(r.key) ?? null) : null, Oe = (e, t, n) => {
|
|
231
|
+
const { links: a, names: o } = Se(e, t), r = ye(a, n), s = r.nodes.length, l = (d) => [...d, ...Array.from({ length: s }, () => null)], u = e.getVariableNames(), c = Object.fromEntries(u.map((d) => {
|
|
232
|
+
const v = e.getValues(d), h = r.flows.map(({ link: x }) => v[x.row] ?? null), S = Ae(d, e, t, r, o), f = S === null ? l(h) : [...h, ...S];
|
|
233
|
+
return [d, {
|
|
234
|
+
type: e.getType(d),
|
|
235
235
|
values: f,
|
|
236
|
-
valueFormat: e.getValueFormat(
|
|
236
|
+
valueFormat: e.getValueFormat(d)
|
|
237
237
|
}];
|
|
238
|
-
})),
|
|
239
|
-
return new
|
|
238
|
+
})), y = [...r.flows.map(({ link: d }) => d.source), ...r.nodes.map(({ key: d }) => d)];
|
|
239
|
+
return new B({
|
|
240
240
|
...c,
|
|
241
|
-
...
|
|
242
|
-
[i.nodeName]:
|
|
241
|
+
...Ke(r),
|
|
242
|
+
[i.nodeName]: Ne(e, t, y, o)
|
|
243
243
|
});
|
|
244
|
-
},
|
|
244
|
+
}, Ke = (e) => {
|
|
245
245
|
const t = e.flows.map(({ link: l, ...u }) => ({
|
|
246
246
|
[i.kind]: "flow",
|
|
247
247
|
[i.observationKey]: JSON.stringify([
|
|
@@ -288,22 +288,23 @@ var i = {
|
|
|
288
288
|
[i.targetY0]: s(i.targetY0),
|
|
289
289
|
[i.targetY1]: s(i.targetY1)
|
|
290
290
|
};
|
|
291
|
-
},
|
|
291
|
+
}, Te = 0.4, Ye = 0.65, Ce = 12, Le = 3, Ee = {}, Fe = {
|
|
292
292
|
fill: "paint",
|
|
293
293
|
fillAlpha: "unitInterval",
|
|
294
294
|
alpha: "unitInterval",
|
|
295
295
|
stroke: "color",
|
|
296
|
-
strokeWidth: "pixels"
|
|
297
|
-
|
|
296
|
+
strokeWidth: "pixels",
|
|
297
|
+
overpaint: "overpaint"
|
|
298
|
+
}, Ve = {
|
|
298
299
|
fontFamily: "fontFamily",
|
|
299
300
|
fontSize: "pixels",
|
|
300
301
|
fontWeight: "fontWeight",
|
|
301
302
|
textColor: "color",
|
|
302
303
|
textOutlineColor: "color",
|
|
303
304
|
textOutlineWidth: "pixels"
|
|
304
|
-
},
|
|
305
|
+
}, Pe = class extends U {
|
|
305
306
|
constructor(...e) {
|
|
306
|
-
super(...e), this.type = "sankey", this.defaultParams = { align: "justify" }, this.defaultStat = new
|
|
307
|
+
super(...e), this.type = "sankey", this.defaultParams = { align: "justify" }, this.defaultStat = new he(), this.aesthetics = [
|
|
307
308
|
{
|
|
308
309
|
kind: "data",
|
|
309
310
|
name: "source",
|
|
@@ -338,22 +339,22 @@ var i = {
|
|
|
338
339
|
},
|
|
339
340
|
{ aes: "target" },
|
|
340
341
|
{ aes: "value" }
|
|
341
|
-
], this.styleTarget =
|
|
342
|
+
], this.styleTarget = Z({
|
|
342
343
|
observation: {
|
|
343
|
-
vocabulary:
|
|
344
|
+
vocabulary: Ee,
|
|
344
345
|
aesthetics: {
|
|
345
346
|
fill: "color",
|
|
346
347
|
alpha: "alpha"
|
|
347
348
|
},
|
|
348
349
|
rest: {
|
|
349
350
|
fill: N("geom"),
|
|
350
|
-
fillAlpha:
|
|
351
|
+
fillAlpha: Te
|
|
351
352
|
},
|
|
352
|
-
hovered: { fillAlpha:
|
|
353
|
+
hovered: { fillAlpha: Ye }
|
|
353
354
|
},
|
|
354
355
|
parts: {
|
|
355
356
|
node: {
|
|
356
|
-
vocabulary:
|
|
357
|
+
vocabulary: Fe,
|
|
357
358
|
aesthetics: {
|
|
358
359
|
fill: "color",
|
|
359
360
|
alpha: "alpha"
|
|
@@ -367,13 +368,13 @@ var i = {
|
|
|
367
368
|
}
|
|
368
369
|
},
|
|
369
370
|
label: {
|
|
370
|
-
vocabulary:
|
|
371
|
+
vocabulary: Ve,
|
|
371
372
|
rest: {
|
|
372
|
-
fontSize:
|
|
373
|
+
fontSize: Ce,
|
|
373
374
|
fontWeight: 500,
|
|
374
375
|
textColor: N("textPrimary"),
|
|
375
376
|
textOutlineColor: N("graphBackground"),
|
|
376
|
-
textOutlineWidth:
|
|
377
|
+
textOutlineWidth: Le
|
|
377
378
|
}
|
|
378
379
|
}
|
|
379
380
|
}
|
|
@@ -385,7 +386,7 @@ var i = {
|
|
|
385
386
|
const a = [...D].filter((s) => t[s] !== void 0).map((s) => ({
|
|
386
387
|
code: "CONFLICTING_STAT_MAPPING",
|
|
387
388
|
message: `sankey stat computes '${s}' from 'source' and 'target'; remove its mapping`
|
|
388
|
-
})), o = [m(t.source), m(t.target)], r =
|
|
389
|
+
})), o = [m(t.source), m(t.target)], r = H.flatMap((s) => {
|
|
389
390
|
const l = m(t[s]);
|
|
390
391
|
return l === null || o.includes(l) ? [] : [{
|
|
391
392
|
code: "UNSUPPORTED_MAPPING",
|
|
@@ -400,7 +401,7 @@ var i = {
|
|
|
400
401
|
x: (n.x0 + n.x1) / 2,
|
|
401
402
|
y: 1 - (n.y0 + n.y1) / 2
|
|
402
403
|
};
|
|
403
|
-
const { top: a, bottom: o } =
|
|
404
|
+
const { top: a, bottom: o } = W(n, 0.5);
|
|
404
405
|
return {
|
|
405
406
|
x: (n.x0 + n.x1) / 2,
|
|
406
407
|
y: 1 - (a + o) / 2
|
|
@@ -413,41 +414,45 @@ var i = {
|
|
|
413
414
|
mapping: {}
|
|
414
415
|
};
|
|
415
416
|
}
|
|
416
|
-
},
|
|
417
|
+
}, _e = ({ layer: e, panelRect: t }) => {
|
|
417
418
|
const { nodes: n, flows: a } = A(e.data), o = (s) => s * t.width, r = (s) => s * t.height;
|
|
418
419
|
return [...a.map((s) => ({
|
|
419
420
|
kind: "region",
|
|
420
|
-
pathData:
|
|
421
|
+
pathData: G(s, t)
|
|
421
422
|
})), ...n.map((s) => ({
|
|
422
423
|
kind: "region",
|
|
423
424
|
pathData: `M${o(s.x0)},${r(s.y0)}H${o(s.x1)}V${r(s.y1)}H${o(s.x0)}Z`
|
|
424
425
|
}))];
|
|
425
|
-
},
|
|
426
|
-
const s = o
|
|
426
|
+
}, $e = ({ flows: e, size: t, source: n, styleReaders: a, hovered: o, shouldAnimateTransitions: r = !1 }) => {
|
|
427
|
+
const s = o === void 0 ? void 0 : "hovered", l = T(() => e.map((y) => a.get("fill", y.observation, s) ?? "transparent"), [
|
|
427
428
|
e,
|
|
428
429
|
a,
|
|
429
430
|
s
|
|
430
|
-
]), { fillFor: u, defs: c } =
|
|
431
|
-
return /* @__PURE__ */ C(Y, { children: [c,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
d
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
431
|
+
]), { fillFor: u, defs: c } = M({ paints: l });
|
|
432
|
+
return /* @__PURE__ */ C(Y, { children: [c, /* @__PURE__ */ g(I, {
|
|
433
|
+
styleReaders: a,
|
|
434
|
+
state: s,
|
|
435
|
+
children: e.map((y, d) => {
|
|
436
|
+
const v = l[d], h = a.get("stroke", y.observation, s);
|
|
437
|
+
return /* @__PURE__ */ g(X, {
|
|
438
|
+
"data-testid": "sankey-flow",
|
|
439
|
+
d: G(y, t),
|
|
440
|
+
source: n,
|
|
441
|
+
fill: v === void 0 ? void 0 : u(v),
|
|
442
|
+
opacity: a.get("alpha", y.observation, s),
|
|
443
|
+
fillOpacity: a.get("fillAlpha", y.observation, s),
|
|
444
|
+
stroke: h === void 0 ? void 0 : K(h),
|
|
445
|
+
strokeOpacity: a.get("strokeAlpha", y.observation, s),
|
|
446
|
+
shouldAnimateTransitions: r
|
|
447
|
+
}, y.key);
|
|
448
|
+
})
|
|
444
449
|
})] });
|
|
445
|
-
},
|
|
450
|
+
}, Ie = 6, Me = (e) => {
|
|
446
451
|
const t = (e.y0 + e.y1) / 2;
|
|
447
452
|
return (e.x0 + e.x1) / 2 < 0.5 ? {
|
|
448
453
|
x: e.x1,
|
|
449
454
|
y: t,
|
|
450
|
-
offsetX:
|
|
455
|
+
offsetX: Ie,
|
|
451
456
|
textAnchor: "start"
|
|
452
457
|
} : {
|
|
453
458
|
x: e.x0,
|
|
@@ -455,8 +460,8 @@ var i = {
|
|
|
455
460
|
offsetX: -6,
|
|
456
461
|
textAnchor: "end"
|
|
457
462
|
};
|
|
458
|
-
},
|
|
459
|
-
const o = a
|
|
463
|
+
}, We = ({ nodes: e, valueFormat: t, styleReaders: n, hovered: a }) => {
|
|
464
|
+
const o = a === void 0 ? void 0 : "hovered", r = n.part("label"), s = ee(), l = te((c) => c.config.numberFormat), u = T(() => q({
|
|
460
465
|
valueFormat: t,
|
|
461
466
|
locale: s,
|
|
462
467
|
numberFormat: l
|
|
@@ -468,97 +473,102 @@ var i = {
|
|
|
468
473
|
return /* @__PURE__ */ g("g", {
|
|
469
474
|
pointerEvents: "none",
|
|
470
475
|
children: e.map((c) => {
|
|
471
|
-
const
|
|
472
|
-
if (
|
|
473
|
-
const
|
|
476
|
+
const y = c.observation[i.nodeName];
|
|
477
|
+
if (y == null) return null;
|
|
478
|
+
const d = Me(c), v = r?.get("textColor", c.observation, o), h = r?.get("textOutlineColor", c.observation, o);
|
|
474
479
|
return /* @__PURE__ */ g("text", {
|
|
475
480
|
"data-testid": "sankey-label",
|
|
476
|
-
x: b(
|
|
477
|
-
y: b(
|
|
478
|
-
dx:
|
|
479
|
-
textAnchor:
|
|
481
|
+
x: b(d.x),
|
|
482
|
+
y: b(d.y),
|
|
483
|
+
dx: d.offsetX,
|
|
484
|
+
textAnchor: d.textAnchor,
|
|
480
485
|
dominantBaseline: "central",
|
|
481
486
|
fontFamily: r?.get("fontFamily", c.observation, o),
|
|
482
487
|
fontSize: r?.get("fontSize", c.observation, o),
|
|
483
488
|
fontWeight: r?.get("fontWeight", c.observation, o),
|
|
484
|
-
fill: v === void 0 ? void 0 :
|
|
485
|
-
stroke: h === void 0 ? void 0 :
|
|
489
|
+
fill: v === void 0 ? void 0 : K(v),
|
|
490
|
+
stroke: h === void 0 ? void 0 : K(h),
|
|
486
491
|
strokeWidth: r?.get("textOutlineWidth", c.observation, o),
|
|
487
492
|
strokeLinejoin: "round",
|
|
488
493
|
paintOrder: "stroke",
|
|
489
|
-
children: u(
|
|
494
|
+
children: u(y, c.observation)
|
|
490
495
|
}, c.key);
|
|
491
496
|
})
|
|
492
497
|
});
|
|
493
|
-
},
|
|
494
|
-
const o = n
|
|
498
|
+
}, Ge = ({ nodes: e, styleReaders: t, hovered: n, shouldAnimateTransitions: a = !1 }) => {
|
|
499
|
+
const o = n === void 0 ? void 0 : "hovered", r = t.part("node"), s = T(() => e.map((c) => r?.get("fill", c.observation, o) ?? "transparent"), [
|
|
495
500
|
e,
|
|
496
501
|
r,
|
|
497
502
|
o
|
|
498
|
-
]), { fillFor: l, defs: u } =
|
|
499
|
-
return /* @__PURE__ */ C(Y, { children: [u,
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
503
|
+
]), { fillFor: l, defs: u } = M({ paints: s });
|
|
504
|
+
return /* @__PURE__ */ C(Y, { children: [u, /* @__PURE__ */ g(I, {
|
|
505
|
+
styleReaders: r?.get("overpaint", void 0, o) === void 0 ? t : r,
|
|
506
|
+
state: o,
|
|
507
|
+
children: e.map((c, y) => {
|
|
508
|
+
const d = s[y], v = r?.get("stroke", c.observation, o);
|
|
509
|
+
return /* @__PURE__ */ g(j, {
|
|
510
|
+
"data-testid": "sankey-node",
|
|
511
|
+
x: b(c.x0),
|
|
512
|
+
y: b(c.y0),
|
|
513
|
+
width: b(c.x1 - c.x0),
|
|
514
|
+
height: b(c.y1 - c.y0),
|
|
515
|
+
fill: d === void 0 ? void 0 : l(d),
|
|
516
|
+
opacity: r?.get("alpha", c.observation, o),
|
|
517
|
+
fillOpacity: r?.get("fillAlpha", c.observation, o),
|
|
518
|
+
stroke: v === void 0 ? void 0 : K(v),
|
|
519
|
+
strokeWidth: r?.get("strokeWidth", c.observation, o),
|
|
520
|
+
effects: Q(t, c.observation, o),
|
|
521
|
+
shouldAnimateTransitions: a
|
|
522
|
+
}, c.key);
|
|
523
|
+
})
|
|
514
524
|
})] });
|
|
515
|
-
},
|
|
516
|
-
/* @__PURE__ */ g(
|
|
525
|
+
}, De = { type: "text" }, E = ({ observations: e, layer: t, size: n, styleReaders: a, hovered: o, shouldAnimateTransitions: r = !1 }) => /* @__PURE__ */ C(Y, { children: [
|
|
526
|
+
/* @__PURE__ */ g($e, {
|
|
517
527
|
flows: e.flows,
|
|
518
528
|
size: n,
|
|
519
529
|
source: t,
|
|
520
530
|
styleReaders: a,
|
|
521
|
-
|
|
531
|
+
hovered: o,
|
|
522
532
|
shouldAnimateTransitions: r
|
|
523
533
|
}),
|
|
524
|
-
/* @__PURE__ */ g(
|
|
534
|
+
/* @__PURE__ */ g(Ge, {
|
|
525
535
|
nodes: e.nodes,
|
|
526
536
|
styleReaders: a,
|
|
527
|
-
|
|
537
|
+
hovered: o,
|
|
528
538
|
shouldAnimateTransitions: r
|
|
529
539
|
}),
|
|
530
|
-
/* @__PURE__ */ g(
|
|
540
|
+
/* @__PURE__ */ g(We, {
|
|
531
541
|
nodes: e.nodes,
|
|
532
|
-
valueFormat: t.data.hasVariable(i.nodeName) ? t.data.getValueFormat(i.nodeName) :
|
|
542
|
+
valueFormat: t.data.hasVariable(i.nodeName) ? t.data.getValueFormat(i.nodeName) : De,
|
|
533
543
|
styleReaders: a,
|
|
534
|
-
|
|
544
|
+
hovered: o
|
|
535
545
|
})
|
|
536
|
-
] }),
|
|
546
|
+
] }), He = ({ layer: e, size: t, styleReaders: n }) => /* @__PURE__ */ g(E, {
|
|
537
547
|
observations: A(e.data),
|
|
538
548
|
layer: e,
|
|
539
549
|
size: t,
|
|
540
550
|
styleReaders: n
|
|
541
|
-
}),
|
|
551
|
+
}), we = ({ layer: e }) => {
|
|
542
552
|
const { nodes: t, flows: n } = A(e.data), a = [...t].reverse(), o = [...n].reverse();
|
|
543
553
|
return (r) => {
|
|
544
554
|
const s = a.find((u) => r.x >= u.x0 && r.x <= u.x1 && r.y >= u.y0 && r.y <= u.y1);
|
|
545
555
|
if (s !== void 0) return { key: s.key };
|
|
546
|
-
const l = o.find((u) =>
|
|
556
|
+
const l = o.find((u) => le(u, r));
|
|
547
557
|
return l === void 0 ? null : { key: l.key };
|
|
548
558
|
};
|
|
549
|
-
},
|
|
559
|
+
}, Be = ({ layer: e, primary: t, size: n, styleReaders: a }) => {
|
|
550
560
|
const o = A(e.data), r = t.observation;
|
|
551
561
|
return /* @__PURE__ */ g("g", {
|
|
552
562
|
"data-testid": "hovered-observations",
|
|
553
563
|
children: /* @__PURE__ */ g(E, {
|
|
554
|
-
observations: T(() =>
|
|
564
|
+
observations: T(() => Ue(o, r), [o, r]),
|
|
555
565
|
layer: e,
|
|
556
566
|
size: n,
|
|
557
567
|
styleReaders: a,
|
|
558
|
-
|
|
568
|
+
hovered: r
|
|
559
569
|
})
|
|
560
570
|
});
|
|
561
|
-
},
|
|
571
|
+
}, Ue = (e, t) => {
|
|
562
572
|
const n = L(t);
|
|
563
573
|
if (n === null) return {
|
|
564
574
|
nodes: [],
|
|
@@ -575,37 +585,38 @@ var i = {
|
|
|
575
585
|
nodes: e.nodes.filter((a) => _(n, a)),
|
|
576
586
|
flows: [n]
|
|
577
587
|
};
|
|
578
|
-
},
|
|
588
|
+
}, Xe = ({ layer: e, size: t, styleReaders: n, shouldAnimateTransitions: a }) => /* @__PURE__ */ g(E, {
|
|
579
589
|
observations: A(e.data),
|
|
580
590
|
layer: e,
|
|
581
591
|
size: t,
|
|
582
592
|
styleReaders: n,
|
|
583
593
|
shouldAnimateTransitions: a
|
|
584
|
-
}),
|
|
594
|
+
}), Je = J(new Pe(), {
|
|
585
595
|
coord: "cartesian",
|
|
586
596
|
swatchShape: "square",
|
|
587
|
-
|
|
597
|
+
overpaintPlacement: "manual",
|
|
598
|
+
render: ({ layer: e, panelRect: t, styleReaders: n, shouldAnimateTransitions: a }) => /* @__PURE__ */ g(Xe, {
|
|
588
599
|
layer: e,
|
|
589
600
|
size: t,
|
|
590
601
|
styleReaders: n,
|
|
591
602
|
shouldAnimateTransitions: a
|
|
592
603
|
}),
|
|
593
|
-
renderHighlight: ({ layer: e, panelRect: t, styleReaders: n }) => /* @__PURE__ */ g(
|
|
604
|
+
renderHighlight: ({ layer: e, panelRect: t, styleReaders: n }) => /* @__PURE__ */ g(He, {
|
|
594
605
|
layer: e,
|
|
595
606
|
size: t,
|
|
596
607
|
styleReaders: n
|
|
597
608
|
}),
|
|
598
|
-
renderHover: ({ layer: e, primary: t, panelRect: n, styleReaders: a }) => /* @__PURE__ */ g(
|
|
609
|
+
renderHover: ({ layer: e, primary: t, panelRect: n, styleReaders: a }) => /* @__PURE__ */ g(Be, {
|
|
599
610
|
layer: e,
|
|
600
611
|
primary: t,
|
|
601
612
|
size: n,
|
|
602
613
|
styleReaders: a
|
|
603
614
|
}),
|
|
604
615
|
renderHoverCompanions: () => null,
|
|
605
|
-
hitTest:
|
|
606
|
-
getEditOutlineShapes:
|
|
616
|
+
hitTest: we,
|
|
617
|
+
getEditOutlineShapes: _e
|
|
607
618
|
});
|
|
608
619
|
export {
|
|
609
|
-
|
|
610
|
-
|
|
620
|
+
Pe as SankeyGeom,
|
|
621
|
+
Je as sankey
|
|
611
622
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GeomStyleReaders, SceneLayer } from '@graphysdk/react';
|
|
1
|
+
import { GeomStyleReaders, Observation, SceneLayer } from '@graphysdk/react';
|
|
2
2
|
import { SankeyFlowObservation } from '../../utils/read-sankey';
|
|
3
3
|
export interface SankeyFlowsProps {
|
|
4
4
|
flows: readonly SankeyFlowObservation[];
|
|
@@ -10,8 +10,9 @@ export interface SankeyFlowsProps {
|
|
|
10
10
|
/** The layer the ribbons are drawn from, so a resize redraws them in place and only new data morphs them. */
|
|
11
11
|
source: SceneLayer;
|
|
12
12
|
styleReaders: GeomStyleReaders;
|
|
13
|
-
|
|
13
|
+
/** The observation under the pointer: paints in the `hovered` state. */
|
|
14
|
+
hovered?: Observation;
|
|
14
15
|
shouldAnimateTransitions?: boolean;
|
|
15
16
|
}
|
|
16
|
-
/** Each flow as a filled ribbon, painted through the observations' readers. */
|
|
17
|
-
export declare const SankeyFlows: ({ flows, size, source, styleReaders,
|
|
17
|
+
/** Each flow as a filled ribbon, painted through the observations' readers, under the geom's overpaint. */
|
|
18
|
+
export declare const SankeyFlows: ({ flows, size, source, styleReaders, hovered, shouldAnimateTransitions, }: SankeyFlowsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { GeomStyleReaders, ValueFormat } from '@graphysdk/react';
|
|
1
|
+
import { GeomStyleReaders, Observation, ValueFormat } from '@graphysdk/react';
|
|
2
2
|
import { SankeyNodeObservation } from '../../utils/read-sankey';
|
|
3
3
|
export interface SankeyLabelsProps {
|
|
4
4
|
nodes: readonly SankeyNodeObservation[];
|
|
5
5
|
/** The node names' format. */
|
|
6
6
|
valueFormat: ValueFormat;
|
|
7
7
|
styleReaders: GeomStyleReaders;
|
|
8
|
-
|
|
8
|
+
/** The observation under the pointer: paints in the `hovered` state. */
|
|
9
|
+
hovered?: Observation;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
12
|
* Each node's name beside it, painted through the `label` part's readers. The outline, in the background's color
|
|
12
13
|
* by default, keeps a name legible where it crosses a flow.
|
|
13
14
|
*/
|
|
14
|
-
export declare const SankeyLabels: ({ nodes, valueFormat, styleReaders,
|
|
15
|
+
export declare const SankeyLabels: ({ nodes, valueFormat, styleReaders, hovered }: SankeyLabelsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { GeomStyleReaders } from '@graphysdk/react';
|
|
1
|
+
import { GeomStyleReaders, Observation } from '@graphysdk/react';
|
|
2
2
|
import { SankeyNodeObservation } from '../../utils/read-sankey';
|
|
3
3
|
export interface SankeyNodesProps {
|
|
4
4
|
nodes: readonly SankeyNodeObservation[];
|
|
5
5
|
styleReaders: GeomStyleReaders;
|
|
6
|
-
|
|
6
|
+
/** The observation under the pointer: paints in the `hovered` state. */
|
|
7
|
+
hovered?: Observation;
|
|
7
8
|
shouldAnimateTransitions?: boolean;
|
|
8
9
|
}
|
|
9
|
-
/** Each node as its box, painted through the `node` part's readers. */
|
|
10
|
-
export declare const SankeyNodes: ({ nodes, styleReaders,
|
|
10
|
+
/** Each node as its box, painted through the `node` part's readers, under the part's overpaint or else the geom's. */
|
|
11
|
+
export declare const SankeyNodes: ({ nodes, styleReaders, hovered, shouldAnimateTransitions }: SankeyNodesProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GeomStyleReaders, SceneLayer } from '@graphysdk/react';
|
|
1
|
+
import { GeomStyleReaders, Observation, SceneLayer } from '@graphysdk/react';
|
|
2
2
|
import { SankeyObservations } from '../../utils/read-sankey';
|
|
3
3
|
export interface SankeyPaintProps {
|
|
4
4
|
observations: SankeyObservations;
|
|
@@ -9,8 +9,9 @@ export interface SankeyPaintProps {
|
|
|
9
9
|
height: number;
|
|
10
10
|
};
|
|
11
11
|
styleReaders: GeomStyleReaders;
|
|
12
|
-
|
|
12
|
+
/** The observation under the pointer: paints in the `hovered` state. */
|
|
13
|
+
hovered?: Observation;
|
|
13
14
|
shouldAnimateTransitions?: boolean;
|
|
14
15
|
}
|
|
15
|
-
/** The flows, the nodes over their ends, and the names over both. */
|
|
16
|
-
export declare const SankeyPaint: ({ observations, layer, size, styleReaders,
|
|
16
|
+
/** The flows, the nodes over their ends, and the names over both; the overpaint covers the flows and the nodes. */
|
|
17
|
+
export declare const SankeyPaint: ({ observations, layer, size, styleReaders, hovered, shouldAnimateTransitions, }: SankeyPaintProps) => import("react/jsx-runtime").JSX.Element;
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"flow",
|
|
15
15
|
"alluvial"
|
|
16
16
|
],
|
|
17
|
-
"version": "0.1.
|
|
17
|
+
"version": "0.1.1-beta.1792404455940",
|
|
18
18
|
"type": "module",
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": "^19.0.0",
|
|
39
|
-
"@graphysdk/react": "^1.9.0-beta.
|
|
39
|
+
"@graphysdk/react": "^1.9.0-beta.1792404455940"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@testing-library/react": "^16.3.1",
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"vite": "^8.1.5",
|
|
50
50
|
"vite-plugin-dts": "^4.5.4",
|
|
51
51
|
"vitest": "^4.1.11",
|
|
52
|
-
"@graphysdk/
|
|
53
|
-
"@graphysdk/
|
|
54
|
-
"@graphytools/eslint-config": "0.0.1",
|
|
52
|
+
"@graphysdk/react": "1.9.0-beta.1792404455940",
|
|
53
|
+
"@graphysdk/viz-engine": "1.9.0-beta.1792404455940",
|
|
55
54
|
"@graphytools/typescript-config": "0.0.1",
|
|
56
|
-
"@graphytools/vitest-config": "1.0.0"
|
|
55
|
+
"@graphytools/vitest-config": "1.0.0",
|
|
56
|
+
"@graphytools/eslint-config": "0.0.1"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|