# Aligning nodes horizontally along a timeline

**URL:** <https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154>\
**Category:** Uncategorized\
**Created:** [April 25, 2024, 2:40am UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154 "2024-04-25T02:40:37Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![j\_jones](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/j_jones/32/1418_2.png) [@j\_jones](https://forum.graphviz.org/u/j_jones)\
**Post date:** [April 25, 2024, 2:40am UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/1 "2024-04-25T02:40:37Z")

</div>

I apologize, I’m a complete newbie at Graphviz and haven’t seen an example which fits what I have in mind.

I would like create a visualization of events happening in parallel along a timeline.

The timeline would run along the top edge of the image and would have vertical lines indicating things like century markers, like 1700, 1800, 1900, etc.

Then each event would be a node box with some data in it. Each event would have a start year and and end year. So I would like to draw it so that the left edge of a node box aligns with its start year on the timeline and the right edge aligns with its end year along the timeline. And events can happen in parallel, so they can be stacked.

Something like this little illustration.

 ![image](https://global.discourse-cdn.com/graphviz/original/2X/3/3bdee1186d7018a1e1d6a0adb8b9b77a15bd1c77.jpeg)

Thank you for any thoughts, clues or pointers to relevant examples I can investigate.  
-j\_jones

---

<div class="post-metadata">

**Author:** ![mark](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/mark/32/84_2.png) [@mark](https://forum.graphviz.org/u/mark)\
**Post date:** [April 25, 2024, 5:22am UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/2 "2024-04-25T05:22:27Z")

</div>

I don’t think Graphviz is the right tool for this; there’s no edges between nodes, for example, and the only auto-layout is the stacking.

If you’re up for a little bit of coding, I’d encourage writing some code to generate SVG to play around with this idea. In SVG you can make rectangles with text in them and set their left/right edges, draw vertical lines for the timeline. You’d need to keep track as you go of what’s overlapping to set the top height.

Or maybe p5.js would be a nice graphics toolkit for easy prototyping: [https://p5js.org/get-started/](https://p5js.org/get-started/)

Or maybe something like this: [https://stackoverflow.com/questions/63213527/is-there-a-way-to-create-range-plot-in-python-using-plotly](https://stackoverflow.com/questions/63213527/is-there-a-way-to-create-range-plot-in-python-using-plotly)

---

<div class="post-metadata">

**Author:** ![j\_jones](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/j_jones/32/1418_2.png) [@j\_jones](https://forum.graphviz.org/u/j_jones)\
**Post date:** [April 25, 2024, 6:03pm UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/3 "2024-04-25T18:03:04Z")

</div>

Thank you. There _will_ be edges between nodes, but I didn’t want to overcomplicate the question. Basically I was hoping to find a way to draw a family tree in such a way as to show both the parent-child relationships and the actual years in which they lived in a visualization that conveyed both ideas.

---

<div class="post-metadata">

**Author:** ![scnorth](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/scnorth/32/89_2.png) [@scnorth](https://forum.graphviz.org/u/scnorth)\
**Post date:** [April 25, 2024, 8:53pm UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/4 "2024-04-25T20:53:21Z")

</div>

Agree, maybe Mermaid.js is suitable? Maybe there’s a custom timeline tool somewhere. Also loo for d3.js timeline visualizations.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [April 25, 2024, 8:55pm UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/5 "2024-04-25T20:55:11Z")

</div>

Sounds cool, but I think it quickly becomes unwieldy. Node overlap would seem to cause ugly edges.  
Scenario:

- A & B have 3 children (E, F, & G)
- B dies (sadly)
- A has one child (H) with new spouse T
- E F & G all have children with their spouses (I J K L M)
- All the above have children of their own - while A & T are still alive

What should the graph look like? Especially

- Are all children nodes positioned “between” the parent nodes? below? other?
- Where should spouse nodes be placed?
- What do the edges look like?

---

<div class="post-metadata">

**Author:** ![j\_jones](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/j_jones/32/1418_2.png) [@j\_jones](https://forum.graphviz.org/u/j_jones)\
**Post date:** [April 25, 2024, 10:02pm UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/6 "2024-04-25T22:02:17Z")

</div>

Yes, part of the problem is indicating the relationships in such a way you can see whose offspring is whose quickly becomes unwieldly. I intend to simplify the problem somewhat by leaving out siblings not directly related to the family line, but it’s still confusing when you have groups of people whose lifespans are all overlapping in various ways. I suppose this is why you never see family trees visualized this way.

 ![image](https://global.discourse-cdn.com/graphviz/original/2X/4/41197a6c7627b21b368a5ddbad2ffb24ccae71fa.jpeg)

btw the apparent potential inbreeding in my example is just an accident, though you can find plenty of similar examples if you have any distant relatives in any way associated with certain types of European royalty

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [April 26, 2024, 12:55am UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/7 "2024-04-26T00:55:16Z")

</div>

I agree with Marc & Steven that this is not a good match for Graphviz, but given the specifics of your intended graph, Graphviz _might_ be as good as any other tool.  
Here is a graph generated by a ~50 line **awk** script + a small data structure:

 ![oo](https://global.discourse-cdn.com/graphviz/original/2X/0/0070cff8cc4a87a6c83d515e8ba4df7eb4eb1820.png)

Note that the vertical sequence is solely based on the sequence of the input records, then the **awk** script calculates the explicit node positions plus the timeline. The script does _not_ allow for overlapping Y coordinates when the X coordinates do not overlap (e.g. greatgrandparents & greatgrandchildren). Not sure how difficult that would be to add.  
As a guess, adding the edges would probably not require much change to the script.

The shell script:

```auto
echo '
TIMELINE|1700|1875|25
Event A|1710|1757|lightpink
Event B|1737|1812|lightpink
Event F|1708|1776|lightgreen
Event G|1782|1858|cyan
Event C|1717|1802|orchid1
Event D|1740|1813|pink
Event E|1717|1773|palegreen
' |
gawk -F'|' '
BEGIN{
  print "graph T {"
  print " node [fixedsize=true height=.66 shape=rect style=\"filled,rounded\"] "
  row=0
  heightFactor=1.3
  Xmin=99999
  Xmax=-99999
}
/TIMELINE/{
  First=$2
  Last=$3
  incr=$4
  next
}
NF>=3{
  row++
  lbl[row]=$1 "\\n" $2 " - " $3 
  Start[row]=$2
  Stop[row]=$3
  Color[row]=$4
  if (Xmin>$2) Xmin=$2
  if (Xmax<$3) Xmax=$3
}
END{
  # timeline nodes later
  XleftPad=40
  if (Xmin>First) Xmin=First
  if (Xmax<Last) Xmax=Last
  widthFactor=8/(Xmax-Xmin)
  # first the timeline
  for (i=First;i<=Last;i+=incr){
    Xpos=XleftPad+((i-Xmin) * widthFactor * 72) 
    Ypos=(1 + row) * heightFactor * 72
    print "\tTLa_" i, "[shape=plaintext label=\"" i "\" style=\"\" fixedsize=false width=0 height=0 "
    print "\t\tpos=\"" Xpos "," Ypos "\"]"  

    Ypos=0
    print "\tTLb_" i, "[shape=plaintext label=\"\" style=\"\" shape=none "
    print "\t\tpos=\"" Xpos "," Ypos "\"]"  

    print "\tTLa_" i " -- TLb_" i " [penwidth=.3]"
  }
  # now the "events"
  for (i=1;i<=row;i++){
    deltaYears=(Stop[i] - Start[i])
    wid= deltaYears * widthFactor 
    Xpos=XleftPad+((Start[i] + deltaYears/2 - Xmin) * widthFactor * 72)
    Ypos=(1 + row-i) * heightFactor * 72
    print "\te_" i, "[label=\"" lbl[i] "\" color=\"" Color[i] "\""
    print "\t\twidth=\"" wid "\" "
    print "\t\tpos=\"" Xpos "," Ypos "\"]" 
  }
  print "}"
}'

```

The generated **neato** input:

```auto
graph T {
  node [fixedsize=true height=.66 shape=rect style="filled,rounded"] 
	TLa_1700 [shape=plaintext label="1700" style="" fixedsize=false width=0 height=0 
		pos="40,460.8"]
	TLb_1700 [shape=plaintext label="" style="" shape=none 
		pos="40,0"]
	TLa_1700 -- TLb_1700 [penwidth=.3]
	TLa_1725 [shape=plaintext label="1725" style="" fixedsize=false width=0 height=0 
		pos="131.139,460.8"]
	TLb_1725 [shape=plaintext label="" style="" shape=none 
		pos="131.139,0"]
	TLa_1725 -- TLb_1725 [penwidth=.3]
	TLa_1750 [shape=plaintext label="1750" style="" fixedsize=false width=0 height=0 
		pos="222.278,460.8"]
	TLb_1750 [shape=plaintext label="" style="" shape=none 
		pos="222.278,0"]
	TLa_1750 -- TLb_1750 [penwidth=.3]
	TLa_1775 [shape=plaintext label="1775" style="" fixedsize=false width=0 height=0 
		pos="313.418,460.8"]
	TLb_1775 [shape=plaintext label="" style="" shape=none 
		pos="313.418,0"]
	TLa_1775 -- TLb_1775 [penwidth=.3]
	TLa_1800 [shape=plaintext label="1800" style="" fixedsize=false width=0 height=0 
		pos="404.557,460.8"]
	TLb_1800 [shape=plaintext label="" style="" shape=none 
		pos="404.557,0"]
	TLa_1800 -- TLb_1800 [penwidth=.3]
	e_1 [label="Event A\n1710 - 1757" color="lightpink"
		width="2.37975" 
		pos="77.6456,403.2"]
	e_2 [label="Event B\n1737 - 1812" color="lightpink"
		width="3.79747" 
		pos="176.785,345.6"]
	e_3 [label="Event F\n1708 - 1776" color="lightgreen"
		width="3.44304" 
		pos="70.8861,288"]
	e_4 [label="Event G\n1782 - 1858" color="cyan"
		width="3.8481" 
		pos="340.861,230.4"]
	e_5 [label="Event C\n1717 - 1802" color="orchid1"
		width="4.3038" 
		pos="104.127,172.8"]
	e_6 [label="Event D\n1740 - 1813" color="pink"
		width="3.6962" 
		pos="187.671,115.2"]
	e_7 [label="Event E\n1717 - 1773" color="palegreen"
		width="2.83544" 
		pos="103.392,57.6"]
}

```

The command line:

```auto
sh forumTimeline2.sh |neato -n -Tpng >oo.png

```

---

<div class="post-metadata">

**Author:** ![goetz\_3rz](https://avatars.discourse-cdn.com/v4/letter/g/ce73a5/32.png) [@goetz\_3rz](https://forum.graphviz.org/u/goetz_3rz)\
**Post date:** [October 8, 2025, 2:29pm UTC](https://forum.graphviz.org/t/aligning-nodes-horizontally-along-a-timeline/2154/8 "2025-10-08T14:29:14Z")

</div>

Thanks a lot for this tiny but great solution, it’s exactly what I’m looking for to embed in an SSG script to deploy timelines of computer models of the 80ies!
