Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TDBChart Möglichkeiten (https://www.delphipraxis.net/116363-tdbchart-moeglichkeiten.html)

Cogito 27. Jun 2008 12:20


TDBChart Möglichkeiten
 
Hallo zusammen,

ich versuche mittels der in Delphi 2007 integrierten TeeChart Komponente (TDBChart) 2 Diagramme darzustellen.
Das erste soll ein einfaches Liniendiagramm sein, bei dem auf der x-Achse Datumswerte und auf der y-Achse zugehörige Werte dargestellt werden sollen.
Was ich nicht schaffe ist, auf der y-Achse Dezimalwerte mit 2 Nachkommastellen darzustellen, obwohl es sich um decimal Werte handelt.
Auf der x-Achse sollten die Datumswerte so dargestellt werden können, dass z.B. nur Nov. 2005, Dez. 2005, Jan. 2006 usw. da steht, aber es sollte dennoch jeder Wert dargestellt werden.
Es sollen bis zu 4 Felder aus der Tabelle auf der y-Achse abgebildet werden können. Falls aber eine Spalte keinen Inhalt hat, sollte auch die Legende für diese Serie nicht dargestellt werden.
Bei einem 2. Diagramm, ein einfaches 2D Balkenchart, sollte es möglich sein, negative Werte mit einem Balken unterhalb der x-Achse darstellen zu können.
Nichts von alldem hab ich bisher hinbekommen. :wall:
Kann hier jemand weiterhelfen?

Cogito 28. Jun 2008 08:54

Re: TDBChart Möglichkeiten
 
OK, das meiste hat sich inzwischen erledigt.
Bleibt nur noch die Frage, wie ich eine Serie, wenn sie keine Werte enthält zur Laufzeit ausblenden kann, damit keine Linie auf der x-Achse verläuft und die Legende weg ist?

Cogito 28. Jun 2008 10:06

Re: TDBChart Möglichkeiten
 
OK, habe inzwischen gesehen, dass es für die Series eine eigene Komponente gibt, mittels der man genaueren Einfluss auf die Serien nehmen kann. Sehr mühsam dies alles ohne eine Hilfe oder Doku rauszufinden!
Bleibt noch meine letzte Frage. Wie kann ich Datumswerte auf der x-Achse so zusammenfassen, das dort nur noch Monate oder Quartale stehen, wobei aber jeder einzelne Wert (also jeder Tag) dargestellt werden muss? Es soll keine Zusammenfassung für ein ganzes Quartal sein.

marabu 28. Jun 2008 12:27

Re: TDBChart Möglichkeiten
 
Hallo,

wenn du Zeitreihen darstellen möchtest, dann sind Monate einfach keine gute Intervallgröße, weil sie keine Zeitnorm darstellen bzw. nicht aus einer solchen abgeleitet werden.

Wenn du deine Anforderung aufrecht erhältst, dann wirst du ein wenig tricksen müssen. Minor Ticks kannst du gleich abschalten, es gibt nur noch Major Ticks = Tage. Die Achsenbeschrifzung musst du auf Text umschalten und beim Ereignis OnGetAxisLabel auf den gewünschten Monatsersten testen.

Gehört zu deinem Delphi Lieferumfang nicht die Datei $(DELPHI)\Help\TeeChart.hlp oder etwas ähnliches?

Grüße vom marabu

Cogito 29. Jun 2008 14:09

Re: TDBChart Möglichkeiten
 
Wann wird das Ereignis denn aufgerufen, einmal pro Darstellung oder jedesmal wenn ein Wert auf irgendeiner Achse dargestellt werden soll?
Könntest du mir eine Behandlung dieses Events vielleicht mal anhand eines kurzen Quelltextes demonstrieren? (Am besten wäre natürlich ein Beispiel für meine Belange, Monate hinschreiben).

Cogito 2. Jul 2008 08:35

Re: TDBChart Möglichkeiten
 
Kann mir denn hier wirklich niemand weiterhelfen? Zu diesem Teil hab ich keine Hilfe und ansonsten ist es nur rumraterei...

marabu 2. Jul 2008 14:06

Re: TDBChart Möglichkeiten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

warum hast du keine Online Hilfe?

Die angehängte Demo produziert die Anzeige von Quartalen auf der X-Achse. Sie verwendet die Tabelle DBDEMOS:ORDERS. Der von mir angewandte Kniff ist die Wahl einer Tagesskalierung (BottomAxis.Increment := dtOneDay). Im Einstellungsdialog der Komponente findest du die Einstellung auf der Seite Skalierung der Achse als Steigung.

Freundliche Grüße

Cogito 2. Jul 2008 14:47

Re: TDBChart Möglichkeiten
 
Nee, weder bei Developer Studio 2006 noch bei Delphi 2007 ist bei mir eine Hilfe zu DBChart dabei.
Bei deiner Anwendung fehlt noch die Überprüfung auf ValueIndex <> -1, sonst kriegt man gleich am Anfang ne Exception um die Ohren.
Vielen Dank, das bringt mich weiter.
Wenn ich das richtig sehe, stellst du alle Werte dar, fasst sie aber in Quartalen zusammen und schreibst das jeweilige Quartal auch nur einmal hin, oder?
Genau das würde ich auch benötigen, nur nicht nach Quartalen sondern nach Monaten. Kannst du mir sagen wie der Algorithmus dann aussehen würde (sorry, kenne Delphi nicht so gut)?

marabu 2. Jul 2008 15:12

Re: TDBChart Möglichkeiten
 
Hi,

Zitat:

Zitat von Cogito
... weder bei Developer Studio 2006 noch bei Delphi 2007 ist bei mir eine Hilfe zu DBChart dabei. ...

das kommt mir aber spanisch vor - kann das noch ein anderer Benutzer dieser Versionen bestätigen? Bei mir ist die Online-Hilfe zur TeeChart-Komponente eine eigenständige Datei, Name siehe mein Beitrag #4.

Zitat:

Zitat von Cogito
... Bei deiner Anwendung fehlt noch die Überprüfung auf ValueIndex <> -1, sonst kriegt man gleich am Anfang ne Exception um die Ohren. ...

Das ist mir unverständlich, da ich die Demo getestet habe. Bist du sicher, dass der Fehler mit meiner Demo auftritt, ohne dass du irgendwelche Änderungen daran vorgenommen hast? ValueIndex hat nämlich keine Bedeutung für meinen Ansatz.

Zitat:

Zitat von Cogito
... Genau das würde ich auch benötigen, nur nicht nach Quartalen sondern nach Monaten. ...

Genau das hatte ich vorausgesehen und deshalb die entsprechende Zeile als Kommentar eingetragen:

Delphi-Quellcode:
begin
  // ...
    DecodeDate(dt, y, m, d);
    //LabelText := Format('%s%.2d', [ShortMonthNames[m], y mod 100]);
    q := Succ(Pred(m) div 3);
  // ...
end;
Du musst also nur den kommentierten Code aktivieren und den Rest weglassen:

Delphi-Quellcode:
begin
  if (Sender = DBChart.BottomAxis) then
  begin
    dt := StrToDate(LabelText);
    DecodeDate(dt, y, m, d);
    if d = 1
      then LabelText := Format('%s%.2d', [ShortMonthNames[m], y mod 100])
      else LabelText := '';
  end;
end;
Freundliche Grüße

Cogito 2. Jul 2008 15:15

Re: TDBChart Möglichkeiten
 
Vielen Dank!!
Nee, tatsächlich ist bei meinem Delphi 2006 (Architect Version) keine Hilfedatei dabei, weder die von dir benannte externe noch in Delphi direkt eingebunden.
Wenn ich bei dir die Überprüfung mit ValueIndex <> -1 weglasse kommt die Exception das ... kein gültiges Datum darstellt. Keine Ahnung warum.
Der einzige Haken ist jetzt noch, das er jeden einzelnen Wert hinschreibt und nicht zusammenfasst, es steht also z.B. 10mal Nov05 da, das ist etwas unschön. Geht das auch zusammengefasst?

marabu 2. Jul 2008 15:24

Re: TDBChart Möglichkeiten
 
Der Fehler hat nichts mit dem ValueIndex zu tun. Es scheint bei dir in der Tabelle DBDEMOS:ORDERS einen fehlenden Wert bei SALEDATE zu geben. Das müsstest du abfangen.

In meinem Code in Beitrag #9 habe ich eine Anpassung gemacht, damit nur der Monatserste einen Label generiert.

Cogito 2. Jul 2008 19:10

Re: TDBChart Möglichkeiten
 
Das mit dem fehlenden Wert könnte natürlich auch sein, hab ich nicht getestet.
Vielen Dank erstmal.
Noch eine Frage hätte ich: Wie kann ich eigentlich feststellen, ob eine Serie nur 0 Werte enthält und diese dann im Chart gar nicht erst anzeigen, damit diese auch in der Legende nicht auftaucht?

marabu 2. Jul 2008 21:38

Re: TDBChart Möglichkeiten
 
Eine Serie ohne Werte liefert für FirstValueIndex den Wert -1. Die Sichtbarkeit einer Serie im Diagramm steuerst du mit der Eigenschaft Active, die Sichtbarkeit in der Legende kannst du mit der Eigenschaft ShowInLegend steuern.

Delphi-Quellcode:
var
  i: Integer;
begin
  with DBChart do
    for i := 0 to Pred(SeriesCount) do
      Series[i].ShowInLegend := Series[i].FirstValueIndex > -1;
end;
Eine Serie, die zwar Werte aufweist, aber diese Werte sind alle 0?

Delphi-Quellcode:
var
  i: Integer;
begin
  with DBChart do
    for i := 0 to Pred(SeriesCount) do
      Series[i].Active := Series[i].YValues.MaxValue > 0;
end;
Getippt und nicht getestet.

Gute Nacht

Cogito 3. Jul 2008 09:03

Re: TDBChart Möglichkeiten
 
Also das ShowsInLegend wird anscheinend nicht benötigt (und zeigt bei mir auch keinen Effekt), die Active-Anweisung blendet die Legende mit aus.
Allerdings funktioniert die Aktualisierung nicht richtig, ich habe die darzustellenden Daten in einer abhängigen Detailtabelle und sobald sich der Masterdatensatz ändert, ändern sich natürlich auch die Detaildaten. Ich muss dann erstmal händisch ein RefreshData für das Chart ausführen, und eine ausgeblendete Serie (also active=false) wird nicht mehr aktiv, obwohl in der Spalte wieder Werte drinstehen?

marabu 3. Jul 2008 11:00

Re: TDBChart Möglichkeiten
 
Moin,

beim Wechsel des Datensatzes im Master-Dataset wird bei der zugeordneten DataSource das Ereignis OnDataChange() ausgelöst. Dort kannst du dann die Serien aktivieren, die von diesem Master abhängig sind. Wenn die Eigenschaft AutoRefresh von DBChart auf True gesetzt wird, dann werden die Reihendaten automatisch aktualisiert. Im Handbuch steht, dass das nur beim Öffnen eines Datasets greift, also probiere es einfach mal aus.

Auf Dauer wirst du nicht ohne eine Online-Hilfe zu TeeChart auskommen.

Freundliche Grüße

Cogito 3. Jul 2008 11:21

Re: TDBChart Möglichkeiten
 
Zitat:

Zitat von marabu
Moin,

beim Wechsel des Datensatzes im Master-Dataset wird bei der zugeordneten DataSource das Ereignis OnDataChange() ausgelöst. Dort kannst du dann die Serien aktivieren, die von diesem Master abhängig sind. Wenn die Eigenschaft AutoRefresh von DBChart auf True gesetzt wird, dann werden die Reihendaten automatisch aktualisiert. Im Handbuch steht, dass das nur beim Öffnen eines Datasets greift, also probiere es einfach mal aus.

Auf Dauer wirst du nicht ohne eine Online-Hilfe zu TeeChart auskommen.

Freundliche Grüße

Hi,

nein eben nicht, ich hab AutoRefresh auf True gestellt aber es passiert keine automatische Aktualisierung. Es könnte allerdings sein, dass dies an den dbgo Komponenten liegt..
Was aber dennoch, auch nach Refresh des Charts, nicht passiert, ist die richtige Legenden Ein/Ausblendung. Wie ich eben schon geschrieben habe, macht er das beim ersten mal noch richtig, aber wenn eine Legende mal ausgeblendet war, wird sie nach Datensatzwechsel nicht mehr eingeblendet, auch wenn diese Serie nicht leer ist.. hast du noch eine Idee?


P.S. Noch ne kleine Frage für zwischendurch: Kann ich irgendwie Einfluss auf die Skalierung der x-Achse nehmen (obwohl die auf 1 Tag steht)? Die Abstände zwischen den Tagen die er darstellt sind so groß,oder schiebt er die automatisch zusammen wenn mehr Werte drinstehen?

marabu 4. Jul 2008 17:35

Re: TDBChart Möglichkeiten
 
Hallo,

was deine offenen Probleme mit der Legendendarstellung und der Achsenskalierung angeht: Erstelle ein Demo-Projekt, das nur diese Aspekte verdeutlicht. Meistens wird einem dann schon selbst klar, wo der Fehler liegt. Wenn nicht, dann schaue ich mir das an. Versprochen.

Grundsätzlich kannst du für die X-Achse das Datenintervall explizit statt automatisch bestimmen und die Steigung individuell festlegen. Mehr geht bei Datumswerten nicht.

Freundliche Grüße

Cogito 7. Jul 2008 11:06

Re: TDBChart Möglichkeiten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von marabu
Hallo,

was deine offenen Probleme mit der Legendendarstellung und der Achsenskalierung angeht: Erstelle ein Demo-Projekt, das nur diese Aspekte verdeutlicht. Meistens wird einem dann schon selbst klar, wo der Fehler liegt. Wenn nicht, dann schaue ich mir das an. Versprochen.

Grundsätzlich kannst du für die X-Achse das Datenintervall explizit statt automatisch bestimmen und die Steigung individuell festlegen. Mehr geht bei Datumswerten nicht.

Freundliche Grüße

Vielen Dank, die Legendendarstellung funktioniert jetzt auch, ich deaktiviere die Serie im Fall wenn kein Wert da ist.
Ich hab dir mal ein Bild des Originalcharts angefügt, ist in Excel erstellt. Glaubst du man bekommt so eine Auflösung hin?
Bei mir macht er die Tage doch immer sehr weit auseinander...


Anmerkung: Mir fällt gerade auf, das er die x-Achen-Darstellung überhaupt nicht ändert, ganz gleich was ich für ein Increment auswähle. Könnte das mit dem implementierten OnGetAxisLabel Event zusammenhängen, indem ja die Werte explizit gesetzt werden? Wäre schon schlecht wenn ich da nichts ändern könnte...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 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