سؤال

أحاول رسم شجرة عائلة مع Dot و Graphviz.

هذا ما لدي حاليا:

# just graph set-up
digraph simpsons {
ratio = "auto"
mincross = 2.0

# draw some nodes
"Abraham"   [shape=box, regular=1, color="blue"] ;
"Mona"      [shape=box, regular=1, color="pink"] ;
"Clancy"    [shape=box, regular=1, color="blue"] ;
"Jackeline" [shape=box, regular=1, color="pink"] ;
"Herb"      [shape=box, regular=1, color="blue"] ;
"Homer"     [shape=box, regular=1, color="blue"] ;
"Marge"     [shape=box, regular=1, color="pink"] ;
"Patty"     [shape=box, regular=1, color="pink"] ;
"Selma"     [shape=box, regular=1, color="pink"] ;
"Bart"      [shape=box, regular=1, color="blue"] ;
"Lisa"      [shape=box, regular=1, color="pink"] ;
"Maggie"    [shape=box, regular=1, color="pink"] ;
"Ling"      [shape=box, regular=1, color="blue"] ;
# creating tiny nodes w/ no label, no color
"ParentsHomer" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"ParentsMarge" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"ParentsBart"  [shape=diamond,style=filled,label="",height=.1,width=.1] ;

# draw the edges
"Abraham"      -> "ParentsHomer" [dir=none, weight=1] ;
"Mona"         -> "ParentsHomer" [dir=none, weight=1] ;
"ParentsHomer" -> "Homer"        [dir=none, weight=2] ;
"ParentsHomer" -> "Herb"         [dir=none, weight=2] ;
"Clancy"       -> "ParentsMarge" [dir=none, weight=1] ;
"Jackeline"    -> "ParentsMarge" [dir=none, weight=1] ;
"ParentsMarge" -> "Marge"        [dir=none, weight=2] ;
"ParentsMarge" -> "Patty"        [dir=none, weight=2] ;
"ParentsMarge" -> "Selma"        [dir=none, weight=2] ;
"Homer"        -> "ParentsBart"  [dir=none, weight=1] ;
"Marge"        -> "ParentsBart"  [dir=none, weight=1] ;
"ParentsBart"  -> "Bart"         [dir=none, weight=2] ;
"ParentsBart"  -> "Lisa"         [dir=none, weight=2] ;
"ParentsBart"  -> "Maggie"       [dir=none, weight=2] ;
"Selma"        -> "Ling"         [dir=none, weight=2] ;
}

إذا قمت بتشغيل هذا من خلال DOT (dot simpsons.dot -Tsvg > simpsons.svg) ، أحصل على التصميم التالي:Original, made by dot/graphviz

ومع ذلك ، أود أن تكون الحواف أكثر "شجرة عائلة"-على غرار: تقع بين شخصين متزوجين مع الخط الرأسي من T المتفرعة مرة أخرى في مقاربة T مقلوبة مع التقسيمات الفرعية الصغيرة لكل من الأطفال ، مثل هذا النموذج ، الذي تم في Kolourpaint:

what I would like to achieve

ما هو بناء جملة DOT الذي يجب أن أستخدمه لتحقيق ذلك؟

هل كانت مفيدة؟

المحلول

هنا حل آخر:

digraph simpsons {  
  subgraph Generation0 {
    rank = same
    Abraham [shape = box, color = blue]
    Mona [shape = box, color = pink]
    AbrahamAndMona [shape = point]
    Abraham -> AbrahamAndMona [dir = none]
    AbrahamAndMona -> Mona [dir = none]

    Clancy [shape = box, color = blue]
    Jackeline [shape = box, color = pink]
    ClancyAndJackeline [shape = point]
    Clancy -> ClancyAndJackeline [dir = none]
    ClancyAndJackeline -> Jackeline [dir = none]
  }

  subgraph Generation0Sons {
    rank = same
    AbrahamAndMonaSons [shape = point]
    HerbSon [shape = point]
    HomerSon [shape = point]
    HerbSon -> AbrahamAndMonaSons [dir = none]
    HomerSon -> AbrahamAndMonaSons [dir = none]

    MargeSon [shape = point]
    PattySon [shape = point]
    SelmaSon [shape = point]
    MargeSon -> PattySon [dir = none] 
    PattySon -> SelmaSon [dir = none] 
  }

  AbrahamAndMona -> AbrahamAndMonaSons [dir = none]
  ClancyAndJackeline -> PattySon [dir = none]

  subgraph Generation1 {
    rank  =  same
    Herb [shape = box, color = blue] 
    Homer [shape = box, color = blue] 
    Marge [shape = box, color = pink] 
    Patty [shape = box, color = pink] 
    Selma [shape = box, color = pink] 

    HomerAndMarge [shape = point]
    Homer -> HomerAndMarge [dir = none]
    Marge -> HomerAndMarge [dir = none]
  }

  HerbSon -> Herb [dir = none]
  HomerSon -> Homer [dir = none]
  MargeSon -> Marge [dir = none]
  PattySon -> Patty [dir = none]
  SelmaSon -> Selma [dir = none]

  subgraph Generation1Sons {
    rank  =  same
    BartSon [shape = point] 
    LisaSon [shape = point] 
    MaggieSon [shape = point] 

    BartSon -> LisaSon [dir = none]
    LisaSon -> MaggieSon [dir = none]
  }

  HomerAndMarge -> LisaSon [dir = none]

  subgraph Generation2 {
    rank  =  same
    Bart [shape = box, color = blue] 
    Lisa [shape = box, color = pink] 
    Maggie [shape = box, color = pink] 
    Ling [shape = box, color = blue] 
  }

  Selma -> Ling [dir = none]
  BartSon -> Bart [dir = none]
  LisaSon -> Lisa [dir = none]
  MaggieSon -> Maggie [dir = none]
}

والنتيجة:

http://dl.dropbox.com/u/72629/simpsons.png

نصائح أخرى

تقوم Gramps (www.gramps-project.org) بإنشاء ملفات نقطة لأشجار الأسرة ، مع أو بدون عقد زواج. هناك أيضًا طريقة لرؤية هذا في واجهة Gramps نفسها. http://gramps-project.org/wiki/index.php؟title=graph_viewلذلك أود أن أقول ، انظر إلى ناتج شجرة عائلتك على النحو الذي تم إنشاؤه بواسطة Gramps

لا أعتقد أنه يمكنك تناول شجرة عائلة تعسفية وتولي تلقائيًا ملفًا نقاطًا حيث يبدو دائمًا جيدًا في GraphViz.

لكني أعتقد أنك يستطيع اجعلها تبدو جيدة دائمًا إذا كنت:

  • استخدم الترتيب = نفس الإجابات الأخرى المذكورة للحصول على اتصالات "T" المطلوبة بواسطة OP
  • استخدم خدعة الطلب التي قام بها براين بلانك لمنع الخطوط الغريبة
  • لا تفترض عدم الزيجات الثانية والنصف
  • ارسم مجموعة فرعية فقط من الشجرة التي تطيع القواعد التالية:
    • فليكن الشخص "المركزي"
    • إذا كان S له أشقاء ، فتأكد من حق كل منهم.
    • إذا كان لدى S زوجة وكان للزوج أشقاء ، فتأكد من أن الزوج على يسار جميع أشقائه.
    • لا تظهر أبناء أخيه أو بنات أو عمات أو أعمام زوج S أو S S
    • لا تظهر أزواج الأشقاء
    • لا تظهر أزواج أشقاء الزوج
    • أظهر أطفال S ، ولكن ليس أزواجهم أو أطفالهم
    • إظهار والديه وأولياء أمور الزوج

سيؤدي هذا إلى إظهار ما لا يزيد عن 3 أجيال في وقت واحد ، مع S في الجيل الأوسط.

في الصورة أدناه s = هوميروس (تم تعديله قليلاً من نسخة براين بلانغ):

digraph G {
  edge [dir=none];
  node [shape=box];
  graph [splines=ortho];

  "Herb"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Homer"     [shape=box, regular=0, color="blue", style="bold, filled" fillcolor="lightblue"] ;
  "Marge"     [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Clancy"    [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Jackeline" [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Abraham"   [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Mona"      [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Patty"     [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Selma"     [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Bart"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Lisa"      [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;
  "Maggie"    [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ;

  a1 [shape=diamond,label="",height=0.25,width=0.25];
  b1 [shape=circle,label="",height=0.01,width=0.01];
  b2 [shape=circle,label="",height=0.01,width=0.01];
  b3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Abraham -> a1 -> Mona};
  {rank=same; b1 -> b2 -> b3};
  {rank=same; Herb; Homer};
  a1 -> b2
  b1 -> Herb
  b3 -> Homer

  p1 [shape=diamond,label="",height=0.25,width=0.25];
  q1 [shape=circle,label="",height=0.01,width=0.01];
  q2 [shape=circle,label="",height=0.01,width=0.01];
  q3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Homer -> p1 -> Marge};
  {rank=same; q1 -> q2 -> q3};
  {rank=same; Bart; Lisa; Maggie};
  p1 -> q2;
  q1 -> Bart;
  q2 -> Lisa;
  q3 -> Maggie;

  x1 [shape=diamond,label="",height=0.25,width=0.25];
  y1 [shape=circle,label="",height=0.01,width=0.01];
  y2 [shape=circle,label="",height=0.01,width=0.01];
  y3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Clancy -> x1 -> Jackeline};
  {rank=same; y1 -> y2 -> y3};
  {rank=same; Patty; Selma; Marge};
  x1 -> y2;
  y1 -> Marge;
  y2 -> Patty;
  y3 -> Selma;
}

هذا يعطي الشجرة التالية بواسطة GraphViz (مع التعليقات التوضيحية أضفت مع Power Point):enter image description here

على الرغم من أنه لا يمكنك التحكم في وضع العقدة ، فقد وجدت أنه يمكنك المساعدة في وضع العقدة عن طريق طلب العقد بترتيب مختلف. قمت بإعادة ترتيب بعض العقد كما هو موضح أدناه وحصلت على رسم بياني لم ينتج عنه أي تقاطعات.

الرمز التالي:

digraph G {
  edge [dir=none];
  node [shape=box];

  "Herb"      [shape=box, regular=1, color="blue"] ;
  "Homer"     [shape=box, regular=1, color="blue"] ;
  "Marge"     [shape=box, regular=1, color="pink"] ;
  "Clancy"    [shape=box, regular=1, color="blue"] ;
  "Jackeline" [shape=box, regular=1, color="pink"] ;
  "Abraham"   [shape=box, regular=1, color="blue"] ;
  "Mona"      [shape=box, regular=1, color="pink"] ;
  "Patty"     [shape=box, regular=1, color="pink"] ;
  "Selma"     [shape=box, regular=1, color="pink"] ;
  "Bart"      [shape=box, regular=1, color="blue"] ;
  "Lisa"      [shape=box, regular=1, color="pink"] ;
  "Maggie"    [shape=box, regular=1, color="pink"] ;
  "Ling"      [shape=box, regular=1, color="blue"] ;

  a1 [shape=circle,label="",height=0.01,width=0.01];
  b1 [shape=circle,label="",height=0.01,width=0.01];
  b2 [shape=circle,label="",height=0.01,width=0.01];
  b3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Abraham -> a1 -> Mona};
  {rank=same; b1 -> b2 -> b3};
  {rank=same; Herb; Homer};
  a1 -> b2
  b1 -> Herb
  b3 -> Homer

  p1 [shape=circle,label="",height=0.01,width=0.01];
  q1 [shape=circle,label="",height=0.01,width=0.01];
  q2 [shape=circle,label="",height=0.01,width=0.01];
  q3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Homer -> p1 -> Marge};
  {rank=same; q1 -> q2 -> q3};
  {rank=same; Bart; Lisa; Maggie};
  p1 -> q2;
  q1 -> Bart;
  q2 -> Lisa;
  q3 -> Maggie;

  x1 [shape=circle,label="",height=0.01,width=0.01];
  y1 [shape=circle,label="",height=0.01,width=0.01];
  y2 [shape=circle,label="",height=0.01,width=0.01];
  y3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Clancy -> x1 -> Jackeline};
  {rank=same; y1 -> y2 -> y3};
  {rank=same; Marge; Patty; Selma};
  {rank=same; Bart; Ling}
  x1 -> y2;
  y1 -> Marge;
  y2 -> Patty;
  y3 -> Selma;
  Selma -> Ling;
}

ينتج هذا الآن:

family tree layout

لا أفهم تمامًا سبب عملها ، ولكن هنا هي عملية التفكير في التغييرات التي أجريتها.

  1. وضعت كلانسي/جاكلين قبل إبراهيم/منى أفكر في أنهم كانوا على الجانب الخطأ. هذا غير الصورة ، ولكن لا يزال لم يكن مثاليًا.
  2. لقد وضعت Homer/Marge أولاً أفكر في أن البرنامج كان عليه أن يفكر في هذه القطع أولاً وربما وضع جميع العقد الأخرى بالنسبة إلى Homer/Marge. هذا ساعد كذلك ، ولكن لا يزال لم يكن مثاليًا.
  3. كان هيرب لا يزال يسيء وضعه ، لذلك وضعت هيرب أولاً حتى يتمكن Graphviz من التفكير في وضع Herb أولاً.

لقد نجح الأمر ، لكن ما زلت لا أستطيع وضع خوارزمية تضمن الأشجار المتسقة بدون حواف متداخلة. أشعر أن Graphviz يجب أن يقوم بعمل أفضل بدون هذه التلميحات. لا أعرف الخوارزمية المستخدمة ، ولكن إذا نظروا في وظيفة موضوعية لتقليل الحواف المتداخلة أو القضاء عليها ، فيجب أن يكون من الممكن وضع خوارزمية أفضل.

للقيام بذلك في GraphViz مباشرة إلى حد ما ؛ هناك زوجان من أنماط بناء الجملة التي تحتاجها: (1) بناء الجملة لتمثيل الاتصال من الخط إلى الخط ("t"-الوظيفية في مخططاتك أعلاه) ؛ (2) بناء الجملة لفرض الهيكل الهرمي (أي ، العقد من نفس الجيل على نفس المستوى على المحور العمودي). من الأسهل إظهار:

digraph G {
    nodesep=0.6;
    edge [arrowsize=0.3];

    "g1" -> "g2" -> "g3" -> "g4"

    { rank = same;
        "g1"; "King"; "ph1"; "Queen";
    };

    { rank = same; 
        "g2"; "ph2"; "ph2L"; "ph2R"; "ph2LL"; "ph2RR"
    };

    { rank = same;
        "g3"; "ps1"; "ps2"; "pr1"; "pr2"
    };

    "King" -> "ph1" [arrowsize=0.0];
    "ph1" -> "Queen" [arrowsize=0.0];

    "ph1" -> "ph2" [arrowsize=0.0];
    "ph2LL" -> "ph2L" [arrowsize=0.0];
    "ph2L" -> "ph2" [arrowsize=0.0];
    "ph2" -> "ph2R" [arrowsize=0.0];
    "ph2R" -> "ph2RR" [arrowsize=0.0];

    "ph2LL" -> "ps1" [arrowsize=0.0];
    "ph2L"-> "pr1" [arrowsize=0.0];
    "ph2R" -> "ps2" [arrowsize=0.0];
    "ph2RR" -> "pr2" [arrowsize=0.0];

}

سينتج الرمز أعلاه الرسم البياني أدناه (لقد حذفت الرمز الذي استخدمته لتلوين العقد). لقد تركت "دليل" على اليسار (G1-> G2 ....) فقط لأوضح لك كيف فرضت المواقف بين العقد من المرتبة المتساوية ، فربما تريد أن تجعلها غير مرئية في مخططاتك الخاصة. أخيرًا ، العقد التي تحتوي على الملصقات التي تبدأ بـ "PH" هي العقد النائبة لـ "T-Junctions".

alt text

أنا هناك تقريبًا ، مستوحاة من استجابة قديمة على قائمة المراسلات GraphViz-Interest و إجابة دوغ.

الرمز التالي:

digraph G {
  edge [dir=none];
  node [shape=box];

  "Abraham"   [shape=box, regular=1, color="blue"] ;
  "Mona"      [shape=box, regular=1, color="pink"] ;
  "Clancy"    [shape=box, regular=1, color="blue"] ;
  "Jackeline" [shape=box, regular=1, color="pink"] ;
  "Herb"      [shape=box, regular=1, color="blue"] ;
  "Homer"     [shape=box, regular=1, color="blue"] ;
  "Marge"     [shape=box, regular=1, color="pink"] ;
  "Patty"     [shape=box, regular=1, color="pink"] ;
  "Selma"     [shape=box, regular=1, color="pink"] ;
  "Bart"      [shape=box, regular=1, color="blue"] ;
  "Lisa"      [shape=box, regular=1, color="pink"] ;
  "Maggie"    [shape=box, regular=1, color="pink"] ;
  "Ling"      [shape=box, regular=1, color="blue"] ;

  a1 [shape=circle,label="",height=0.01,width=0.01];
  b1 [shape=circle,label="",height=0.01,width=0.01];
  b2 [shape=circle,label="",height=0.01,width=0.01];
  b3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Abraham -> a1 -> Mona};
  {rank=same; b1 -> b2 -> b3};
  {rank=same; Herb; Homer};
  a1 -> b2
  b1 -> Herb
  b3 -> Homer

  p1 [shape=circle,label="",height=0.01,width=0.01];
  q1 [shape=circle,label="",height=0.01,width=0.01];
  q2 [shape=circle,label="",height=0.01,width=0.01];
  q3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Homer -> p1 -> Marge};
  {rank=same; q1 -> q2 -> q3};
  {rank=same; Bart; Lisa; Maggie};
  p1 -> q2;
  q1 -> Bart;
  q2 -> Lisa;
  q3 -> Maggie;

  x1 [shape=circle,label="",height=0.01,width=0.01];
  y1 [shape=circle,label="",height=0.01,width=0.01];
  y2 [shape=circle,label="",height=0.01,width=0.01];
  y3 [shape=circle,label="",height=0.01,width=0.01];
  {rank=same; Clancy -> x1 -> Jackeline};
  {rank=same; y1 -> y2 -> y3};
  {rank=same; Marge; Patty; Selma};
  {rank=same; Bart; Ling}
  x1 -> y2;
  y1 -> Marge;
  y2 -> Patty;
  y3 -> Selma;
  Selma -> Ling;
}

ينتج هذا الآن:

alt text

لذا ، تبدو جيدة باستثناء تلك الحافة الغريبة حول هوميروس. إذا تمكنت من إيجاد طريقة لتحريك إبراهيم ، منى والأعشاب إلى الجانب الأيسر من الصورة ، كان لدي صورة محاذاة مثالية.

أي أفكار حول كيفية تحقيق ذلك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top