Sign in Join
Wiki copytemporary

TAChart documentation/uk: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: TAChart documentation/uk

OldNewLine
1+## Огляд
2+
3+[[TAChart]] є компонентою для малювання графіків, кругових та інших діаграм. Він сумісний, але не повністю, з можливостями компоненти TeeChart в Delphi. Однією з основних відмінностей є те, що деякі можливості (напр. джерела даних і перетворення осей) реалізовані окремими компонентами, а не властивостями. Це дає більшу гнучкість і кращі можливості повторного використання коду, ціною за це є деяка складність API.
4+
5+## Серії (послідовності даних)
6+
7+Серії є центральною частиною TAChart. Більшість серій відображають дані, взяті з джерел, графічним способом, напр. лініями чи стовпчиками.
8+
9+### Серія - фіксована лінія
10+
11+Це найпростіший тип серій, представлений фіксовано вертикальною чи горизонтальною лінією. Лінія може використовуватися як центральна вісь у графіках функцій або як перетягувана мітка.
12+
13+Також, задавши `Active`=true, `Pen.Style=psClear`, `UseBounds=true` і відповідну `AxisIndexX`, вона стає "розширенням осі", чим гаранту, що задана `Position` завжди буде включена в інтервал осі.
14+
15+### Основні серії
16+
17+Основні серії використовуються найчастіше, вони включають line, bar і area. All basic series can be "stacked" by using multi-valued source. Також усі основні серії повністю підтримують обертання і 3-D відображення.
18+
19+#### Line series
20+
21+`TLineSeries` can be used to draw a given set of points, optionally marking them with shapes and connecting with lines.
22+
23+You can get a "stepped" look by setting `LineType` property to `ltStepXY` or `ltStepYX`.
24+
25+##### Fast lines
26+
27+Some charting packages include special "fast line" series to quickly draw line series from extremely large datasets (10000+ points). Instead, TAChart contains an optimized fast path inside standard line series code, achieving comparable drawing speed. Line series will be drawn very fast if all of the following are true:
28+
29+- There are no marks.
30+- There are no pointers.
31+- `LineType` is not `ltFromOrigin`.
32+
33+Some operating systems/widgetsets may additionally require that `LinePen.Style=psSolid` and `LinePen.Width=1`.
34+
35+Additional speedups will be available if `Source.Sorted=true`.
36+
37+You can measure line speed drawing on your platform with the "line" demo.
38+
39+#### Bar series
40+
41+`TBarSeries` represents data as a set or bars, extending from `ZeroLevel` to data points.
42+
43+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`.
44+
45+You can draw multiple bar series side-by-side by using `BarOffsetPercent` property.
46+
47+#### Area series
48+
49+`TAreaSeries` represents data as a polygon extending from the data points to either `ZeroLevel` line or infinitely down (if `UseZeroLevel=false`).
50+
51+You can get a "stepped" look by setting `ConnectType` property.
52+
53+### Multi-value series
54+
55+Multi-value series require multi-valued data source, and use additional Y values as extra parameters to draw complex shapes.
56+
57+#### Bubble series
58+
59+`TBubbleSeries` represent data as a circles of variable radius centered at data points. This series requires source with `YCount` of at least 2, and uses first additional Y value as radius.
60+
61+#### Box-and-whiskers series
62+
63+`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](https://en.wikipedia.org/wiki/Box_plot) is supposed to be based on specific data quartiles, TAChart does not enforce this, allowing users to draw arbitrary plots.
64+
65+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](https://en.wikipedia.org/wiki/Gantt_chart) or [Candlestick chart](https://en.wikipedia.org/wiki/Candlestick_chart).
66+
67+This series requires source with `YCount` of at least 5, and uses Y values as follows:
68+
69+| Index | Usage |
70+|-------|-----------------|
71+| 0 | Lower whisker |
72+| 1 | Lower box bound |
73+| 2 | Medium line |
74+| 3 | Upper box bound |
75+| 4 | Upper whisker |
76+| | |
77+
78+#### Open-high-low-close series
79+
80+`TOpenHighLowCloseSeries` represent data as a vertical lines with two ticks, as described [here](https://en.wikipedia.org/wiki/Open-high-low-close_chart).
81+
82+It usually requires `YCount` of at least 4, and uses Y values as follows:
83+
84+| Property | Default | Usage |
85+|-------------|---------|----------------------------|
86+| YIndexLow | 0 | Lower point of line |
87+| YIndexOpen | 1 | Left-facing tick position |
88+| YIndexClose | 2 | Right-facing tick position |
89+| YIndexHigh | 3 | Upper point of line |
90+| | | |
91+
92+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.
93+
94+### Radial series
95+
96+Radial series ignore axis transformations. You can see examples of radial series in the "radial" demo.
97+
98+#### Pie series
99+
100+`TPieSeries` draws pie charts.
101+
102+For each data point, pie series interprets Y value as a relative size of the slice, and X value as a distance of splice from the center of the pie (only if `Exploded` property is true). Slice colors can be set in data items, or taken from the hard-coded list.
103+
104+Pie radius can be either set manually by `FixedRadius` property, or calculated automatically so that the whole series, including all labels, exactly fits the parent chart.
105+
106+There are several options for label positioning, controlled by `MarkPositions` property:
107+
108+- `pmpAround` -- marks are drawn outside the pie, on the continuation or radius vector for each slice
109+- `pmpInside` -- marks are drawn inside each slice
110+- `pmpLeftRight` -- marks are drawn directly to the left or to the right of slice
111+
112+If `RotateLabels` is true, each label is additionally rotated so that (if `LabelFont.Orientation=0`) it is parallel to the radius vector of its slice.
113+
114+If the Y value of thr data item is set to NaN, the item is skipped. If the X value is set to NaN, the item is not drawn, but the space for it is still reserved. This allows drawing of "partial" pie diagrams.
115+
116+#### Polar series
117+
118+`TPolarSeries` represents data as points in [polar coordinates](https://en.wikipedia.org/wiki/Polar_coordinate_system).
119+
120+The origin of the polar coordinate system is defined in graph coordinates by `OriginX` and `OriginY` properties.
121+
122+For each data point, X value is interpreted as an angle in radians and Y value -- as a distance from the center.
123+
124+### User-drawn series
125+
126+Provides `OnDraw` and `OnGetBounds` events to allow arbitrary custom drawing on the TChart. Note that using `TChart.Canvas` directly is highly discouraged an will often not as expected.
127+
128+### Functional series
129+
130+Functional series are recommended way to draw functional plots as opposed to, for example, pre-calculating function data and using line series. They provide scale-independent controls of smoothness vs drawing speed.
131+
132+You can see examples of functional series in "func" demo.
133+
134+#### Function series
135+
136+`TFuncSeries` represents a one-dimensional function defined by `OnCalculate` event as a line.
137+
138+The function is calculated for each `Step` pixels of the image, so you can use this property to increase "smoothness" or drawing speed.
139+
140+`DomainExclusions` property allows to exclude some intervals from the function domain. Function series correctly draws discontinuity points set by `DomainExclusions`. Currently, `DomainExclusions` can only be set at run-time.
141+
142+#### B-spline series
143+
144+`TBSplineSeries` draws [B-spline](https://en.wikipedia.org/wiki/B-spline) of given `Dergee` using [De Boor's algorithm](https://en.wikipedia.org/wiki/De_Boor's_algorithm).
145+
146+Spline segments shorter then `Step` pixels are represented by straight lines.
147+
148+#### Cubic spline series
149+
150+`TCubicSplineSeries` draws [cubic spline](https://en.wikipedia.org/wiki/Spline_interpolation) using standard Numlib package from the FPC.
151+
152+The spline function is calculated for each `Step` pixels of the image, so you can use this property to increase "smoothness" or drawing speed.
153+
154+Data source must contain at least 4 points and have strictly increasing X coordinate.
155+
156+If there are too few points, and `csoDrawFewPoints` option is set, line will be drawn instead of spline using `BadDataPen`.
157+
158+If X values are unordered and `csoDrawUnorderedX` option is set, spline will be drawn ignoring offending points using `BadDataPen`.
159+
160+`csoExtrapolateLeft` and `csoExtrapolateRight` options enable natural extrapolation to the left and to the right correspondingly.
161+
162+#### Color map series
163+
164+`TColorMapSeries` represent 2-dimensional function defined by `OnCalculate` event as a field of pixels, with color depending on function value.
165+
166+The field is drawn as a set of rectangles of size `StepX` by `StepY` pixels. The function is called once for each rectangle.
167+
168+Color values are defined by `ColorSource`, which must be sorted. For each data point is interpreted as having X value correspond to Color value. If the actual value falls between color levels, it can be either linearly interpolated (if `Interpolate=true`) or rounded down to the nearest level.
169+
170+When `Legend.Multiplicity=lmPoint`, color map series will display color levels in the legend.
171+
172+## Sources
173+
174+Data can get into a chart from various sources. They are implemented as a set of components derived from `TCustomChartSource`.
175+
176+To assign a source to a series, you can set the `Source` property. If the property is left unassigned, the 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, a random chart source to the series, a call to `AddXY` will raise an exception.
177+
178+Each data item has the following fields: X, Y, YList, Color, Text.
179+
180+### Sorted sources
181+
182+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.
183+
184+### Multi-valued sources
185+
186+Sources can contain multiple Y values for each X value. These values are stored in the `YList` field of the source data item. The number of Y values is determined by the `YCount` property. Note that the first Y value is stored in Y field anyway, so `YCount=3` means that values are stored in `Y`, `YList[0]` and `YList[1]`.
187+
188+Additional values may be used by various series -- for example, stacked bars or bubble charts.
189+
190+### Skipping source items
191+
192+It is possible to instruct TAChart to skip drawing some source items without removing them from the source. This may be useful for both optimization and user interface reasons.
193+
194+To skip the item, assign [NaN](http://www.freepascal.org/docs-html/rtl/math/nan.html) to either X value or one of the Y values. The exact effect of skipping depends on the series, but usually setting X to NaN means skipping the entire item, while setting Y or some element of YList means skipping only this Y value, while still drawing others.
195+
196+Also note that if you set only one coordinate to NaN, the other will still take part in extent calculation.
197+
198+You can see examples of skipping items in the "nan" demo.
199+
200+### List source
201+
202+`TListChartSource` is a basic chart source, storing chart data inside itself. As such, you can use `Add` and `Delete` functions to change source data.
203+
204+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 it to add data points from the code.
205+
206+You can control X value sorting by setting the `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 either set `Sorted` to true only after insertion, or pre-sort your data to avoid this.
207+
208+### Random source
209+
210+`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.
211+
212+Each random source uses its own independent random number generator to guarantee stability of its values.
213+
214+### User-defined source
215+
216+This source may be used if you already have your data in memory, but in a 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.
217+
218+You can of course also generate, filter or modify data with the user-defined source.
219+
220+Note that if the `Sorted` property is set to true, it is the responsibility of the event handler to provide actually sorted data.
221+
222+### Database source
223+
224+`TDbChartSource` takes data directly from a database. It is contained in a separate unit to avoid introducing a db-aware component dependency into every project using TAChart.
225+
226+The following properties contain database field names for data item fields:
227+
228+| Property | Access method |
229+|--------------|---------------|
230+| `FieldX` | AsFloat |
231+| `FieldY` | AsFloat |
232+| `FieldColor` | AsInteger |
233+| `FieldText` | AsString |
234+| | |
235+
236+If `FieldX` property is empty, RecNo is used instead.
237+
238+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.
239+
240+### Calculated source
241+
242+`TCalculatedChartSource` is the source used for manipulating data taken from the `Origin` source. This source performs transformations in the following order:
243+
244+- 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.
245+- Accumulation -- replaces each item's Y values by a function of the neighboring values.
246+- 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 the `Percentage` property is false.
247+
248+Accumulation is controlled by several properties:
249+
250+`AccumulationRange` controls number of items to accumulate, counting the current item, so `AccumulationRange = 1` disables accumulation. `AccumulationRange = 0` is interpreted as "infinite" range, i.e. request to accumulate over all the available data. This is mostly useful in conjunction with `camSum` method to produce cumulative sums.
251+
252+Note that the actual number of items may be lower for the points near the beginning or end of the source.
253+
254+`AccumulationDirection`:
255+
256+- cadBackward -- use previous values from the source,
257+- cadForward -- use next values from the source,
258+- cadCenter -- use both previous and next values for a total number of up to `2 * AccumulationRange - 1`.
259+
260+`AccumulationMethod`:
261+
262+- camNone -- skip accumulation step,
263+- camSum -- sum of the last `AccumulationRange` items,
264+- camAverage -- average the last `AccumulationRange` items,
265+- camDerivative -- finite differences derivative, calculated using the last `AccumulationRange` items. Note that the calculation method assumes equidistant X values, and may loose accuracy if the X distance varies substantially.
266+- camSmoothDerivative -- smoothed finite differences derivative, more robust against random measurement errors in the data.
267+
268+### Interval source
269+
270+`TIntervalChartSource` can supply arbitrarily many points in a given interval, controlled by various properties of the source. This source is the default built-in source for axis marks. If you want to set the same axis interval parameters for several axises, you can assign a single `TIntervalChartSource` component the `Marks.Source` of each of those axises.
271+
272+### Date-time interval source
273+
274+`TDateTimeIntervalChartSource` is similar to the TIntervalChartSource, but provides marks formatted as date/time values. This source automatically selects appropriate calendar interval (such as week or hour) depending on the axis scale.
275+
276+Note that X values of provided data items are `TDateTime` values, and `Label` values contain formatted date-time strings. If you want to use `TDateTimeIntervalChartSource` as the source of axis marks, you should probably set `Marks.Format` or `Marks.Style` properties to make use of provided labels.
277+
278+If the `DateTimeFormat` property is set, it is used to format all labels. Formatting is performed with standard [SysUtils.FormatDateTime](http://www.freepascal.org/docs-html/rtl/sysutils/formatdatetime.html) function. If `DateTimeFormat` is empty, format is chosen automatically based on scale.
279+
280+### Source optimization notes
281+
282+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 it may 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.
283+
284+A notable exception is the list source, which is guaranteed to provide fast random access. It may be used to cache slow sources with the help of `CopyForm` procedure.
285+
286+Also note that the pointer returned by `GetItem` function may point to the internal buffer which will be overwritten by the next call to `GetItem`. Again the list source does not have this limitation.
287+
288+## Coordinates and axises
289+
290+TAChart uses three coordinate systems:
291+
292+- *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 terms of specific axis -- the same coordinate value may have different meaning depending on the axis it is applied to.
293+- *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.
294+- *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.
295+
296+You can add or remove an 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.
297+
298+Visually, axis consists of the axis line (drawn by `AxisPen`), grid lines (drawn by `GridPen`), ticks, marks and arrow.
299+
300+Each axis is drawn inside its own rectangle, determined by the size of mark labels and ticks. By assigning several axis the same positive `Group` number, you can have them share the same rectangular area. Grouped axises can be used to achieve "panes" look, when several series are drawn on different portions of the same graph.
301+
302+### Axis transformations
303+
304+Axis transformations are grouped in the `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).
305+
306+For transformations to have an effect, you should:
307+
308+- Make sure `Enabled` property is true for all transformations.
309+- Assign transformations component to `Transformations` property of at least one axis.
310+- Assign `AxisIndexX` and/or `AxisIndexY` properties of the series to the appropriate axis index.
311+
312+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.
313+
314+#### Linear and logarithmic transformation
315+
316+Those are simple arithmetic transformations.
317+
318+#### Auto-scaling transformation
319+
320+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".
321+
322+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).
323+
324+#### User-defined transformation
325+
326+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:
327+
328+- `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).
329+- Functions should be monotonic.
330+
331+### Date and time axises
332+
333+Using date/time values for axis marks is a common requirement. Proper way to do this depends on the exact nature of date/time data:
334+
335+- If the data is actual `TDateTime values`, use it as X coordinate in points, assign TDateTimeIntervalChartSource to the `Marks.Source` of the corresponding axis, and change `Marks.Style` to `smsLabel`. `TDateTimeIntervalChartSource` provides automatic labeling depending on the scale in wide range -- from centuries to milliseconds.
336+- If the data is in physical units, but outside `TDateTime values` range, such as astronomical or micro-electronics timings, use it a normal X coordinate with custom `Marks.Format`.
337+- If the data is in calendar units, such as months and years, which is common for financial data, you have several options:
338+ - If date units are "equidistant" when interpreted as numbers (for example, simple year numbers), assign the same data source to both series and axis marks, then use custom `Marks.Format`, `Axis.OnMarkToText` event or `Text` field of the data items to format dates per your requirements.
339+ - If date units are not "equidistant" (for example, numbers in YYYYMM format or even date strings), use surrogate X coordinate (usually, simply a point index) instead and display dates using methods described above.
340+ - Convert coordinates to `TDateTime values` beforehand, then use `TDateTimeIntervalChartSource` as described above.
341+
342+### Axis intervals
343+
344+Axis marks are located along the axis at equal intervals chosen by the chart. The choice of intervals can be influenced via `Intervals` property. This property has a few subproperties, which are applied in the following order:
345+
346+- `Options` property contains a set of flags controlling usage of other parameters. If the flag is not in the set, corresponding parameter is ignored.
347+- `NiceSteps` is a string containing a sequence of "step multipliers" -- floating point values in the range from 0 to 1, excluding 0. If this property is applied, the axis step will be a power of ten multiplied by one of the provided values. If several multipliers can be used, the leftmost one will be chosen. Multipliers are separated by the vertical bar (\|) character.
348+- If `NiceSteps` is ignored or TAChart fails to find appropriate step, the axis range will be divided into equal intervals without regard to the number of decimal digits in the representation of mark values. In this case, it is recommended to reduce the number of visible digits in `Marks.Format`.
349+- `MinLength` and `MaxLength` properties set the limits of interval length *in image units* (usually pixels).
350+- `Count` property is the desired number of axis marks. Among all mark steps passing the previous tests, TChart chooses the one which gives the number of marks nearest to the `Count`. If `Count` property is ignored, or there are several steps with equal number of marks, the longest step is chosen.
351+
352+Note that if you set chart source manually, `Intervals` property may apply only partially or not apply at all. For example, list source is unable to guarantee maximum interval length, since it has only a finite number of points. See also interval chart source.
353+
354+## Extents and margins
355+
356+### Extents
357+
358+Chart *extent* is a rectangle in graph coordinates.
359+
360+There are several extents defined by TChart:
361+
362+- *Full extent* -- usually determined automatically as the area encompassing all the data from series and axis ranges. Returned by `GetFullExtent` function.
363+- *Fixed extent* -- determined by `TChart.Extent` property. May override full extent calculation partially or fully.
364+- `LogicalExtent` -- the extent requested by user to be seen on chart image. Writing to this property if the official way to change chart extent by the external code. For example, `LogicalExtent := GetFullExtent` is (almost) equivalent to calling `ZoomFull` procedure.
365+- `CurrentExtent` -- the extent actually displayed to the user. May differ from the `LogicalExtent` due to the need to reserve space for series marks, inner chart margins etc.
366+
367+### Linked extents
368+
369+Using `TChartExtentLink` component, you can ensure that logical extents of several charts enumerated by `LinkedCharts` property always stay the same.
370+
371+This is useful for simulating multi-pane chart layout. See "panes" demo for an example.
372+
373+### Margins
374+
375+*Margin* is a distance reserved around the edges of rectangular region. Margins are measured in image units (usually pixels). Chart itself have two margins:
376+
377+- Internal (`Margins` property) -- applied after the axises drawing. Are also influenced by series marks and series themselves.
378+- External (`MarginsExternal` property) -- applied before the axises drawing. Are also influenced by axis marks and arrows.
379+
380+Other chart elements, such as legend, title, footer and labels, also have margins.
381+
382+### Optimization notes
383+
384+Calculation of `CurrentExtent` and actual margins is non-trivial *iterative* process (see `TChart.PrepareAxis` code for details). Although usually fast, in complex cases it can require multiple passes through chart sources.
385+
386+## Tools
387+
388+Chart tools define reaction of the chart to various user actions, primarily mouse movements and clicks. You can see examples of tools usage in "tools" demo.
389+
390+Tools are grouped in `TChartToolset` component, which should be assigned to chart's `Toolset` property. Same toolset can be used in several charts.
391+
392+If `Toolset` is unassigned, for compatibility reasons built-in toolset consisting of drag zoom and reticule tools is used.
393+
394+Each user action, tools in the toolset are processed in order, and for each tool:
395+
396+- If `Enabled=false`, the tool is ignored.
397+- If `Shift` is not equal to the current shift state, the tool is ignored.
398+- Tools is asked to process the action.
399+- If the tool signaled that the action is handles, processing is stopped, otherwise it continues to the next tool.
400+
401+In you application you can create, for example, a toolbar with each button enabling corresponding tool in the toolset and disabling all others. Alternatively, by assigning different `Shift` values, you can enable several tools at once.
402+
403+### Drawing mode
404+
405+Some tools, such as drag zoom or crosshair, display moving shapes over the chart with the mouse movement.
406+
407+There are two ways to display those shapes: either simply draw them over the chart, fully redrawing the chart upon each mouse movement, or use `pmXor` pen mode to draw and erase the shape directly from the `MouseMove` event handler. The former method allows to use arbitrary pen color and style, but the latter is much more efficient. Additionally, some widgetset ignore all drawing outside the `Paint` event, so the latter method will not work at all.
408+
409+Display method is controlled by `DrawingMode` property with the following values:
410+
411+- `tdmXor` -- use XOR method;
412+- `tdmNormal` -- use full chart redraw;
413+- `tdmDefault` -- use XOR method on widgetsets where it is known to work (Windows and Gtk) and full redraw on others.
414+
415+### Extent tools
416+
417+Extent tools modify chart's logical extent.
418+
419+Zooming tools can be animated by setting `AnimationSteps` to the value greater then 1 and `AnimationInterval` (in milliseconds).
420+
421+Panning tools can be restricted to the chart extent on all or some directions by using `LimitToExtent` property.
422+
423+#### Zoom drag tool
424+
425+`TZoomDragTool` allows user to zoom in by drawing rectangle with the mouse. The rectangle then becomes the new logical extent. Drawing rectangle "in reverse", from the bottom-right to the upper-left corner, restores zooming to the full extent.
426+
427+`RatioLimit` property lets you restrict zooming to one of the coordinates, or require it to keep original proportions.
428+
429+#### Zoom click tool
430+
431+`TZoomClickTool` allows user to zoom in or out clicking on the chart with the mouse. `ZoomFactor` is the multiplier of scale applied by the tool, so factors below 1 represent zoom out, and factors above represent zoom in. `ZoomRatio` allows to set non-proportional zoom by indicating ratio of X to Y scale.
432+
433+If `FixedPoint` is true, the location of the mouse click is used as a fixed point for zooming, otherwise chart image center is used instead.
434+
435+#### Zoom mouse-wheel tool
436+
437+`TZoomMouseWheelTool` allows user to zoom in and out with the mouse wheel. Its properties are identical to the zoom click tool.
438+
439+Chart is scaled by `ZoomFactor` when the used scrolls mouse wheel up, and by `1 / ZoomFactor` when the user scrolls the mouse wheel down.
440+
441+#### Pan drag tool
442+
443+`TPanDragTool` allows user to move logical extent by dragging mouse in the directions indicated by `Directions` property.
444+
445+#### Pan click tool
446+
447+`TPanClickTool` allows user to move logical extent by clicking inside `Margins` pixels from the corresponding border of chart image.
448+
449+The panning offset is determined by the distance from the edge of the chart (the nearer to the edge, the greater). Setting `Interval` in milliseconds will allow to continue panning with the given interval until the moue button is up.
450+
451+### Data tools
452+
453+Data tools are linked to specific data series via `AffectedSeries` property, which is a string of comma-separated series indexes. Note that indexes may change if you add or remove series.
454+
455+When the data tool is activated, it determines the nearest point of the affected series which is located inside of the `GrabRadius` (in pixels).
456+
457+#### Data point drag tool
458+
459+`TDataPointDragTool` allows user to change data values by dragging the data point. Note that this requires series' data source to be a list source.
460+
461+#### Data point click tool
462+
463+`TDataPointClickTool` allows you to assign `OnPointClick` event handler, which will be called when the user clicks on the data point.
464+
465+#### Data point hint tool
466+
467+`TDataPointHintTool` displays hint when the user moves the mouse over the data point. The hint is either equal to the point label (if `UseDefaultHintText=true`) or determined by calling `OnHint` event handler.
468+
469+#### Data point crosshair tool
470+
471+`TDataPointCrosshairTool` displays a cross-hair centered on the data point.
472+
473+#### Reticule tool
474+
475+Reticule tool is deprecated. Use TDataPointCrosshairTool instead.
476+
477+### User defined tool
478+
479+To add you own tool, either inherit from `TUserDefinedTool` or use it directly, assigning one or more On{After,Before}{KeyDown,KeyUp,MouseDown,MouseMove,MouseUp} event handlers.
480+
481+## Decorative elements
482+
483+### Title and footer
484+
485+Chart title and footer are multi-line texts appearing above and below the chart correspondingly. They support various rotations and alignments.
486+
487+### Legend
488+
489+Chart legend is a table with each item containing an icon and a text line.
490+
491+Legend supports various alignments and can be located inside the chart or on the sidebar. Legend can be displayed in two or more columns by setting `ColumnCount` property. Setting `ColumnCount` to a very large value effectively creates "horizontal" legend.
492+
493+Legend items are generated based on chart series which have both `Active` and `ShowInLegend` set to true. Depending in `Legend.Multiplicity` series can produce a single item or one item per point.
494+
495+Legend items can be grouped together under sub-headers. Sub-headers are taken from `GroupNames` property, and each series can use `Legend.GroupIndex` property to indicate its group.
496+
497+Legend items are sorted as following:
498+
499+- By group index, items without group (`GroupIndex=-1` going first to avoid confusion with the last group).
500+- By `Order` property, items without explicit order (`Order=-1`) going last.
501+- By creation order of series.
502+- For multiple items per series, by generation order (for standard series it is the order of points).
503+
504+#### User-defined legend items
505+
506+Arbitrary legend items can be generated by overriding `OnCreate` and `OnDraw` events of series `Legend` property.
507+
508+Note that user-defined item count is controlled solely by `UserItemsCount` property and does not depend on `Multiplicity`. Also note that `GroupIndex` and `Order` properties are actually per-item, so you can totally override entire legend from a single (perhaps fictive) series.
509+
510+### Arrows
511+
512+Arrowheads can be drawn at the end of axis lines, controlled by `TChartAxis.Arrow` property.
513+
514+## Marks
515+
516+Marks annotate certain points of the chart. Typically, mark consists of some graphical element (such as an axis tick) and a text label. However, either of these elements can be omitted.
517+
518+You can see examples in the "labels" demo.
519+
520+### Mark labels
521+
522+The label text can be enclosed in a box, controlled by `LabelBrush` and `Frame` properties. The text itself is created based on the data source items, with the help of `Format` property. This property is used as a first argument for the [`SysUtils.Format`](http://www.freepascal.org/docs-html/rtl/sysutils/format.html) function, with the second argument containing following data items:
523+
524+0\. Y
525+
526+1\. Y as a percentage of the Y total
527+
528+2\. Text
529+
530+3\. Y total
531+
532+4\. X
533+
534+Where "Y total" is the sum of all Y values for this source. Note that not all sources supply all the items above.
535+
536+Some pre-defined formats can be set via the `Style` property.
537+
538+If the source is mutli-valued, `YIndex` property determines which Y value is used. If `YIndex = -1`, a separate label is displayed for each Y value, which is useful for the stacked series.
539+
540+The text or rendered using the `LabelFont`. Note in particular that TAChart supports arbitrary font `Orientation`.
541+
542+#### Multi-line marks
543+
544+If the mark text contains [`LineEnding`](http://www.freepascal.org/docs-html/rtl/system/lineending.html) character sequence, it is split into several lines. If lines have different lengths, they are aligned according to </code>Alignment</code> property.
545+
546+### Mark positions and attachment
547+
548+Mark position relative to the marked point is determined by the marks owner (series or axis).
549+
550+Common mark properties include `Distance`, which measures the distance from the origin point to the attachment point in image units, and `Attachment`, which controls whether the attachment point is considered to be in the center or at the edge of the label box.
551+
552+Additionally, basic chart series have `MarkPositions` property, specifying the direction of labels' offsets relative to series data points as following:
553+
554+- lmpOutside -- away from zero level
555+- lmpPositive -- positive direction of series' Y axis
556+- lmpNegative -- negative direction of series' Y axis
557+- lmpInside -- towards zero level
558+
559+## Drawers
560+
561+For low-level drawing routines, TAChart uses special set of classes implementing `IChartDrawer` interface. This allows such features as printing charts and exporting them to SVG format.
562+
563+These classes are called *drawing back-ends* or *drawers* for short.
564+
565+### TCanvas drawer
566+
567+`TCanvasDrawer` is the default drawer used to display chart on TCanvas. This includes screen and various raster image formats. The image produced by this drawer is used as a reference when developing and debugging other back-ends.
568+
569+### TFPCanvas drawer
570+
571+`TFPCanvasDrawer` is similar to TCanvas drawer, but based on `TFPCanvas`, which is `TCanvas` implemented in FCL instead of LCL.
572+
573+See "nogui" demo for an example.
574+
575+Although `TFPCanvas` and, correspondingly, `TFPCanvasDrawer` have limited implementation of some TAChart features, their important advantage is possibility of compiling the application with nogui widgetset. So it can be used in Web applications to generate raster chart images without the need for X/Gtk/Qt in server.
576+
577+### SVG drawer
578+
579+`TSVGDrawer` produces text stream with the image of the chart in [SVG](https://en.wikipedia.org/wiki/SVG) format. Similarly to TFPCanvas drawer, it is independent of LCL and can be used in Web applications to generate vector charts in nogui widgetset.
580+
581+See "svg" demo for an example.
582+
583+For this drawer, image unit is an SVG canvas unit instead of a pixel.
584+
585+Note that due to the nature of SVG, there is no way to measure font dimensions, so they are approximated crudely. This may result in problems like label text not fitting in the mark rectangle, especially in browsers like Firefox that do not support `textLength` attribute.
586+
587+### OpenGL drawer
588+
589+`TOpenGLDrawer` draws chart on the current [OpenGL](https://en.wikipedia.org/wiki/OpenGL) context. It is suitable be used in games and other OpenGL-only applications.
590+
591+OpenGL drawer expects, but does not set by itself, orthogonal projection. See "opengl" demo for an example.
592+
593+Note that, like in OpenGL itself, `TOpenGLDrawer` font support is extremely limited.
594+
595+### Printer drawer
596+
597+`TPrinterDrawer` draws chart on the printer canvas. It does not flush the page.
598+
599+Although printer canvas is a descendant of `TCanvas`, and so printing can be done using the default drawer, `TPrinterDrawer` does proper re-scaling of image coordinates according to printer vs screen DPI.
600+
601+You can use this drawer to export chart to PDF format using one of the available PDF writer products.
602+
603+See "print" demo for an example.
604+
605+Note that this drawer is located in a separate TAChartPrint package.
606+
607+### AggPas drawer
608+
609+`TAggPasDrawer` draws chart using [AggPas library](http://www.crossgl.com/aggpas).
610+
611+AggPas offers high-speed antialiased drawing and is included in Lazarus sources. Unfortunately, the library is currently not maintained and there are some limitations in TAChart support.
612+
613+Note that this drawer is located in a separate TAChartAggPas package.
614+
615+### BGRABitmap drawer
616+
617+`TBGRADrawer` draws chart using [[BGRABitmap]] library.
618+
619+BGRABitmap is recently created and actively developed graphics library, offering, in particular, anti-aliasing and rich selection of gradients.
620+
621+Currently BGRABitmap supports all TAChart features, but is somewhat slower then other drawing methods.
622+
623+Note that this drawer is located in a separate TAChartBGRA package, which depends on external `bgrabitmappack` package.
624+
625+### FPVectorial drawer
626+
627+`TFPVectorialDrawer` draws chart using [[fpvectorial]] library. FPVectorial offers exporting to various vector formats, including SVG, PDF, CorelDraw and even instructions for metal cutting machines.
628+
629+It currently has some limitations in TAChart support, but is actively developed.
630+
631+Note that this drawer is located in a separate `TAChartFPVectorial` package, which depends on external `fpvectorialpkg` package.
632+
633+### WMF drawer
634+
635+`TWindowsMetafileDrawer` draws chart into a [Windows Metafile](https://en.wikipedia.org/wiki/Windows_Metafile).
636+
637+It uses WinAPI directly, and so will only work on Windows. In the future, WMF support may be added to fpvectorial, which will provide cross-platform alternative to this package.
638+
639+## Navigation
640+
641+Chart *navigation* consists of two parts: moving logical extent around without changing zoom factor, and visualizing the logical extent's position and size relative to the full extent.
642+
643+Moving extent (but not visualizing it) is possible by using panning tools.
644+
645+You can see examples in the "navigation" demo.
646+
647+### Scroll bars
648+
649+`TChartNavScrollBar` is a `TCustomScrollBar` descendant with additional `Chart` property referencing the chart. `TChartNavScrollBar` synchronizes its position with chart extent in both directions. If the logical extent is equal to or larger then full extent, navigation scroll bar does nothing.
650+
651+Setting `AutoPageSize = true` lets `TChartNavScrollBar` to pick page size proportional to the logical extent.
652+
653+Note that `Min` and `Max` properties are *not* changed automatically. It is recommended to set `Min = 0` and `Max` to some fairly large integer value to avoid rounding issues.
654+
655+Also note that `TChartNavScrollBar` does not automatically align or attach itself to a chart, so it can be arbitrarily positioned on the form.
656+
657+### Navigation panel
658+
659+`TChartNavPanel` component displays logical and full extent of an assigned chart as differently colored rectangles, allowing user to drag the logical extent rectangle if `AllowDragNavigation = true`.
660+
661+If `MiniMap = true`, the panel additionally displays the chart series.
662+
663+`TChartNavPanel` can have arbitrary size, but it is recommended to keep height to width proportion the same as in the assigned chart. Setting `Proportional = true` will enforce the same proportions even if the above condition is not met, at the cost of some wasted space on the panel.
664+
665+## Technical details
666+
667+### Drawing order
668+
669+Chart drawing consists of three stages:
670+
671+1. *Preparation*. At this stage various internal data structures are initialized.
672+2. *Measurement*. At this stage chart calculates the sizes of all elements, and optimizes them for best presentation. Optimization may require several iterations, so measurement stage is often the heaviest one both in terms of implementation complexity and running time.
673+3. *Drawing*. At this stage actual chart image is displayed.
674+
675+There also exists an ordering among various chart elements:
676+
677+1. Background (using `TChart.Color` property).
678+2. Back-wall (using `TChart.BackColor` property).
679+3. Series and axises according to `ZPosition` property.
680+ 1. For each series and axis, graphic elements are drawn before marks. Note that this protects marks against hiding by the axis/series they belong to, but not by other axises/series.
681+4. Legend.
682+5. Tools.
683+
684+Note that `ZPosition` works for both 2-D and 3-D charts, so you can overlay series and axises in arbitrary order.
685+
686+### Coding style
687+
688+Historically FPC, Lazarus and LCL sources contain a mix of coding styles, with the general rule being "be consistent with the surrounding code".
689+
690+However, since TAChart was much fewer contributors, it is feasible to adopt and maintain a consistent style across all TAChart code. If you want to contribute to TAChart, please format your code accordingly. Also remember that any coding style may be violated in certain situations when the reason if good enough, but please explain that reason if you do so.
691+
692+#### Spaces
693+
694+- No double spaces anywhere.
695+- Spaces after: operations, comma, semicolon, assignment, closing parenthesis in expressions (not in function call).
696+- Spaces before: operations, assignment, opening parenthesis in expressions (not in function call).
697+
698+#### Lines
699+
700+- No double empty lines anywhere.
701+- Empty lines between procedures, classes, unit sections. Rare empty lines inside procedure bodies to separate logical blocks.
702+- Line length below 80 characters, with rare exceptions.
703+- Single statement per line, except *if* ... *then* {*exit*\|*break*\|*continue*} and some rare cases of mass assignment.
704+- If the line is too long, line breaks may be inserted after at the following symbols, in the order of decreasing priority: keywords, opening parenthesis, opening square bracket, semicolon, comma, operation.
705+
706+#### Indentation and blocks
707+
708+- Always two spaces, both for blocks and continuation lines.
709+- *begin* on the same line as the control statement, *end* aligned with the control statement.
710+- Use *begin*/*end* only when necessary (i. e. not for single statements).
711+
712+#### Comments
713+
714+- License header at the beginning of every file.
715+- Single-line comments everywhere except the license header.
716+- Only full sentences in comments, starting with capital letter and ending with the full stop.
717+- Comments before commented code, except rare cases where comment fits in the end of the same line.
718+- Comments should only include information not evident from the source. In particular, prefer meaningful procedure and argument names to comments describing their usage.
719+
720+#### Names
721+
722+- Constants use ALL_CAPS_WITH_UNDERSCORE, everything else use CamelCase.
723+- Local variables start from lower-case letter, everything else starts from upper-case letter, even when FPC library disagrees (e.g. \`\`Math\`\`, not \`\`math\`\`).
724+- Class fields start with 'F', arguments start with 'A', types start with 'T', TAChart units start with 'TA'.
725+
726+#### Classes and methods
727+
728+- Methods are grouped per-class, methods inside class are sorted alphabetically both in interface and implementation. There should be zero Code Observer warnings about 'Unsorted members'.
729+- If there is a need to group methods by topic, use visibility specifiers as topic separators. In particular, group overridden methods separately from the newly introduced ones.
730+- Use *strict private*/*strict protected visibility* where possible.
731+
732+#### Hints and warnings
733+
734+- Code should compile with zero hints and warnings.
735+- Silence "unused parameter" warning with the \`\`Unused\`\` procedure from TAChartUtils unit.
736+
737+#### Control flow
738+
739+- Use *exit* or *raise* to abort method execution in case of violated pre-condition.
740+- Use enumerators where possible.
741+- Use *with* carefully, only where is significantly saves code size and in minimal range possible.
742+- Limit the procedure size to 50-60 lines, use nested procedures liberally.
743+
744+---
745+*From the Free Pascal wiki, page "TAChart documentation/uk", as it stood on 2023-02-23 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
746+Category: Pages for deletion

Back to history