Один из способов сделать это - использовать модель псевдофизики. Ваши объекты обладают силой отталкивания и силой притяжения, если они прикреплены.
Вы перемещаете объекты в соответствии с суммой приложенных к ним сил: на каждом шаге вычисляйте сумму сил, приложенных к объекту, и перемещайте их в направлении силы.
В псевдокоде одна итерация будет:
for each object o1
force[o1] = 0
for each object o2
if o1 and o2 are linked
force[o1] += attraction_force(o1, o2)
else
force[o1] += repulsion_force(o1, o2)
for each object o1
move(o1, force[o1])
И остановить итерации, когда объекты достигли стабильного состояния.
Возможно, вам придется поэкспериментировать с различными законами силы. В частности, вы хотите, чтобы соседние объекты быстро достигли равновесия. Я бы экспериментировал с интенсивностью силы, линейной по отношению к расстоянию (как у пружины) или квадратичной (гравитация / электрическое притяжение)
Также вам, вероятно, нужно будет перемещать объекты случайным образом, чтобы не допустить того, что части графика остались застрявшими . Количество случайных перемещений должно быть большим для первых итераций и уменьшаться со временем.