Formatting of bar values

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Formatting of bar values

Post by Cogito » Fri May 29, 2009 6:56 am

Hello,

in my application I use a bar chart, which shows the bar value in decimal format above the bars. This chart is used in a report, which is printed in different languages. The problem is, that the bar values should be shown in the right format, that means with the correct decimal separator and so on...This could be done with the Format command in Delphi, but what is the right place to do that, which event? Has anybody here a sample to demontrate this?

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Post by Yeray » Fri May 29, 2009 8:53 am

Hi Cogito,

If you want the same character in all your charts:

Code: Select all

DecimalSeparator := '.';
If you have more than one chart, or you want to set different decimal separators in the same chart, yes, you should use OnGetAxisLabels or OnGetMarkText events to change each mark, label text.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Fri May 29, 2009 9:51 am

9348257 wrote:Hi Cogito,

If you want the same character in all your charts:

Code: Select all

DecimalSeparator := '.';
If you have more than one chart, or you want to set different decimal separators in the same chart, yes, you should use OnGetAxisLabels or OnGetMarkText events to change each mark, label text.
If I use the OnGetAxisLabels event, how could I get the bar values, to define the formatted LabelText parameter? Could you give me a sample?

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Fri May 29, 2009 1:11 pm

The event OnGetMarkText isn't fired in my application???

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Post by Yeray » Fri May 29, 2009 1:57 pm

Hi

Here you have an example using these events:

Code: Select all

//...

private
    { Private declarations }
    procedure Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
    procedure SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);

//...

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D := false;

  Chart1.AddSeries(TBarSeries.Create(self));

  with (Chart1[0] as TBarSeries) do
  begin
    AddBar(10.5, '', clTeeColor);
    AddBar(5.5, '', clTeeColor);
    AddBar(8.5, '', clTeeColor);
    AddBar(3.5, '', clTeeColor);
    AddBar(4.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
    AddBar(11.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
  end;

  Chart1[0].OnGetMarkText := SeriesGetMarkText;
  Chart1.OnGetAxisLabel := Chart1GetAxisLabel;
end;

procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  if sender = Chart1[0] then
  begin
    if Chart1[0].XValue[ValueIndex] > 3 then
      MarkText  := StringReplace(MarkText, ',', '.', [rfReplaceAll, rfIgnoreCase])
    else
      MarkText  := StringReplace(MarkText, '.', ',', [rfReplaceAll, rfIgnoreCase]);
  end;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  if Sender = Chart1.Axes.Left then
  begin
    if (StrToFloat(LabelText)) > 5 then
      LabelText := LabelText + ' high'
    else
      LabelText := LabelText + ' low';
  end;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Fri May 29, 2009 3:06 pm

9348257 wrote:Hi

Here you have an example using these events:

Code: Select all

//...

private
    { Private declarations }
    procedure Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
    procedure SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);

//...

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D := false;

  Chart1.AddSeries(TBarSeries.Create(self));

  with (Chart1[0] as TBarSeries) do
  begin
    AddBar(10.5, '', clTeeColor);
    AddBar(5.5, '', clTeeColor);
    AddBar(8.5, '', clTeeColor);
    AddBar(3.5, '', clTeeColor);
    AddBar(4.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
    AddBar(11.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
  end;

  Chart1[0].OnGetMarkText := SeriesGetMarkText;
  Chart1.OnGetAxisLabel := Chart1GetAxisLabel;
end;

procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  if sender = Chart1[0] then
  begin
    if Chart1[0].XValue[ValueIndex] > 3 then
      MarkText  := StringReplace(MarkText, ',', '.', [rfReplaceAll, rfIgnoreCase])
    else
      MarkText  := StringReplace(MarkText, '.', ',', [rfReplaceAll, rfIgnoreCase]);
  end;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  if Sender = Chart1.Axes.Left then
  begin
    if (StrToFloat(LabelText)) > 5 then
      LabelText := LabelText + ' high'
    else
      LabelText := LabelText + ' low';
  end;
end;
No sorry, I've created a DBChart (simple inserted the control), then I've created one series, made my settings (colors and so on), but when I try to implement the OnGetMarkText of the series, nothing happens. Even if I write a simple ShowMessage... it doesn't appear...

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Sat May 30, 2009 7:09 am

9348257 wrote:Hi

Here you have an example using these events:

Code: Select all

//...

private
    { Private declarations }
    procedure Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
    procedure SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);

//...

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D := false;

  Chart1.AddSeries(TBarSeries.Create(self));

  with (Chart1[0] as TBarSeries) do
  begin
    AddBar(10.5, '', clTeeColor);
    AddBar(5.5, '', clTeeColor);
    AddBar(8.5, '', clTeeColor);
    AddBar(3.5, '', clTeeColor);
    AddBar(4.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
    AddBar(11.5, '', clTeeColor);
    AddBar(7.5, '', clTeeColor);
  end;

  Chart1[0].OnGetMarkText := SeriesGetMarkText;
  Chart1.OnGetAxisLabel := Chart1GetAxisLabel;
end;

procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  if sender = Chart1[0] then
  begin
    if Chart1[0].XValue[ValueIndex] > 3 then
      MarkText  := StringReplace(MarkText, ',', '.', [rfReplaceAll, rfIgnoreCase])
    else
      MarkText  := StringReplace(MarkText, '.', ',', [rfReplaceAll, rfIgnoreCase]);
  end;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  if Sender = Chart1.Axes.Left then
  begin
    if (StrToFloat(LabelText)) > 5 then
      LabelText := LabelText + ' high'
    else
      LabelText := LabelText + ' low';
  end;
end;

You create the bars manually, I use a DBChart which is bound to a dataset and therefore autmatically populated with data. Also I create at design time one series. Maybe that the behaviour of a DBChart is different from a standard chart? The event isn't fired... Any other idea?

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Mon Jun 01, 2009 7:43 am

Maybe it's a bug, which is fixed in 8.05 version ?

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Post by Yeray » Mon Jun 01, 2009 7:52 am

Hi Cogito,

You have two options in order to assign events:

- You can create them at design time: To create an event at design time, you need the object that fires the event to be created also at design time. For example, to use SeriesGetMarkText, that is an event from the series, you need the chart and a series to be created at design time. Then, select the series in the Object Inspector, go to events tab and double click on the combobox next to OnGetMarkText. This should create the necessary code to fire and use the event:

Definitions:

Code: Select all

procedure Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
Implementations:

Code: Select all

procedure TForm1.Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  //if you don't write anything, delphi will delete unused definitions and implementations
end;

- You can create the events at runtime as I showed you in the previous message. You have to write events definitions and implementations manually but also you have to link the event call to the own created method:

Code: Select all

Chart1[0].OnGetMarkText := SeriesGetMarkText;
I hope this helps
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Mon Jun 01, 2009 8:41 am

9348257 wrote:Hi Cogito,

You have two options in order to assign events:

- You can create them at design time: To create an event at design time, you need the object that fires the event to be created also at design time. For example, to use SeriesGetMarkText, that is an event from the series, you need the chart and a series to be created at design time. Then, select the series in the Object Inspector, go to events tab and double click on the combobox next to OnGetMarkText. This should create the necessary code to fire and use the event:

Definitions:

Code: Select all

procedure Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
Implementations:

Code: Select all

procedure TForm1.Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  //if you don't write anything, delphi will delete unused definitions and implementations
end;

- You can create the events at runtime as I showed you in the previous message. You have to write events definitions and implementations manually but also you have to link the event call to the own created method:

Code: Select all

Chart1[0].OnGetMarkText := SeriesGetMarkText;
I hope this helps
Sorry, I'm not experienced with TeeChart, but I'm not new with Delphi. I've implemented the OnGetMarkText-Event at the Series-object, write a ShowMessage(MarkText) command, but this MessageBox doesn't appear at runtime. The chart is displayed correct! This event is definitely not fired...

Edit: If I set AutoRefresh := true, the event is fired after application start one-time. At runtime I call the RefreshData (and I've tried Refresh) command, but the event wasn't triggered.

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Post by Yeray » Mon Jun 01, 2009 1:10 pm

Hi Cogito,

Excuse me if I offended you with the events guide. It's only that this seems really strange.

Please, could you send us a simple example project we can run "as-is" to reproduce the problem here?
You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Mon Jun 01, 2009 3:35 pm

9348257 wrote:Hi Cogito,

Excuse me if I offended you with the events guide. It's only that this seems really strange.

Please, could you send us a simple example project we can run "as-is" to reproduce the problem here?
You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.
I've send you a sample with a similiar implementation like in my application.

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Post by Yeray » Tue Jun 02, 2009 11:15 am

Hi Cogito,

The problem is that you are using ADODataSet1AfterScroll event to load your chart from a tee file and neither events nor datasets are loaded with this method. That means that reassigning them manually after the LoadChartFromFile call, should solve the issue (and it does for me here):

Code: Select all

procedure TForm1.ADODataSet1AfterScroll(DataSet: TDataSet);
begin
  LoadChartFromFile(TCustomChart(AllocationChart), ExtractFilePath(Application.ExeName) + '\allocationchart.tee');
  AllocationChart[0].DataSource := ADODataSet2;
  AllocationChart[0].YValues.ValueSource := 'Y-Value';
  AllocationChart[0].XLabelsSource := 'X-Value';
  AllocationChart[0].OnGetMarkText:=Series5GetMarkText;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Cogito
Newbie
Newbie
Posts: 17
Joined: Fri Feb 06, 2009 12:00 am

Post by Cogito » Wed Jun 03, 2009 9:14 am

Thanx, that's the solution.

Post Reply