Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // "geneHack" by James Mulholland
- // a family tree viewer (prototype)
- // compatible with GEDCOM files (.ged)
- /// for Interactive Art & Computational Design, Spring 2011
- /// Carnegie Mellon University
- // used some code as a very basic starting point - http://forum.processing.org/topic/simple-file-manipulation
- import java.util.*;
- import processing.pdf.*;
- String[] records;
- ArrayList<Person> people = new ArrayList<Person>(); //create people array
- ArrayList<Family> families = new ArrayList<Family>(); //create family array
- int count = 0;
- int totalPeople = 0;
- int totalFamilies = 0;
- int rectHeight = 12;
- int rectWidth = 12;
- Map familyHash = new HashMap();
- ArrayList myList;
- void setup()
- {
- frameRate(10);
- // size(2200, 1000, PDF, "filename.pdf");
- size(2200, 1000);
- smooth();
- background(100);
- ///////////////////////////////////////////// reads a .ged file and prints
- records = loadStrings("/my.ged");
- //scans through lines and finds the start of a record, prints location of record
- createFamilies();
- createIndividuals();
- //display people
- println("The eldest member of the tree is " + earliestPerson().NAME + " " + earliestPerson().FAMS);
- //start drawing family ... with ME!
- Family sFamily = (Family) familyHash.get("F1992");
- drawNodes(sFamily.children.get(0), 50, 0);
- //
- // Family sFamily = (Family) familyHash.get("F1098");
- // drawNodes(sFamily.children.get(0), width/2, 0);
- // ////////CLEAN UP non-drawn pieces if relationships weren't 100% in-tact
- // for (int i = 0; i < people.size() ; i++)
- // {
- // Person current = people.get(i);
- // if (current.isDrawn == false) {
- // drawNodes(current, 100, 0);
- // }
- // }
- // println(sFamily.children.get(0).x + "," + sFamily.children.get(0).y);
- }
- void draw() {
- //display time periods rectangles
- rectMode(CORNER);
- stroke(100);
- fill(255);
- rect(0,0,width,height); //pre-modern Britain
- fill(255);
- rect(0,500,width,height-500); //Early Modern Britain
- fill(255);
- rect(0,850,width,height-850); //Early 20th century
- fill(255);
- rect(0,922,width,height-922); //
- for (int i = 0; i < people.size() ; i++) {
- people.get(i).isDrawn = false;
- people.get(i).display();
- }
- highlight();
- // println("Finished.");
- // exit();
- }
- void highlight() {
- Person p = null;
- for (int i = 0; i < people.size() ; i++)
- {
- p = people.get(i);
- if (mouseX > (p.x - rectWidth/2) && mouseX < (p.x + rectWidth/2) && mouseY > (p.y - rectHeight/2) && mouseY < (p.y+rectHeight/2))
- {
- //if mouseX is greater
- println(p.NAME + " is now 'Selected'");
- p.showDetail();
- }
- // if (mouseY > (p.y - rectHeight/2) && mouseY < (p.y+rectHeight/2))
- // {
- // //if mouseX is greater
- //// p.selected = true;
- // println(p.NAME + " is now 'Selected'");
- // p.showDetail();
- // }
- }
- }
- //void keyPressed() {
- // Person p = null;
- // for (int i = 0; i < people.size() ; i++)
- // {
- // p = people.get(i);
- // p.NAME = people.get(i).NAME;
- // if (p.NAME.charAt(0) == key) {
- // p.showDetail();
- //
- // }
- // }
- //}
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- ////PARSING/////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- void createIndividuals()
- {
- count = 0;
- for(int i = 0; i < records.length; i++) // scan through lines of data file
- {
- //////////////
- /////CREATE A NEW RECORD
- //////////////
- if (records[i].charAt(0) == ('0') && records[i].charAt(2) == '@') // if a new record is found (indicated by "0 @")
- {
- String newID; //newID variable starts with value of char after first @
- String newName;
- String newSurname;
- String newGiven;
- char newSex;
- String newDOB;
- String newPOB;
- String newDOD;
- String newPOD;
- String newUID;
- String newFAMS;
- String newFAMC;
- //////INDIVIDUALS//////
- if (records[i].charAt(records[i].length()-1) == 'I') // if the record is for an individual "the line ends in I"
- {
- println("new person record at " + i); //print note of new records location
- //Record the ID
- newID = records[i].substring(3);
- newID = newID.replace("@ INDI","");
- Person newPerson = new Person(newID);
- people.add(newPerson);
- // people.get(people.size()-1);
- //Get information to create new individual
- for (int x = 1 ; x < 16 ; x++)
- {
- int rowNum = x+i; // row number relative to the start of new record
- if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'N' && records[rowNum].charAt(3) == 'A') // if a NAME record is found (indicated by "1 N", short for 1 NAME)
- {
- newName = records[rowNum].substring(7); //Parse Full Name
- newName = newName.replace("/",""); //remove "/" separators
- newPerson.NAME = newName;
- }
- else if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'S') // if a surname is found (indicated by "2 S", short for 2 SURN)
- {
- newSurname = records[rowNum].substring(7); //Parse Surname
- newPerson.SURN = newSurname;
- }
- else if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'G') // if a given name is found (indicated by "2 G", short for 2 GIVN)
- {
- newGiven = records[rowNum].substring(7); //Parse Given Name
- newPerson.GIVN = newGiven;
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'S') // if a gender is found (indicated by "1 S", short for 1 SEX)
- {
- newSex = records[rowNum].charAt(6); //Parse Sex
- newPerson.SEX = newSex;
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'B') // if birth info is found (indicated by "1 B", short for 1 BIRT)
- {
- for (int y = 1 ; y < 3 ; y++ )
- {
- rowNum += y;
- if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'D') //if birthdate info is found (indicated by "2 D", short for 2 DATE)
- {
- newDOB = records[rowNum].substring(records[rowNum].length() - 4); //Parse DOB
- // thanks to the following site for this bit of try/catch code - http://www.devdaily.com/java/edu/qanda/pjqa00010.shtml
- try
- {
- // the String to int conversion happens here
- newPerson.DOB = Integer.parseInt(newDOB.trim());
- // print out the value after the conversion
- println("int newPerson.DOB = " + newPerson.DOB);
- }
- catch (NumberFormatException nfe)
- {
- println("NumberFormatException: " + nfe.getMessage());
- }
- }
- else if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'P') //if birthplace info is found (indicated by "2 P", short for 2 PLAC)
- {
- newPOB = records[rowNum].substring(7); //Parse POB
- newPerson.POB = newPOB;
- }
- }
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'D') // if death info is found (indicated by "1 B", short for 1 DEAT)
- {
- for (int y = 1 ; y < 3 ; y++ )
- {
- rowNum += y;
- if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'D') //if deathdate info is found (indicated by "2 D", short for 2 DATE)
- {
- newDOD = records[rowNum].substring(records[rowNum].length() - 4); //Parse DOD
- // thanks to the following site for this bit of try/catch code - http://www.devdaily.com/java/edu/qanda/pjqa00010.shtml
- try
- {
- // the String to int conversion happens here
- newPerson.DOD = Integer.parseInt(newDOD.trim());
- // print out the value after the conversion
- println("int newPerson.DOD = " + newPerson.DOD);
- }
- catch (NumberFormatException nfe)
- {
- println("NumberFormatException: " + nfe.getMessage());
- }
- }
- else if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'P') //if deathplace info is found (indicated by "2 P", short for 2 PLAC)
- {
- newPOD = records[rowNum].substring(7); //Parse POB
- }
- }
- } //end else if death info is found
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == '_') // if UID is found (indicated by "1 _", short for 1 _UID)
- {
- newUID = records[rowNum].substring(7); //Parse UID
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'F' && records[rowNum].charAt(5) == 'S') // if FAMS# is found (indicated by "1 F--S", short for 1 FAMS)
- {
- newFAMS = records[rowNum].substring(8); //Parse FAMS
- newFAMS = newFAMS.replace("@",""); //remove "@"
- if (newPerson.FAMS == null) {
- newPerson.FAMS = newFAMS;
- }
- //check if family exists in map
- //if yes, get family
- //add to F...
- //if no, create family
- //add to family
- ////////////
- Family sFamily = (Family) familyHash.get(newFAMS);
- // println(newFAMS + ": is null " + (sFamily == null)); //COmment in to debug if Family exists
- if (familyHash.containsKey(newFAMS) == false)
- {
- familyHash.put(newFAMS, sFamily);
- }
- if (newFAMS != null && newPerson.SEX == 'M') //Determine if male sire
- {
- sFamily.father = newPerson;
- }
- else if (newFAMS != null && newPerson.SEX == 'F') //Determine if female sire
- {
- sFamily.mother = newPerson;
- }
- if (sFamily.children.isEmpty() == false)
- {
- println(newPerson.NAME + " (born " + newPerson.DOB + ") is the parent of " + sFamily.children.get(0).NAME ) ;
- }
- ////////////
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'F' && records[rowNum].charAt(5) == 'C') // if FAMC# is found (indicated by "1 F--S", short for 1 FAMC)
- {
- newFAMC = records[rowNum].substring(8); //Parse FAMC
- newFAMC = newFAMC.replace("@",""); //remove "@"
- newPerson.FAMC = newFAMC;
- ////////////
- if (newFAMC != null) //Determine if child
- {
- if (familyHash.containsKey(newFAMC) == false)
- {
- familyHash.put(newFAMC, new Family());
- }
- Family cFamily = (Family) familyHash.get(newFAMC);
- cFamily.children.add(newPerson); //add children to array list
- // if (cFamily.father.isEmpty() == false)
- // {
- // println(newPerson.NAME + " is the child of " + sFamily.father.get(0).NAME ) ;
- // }
- }
- ////////////
- }
- //if new record found, STOP and CONTINUE ON
- if (records[rowNum].charAt(0) == ('0'))
- {
- break;
- }
- }
- totalPeople += 1;
- }
- count += 1; //advance record
- }
- }
- println(records.length + " lines of data");
- println(totalPeople + " total people records");
- }
- ///////////////Method to get data from Family data and create f=Family objects in the 'families' array
- void createFamilies()
- {
- count = 0;
- for(int i = 0; i < records.length; i++) // scan through lines of data file
- {
- if (records[i].charAt(0) == ('0') && records[i].charAt(2) == '@') // if a new record is found (indicated by "0 @")
- {
- //////FAMILIES//////
- if (records[i].charAt(records[i].length()-1) == 'M') // if the record is for an family, the line ends in FAM
- {
- String newID = "_";
- String newUID = "_";
- String newHUSB = "_";
- String newWIFE = "_";
- String newDOM = "_";
- String newPOM = "_";
- println("new family record at " + i); //print note of new records location
- //Record the ID
- newID = records[i].substring(3);
- newID = newID.replace("@ FAM","");
- Family newFamily = new Family();
- families.add(newFamily);
- println("(" + newID + ")");
- newFamily.ID = newID;
- //check for hash.
- if (familyHash.containsKey(newID) == false)
- {
- familyHash.put(newID, newFamily);
- }
- // families.add(new Family(newID, newUID, newHUSB, newWIFE, newDOM, newPOM)); //create new person with properties defined by above parsing
- if (familyHash.containsKey(newID) == true)
- {
- //Get information to create new family
- for (int x = 1 ; x < 7; x++)
- {
- int rowNum = x+i;
- if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == '_') // if UID is found (indicated by "1 _", short for 1 _UID)
- {
- newUID = records[rowNum].substring(7); //Parse UID
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'H') // if husband info is found (indicated by "1 H", short for 1 HUSB)
- {
- newHUSB = records[rowNum].substring(7); //Parse HUSB
- newHUSB = newHUSB.replace("@",""); //remove "@"
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'W') // if wife info is found (indicated by "1 W", short for 1 WIFE)
- {
- newWIFE = records[rowNum].substring(7); //Parse WIFE
- newWIFE = newWIFE.replace("@",""); //remove "@"
- }
- else if (records[rowNum].charAt(0) == ('1') && records[rowNum].charAt(2) == 'M') // if marriage info is found (indicated by "1 M", short for 1 MARR)
- {
- for (int y = 1 ; y < 3 ; y++ )
- {
- rowNum += y;
- if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'D') // if date of marriage info is found (indicated by "2 D", short for 2 DATE)
- {
- newDOM = records[rowNum].substring(7); //Parse DOM
- }
- else if (records[rowNum].charAt(0) == ('2') && records[rowNum].charAt(2) == 'P') // if place of marriage info is found (indicated by "2 P", short for 2 PLACE)
- {
- newPOM = records[rowNum].substring(7); //Parse POM
- }
- }
- }
- //if new record found, STOP and CONTINUE ON
- else if (records[rowNum].charAt(0) == ('0'))
- {
- break;
- }
- }
- }
- println(newID + " " + newUID + " (" + newHUSB + ", " + newWIFE + ") " + newDOM + ", " + newPOM); //print out new record
- totalFamilies += 1;
- }
- count += 1; //advance record
- }
- }
- println(records.length + " lines of data");
- println(totalFamilies + " total family records");
- }
- //////SOURCES//////
- //////NOTES////////
- class Family //new Person(newID, newUID, newHUSB, newWIFE, newDOM, newPOM);
- {
- String ID; // unique ID for entry
- String UID;
- String HUSB;
- String WIFE;
- String DOM;
- String POM;
- Person father;
- Person mother;
- ArrayList<Person> children = new ArrayList<Person>();
- Family (
- // String iID,
- // String iUID,
- // String iHUSB,
- // String iWIFE,
- // String iDOM,
- // String iPOM
- )
- {
- // ID = iID;
- // UID = iUID;
- // HUSB = iHUSB;
- // WIFE = iWIFE;
- // DOM = iDOM;
- // POM = iPOM;
- }
- }
- void drawNodes(Person main, float ix, int gen) {
- float DOBmult = 1;
- int DOBadd = -1000;
- int yearBuffer = 40;
- int genS = gen;
- int genC = gen;
- int genM = gen;
- int genF = gen; //set gens to be modified separately for each new person form this one.
- int xmodS = (int) (rectWidth/1.5); //sibling spacing
- int xmodP = rectHeight; //parent spacing
- String FAMSID = main.FAMS;
- String FAMCID = main.FAMC;
- Family cFamily = (Family) familyHash.get(FAMCID); //get family for child-of
- Family sFamily = (Family) familyHash.get(FAMSID); //get family for sire-of
- //////DISPLAY PERSON
- if (main.isDrawn == false) {
- main.x = ix; //draw using modifier passed from parameter
- main.GEN = gen; //set generation of Person to passed value
- if (main.DOB == 0) //if no DOB data
- {
- println("Trying to find DOB");
- if (cFamily != null && cFamily.children.size() > 0) //if cFamily is OK -&- there ARE children
- {
- for (int i = 0 ; i < cFamily.children.size() ; i++) //go through siblings
- {
- if (cFamily.children.get(i).DOB > 0) //if a sibling has DOB not 0, copy it
- {
- main.DOB = cFamily.children.get(i).DOB;
- break;
- }
- }
- }
- if (main.DOB == 0 && sFamily != null) //if STILL 0 -&- is parent
- {
- println(sFamily.ID);
- if (sFamily.children.size() > 0) // if person has children
- {
- for (int c = 0 ; c < sFamily.children.size() ; c++) //go through children
- {
- if (sFamily.children.get(c).DOB > 0) //if child's age is OK
- {
- main.DOB = sFamily.children.get(c).DOB - 30; //take child's DOB and subtract 30 to get est. year
- break;
- }
- }
- }
- }
- }
- if (main.DOB != 0)
- {
- //main.y = (main.DOB*DOBmult)+DOBadd; //manipulate DOB to get y-coord
- main.y = main.DOB+DOBadd;
- }
- else {
- main.y = 500;
- }
- main.display();
- ///////IF PERSON IS A CHILD (has FAMC) - find siblings, find parents
- if (cFamily != null && cFamily.children.size() > 0)
- {
- println("FAMC = " + cFamily.ID);
- ////draw siblings
- for( int s = 0 ; s < cFamily.children.size() ; s++ )
- {
- Person child = cFamily.children.get(s); //get all siblings
- if (child.isDrawn == false)
- {
- //no gen modifier, sibling is same gen
- int sib = s;
- // if (s % 2 > 0) {
- // sib = s*-1;
- // }
- drawNodes(child, main.x+xmodS*sib, genS); //xmodifier
- }
- }
- ////draw parents
- if (cFamily.father != null) //if person has father
- {
- genF += 1;
- drawNodes(cFamily.father, main.x-xmodP, genF);//draw father
- }
- if (cFamily.mother != null) //if person has mother
- {
- genM += 1;
- drawNodes(cFamily.mother, main.x+xmodP, genM);//draw mother
- }
- } //end if cFamily
- ///////IF PERSON IS A PARENT (has FAMS)
- if (sFamily != null)
- {
- // println("FAMS = " + sFamily.ID);
- //find children()
- //if child is not drawn
- //display
- } //end if sFamily is null
- } //end if main
- } //end drawNodes
- Person earliestPerson() {
- int earlyYear = 3000;
- Person earlyPerson = new Person();
- for (int i = 0 ; i < people.size() ; i++) {
- if (people.get(i).DOB > 0 && people.get(i).DOB < earlyYear) {
- earlyYear = people.get(i).DOB;
- earlyPerson = people.get(i);
- }
- }
- return earlyPerson;
- }
- class Person
- {
- String ID; // unique ID for entry
- String NAME; // full name string of person
- String SURN; // surname of person
- String GIVN; // given name of person
- char SEX; // sex of person (M or F)
- String BIRT; // birthdate of person
- int DOB; //
- String POB;
- int DOD;
- String POD;
- String UID;
- String FAMS;
- String FAMC;
- Person Mom;
- Person Dad;
- ArrayList<Person> children = new ArrayList();
- float x, y;
- boolean isDrawn = false;
- int GEN = 0;
- boolean selected = false;
- Person (
- String iID
- // String iNAME,
- // String iSURN,
- // String iGIVN,
- // char iSEX,
- // String iDOB,
- // String iPOB,
- // String iDOD,
- // String iPOD,
- // String iUID,
- // String iFAMS,
- // String iFAMC
- )
- {
- ID = iID;
- x = width/2;
- y = height-20;
- isDrawn = false;
- // NAME = iNAME;
- // SURN = iSURN;
- // GIVN = iGIVN;
- // SEX = iSEX;
- // DOB = iDOB;
- // POB = iPOB;
- // DOD = iDOD;
- // POD = iPOD;
- // UID = iUID;
- // FAMS = iFAMS;
- // FAMC = iFAMC;
- }
- Person () {
- } //empty constructor
- void display()
- {
- if (isDrawn == false) {
- noStroke();
- fill(getFill(), 90);
- rectMode(CENTER);
- ellipseMode(CENTER);
- ellipse(x, y, rectWidth, rectHeight);
- fill(0);
- textAlign(LEFT);
- textSize(8);
- println(NAME + " , " + x + " , " + y + " " + GEN);
- if (selected == true)
- {
- text(NAME,x+(rectWidth/2)+3 , y+(textAscent()/2));
- }
- isDrawn = true;
- }
- }
- void showDetail() {
- //highlight box
- strokeWeight(1);
- stroke(0);
- fill(0,50,50,90);
- rectMode(CENTER);
- rect(x, y, rectWidth, rectHeight);
- fill(0);
- textAlign(LEFT);
- textSize(8);
- String newText = NAME + " " + DOB;
- text(newText,x+(rectWidth/2)+3 , y+(textAscent()/2));
- }
- color getFill()
- {
- color newColor;
- int age = DOD-DOB;
- age = (int) map(age, -20, 100, 0, 255);
- if (age <=40) {
- newColor = color(150);
- }
- else if (DOB > 1922) //current
- {
- newColor = color(age,age,50);
- }
- else if (DOB > 1851) //Early 20th century
- {
- newColor = color(0,age, age);
- }
- else if (DOB > 1500) //Early Modern Britain
- {
- newColor = color(age, 0, age);
- }
- else
- {
- newColor = color(age);
- }
- return newColor;
- }
- } //End class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement