![]() |
Suche Pfeile zur Visualisierung von Beziehungen
Hallo Wissende,
ich habe ein kleines Tool, mit dem sich XP-Buttons oder ähnliche Inhaltsträger erstellen kann, um Gruppen anzulegen. Diese werden dann einfach mit der Caption befüllt und so verschoben wie man sich die Struktur eines Unternehmens o.ä. vorstellt. Um diese nun noch in Beziehungen zu bringen suche ich noch eine Komponente, die mir verschiedene Pfeile bietet, die zumindest einige Anpassungen ermöglicht, wie z-b.: Farbe, Grösse, Drehwinkel, Pfeilgrösse und Dicke... Irgendwie konnte ich nicht wirklich was finden. Das was ich bei Torry gefunden habe, war nicht Live-Tauglich, also nicht z.b. nicht drehbar. Wenn man die Pfeile an die Buttons oder andere Controls andocken könnte wäre das auch cool. |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Wenn's was kosten darf:
ExpressOrgChart Suite $129.99 with full source code, $89.99 without full source code ![]() |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Danke für Deinen Tipp! Leider war das nicht das, was ich suche, da die nur das bieten, was ich schon habe. Ich brauche einfach nur die Pfeile, um die Beziehungen selbst dazwischen herstellen zu können. Ich könnte das zwar auch mit tranparenten PNG-Pfeilen machen, aber dann kann der Kunde nicht FREI drehen, sondern muss das Bild über eine Trackbar ändern. Das ist ziemlich umständlich und dauert manchmal auch zu lange...
Gibt es noch andere Möglichkeiten? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Spontan würd ich sagen, selber zeichnen :) Das sollte nicht zu schwer sein. Du brauchst lediglich eine Zeichenfläche (dürfte das Fenster sein auf dem die Buttons sind), sowie anfangs und endpunkte.
|
Re: Suche Pfeile zur Visualisierung von Beziehungen
Ok, da ich da noch nicht ganz durchsteige füge ich mal noch folgende Infos hinzu. Die Buttons, Panels und Gradients sind alles TControls, die auf einer TScrollbox platziert werden und live verschoben werden können. Ich brauche also einen oder mehrer Pfeile, welche ich dieser Scrollbox hinzufügen kann, die möglich auch von TControl kommen, damit ich diese auch ansprechen, verschieben und zur Laufzeit noch drehen und sonstwie ändern kann.
Wie könnte also Dein Ansatz da funktionieren? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Als Ansatz würde sich da TGraphicsControl anbieten. Zwei Punktkoordinaten für Anfangs- und Endpunkt als zusätzliche Propertys. und dann auf den Canvas entsprechend Pinseln. Die Position und Höhe und Breite haste automatisch mit dabei.
|
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hört sich gut an und liest sinnvoll, aber ich damit noch 0-Erfahrung und in diesem Forum waren NUR 5 Threads zum Thema TGraphicsControl zu finden. Naja, da werde ich wohl noch etwas googlen müssen. Ich hoffe nur, dass ich den gezeichneten Pfeil noch anklicken und verschieben kann!?
|
Re: Suche Pfeile zur Visualisierung von Beziehungen
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
ich hatte aktuell ein ähnliches Problem. Meine Verbinder sollen zwar nicht schräg laufen, dafür aber mehrere Ecken haben. Ich hab es mit TGraphicControl probiert. Dann auf TCustomControl geändert. Hier meine Erfahrungen: TGraphicControl: Vorteile: - Hintergrund ist schon transparent, Nachteile: - kein Focus - Größenänderung nicht mit Perform machbar - nicht durchklickbar TCustomControl: Vorteile: - alle meine anderen Visuellen Elemente sind von TCustomControl abgeleitet (gemeinsamme Basisklasse für Grundfunktionen Selektieren Größe ändern ...) - Fokus kann gewechselt werden (DoEnter, DoExit) Nachteile: - Hintergrund nicht transparent - nicht durchklickbar Gelöst habe ich die Themen: - Größenänderung machbar - durchklickbar Bsp.: siehe Anhang |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo,
das sieht schon eher nach dem aus, was ich suche. Also ich will ehrlich sein. Ich habe keine Ahnung, wie Du das realisiert hast, aber könntest du mir ein kleinen Happen zum Frühstück reichen? Nicht alles, einfach nur einen Anfang, da ich wirklich nicht weiss, wie es losgehen soll. Ich suche hier mal im Forum weiter danach, vielleicht finde ich ja was passendes... |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Liste der Anhänge anzeigen (Anzahl: 3)
Hi torud!
Mein ansatz war folgender. Ich benötige mehrere unterschiedliche Komponenten, die zur Laufzeit in einer ScrollBox erstellt und bearbeitet werden können. Dazu zählen verschiedenste Komponenten für spezielle Zwecke. Unter anderem sollen diese Elemente in Gruppenboxen angeordnet sein. Im Bild ist zum Bsp. Mein Label mit den entsprechenden Verbindern in einer Gruppenbox zu sehen. Damit ich von "außen" (Hauptprogramm) alle einheitlich suchen oder ansprechen kann, hab ich mir eine Basisklasse geschrieben, in der meine Grundfunktionen enthalten sind.
Delphi-Quellcode:
Von dieser Basisklasse leite ich dann meine weiteren Controls ab. Ein wesentlicher Unterschied zwischen meinen Connectoren und den anderen Elementen (z.B. Label) ist, dass der Connector über die Eckpunkte in seiner Größe verändert wird. Eckpunkt greifen und verschieben. Zwischen zwei Eckpunkten gibt es z.B. horizontale und vertikale Zugpunkte um die entsprechende Teillinie mit ihren Eckpunkten zu verschieben. Da hab ich recht lange dran gesessen.
TBaseCustomControl = class(TCustomControl)
private FCaption: String; FMoveable: Boolean; // Control verschiebbar FOnItemSelected: TNotifyEvent; FSelected: Boolean; // Control selectiert FShowMode: TSeyShowMode; // Anzeige für Programm-/Designdarstellung procedure SetCaption(const Value: String); procedure SetSelected(const Value: Boolean); protected procedure CreateWnd; override; procedure DoEnter; override; procedure DoExit; override; procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; procedure Paint; override; procedure SetFirstName; procedure SetName(const Value: TComponentName); override; procedure SetShowMode(const Value: TSeyShowMode); virtual; public Constructor Create(AOwner: TComponent); override; property Caption : String read FCaption write SetCaption; property Color; property Font; property Moveable : Boolean read FMoveable write FMoveable; property OnItemSelected : TNotifyEvent read FOnItemSelected write FOnItemSelected; property Selected : Boolean read FSelected write SetSelected; property ShowMode : TSeyShowMode read FShowMode write SetShowMode; published procedure DoItemSelected(Sender : TObject); virtual; end; Bei den Labels ist es einfacher, Dort kann ich durch Ziehen der äußeren Eckpunkte die Größe ändern. Den Code dazu findest du hier im Forum. Um das zu verdeutlichen hab ich noch mal was in den Anhang gelegt. Bei den Connectoren entstand zusätzlich das Problem, dass das Control ein Viereck ist, aber nur die Linien sichtbar sein sollen. Geht also ein Verbinder von links oben nach rechts unten, so würde er alle anderen Elemente verdecken (optisch und für Maus-Aktionen). Suche im Forum nach "durchklickbar", dann findest du entsprechende Beispiele für die Verwendung von Ranges. Ich helfe dir gerne bei deinem Problem, möchte aber nicht den kompletten Code hier posten. erstens habe ich das Projekt nicht als open Source angelegt, zweitens ist auch noch nicht alles fertig. Funktionen wie: - Ausrichten am Gitter - Fixieren an anderen (meinen) Controls - Verbindung von Eingangs-/Ausgangs-Gates - Anzeige und Bearbeitung von Eigenschaften sind nicht oder nur teilweise umgesetzt. Arbeite ich halt dran. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo,
es tut mir leid, wenn ich Deinen Ausführungen zwar inhaltlich folgen kann, aber eigentlich mit der Umsetzung total überfordert bin. Ich habe folgenden Link gefunden, der das Zeichnen eines Pfeiles von x,y nach x,y schon mal realisiert. ![]() Das hat zwar mit dem was Du tust, nichts zu tun, aber es bringt mich ein Stück weiter. Allerdings bin ich mit dieser Lösung KEINEN Schritt voran gekommen, da ich damit nur einen Pfeil zeichnen kann, aber danach habe ich nen Pfeil auf nem Canvas und habe eher keine Chance diesen zu bewegen oder zu löschen oder sonstwas mit ihm anzustellen... Also weiss ich jetzt zwar, wie ich einen Pfeil zeichne, aber ich weiss noch nicht genau, worauf ich ihn zeichnen soll. Wie wäre es mit einem TLabel? Oder welche Frage muss ich mir stellen, um wieder einen Schritt voran zu kommen? Bezüglich der Linien des Pfeiles gefallen mir die grässlichen Treppchen nicht. Aber ich habe auch blos keine Ahnung, wie man die wegbekommen kann. AntiAlaising!? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Ich habe gerade festegestellt, dass ich zwar gelernt habe, wie man Pfeile zeichnen lassen kann und dies dahingehend erweitert, dass ich erstmal die Pfeile von einem Button zum anderen zeichnen lasse, aber nachdem das Fenster mal im Hintergrund war, war durch ein Repaint des Fensters nichts mehr zu sehen von den Pfeilen. Eigentlich logisch.
Also muss ich wohl oder über auf eine Control zeichnen. Da scheint sich langsam der Kreis zu schliessen...Ich denke, dass ich jetzt dann zu TCustomControl gelangen werde!? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Zitat:
Somit hast du dein eigenes Control (TArrowControl), mit dem du alles notwendige anstellen kannst. Implementiere in dein neues Control eine Methode:
Delphi-Quellcode:
In die Procedure DrawArrow packst du deinen Code für das Zeichen deines Pfeiles.
procedure DrawArrow;
procedure Paint; override; procedure TArrowControl.Paint; begin inherited; DrawArrow; end; Registriere dieses Control als Komponente in einer eigenen Seite deiner IDE. Dann kannst du es zur Designzeit verwenden. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Liste der Anhänge anzeigen (Anzahl: 1)
Ehrlich gesagt ist das zu viel des Guten. Ich habe zum einen noch keine eigene Komponente erstellt und weiss auch nicht sooo recht, was Du da schreibst...Allerdings habe ich festgestellt, dass selbst der Cnavas des TLabels nach dem Neuzeichnen des Forms leer ist.
Ich erlaube mir mal mein Demo-Projekt anzuhängen, in der Hoffnung, dass Du oder ein andere mal testet und mir etwas weitere Hilfe gewährt... Zur Funktionalität: Einfach nur auf einen Button klicken und danach auf einen anderen button klicken. Beim 2. Buttonklick wird dann ein Pfeil vom ersten zum zweiten Button gezeicht, in ein Label, welches nicht generiert wurde, sondern alClient auf dem Form selbst liegt... Das dynamische Generieren eines Labels sollte kein Problem sein. Auch das ausrichten der Pfeile, die derzeit noch immer von oben links starten ist kein Problem, aber ich verstehe nicht wirklich alles von dem was Du da schreibst...Schaust Du bitte mal drüber...? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hi,
also, du hast jetzt zwei Möglichkeiten. 1. Du zeichnest alles auf deine Form. Dann ist das halt gezeichnet. Verschieben einzelner Elemente (Pfeile etc.) ist dann aber nicht möglich. Halt nur neu zeichen. Dein Formular hat ein Ereignis OnPaint. Wenn alles nach dem "Neuanzeigen" wieder gezeichnet werden muß, dann rufe deine Zeichenmethode von dort auf. 2. Du estellst dir eigene Controls. Dann empfehle ich dir dich erst mal mit der Erstellung eigener Klassen und Komponenten zu beschäftigen. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
ok, jetzt mit etwas mehr Zeit.
In deinem Demo zeichnest du zur Laufzeit die Linien und die Pfeile in den Canvas. Das erfolgt aber nur, wenn du auf den Button klickst. Wird dein Fenster neu gezeichnet, so musst du natürlich dafür sorgen, dass auch deine Linien und Pfeile neu gezeichnet werden. Um das zu ereichen, mußt du deine Zeichenmethoden in das OnPaint-Ereignis verlagern oder die Methode Paint des Controls (Fensters) auf dessen Canvas du zeichnest überschreiben. Zusätzlich ist es natürlich notwendig, dass du einen Start und Endpunkt hast. Fang mal einfach an. Lege einen Startpunkt und endpunkt im Code fest. Dann verlagere das, was du bei deinem ButtonClick machst in eine Procedure. Schreibe den Namen dieser Procedure in das OnPaint-ereignis. schwups wird immer dein Pfeil gezeichnet. Solltest du so nicht weiter kommen, so sag bescheid. Dann schau ich mir dein Demo mal genauer an und überarbeite den Code. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo,
wie ich ein eigenes TControl zur Laufzeit erstelle ist mir natürlich klar. Das ist nicht das Problem. Ich bin also schon in der Lage in TLabel zur Laufzeit zu erstellen und es so zu platzieren, dass es Sinn macht und dann darauf den Pfeil zu zeichnen. Das ist kein Problem. Aber wie verhindere ich, dass der Pfeil verschwindet, wenn das Form oder das Label selbst neu gezeichnet wird!? Diese Frage impliziert die Entscheidung zur Variante 2. Ich habe aber nicht vor, mir deshalb eine eigene Komponente zu programmieren, wenns sich nicht wirklich vermeiden lässt... |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hei torud,
das Erstellen zur Laufzeit reicht halt nicht. Die Klasse muß auch neue Eigenschaften besitzen. Halt Pfeil zeichnen. Kennst du eine Kompo oder Klasse die das kann? Ich denke nicht, sonst würdest du nicht fragen :lol: Also brauchst du eine neue Klasse! Ob du daraus auch gleich mittels Register eine Komponente in deiner IDE machst bleibt dir überlassen. Dieser neuen Klasse mußt du jetzt die Eigenschaft Pfeil zeichnen verpassen. Dazu gehören die entsprechenden Start- und Endpunkte deiner Linie und an welchem Punkt der Pfeil gezeichnet werden soll. Dann noch eine Procedure, die alles in den Canvas zeichnet, aufgerufen in der vererbten Procedure Paint und fertig. Das wars schon. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Ok, ich denke...das das dann mit nem neuen Thema verbunden ist und werde dann wohl nen neuen Thraed aufmachen oder aber mich zum Thema Erstellung einer Komponente beschäftigen...Muss ja auch lösbar sein oder!?
Soll ich nun ein TLabel nehmen oder bietet sich nicht ein TShape an? Und wie stellt man sicher, dass der gezeichnete Pfeil nicht immer verschwindet? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo Tom,
ich habe hier eine kleine Demo zusammengebaut, die dir zeigen soll, wie du möglicherweise auf eine Pfeil-Komponente verzichten kannst. Zum Testen benötigst du lediglich ein leeres Formular, auf das du zwei Panels (Panel1 und Panel2) legst. Die Ereignisse OnMouseDown, OnMouseMove und OnMouseUp der Panels verbindest du über den Objektinspektor mit den zugehörigen Methoden des folgenden Codes. Das Ereignis OnPaint des Formulars verbindest du mit der Methode FormPaint. Wenn du nun die Anwendung startest, solltest du beide Panels mit der Maus verschieben können. Ein Pfeil verbindet Panel1 mit Panel2.
Delphi-Quellcode:
Im Beispiel wird eine feste Verbindung eingezeichnet, in deiner Anwendung wirst du diese Verbindung variabel gestalten wollen. Du mußt dir dazu überlegen, wie du die beiden beteiligten Controls zusammen mit den benutzten Anschlußpunkten verwalten kannst.
// uses Math;
type TForm1 = class (TForm) Panel1: TPanel; Panel2: TPanel; procedure FormPaint (Sender: TObject); procedure PanelMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure PanelMouseMove (Sender: TObject; Shift: TShiftState; X,Y: Integer); procedure PanelMouseUp (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private FAnchor : TPoint; // Mausposition zu Beginn des Verschiebens FOrgPos : TPoint; // Position des Controls vor dem Verschieben FPanning : Boolean; // True während des Verschiebens end; CONST GRIDINTERVAL = 16; type TPin = (pinBody, pinLeft, pinTop, pinRight, pinBottom); // zeichnet einen Vektor mit einer Pfeilspitze procedure DrawVector (aCanvas: TCanvas; x1, y1, x2, y2: Integer; aHeadSize: Integer = 5; aFillHead: Boolean = False); const ApexAngle = 30 * Pi / 180; var dx, dy : Integer; angle : Double; s1, c1 : Extended; s2, c2 : Extended; P1, P2 : TPoint; begin aCanvas.MoveTo (x1, y1); aCanvas.LineTo (x2, y2); if (x1 <> x2) then angle := {Math.}ArcTan2(y2 - y1, x2 - x1) else if (y1 < y2) then angle := Pi / 2 else angle := 3 * Pi / 2; {Math.}SinCos (angle - ApexAngle, s1, c1); {Math.}SinCos (angle + ApexAngle, s2, c2); P1.x := x2 - Round(c1 * aHeadSize); P1.y := y2 - Round(s1 * aHeadSize); P2.x := x2 - Round(c2 * aHeadSize); P2.y := y2 - Round(s2 * aHeadSize); if aFillHead then aCanvas.Polygon ([P1, Point(x2, y2), P2]) else begin aCanvas.MoveTo (P1.x, P1.y); aCanvas.LineTo (x2, y2); aCanvas.MoveTo (P2.x, P2.y); aCanvas.LineTo (x2, y2); end; end; // Liefert die Position eines Anschlußpunktes für ein Control function PinPosition (aControl: TControl; aPin: TPin): TPoint; var w2, h2 : Integer; begin w2 := aControl.Left + aControl.Width div 2; h2 := aControl.Top + aControl.Height div 2; case aPin of pinLeft: Result := Point(aControl.Left, h2); pinTop: Result := Point(w2, aControl.Top); pinRight: Result := Point(aControl.Left + aControl.Width, h2); pinBottom: Result := Point(w2, aControl.Top + aControl.Height); else Result := Point(w2, h2); end; end; procedure TForm1.PanelMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FAnchor := Mouse.CursorPos; FOrgPos := TControl(Sender).BoundsRect.TopLeft; FPanning := True; end; procedure TForm1.PanelMouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); var xPos, yPos : Integer; begin if FPanning then begin xPos := FOrgPos.X + (Mouse.CursorPos.X - FAnchor.X); yPos := FOrgPos.Y + (Mouse.CursorPos.Y - FAnchor.Y); TControl(Sender).Left := xPos - (xPos mod GRIDINTERVAL); TControl(Sender).Top := yPos - (yPos mod GRIDINTERVAL); Invalidate; end; end; procedure TForm1.PanelMouseUp (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FPanning := False; end; procedure TForm1.FormPaint (Sender: TObject); var P1, P2 : TPoint; begin inherited; // zeichne eine Verbindung von Panel1 (rechter Anschlußpunkt) zu Panel2 (linker Anschlußpunkt) P1 := PinPosition(Panel1, pinRight); P2 := PinPosition(Panel2, pinLeft); Canvas.Pen.Color := clBlue; Canvas.Brush.Color := clBlue; { Canvas.Pen.Width := 2; Canvas.MoveTo (P1.X, P1.Y); Canvas.LineTo (P2.X, P2.Y); } DrawVector (Canvas, P1.X, P1.Y, P2.X, P2.Y, 10, True); end; end. Der Code wird sicher nicht genau dem entsprechen, was du dir vorstellst, er soll lediglich das Prinzip zeigen. Um die Treppen bei den Linien zu entfernen, könntest du das ![]() Gruß Hawkeye |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo Hawkeye,
vielen Dank für Dein Beispiel. Ich finde es so wie es ist schon ganz ok. Nun kommen die ABERS...für die ich sicher selbst versuchen muss eine Lösung zu finden. Die Pfeile sind nicht verwaltbar. Sie nicht verschiebbar oder sonstwie editierbar. Logisch, sie folgen ja automatisch ihrer Bindung. Das ist auch gut so! Die Pfeile gehen nicht umme Ecke. :-) => Das ist sicher auch einer der schwierigen Abschnitte. Auch wandert die Pfeilspitze und der Linienanfang nicht mit, wenn man die Seiten der Panels vertauscht. Ich könnte mir zwar im Hintergrund eine Liste halten, wo ich mir nortiere, welche Controls miteinander verbunden sind und dann desweiteren noch notieren, was für ein Pfeil zwischen den Controls ist (Farbe,Style usw.) aber ich denke, dass das ziemlich aufwendig ist. Ich denke insgesamt, ist das eigentlich schon ein Riesenprojekt für sich, an dem mich wundert, dass es sowas noch nicht gibt. Die Jungs von TMS haben zwar sowas schon, aber geht dies nur in deren DiagrammStudio. Ansonsten habe ich nicht wirklich viel zu diesem Thema finden können. Zum einen wäre es das allereinfachste eine Komponente zu haben, die man einfach nur platziert und man hat einen fertigen Pfeil, den man in der Grösse, Drehrichtung, Farbe und sonstigem Styling anpassen kann. Wenn dieser noch an dere Control gedockt werden kann, wäre es perfekt. Ich schwanke noch zwischen den beiden Lösungen, weiss aber auch, dass ich nicht in der Lage sein werde, sowas komplett allein zu erstellen...Was sind Eure Favoriten!? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hi torud,
Zitat:
In dem du es in einer Klassen kapselst programmierst du das Verhalten incl. der Eigenschaften einmal und erstellst zur Laufzeit mehrere Instanzen (bei dir also Pfeile). Wenn du in deiner Klasse eine Eigenschaft LineColor definierst, dann nimmst du beim zeichnen eben nicht eine feste Farbe, sonder FLineColor. Jedes Pfeilobjekt hat somit sein eigenes LineColor was es sich selber merkt. Ich denke Hawkeye hat sein einfaches Beispiel ganz bewust so gewählt. Du hast zur Zeit zwei wesentliche Probleme: 1. dir ist das Prinzip von OOP noch nicht ganz klar, 2. du hast noch kein "Gefühl" dafür wie das Prinzip der VCL abläuft. Mit Hawkeye's Beispiel kannst du eventuell den 2. Punkt etwas klarer sehen. Da siehst du gut, wie das mit dem Zeichnen und darstellen abläuft, ohne das dir gleich einer was von eigenen Controls erzählt. An deiner Stelle würde ich Hawkeye's Beispiel nehmen und versuchen die fehlenden Sachen zu ergänzen. Dann schaun wir weiter. Der weg zur eigenen Klasse ist dann auch nicht weit. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hello Again,
ich danke Euch beiden für Eure hilfreichen Tipps und den Hinweis darauf, dass ich meine Schwachstellen abdichten muss. Ich gelobe Besserung. => Binsoweit, dass der Pfeil fast richtig mitwandert... Ich habe mich etwas mit dem Beispiel auseinandergesetzt, da ich finde, dass ich schon verstehen muss, was da passiert und sicher einiges davon gebrauchen kann, was drin geschrieben steht. Ich beziehe mich jetzt also auf das Beispiel mit den beiden Panels. Dort gibt es die Routine FormPaint, wo bisher geschrieben stand, von wo nach wo der Pfeil gezeichnet werden soll. Ich habe versucht diese Routine zu verfeinern, bin aber nicht wirklich glücklich mit der Lösung, da ich, wie ich finde eigentlich einen Winkel um jeden Pin legen müsste. Wenn sich das andere Panel in einem der Winkel befindet, oder es tangiert, wäre klar, dass von wo nach wo der Pfeil gezeichnet werden muss. Da mir dazu die Routine fehlt, habe ich es erstmal provisorisch so gelöst:
Delphi-Quellcode:
Der Code könnte Fehler beinhalten, da ich ihn mit der Hand abschreiben musste. Sitze hier an einem Rechner, wo ich nicht mal eben den Code vom Stick kopieren kann.
procedure TForm1.FormPaint (Sender: TObject);
var P1, P2 : TPoint; begin inherited if Panel1.Top > Panel2.Top + Panel2.Height then P1 := PinPosition(Panel1,pinTop); if Panel1.Top < Panel2.Top + Panel2.Height then P1 := PinPosition(Panel1,pinBottom); if Panel1.Top = Panel2.Top then P1 := PinPosition(Panel1,pinRight); if Panel1.Left < Panel2.Left then P2 := PinPosition(Panel2,pinLeft); if Panel1.Left > Panel2.Left then P2 := PinPosition(Panel2,pinLeft); if Panel1.Left = Panel2.Left then if Panel1.Top < Panel2.Top then P2 := PinPosition(Panel2,pinTop); if Panel1.Top > Panel2.Top then P2 := PinPosition(Panel2,pinBottom); {und dann der rest vom Schützenfest} end; Problem oder Unsauberkeit des Codes ist, dass Pfeil nur dann Rechts oder Links angedockt wird, wenn die beiden Panels auf gleicher Höhe sind. Besser wäre aber, wenn in der Routine ein gewisser Bereich berücksichtigt werden würde. Skizziert sieht das ganz einfach aus. man zeichne ein Panel in die Mitte und ziehe linien diagonal durch. Die dadurch enstehenden 4 Bereiche sind die Bereiche, die wichtig sind. Wie kann ich das nun ermitteln??? |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hi torud,
Zitat:
Dann nimmst du deinen Verbindungspunkt deines zweiten Panels und berechnest für die Koordinatenwerte die entsprechende Lage der Graphen. Mit einfacher <> Prüfung auf X und Y kannst du dann den "Quadranten" (eigentlich sind es ja keine) ermitteln, in dem dein zweites Panel in Bezug auf dein erstes Panel liegt. danach dei festgelegten Punkte verbinden. Die Festlegung der Typen für pinTop etc. sind übriegens sehr gut. Das erhöht ungemein die Lesbarkeit des Codes. Gruß oki |
Re: Suche Pfeile zur Visualisierung von Beziehungen
also das klingt jetzt ganz schön kompliziert. ich werde mal das forum nach graphen und alldem, was du da geschrieben hast, durchsuchen, da mein mathe mehr als eingerostet ist und ich zwar alles mögliche im kopf rechne, aber winkelfunktionen und dergleichen zuletzt vor ca. 19 jahren hatte... :shock:
mir ist schon klar, dass bei dem zeichnen der diagonalen 4 dreiecke entstehen und ich nur checken muss, ob das 2. panel in einem der bereiche ist. |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo Tom,
die Position der beiden beteiligten Panels zueinander läßt sich recht einfach mit dem ![]()
Delphi-Quellcode:
Die Lösung von oki (mehrere Ecken pro Verbindung) ist natürlich wesentlich ansprechender, aber auch etwas aufwendiger.
procedure TForm1.FormPaint (Sender: TObject);
procedure DoDrawVector (aPin1, aPin2: TPin); var P1, P2 : TPoint; begin P1 := PinPosition(Panel1, aPin1); P2 := PinPosition(Panel2, aPin2); Canvas.Pen.Color := clBlue; Canvas.Brush.Color := clBlue; DrawVector (Canvas, P1.X, P1.Y, P2.X, P2.Y, 10, True); end; var code : Integer; begin inherited; // Lagecode des ersten Panels bezogen auf das zweite Panel ermitteln code := 0; if (Panel1.Left + Panel1.Width < Panel2.Left) then Inc (code, 1); if (Panel1.Left > Panel2.Left + Panel2.Width) then Inc (code, 2); if (Panel1.Top + Panel1.Height < Panel2.Top) then Inc (code, 8); if (Panel1.Top > Panel2.Top + Panel2.Height) then Inc (code, 4); // Vektor in Abhängigkeit des Lagecodes zeichnen case code of 1: DoDrawVector (pinRight, pinLeft); 2: DoDrawVector (pinLeft, pinRight); 4: DoDrawVector (pinTop, pinBottom); 5: DoDrawVector (pinTop, pinLeft); 6: DoDrawVector (pinTop, pinRight); 8: DoDrawVector (pinBottom, pinTop); 9: DoDrawVector (pinBottom, pinLeft); 10: DoDrawVector (pinBottom, pinRight); end; end; Gruß Hawkeye |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Wird sofort ausprobiert.
Feedback garantiert! |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
also das funktioniert nun schon ganz gut. Folgendes interessiert mich nun noch. Wie kann ich den Pfeil auch mit einer gestrichelten Linie darstellen? - Canvas.Pen.Style := psDashDot; //führte nicht zum Erfolg Ist es möglich auch einen Doppelpfeil darstellen zu lassen? - Ich denke, dass ich dazu DrawVector etwas modifizieren müsste...!? Was muss ich tun, um den Pfeil mit Grafics32 besser aussehen zu lassen? - Mich stören noch die Treppchen in der Linie. Wie könnte ich intern die Pfeile verwalten? - Ich weiss, das OKI sicher wieder darauf verweisen wird, dass es besser wäre eine eigene Extra-Komponente zu erstellen. Ich gebe ihm da auch recht, aber in der Kürze der Zeit ist das derzeit nicht drin. --Anfang sollen also gar keine Pfeile zwischen den Controls sein. Der User soll auswählen können von wo nach wo ein Pfeil erstellt werden soll. Dazu müsste ich mir intern notieren: - von Control - nach Control - Art der Pfeilspitze - Farbe des Pfeiles - Style der Pfeillinie Bei jedem FormPaint müsste ich dann in einer Schleife die interne Liste abarbeiten und die Pfeile neuzeichnen. Was empfehlt ihr hierzu? Ich würde es in einer einer TStringlist vorhalten und die Eigenschaften eines jeden Pfeiles in einem Item Semikolon-getrennt schreiben und in einer Extraliste dem User visualisieren. Gehts auch anders? Oder anders gefragt, macht es anders mehr Sinn? Im Anhang mein aktuelles Beispiel... |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo Tom,
Zitat:
Zitat:
Zitat:
Zitat:
Gruß Hawkeye |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Wissende,
im Anhang habe ich ein erstes Ergebnis als Bild angehangen. WIe ich finde nicht soo schlecht. Leider habe ich doch noch ein paar Fragen, da wie Ihr vielleicht zustimmen werdet, die Pfeile noch nicht optimal verlaufen. Die Pfeile von Objekt 2 zu 3 und 5 wären mir OnTop wesentlich lieber, damit es einheitlicher wirkt. Das Fenster zur Pfeileverwaltung zeige ich nur Modal an und sobald ich es über das Fenster mit den Pfeilen schiebe, werden diese gelöscht und erst dann neu gezeichnet, wenn ich auf die Paintbox klicke, die ich alClient auf die Scrollbox gelegt habe. Wie kann ich das umgehen? Ich habe schon my_controls.PaintBox.Repaint; versucht, wenn ich das Fenster bewege und dann mit der Maus loslasse, aber es wird nicht neu gezeichnet. Wenn ich die Objekte bewege und verschiebe, werden die Pfeile neu gezeichnet, aber die alten bleiben vorhanden. Erst wenn ich wieder auf die Paintbox klicke, werden alle Pfeile gelöscht und neu gezeichnet... Die Ereignisse zu den Control bei MouseDown,MouseMove oder MouseUp musste rausnehmen, da ich eine andere Komponente zum verschieben der Controls benutze. Wenn ich diese Routinen anbinde, dann reicht es, wenn ich mit der Maus in die Nähe komme und schon laufen mir die Controls vor der Maus weg. Sieht zwar lsutig aus, aber ist so nicht zu gebrauchen. Ich werde mal sehen, was in den 3 Routinen gemacht wird, damit ich es vielleicht selbst woanders implementiere... Über Ideen und Anregungen würde ich mich freuen... |
Re: Suche Pfeile zur Visualisierung von Beziehungen
Das regelmäßige Zeichnen habe ich hinbekommen. Ich musste hier und da OnFormPaint aufrufen, bzw. in OnFormPaint das Zeichnen der Paintbox anbinden. Die restlichen Fragen sind leider noch offen...
|
Re: Suche Pfeile zur Visualisierung von Beziehungen
Hallo Tom,
die Anschlußpunkte für die Pfeile kannst du frei bestimmen, du mußt nur geeignete Bedingungen für die Auswahl der Parameter von DoDrawVector finden. In meinem Beispiel habe ich diese Parameter einfach in Abhängigkeit des Lagecodes gewählt. Du wirst wahrscheinlich weitere Informationen einfließen lassen, z.B. den x- oder y-Abstand der beteiligten Panels oder die Steigung des Verbindungspfeils. Gruß Hawkeye |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz