Sign in Join
Wiki copytemporary

TAChart documentation/uk: what changed

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

OldNewLine
11## Огляд
22
33[[TAChart]] є компонентою для малювання графіків, кругових та інших діаграм. Він сумісний, але не повністю, з можливостями компоненти TeeChart в Delphi. Однією з основних відмінностей є те, що деякі можливості (напр. джерела даних і перетворення осей) реалізовані окремими компонентами, а не властивостями. Це дає більшу гнучкість і кращі можливості повторного використання коду, ціною за це є деяка складність API.
44
55## Серії (послідовності даних)
66
77Серії є центральною частиною TAChart. Більшість серій відображають дані, взяті з джерел, графічним способом, напр. лініями чи стовпчиками.
88
99### Серія - фіксована лінія
1010
1111Це найпростіший тип серій, представлений фіксовано вертикальною чи горизонтальною лінією. Лінія може використовуватися як центральна вісь у графіках функцій або як перетягувана мітка.
1212
1313Також, задавши `Active`=true, `Pen.Style=psClear`, `UseBounds=true` і відповідну `AxisIndexX`, вона стає "розширенням осі", чим гаранту, що задана `Position` завжди буде включена в інтервал осі.
1414
1515### Основні серії
1616
1717Основні серії використовуються найчастіше, вони включають line, bar і area. All basic series can be "stacked" by using multi-valued source. Також усі основні серії повністю підтримують обертання і 3-D відображення.
1818
1919#### Line series
2020
2121`TLineSeries` can be used to draw a given set of points, optionally marking them with shapes and connecting with lines.
2222
2323You can get a "stepped" look by setting `LineType` property to `ltStepXY` or `ltStepYX`.
2424
2525##### Fast lines
2626
2727Some 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:
2828
2929- There are no marks.
3030- There are no pointers.
3131- `LineType` is not `ltFromOrigin`.
3232
3333Some operating systems/widgetsets may additionally require that `LinePen.Style=psSolid` and `LinePen.Width=1`.
3434
3535Additional speedups will be available if `Source.Sorted=true`.
3636
3737You can measure line speed drawing on your platform with the "line" demo.
3838
3939#### Bar series
4040
4141`TBarSeries` represents data as a set or bars, extending from `ZeroLevel` to data points.
4242
4343You 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`.
4444
4545You can draw multiple bar series side-by-side by using `BarOffsetPercent` property.
4646
4747#### Area series
4848
4949`TAreaSeries` represents data as a polygon extending from the data points to either `ZeroLevel` line or infinitely down (if `UseZeroLevel=false`).
5050
5151You can get a "stepped" look by setting `ConnectType` property.
5252
5353### Multi-value series
5454
5555Multi-value series require multi-valued data source, and use additional Y values as extra parameters to draw complex shapes.
5656
5757#### Bubble series
5858
5959`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.
6060
6161#### Box-and-whiskers series
6262
6363`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.
6464
6565With 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).
6666
6767This series requires source with `YCount` of at least 5, and uses Y values as follows:
6868
6969| Index | Usage |
7070|-------|-----------------|
7171| 0 | Lower whisker |
7272| 1 | Lower box bound |
7373| 2 | Medium line |
7474| 3 | Upper box bound |
7575| 4 | Upper whisker |
7676| | |
7777
7878#### Open-high-low-close series
7979
8080`TOpenHighLowCloseSeries` represent data as a vertical lines with two ticks, as described [here](https://en.wikipedia.org/wiki/Open-high-low-close_chart).
8181
8282It usually requires `YCount` of at least 4, and uses Y values as follows:
8383
8484| Property | Default | Usage |
8585|-------------|---------|----------------------------|
8686| YIndexLow | 0 | Lower point of line |
8787| YIndexOpen | 1 | Left-facing tick position |
8888| YIndexClose | 2 | Right-facing tick position |
8989| YIndexHigh | 3 | Upper point of line |
9090| | | |
9191
9292Note 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.
9393
9494### Radial series
9595
9696Radial series ignore axis transformations. You can see examples of radial series in the "radial" demo.
9797
9898#### Pie series
9999
100100`TPieSeries` draws pie charts.
101101
102102For 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.
103103
104104Pie 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.
105105
106106There are several options for label positioning, controlled by `MarkPositions` property:
107107
108108- `pmpAround` -- marks are drawn outside the pie, on the continuation or radius vector for each slice
109109- `pmpInside` -- marks are drawn inside each slice
110110- `pmpLeftRight` -- marks are drawn directly to the left or to the right of slice
111111
112112If `RotateLabels` is true, each label is additionally rotated so that (if `LabelFont.Orientation=0`) it is parallel to the radius vector of its slice.
113113
114114If 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.
115115
116116#### Polar series
117117
118118`TPolarSeries` represents data as points in [polar coordinates](https://en.wikipedia.org/wiki/Polar_coordinate_system).
119119
120120The origin of the polar coordinate system is defined in graph coordinates by `OriginX` and `OriginY` properties.
121121
122122For each data point, X value is interpreted as an angle in radians and Y value -- as a distance from the center.
123123
124124### User-drawn series
125125
126126Provides `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.
127127
128128### Functional series
129129
130130Functional 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.
131131
132132You can see examples of functional series in "func" demo.
133133
134134#### Function series
135135
136136`TFuncSeries` represents a one-dimensional function defined by `OnCalculate` event as a line.
137137
138138The function is calculated for each `Step` pixels of the image, so you can use this property to increase "smoothness" or drawing speed.
139139
140140`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.
141141
142142#### B-spline series
143143
144144`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).
145145
146146Spline segments shorter then `Step` pixels are represented by straight lines.
147147
148148#### Cubic spline series
149149
150150`TCubicSplineSeries` draws [cubic spline](https://en.wikipedia.org/wiki/Spline_interpolation) using standard Numlib package from the FPC.
151151
152152The spline function is calculated for each `Step` pixels of the image, so you can use this property to increase "smoothness" or drawing speed.
153153
154154Data source must contain at least 4 points and have strictly increasing X coordinate.
155155
156156If there are too few points, and `csoDrawFewPoints` option is set, line will be drawn instead of spline using `BadDataPen`.
157157
158158If X values are unordered and `csoDrawUnorderedX` option is set, spline will be drawn ignoring offending points using `BadDataPen`.
159159
160160`csoExtrapolateLeft` and `csoExtrapolateRight` options enable natural extrapolation to the left and to the right correspondingly.
161161
162162#### Color map series
163163
164164`TColorMapSeries` represent 2-dimensional function defined by `OnCalculate` event as a field of pixels, with color depending on function value.
165165
166166The field is drawn as a set of rectangles of size `StepX` by `StepY` pixels. The function is called once for each rectangle.
167167
168168Color 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.
169169
170170When `Legend.Multiplicity=lmPoint`, color map series will display color levels in the legend.
171171
172172## Sources
173173
174174Data can get into a chart from various sources. They are implemented as a set of components derived from `TCustomChartSource`.
175175
176176To 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.
177177
178178Each data item has the following fields: X, Y, YList, Color, Text.
179179
180180### Sorted sources
181181
182182If 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.
183183
184184### Multi-valued sources
185185
186186Sources 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]`.
187187
188188Additional values may be used by various series -- for example, stacked bars or bubble charts.
189189
190190### Skipping source items
191191
192192It 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.
193193
194194To 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.
195195
196196Also note that if you set only one coordinate to NaN, the other will still take part in extent calculation.
197197
198198You can see examples of skipping items in the "nan" demo.
199199
200200### List source
201201
202202`TListChartSource` is a basic chart source, storing chart data inside itself. As such, you can use `Add` and `Delete` functions to change source data.
203203
204204The 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.
205205
206206You 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.
207207
208208### Random source
209209
210210`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.
211211
212212Each random source uses its own independent random number generator to guarantee stability of its values.
213213
214214### User-defined source
215215
216216This 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.
217217
218218You can of course also generate, filter or modify data with the user-defined source.
219219
220220Note that if the `Sorted` property is set to true, it is the responsibility of the event handler to provide actually sorted data.
221221
222222### Database source
223223
224224`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.
225225
226226The following properties contain database field names for data item fields:
227227
228228| Property | Access method |
229229|--------------|---------------|
230230| `FieldX` | AsFloat |
231231| `FieldY` | AsFloat |
232232| `FieldColor` | AsInteger |
233233| `FieldText` | AsString |
234234| | |
235235
236236If `FieldX` property is empty, RecNo is used instead.
237237
238238To 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.
239239
240240### Calculated source
241241
242242`TCalculatedChartSource` is the source used for manipulating data taken from the `Origin` source. This source performs transformations in the following order:
243243
244244- 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.
245245- Accumulation -- replaces each item's Y values by a function of the neighboring values.
246246- 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.
247247
248248Accumulation is controlled by several properties:
249249
250250`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.
251251
252252Note that the actual number of items may be lower for the points near the beginning or end of the source.
253253
254254`AccumulationDirection`:
255255
256256- cadBackward -- use previous values from the source,
257257- cadForward -- use next values from the source,
258258- cadCenter -- use both previous and next values for a total number of up to `2 * AccumulationRange - 1`.
259259
260260`AccumulationMethod`:
261261
262262- camNone -- skip accumulation step,
263263- camSum -- sum of the last `AccumulationRange` items,
264264- camAverage -- average the last `AccumulationRange` items,
265265- 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.
266266- camSmoothDerivative -- smoothed finite differences derivative, more robust against random measurement errors in the data.
267267
268268### Interval source
269269
270270`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.
271271
272272### Date-time interval source
273273
274274`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.
275275
276276Note 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.
277277
278278If 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.
279279
280280### Source optimization notes
281281
282282Primary 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.
283283
284284A 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.
285285
286286Also 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.
287287
288288## Coordinates and axises
289289
290290TAChart uses three coordinate systems:
291291
292292- *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.
293293- *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.
294294- *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.
295295
296296You 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.
297297
298298Visually, axis consists of the axis line (drawn by `AxisPen`), grid lines (drawn by `GridPen`), ticks, marks and arrow.
299299
300300Each 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.
301301
302302### Axis transformations
303303
304304Axis 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).
305305
306306For transformations to have an effect, you should:
307307
308308- Make sure `Enabled` property is true for all transformations.
309309- Assign transformations component to `Transformations` property of at least one axis.
310310- Assign `AxisIndexX` and/or `AxisIndexY` properties of the series to the appropriate axis index.
311311
312312Note 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.
313313
314314#### Linear and logarithmic transformation
315315
316316Those are simple arithmetic transformations.
317317
318318#### Auto-scaling transformation
319319
320320To 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".
321321
322322By 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).
323323
324324#### User-defined transformation
325325
326326You 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:
327327
328328- `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).
329329- Functions should be monotonic.
330330
331331### Date and time axises
332332
333333Using date/time values for axis marks is a common requirement. Proper way to do this depends on the exact nature of date/time data:
334334
335335- 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.
336336- 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`.
337337- If the data is in calendar units, such as months and years, which is common for financial data, you have several options:
338338 - 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.
339339 - 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.
340340 - Convert coordinates to `TDateTime values` beforehand, then use `TDateTimeIntervalChartSource` as described above.
341341
342342### Axis intervals
343343
344344Axis 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:
345345
346346- `Options` property contains a set of flags controlling usage of other parameters. If the flag is not in the set, corresponding parameter is ignored.
347347- `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.
348348- 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`.
349349- `MinLength` and `MaxLength` properties set the limits of interval length *in image units* (usually pixels).
350350- `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.
351351
352352Note 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.
353353
354354## Extents and margins
355355
356356### Extents
357357
358358Chart *extent* is a rectangle in graph coordinates.
359359
360360There are several extents defined by TChart:
361361
362362- *Full extent* -- usually determined automatically as the area encompassing all the data from series and axis ranges. Returned by `GetFullExtent` function.
363363- *Fixed extent* -- determined by `TChart.Extent` property. May override full extent calculation partially or fully.
364364- `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.
365365- `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.
366366
367367### Linked extents
368368
369369Using `TChartExtentLink` component, you can ensure that logical extents of several charts enumerated by `LinkedCharts` property always stay the same.
370370
371371This is useful for simulating multi-pane chart layout. See "panes" demo for an example.
372372
373373### Margins
374374
375375*Margin* is a distance reserved around the edges of rectangular region. Margins are measured in image units (usually pixels). Chart itself have two margins:
376376
377377- Internal (`Margins` property) -- applied after the axises drawing. Are also influenced by series marks and series themselves.
378378- External (`MarginsExternal` property) -- applied before the axises drawing. Are also influenced by axis marks and arrows.
379379
380380Other chart elements, such as legend, title, footer and labels, also have margins.
381381
382382### Optimization notes
383383
384384Calculation 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.
385385
386386## Tools
387387
388388Chart 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.
389389
390390Tools are grouped in `TChartToolset` component, which should be assigned to chart's `Toolset` property. Same toolset can be used in several charts.
391391
392392If `Toolset` is unassigned, for compatibility reasons built-in toolset consisting of drag zoom and reticule tools is used.
393393
394394Each user action, tools in the toolset are processed in order, and for each tool:
395395
396396- If `Enabled=false`, the tool is ignored.
397397- If `Shift` is not equal to the current shift state, the tool is ignored.
398398- Tools is asked to process the action.
399399- If the tool signaled that the action is handles, processing is stopped, otherwise it continues to the next tool.
400400
401401In 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.
402402
403403### Drawing mode
404404
405405Some tools, such as drag zoom or crosshair, display moving shapes over the chart with the mouse movement.
406406
407407There 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.
408408
409409Display method is controlled by `DrawingMode` property with the following values:
410410
411411- `tdmXor` -- use XOR method;
412412- `tdmNormal` -- use full chart redraw;
413413- `tdmDefault` -- use XOR method on widgetsets where it is known to work (Windows and Gtk) and full redraw on others.
414414
415415### Extent tools
416416
417417Extent tools modify chart's logical extent.
418418
419419Zooming tools can be animated by setting `AnimationSteps` to the value greater then 1 and `AnimationInterval` (in milliseconds).
420420
421421Panning tools can be restricted to the chart extent on all or some directions by using `LimitToExtent` property.
422422
423423#### Zoom drag tool
424424
425425`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.
426426
427427`RatioLimit` property lets you restrict zooming to one of the coordinates, or require it to keep original proportions.
428428
429429#### Zoom click tool
430430
431431`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.
432432
433433If `FixedPoint` is true, the location of the mouse click is used as a fixed point for zooming, otherwise chart image center is used instead.
434434
435435#### Zoom mouse-wheel tool
436436
437437`TZoomMouseWheelTool` allows user to zoom in and out with the mouse wheel. Its properties are identical to the zoom click tool.
438438
439439Chart is scaled by `ZoomFactor` when the used scrolls mouse wheel up, and by `1 / ZoomFactor` when the user scrolls the mouse wheel down.
440440
441441#### Pan drag tool
442442
443443`TPanDragTool` allows user to move logical extent by dragging mouse in the directions indicated by `Directions` property.
444444
445445#### Pan click tool
446446
447447`TPanClickTool` allows user to move logical extent by clicking inside `Margins` pixels from the corresponding border of chart image.
448448
449449The 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.
450450
451451### Data tools
452452
453453Data 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.
454454
455455When the data tool is activated, it determines the nearest point of the affected series which is located inside of the `GrabRadius` (in pixels).
456456
457457#### Data point drag tool
458458
459459`TDataPointDragTool` allows user to change data values by dragging the data point. Note that this requires series' data source to be a list source.
460460
461461#### Data point click tool
462462
463463`TDataPointClickTool` allows you to assign `OnPointClick` event handler, which will be called when the user clicks on the data point.
464464
465465#### Data point hint tool
466466
467467`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.
468468
469469#### Data point crosshair tool
470470
471471`TDataPointCrosshairTool` displays a cross-hair centered on the data point.
472472
473473#### Reticule tool
474474
475475Reticule tool is deprecated. Use TDataPointCrosshairTool instead.
476476
477477### User defined tool
478478
479479To 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.
480480
481481## Decorative elements
482482
483483### Title and footer
484484
485485Chart title and footer are multi-line texts appearing above and below the chart correspondingly. They support various rotations and alignments.
486486
487487### Legend
488488
489489Chart legend is a table with each item containing an icon and a text line.
490490
491491Legend 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.
492492
493493Legend 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.
494494
495495Legend 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.
496496
497497Legend items are sorted as following:
498498
499499- By group index, items without group (`GroupIndex=-1` going first to avoid confusion with the last group).
500500- By `Order` property, items without explicit order (`Order=-1`) going last.
501501- By creation order of series.
502502- For multiple items per series, by generation order (for standard series it is the order of points).
503503
504504#### User-defined legend items
505505
506506Arbitrary legend items can be generated by overriding `OnCreate` and `OnDraw` events of series `Legend` property.
507507
508508Note 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.
509509
510510### Arrows
511511
512512Arrowheads can be drawn at the end of axis lines, controlled by `TChartAxis.Arrow` property.
513513
514514## Marks
515515
516516Marks 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.
517517
518518You can see examples in the "labels" demo.
519519
520520### Mark labels
521521
522522The 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:
523523
5245240\. Y
525525
5265261\. Y as a percentage of the Y total
527527
5285282\. Text
529529
5305303\. Y total
531531
5325324\. X
533533
534534Where "Y total" is the sum of all Y values for this source. Note that not all sources supply all the items above.
535535
536536Some pre-defined formats can be set via the `Style` property.
537537
538538If 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.
539539
540540The text or rendered using the `LabelFont`. Note in particular that TAChart supports arbitrary font `Orientation`.
541541
542542#### Multi-line marks
543543
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.
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 Alignment property.
545545
546546### Mark positions and attachment
547547
548548Mark position relative to the marked point is determined by the marks owner (series or axis).
549549
550550Common 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.
551551
552552Additionally, basic chart series have `MarkPositions` property, specifying the direction of labels' offsets relative to series data points as following:
553553
554554- lmpOutside -- away from zero level
555555- lmpPositive -- positive direction of series' Y axis
556556- lmpNegative -- negative direction of series' Y axis
557557- lmpInside -- towards zero level
558558
559559## Drawers
560560
561561For 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.
562562
563563These classes are called *drawing back-ends* or *drawers* for short.
564564
565565### TCanvas drawer
566566
567567`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.
568568
569569### TFPCanvas drawer
570570
571571`TFPCanvasDrawer` is similar to TCanvas drawer, but based on `TFPCanvas`, which is `TCanvas` implemented in FCL instead of LCL.
572572
573573See "nogui" demo for an example.
574574
575575Although `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.
576576
577577### SVG drawer
578578
579579`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.
580580
581581See "svg" demo for an example.
582582
583583For this drawer, image unit is an SVG canvas unit instead of a pixel.
584584
585585Note 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.
586586
587587### OpenGL drawer
588588
589589`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.
590590
591591OpenGL drawer expects, but does not set by itself, orthogonal projection. See "opengl" demo for an example.
592592
593593Note that, like in OpenGL itself, `TOpenGLDrawer` font support is extremely limited.
594594
595595### Printer drawer
596596
597597`TPrinterDrawer` draws chart on the printer canvas. It does not flush the page.
598598
599599Although 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.
600600
601601You can use this drawer to export chart to PDF format using one of the available PDF writer products.
602602
603603See "print" demo for an example.
604604
605605Note that this drawer is located in a separate TAChartPrint package.
606606
607607### AggPas drawer
608608
609609`TAggPasDrawer` draws chart using [AggPas library](http://www.crossgl.com/aggpas).
610610
611611AggPas 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.
612612
613613Note that this drawer is located in a separate TAChartAggPas package.
614614
615615### BGRABitmap drawer
616616
617617`TBGRADrawer` draws chart using [[BGRABitmap]] library.
618618
619619BGRABitmap is recently created and actively developed graphics library, offering, in particular, anti-aliasing and rich selection of gradients.
620620
621621Currently BGRABitmap supports all TAChart features, but is somewhat slower then other drawing methods.
622622
623623Note that this drawer is located in a separate TAChartBGRA package, which depends on external `bgrabitmappack` package.
624624
625625### FPVectorial drawer
626626
627627`TFPVectorialDrawer` draws chart using [[fpvectorial]] library. FPVectorial offers exporting to various vector formats, including SVG, PDF, CorelDraw and even instructions for metal cutting machines.
628628
629629It currently has some limitations in TAChart support, but is actively developed.
630630
631631Note that this drawer is located in a separate `TAChartFPVectorial` package, which depends on external `fpvectorialpkg` package.
632632
633633### WMF drawer
634634
635635`TWindowsMetafileDrawer` draws chart into a [Windows Metafile](https://en.wikipedia.org/wiki/Windows_Metafile).
636636
637637It 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.
638638
639639## Navigation
640640
641641Chart *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.
642642
643643Moving extent (but not visualizing it) is possible by using panning tools.
644644
645645You can see examples in the "navigation" demo.
646646
647647### Scroll bars
648648
649649`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.
650650
651651Setting `AutoPageSize = true` lets `TChartNavScrollBar` to pick page size proportional to the logical extent.
652652
653653Note 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.
654654
655655Also note that `TChartNavScrollBar` does not automatically align or attach itself to a chart, so it can be arbitrarily positioned on the form.
656656
657657### Navigation panel
658658
659659`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`.
660660
661661If `MiniMap = true`, the panel additionally displays the chart series.
662662
663663`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.
664664
665665## Technical details
666666
667667### Drawing order
668668
669669Chart drawing consists of three stages:
670670
6716711. *Preparation*. At this stage various internal data structures are initialized.
6726722. *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.
6736733. *Drawing*. At this stage actual chart image is displayed.
674674
675675There also exists an ordering among various chart elements:
676676
6776771. Background (using `TChart.Color` property).
6786782. Back-wall (using `TChart.BackColor` property).
6796793. Series and axises according to `ZPosition` property.
680680 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.
6816814. Legend.
6826825. Tools.
683683
684684Note that `ZPosition` works for both 2-D and 3-D charts, so you can overlay series and axises in arbitrary order.
685685
686686### Coding style
687687
688688Historically FPC, Lazarus and LCL sources contain a mix of coding styles, with the general rule being "be consistent with the surrounding code".
689689
690690However, 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.
691691
692692#### Spaces
693693
694694- No double spaces anywhere.
695695- Spaces after: operations, comma, semicolon, assignment, closing parenthesis in expressions (not in function call).
696696- Spaces before: operations, assignment, opening parenthesis in expressions (not in function call).
697697
698698#### Lines
699699
700700- No double empty lines anywhere.
701701- Empty lines between procedures, classes, unit sections. Rare empty lines inside procedure bodies to separate logical blocks.
702702- Line length below 80 characters, with rare exceptions.
703703- Single statement per line, except *if* ... *then* {*exit*\|*break*\|*continue*} and some rare cases of mass assignment.
704704- 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.
705705
706706#### Indentation and blocks
707707
708708- Always two spaces, both for blocks and continuation lines.
709709- *begin* on the same line as the control statement, *end* aligned with the control statement.
710710- Use *begin*/*end* only when necessary (i. e. not for single statements).
711711
712712#### Comments
713713
714714- License header at the beginning of every file.
715715- Single-line comments everywhere except the license header.
716716- Only full sentences in comments, starting with capital letter and ending with the full stop.
717717- Comments before commented code, except rare cases where comment fits in the end of the same line.
718718- Comments should only include information not evident from the source. In particular, prefer meaningful procedure and argument names to comments describing their usage.
719719
720720#### Names
721721
722722- Constants use ALL_CAPS_WITH_UNDERSCORE, everything else use CamelCase.
723723- Local variables start from lower-case letter, everything else starts from upper-case letter, even when FPC library disagrees (e.g. \`\`Math\`\`, not \`\`math\`\`).
724724- Class fields start with 'F', arguments start with 'A', types start with 'T', TAChart units start with 'TA'.
725725
726726#### Classes and methods
727727
728728- 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'.
729729- 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.
730730- Use *strict private*/*strict protected visibility* where possible.
731731
732732#### Hints and warnings
733733
734734- Code should compile with zero hints and warnings.
735735- Silence "unused parameter" warning with the \`\`Unused\`\` procedure from TAChartUtils unit.
736736
737737#### Control flow
738738
739739- Use *exit* or *raise* to abort method execution in case of violated pre-condition.
740740- Use enumerators where possible.
741741- Use *with* carefully, only where is significantly saves code size and in minimal range possible.
742742- Limit the procedure size to 50-60 lines, use nested procedures liberally.
743743
744744---
745745*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).*
746746Category: Pages for deletion

Back to history