SVG-based sidebar widget displaying immediate family relationships (parents, siblings, spouses, children) with compact card layout, multi-spouse routing, wrapped rows, and ancestor/descendant indicators.
2 lines
23 KiB
JavaScript
2 lines
23 KiB
JavaScript
!function(){"use strict";function t(t,s,o){const i=new Map;for(const n of t)i.set(n.id,n);const a=o.cardWidth,c=o.cardHeight,u=o.horizontalSpacing,l=o.verticalSpacing;o.targetWidth;const h=function(t,n){const e=new Map;e.set(n,0);const r=[n],s=new Set([n]);for(;r.length>0;){const n=r.shift(),o=e.get(n),i=t.get(n);if(i){for(const n of i.rels.spouses||[])!s.has(n)&&t.has(n)&&(e.set(n,o),s.add(n),r.push(n));for(const n of i.rels.parents||[])!s.has(n)&&t.has(n)&&(e.set(n,o-1),s.add(n),r.push(n));for(const n of i.rels.children||[])!s.has(n)&&t.has(n)&&(e.set(n,o+1),s.add(n),r.push(n))}}return e}(i,s),f=function(t){const n=new Map;for(const[e,r]of t){const s=(r.rels.parents||[]).filter(n=>t.has(n));if(0===s.length)continue;const o=[...s].sort().join("|");n.has(o)||n.set(o,{parents:[...s].sort(),children:[]}),n.get(o).children.push(e)}return[...n.values()]}(i),p=f.filter(t=>t.parents.includes(s)&&t.children.length>0).slice(0,2),d=i.get(s),g=new Set(d&&d.rels.spouses||[]);if(g.size>0)for(const[t,n]of h)0!==n||t===s||g.has(t)||h.set(t,-.5);const y=new Set;for(const t of p)for(const n of t.parents)n!==s&&y.add(n);if(p.length>=2)for(const t of y)h.has(t)&&h.set(t,.5);const m=new Map;for(const[t,n]of h)m.has(n)||m.set(n,[]),m.get(n).push(t);const _=new Map,x=[...m.keys()].sort((t,n)=>t-n);let v=0;for(const t of x){const r=n(m.get(t),t,s,f,i,p);if(t>=1&&p.length>=2){const t=r.filter(t=>p[0].children.includes(t)),n=r.filter(t=>p[1].children.includes(t)),s=e(t,1),o=e(n,1),i=Math.max(s.length,o.length),h=-(2*a+u)/2+a/2,f=h+a+u;for(let t=0;t<i;t++){const n=s[t]||[],e=o[t]||[];for(const t of n)_.set(t,{x:h,y:v});for(const t of e)_.set(t,{x:f,y:v});v+=c+(t<i-1?.5*l:0)}v+=l;continue}const o=e(r,0===t?r.length:2);for(let n=0;n<o.length;n++){const e=o[n];let r=-(e.length*a+(e.length-1)*u)/2+a/2;-.5===t&&e.length%2==1&&(r-=(a+u)/2);for(let t=0;t<e.length;t++)_.set(e[t],{x:r+t*(a+u),y:v});v+=c+(n<o.length-1?.5*l:0)}v+=-.5===t||.5===t?.6*l:l}const $=_.get(s);if($){const t=$.x,n=$.y;for(const e of _.values())e.x-=t,e.y-=n}const w=[];for(const[t,n]of _){const e=i.get(t);w.push({x:n.x,y:n.y,id:t,isMain:t===s,data:e.data})}const M=function(t,n,e,s,o,i){const a=[],c=e.cardHeight/2,u=e.cardWidth;e.verticalSpacing;const l=o.length>=2,h=n.get(s),f=12;for(const e of t){if(o.indexOf(e)>=0&&l)continue;const t=e.parents.map(t=>n.get(t)).filter(Boolean),s=e.children.map(t=>({id:t,...n.get(t)})).filter(t=>void 0!==t.x);if(0===t.length||0===s.length)continue;const i=Math.max(...t.map(t=>t.y))+c,u=i+.3*(Math.min(...s.map(t=>t.y))-c-i),h=t.reduce((t,n)=>t+n.x,0)/t.length;if(t.length>=2){const n=t.map(t=>t.x).sort((t,n)=>t-n);a.push({path:`M ${n[0]} ${u} L ${n[n.length-1]} ${u}`,cssClass:"link couple-link"})}for(const n of t)a.push({path:`M ${n.x} ${n.y+c} L ${n.x} ${u}`,cssClass:"link ancestor-link"});r(a,s,h,u,c)}if(l&&h)for(let t=0;t<o.length;t++){const e=o[t],i=e.parents.find(t=>t!==s),l=i?n.get(i):null,p=e.children.map(t=>({id:t,...n.get(t)})).filter(t=>void 0!==t.x);if(!l||0===p.length)continue;const d=l.y+c,g=Math.min(...p.map(t=>t.y))-c-d,y=1===p.length;let m;m=0===t?Math.min(...p.map(t=>t.x))-u/2-f:Math.max(...p.map(t=>t.x))+u/2+f;const _=d+.3*g,x=(h.y+c+l.y-c)/2;if(a.push({path:`M ${h.x} ${h.y+c} L ${h.x} ${x}`,cssClass:"link couple-link"}),a.push({path:`M ${h.x} ${x} L ${m} ${x}`,cssClass:"link couple-link"}),a.push({path:`M ${m} ${x} L ${m} ${_}`,cssClass:"link couple-link"}),a.push({path:`M ${l.x} ${d} L ${l.x} ${_}`,cssClass:"link couple-link"}),a.push({path:`M ${m} ${_} L ${l.x} ${_}`,cssClass:"link couple-link"}),y)a.push({path:`M ${l.x} ${_} L ${l.x} ${p[0].y-c}`,cssClass:"link descendant-link"});else{const t=Math.min(...p.map(t=>t.y))-c-6,n=(m+l.x)/2;a.push({path:`M ${n} ${_} L ${n} ${t}`,cssClass:"link descendant-link"}),r(a,p,m,t,c)}}const p=i.get(s),d=new Set;for(const t of o)for(const n of t.parents)n!==s&&d.add(n);if(p&&h&&l)for(const t of p.rels.spouses||[]){if(d.has(t))continue;const e=n.get(t);if(!e)continue;const r=h.y+c+8;a.push({path:`M ${h.x} ${h.y+c} L ${h.x} ${r}`,cssClass:"link couple-link"}),a.push({path:`M ${h.x} ${r} L ${e.x} ${r}`,cssClass:"link couple-link"}),a.push({path:`M ${e.x} ${r} L ${e.x} ${e.y+c}`,cssClass:"link couple-link"})}return a}(f,_,o,s,p,i);return{persons:w,connections:M}}function n(t,n,e,r,s,o){return-.5===n?function(t,n,e){const r=[],s=new Set;for(const o of n){const n=o.children.filter(n=>t.includes(n)&&!s.has(n));n.sort((t,n)=>(e.get(t)?.data?.birthYear||9999)-(e.get(n)?.data?.birthYear||9999));for(const t of n)r.push(t),s.add(t)}for(const n of t)s.has(n)||r.push(n);return r}(t,r,s):n<0?function(t,n){const e=n.filter(n=>n.parents.some(n=>t.includes(n)));if(0===e.length)return[...t];const r=[],s=new Set,o=[...e],i=o.shift();for(const n of i.parents)t.includes(n)&&!s.has(n)&&(r.push(n),s.add(n));for(;o.length>0;){const n=o.findIndex(t=>t.parents.some(t=>s.has(t))),e=n>=0?o.splice(n,1)[0]:o.shift();for(const n of e.parents)t.includes(n)&&!s.has(n)&&(r.push(n),s.add(n))}for(const n of t)s.has(n)||r.push(n);return r}(t,r):0===n?function(t,n,e,r){const s=r.get(n),o=[],i=new Set;o.push(n),i.add(n);for(const n of s.rels.spouses||[])t.includes(n)&&!i.has(n)&&(o.push(n),i.add(n));for(const n of t)i.has(n)||o.push(n);return o}(t,e,0,s):.5===n?function(t,n){const e=[],r=new Set;for(const s of n)for(const n of s.parents)t.includes(n)&&!r.has(n)&&(e.push(n),r.add(n));for(const n of t)r.has(n)||e.push(n);return e}(t,o):function(t,n,e,r){const s=[],o=new Set;for(const n of r)for(const e of n.children)t.includes(e)&&!o.has(e)&&(s.push(e),o.add(e));const i=e.filter(t=>t.parents.includes(n));for(const n of i)if(!r.includes(n))for(const e of n.children)t.includes(e)&&!o.has(e)&&(s.push(e),o.add(e));for(const n of t)o.has(n)||s.push(n);return s}(t,e,r,o)}function e(t,n){const e=[];for(let r=0;r<t.length;r+=n)e.push(t.slice(r,r+n));return e}function r(t,n,e,r,s,o){const i=new Map;for(const t of n){const n=Math.round(10*t.y)/10;i.has(n)||i.set(n,[]),i.get(n).push(t)}const a=[...i.keys()].sort((t,n)=>t-n);if(a.length>1){const n=a.map(t=>t-s-6);r>n[0]&&(n[0]=r);const o=n[n.length-1];t.push({path:`M ${e} ${r} L ${e} ${o}`,cssClass:"link descendant-link"});for(let r=0;r<a.length;r++){const o=i.get(a[r]),c=n[r],u=o.map(t=>t.x).sort((t,n)=>t-n),l=Math.min(u[0],e),h=Math.max(u[u.length-1],e);t.push({path:`M ${l} ${c} L ${h} ${c}`,cssClass:"link descendant-link"});for(const n of o)t.push({path:`M ${n.x} ${c} L ${n.x} ${n.y-s}`,cssClass:"link descendant-link"})}}else{const o=a[0]-s-6,i=Math.max(o,r);if(r<i&&t.push({path:`M ${e} ${r} L ${e} ${i}`,cssClass:"link descendant-link"}),1===n.length)Math.abs(n[0].x-e)>1&&t.push({path:`M ${e} ${i} L ${n[0].x} ${i}`,cssClass:"link descendant-link"}),t.push({path:`M ${n[0].x} ${i} L ${n[0].x} ${n[0].y-s}`,cssClass:"link descendant-link"});else{const r=n.map(t=>t.x).sort((t,n)=>t-n),o=Math.min(r[0],e),a=Math.max(r[r.length-1],e);t.push({path:`M ${o} ${i} L ${a} ${i}`,cssClass:"link descendant-link"});for(const e of n)t.push({path:`M ${e.x} ${i} L ${e.x} ${e.y-s}`,cssClass:"link descendant-link"})}}}function s(t,n,e,r){const s=n.data,o=e.cardWidth,i=e.cardHeight,a=`sex-${(s.gender||"u").toLowerCase()}`,c=n.isMain?"is-root":"",u=t.append("g").attr("class",`person-card ${a} ${c}`.trim()).attr("transform",`translate(${n.x-o/2}, ${n.y-i/2})`).style("cursor","pointer").on("click",t=>{t.stopPropagation(),r({id:n.id,data:s})});if(s.hasMoreAncestors){const t=u.append("g").attr("class","more-ancestors-indicator").style("cursor","pointer").on("click",t=>{t.stopPropagation(),r({id:n.id,data:s})}),e=10,i=7,a=4,c=o-25,l=-14,h=c-a/2-e,f=c+a/2,p=l+i;t.append("line").attr("x1",h+e/2).attr("y1",p).attr("x2",f+e/2).attr("y2",p),t.append("line").attr("x1",c).attr("y1",p).attr("x2",c).attr("y2",0),t.append("rect").attr("x",h).attr("y",l).attr("width",e).attr("height",i).attr("rx",1).attr("ry",1),t.append("rect").attr("x",f).attr("y",l).attr("width",e).attr("height",i).attr("rx",1).attr("ry",1)}if(s.hasMoreDescendants){const t=u.append("g").attr("class","more-descendants-indicator").style("cursor","pointer").on("click",t=>{t.stopPropagation(),r({id:n.id,data:s})}),e=10,a=7,c=4,l=o-25,h=i+7,f=l-c/2-e,p=l+c/2,d=h;t.append("line").attr("x1",l).attr("y1",i).attr("x2",l).attr("y2",d),t.append("line").attr("x1",f+e/2).attr("y1",d).attr("x2",p+e/2).attr("y2",d),t.append("rect").attr("x",f).attr("y",h).attr("width",e).attr("height",a).attr("rx",1).attr("ry",1),t.append("rect").attr("x",p).attr("y",h).attr("width",e).attr("height",a).attr("rx",1).attr("ry",1)}u.append("rect").attr("width",o).attr("height",i).attr("rx",6).attr("ry",6);const l=28,h=(i-l)/2,f=`fng-clip-${n.id}-${Math.random().toString(36).slice(2,6)}`;if(u.append("clipPath").attr("id",f).append("circle").attr("cx",20).attr("cy",h+14).attr("r",13),s.avatar)u.append("image").attr("href",s.avatar).attr("x",6).attr("y",h).attr("width",l).attr("height",l).attr("preserveAspectRatio","xMidYMid slice").attr("clip-path",`url(#${f})`);else{u.append("circle").attr("cx",20).attr("cy",h+14).attr("r",13).attr("class","photo-placeholder");const t=20,n=h+14;u.append("circle").attr("cx",t).attr("cy",n-3).attr("r",5).attr("class","silhouette"),u.append("ellipse").attr("cx",t).attr("cy",n+8).attr("rx",7).attr("ry",5).attr("class","silhouette")}const p=function(t,n,e){const r=t&&!t.match(/^@[A-Z]\.N\.$/)?t:"",s=n&&!n.match(/^@[A-Z]\.N\.$/)?n:"";if(!r&&!s){return(e?e.replace(/@[A-Z]\.N\./g,"…").trim():"")||"???"}const o=r?r.split(/\s+/)[0]:"";if(o&&s)return`${o} ${s}`;return o||s||"???"}(s["first name"]||"",s["last name"]||"",s.fullName),d=o-41-5;u.append("text").attr("class","person-name").attr("x",41).attr("y",i/2-4).text(function(t,n,e){const r=Math.floor(n/e);return!t||t.length<=r?t||"":t.substring(0,r-1)+"…"}(p,d,6.5));const g=(y=s.birthYear,m=s.deathYear,_=s.isDead,y||m?y&&m?`${y}–${m}`:y&&_?`${y}–?`:y?`* ${y}`:`† ${m}`:"");var y,m,_;return g&&u.append("text").attr("class","person-dates").attr("x",41).attr("y",i/2+9).text(g),u}var o="http://www.w3.org/1999/xhtml",i={svg:"http://www.w3.org/2000/svg",xhtml:o,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function a(t){var n=t+="",e=n.indexOf(":");return e>=0&&"xmlns"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),i.hasOwnProperty(n)?{space:i[n],local:t}:t}function c(t){return function(){var n=this.ownerDocument,e=this.namespaceURI;return e===o&&n.documentElement.namespaceURI===o?n.createElement(t):n.createElementNS(e,t)}}function u(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function l(t){var n=a(t);return(n.local?u:c)(n)}function h(){}function f(t){return null==t?h:function(){return this.querySelector(t)}}function p(){return[]}function d(t){return function(){return null==(n=t.apply(this,arguments))?[]:Array.isArray(n)?n:Array.from(n);var n}}function g(t){return function(n){return n.matches(t)}}var y=Array.prototype.find;function m(){return this.firstElementChild}var _=Array.prototype.filter;function x(){return Array.from(this.children)}function v(t){return new Array(t.length)}function $(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}function w(t,n,e,r,s,o){for(var i,a=0,c=n.length,u=o.length;a<u;++a)(i=n[a])?(i.__data__=o[a],r[a]=i):e[a]=new $(t,o[a]);for(;a<c;++a)(i=n[a])&&(s[a]=i)}function M(t,n,e,r,s,o,i){var a,c,u,l=new Map,h=n.length,f=o.length,p=new Array(h);for(a=0;a<h;++a)(c=n[a])&&(p[a]=u=i.call(c,c.__data__,a,n)+"",l.has(u)?s[a]=c:l.set(u,c));for(a=0;a<f;++a)u=i.call(t,o[a],a,o)+"",(c=l.get(u))?(r[a]=c,c.__data__=o[a],l.delete(u)):e[a]=new $(t,o[a]);for(a=0;a<h;++a)(c=n[a])&&l.get(p[a])===c&&(s[a]=c)}function A(t){return t.__data__}function k(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function C(t,n){return t<n?-1:t>n?1:t>=n?0:NaN}function S(t){return function(){this.removeAttribute(t)}}function L(t){return function(){this.removeAttributeNS(t.space,t.local)}}function b(t,n){return function(){this.setAttribute(t,n)}}function N(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function E(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function B(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function P(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function D(t){return function(){this.style.removeProperty(t)}}function H(t,n,e){return function(){this.style.setProperty(t,n,e)}}function Y(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function q(t){return function(){delete this[t]}}function O(t,n){return function(){this[t]=n}}function R(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function W(t){return t.trim().split(/^|\s+/)}function I(t){return t.classList||new j(t)}function j(t){this._node=t,this._names=W(t.getAttribute("class")||"")}function z(t,n){for(var e=I(t),r=-1,s=n.length;++r<s;)e.add(n[r])}function T(t,n){for(var e=I(t),r=-1,s=n.length;++r<s;)e.remove(n[r])}function U(t){return function(){z(this,t)}}function V(t){return function(){T(this,t)}}function F(t,n){return function(){(n.apply(this,arguments)?z:T)(this,t)}}function X(){this.textContent=""}function Z(t){return function(){this.textContent=t}}function G(t){return function(){var n=t.apply(this,arguments);this.textContent=null==n?"":n}}function J(){this.innerHTML=""}function K(t){return function(){this.innerHTML=t}}function Q(t){return function(){var n=t.apply(this,arguments);this.innerHTML=null==n?"":n}}function tt(){this.nextSibling&&this.parentNode.appendChild(this)}function nt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function et(){return null}function rt(){var t=this.parentNode;t&&t.removeChild(this)}function st(){var t=this.cloneNode(!1),n=this.parentNode;return n?n.insertBefore(t,this.nextSibling):t}function ot(){var t=this.cloneNode(!0),n=this.parentNode;return n?n.insertBefore(t,this.nextSibling):t}function it(t){return function(){var n=this.__on;if(n){for(var e,r=0,s=-1,o=n.length;r<o;++r)e=n[r],t.type&&e.type!==t.type||e.name!==t.name?n[++s]=e:this.removeEventListener(e.type,e.listener,e.options);++s?n.length=s:delete this.__on}}}function at(t,n,e){return function(){var r,s=this.__on,o=function(t){return function(n){t.call(this,n,this.__data__)}}(n);if(s)for(var i=0,a=s.length;i<a;++i)if((r=s[i]).type===t.type&&r.name===t.name)return this.removeEventListener(r.type,r.listener,r.options),this.addEventListener(r.type,r.listener=o,r.options=e),void(r.value=n);this.addEventListener(t.type,o,e),r={type:t.type,name:t.name,value:n,listener:o,options:e},s?s.push(r):this.__on=[r]}}function ct(t,n,e){var r=P(t),s=r.CustomEvent;"function"==typeof s?s=new s(n,e):(s=r.document.createEvent("Event"),e?(s.initEvent(n,e.bubbles,e.cancelable),s.detail=e.detail):s.initEvent(n,!1,!1)),t.dispatchEvent(s)}function ut(t,n){return function(){return ct(this,t,n)}}function lt(t,n){return function(){return ct(this,t,n.apply(this,arguments))}}$.prototype={constructor:$,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}},j.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var n=this._names.indexOf(t);n>=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var ht=[null];function ft(t,n){this._groups=t,this._parents=n}ft.prototype={constructor:ft,select:function(t){"function"!=typeof t&&(t=f(t));for(var n=this._groups,e=n.length,r=new Array(e),s=0;s<e;++s)for(var o,i,a=n[s],c=a.length,u=r[s]=new Array(c),l=0;l<c;++l)(o=a[l])&&(i=t.call(o,o.__data__,l,a))&&("__data__"in o&&(i.__data__=o.__data__),u[l]=i);return new ft(r,this._parents)},selectAll:function(t){t="function"==typeof t?d(t):function(t){return null==t?p:function(){return this.querySelectorAll(t)}}(t);for(var n=this._groups,e=n.length,r=[],s=[],o=0;o<e;++o)for(var i,a=n[o],c=a.length,u=0;u<c;++u)(i=a[u])&&(r.push(t.call(i,i.__data__,u,a)),s.push(i));return new ft(r,s)},selectChild:function(t){return this.select(null==t?m:function(t){return function(){return y.call(this.children,t)}}("function"==typeof t?t:g(t)))},selectChildren:function(t){return this.selectAll(null==t?x:function(t){return function(){return _.call(this.children,t)}}("function"==typeof t?t:g(t)))},filter:function(t){"function"!=typeof t&&(t=function(t){return function(){return this.matches(t)}}(t));for(var n=this._groups,e=n.length,r=new Array(e),s=0;s<e;++s)for(var o,i=n[s],a=i.length,c=r[s]=[],u=0;u<a;++u)(o=i[u])&&t.call(o,o.__data__,u,i)&&c.push(o);return new ft(r,this._parents)},data:function(t,n){if(!arguments.length)return Array.from(this,A);var e,r=n?M:w,s=this._parents,o=this._groups;"function"!=typeof t&&(e=t,t=function(){return e});for(var i=o.length,a=new Array(i),c=new Array(i),u=new Array(i),l=0;l<i;++l){var h=s[l],f=o[l],p=f.length,d=k(t.call(h,h&&h.__data__,l,s)),g=d.length,y=c[l]=new Array(g),m=a[l]=new Array(g);r(h,f,y,m,u[l]=new Array(p),d,n);for(var _,x,v=0,$=0;v<g;++v)if(_=y[v]){for(v>=$&&($=v+1);!(x=m[$])&&++$<g;);_._next=x||null}}return(a=new ft(a,s))._enter=c,a._exit=u,a},enter:function(){return new ft(this._enter||this._groups.map(v),this._parents)},exit:function(){return new ft(this._exit||this._groups.map(v),this._parents)},join:function(t,n,e){var r=this.enter(),s=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=n&&(s=n(s))&&(s=s.selection()),null==e?o.remove():e(o),r&&s?r.merge(s).order():s},merge:function(t){for(var n=t.selection?t.selection():t,e=this._groups,r=n._groups,s=e.length,o=r.length,i=Math.min(s,o),a=new Array(s),c=0;c<i;++c)for(var u,l=e[c],h=r[c],f=l.length,p=a[c]=new Array(f),d=0;d<f;++d)(u=l[d]||h[d])&&(p[d]=u);for(;c<s;++c)a[c]=e[c];return new ft(a,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,n=-1,e=t.length;++n<e;)for(var r,s=t[n],o=s.length-1,i=s[o];--o>=0;)(r=s[o])&&(i&&4^r.compareDocumentPosition(i)&&i.parentNode.insertBefore(r,i),i=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=C);for(var e=this._groups,r=e.length,s=new Array(r),o=0;o<r;++o){for(var i,a=e[o],c=a.length,u=s[o]=new Array(c),l=0;l<c;++l)(i=a[l])&&(u[l]=i);u.sort(n)}return new ft(s,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,n=0,e=t.length;n<e;++n)for(var r=t[n],s=0,o=r.length;s<o;++s){var i=r[s];if(i)return i}return null},size:function(){let t=0;for(const n of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var n=this._groups,e=0,r=n.length;e<r;++e)for(var s,o=n[e],i=0,a=o.length;i<a;++i)(s=o[i])&&t.call(s,s.__data__,i,o);return this},attr:function(t,n){var e=a(t);if(arguments.length<2){var r=this.node();return e.local?r.getAttributeNS(e.space,e.local):r.getAttribute(e)}return this.each((null==n?e.local?L:S:"function"==typeof n?e.local?B:E:e.local?N:b)(e,n))},style:function(t,n,e){return arguments.length>1?this.each((null==n?D:"function"==typeof n?Y:H)(t,n,null==e?"":e)):function(t,n){return t.style.getPropertyValue(n)||P(t).getComputedStyle(t,null).getPropertyValue(n)}(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?q:"function"==typeof n?R:O)(t,n)):this.node()[t]},classed:function(t,n){var e=W(t+"");if(arguments.length<2){for(var r=I(this.node()),s=-1,o=e.length;++s<o;)if(!r.contains(e[s]))return!1;return!0}return this.each(("function"==typeof n?F:n?U:V)(e,n))},text:function(t){return arguments.length?this.each(null==t?X:("function"==typeof t?G:Z)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?J:("function"==typeof t?Q:K)(t)):this.node().innerHTML},raise:function(){return this.each(tt)},lower:function(){return this.each(nt)},append:function(t){var n="function"==typeof t?t:l(t);return this.select(function(){return this.appendChild(n.apply(this,arguments))})},insert:function(t,n){var e="function"==typeof t?t:l(t),r=null==n?et:"function"==typeof n?n:f(n);return this.select(function(){return this.insertBefore(e.apply(this,arguments),r.apply(this,arguments)||null)})},remove:function(){return this.each(rt)},clone:function(t){return this.select(t?ot:st)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,n,e){var r,s,o=function(t){return t.trim().split(/^|\s+/).map(function(t){var n="",e=t.indexOf(".");return e>=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}})}(t+""),i=o.length;if(!(arguments.length<2)){for(a=n?at:it,r=0;r<i;++r)this.each(a(o[r],n,e));return this}var a=this.node().__on;if(a)for(var c,u=0,l=a.length;u<l;++u)for(r=0,c=a[u];r<i;++r)if((s=o[r]).type===c.type&&s.name===c.name)return c.value},dispatch:function(t,n){return this.each(("function"==typeof n?lt:ut)(t,n))},[Symbol.iterator]:function*(){for(var t=this._groups,n=0,e=t.length;n<e;++n)for(var r,s=t[n],o=0,i=s.length;o<i;++o)(r=s[o])&&(yield r)}};window.FamilyNavGraphChart=class{constructor(t,n){this.containerSelector=t,this.data=n,this.config={cardWidth:130,cardHeight:42,horizontalSpacing:18,verticalSpacing:45}}async render(){const n=function(t){return"string"==typeof t?new ft([[document.querySelector(t)]],[document.documentElement]):new ft([[t]],ht)}(`${this.containerSelector} .full-diagram-chart`),e=n.node().getBoundingClientRect().width||320;this.config.targetWidth=e;const r=t(this.data.persons,this.data.mainId,this.config),o=this.computeBounds(r,12),i=o.width,a=o.height,c=n.append("svg").attr("viewBox",`${o.minX} ${o.minY} ${i} ${a}`).attr("width","100%").attr("preserveAspectRatio","xMidYMid meet").style("display","block").append("g").attr("class","full-diagram-canvas"),u=t=>{t.data.url&&(window.location.href=t.data.url)},l=c.append("g").attr("class","edges");for(const t of r.connections)l.append("path").attr("class",t.cssClass).attr("d",t.path);for(const t of r.persons)s(c,t,this.config,u)}computeBounds(t,n){const e=this.config.cardWidth/2,r=this.config.cardHeight/2;let s=1/0,o=-1/0,i=1/0,a=-1/0;for(const n of t.persons){s=Math.min(s,n.x-e),o=Math.max(o,n.x+e);const t=n.data.hasMoreAncestors?14:0,c=n.data.hasMoreDescendants?14:0;i=Math.min(i,n.y-r-t),a=Math.max(a,n.y+r+c)}for(const n of t.connections){const t=n.path.match(/-?[\d.]+/g);if(t)for(let n=0;n<t.length;n+=2){const e=parseFloat(t[n]),r=parseFloat(t[n+1]);s=Math.min(s,e),o=Math.max(o,e),i=Math.min(i,r),a=Math.max(a,r)}}return{minX:s-n,minY:i-n,width:o-s+2*n,height:a-i+2*n}}}}();
|