{"id":4389,"date":"2023-08-25T08:12:32","date_gmt":"2023-08-25T01:12:32","guid":{"rendered":"https:\/\/kamnotra.io\/en\/?page_id=4389"},"modified":"2023-09-28T13:44:06","modified_gmt":"2023-09-28T06:44:06","slug":"political-family-connections","status":"publish","type":"page","link":"https:\/\/kamnotra.io\/en\/succession\/political-family-connections\/","title":{"rendered":"Family Networks"},"content":{"rendered":"\n<section>\n\t<input\n\t\tid=\"sxSearch\"\n\t\ttype=\"search\"\n\t\tclass=\"knSearch\"\n\t\tplaceholder=\"Name\"\n\t\tlist=\"names\"\n\t\tonchange=\"window.location.hash=this.value\"\n\t\/>\n\t<datalist id=\"names\"><\/datalist>\n\t<p>\n\t\t<span style=\"font-variant:small-caps\">context:<\/span>\n\t\t<a href=\"javascript:_Ministers()\">Ministers<\/a> \/\n\t\t<a href=\"javascript:_Lawmakers()\">Lawmakers<\/a>\n\t<\/p>\n<\/section>\n<section id=\"canvas\"><\/section>\n<style>\n#canvas {\n\tposition: relative;\n\twidth: 100%;\n\tborder: solid 1px rgba(0,0,0,0.125);\n}\n#canvas .graph-tooltip {\n\tfont-family: Roboto, Battambang;\n\tfont-size: 0.75rem;\n}\n.panel {\n\tbox-sizing: border-box;\n\theight: 100%;\n\toverflow: auto;\n\ttop: 0; left: 0;\n\tbackground-color: rgb(253, 240, 243, 0.6);\n}\n<\/style>\n<script src=\"\/\/unpkg.com\/force-graph\"><\/script>\n<script>\nlet RING, GRAPH = ForceGraph()(document.getElementById('canvas'));\n_Start();\nasync function _Start() {\n\tawait knData([...SXes, 'Translations']);\n\t_Ministers();\n\n\twindow.onhashchange = () => {\n\t\tif (window.location.hash && window.location.hash != '#') {\n\t\t\t_Reload(decodeURI(window.location.hash.slice(1)));\n\t\t}\n\t};\n}\n\nfunction _Ministers() {\n\tRING = [...new Set(\n\t\tknDATA['Sx-State']\n\t\t\t.filter(row =>\n\t\t\t\trow.Position.endsWith(' minister')\n\t\t\t\t&& !row.Position.startsWith('Former ')\n\t\t\t)\n\t\t\t.map(row => row.English)\n\t\t\t.sort(knSort)\n\t)];\n\t_Reload();\n}\n\nfunction _Lawmakers() {\n\tRING = [...new Set(\n\t\tknDATA['Sx-State']\n\t\t\t.filter(row => row.Position.startsWith('Lawmaker'))\n\t\t\t.map(row => row.English)\n\t\t\t.sort(knSort)\n\t)];\n\t_Reload();\n}\n\nfunction _Reload() {\n\t\/\/ Set search hints\n\tdocument.getElementById('names').innerHTML = RING\n\t\t.map(name => `<option value=\"${name}\">`)\n\t\t.join('');\n\n\t\/\/ Close previous panel\n\tconst old = document.querySelector('#canvas .panel');\n\tif (old) {\n\t\told.remove();\n\t}\n\n\tif (window.location.hash && window.location.hash.length > 1 && window.location.hash != '#0') {\n\t\tconst name = decodeURI(window.location.hash.slice(1));\n\t\t_Graph(name);\n\n\t\t\/\/ Show panel\n\t\tdocument.getElementById('canvas').append(\n\t\t\tknElem('div', {\n\t\t\t\tclassName: 'sxPopup panel',\n\t\t\t\tinnerHTML: knNoteContent(name)\n\t\t\t})\n\t\t);\n\t} else {\n\t\t_Graph();\n\t}\n}\n\nfunction _Graph(target) {\n\tconst radius = 720, big_r = 24, little_r = 16;\n\tconst colors = {\n\t\tSiblings: '#ABB8C3',\n\t\tMarriage: '#F78DA7',\n\t\tChildren: '#ABB8C3',\n\t\tRelatives: '#ABB8C3',\n\t\tAssociates: '#ABB8C3'\n\t};\n\n\tlet NODES = {}, LINKS = {}, DONE = {};\n\tif (target) {\n\t\t_Nodes(target);\n\t} else {\n\t\tRING.forEach(name => _Nodes(name));\n\t}\n\n\tGRAPH.width(document.getElementById('canvas').clientWidth)\n\t\t.graphData({\n\t\t\tnodes: Object.values(NODES),\n\t\t\tlinks: Object.values(LINKS)\n\t\t})\n\t\t.nodeCanvasObject(({id, img, type, x, y}, ctx) => {\n\t\t\tif (type == 'Person') {\n\t\t\t\tlet r = RING.includes(id)? big_r: little_r;\n\t\t\t\tctx.save();\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.arc(x, y, r, 0, 2*Math.PI);\n\t\t\t\tctx.clip();\n\t\t\t\tctx.drawImage(img, x-r, y-r, 2*r, 2*r);\n\t\t\t\tctx.restore();\n\t\t\t\tif (id == target) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.lineWidth = 4;\n\t\t\t\t\tctx.strokeStyle = '#FF6900';\n\t\t\t\t\tctx.arc(x, y, r+2, 0, 2*Math.PI);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.arc(x, y, type == 'Business'? 8: 4, 0, 2*Math.PI);\n\t\t\t\tctx.fillStyle = colors[type];\n\t\t\t\tctx.fill();\n\t\t\t}\n\t\t})\n\t\t.nodeLabel('id')\n\t\t.nodeRelSize(20)\n\t\t.linkLabel('id')\n\t\t.linkLineDash(({type}) => type == 'Associates'? [4, 8]: null)\n\t\t.zoom(0.5)\n\t\t.onNodeClick(node => {\n\t\t\tif (node.type == 'Person') {\n\t\t\t\twindow.location.hash = encodeURI(node.id);\n\t\t\t}\n\t\t});\n\n\t\/\/ Events\n\tdocument.getElementById('canvas').addEventListener('click', () =>\n\t\twindow.location.hash = '0'\n\t);\n\n\t\/\/ Nodes and Links\n\tfunction _Nodes(name) {\n\t\tif (name in DONE) {return;}\n\t\tlet names = [];\n\n\t\t\/\/ Self\n\t\t_Node(name);\n\n\t\t\/\/ Family\n\t\tconst familyRows = knDATA['Sx-Families'].filter(row =>\n\t\t\trow.Wife == name || row.Husband == name\n\t\t\t|| row.Daughters.split(', ').includes(name)\n\t\t\t|| row.Sons.split(', ').includes(name)\n\t\t\t|| row.Others.split(', ').includes(name)\n\t\t);\n\n\t\tfor (const row of familyRows) {\n\t\t\t\/\/ Make all nodes\n\t\t\t_Node(row.Wife);\n\t\t\t_Node(row.Husband);\n\t\t\trow.Daughters.split(', ').forEach(_Node);\n\t\t\trow.Sons.split(', ').forEach(_Node);\n\t\t\trow.Others.split(', ').forEach(_Node);\n\n\t\t\t\/\/ Add to names\n\t\t\tnames.push(row.Wife);\n\t\t\tnames.push(row.Husband);\n\t\t\tnames.push(...row.Daughters.split(', '));\n\t\t\tnames.push(...row.Sons.split(', '));\n\t\t\tnames.push(...row.Others.split(', '));\n\n\t\t\t\/\/ Try others first\n\t\t\tif (row.Others) {\n\t\t\t\trow.Others.split(', ').forEach(other =>\n\t\t\t\t\t_Link(row.Wife || row.Husband, other, 'Relatives')\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t\/\/ Otherwise, parents\/children\/siblings\n\t\t\tlet root, branch;\n\t\t\tif (row.Wife && row.Husband && (row.Daughters || row.Sons)) {\n\t\t\t\t\/\/ Make marriage node\n\t\t\t\tconst id = _ID([row.Wife, row.Husband], 'Marriage');\n\t\t\t\t_Hub(id, 'Marriage');\n\t\t\t\t_Link(row.Wife, id, 'Marriage');\n\t\t\t\t_Link(row.Husband, id, 'Marriage');\n\t\t\t\t\/\/ Set as root\n\t\t\t\troot = id;\n\t\t\t} else {\n\t\t\t\t\/\/ Marriage only or single root\n\t\t\t\tif (row.Wife && row.Husband) {\n\t\t\t\t\t_Link(row.Wife, row.Husband, 'Marriage');\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (row.Wife || row.Husband) {\n\t\t\t\t\troot = row.Wife || row.Husband;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst siblings = row.Daughters.split(', ')\n\t\t\t\t.concat(row.Sons.split(', '))\n\t\t\t\t.filter(i => i);\n\t\t\tif (siblings.length == 1 && root) {\n\t\t\t\tbranch = siblings[0];\n\t\t\t} else if (siblings.length == 2 && !root) {\n\t\t\t\t_Link(siblings[0], siblings[1], 'Siblings');\n\t\t\t} else if (siblings.length >= 2) {\n\t\t\t\t\/\/ Make siblings node\n\t\t\t\tconst id = _ID(siblings, 'Siblings');\n\t\t\t\t_Hub(id, 'Siblings');\n\t\t\t\tsiblings.forEach(sibling => _Link(sibling, id, 'Siblings'));\n\t\t\t\t\/\/ Set as branches\n\t\t\t\tbranch = id;\n\t\t\t} \n\t\t\tif (root && branch) {\n\t\t\t\t_Link(root, branch, 'Children');\n\t\t\t}\n\t\t}\n\n\t\t\/\/ Associates\n\t\tconst companyRows = knDATA['Sx-Associates'].filter(row =>\n\t\t\trow.Directors.split(', ').map(i => i.split(' (')[0]).includes(name)\n\t\t\t|| row.Former.split(', ').map(i => i.split(' (')[0]).includes(name)\n\t\t\t|| row.Others.split(', ').map(i => i.split(' (')[0]).includes(name)\n\t\t);\n\n\t\tfor (const row of companyRows) {\n\t\t\t\/\/ Get all associates\n\t\t\tconst associates = row.Directors.split(', ').map(i => i.split(' (')[0])\n\t\t\t\t.concat(row.Former.split(', ').map(i => i.split(' (')[0]))\n\t\t\t\t.concat(row.Others.split(', ').map(i => i.split(' (')[0]))\n\t\t\t\t.filter(i => i);\n\n\t\t\t\/\/ Make all nodes\n\t\t\tassociates.forEach(_Node);\n\n\t\t\t\/\/ Add to names\n\t\t\tnames.push(...associates);\n\n\t\t\t\/\/ A hub or just two partners?\n\t\t\tif (associates.length == 2) {\n\t\t\t\t_Link(associates[0], associates[1], 'Associates');\n\t\t\t} else if (associates.length > 2) {\n\t\t\t\tconst id = _ID(associates, row.English);\n\t\t\t\t_Hub(id, 'Associates');\n\t\t\t\tassociates.forEach(associate => _Link(associate, id, 'Associates'));\n\t\t\t}\n\t\t}\n\n\t\t\/\/ Don't do again\n\t\tDONE[name] = true;\n\n\t\t\/\/ Try the others\n\t\tnames = [...new Set(names.filter(i => i))];\n\n\t\tif (names.includes('Try Pheap')) {\n\t\t\tconsole.log(names);\n\t\t}\n\n\t\tnames.forEach(_Nodes);\n\t}\n\n\tfunction _Node(id) {\n\t\tif (!id || (id in NODES)) {return;}\n\n\t\tconst img = new Image();\n\t\timg.src = _Pic(id);\n\t\tif (RING.includes(id)) {\n\t\t\tNODES[id] = {id, img, type: 'Person',\n\t\t\t\tfx: radius*Math.sin(2*Math.PI*RING.indexOf(id)\/RING.length),\n\t\t\t\tfy: -radius*Math.cos(2*Math.PI*RING.indexOf(id)\/RING.length)\n\t\t\t};\n\t\t} else {\n\t\t\tNODES[id] = {id, img, type: 'Person'};\n\t\t}\n\t}\n\n\tfunction _Pic(en) {\n\t\tconst extras = knDATA['Sx-Extras'].find(row => row.English == en);\n\t\treturn '\/Pics\/' + (extras && extras.Pic? extras.Pic: 'blank.png');\n\t}\n\n\tfunction _Hub(id, type) {\n\t\tif (!id || (id in NODES)) {return;}\n\t\tNODES[id] = {id, type};\n\t}\n\n\tfunction _ID(list, type) {\n\t\treturn type + ': ' + list.sort(knSort).join(', ');\n\t}\n\n\tfunction _Link(source, target, type) {\n\t\tconst id =\n\t\t\ttarget.startsWith(type + ': ')?\n\t\t\t\tsource + ' \u21c4 ' + target:\n\t\t\ttype == 'Children'?\n\t\t\t\ttype + ': ' + source + ' \u21c9 ' + target:\n\t\t\t\ttype + ': ' + source + ' \u21c4 ' + target;\n\t\tif (id in LINKS) {return;}\n\t\tLINKS[id] = {id, source, target, type, color: colors[type]};\n\t}\n}\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>context: Ministers \/ Lawmakers<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":4393,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pgc_sgb_lightbox_settings":"","_FSMCFIC_featured_image_caption":"","_FSMCFIC_featured_image_nocaption":"","_FSMCFIC_featured_image_hide":"","footnotes":""},"class_list":["post-4389","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/pages\/4389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/comments?post=4389"}],"version-history":[{"count":12,"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/pages\/4389\/revisions"}],"predecessor-version":[{"id":5462,"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/pages\/4389\/revisions\/5462"}],"up":[{"embeddable":true,"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/pages\/4393"}],"wp:attachment":[{"href":"https:\/\/kamnotra.io\/en\/wp-json\/wp\/v2\/media?parent=4389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}