AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign konzeptionelle Gedanken optische Darstellung Stammbaum
Thema durchsuchen
Ansicht
Themen-Optionen

konzeptionelle Gedanken optische Darstellung Stammbaum

Ein Thema von hansklok · begonnen am 5. Aug 2015 · letzter Beitrag vom 14. Mai 2018
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#1

konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 03:34
Ein herzliches Hallo an alle,

Ich würde gern einen Stammbaum grafisch und interaktiv ausgeben. Jedes Element soll anklickbar sein.

Ich dachte mir, dass ich dazu zwei Klassen brauche: TFamilyTree (abgeleitet von TCanvas) und TTreeItem.

TFamilyTree hat folgende Eigenschaften, da ich bis zu 4 Generationen (optional) abbilden möchte:
  • Proband: TTreeItem
  • Children: TObjectList (TTreeItem)
  • Father: TTreeItem
  • Mother: TTreeItem
  • GrandPaA: TTreeItem
  • GrandPaB: TTreeItem
  • GrandMaA: TTreeItem
  • GrandMaB: TreeItem
  • Offset: TBitmap
Später könnten auch noch eine Liste mit den Partnern (Spouses) und Geschwistern (Siblings) hinzugefügt werden. Es geht aber erstmal ums Prinzip.

TTreeItem hat folgende Eigenschaften:
  • ID: Integer
  • Offset: TBitmap
  • Width: Integer = 200
  • Height: Integer = 75

Nun soll TFamilyTree beispielsweise nie größer als 800x600 Pixel sein. Die Größe des Offsets soll sich dynamisch generieren. Dazu muss folgendes gecheckt werden:
  • gibt es einen Probanden?
  • hat der Proband Eltern? Einen Teil, oder beide (Breite würde sich verdoppeln!)
  • hat der Proband Kinder? (Breite generiert sich dynamisch aus der Anzahl der Kinder + 20 Pixeln Abstand dazwischen)
  • so in etwa, mit den Großeltern wäre es dasselbe, wobei in der 1. Generation da ja maximal 4 TTreeItems nebeneinander stünden

Hat ein Proband nun sehr viele Kinder, wir das Offset schnell breiter, als 800 Pixel.

Mich würde nun interessieren, wie man möglichst sinnvoll und WIE die Breite und Höhe des Offsets vorab berechnen kann und wie man bei einer festen Breite und Höhe von TFamilyTree diesen via Scrollbars scrollen kann, aber so, dass man die Objekte immer noch richtig anklicken kann (also eine Koordinatenfrage!).

Hat jemand etwas ähnliches schon einmal versucht? Könnt ihr mir folgen? Habe ich mir die richtigen Gedanken gemacht?

Danke Euch im Voraus.
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#2

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 07:42
Meines Erachtens ist der Ansatz grundlegend falsch. Du vermengst hier die Datenhaltung und die Bildschirmdarstellung.

Die Daten selbst sollten völlig I/O-unabhängig gespeichert werden, und für die Darstellung eines Knotens am Bildschirm definierst du ein TFrame.
Die Frames erzeugst du dynamisch nach Bedarf. Anklickbar sind die ganz von selbst, wenn sie einen scrollbaren Container als Parent haben (die Form selbst oder eine Scrollbox auf der Form), da brauchst du nichts selbst zu programmieren.

Übrigens: Was du mit offset: TBitmap vorhast, versteh ich überhaupt nicht.

Geändert von idefix2 ( 5. Aug 2015 um 07:46 Uhr)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
703 Beiträge
 
Delphi 12 Athens
 
#3

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 07:59
  • Proband: TTreeItem
  • Children: TObjectList (TTreeItem)
  • Father: TTreeItem
  • Mother: TTreeItem
  • GrandPaA: TTreeItem
  • GrandPaB: TTreeItem
  • GrandMaA: TTreeItem
  • GrandMaB: TreeItem
  • Offset: TBitmap
Die Großeltern kannst du dir sparen. GrandPaA ist doch einfach Father.Father
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 09:46
Ich denke auch, dass du da den falschen Ansatz wählst.
Wenn überhaupt, wird ein Teilbereiches des Baumes auf einen Canvas gemalt (ggf. über eine dritte Klasse), aber sollte sich nicht selber zeichnen, indem es von Canvas abgeleitet ist.
Warum eigentlich diese Beschränkung auf 800 x 600 Pixel in der Ausgabe?

Um mir Ideen zu holen, würde ich immer bei den großen Playern schauen, wie die bestimmte Sachen lösen.
Kennst du myheritage.com?
Deren Clientsoftware ist zwar etwas altbacken, aber die Darstellung eines Stammbaumes in der Web-Darstellung finde ich sehr gelungen.
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#5

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 13:36
Die Daten selbst sollten völlig I/O-unabhängig gespeichert werden, und für die Darstellung eines Knotens am Bildschirm definierst du ein TFrame.
...die Daten werden aus einer SQLite-Datenbank geholt, deswegen hat TTreeItem eine ID-Property!
Ich denke auch, dass du da den falschen Ansatz wählst.
Wenn überhaupt, wird ein Teilbereiches des Baumes auf einen Canvas gemalt (ggf. über eine dritte Klasse), aber sollte sich nicht selber zeichnen, indem es von Canvas abgeleitet ist.
Warum eigentlich diese Beschränkung auf 800 x 600 Pixel in der Ausgabe?

Um mir Ideen zu holen, würde ich immer bei den großen Playern schauen, wie die bestimmte Sachen lösen.
Kennst du myheritage.com?
Deren Clientsoftware ist zwar etwas altbacken, aber die Darstellung eines Stammbaumes in der Web-Darstellung finde ich sehr gelungen.
Genau, es geht ja nur um die Darstellung eines Teilbereiches. Gern würde ich alle möglichen Generationen iterativ darstellen, nur handelt es sich bei meinen Vorstellungen um eine Art "Sanduhrdiagramm". Die Darstellung müsste ja immer ausgehend vom Probanden generiert werden. Alles oberhalb hat immer einen Vater und eine Mutter, unterhalb haben alle Einträge 0..* Kinder.
Natürlich kenne ich MyHeritage
Von welcher dritten Klasse sprichst Du?
Die Beschränkung war ein Beispiel. Es get nur darum, dass das ganze Scrollbar sein soll.

Ich bin für Input weiterhin sehr dankbar, weil es zum Beispiel auch darum gehen wird, wie man dann die einzelnen Verbindungsknoten unter den Einträgen zeichnet etc. Äußerst komplex.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 14:18
Genau, es geht ja nur um die Darstellung eines Teilbereiches. Gern würde ich alle möglichen Generationen iterativ darstellen, nur handelt es sich bei meinen Vorstellungen um eine Art "Sanduhrdiagramm". Die Darstellung müsste ja immer ausgehend vom Probanden generiert werden. Alles oberhalb hat immer einen Vater und eine Mutter, unterhalb haben alle Einträge 0..* Kinder.
Und wo ist das Problem?

Ich würde TTreeItem (oder besser TPerson) so definieren:

Delphi-Quellcode:
TPerson = class
  Mother: TPerson;
  Father: TPerson;
  Name: String;
end;
Und mehr brauchst du gar nicht. Die Kinder musst du gar nicht speichern, weil sie sich implizit ergeben: Das sind die Personen, wo entweder Father oder Mother das jeweilige Subjekt sind.

Dann noch TFamilyTree in etwa so:
Delphi-Quellcode:
TFamilyTree = class
  Family: TList<TPerson>;
  function TreeToLayers(Subject: TPerson; Depth: Integer): TList<TLayer>;
end;
Um den Baum (eigentlich ein Graph) zu zeichnen, musst du über den Graphen iterieren und ihn in „Schichten“ (= Generationen) anordnen.
Delphi-Quellcode:
type
  TLayer = TList<TPerson>;

function TFamilyTree.TreeToLayers(Subject: TPerson; Depth: Integer): TList<TLayer>;
  procedure AssignPerson(Person: TPerson; Layers: TList<TLayer>; LayerIndex: Integer);
  begin
    if LayerIndex >= Layers.Count then exit;
    Layers[CurrentLayerIndex].Add(Person);
    AssignPerson(Person.Mother, Layers, LayerIndex+1);
    AssignPerson(Person.Father, Layers, LayerIndex+1);
  end;
var
  i: Integer;
begin
  Result := TList<TLayer>.Create;
  for i := 0 to Depth-1 do
    Result.Add(TLayer.Create);
  AssignPerson(Subject, 0);
end;
In dem Beispielcode werden nur die Ahnen berücksichtigt, aber es ist nicht schwer es so zu erweitern, dass auch Kinder, Geschwichter, Cousins etc. in die jeweiligen Schichten eingefügt werden. Man muss dann nur aufpassen, dass man einen Knoten nicht mehrfach hinzufügt.

Die Schichten kannst du dann problemlos in einer Richtung zeichnen.
  Mit Zitat antworten Zitat
Bentissimo

Registriert seit: 25. Apr 2006
Ort: Friedenfels
82 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 14:20
In einem meiner kommerziellen Programme habe ich etwas vergleichbares für Schach, speziell Eröffnungsvarianten, gebaut.

http://project-it.de/horst/images/pr...antenbaum2.gif

Dafür habe ich das TdxOrgChart von DexExpress verwendet. Diese Komponente bietet eigentlich alles, was Du für Deine Anforderung benötigst und natürlich gibt es auch eine datenbasierte Variante. Nachteil ist aber natürlich der nicht unerhebliche Kostenfaktor, da es das TdxOrgChart nur als Teil der VCL Subscription gibt.
Stephan Schmahl
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#8

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 14:34
Es get nur darum, dass das ganze Scrollbar sein soll.
Worin besteht das Problem?
Für die Darstellung der einzelnen Knoten nimmst du geeignete visuelle Komponenten. Die Komponenten wissen auch, wenn sie gescrollt werden, wann sie angeklickt werden, und du kannst in den entsprechenden Ereignisroutinen (onclick etc.) darauf reagieren. Um das Scrollen brauchst du dich nicht zu kümmern.

Die Bildschirmdarstellung sollte ausser der Bildschirmdarstellung nichts tun, insbesonders keine Strukturdaten enthalten. Auf Grund der Strukturdaten, die du in eigenen Klassen bereit hältst, die mit der Darstellung am Schirm gar nichts zu tun haben, erstellst du dann die visuellen Komponenten.

Also nicht: Visuelle Komponente enthält Referenz auf Datenbankwert
sondern - Aus der Datenbank erzeuge Baum bzw. Netzstruktur, und dann erzeuge für jeden Netzknoten adäquate visuelle Controls mit geeigneten Namen. Wenn ein Control angeklickt wurde, weisst du auf Grund des Parameters "Sender" in allen Ereignisbehandlungsroutinen, wer angeklickt wurde.

Und mehr brauchst du gar nicht. Die Kinder musst du gar nicht speichern, weil sie sich implizit ergeben: Das sind die Personen, wo entweder Father oder Mother das jeweilige Subjekt sind.
Es kann schon ganz praktisch sein, wenn von jedem Knoten weg in alle Richtungen verkettet wird:
Person -> Vater
Person -> Mutter
Person -> nächstälteres Geschwister
Person -> nächstjüngeres Geschwister
Person -> jüngstes (oder ältestes) Kind

edit
Wobei das mit den Geschwistern komplizierter ist, es gibt ja auch Halbgeschwister und dergleichen. Da ist es vielleicht wirklich am besten, wie Namenloser schreibt, nur die Eltern zu speichern und für alles andere die Liste aller Personen durchzugehen. So viele Leute können das nicht sein, dass da Performance Probleme drohen würden.

Geändert von idefix2 ( 5. Aug 2015 um 14:43 Uhr)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 14:39
Und mehr brauchst du gar nicht. Die Kinder musst du gar nicht speichern, weil sie sich implizit ergeben: Das sind die Personen, wo entweder Father oder Mother das jeweilige Subjekt sind.
Es kann schon ganz praktisch sein, wenn von jedem Knoten weg in alle Richtungen verkettet wird:
Person -> Vater
Person -> Mutter
Person -> nächstälteres Geschwister
Person -> nächstjüngeres Geschwister
Person -> jüngstes (oder ältestes) Kind
Redundanz ist in meiner Erfahrung immer schlecht und gilt es so gut es geht zu vermeiden. Man kann sich Methoden bauen, die einem die entsprechenden Familienmitglieder zurückgeben. Aber man sollte sie nicht explizit speichern.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: konzeptionelle Gedanken optische Darstellung Stammbaum

  Alt 5. Aug 2015, 14:44
In einer modernen Welt könnte man auch Father/Mother durch SPouse1/Spouse2 ersetzten oder noch besser die Eltereigenschaft getrennt setzen.
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz