Programmierung

Graph-Darstellung mit Overlays

Interaktive Graphen

Picture- und MetaPicture-Objekte geben dem CONZEPT 16-Entwickler die Möglichkeit, Grafiken unterschiedlicher Dateiformate in der Benutzeroberfläche darzustellen. Im Laufe der Zeit wurden die Objekte jedoch um viele Funktionen erweitert, so dass sich die Anwendungsmöglichkeiten nicht nur auf die reine Anzeige von Bildern beschränken, wie der nachfolgende Artikel demonstrieren soll.

Einleitung

Das Picture-Objekt dient der Anzeige von Rastergrafiken. Populäre Vertreter diesen Typs sind TIFF-, JPEG- oder PNG-Dateien. Das MetaPicture-Objekt hingegen zeigt Vektorgrafiken an. Hier werden die Dateiformate WMF und EMF unterstützt. Diese bieten gegenüber den Rastergrafiken den Vorteil, dass sie ohne Verluste skalierbar sind.
Ein interessantes Feature von Picture- und MetaPicture besteht in der Möglichkeit, dass den Objekten wiederum Picture- und MetaPicture-Objekte untergeordnet werden können.

Overlays
Abb.1: Anwendung von Overlays

Die untergeordneten Picture- und MetaPicture-Objekte werden hierbei als Overlays bezeichnet, da sie das übergeordnete Hauptbild überlagern. Das Beispiel ‘PicOverlayDashboard’ in der CodeLibrary zeigt dies am Beispiel eines Tachometers sowie einer Ladezustandsanzeige (Abb.1).
Die Tachonadel wird durch ein Overlay dargestellt, die das Hauptbild (den Tachometer) überlagert. Die Drehung der Tachonadel wird durch die Eigenschaft wpRotation des Overlay erreicht. Ähnlich verhält es sich mit der Batterieanzeige: dort ist der grüne Balken das Overlay.
Overlays bieten, wie das übergeordnete Hauptbild, auch die Möglichkeit Text anzuzeigen. Hierfür existiert die Eigenschaft wpTextLabel. Textfarbe und Position sind ebenfalls einstellbar (Weiterführender Blog-Artikel: Grafische Darstellung von Kennzahlen).

Graphen
GraphAbb.2: Der Graph

Im Folgenden soll beispielhaft dargestellt werden, wie damit die Erstellung eines einfachen Graphen bestehend aus Boxen (den Knoten) und Linien (den Verbindungen zwischen den Knoten) erreicht werden kann (Abb. 2). Der Graph an sich wird hierbei durch ein Picture-Objekt repräsentiert, welches die Box- und Line-Objekte in Form von Overlays enthält.

Die Graph-Bibliothek

Die Graph-Bibliothek (Datenbank am Ende des Artikels) besteht im Wesentlichen aus der Prozedur ‘GraphLib’. Diese implementiert die drei Komponenten Graph, GraphBox und GraphLine und stellt entsprechende Funktionen zu deren Erstellung und Verwendung bereit. Die Prozedur ‘GraphLib.Include’ beinhaltet ein paar Makros, die für den Aufruf der bereitgestellten Funktionen benötigt werden.
GraphBox
Eine Instanz eines GraphBox-Objektes wird mit der Funktion ‘GraphBox.Create’ generiert.

sub GraphBox.Create
(
  aTitle           : alpha;   // Anzuzeigender Text
  opt aPosGridLeft : int;     // Position linke Seite der Box (default = 0)
  opt aPosGridTop  : int;     // Position obere Seite der Box (default = 0)
  opt aWidthGrid   : int;     // Breite der Box (default = 6)
  opt aHeightGrid  : int;     // Höhe der Box (default = 2)
)

: handle;

Der Funktion wird ein Titel für den anzuzeigenden Text übergeben sowie die Koordinaten der Box. Diese werden zur einfacheren Positionierung in Raster-Koordinaten übergeben. Ein Raster-Punkt entspricht hierbei 16 Pixel. Die Größe wurde beliebig gewählt und kann in der Prozedur ‘GraphLib.Include’ angepasst werden. Höhe und Breite der Box werden ebenfalls in Raster-Koordinaten angegeben. Alle Positions- und Größenangaben sind optional.

Manchmal ist es praktikabler, wenn die Position einer Box relativ zu einer anderen angegeben werden kann. Zu diesem Zweck gibt es die Funktion ‘GraphBox.MoveToBox’.

sub GraphBox.MoveToBox
(
  aGraphBoxToMove   : handle;   // Zu positionierende Box
  aGraphBox         : handle;   // Box zu der relativ positioniert werden soll
  aPosMode          : int;      // Modus
  opt aDistanceGrid : int;      // Distanz in Grid-Koordinaten (default = 0)
)

Das Argument aPosMode gibt an, ob die Box (aGraphBoxToMove) links, rechts, oberhalb oder unterhalb der angegebenen Box (aGraphBox) positioniert werden soll. Das optionale Argument aDistanceGrid gibt an, um wie viele Rastereinheiten verschoben werden soll.

Um auf Mausklicks des Anwenders reagieren zu können, existiert die Funktion ‘GraphBox.SetMouseEvent’.

sub GraphBox.SetMouseEvent
(
  aGraphBox      : handle;    // Box
  aEventFunction : alpha;     // Ereignisfunktion
)
{ aGraphBox->WinEvtProcNameSet(_WinEvtMouse,aEventFunction); }

Diese leitet alle Mauseingaben an die angegebene Ereignisfunktion weiter.

Neben den erwähnten Funktionen gibt es noch weitere zum Setzen und Lesen des Anzeigetextes sowie der Füllfarbe.
GraphLine
Zum Erstellen einer Verbindung existiert die Funktion ‘GraphLine.Create’. Sie hat keine Argumente und liefert lediglich den generierten Deskriptor zurück. Zum Definieren einer Verbindung zwischen zwei Boxen muss anschließend ‘GraphLine.Connect’ aufgerufen werden.

sub GraphLine.Connect
(
  aGraphLine : handle;      // Verbindung
  aBoxFirst  : handle;      // Box für Startpunkt der Verbindung
  aBoxSecond : handle;      // Box für Endpunkt der Verbindung
)

Die Verbindung passt sich nicht automatisch an, wenn sich Position oder Größe einer der Boxen nachträglich verändert. In diesem Fall muss ‘GraphLine.Connect’ einfach erneut aufgerufen werden.
Graph
Das Graph-Objekt stellt den Container für die GraphBox- und GraphLine-Objekte dar und wird mit der Funktion ‘Graph.Create’ erstellt.

sub Graph.Create
(
  aRect     : rect;     // Position und Größe des Anzeigebereiches
)
: handle;

Im Argument aRect wird der Anzeigebereich des Graphen übergeben. Über die Funktionen ‘Graph.AddBox’ und ‘Graph.AddLine’ werden die zuvor generierten Box- und Line-Objekte (als Overlays) zum Graphen hinzugefügt und dadurch sichtbar gemacht.

Die Beispiel-Datenbank

Der Download enthält die Datenbank mit den oben beschriebenen Funktionen. Die Prozedur ‘Demo’ erstellt den Graphen aus Abb. 2 unter Verwendung der vorgestellten Funktionen.

Download

Graph-Demo graph.zip (32.00 KB)
Sie müssen angemeldet sein, um die Datei herunterladen zu können.

Keine Kommentare

Kommentar abgeben