# How to make bitmap editor (plot a family tree)

**URL:** https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769
**Category:** Project Guidance
**Created:** [January 26, 2024, 7:42pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769 "2024-01-26T19:42:27Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [January 26, 2024, 7:42pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/1 "2024-01-26T19:42:27Z")

</div>

… to show as dots ancestors found in family tree, that is a 2D rendering of the entire tree using a dot for each ancestor. Black dots on white canvas.  
 →

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [January 26, 2024, 8:07pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/2 "2024-01-26T20:07:21Z")

</div>

Do you have a real family tree that you want to visualize or do you  
want just the image of a tree?

If you have a family tree, in which form is the data?

---

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [January 26, 2024, 8:26pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/3 "2024-01-26T20:26:05Z")

</div>

I want to enter each dot manually on a grid - with scrolling and printing features…/Lennart

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [January 26, 2024, 8:34pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/4 "2024-01-26T20:34:30Z")

</div>

Do you want to save on hard drive or just have it once and when you close the Sketch the data is lost?

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [January 26, 2024, 9:26pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/5 "2024-01-26T21:26:44Z")

</div>

here is an example to get you started (processing, not p5.js)

```auto

// input family tree

// point data in a list
ArrayList<PVector> listPVectors = new ArrayList();
boolean showRect=true;

// -------------------------------------------------------------------------------

void setup() {
  size(1900, 1000);
  rectMode(CENTER);
}//func

void draw() {
  background(255); // white

  // show help text
  fill(0); // black
  text("Click mouse to set an ancestor.\nBackspace to remove last. Space Bar - dump. Return - toggle view (rects or only points).", 17, 17);

  // show list
  for (PVector pv : listPVectors) {
    stroke(0); // black
    noFill(); // no filling

    // rect and/or point
    if (showRect)
      rect(pv.x, pv.y, 4, 4);
    point(pv.x, pv.y);
  }//for
}//func

// ------------------------------------------------------------------------
// Inputs

void mousePressed() {
  // store point
  listPVectors.add (new PVector(mouseX, mouseY));
}//func

void keyPressed() {
  if (key==' ') {
    // space bar
    // dump
    println("--- " + listPVectors.size() + " entries. --- ");
    for (PVector pv : listPVectors) {
      println(pv.x+","+pv.y);
    }//for
  } else if (key==BACKSPACE) {
    // delete last
    if (listPVectors.size()>0) {
      listPVectors.remove(listPVectors.size()-1);
    }
  } else if (key==ESC) {
    // kill ESC
    key=0; // kill ESC
  } else if (key==RETURN||key==ENTER) {
    // toggle
    showRect=
      ! showRect; //
  }
}//func
//

```

---

<div class="post-metadata">

### Author: ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)
#### Post date: [January 26, 2024, 9:52pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/6 "2024-01-26T21:52:31Z")

</div>

A second variation uses a Rect class and toggles fill color of selected rectangle, shouldn’t be too difficult to port to p5.js:

```auto
Rect[] r;

final int _numCols = 70;
final int _numRows = 60;

final int _wndW = 700;
final int _wndH = 600;

class Rect {
 int x,y,w,h;
 boolean isSelected = false;
 
 // Constructor
 Rect(int xpos, int ypos, int wide, int ht) {
   x = xpos;
   y = ypos;
   w = wide;
   h = ht;
 }
  
 void display() {
  rect(x,y,w,h);
 }
}

 void rectGrid(int left, int top, int w, int h, int vg, int hg) {
   int id = 0;
  for(int k = 0; k < _numRows; k++) {
   for(int j = 0; j < _numCols; j++){
     int x = left + j*(w+vg);
     int y = top + k*(h+hg);
     r[id] = new Rect(x,y,w,h);
     id++;
   }
  }
 }
 
void setup() {
 size(_wndW,_wndH);
 r = new Rect[_numRows*_numCols];
 rectGrid(0, 0, 10, 10, 0, 0);
}

void draw() {
 for (int i = 0; i < r.length; i++) {
   if(r[i].isSelected){
     fill(0);
   } else {
     fill(255);
   }
   r[i].display(); // Display each object  
 }
}

void mousePressed(){
 for (int i = 0; i < r.length; i++) {
  if ((mouseX >= r[i].x) && (mouseX <= r[i].x +r[i].w) && (mouseY >= r[i].y) && (mouseY <= r[i].y + r[i].h)) {
    println("id =",i);
    if (r[i].isSelected){
      r[i].isSelected = false;
    } else {
      r[i].isSelected = true;
    }
  }
 }
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [January 27, 2024, 1:28pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/7 "2024-01-27T13:28:14Z")

</div>

not clear whether you want to have a bitmap editor or a family tree…

 ![sd](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/a/ea17a8676087f91e8027e78c265534a5cd33e2f9.jpeg)

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [January 27, 2024, 1:45pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/8 "2024-01-27T13:45:11Z")

</div>

@lennartd welcome to the forum, if you want members to provide relevant answers then your question should be made very clear.

What you have provided represents a _minimum information problem_ . I certainly can’t see how the title ‘How to make Bitmap editor’ is relevant to family trees. You need to provide must more detail. 🤔

---

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [February 10, 2024, 6:52pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/9 "2024-02-10T18:52:23Z")

</div>

I want to see which ancestors I have identified and which ones are still missing in a 2D format. By transferring information person-by-person from my tree (which is in pages format). Thus building “strings” of black dots on a white background - one “string” for each branch. It could be a manual procedure or smart by searching he document at hand. The ancestors are named using Kekule´s system: generation (level) 1 denoted by “2” and “3” where “2” is father and “3” is mother - “4” is father´s father, “5” is father´s mother, “6” is mother´s father, “7” is mother´s mother, etcetera back through the generations. The 10th generation will have 2^10 = 1024 possible dots. So I want one dot for each of these numbers, built up level by level from the bottom up. The size of the dots must be customizable for readability. I have an A3 paper size printer which I will use for output.  
Lennart

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [February 11, 2024, 9:14am UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/10 "2024-02-11T09:14:34Z")

</div>

> [@lennartd](#):
>
> The ancestors are named using Kekule´s system:

I can find no reference to this system ☹ the closest I found is the [Ahnentafel Numbering System](https://gramps-project.org/wiki/index.php/Genealogical_Numbering_Systems#Simple_numbering).

> [@lennartd](#):
>
> The 10th generation will have 2^10 = 1024 possible dots.

Consider your parents, they may well have a common ancestor so not all 1024 dots have to represent a _unique_ person. How many generations do you want to go back? You will soon reach the legible limit of the printer resolution.

---

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [February 11, 2024, 10:06am UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/11 "2024-02-11T10:06:42Z")

</div>

I just explained what Kekule´s system means. So you do not need to look it up. If this is unclear we leave the subject.  
The resolution of the printer is a non-issue here. We start with a screen solution.  
Lennart

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 11, 2024, 11:05am UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/12 "2024-02-11T11:05:18Z")

</div>

Do you mean a structure like this:

![Clipboard02sss](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/e/0ec3e75f3b7b5320598541e98df0d06419a41fa9.jpeg)

> [@lennartd](#):
>
> By transferring information person-by-person from my tree

can you post the data you have?

Because then we can have a look as how to load and parse the data to a bit map.

Thank you!

Chrisir

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [February 11, 2024, 11:41am UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/13 "2024-02-11T11:41:48Z")

</div>

> [@lennartd](#):
>
> I just explained what Kekule´s system means. So you do not need to look it up. If this is unclear we leave the subject.

I looked it up because I wanted more information about this system so I could help, it was not meant as a criticism.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 11, 2024, 11:45am UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/14 "2024-02-11T11:45:46Z")

</div>

> [@lennartd](#):
>
> Kekule´s system

> **[Kekule-Nummer](https://de.wikipedia.org/wiki/Kekule-Nummer)**
>
> Die Kekule-Nummer, auch Nummerierung nach dem Sosa-Stradonitz-System oder kurz Sosa-Nummer genannt, bezeichnet die Nummer einer Person in einer Ahnenliste oder Ahnentafel nach Stephan Kekule von Stradonitz. Diese Nummerierung, die sich international durchgesetzt hat, war bereits 1590 durch Michael von Aitzing angewendet worden, dann 1676 durch Hieronymus de Sosa und 1883 durch Francis Galton.
> Der Proband erhält unabhängig vom Geschlecht die Nummer 1, sein Vater die Nummer 2, die Mutter die Numme...

seems to be the same as Sosa-Stradonitz-System / Sosa-Number

> **[Genealogical numbering systems](https://en.wikipedia.org/wiki/Genealogical_numbering_systems)**
>
> Several genealogical numbering systems have been widely adopted for presenting family trees and pedigree charts in text format. 
> Ahnentafel, also known as the Eytzinger Method, Sosa Method, and Sosa-Stradonitz Method, allows for the numbering of ancestors beginning with a descendant. This system allows one to derive an ancestor's number without compiling the complete list, and allows one to derive an ancestor's relationship based on their number. The number of a person's father is twice their ow...

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [February 11, 2024, 12:09pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/15 "2024-02-11T12:09:14Z")

</div>

Thanks @Chrisir for the information - most interesting.

---

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [February 11, 2024, 12:20pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/16 "2024-02-11T12:20:13Z")

</div>

Each of my family trees start with a summary of the ancestors as is shown below. Otherwise the whole document has to be searched which is probably overkill. Thus different numbering from different trees are to be converged into one chart of dots - one tree at a time. These trees (“Ahnentafel”) are updated when a new generation is discovered.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/2/d/2dd2200902d8e587f19c16f97f759f02313eb791.png)

---

<div class="post-metadata">

### Author: ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)
#### Post date: [February 11, 2024, 2:33pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/17 "2024-02-11T14:33:53Z")

</div>

Hello @lennartd,

I was able to code this in steps:

- nested for() loops for nodes
- drawing lines between nodes (can be skipped)
- counter in the for() loop to number the nodes
- extracting data (numbers) from your summary (picture)
- if() else() to test for number to color the nodes as required

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/3/8/3829affe2c2a527c71e268f6bbb76b2ec309e6c4.png)

Can you provide a simple text file of the data on that page?  
You may be able to export this.

A text file can be loaded and parsed to extract data:

> **[loadStrings() / Reference](https://processing.org/reference/loadstrings_)**
>
> Reads the contents of a file and creates a String array of its individual lines. If the name of the file is used as the parameter, as in the above example, the file must be loaded in the sketch's "dat…

I can provide guidance and hints but will not provide code.

The coding took some time and effort but was was well worth the reward.  
Keep it simple and work through it in steps.  
Save a working copy with comments along the way (number these) and keep adding to it.

Reference:  
[6.6: Nested Loops - Processing Tutorial](https://www.youtube.com/watch?v=H7frvcAHXps)

`:)`

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 11, 2024, 2:59pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/18 "2024-02-11T14:59:36Z")

</div>

> [@lennartd](#):
>
> person-by-person from my tree (which is in pages format).

Maybe you can export from Pages to csv or tsv  
format.

Then we have format we can parse from Processing.

- Eg. `number,name,generation,date of birth,date of death`

- So, values separated by comma or tabs

and a list of those

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [February 11, 2024, 3:42pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/19 "2024-02-11T15:42:26Z")

</div>

The demo by @glv is good and also highlights the problem of resolution that I raised earlier and was dismissed as unimportant. In your data you have 12 generations and if all ancestors were present that is 4096 ancestors at generation 12. So using 1 pixel for the black dot and 1 white pixel to visually separate them then the image must be at least 8192 pixels wide.

This code displays the data you provided one dot per ancestor but fails at higher generations as the dots merge…

```auto
let ancestors = [1, 2, 3, 4, 5, 8, 9, 16, 17, 34, 35, 70, 71, 140, 141, 280, 281, 560, 561, 1120, 1121, 2240, 2241];

function setup() {
    console.clear(); console.log('GLOBAL mode');
    let p5canvas = createCanvas(1360, 300);
    chart = createAncestorImage(1280, 200, 20, 10, ancestors);
}

function draw() {
    background(128);
    image(chart, 0, 0);
}

function createAncestorImage(chartWidth, chartHeight, border, ygap, ans) {
    function level(an) { return 1 + Math.floor(Math.log2(an)); }
    function levelSize(lvl) { return 2 ** (lvl - 1); }
    function levelMidRange(lvl) { return (2 **(lvl - 1) + 2** lvl - 1) / 2 };
    let pg = createGraphics(chartWidth + 2 * border, chartHeight + 2 * border);
    pg.background(255);
    pg.fill(0);
    ans.forEach(a => {
        let lvl = level(a), lvlSize = levelSize(lvl);
        let lvlMidRange = levelMidRange(lvl);
        let xgap = chartWidth / (lvlSize), dy = border + lvl * ygap;
        let px = border + (chartWidth / 2) + (a - lvlMidRange) * xgap;
        let py = border + lvl * ygap;
        pg.ellipse(px, py, 1, 1);
    });
    return pg;
}

```

---

<div class="post-metadata">

### Author: ![lennartd](https://avatars.discourse-cdn.com/v4/letter/l/c37758/32.png) [@lennartd](https://discourse.processing.org/u/lennartd)
#### Post date: [February 12, 2024, 11:33pm UTC](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769/20 "2024-02-12T23:33:25Z")

</div>

The chart looks great but can be simplified i the following fashion:  
(1) No text - just dots. - But see (3) below - then the lines could be skipped.  
(2) A screen scrolling feature would solve the scaling problem. And then skip printing.  
(3) To complicate things: Would be great (but not necessary) to be able to move the mouse over a dot and expand with some relevant text - perhaps even extracted from the text source file.  
(4) I will provide an actual text sample tomorrow.

[Next page](https://discourse.processing.org/t/how-to-make-bitmap-editor-plot-a-family-tree/43769.md?page=2)
