TeeChart - mil e uma dicas sobre o uso graficos TeeChart

Top  Previous  Next

Notes on Using TeeChart

 

 

June 2003 - Phil Sheppard - Creative Analytics Pty Ltd

 

 

The following notes have been compiled on the TeeChart configurations I’ve 

  found useful in my applications.  TeeChart is very comprehensive which can tend 

  to make it a little complex to understand and use. I find that in most applications 

  I need to configure the chart and series’ in run-time, and so these examples 

  focus on that approach. The following examples are based on TeeChart Pro version 

  6 and I commonly use the TChart and TChartGrid components.

 

 

 

The information contained in this document is believed to be reliable however 

  Creative Analytics Pty Ltd does not guarantee its completeness or accuracy.

 

 

 

Configuring the Chart

 

 

By default TeeChart will place the values of the series in the legend, however 

  I prefer the series names so I generally set the following two properties.

 

 

 

Chart.Legend.LegendStyle := lsSeries;  //to display series’ names in legend

Chart.Legend.ShadowSize := 0;   //to remove shadow in legend

Chart.Legend.Visible := True;

 

 

 

I find the following method useful to undo a user-invoked zoom.

 

 

 

Chart.UndoZoom;

 

 

Configuring an Axis

 

 

It is possible to set the range of any axis (rather than have it automatic).  

  The labels can also be set at an angle by specifying the angle in degrees.

 

 

 

Chart.BottomAxis.Automatic := False;

Chart.BottomAxis.SetMinMax(01);

Chart.BottomAxis.LabelsAngle := 90;

 

 

 

Adding and Configuring a Series

 

 

When you add a series to a chart in run-time, there are quite a few properties 

  that need setting, so I often use a local procedure for this and MyLine or MyBar 

  are local variables. 

 

 

 

Most of the properties are self explanatory, however:

 

 

 

 

  

The Marks property relates to coloured rectangles with a text string near 

    to each Series point. 

  

The pointer property relates to boxes or circles etc at each data point 

    in addition to the series line 

  

The XValues.DateTime is used for timeseries data (see below). 

  

The MultiBar property of the TBarSeries is used to specify whether the series 

    is stacked on another bar series or simply drawn beside. 

  

The BarPen.Visible property specifies whether a line is drawn around each 

    bar. 

 

 

 

procedure AddLineSeries(const Title: string);

begin

  MyLine := TLineSeries.Create(Chart);

  Chart.AddSeries(MyLine);

  MyLine.Title := Title;

  MyLine.ShowInLegend := True;

  MyLine.Marks.Visible := False;

  MyLine.Pointer.Visible := True;

  MyLine.XValues.DateTime := True;

  MyLine.LinePen.Width := 2;

end;

 

 

procedure AddBarSeries(const Title: string);

begin

  MyBar := TBarSeries.Create(Chart);

  Chart.AddSeries(MyBar);

  MyBar.Title := Title;

  MyBar.ShowInLegend := True;

  MyBar.Marks.Visible := False;

  MyBar.MultiBar := mbStacked;

  MyBar.BarPen.Visible := False;

end;

 

 

The Pointer property relates to boxes or  circles etc at each data point in addition to the series line.

 

 

 

MyLine.Pointer.Style is one of psRectangle, psCircle, 

  psTriangle, psDownTriangle, psCross, psDiagCross, psStar, psDiamond, or psSmallDot

 

 

 

By default each series has the same pointer (!) so I use the following to set 

  a different pointer styles for each series.  I set p to zero for the first series, 

  and then incrementing it for each series, checking that p is valid.

 

 

 

MyLine.Pointer.Style := TSeriesPointerStyle(p);

if p > Ord(High(TSeriesPointerStyle)) then p := 0//Check for valid p

 

 

The Y values can be sorted using the following:

 

 

 

MySeries.YValues.Order := loDescending;

MySeries.YValues.Sort;

MySeries.XValues.FillSequence;

 

 

Adding Data to a Series

 

 

The easiest way to add data is to using the Add method, specifying the Y value 

  and its associated label.  For example:

 

 

 

for i := 0 to n-1 do

  MyBar.Add(YData[i], MyLabel[i]);

 

 

Y values can be modified in a series as follows:

 

 

 

for i := 0 to n-1 do

  MyLine.YValue[i] := YData[i];

 

 

X labels can be modified in a series as follows:

 

 

 

for i := 0 to n-1 do

  MyLine.XLabel[i] := MyLabel[i];

 

 

Alternatively, an array of data can also be added in one hit as follows (YData 

  is an array of Real):

 

 

 

for s := 0 to Chart.SeriesCount-1 do

  Chart.Series[s].AddArray(YData);

 

 

Copying to the Clipboard

 

 

Copying the chart as a picture is straightforward, 

  however if we just use a standard method such as Chart.CopyToClipboardMetafile(True)style='"Courier New"'> we may get a border on the top and left side (depending 

  on the Bevel settings). So I tend to set the Bevel’s to bvNone before calling 

  the copy to remove the partial-border.

 

 

 

procedure TMainForm.BtnCopyChartClick(Sender: TObject);

begin

  Chart.BevelInner := bvNone;

  Chart.CopyToClipboardMetafile(True);

  Chart.BevelInner := bvLowered;

end;

 

 

Copying the data underpinning a chart is a bit more complex, however the following 

  seems to work well.  (This requires TeeStore in uses clause).

 

 

 

procedure TMainForm.BtnCopyDataClick(Sender: Object);

var

  Data: TSeriesDataText;

begin

  Data := TSeriesDataText.Create(Chart, nil);

  try

    Data.IncludeLabels := True;

    Data.IncludeHeader := True;

    Data.IncludeIndex := False;

    Data.IncludeColors := False;

    Data.CopyToClipboard;

  finally

    Data.Free;

  end;

end;

 

 

Saving and Loading tee Files

 

 

Saving and loading charts as TeeChart files has a couple of complications. 

  The procedures are globals, and not methods of the Chart object.  They require 

  both TeeStore and TeeEdiSeri (!) in the uses clause.  The application will compile 

  with just TeeStore but will generate run-time errors if you don’t include TeeEdiSeri.

 

 

 

LoadChartFromFile(TCustomChart(Chart), FileName);

SaveChartToFile(Chart, FileName, True);

 

 

 

Events and linked components such as a popup menu cannot be saved, and you 

  must set all events to nil before saving the chart and re-assign them after 

  the chart is loaded.

 

 

 

Functions

 

 

There are many things you can do with functions. What I’ve used here relates 

  to creating a series that is the total of the other series.  This requires TeeFunci 

  in uses clause.

 

 

 

Create the TLineSeries as above then

 

 

 

MyLine.SetFunction(TAddTeeFunction.Create(Self));

for i := 0 to Chart.SeriesCount-1 do

  MyLine.DataSources.Add(Chart.Series[i]);

MyLine.CheckDataSource;  //required to update function-series!

 

 

Apparently this is the correct way of using a TeeFunction, however it does 

  create an access violation when exiting the application.  This is a bug and 

  the work-around is to include a Chart.FreeAllSeries 

  in the FormClose event.

 

 

 

Timeseries Charts

 

 

Datetime based series can be plotted in TChart by setting the DateTime 

  property of the style='font-family:"Courier New"'>XValues property.  

  The datetime format of the bottom axis can be specified and then TChart will 

  create x-axis labels according to your format with having to expressly define 

  labels. I tend to use the AddXY() method when adding data to a timeseries chart, 

  where X is your timestamp and Y is the value at that timestamp.style='font-family:"Courier New"'>

 

 

 

MyLine.XValues.DateTime := True;

Chart.BottomAxis.DateTimeFormat := 'hh:mm';

Chart.BottomAxis.Increment := DateTimeStep[dtOneMonth];

Chart.BottomAxis.Increment := DateTimeStep[dtThirtyMinutes];

 

 

 

Gantt Charts

 

 

set the Order properties because I didn't want 

  the chart to automatically sort each series. I wasn't sure how many series

  I should have, but I just used one series for 50 plus bars in the Gantt chart.  

  You can then superimpose other series (such as a line) over the Gantt if your 

  require this. 

 

 

 

MyGantt := TGanttSeries.Create(Chart);

Chart.AddSeries(MyGantt);

MyGantt.ShowInLegend := False;

MyGantt.XValues.Order := loNone;

MyGantt.YValues.Order := loNone;

MyGantt.ConnectingPen.Width := 2;

For i := 0 to n-1 do

  MyGantt.AddGanttColor(StartDate[i], EndDate[i], i, Name[i], MyColour[i]);

 

 

 

3-D Charts

 

 

While 3D charts look cool, they are harder to read than a 2D chart so I don’t 

  tend to use them too much. They are a little more complex to configure (and 

  populate with data) than a 2D series, but this is how I’ve implemented a 3D 

  surface.

 

 

 

MySurface := TSurfaceSeries.Create(Chart);

Chart.AddSeries(MySurface);

Chart.DepthAxis.Visible := True;

Chart.View3DOptions.Orthogonal := False;

Chart.View3DOptions.Zoom := 90;

Chart.Chart3Dpercent := 40;

MySurface.IrregularGrid := True;

MySurface.UseColorRange := False;

MySurface.UsePalette := True;

MySurface.PaletteStyle := psPale;

MySurface.Pen.Visible := True;

MySurface.ShowInLegend := False;

for i := 0 to n-1 do

  for j := 0 to m-1 do

    MySurface.AddXYZ(j, MyData[i,j], i);

 

 

 

TChartGrid

 

 

I have found that the grid doesn’t always populate properly and so I always 

  call ChartGrid.RecalcDimensions 

  once I’ve finished adding series and data.

 

 

 

The top left cell in the ChartGrid contains the word “Text” by default, and 

  this can be changed by setting the global variable: style='font-family:"Courier New"'>TeeMsg_Text := ‘my text’.  This requires 

  the TeeConst in 

  the uses clause.

.