Difference between revisions of "TAChart documentation"

From Lazarus wiki
Jump to navigationJump to search
Line 20: Line 20:
 
It can be used as "central axis" in function graphs or as a draggable marker.
 
It can be used as "central axis" in function graphs or as a draggable marker.
  
Also, by setting <code>Active</code>=true, <code>Pen.Style</code>=<code>psClear</code> and
+
Also, by setting <code>Active</code>=true, <code>Pen.Style=psClear</code> and
<code>UseBounds</code>=true and appropriate <code>AxisIndexX</code>, it becomes "axis extender",
+
<code>UseBounds=true</code> and appropriate <code>AxisIndexX</code>, it becomes "axis extender",
 
making sure that given <code>Position</code> will always by included in the axis range.
 
making sure that given <code>Position</code> will always by included in the axis range.
  
Line 28: Line 28:
 
Basic series are mos often used, and include [[#Line series|line]], [[#Bar series|bar]] and [[#Area series|area]] series.
 
Basic series are mos often used, and include [[#Line series|line]], [[#Bar series|bar]] and [[#Area series|area]] series.
 
All basic series can be "stacked" by using [[#Multi-valued sources|multi-valued source]].
 
All basic series can be "stacked" by using [[#Multi-valued sources|multi-valued source]].
Also, all basic series fully support rotation and 3-d drawing.
+
Also, all basic series fully support rotation and 3-D drawing.
  
 
==== Line series ====
 
==== Line series ====
Line 49: Line 49:
  
 
Some operating systems/widgetsets may additionally require that
 
Some operating systems/widgetsets may additionally require that
<code>LinePen.Style</code>=<code>psSolid</code> and <code>LinePen.Width</code>=1.
+
<code>LinePen.Style=psSolid</code> and <code>LinePen.Width=1</code>.
  
Additional speedups will be available if <code>Source.Sorted</code>=true.
+
Additional speedups will be available if <code>Source.Sorted=true</code>.
  
 
You can measure line speed drawing on your platform with the "line" demo.
 
You can measure line speed drawing on your platform with the "line" demo.
Line 61: Line 61:
 
You can control bar width with <code>BarWidthPercent</code> property. Note that the it is measured relative to the
 
You can control bar width with <code>BarWidthPercent</code> property. Note that the it is measured relative to the
 
neighboring bars. If the X values are not equidistant, bars will have varying width.
 
neighboring bars. If the X values are not equidistant, bars will have varying width.
To prevent that, set <code>BarWidthStyle</code>=<code>bwPercentMin</code>.
+
To prevent that, set <code>BarWidthStyle=bwPercentMin</code>.
  
 
You can draw multiple bar series side-by-side by using <code>BarOffsetPercent</code> property.
 
You can draw multiple bar series side-by-side by using <code>BarOffsetPercent</code> property.
Line 68: Line 68:
  
 
<code>TAreaSeries</code> represents data as a polygon extending from the data points to either <code>ZeroLevel</code> line
 
<code>TAreaSeries</code> represents data as a polygon extending from the data points to either <code>ZeroLevel</code> line
or infinitely down (if <code>UseZeroLevel</code>=false).
+
or infinitely down (if <code>UseZeroLevel=false</code>).
  
 
You can get "stepped" look by setting <code>ConnectType</code> property.
 
You can get "stepped" look by setting <code>ConnectType</code> property.
  
 
=== Multi-value series ===
 
=== Multi-value series ===
 +
 +
Multi-value series require [[#Multi-valued sources|multi-valued data source]], and use additional Y values
 +
as extra parameters to draw complex shapes.
 +
 +
==== Bubble series ====
 +
 +
<code>TBubbleSeries</code> represent data as a circles of variable radius centered at data points.
 +
This series require source with <code>YCount</code> of at least 2,
 +
and use first additional Y value as radius.
 +
 +
==== Box-and-whiskers series ====
 +
 +
<code>TBoxAndWhiskerSeries</code> represents data as rectangles with a medium line and
 +
two T-like shape protruding in both directions.
 +
Although in statistics [[Wikipedia:Box_plot|box-and whiskers plot]] is supposed to be based in specific
 +
data quartiles, TAChart does not enforce this, allowing user to draw arbitrary plots.
 +
 +
With some effort, box-and whiskers series may be used to represent other charts
 +
different in meaning, but similar in appearance, such as
 +
[[Wikipedia:Gantt_chart|Gantt diagram]] or [[Wikipedia:Candlestick_chart|Candlestick chart]].
 +
 +
This series require source with <code>YCount</code> of at least 5, and use Y values as follows:
 +
{|
 +
!Index!!Usage
 +
|-
 +
|0||Lower whisker
 +
|-
 +
|1||Lower box bound
 +
|-
 +
|2||Medium line
 +
|-
 +
|3||Upper box bound
 +
|-
 +
|4||Upper whisker
 +
|-
 +
|}
 +
 +
==== Open-high-low-close series ====
 +
 +
<code>TOpenHighLowCloseSeries</code> represent data as a vertical lines with two ticks,
 +
as described [[Wikipedia:Open-high-low-close_chart|here]].
 +
 +
It usually requires <code>YCount</code> of at least 4, and use Y values as follows:
 +
{|
 +
!Property!!Default!!Usage
 +
|-
 +
|YIndexLow||0||Lower point of line
 +
|-
 +
|YIndexOpen||1||Left-facing tick position
 +
|-
 +
|YIndexClose||2||Right-facing tick position
 +
|-
 +
|YIndexHigh||3||Upper point of line
 +
|-
 +
|}
 +
 +
Note that although Y values are supposed to be ordered ascending along the table above,
 +
the series does not enforce this and will draw any supplied data.
  
 
=== Radial series ===
 
=== Radial series ===
 +
 +
You can see axamples of radial series in "radial" demo.
  
 
==== Pie series ====
 
==== Pie series ====
 +
  
 
==== Polar series ====
 
==== Polar series ====
 +
 +
<code>TPolarSeries</code> represent data as points in [[Wikipedie:Polar_coordinate_system|polar coordinates]].
 +
 +
The origin of the polar coordinate system is defined in graph coordinates by <code>OriginX</code> and <code>OriginY</code>
 +
properties.
 +
 +
For each data point, X value is interpreted as angle in radians and Y value -- as a distance from the center.
  
 
=== User-drawn series ===
 
=== User-drawn series ===

Revision as of 09:29, 29 July 2011

English (en) русский (ru) українська (uk) 中文(中国大陆)‎ (zh_CN)

Overview

TAChart is a package for drawing graphs, charts and other diagrams. It is comparable in features, but not specifically compatible, with Delphi TeeChart package. One substantial difference is that some features (e.g. data sources and axis transformations) are implemented via separate components instead of just properties. This leads to increased flexibility and opportunity for code re-use, but at the cost of some additional API complexity.

Series

Series are the central part of TAChart. Most of the series represent data taken from data sources in graphical ways, such as lines or bars.

Constant line series

This is the simplest series type, representing "infinite" vertical or horizontal line. It can be used as "central axis" in function graphs or as a draggable marker.

Also, by setting Active=true, Pen.Style=psClear and UseBounds=true and appropriate AxisIndexX, it becomes "axis extender", making sure that given Position will always by included in the axis range.

Basic series

Basic series are mos often used, and include line, bar and area series. All basic series can be "stacked" by using multi-valued source. Also, all basic series fully support rotation and 3-D drawing.

Line series

TLineSeries can be used to draw give set of points, optionally marking them with shapes and connecting with lines.

You can get "stepped" look by setting LineType property to ltStepXY or ltStepYX.

Fast lines

Some charting packages include special "fast line" series to quickly draw line series from extremely large datasets (10000+ points). Instead, TAChart contains optimized fast path inside standard line series code, achieving comparable drawing speed. Line series will draw very fast if all of the following are true:

  • There is no marks.
  • There is no pointers.
  • LineType is not ltFromOrigin.

Some operating systems/widgetsets may additionally require that LinePen.Style=psSolid and LinePen.Width=1.

Additional speedups will be available if Source.Sorted=true.

You can measure line speed drawing on your platform with the "line" demo.

Bar series

TBarSeries represents data as a set or bars, extending from ZeroLevel to data points.

You can control bar width with BarWidthPercent property. Note that the it is measured relative to the neighboring bars. If the X values are not equidistant, bars will have varying width. To prevent that, set BarWidthStyle=bwPercentMin.

You can draw multiple bar series side-by-side by using BarOffsetPercent property.

Area series

TAreaSeries represents data as a polygon extending from the data points to either ZeroLevel line or infinitely down (if UseZeroLevel=false).

You can get "stepped" look by setting ConnectType property.

Multi-value series

Multi-value series require multi-valued data source, and use additional Y values as extra parameters to draw complex shapes.

Bubble series

TBubbleSeries represent data as a circles of variable radius centered at data points. This series require source with YCount of at least 2, and use first additional Y value as radius.

Box-and-whiskers series

TBoxAndWhiskerSeries represents data as rectangles with a medium line and two T-like shape protruding in both directions. Although in statistics box-and whiskers plot is supposed to be based in specific data quartiles, TAChart does not enforce this, allowing user to draw arbitrary plots.

With some effort, box-and whiskers series may be used to represent other charts different in meaning, but similar in appearance, such as Gantt diagram or Candlestick chart.

This series require source with YCount of at least 5, and use Y values as follows:

Index Usage
0 Lower whisker
1 Lower box bound
2 Medium line
3 Upper box bound
4 Upper whisker

Open-high-low-close series

TOpenHighLowCloseSeries represent data as a vertical lines with two ticks, as described here.

It usually requires YCount of at least 4, and use Y values as follows:

Property Default Usage
YIndexLow 0 Lower point of line
YIndexOpen 1 Left-facing tick position
YIndexClose 2 Right-facing tick position
YIndexHigh 3 Upper point of line

Note that although Y values are supposed to be ordered ascending along the table above, the series does not enforce this and will draw any supplied data.

Radial series

You can see axamples of radial series in "radial" demo.

Pie series

Polar series

TPolarSeries represent data as points in polar coordinates.

The origin of the polar coordinate system is defined in graph coordinates by OriginX and OriginY properties.

For each data point, X value is interpreted as angle in radians and Y value -- as a distance from the center.

User-drawn series

Functional series

Sources

Data can gen into a chart from various sources. They are implemented as a set of components derived from TCustomChartSource.

To assign source to a series, you can set Source property. If the property is left unassigned, series will use its own built-in list source. Methods like AddXY are delegated to the current series source. Note that the list source is the only editable source, so after you assign, for example, random chart source to the series, call to AddXY will raise an exception.

Each data item has the following fields: X, Y, YList, Color, Text.

Sorted sources

If it is known that X values of the source are ascending, some additional optimizations like binary search become possible. So all sources have IsSorted property which helps determine that.

Multi-valued sources

Sources can contain multiple Y values for each X value. These values are stored in YList field of the source data item. The number of Y values is determined by YCount property. Note that first Y value is strored in Y field anyway, so YCount = 3 means that values are stored in Y, YList[0] and YList[1].

Additional values may be used by various series -- for example, stacked bars or bubble charts.

List source

TListChartSource is a basic chart source, storing chart data inside itself. As such, you can use Add and Delete function change source data.

The source also has DataPoints property to allow setting data at design time. This property is a TStringList, with each line representing a data point. Line consists of X, Y, optional YList, Color and Text values separated by | (vertical bar) character. Note that DataPoints property is designed primarily for sample and demo code. It is very inefficient, and you should not use if to add data points from the code.

You can control X value sorting by setting Sorted property. Note when Sorted is set to true, list source sorts the data and keeps it sorted after insertion of new points. If inserted points are not sorted, this may result in quadratic running time. You should so either set Sorted to true only after insertion, or pre-sort your data to avoid this.

Random source

TRandomChartSource source generates random data in the given range and is intended mostly to use in demos. You can also use it as design-time replacement for you actual data source. This will let you see and change the look of your chart without having to run the application.

Each random source uses it's own independent random number generator to guarantee stability of it's values.

User-defined source

This source may be used if you already have your data in memory, but in the format different from the data items used in TAChart. Using user-defined source to access your data directly instead of first moving it all into a list source may (or may not) be beneficial for speed.

You can of course also use user-defined source to generate, filter or modify data.

Note that if Sorted property is set to true, it is the responsibility of event handler to provide actually sorted data.

Database source

TDbChartSource takes data directly from the database. It is contained in a separate unit to avoid introducing db-aware component dependency into every project using TAChart.

The following properties contain database field names for data item fields:

Property Access method
FieldX AsFloat
FieldY AsFloat
FieldColor AsInteger
FieldText AsString

If FieldX property is empty, RecNo is used instead.

To get multi-valued source, set FieldY property to a comma-separated list of field names. Note that YCount will be set automatically -- trying to set it by hand will raise an exception.

Calculated source

TCalculatedChartSource is the source used for manipulating data taken from the Origin source. This source performs transformations in the following order:

  • Y reordering -- Y values of multi-valued source can be duplicated, removed or exchanged according to ReorderYList property, which is a comma-separated list of original Y value indexes. Step skipped if ReorderYList is empty.
  • Accumulation -- replaces each item's Y values by some function (for example, sum or average) of the last AccumulationRange items. Step skipped if AccumulationMethod property is camNone.
  • Percentage -- replace each Y value by the percentage of total of all Y values for that item. Useful for drawing "stacked percentage" bar and area charts. Step skipped if Percentage property is false.

Efficiency notes

Primary data source API allows random access. Nevertheless, many sources, in particular random, database and calculated, may exhibit quadratic or worse behavior if actually accessed randomly. TAChart itself takes care to only use sequential access (although may it require several passes). Sources optimize sequential access by using internal state. User code should be careful not to reset this state during chart drawing from event handlers or custom series code.

Notable exception is list source, which is guaranteed to provide fast random access. It may be used to cache slow sources with the help of CopyForm procedure.

Coordinates and axises

TAChart uses three coordinate systems:

  • Axis coordinates (known in some other applications as object coordinates) -- this is the "raw" coordinate values obtained from the data. As the name implies, axis coordinates are interpreted in therms of specific axis -- the same coordinate value may have different meaning depending on the axis it is applied to.
  • Graph coordinates (aka world coordinates) are converted from the axis coordinates using axis transformation, such as logarithmic scale. Graph coordinates are common for all objects in the chart.
  • Image coordinates (aka screen coordinates) are converted from graph coordinates based on the chart viewport. This transformation is always linear and can be influenced by chart tools such as zooming and panning.

You can add or remove arbitrary number of axises by editing AxisList property. By default, chart have two axises: one horizontal and one vertical. They are accessible via BottomAxis and LeftAxis properties. Note that those properties are aliases to AxisList[0] and AxisList[1], so if you remove those default axises, accessing BottomAxis and LeftAxis will return nil.

Axis transformations

Axis transformations are grouped in TChartAxisTransformations component. It contains a list of transformations which are applied in the order given. (For example, performing scale before and after logarithm will yield different results).

For transformations to have an effect, you should:

  • Make sure Enabled property is true for all transformations.
  • Assign transformations component to Transformations property of at least one axis.
  • Assign AxisIndexX and/or AxisIndexY properties of the series to the appropriate axis index.

Note that by default, AxisIndexX and AxisIndexY have a special value of -1, which means "ignore axis transformations". Also note that if you add or remove axises, the indexes may change. You can rotate the series by assigning both AxisIndexX to vertical axis and AxisIndexY to the horizontal axis.

Linear and logarithmic transformation

Those are simple arithmetic transformations.

Auto-scaling transformation

To display several independently scaled series, assign them to two or more axises and apply TAutoScaleAxisTransform to each axis. See "axistransf" demo, page "Linear", checkbox "Auto scale".

By using MinValue and MaxValue properties you can control the in graph coordinates of the auto-scaled series. For example, by setting one transformation to a range from 0 to 1, and another to a range from 1 to 2, you will confine all the series using the first transformation to the upper half of the chart, and all the series using the second transformation to the lower half (assuming there are no unassigned series left).

User-defined transformation

You can create you own transformation either by inheriting from TAxisTransform, or, if you prefer "visual" programming, by using TUserDefinedAxisTransform. In either case there are two basic requirements:

  • AxisToGraph and GraphToAxis functions should be defined everywhere in data range and inverse of each other (for example, avoid now only dividing, but also multiplying by zero).
  • functions should be monotonic.

Extents

Tools

TODO

Legend

TODO

Marks

TODO

Drawers

TODO

Navigation

TODO