Page 1 of 1

Unit Conversion in teechart?

Posted: Tue Apr 28, 2009 11:14 am
by 10548492
Hi@All

I need to convert untis in teechart. In my database I have stored all values for heights in Meters. To convert them and display them as inches or feets I use the Delphi TField.OnGetText function. In this function the float values from the database where converted and displayed as strings in the attached control like TDBEdit.
In Teechart this doesn't work. It seems like Teechart does directly access the Field or the Dataset in the database.
Who knows how I can display the series with other units?

Posted: Tue Apr 28, 2009 11:57 am
by yeray
Hi FHG_AST,

I can think in some different possibilities:

1. The best solution would be if you could use a database that wouldn't need any conversion. I mean, it would be better if you could convert your values to a new database and use this new database as your series' source.

2. You could use a series linked to your database in meters but inactive. Then you could have another series and every time you want to update it's values, search in the "source dummy series" for new values and convert them before adding to the second series.

3. You could have your series with values in meters and use the events OnGetAxisLabels and OnGetSeriesMarks (if marks are shown) to convert the labels from meters to feet.

If you need an example of some of the options or any further suggestions, please don't hesitate to let us know, give us as precise information as possible, and we'll try to help you.

Posted: Tue Apr 28, 2009 1:49 pm
by 10548492
Hi Yeray.

The third option sounds for me as the most suitable because I have implemented an object (TunitConv) which parses each form for datasets and changes the onGetText function of the TFloatfields in them. So it is easy to add this functionality for the onGetAxisLabels and OnGetSeriesMarks of TSeries, I think.

If you have en example how to do this I woul be very grateful.

Posted: Tue Apr 28, 2009 2:11 pm
by yeray
Hi FHG_AST,

Here is how you could do it but note that with this way, the texts won't show integers but the corresponding values of the original integers.

In the example I created a Point series and generated the events at designtime:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
begin
  Series1.FillSampleValues(5);
  Series1.Marks.Visible := True;
end;

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
  LabelText := FloatToStr(StrToFloat(LabelText) * 3.2808399);
end;

procedure TForm1.Series1GetMarkText(Sender: TChartSeries;
  ValueIndex: Integer; var MarkText: String);
begin
  MarkText := FloatToStr(StrToFloat(MarkText) * 3.2808399);
end;

Posted: Mon May 04, 2009 12:51 pm
by 10548492
Ok I tried to use this code but I have a problem.

I have a chart with multiple axes and each valuesource has a different unit conversion factor dependig on the field in the database.
I can get the unit conversion factor from the Tag of the field in the attached dataset. So my idea is to get the dataset from the series

Code: Select all

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis; 
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
var Uindex:integer;
begin
  Uindex:=TDataset(Series.dataset).fieldbyname(Series.yValues.Valuesource).tag;
...

end;

Btw. the conversion of the seriesmarks is not neccessary because it is done in the Fields OnGetText event
but series in this function is always NIL.

Posted: Tue May 05, 2009 10:52 am
by yeray
Hi FHG_AST,

Looking at TeeChart Help, you can see at the OnGetAxisLabel description:
An Event is triggered for each Axis Label painted.
There are two different uses for OnGetAxisLabel:

1) Axis Labels are Values.
In this case, the Series parameter will be nil, and the ValueIndex will be -1.

2) Axis Labels are Series points.
The Series parameter will be a valid TChartSeries, and the ValueIndex will be the current Series point position.
So, the Series will be different to null only when some axis LabelStyle is set as talMark.

In your case you probably know what series are linked to each axis, so you could decide your conversion factor considering the Sender (TChartAxis), not the Series. Something like this:

Code: Select all

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
var factor: double;
begin
  factor := 1;

  if Sender = Chart1.Axes.Left then
    factor := 2
  else if Sender = Chart1.Axes.Right then
    factor := 3
  else if Sender = Chart1.Axes[6] then
    factor := 4
  else if Sender = Chart1.Axes[7] then
    factor := 5;
  //...
end;

Posted: Tue May 05, 2009 12:44 pm
by 10548492
Well it works fine if I set the lablestyle to talText.

But I habe an addition question. How can I get the axes associated with the series at runtime?

Posted: Tue May 05, 2009 1:12 pm
by yeray
Hi FHG_AST,

Here it is a simple example:

Code: Select all

uses series;

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

  for i:=0 to 3 do
  begin
    Chart1.AddSeries(TLineSeries.Create(self));
    Chart1[i].FillSampleValues(25);
  end;

  Chart1.CustomAxes.Add;
  Chart1.CustomAxes.Add;

  Chart1[0].CustomVertAxis := Chart1.Axes.Left;
  Chart1[1].CustomVertAxis := Chart1.Axes.Right;
  Chart1[2].CustomVertAxis := Chart1.CustomAxes[0];
  Chart1[3].CustomVertAxis := Chart1.CustomAxes[1];

  Chart1.CustomAxes[0].PositionUnits := muPixels;
  Chart1.CustomAxes[1].PositionUnits := muPixels;
  Chart1.CustomAxes[0].PositionPercent := -50;
  Chart1.CustomAxes[1].OtherSide := true;
  Chart1.CustomAxes[1].PositionPercent := -50;

  Chart1.MarginUnits := muPixels;
  Chart1.MarginLeft := 60;
  Chart1.MarginRight := 60;
end;

Posted: Tue May 05, 2009 1:38 pm
by 10548492
Yes, I know but I need to set the title caption (including the unit) of the axis as the same of the datafield.Displaylabel of the associated Series.
This means in the TField.Displaylabel is a string like Diameter [%s] and I want to convert it into Diameter [mm] and set as the chartaxis.title.caption.
How do I get from the dataset field via TDbchart or TChartseries to the Axis associated to the TChartseries that gets its data from that field in the dataset?

Posted: Tue May 05, 2009 2:16 pm
by yeray
Hi

If I understand well, you have the series and need to access to it's vertical associated axis. Something like this:

Code: Select all

Chart1[0].GetVertAxis.Title.Caption := 'my new title';

Posted: Wed May 06, 2009 7:53 am
by 10548492
Hi Yeray.
I know how to set the title caption but I need the connection from

TDatabase.TField-> TChartseries->TChartaxis

I have chart with 4 TFaslineseries and each has a customaxis. But which of them is Chart[0] and Chart[1] ... Chart[XXX].

In des Editdialog I have the Series "Verbrauch" Assigned to Vertaxis=Custom3
Image

and on the other tab I have the data connection ti the assocuated datafield for te yvalues =Wassermenge

Image

My starting point is the TDataset.fieldbyname("WASSERMENGE") and I need to go to the Chart1[????].GetVertAxis.Title.Caption= TField(TDataset.fieldbyname("WASSERMENGE")).Displaylabel;

The ??? is that what is if interest for me.

In this Form I can hard code it when I open the Charteditor an look at the order of the customseries. But I have a lot of different forms with other Datafields and other series and different count of them. So I want to create a parent class which parses the form for all Fields of TDatasets and then translates the associated axes.

Posted: Wed May 06, 2009 9:47 am
by yeray
Hi FHG_AST,

So you need to retrieve the series' index of the series where Labels are set to 'WASSERMENGE', right? This could be done as follows:

Code: Select all

var i, SeriesIndex: Integer;
//...
  for i:=0 to DBChart1.SeriesCount-1 do
    if Series1.XLabelsSource = 'WASSERMENGE' then
    begin
      SeriesIndex := i;
      break;
    end;

  DBChart1[SeriesIndex].GetVertAxis.Title.Caption := 'your custom title';

Posted: Wed May 06, 2009 11:51 am
by 10548492
YES!!!
Thats it. It works.
Thank you.