TAChart Tutorial: BarSeries/de
│
Deutsch (de) │
English (en) │
suomi (fi) │
русский (ru) │
Einführung
Die TAChart-Bibliothek kann eine Vielzahl von Diagrammen in Lazarus erstellen. Aber im Vergleich zu anderen Serientypen scheinen Balken-Plots schwieriger zu sein, vor allem, weil es eine Vielzahl von Möglichkeiten gibt:
- Nebeneinander angeordnete Balken
- Gestapelte Balken
- Gestapelte Balken, auf 100 % normiert
- Vertikale Balken
- Horizontale Balken
In diesem Tutorial möchten wir dir die Grundidee zeigen, wie du ein Diagramm mit mehreren nebeneinander angeordneten Balkenreihen erstellen kannst. In einem Nachfolge-Tutorial lernst du, wie man die Balken übereinander stapeln kann.
Neben Balkenserien stellt dieses Tutorial auch TRandomChartSource vor, eine praktische Datenquelle zum Entwerfen und Testen eines Diagramms, ohne die Anwendung kompilieren zu müssen.
Du benötigst Grundkenntnisse in Pascal und Lazarus. Wirf einen Blick auf das TAChart Tutorial: Getting started, um einige grundlegende Fähigkeiten für die Arbeit mit TAChart zu erlernen, wenn diese Bibliothek neu für dich ist. Wir empfehlen auch, die TAChart-Dokumentation zu studieren.
Vorbereitung
Einrichten des Diagramms
Erstelle ein neues Projekt und speichere es. Platziere eine TChart-Komponente aus der Lazarus-Komponentenpalette auf dem Formular Form1 und ziehe ihre Größe soweit auf, dass sie den gewünschten Bereich des Formulars ausfüllt.
Daten zum Plotten
Bevor wir fortfahren, müssen wir uns überlegen, welche Daten wir darstellen wollen. Vielleicht könntest du das Guthaben deiner Giro- und Sparkonten verwenden, oder die Geschäftsergebnisse großer Unternehmen, die irgendwo im Internet zu finden sind, oder etwas ganz anderes ...
Gehen wir dieses Mal einen anderen Weg: Warum zeichnen wir nicht einfach zufällige Daten? Natürlich haben diese keine Bedeutung, aber sie sind einfach und sehr bequem zum Üben. Insbesondere enthält TAChart die Komponente TRandomChartSource, die Zufallsdaten bereitstellt, die zur Entwurfszeit nahtlos in einer Datenreihe eingefügt werden können. Das bedeutet, dass du diesem Tutorial folgen kannst, ohne eine Codezeile schreiben zu müssen und ohne die Demo-Anwendung kompilieren zu müssen. Später, wenn die Layoutarbeiten abgeschlossen sind, kannst du die RandomChartSources entfernen und durch ChartSources mit "echten" Daten ersetzen.
Wie wir gleich sehen werden, gibt es im Chart drei Serien, jede davon mit – sagen wir – vier Balken. Für jede Serie benötigst du eine Datenquelle. Wiegesagt, wir nehmen eine TRandomChartSource
. Um diese verfügbar zu machen, wirf einen Blick auf die "Chart"-Komponentenpalette - es ist das vierte Symbol in der Palette und im folgenden Screenshot rot hervorgehoben:
Füge dem Formular drei RandomChartSources hinzu – eine pro Serie. Benenne sie um in RedChartSource, BlueChartSource und YellowChartSource um, da sie mit "roten", "blauen" und "gelben" Balkenreihen verknüpft werden sollen (man sollte immer lieber "sprechende" Variablennamen verwenden.)
Zuvor müssen wir die RandomChartSources einrichten, da sie standardmäßig keine Daten liefern. Wir wollen vier Balken pro Serie haben. Setze daher die Eigenschaft PointsNumber auf 4. Damit die Achsenbeschriftungen mit den Balken synchron sind, muss die x-Achse zwischen 1 und 4 liegen (oder zwischen 0 und 3, oder zwischen 0 und 39, was auch immer du möchtest - wir werden später genauer auf die Achsenbeschriftungen eingehen): XMin = 1, XMax = 4. Und schließlich müssen wir auch den y-Achsenbereich angeben, vielleicht wählst du YMin = 0 und YMax = 100.
Balkenserie
Serie hinzufügen
Nachdem alle Vorbereitungen abgeschlossen sind, können wir die Balkenserie zum Diagramm hinzufügen. Klicke doppelt auf dem Diagramm, um den Reiheneditor zu öffnen, dann auf „Hinzufügen“ und wähle aus der Liste den Eintrag „Balkenserie“ aus. Dasselbe zweimal wiederholen, so dass wir am Ende drei Balkenserien im Chart haben. Wir sehen sie im Diagramm noch nicht, weil sie noch nicht mit unseren Daten verknüpft sind. Im Objektbaum des Objektinspektors erscheinen die Serien jedoch als Unterknoten des "Chart"-Knotens.
Klicke auf die erste Reihe im Objektbaum und gehe im Objektinspektor zur Eigenschaft Source; wähle den Eintrag RedChartSource aus der Liste aus. Jetzt wird die Reihe im Diagramm sichtbar. Um sie "rot" zu machen, gehe Sie zur Eigenschaft SeriesColor und wählen die Farbe clRed
. Benenne Sie die Datenreihe um nach „RedBarSeries“ und ändere ihren Titel zu „red“. Letzteres ist für die Legende, die wir aktivieren, indem wir Legend.Visible des Chart auf true setzen.
Wiederhole das mit den anderen beiden Serien entsprechend.
Jetzt zeigt der Chart die Balkenserien an. Die Balken befinden sich jedoch jeweils auf demselben Wert der x
-Achse, die gelben Balken werden teilweise von den anderen Balken verdeckt. Das wollen wir jetzt beheben.
Nebeneinander angeordnete Balken
Um die Balken jeder Gruppe (d. h. Balken, die demselben x-Wert zugeordnet sind) nebeneinander anzuordnen, müssen wir sie horizontal verschieben. TBarSeries bietet zu diesem Zweck zwei Eigenschaften:
- BarWidthPercent
- BarOffsetPercent
Beide Zahlen werden in Prozent des Abstands zur nächsten Balkengruppe ausgedrückt. (In manchen Diagrammen sind die Balken nicht äquidistant und erhalten daher unterschiedliche Balkenbreiten. Um in einem solchen Fall eine konstante Balkendicke zu erreichen, setze die Eigenschaft BarWidthStyle auf bwPercentMin.)
Die Grundidee ist, dass der Raum zwischen den Balkengruppen (100%) durch die Balken und etwas Leerraum zur nächsten Gruppe geteilt wird. Wenn wir zwischen den Gruppen eine Lücke von beispielsweise einer Balkenbreite lassen wollen, müssen wir 100 % durch 4 teilen (3 Balken plus Lücke), d. h. jeder Balken kann eine Breite von 25 % einnehmen.
Setzen wir also BarWidthPercent auf 25 und sehen, was passiert. Oh - nicht ganz das, was wir wollten: Die Balken sind zwar schmaler geworden, aber sie überlappen sich immer noch. Dies geschieht natürlich, weil wir den Parameter BarOffsetPercent nicht geändert haben.
Derzeit ist BarOffsetPercent null, was bedeutet, dass sich die Mitte jedes Balkens genau an der Position des Achsenstrichs befindet. Wir müssen die roten Balken nach links und die gelben Balken nach rechts so verschieben, dass sie die in der Mitte verbleibenden blauen Balken berühren. Die Verschiebungsdifferenz beträgt eine Balkenbreite, also 25 %. Um die roten Balken nach links zu verschieben, muss ihr BarOffsetPercent negativ sein.
Zusammenfassend verwenden wir die folgenden Werte:
- RedBarSeries: BarOffsetPercent = -25, BarWidthPercent = 25
- BlueBarSeries: BarOffsetPercent = 0, BarWidthPercent = 25
- YellowBarSeries: BarOffsetPercent = 25, BarWidthPercent = 25
Achse
Achsenbeschriftung
Das nächste zu behandelnde Problem ist die x-Achse. Normalerweise stellen Balkendiagramme die Kategorien von Datensätzen dar, was häufig Textbeschriftungen unter jeder Balkengruppe erfordert. Aber bisher haben wir hier nur numerische Bezeichnungen. Außerdem sind die Zwischenbeschriftungen bei halben Zahlen unschön.
Der beste Weg, dies richtig zu machen, ist, eine zusätzliche ChartSource für die Zuordnung der Zeichenketten zu den Achsenwerten zu verwenden. Es ist diesmal eine TListChartSource, die als zweites Symbol in der Palette der Diagrammkomponenten zu finden ist. Klicke sie auf das Formular und nenne sie in LabelsChartSource.
Die ListChartSource hat einen eingebauten Datenpunkt-Editor, der es ermöglicht, Daten zur Entwurfszeit einzugeben. Wählen die LabelsChartSource an und gehe im Objekt-Inspektor zur Eigenschaft DataPoints. Klicke rechts auf "...", um den Datenpunkt-Editor zu öffnen, und gib folgende Daten ein:
In der Spalte "X" tragen wir die Werte der x-Koordinaten jeder Balkengruppe ein. Wir könnten die "Y"-Spalte weglassen, aber wie wir später bei dem horizontalen Balkendiagramm sehen werden, ist es praktisch, die gleichen Daten auch in dieser Spalte zu haben, damit die Beschriftungen nach dem Drehen der Balken erhalten bleiben. In der Spalte „Text“ legen wir die Texte fest, die für jede Balkengruppe entlang der Achse als Achsenmarkierungen erscheinen sollen. Nehmen wir an, dass unsere Daten saisonale Werte darstellen und verwenden die Abkürzungen „Q1“, „Q2“, „Q3“ und „Q4“ für „Quartal 1“ usw. Die Spalte „Farbe“ kann leer bleiben.
Um diese Beschriftungen zu aktivieren, müssen wir diese ChartSource der Eigenschaft Source der Marks der unteren Achse zuweisen. Weiterhin muss die Eigenschaft Style von Marks
auf smsLabel
geschaltet werden, denn das wählt für die Beschriftungen den oben unter „Text“ eingegebenen Daten aus.
Voila - und unser Chart sieht nun so aus:
Rasterlinien und Unterteilungsstriche zwischen den Gruppen anzeigen
Ein kleines Problem kann verbessert werden: Das Diagramm wäre verständlicher, wenn sich die Achsenmarkierungen und Gitterlinien nicht in der Mitte der Balkengruppen, sondern direkt zwischen ihnen befinden würden.
Zuerst schalten wir das Raster der unteren Achse aus: BottomAxis.Grid.Visible = false. Um die Unterteilungsstriche ("Ticks") zu entfernen, können wir TickLength und TickInnerLength auf 0 setzen.
Aber wie erzeugt man die Gitterlinien zwischen den Diagrammgruppen? Dies kann durch Erstellen einer "Sekundär-Achse" zur unteren Achse erfolgen. Dies ist ein weiterer Satz von Ticks und Gitterlinien zusätzlich zur "Haupt"-Achse. Gehe zur unteren Achse und klicke auf Minors, um den entsprechenden Editor zu öffnen. Klicke nun auf "Hinzufügen" und wähle den Eintrag 0 - M in der Liste aus. Zurück im normalen Objektinspektor, aktiviere Visible, erhöhe TickLength auf 4 und setze schließlich Intervals.Count auf 1 - Wir wollen nur 1 kleinen Tick zwischen den großen Ticks. Überprüfe Sie die Grid-Einstellungen der Sekundär-Achse - Visible sollte auf true eingestellt sein.
Dies führt zum Endergebnis. Fertig? Nicht ganz! Unter den Balken ist ein störender kleiner Spalt. Dies rührt von der Eigenschaft Margins des Diagramms her, die einen gewissen Abstand zwischen der Reihe und den Achsen lässt. Setze einfach Chart.Margins.Bottom auf 0, um die Lücke zu entfernen.
Horizontale Balkenserie
Bevor wir diese Lektion schließen, möchten wir dieses Projekt schnell ändern und ein Diagramm mit horizontalen Balken erstellen. Diese Art von Diagramm wird häufig bevorzugt, wenn die Achsenbeschriftungen aus langen Texten bestehen und das Diagramm im Querformat ausgerichtet ist.
TAChart bietet keine spezielle "THorizontalBarSeries", aber die standardmäßige TBarSeries kann leicht modifiziert werden, um horizontale Balken zu bekommen. Wie bei jedem andere Nachfahren von TChartSeries gibt es auch hier die Eigenschaften AxisIndexX und AxisIndexY, um anzugeben, welche Achse für die x und y Koordinaten verantwortlich ist. Setze einfach AxisIndexX auf den Index der LeftAxis (normalerweise 0) und AxisIndexY auf den Index der BottomAxis; das vertauscht die x- und y-Achsen, und die Balkenrichtung wird gedreht.
Und natürlich muss diesmal die LabelsChartSource mit der Marks.Source der LeftAxis verknüpft werden. Und die Sekundärachse muss entsprechend gehandhabt werden.
Im Grunde ist das alles, was du brauchst, um ein Diagramm mit horizontalen Balken zu erstellen.
Zusammenfassung
Schritte zum Erstellen eines Balkendiagramms mit nebeneinander angeordneten Balken:
- Für jeden Balken ist eine eigene BarSeries-Komponente erforderlich.
- Verwende die BarSeries-Eigenschaften BarWidthPercent und BarOffsetPercent, um die Balken nebeneinander mit oder ohne Überlappung anzuordnen. Die Prozentangaben beziehen sich auf den Abstand zwischen den Mittelpunkten der Balkengruppen.
- Setze für horizontale Balkenreihen den AxisIndexX der Reihe auf den Index der LeftAxis des Diagramms (normalerweise 0) und AxisIndexY code> auf den Index der BottomAxis (normalerweise 1).
Quellcode
Der Quellcode dieses Tutorials ist im Ordner components/tachart/tutorials/bar_series
deiner TAChart-Installation neuerer Lazarus-Versionen verfügbar.
Projektdatei
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, tachartlazaruspkg, Unit1
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1.pas
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, TAGraph,
TASeries, TASources;
type
{ TForm1 }
TForm1 = class(TForm)
Chart1: TChart;
LabelsChartSource: TListChartSource;
RedBarSeries: TBarSeries;
BlueBarSeries: TBarSeries;
YellowBarSeries: TBarSeries;
RedChartSource: TRandomChartSource;
BlueChartSource: TRandomChartSource;
YellowChartSource: TRandomChartSource;
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
end.
Unit1.lfm (vertikale Balken)
object Form1: TForm1
Left = 381
Height = 272
Top = 444
Width = 429
Caption = 'Form1'
ClientHeight = 272
ClientWidth = 429
LCLVersion = '1.3'
object Chart1: TChart
Left = 0
Height = 272
Top = 0
Width = 384
AxisList = <
item
Minors = <>
Title.LabelFont.Orientation = 900
end
item
Grid.Visible = False
TickLength = 0
Alignment = calBottom
Marks.Format = '%2:s'
Marks.Source = LabelsChartSource
Marks.Style = smsLabel
Minors = <
item
Intervals.Count = 1
Intervals.MinLength = 5
Intervals.Options = [aipUseCount, aipUseMinLength]
TickLength = 4
end>
end>
Foot.Brush.Color = clBtnFace
Foot.Font.Color = clBlue
Legend.Visible = True
Margins.Bottom = 0
Title.Brush.Color = clBtnFace
Title.Font.Color = clBlue
Title.Text.Strings = (
'TAChart'
)
ParentColor = False
object RedBarSeries: TBarSeries
Title = 'red'
BarBrush.Color = clRed
BarOffsetPercent = -25
BarWidthPercent = 25
Source = RedChartSource
end
object BlueBarSeries: TBarSeries
Title = 'blue'
BarBrush.Color = clBlue
BarWidthPercent = 25
Source = BlueChartSource
end
object YellowBarSeries: TBarSeries
Title = 'yellow'
BarBrush.Color = clYellow
BarOffsetPercent = 25
BarWidthPercent = 25
Source = YellowChartSource
end
end
object RedChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 1
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 72
end
object BlueChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 2
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 120
end
object YellowChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 3
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 168
end
object LabelsChartSource: TListChartSource
DataPoints.Strings = (
'1|1|?|Q1'
'2|2|?|Q2'
'3|3|?|Q3'
'4|4|?|Q4'
)
left = 361
top = 220
end
end
Unit1.lfm (horizontale Balken)
object Form1: TForm1
Left = 381
Height = 272
Top = 444
Width = 429
Caption = 'Form1'
ClientHeight = 272
ClientWidth = 429
LCLVersion = '1.3'
object Chart1: TChart
Left = 0
Height = 272
Top = 0
Width = 384
AxisList = <
item
Grid.Visible = False
TickLength = 0
Marks.Format = '%2:s'
Marks.Source = LabelsChartSource
Marks.Style = smsLabel
Minors = <
item
Intervals.Count = 1
Intervals.MinLength = 5
Intervals.Options = [aipUseCount, aipUseMinLength]
TickLength = 4
end>
Title.LabelFont.Orientation = 900
end
item
Alignment = calBottom
Minors = <>
end>
Foot.Brush.Color = clBtnFace
Foot.Font.Color = clBlue
Legend.Visible = True
Margins.Bottom = 0
Title.Brush.Color = clBtnFace
Title.Font.Color = clBlue
Title.Text.Strings = (
'TAChart'
)
ParentColor = False
object RedBarSeries: TBarSeries
Title = 'red'
AxisIndexX = 0
AxisIndexY = 1
BarBrush.Color = clRed
BarOffsetPercent = -25
BarWidthPercent = 25
Source = RedChartSource
end
object BlueBarSeries: TBarSeries
Title = 'blue'
AxisIndexX = 0
AxisIndexY = 1
BarBrush.Color = clBlue
BarWidthPercent = 25
Source = BlueChartSource
end
object YellowBarSeries: TBarSeries
Title = 'yellow'
AxisIndexX = 0
AxisIndexY = 1
BarBrush.Color = clYellow
BarOffsetPercent = 25
BarWidthPercent = 25
Source = YellowChartSource
end
end
object RedChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 1
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 72
end
object BlueChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 2
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 120
end
object YellowChartSource: TRandomChartSource
PointsNumber = 4
RandSeed = 3
XMax = 4
XMin = 1
YMax = 100
YMin = 0
left = 360
top = 168
end
object LabelsChartSource: TListChartSource
DataPoints.Strings = (
'1|1|?|Q1'
'2|2|?|Q2'
'3|3|?|Q3'
'4|4|?|Q4'
)
left = 361
top = 220
end
end