var d = 10; //vzdalenost mezi symboly var pd = 20; //vzdalenost mezi partnery var s_size = 20 //velikost symboly var paddingTop = 10 var vspace = 24 var baseX = 200 var baseY = 20 var levelMax = new Array() //meze pro vykreslovani generaci var maxLevel = 6; //maximalni uroven stromu - pocet generaci var husbandSelection = false; // vyber partnera - vypnuto var xMin = 1000; var xMax = 0; var yMin = 1000; var yMax = 0; var koefY = 1.45 // podil vzdalenosti vodorovne cary pod symbolem ku jeho velikosti var families = new Array(); var marriages = []; var selectedNodes = new Array(); var priklady = [ "F0:MP(mmP(MmmZzMmZ1(MzMZ))zZM);F1:mP(M1ZZMZMM);", "F0:MP(ZP(M1(ZZzmZM))ZMP(Z1ZMmP(MmZ))ZPZ);", "F0:MP(ZP(MZ1(mZzzMZ))ZP(m1ZP(MZ)zZ2(MZm))ZMP(M2ZMP(ZZMM)ZMZP(ZZM))Z);", "F0:zP(zmP(mmZMm)MZzP(mZZMm)MP(ZMM)MP(Z));", "F0:mP(ZZMP(M1(z))ZP(Z1));", "F0:Mp(ZP(ZMZZ)mzZMz1(ZmzmmP(ZZZ)));F1:Mp(m1M);", "F0:Mp(zP(MzMZ1(MzzmMZ))mP(m1Z));", "F0:mP(mP(mZzmM)ZP(ZMMZ)MZzP(mp(MMZ)ZzM));", "F0:MP(ZmZz1(zzmzmP(MZZM)));F1:MP(m1MZz);", "F0:mP(mp(mzzzm)zMZM1(MzM));F1:Mp(Z1MZ);", "F0:Mp(zP(MMmP(ZmzMzzm)MMP(MM)mP(mP(MmMz)MmP(zz))));", "F0:Mp(MMZ1(ZmZMzM));F1:MP(m1ZzMMZM);", "F0:mp(zP(ZMz)MP(MZM));" ] var colors = [ ["orange", "#ffa500"], ["red", "#f00"], ["blue", "#09f"], ["green", "#0c0"], ["yellow", "#ff0"], ["gray", "#808080"], ["black", "#000"], ["violet", "#f69"], ] var actColor = "#ffa500" var history = new Array() var maxHistory = 10; var hIndex = -1; var bt_undo = null; var bt_redo = null; function initApplication() { resetHistory(); families = new Array(); selectedNodes = new Array(); var adresa = window.location.href if (adresa.indexOf("file://") != 0) document.getElementById("fileIO").style.display = "none" disableAll() //alert(window.location.href) } function setSrc(nid, src) { var tl = document.getElementById(nid) tl.setAttribute("src","design/" + src + ".png"); if (src.indexOf("gray") > -1) tl.setAttribute("disabled", "disabled"); else tl.removeAttribute("disabled"); } function disableAll() { setSrc("bt_add_pa", "add_pfa_gray") setSrc("bt_add_pn", "add_pfn_gray") setSrc("bt_add_ma", "add_ma_gray") setSrc("bt_add_mn", "add_mn_gray") setSrc("bt_add_fa", "add_fa_gray") setSrc("bt_add_fn", "add_fn_gray") setSrc("bt_swap_affl", "swap_affl_f_gray") setSrc("bt_delete", "edit-cut_gray") setSrc("bt_marriage", "add-to-favorites_gray") setSrc("bt_divorce", "heart-broken_gray") } function resetHistory() { setSrc("bt_undo", "edit-undo_gray") setSrc("bt_redo", "edit-redo_gray") history = new Array(); hIndex = -1; } function updateHistory() { //if (history.length == maxHistory) history.shift(); if (hIndex < history.length -1) { while (history.length > hIndex+1) history.pop(); } history[++hIndex] = getTextOutput(); //hIndex = history.length-1; if (history.length > 1) setSrc("bt_undo", "edit-undo") else setSrc("bt_undo", "edit-undo_gray") setSrc("bt_redo", "edit-redo_gray") } function undoLast() { if (hIndex > 0) { document.getElementById("familyString").value = history[--hIndex] readFamilies(); } if (hIndex == 0) setSrc("bt_undo", "edit-undo_gray") else setSrc("bt_undo", "edit-undo") if (hIndex == history.length-1) setSrc("bt_redo", "edit-redo_gray") else (setSrc("bt_redo", "edit-redo")) } function redoLast() { if (hIndex < history.length-1) { document.getElementById("familyString").value = history[++hIndex] readFamilies(); } if (hIndex == history.length-1) setSrc("bt_redo", "edit-redo_gray") else (setSrc("bt_redo", "edit-redo")) if (hIndex == 0) setSrc("bt_undo", "edit-undo_gray") else setSrc("bt_undo", "edit-undo") } function showExample(index) { document.getElementById("familyString").value = priklady[index] readFamilies() updateHistory() } /************************ struktura stromu ***********************/ function FTree(fid) { this.nodecount = 0; this.id = fid; this.members = new Array(); this.generations = new Array(); this.getMember = function(id) { for (var i = 0; i < this.members.length; i++) { if (this.members[i].id == id) { return this.members[i]} } return null; } } function Member(gender) { this.id = ""; this.indexId = "" this.gender = gender; this.generation = 0; this.married = null; this.children = new Array(); this.parents = new Array(); this.partner = null; this.afflicted = (gender == "m" || gender == "z" ); this.min = [1e10, 1e10, 1e10, 1e10, 1e10, 1e10] this.max = [-1e10, -1e10, -1e10, -1e10, -1e10, -1e10] this.x = 0 } function addFamily() { var index = families.length var family = createFamily("F" + index); var otec = new Member("M") otec.id = "F" + index + "M0"; otec.indexId = "" + index + "|1" otec.level = 0; otec.index = 1; otec.y = paddingTop; var matka = new Member("Z") matka.id = "F" + index + "M0P"; matka.level = 0; matka.index = 1 matka.y = paddingTop; family.members.push(otec) family.members.push(matka) otec.partner = matka; matka.partnerOf = otec; // var vystup = "F" + index + "_M1\nF" + index + "_M1P"; //createFamily("F" + index) // parseFamilies(vystup); updateTrees() updateHistory() selectedNodes = []; disableAll() } function createFamily(fid) { var family = new FTree(fid); families.push(family); return family; } function getFamily(fid) { for (var i = 0; i < families.length; i++) { if( families[i].id == fid) return families[i]; } var family = new FTree(fid); families.push(family); return family; } function resetAll() { clearAll(); clearCanvas("rodokmen"); clearCanvas("vystupni_obr"); families = new Array(); marriages = new Array() selectedNodes = new Array(); //resetHistory() document.getElementById("familyString").value = "" updateHistory() disableAll() } function addChild (g) { var child = new Member(g); var rid = selectedNodes[0]; var fid = rid.substring(0, rid.indexOf("_")) var family = getFamily(fid) var rodic = family.getMember(rid) if (rid.charAt(rid.length-1) == "P" ||rid.charAt(rid.length-1) == "p" ) rodic = family.getMember(rid.substring(0, rid.length-1)) var maxY = rodic.y if (rodic.marriedTo && rodic.marriedTo != null) { rodic = rodic.marriedTo; maxY = Math.max(maxY, rodic.married.y ) } var index = rodic.children.length + 1 child.parent = rodic; child.level = rodic.level + 1; child.y = maxY + 2*vspace //child.level*2*vspace + paddingTop; child.index = index; child.min[child.level] = 0 child.max[child.level] = s_size; var cid = rodic.id + "_" + g + index; child.id = cid; child.indexId = rodic.indexId +"|" + index rodic.children.push(child); family.members.push(child) drawMember(child) updateTrees() updateHistory() selectedNodes = new Array(); selectMember(rid) } function addPartner(afflicted) { var nid = selectedNodes[0] var fid = nid.substring(0,nid.indexOf("_")); var family = getFamily(fid) var m1 = family.getMember(selectedNodes[0]) if (m1.partner|| m1.partnerOf) return; var gender = "MZ".charAt( 1-"MZ".indexOf(m1.gender.toUpperCase() ) ) if (afflicted) gender = gender.toLowerCase() var partner = new Member(gender); m1.partner = partner partner.partnerOf = m1; partner.afflicted = afflicted; partner.id = m1.id + ((afflicted) ? "p" : "P"); //alert (partner.id) partner.level = m1.level; partner.y = m1.y; partner.index = m1.index; partner.min[partner.level] = 0 partner.max[partner.level] = s_size; drawMember(partner) updateTrees(); updateHistory() selectedNodes = new Array(); selectMember(nid) } function chargeMarriage() { husbandSelection = true; } function dischargeMarriage() { husbandSelection = false; } function breakMarriage() { if (selectedNodes.length == 0) return; var p1 = getSelectedNode(); //alert("1. rozvadeny " + p1.id) var p2 = null if (p1.married != null) { //alert("2. rozvadeny " + p1.married.id ) deleteMarriage(p1, p1.married); return; } if (p1.marriedTo != null) { deleteMarriage(p1, p1.marriedTo); return; } } function deleteMarriage(p1, p2) { p1.married = null; p2.married = null; p1.marriedTo = null; p2.marriedTo = null; for (var i =0; i < marriages.length; i++) { if ( ( marriages[i][0] == p1 && marriages[i][1] == p2 ) || ( marriages[i][0] == p2 && marriages[i][1] == p1 ) ) { marriages.splice(i,1); } } selectedNodes = [] updateTrees() updateHistory() disableAll() } function addToMarriage(m_index, uzel) { //alert(uzel.id + " " + m_index) if (!marriages[m_index]) marriages[m_index] = new Array(); marriages[m_index].push(uzel) } function readFamilies() { var vstup = document.getElementById("familyString").value; parseFamilies(vstup) } function parseFamilies(vstup) { document.getElementById("vystupni").innerHTML = "" clearCanvas("rodokmen"); clearCanvas("vystupni_obr"); clearAll() selectedNodes = new Array(); marriages = new Array(); families = new Array(); var rodiny = vstup.split(";") for (var i = 0; i < rodiny.length; i++) { if (rodiny[i] == "") continue; var fid = rodiny[i].substring(0, rodiny[i].indexOf(":") ); // id rodiny var family = getFamily(fid); var koren = rodiny[i].substring(rodiny[i].indexOf(":")+1 ); parseNode(koren, 1, null, family) } updateTrees() disableAll() } function parseNode(retez, index, rodic, rodina) { if (retez.charAt(0) == ")") return; var pChild = 1; var gender = retez.charAt(0); var member = new Member(gender); member.id = (rodic != null) ? rodic.id + "_" + gender + index : rodina.id + "_" + gender + index; member.indexId = (rodic != null) ? rodic.indexId + "|" + index : rodina.id + "|" + index; member.level = (rodic != null) ? rodic.level + 1 : 0; member.index = index; member.parent = rodic; member.min[member.level] = 0; member.max[member.level] = s_size; member.width = s_size; member.x = 0; member.y = member.level*2*vspace + paddingTop; rodina.members.push(member); if (member.parent) rodic.children.push(member) document.getElementById("vystupni").innerHTML += "

" + retez + ": " + member.id + "

" drawMember(member) if (retez.charCodeAt(1) > 48 && retez.charCodeAt(1) < 58) { // manzelstvi s netrivialnim partnerem var m_index = retez.charCodeAt(1) - 49; addToMarriage(m_index, member); pChild++; } if (retez.charAt(1) == "P" || retez.charAt(1) == "p") { //partner gender = "MZ".charAt( 1-"MZ".indexOf(gender.toUpperCase() ) ) if (retez.charAt(1) == "p") gender = gender.toLowerCase(); var partner = new Member(gender) member.partner = partner; partner.partnerOf = member; partner.id= member.id + retez.charAt(1) partner.y = member.y; partner.level = member.level drawMember(partner) pChild++; document.getElementById("vystupni").innerHTML += "

" + partner.id + "

" } if (retez.charAt(pChild) == "(") { // mame deti, vytahneme jejich podretezec var deti = "" var zavorky = 1; //pChild++; while (zavorky > 0 && pChild < retez.length) { pChild++; if (retez.charAt(pChild) == ")") { zavorky--; if (zavorky == 0) { pChild++; continue; } } if (retez.charAt(pChild) == "(") { zavorky++; } deti += retez.charAt(pChild); } parseNode(deti, 1, member, rodina) } if (pChild < retez.length) parseNode(retez.substring(pChild), index+1, rodic, rodina) } /************************ kreslici funkce ***********************/ function clearCanvas(cid) { //alert(cid) c = document.getElementById(cid).getContext("2d"); c.fillStyle = (cid == "rodokmen" ) ? "#ffc" : "#fff"; c.clearRect(0, 0, 900, 500); //c.fill() } function getMaxBounds() { xMin = 1000; xMax = 0; yMin = 1000; yMax = 0; for (var i = 0; i < families.length; i++) { var family = families[i]; for (var j = 0; j < families[i].members.length; j++) { var m1 = families[i].members[j]; //xMin = Math.min(m1.x, xMin) xMax = Math.max(m1.x + s_size, xMax) //yMin = Math.min(m1.y, yMin) yMax = Math.max(m1.y + s_size, yMax) } } var c = document.getElementById("vystupni_obr") c.setAttribute("width", xMax + 10) c.setAttribute("height", yMax + 10) } function drawTrees(cid) { clearCanvas(cid); for (var i = 0; i < families.length; i++) { var family = families[i]; var koren = family.members[0]; drawNodeSymbol(koren, cid) var maxY = koren.y c_center = koren.x + 0.5*s_size; if (koren.partner != null) { maxY = Math.max(koren.y, koren.partner.y); drawLine(koren.x + s_size/2, koren.y + s_size, koren.x + s_size/2, maxY + s_size*koefY, cid) drawLine(koren.partner.x + s_size/2, koren.partner.y + s_size, koren.partner.x + s_size/2, maxY + s_size*koefY, cid) drawLine(koren.x + s_size/2, maxY + s_size*koefY, koren.partner.x + s_size/2, maxY + s_size*koefY, cid) c_center = s_size + 0.5*pd; drawNodeSymbol(koren.partner, cid) } if (koren.children.length > 0) { c_center += koren.x drawLine(c_center, maxY + s_size*koefY, c_center ,maxY + s_size*(1-koefY) + 2*vspace, cid ) var c_width = (koren.children.length - 1)*(s_size + d) var posX = c_center - c_width/2 - s_size/2 var initX = posX; //drawNodeSymbol(koren, cid) //vodorovna cara nad detmi drawLine( koren.children[0].x + s_size/2 , maxY - s_size*(koefY-1) + 2*vspace, koren.children[koren.children.length-1].x + s_size/2, koren.y - s_size*(koefY-1) + 2*vspace, cid ) for (var j =0; j < koren.children.length; j++) { var child = koren.children[j]; drawNode(child, cid) } } } } function drawNode(uzel, cid) { drawLine( uzel.x + s_size/2 , uzel.y + s_size/2, uzel.x + s_size/2, uzel.y - s_size*(koefY-1), cid ) var maxY = uzel.y var c_center = uzel.x + s_size/2 if (uzel.partner != null) { maxY = Math.max(uzel.y, uzel.partner.y); drawLine(uzel.x + s_size/2, uzel.y + s_size, uzel.x + s_size/2, maxY + s_size*koefY, cid) drawLine(uzel.partner.x + s_size/2, uzel.partner.y + s_size, uzel.partner.x + s_size/2, maxY + s_size*koefY, cid) drawLine(uzel.x + s_size/2, maxY + s_size*koefY, uzel.partner.x + s_size/2, maxY + s_size*koefY, cid) //drawLine(uzel.x + s_size/2, uzel.y + s_size/2, uzel.partner.x + s_size/2, uzel.partner.y + s_size/2, cid) c_center += 0.5*pd + s_size/2; drawNodeSymbol(uzel.partner, cid) } var ypos = uzel.y + s_size*(koefY-1) var ypos2 = ypos + vspace // if (uzel.married != null ) { //manzele z ruznych vetvi //alert("Married: " + uzel.id + ", p2: " + uzel.married.id ) var p2 = uzel.married; c_center = (uzel.x + p2.x + s_size)/2 maxY = Math.max(uzel.y, p2.y) if (uzel.id.substring(0,2) == p2.id.substring(0,2)) { //pribuzensky snatek - dvojita cara //drawLine(uzel.x + s_size/2, ypos - 2 , p2.x + s_size/2, p2.y + s_size/2 -2, cid ); //drawLine(uzel.x + s_size/2, ypos + 2 , p2.x + s_size/2, p2.y + s_size/2 + 2, cid ); ypos += 2 //ypos2 -= 2 drawLine(uzel.x + s_size/2, maxY + koefY*s_size -3, p2.x + s_size/2, maxY + koefY*s_size-3, cid); } drawLine(uzel.x + s_size/2, maxY + koefY*s_size, p2.x + s_size/2, maxY + koefY*s_size, cid); drawLine(uzel.x + s_size/2, maxY + koefY*s_size, uzel.x + s_size/2, uzel.y + s_size, cid); drawLine(p2.x + s_size/2, maxY + koefY*s_size, p2.x + s_size/2, p2.y + s_size, cid); } if (uzel.children.length > 0) { //svisla cara od rodicu k vodorovne care //drawLine(c_center, ypos, c_center, ypos2, cid ) var y_offset = (uzel.married == null && uzel.partner == null) ? 1 : koefY if (uzel.children.length == 1) c_center = (uzel.children[0].x + uzel.children[uzel.children.length-1].x)/2 + s_size/2 drawLine(c_center, maxY + s_size*y_offset, c_center ,maxY + s_size*(1-koefY) + 2*vspace, cid ) // vodorovna cara nad detmi drawLine( uzel.children[0].x + s_size/2 , maxY - s_size*(koefY-1) + 2*vspace, uzel.children[uzel.children.length-1].x + s_size/2, maxY - s_size*(koefY-1) + 2*vspace, cid ) } drawNodeSymbol(uzel, cid) for (var j =0; j < uzel.children.length; j++) { drawNode(uzel.children[j], cid) } } function drawLine(x1, y1, x2, y2, cid) { c = document.getElementById(cid).getContext("2d") c.strokeStyle = "#000000"; c.lineWidth = 1; c.beginPath() c.moveTo(x1, y1); c.lineTo(x2,y2); c.stroke() } function drawNodeSymbol(uzel, cid) { var barva = ("MZP".indexOf(uzel.gender) > -1 ) ? "#fff" : actColor; if ("Mm".indexOf(uzel.gender) > -1) drawRect(uzel.x, uzel.y, barva, cid) else drawCircle(uzel.x, uzel.y, barva, cid) } function drawRect(x1, y1, barva,cid) { c = document.getElementById(cid).getContext("2d") c.strokeStyle = "#000000"; c.fillStyle = barva c.lineWidth = 1; c.fillRect(x1, y1, s_size, s_size) c.strokeRect(x1 , y1, s_size, s_size) } function drawCircle(x1, y1, barva, cid) { c = document.getElementById(cid).getContext("2d") c.strokeStyle = "#000000"; c.fillStyle = barva c.lineWidth = 1; c.beginPath(); c.arc(x1 + s_size/2, y1 + s_size/2, s_size/2, 0, Math.PI*2, true); c.closePath(); c.fill(); c.beginPath(); c.arc(x1 + s_size/2, y1 + s_size/2, s_size/2, 0, Math.PI*2, true); c.closePath(); c.stroke(); } function initTrees() { //marriages = new Array() for (var i=0; i < families.length; i++) { var family = families[i]; if (family.members.length > 0) initNode(family.members[0]) } } function initNode(uzel) { uzel.finalized = false; uzel.x = 0; uzel.min = [1e10, 1e10, 1e10, 1e10, 1e10, 1e10] uzel.max = [-1e10, -1e10, -1e10, -1e10, -1e10, -1e10] // uzel.married = null // uzel.marriedTo = null; //drawMember(uzel.id) if (uzel.partner) { uzel.partner.finalized = false; uzel.partner.x = 0; } //initNode(uzel.partner) for (var i = 0; i < uzel.children.length; i++) { initNode(uzel.children[i])//; drawMember(uzel.children[i].id) } } function initTrees2() { //marriages = new Array() for (var i=0; i < families.length; i++) { var family = families[i]; if (family.members.length > 0) initNode(family.members[0]) } } function initNode2(uzel) { uzel.finalized = false; //uzel.x = 0; //uzel.min = [1e10, 1e10, 1e10, 1e10, 1e10, 1e10] //uzel.max = [-1e10, -1e10, -1e10, -1e10, -1e10, -1e10] // uzel.married = null // uzel.marriedTo = null; //drawMember(uzel.id) if (uzel.partner) { uzel.partner.finalized = false; uzel.partner.x = 0; } //initNode(uzel.partner) for (var i = 0; i < uzel.children.length; i++) { initNode(uzel.children[i])//; drawMember(uzel.children[i].id) } } function updateTrees() { clearAll() getTextOutput() document.getElementById("vstupni").value = "" for (var i = 0; i < families.length; i++) { var koren = families[i].members[0]; families[i].members = new Array(); koren.id = "F" + i + "_" + koren.gender + "0" families[i].members.push(koren) drawMember(koren) document.getElementById("vstupni").value += koren.id + "\n" if (koren.partner) { koren.partner.id = koren.id + ((koren.partner.afflicted) ? "p" : "P"); families[i].members.push(koren.partner) drawMember(koren.partner) document.getElementById("vstupni").value += koren.partner.id + "\n" } for (var j =0; j < koren.children.length; j++) { updateNode(koren.children[j], families[i], j); } } initTrees() finalizeTrees() finalizeMarriages() drawTrees("rodokmen") getMaxBounds() drawTrees("vystupni_obr") //updateHistory() } function updateNode(uzel, family, index) { family.members.push(uzel); uzel.index = index + 1 uzel.id = uzel.parent.id + "_" + uzel.gender + uzel.index drawMember(uzel) document.getElementById("vstupni").value += uzel.id + "\n" if (uzel.partner) { uzel.partner.id = uzel.id + ((uzel.partner.afflicted) ? "p" : "P"); family.members.push(uzel.partner); drawMember(uzel.partner) document.getElementById("vstupni").value += uzel.partner.id + "\n" } for (var j =0; j < uzel.children.length; j++) { updateNode(uzel.children[j], family, j); } } function finalizeTrees() { var familyMin = 10 for (var i = 0; i < families.length; i++) { var family = families[i]; finalizeNode(family.members[0]) var posun = 0 var sirka = 0 if (i == 0) { for (var k = 0; k< maxLevel; k++) { posun = Math.min(posun, family.members[0].min[k] ) sirka = Math.max(sirka, family.members[0].max[k] ) } moveNode(family.members[0], - posun + familyMin) familyMin += pd } if (i > 0) { var previous = families[i-1].members[0]; for (var k = 0; k< maxLevel; k++) { posun = Math.min(posun, family.members[0].min[k] - previous.max[k] ) } moveNode(family.members[0], - posun + s_size /*+ pd*/ + familyMin ) familyMin = familyMin + sirka - posun + pd } } //alert("Pocet manzelstvi: " + marriages.length) } function mSorterLeft(m1, m2) { /* var min1 = Math.min(m1[0].x, m1[1].x) var min2 = Math.min(m2[0].x, m2[1].x) if (min1 > min2) return 1 if (min1 < min2) return -1 if (min1 == min2) return 0 */ var center1 = (m1[0].x + m1[1].x)/2 var center2 = (m2[0].x + m2[1].x)/2 if (center1 > center2) return 1 if (center1 < center2) return -1 if (center1 == center2) return 0 } function finalizeMarriages() { //alert(marriages); marriages = marriages.sort(mSorterLeft) //for( var j = marriages.length-1; j > -1 ; j--) { //posunuti uzlu deti v manzelstvi for( var j =0; j< marriages.length; j++) { //alert("Manzelstvi " + j + ": " + marriages[j]) // alert(marriages[j][0] + " + " + marriages[j][1]) var p1 = marriages[j][0]; var p2 = marriages[j][1]; if ( p1 == undefined || p2 == undefined) continue; p1.married = p2; p2.marriedTo = p1; //.id if (p1.children.length == 0) continue; var dx = checkSpaceRight(p1.children[p1.children.length-1]) //if (dx == 10000) dx = 0; //else dx = Math.min(dx, Math.abs(p2.x - p1.x )/2 ) for (var k = 0; k < p1.children.length; k++) { moveNode(p1.children[k],dx ) } } } function checkSpaceRight(uzel) { var dx = 10000; var leve = [] for (var i = 0; i < families.length; i++) { var family = families[i]; for (var j = 0; j < family.members.length; j++) { var m = families[i].members[j]; if (m.level != uzel.level || m.index > 1 || m == uzel) continue; if (m.indexId < uzel.indexId) continue; //alert(m.indexId) dx = Math.min(dx, m.x - uzel.x - pd - s_size /**/) leve.push(m) } } if (leve.length == 0) dx = 10000 //alert("navrzeny posun " + uzel.indexId + ": " + dx) var vystup = "" + uzel.indexId + ": " + uzel.x + " " for (var i = 0; i < leve.length; i++) { vystup += "" + leve[i].indexId + ".x = " + leve[i].x + "," } //alert(vystup) return dx } function finalizeNode(uzel) { if (uzel.children.length == 0) { uzel.finalized = true; uzel.min[uzel.level] = 0; uzel.max[uzel.level] = s_size; if (uzel.index == 1) { // nejlevejsi uzel uzel.x = 0; uzel.min[uzel.level] = 0; uzel.max[uzel.level] = s_size; if (uzel.partner != null) { uzel.partner.x = uzel.x + s_size + pd uzel.max[uzel.level] += pd + s_size; } } else { var minimum = 0 var p_sibling = uzel.parent.children[uzel.index-2] for (var j = uzel.level; j < maxLevel; j++) { var dx = uzel.min[j] - p_sibling.max[j]; minimum = Math.min( dx, minimum) } var posun = - minimum + pd uzel.x = (p_sibling.partner) ? p_sibling.partner.x + s_size + pd : p_sibling.x + s_size + pd if (uzel.partner) { uzel.partner.x = uzel.x + s_size + pd uzel.max[uzel.level] += pd + s_size; } moveNode(uzel, 0) for (var k = uzel.level; k< maxLevel; k++ ) { uzel.min[k] += posun uzel.max[k] = Math.max( p_sibling.max[k], uzel.max[k] + posun) } } //if (uzel.married != "" ) { marriages.push([uzel.id, uzel.married] ) } if (uzel.level == 0 && uzel.finalized) return; if (uzel.parent.children.length > uzel.index) { finalizeNode(uzel.parent.children[uzel.index]) } if (uzel.parent.children.length == uzel.index && uzel.parent.level >= 0) { finalizeNode(uzel.parent) } } if (uzel.children.length > 0 && !uzel.children[0].finalized) finalizeNode(uzel.children[0]) if (uzel.children.length > 0 && uzel.children[0].finalized) { if(uzel.finalized) return; uzel.finalized = true; //if (uzel.married != "" ) { marriages.push([uzel.id, uzel.married] ) } uzel.x = (uzel.children[0].x + uzel.children[uzel.children.length-1].x)/2 uzel.min[uzel.level] = uzel.x; uzel.max[uzel.level] = uzel.x + s_size; if (uzel.partner != null) { uzel.partner.finalized = true uzel.x -= s_size uzel.partner.x = uzel.x + s_size + pd uzel.max[uzel.level] = uzel.partner.x + s_size; uzel.min[uzel.level] -= s_size + pd/2 drawMember(uzel.partner) } drawMember(uzel) if (uzel.index > 1) { var minimum = 30 var p_sibling = uzel.parent.children[uzel.index-2] updateMinMax(uzel) for (var j = uzel.level; j < maxLevel; j++) { var dx = uzel.min[j] - p_sibling.max[j]; minimum = Math.min(dx, minimum) } var posun = - minimum + pd moveNode(uzel, posun) } updateMinMax(uzel) if (uzel.parent && uzel.parent.children.length > uzel.index) { finalizeNode(uzel.parent.children[uzel.index]) } if (uzel.parent && uzel.parent.children.length == uzel.index && uzel.parent.level >= 0) { finalizeNode(uzel.parent) } } } var layers = new Array() function detectCollisions() { layers = []; } function updateMinMax(uzel) { uzel.min[uzel.level] = uzel.x uzel.max[uzel.level] = uzel.x + s_size; if (uzel.partner) uzel.max[uzel.level] += pd + s_size; for (var i = uzel.level+1; i < maxLevel; i++) { uzel.min[i] = 1e10; uzel.max[i] = -1e10; } for (var j = 0; j < uzel.children.length; j++) { getSubtreeMinMax(uzel.children[j],uzel) } } function getSubtreeMinMax(dite, uzel) { uzel.min[dite.level] = Math.min(dite.x, uzel.min[dite.level]) uzel.max[dite.level] = Math.max(dite.x + s_size, uzel.max[dite.level]) if (dite.partner) uzel.max[dite.level] = Math.max(dite.partner.x + s_size, uzel.max[dite.level]) for (var j = 0; j < dite.children.length; j++) { getSubtreeMinMax(dite.children[j],uzel) } } function drawMember(m1) { var plocha = document.getElementById("rodokmeny_canvas"); var member = document.getElementById(m1.id); if ( !member) { member = document.createElement("DIV"); member.setAttribute("class", m1.gender); member.setAttribute("onclick", "selectNode(this)"); member.setAttribute("data_id", m1.id); member.setAttribute("id", m1.id); //member.innerHTML = m1.gender + m1.index plocha.appendChild(member); } member.setAttribute("style", "left: " + m1.x + "px; top: " + m1.y + "px;"); } function moveMember(m1) { //alert(m1.id) if (!m1.id) return; var member = document.getElementById(m1.id); member.style.left = m1.x + "px" member.style.top = m1.y + "px" } function moveNode(uzel, posun) { uzel.x += posun; moveMember(uzel) if (uzel.partner) { uzel.partner.x = uzel.x + pd + s_size; moveMember(uzel.partner) } for (var i = 0; i < uzel.children.length; i++) { moveNode(uzel.children[i], posun) } } //prebarveni uzlu - preinani postizeni vybraneho jedince function toggleAffl() { var sel = getSelectedNode(); // alert(sel.id) var pohlavi = "ZMmz" sel.gender = pohlavi.charAt(pohlavi.length -1 - pohlavi.indexOf(sel.gender)) if (sel.partnerOf) { // volny partner var konec = "Pp".charAt(1 - "Pp".indexOf(sel.id.charAt(sel.length-1))) sel.id = sel.partnerOf.id + konec; } else { sel.id = sel.id.substring(0, sel.id.lastIndexOf("_") + 1) + sel.gender + sel.index } /* if (sel.marriedTo && sel.marriedTo != "") { //alert("prebarveni partnera" + sel.id ) var p1 = getNode(sel.marriedTo); p1.married = sel.id; } */ updateTrees() updateHistory() selectMember(sel.id) //reindexSubtree(sel); //clearAll(); //finalizeTrees(); } function getSelectedNode() { var nid = selectedNodes[0] var fid = nid.substring(0, nid.indexOf("_")); //alert(nid + ", " + fid) return getFamily(fid).getMember(nid) } function getNode(nid) { //alert("Hledam uzel " + nid) var fid = nid.substring(0, nid.indexOf("_")) return getFamily(fid).getMember(nid) } function deleteSelectedNode() { if (selectedNodes.length == 0) return; var nid = selectedNodes.pop(); // alert("MaĹžu: " + nid) var member = getNode(nid); deleteNode(member) updateTrees(); updateHistory() disableAll() } function deleteNode(uzel) { var pid = uzel.id.substring(uzel.id.lastIndexOf("_")+1) if ( uzel.partnerOf ) { var m2 = uzel.partnerOf; m2.partner = null; } if ( pid.length == 2 && uzel.parent) { uzel.parent.children.splice(uzel.index-1,1); } if (uzel.marriedTo && uzel.marriedTo != null) { uzel.marriedTo.married = null; } if (uzel.married && uzel.married != null) { uzel.married.marriedTo = null; } for (var i = 0; i < marriages.length; i++) { if (uzel == marriages[i][0] || uzel == marriages[i][1]) { marriages.splice(i, 1); break } } for (var i = 0; i < uzel.children.length; i++) { deleteNode(uzel.children[i]) } } function deleteDivs(nid) { var plocha = document.getElementById("rodokmeny_canvas") var divs = plocha.getElementsByTagName("DIV"); for (var i = divs.length -1; i > -1 ; i--) { if (divs[i].getAttribute("id").indexOf(nid) == 0) plocha.removeChild(divs[i]) } } function selectMember(mid) { selectedNodes.pop() selectNode(document.getElementById(mid)) } function selectNode(uzel) { var last = null; if (selectedNodes.length > 0) { last = document.getElementById(selectedNodes.pop()); last.className = last.className.substring(0, last.className.indexOf(" ")) } setSrc("bt_add_ma", "add_ma") setSrc("bt_add_mn", "add_mn") setSrc("bt_add_fa", "add_fa") setSrc("bt_add_fn", "add_fn") var member = getNode(uzel.getAttribute("data_id")); if ("Mm".indexOf(member.gender) > -1) { setSrc("bt_swap_affl", "swap_affl_m") } if ("Zz".indexOf(member.gender) > -1) { setSrc("bt_swap_affl", "swap_affl_f") } if (member.level > 0) setSrc("bt_delete", "edit-cut") else setSrc("bt_delete", "edit-cut_gray") if (!member.partner && !member.partnerOf && !member.married && !member.marriedTo) { setSrc("bt_marriage", "add-to-favorites") if ("Mm".indexOf(member.gender) > -1) { setSrc("bt_add_pa", "add_pfa") setSrc("bt_add_pn", "add_pfn") } if ("Zz".indexOf(member.gender) > -1) { setSrc("bt_add_pa", "add_pma") setSrc("bt_add_pn", "add_pmn") } } else { setSrc("bt_marriage", "add-to-favorites_gray") if ("Mm".indexOf(member.gender) > -1) { setSrc("bt_add_pa", "add_pfa_gray") setSrc("bt_add_pn", "add_pfn_gray") } if ("Zz".indexOf(member.gender) > -1) { setSrc("bt_add_pa", "add_pma_gray") setSrc("bt_add_pn", "add_pmn_gray") } } if (member.married || member.marriedTo) { setSrc("bt_divorce", "heart-broken") } else setSrc("bt_divorce", "heart-broken_gray") if (husbandSelection && last) { // FORMOVANI NOVEHO MANZELSTVI var p1 = getNode(last.getAttribute("data_id")); var p2 = getNode(uzel.getAttribute("data_id")); if (p1.gender.toLowerCase() != p2.gender.toLowerCase()) { if (p1.married || p1.marriedTo || p2.married || p2.marriedTo) { dischargeMarriage(); return; } if (p1.x < p2.x) { p1.married = p2; p2.marriedTo = p1; marriages.push([ p1, p2 ]) } else {p1.marriedTo = p2; p2.married = p1; marriages.push([ p2, p1 ]) } dischargeMarriage() updateTrees(); updateHistory() return; } } selectedNodes[0] = uzel.getAttribute("data_id") if (uzel.className.indexOf("selected") < 0) uzel.className += " selected" var nid = selectedNodes[0] var fid = nid.substring(0, nid.indexOf("_")) getNodeInfo(getFamily(fid).getMember(nid)) } function clearAll() { var plocha = document.getElementById("rodokmeny_canvas") var divs = plocha.getElementsByTagName("DIV"); for (var i = divs.length -1; i > -1 ; i--) plocha.removeChild(divs[i]) disableAll() } //zmena barvy vyznacencych uzlu function changeColor(barva) { document.getElementById("rodokmeny_canvas").className = barva //clearAll() //drawTrees() for (var i=0; i 90) ? "p" : "P" if (uzel.children.length > 0) { vystup += "(" for(var i = 0; i < uzel.children.length; i++) { vystup += getNodeTextOutput(uzel.children[i]) } vystup += ")" } return vystup } function getNodeInfo(uzel) { var vystup = "

" + uzel.id + "

" vystup += "

x: " + uzel.x + "

" if (uzel.married != "") vystup += "

v manzelstvi s: " + uzel.married + "

" if (uzel.marriedTo && uzel.marriedTo != "") vystup += "

manzel(ka) uzlu: " + uzel.marriedTo + "

" vystup += "" if (uzel.partner) vystup += "

partner: " + uzel.partner.id + "

" if (uzel.partnerOf) vystup += "

v partnerstvi s: " + uzel.partnerOf.id + "

" vystup += "
" for (var i = 0; i < maxLevel; i ++) { vystup += "" } vystup += "
min[" + i + "]" + uzel.min[i] + "max[" + i + "]" + uzel.max[i] + "
" document.getElementById("node_info").innerHTML = vystup; } function GetChar (event){ var kod = event.keyCode; //event.charCode //: if (kod == 46) deleteSelectedNode() //alert (kod); } /********************* funkce pro nacitani a ukladani souboru *****************/ var saveFile = null; var FileManager = { write: function (File, Text) { if (!File) return; var unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); unicodeConverter.charset = "UTF-8"; Text = unicodeConverter.ConvertFromUnicode(Text); var os = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); os.init(File, 0x02 | 0x08 | 0x20, 0700, 0); os.write(Text, Text.length); os.close(); }, read: function (File) { if (!File) return; var res; var is = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream); var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream); is.init(File, 0x01, 0400, null); sis.init(is); res = sis.read(sis.available()); is.close(); return res; }, } function createNewFile() { resetAll(); saveFile = null; } function loadData() { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Nelze načítat soubory."); } var nsIFilePicker = Components.interfaces.nsIFilePicker; var fileChooser = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fileChooser.init(window, "Načíst soubor ...", nsIFilePicker.modeLoad); fileChooser.appendFilter("Soubory rodokmenů (*.fts)","*.fts") var fileBox = fileChooser.show(); var file = fileChooser.file //Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); saveFile = file; var vstup = FileManager.read(file) if (vstup != "") { parseFamilies(vstup); resetHistory() } } function saveData() { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Nelze ukládat soubory."); return } if (saveFile != null) { FileManager.write(saveFile, getTextOutput()) } else saveDataAs() } function saveDataAs() { try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Permission to save file was denied."); } var nsIFilePicker = Components.interfaces.nsIFilePicker; var fileChooser = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fileChooser.init(window, "Uložit data do souboru ...", nsIFilePicker.modeSave); fileChooser.appendFilter("Soubory rodokmenů (*.fts)","*.fts") var fileBox = fileChooser.show(); var file = fileChooser.file //Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); if ( file.exists() == false ) { alert( "Vytvářím soubor ... " ); file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 ); } saveFile = file; FileManager.write(file,getTextOutput()) } function exportImage() { var canvas = document.getElementById("vystupni_obr"); //canvas.style.width = "250px" window.open(canvas.toDataURL('image/png')) /* .getContext("2d") try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch (e) { alert("Permission to save file was denied."); } var nsIFilePicker = Components.interfaces.nsIFilePicker; var fileChooser = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fileChooser.init(window, "Uložit data do souboru ...", nsIFilePicker.modeSave); fileChooser.appendFilter("Soubory rodokmenů (*.fts)","*.fts") var fileBox = fileChooser.show(); var file = fileChooser.file //Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile); if ( file.exists() == false ) { alert( "Vytvářím soubor ... " ); file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 ); } saveFile = file; FileManager.write(file,getTextOutput()) */ } //-->