Page 1 of 1

Formatting of bar values

Posted: Fri May 29, 2009 6:56 am
by 10051657
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?

Posted: Fri May 29, 2009 8:53 am
by yeray
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.

Posted: Fri May 29, 2009 9:51 am
by 10051657
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?

Posted: Fri May 29, 2009 1:11 pm
by 10051657
The event OnGetMarkText isn't fired in my application???

Posted: Fri May 29, 2009 1:57 pm
by yeray
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;

Posted: Fri May 29, 2009 3:06 pm
by 10051657
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...

Posted: Sat May 30, 2009 7:09 am
by 10051657
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?

Posted: Mon Jun 01, 2009 7:43 am
by 10051657
Maybe it's a bug, which is fixed in 8.05 version ?

Posted: Mon Jun 01, 2009 7:52 am
by yeray
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

Posted: Mon Jun 01, 2009 8:41 am
by 10051657
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.

Posted: Mon Jun 01, 2009 1:10 pm
by yeray
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.

Posted: Mon Jun 01, 2009 3:35 pm
by 10051657
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.

Posted: Tue Jun 02, 2009 11:15 am
by yeray
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;

Posted: Wed Jun 03, 2009 9:14 am
by 10051657
Thanx, that's the solution.