Sign in Join
Wiki copytemporary

TAChart Tutorial: Chart Tools: what changed

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

OldNewLine
11## Introduction
22
33![](/wiki-images/c/c6/ZoomPan06.png)
44
55Charts are powerful tools to display relationships between data. They get even more powerful if the user can interact with them, for example:
66
77- by **zooming** into a crowded series to display more details,
88- by **panning** the visible viewport to other regions,
99- by **displaying data values** from the series or measuring characteristic parameters of the plot.
1010
1111The [[TAChart]] package is equipped with a powerful collection of tools to help creating interactive charts. In this tutorial, we want to show how to apply these tools to create interactive charts.
1212
1313If you are not familiar with TAChart we recommend that you have a look at the [[TAChart Tutorial: Getting started|Getting started tutorial]]. Of course, you must have some experience with Lazarus and FPC.
1414
1515## Preparation
1616
1717We need a chart to play with. Instead of creating a new chart let's reuse the simple chart of the [[TAChart Tutorial: Getting started|Getting started tutorial]]. In this project we had created a chart of some mathematical functions for x between -10 and 10. The functions were drawn by means of `TLineSeries` storing their data in the built-in list source. Copy the project files (`project1.lpi, project1.lpr, unit1.pas, unit1.lfm`) into a separate folder for the new tutorial.
1818
1919![](/wiki-images/2/2f/Tachart_getting_started_step6.png)
2020
2121## Zooming and Panning - the easy way
2222
2323### Zooming
2424
2525Zooming is very easy -- you don't have to do anything to implement it since it is built into the heart of the chart component. You just have to drag a rectangle with the **left** mouse button down around the feature of interest that you want to see in detail. Keep in mind that you have to drag the mouse from the top-left to the right-bottom corner of the rectangle to get the zoom effect. After you release the mouse button, the region is blown up to fill the entire chart. Easy.
2626
2727![](/wiki-images/3/34/ZoomPan01.png) ![](/wiki-images/f/f8/ZoomPan02.png)
2828
2929You can repeat this procedure to zoom into the chart deeper and deeper.
3030
3131If you want to restore the original viewport just click into the chart with the left button, or left-drag a rectangle in any direction, except of course from top-left to right-bottom -- this would zoom in even further.
3232
3333Maybe, for some reason, you do not like this behavior. `TChart` has a property `AllowZoom` with which you can turn off the zooming capability. Beyond that, there is nothing else to control the default zooming action. But don't give up: a bit further down we will discuss chart tools, and they give you almost unlimited access to any interactive feature.
3434
3535### Panning
3636
3737After you have zoomed into a chart you may want to shift the viewport a bit to find a better view. This operation is called "panning". For the built-in panning operation you hold down the **right** mouse button and drag the viewport into the desired direction. More panning options are available by means of the Chart Tools.
3838
3939![](/wiki-images/8/8b/ZoomPan03.png)
4040
4141As with zooming you can restore the original viewport by clicking into the chart, or by dragging a rectangle in any direction, except from top-left to bottom-right. Note that you use the left mouse button for "un-panning" although you had used the right button for panning.
4242
4343Since Lazarus v2.1+, TChart has a property `AllowPanning` to disable panning. As we will see shortly, panning can be turned off also with the chart tools, so there is no real disadvantage for older versions.
4444
4545## Fundamentals on chart tools
4646
4747### What are chart tools?
4848
4949As you have seen, to add zooming and panning capabilities to your program can't be easier -- there's nothing to do, they are already there. But on the other hand, usage of the built-in routines is quite limited: zooming is only possible by using the left mouse button, panning by using the right mouse button; no mouse-wheel support; no vertical-only or horizontal-only zooming; no reading of data values, etc.
5050
5151For more versatile user interaction a set of [[TAChart documentation|chart tools]] has been added to TAChart. Each tool is specialized to some specific action. From the user point of view, there are two types of tools: [[TAChart documentation|Extent tools]] and [[TAChart documentation|data tools]].
5252
5353- [[TAChart documentation|Extent tools]] modifiy the **extent** of the chart -- this is the visible viewport -- i.e. they are responsible for zooming and panning. For zooming, you can select from [[TAChart documentation|TZoomDragTool]], [[TAChart documentation|TZoomClickTool]], or [[TAChart documentation|TZoomMouseWheelTool]]; for panning, you can use [[TAChart documentation|TPanDragTool]], [[TAChart documentation|TPanClickTool]], or [[TAChart documentation|TPanMouseWheelTool]]. Note that there are no dedicated tools for unzooming or "un-panning", this feature is built into the tools used for zooming.
5454- [[TAChart documentation|Data tools]] give interactive access to data displayed in the series, or even allow to modify the data: you will find [[TAChart documentation|TDataPointClickTool]], [[TAChart documentation|TDataPointDragTool]], [[TAChart documentation|TDataPointHintTool]], [[TAChart documentation|TDataPointCrosshairTool]], or [[TAChart documentation|TDataPointDistanceTool]].
5555- If nothing else fits your needs, [[TAChart documentation|TUserDefinedTool]] allows to build your own tool according to your specific requirements.
5656
5757### Properties of chart tools
5858
5959All these tools have a property called **`Shift`** containing a set of shift states that activate the tool (see the standard LCL enumeration `TShiftState`).
6060
6161An example: If the tool's `Shift` contains `ssCtrl` and `ssLeft`, then the tool becomes active when the user presses the `Ctrl` key *and* left mouse button. Note that all conditions must be met, the tool does not activate if the left mouse button is pressed alone. Each tool must have its own set of unique `Shift` combinations.
6262
6363A note on the keyboard states: In order to receive messages on keyboard events the chart must have the focus. If tools do not work properly try to call `Chart.SetFocus`. There is also a property `AutoFocus` which automatically focuses the chart when the user moves the mouse into the chart. The disadvantage of `AutoFocus` should not be left unmentioned: if you type some text into a memo, move the mouse over the chart and want to continue typing you will notice that the memo has lost the focus, and the keystrokes typed will be ignored...
6464
6565There is another condition that must be met for the tool to become active: Its property **`Enabled`** must be set to `true`, but this is the default setting. This property is useful when several tools share the same `Shift` combinations and are activated by some other code, for example by toolbar buttons.
6666
6767Finally, all tools have in common various **events** that are fired before or after a key or mouse button is pressed or released; in case of the mouse, there are also events that fire before or after the mouse is moved. Usually, chart tools work "out of the box", and these events are not needed. But they are necessary when some functionality is to be added. We will see examples in the course of this tutorial.
6868
6969### TChartToolset
7070
7171![](/wiki-images/9/9c/TChartToolset-Icon2.png)
7272
7373Chart tools are collected in a special component, `TChartToolset`. You can find it somewhere in the center of the "Chart" page of the Lazarus component palette, it has the icon with the red screw driver.
7474
7575The `TChartToolset` manages communications between tools and chart. Therefore, the chart has a property `Toolset` which has to be assigned to the `TChartToolset` instance. Note that this is a 1:n relationship, i.e. one toolset can handle multiple charts, a very nice feature! I should also mention that I usually forget to make that assignment -- and have to spend time in seeking for the reason why the tools do not work...
7676
7777## Zooming by the mouse-wheel
7878
7979But now, enough of theory! Let's practise instead.
8080
8181Let us add tools to our demo chart. For this purpose we need a `TChartToolset` ![](/wiki-images/4/40/TChartToolset-Icon.png). Drop it onto your form and link it to the `Toolset` property of the chart.
8282
8383Although we did not yet add any tools to the toolset, maybe this is a good point to compile and run our program. Try to zoom or pan, as we did above. Oh -- no longer working! This is an important observation: by adding a `TChartToolset` to the form we replaced the default toolset built into the chart. So, the built-in tools for zooming and panning are not operational any more.
8484
8585In order to re-establish zooming and panning for our application we have to add one (or more) zooming or panning tools to the toolset.
8686
8787What do want to achieve? Maybe, instead of using the left and right mouse buttons we could take advantage of the mouse wheel for zooming and panning. And we could assign the left mouse button to a tool which allows us to read data values from the series while clicking onto a data point.
8888
8989To add a mouse-wheel tool for zooming to the chart you double-click on the `ChartToolset1` on the form, or double-click on it on the object tree of the object inspector, or right-click on it and select *"Edit tools"*, as you do with all collection editors of TAChart. Press *"Add"* button, select *"Zoom by mouse-wheel"* from the dropdown list, and a new item `ChartToolset1ZoomMousewheelTool1` appears in the object tree as a child of `ChartToolset1`.
9090
9191![](/wiki-images/2/29/ChartToolset_Editor.png)
9292
9393If you would run the program at this time, zooming still would not work because the tool has properties `ZoomFactor` and `ZoomRatio` that define the amount of zooming per mouse-wheel step, and they are still at their default of 1. So, set `ZoomFactor` to 1.1, and run the program. Now zooming works fine.
9494
9595When you scroll the mouse-wheel towards yourself the chart is magnified as if you bring the chart closer to you. Many programs work the other way round: for the same scrolling direction the chart gets smaller as if you move away from the chart. If you want this behavior set the `ZoomFactor` to a number less then 1, for example 0.9. (We will stick to 1.1 for the rest of the tutorial, though).
9696
9797#### Some properties
9898
9999Let's have a look at the properties of the zoom mousewheel tool. There are `AnimationInterval` and `AnimationsSteps` which can be used to achieve an animation of the zooming effect.
100100
101101What is `FixedPoint`? If `true` the center of the zooming operation is the position of the mouse cursor. So, if you want to zoom into a particular feature in the chart move the mouse to the feature and rotate the mouse wheel. If `false` the zooming is always relative to the chart center, no matter where the mouse cursor is. In this case you have to be very careful because it is extremely easy to lose orientation in the chart.
102102
103103#### Using the ExtentSizeLimit
104104
105105![](/wiki-images/a/a3/ZoomPan04.png)
106106
107107When you zoom *out* you will expose empty regions. Because the user can zoom out further and further the chart may eventually disappear. To prevent this we should restrict the axis ranges such that always data are displayed.
108108
109109For this purpose, TChart has a property **`ExtentSizeLimit`**. Our chart has an x extent from -10 to 10. So we set `ExtentSizeLimit.XMax` to the difference, 20, and activate this setting by `ExtentSizeLimit.UseXMax = true`. Now, we can no longer zoom out beyond the original *x* extent. Similarly, we should restrict the extent of the *y* axis to 2.
110110
111111In the same way, we could prevent to zoom *into* the chart beyond an x extent of, say, 0.01. For this we would set the properties `ExentSizeLimit.XMin` and `ExtentSizeLimit.UseXMin` accordingly.
112112
113113#### Horizontal and vertical zooming
114114
115115Why are there two parameters that control the amount of zooming, **`ZoomFactor`** and **`ZoomRatio`**? This is because the tool can be used for non-proportional zooming: the *x* zoom factor is given by `ZoomFactor` alone while the *y* zoom factor is determined by the product `ZoomFactor*ZoomRatio`. As long as `ZoomRatio=1`, zooming occurs isotropically in all directions. When you set `ZoomFactor=1` and `ZoomRatio=1.1` we leave the *x* direction unchanged, but zoom only along the *y* direction. Or, if we set `ZoomRatio = 1/ZoomFactor` zooming occurs only horizontally along the *x* axis.
116116
117117Hey -- these would be nice features for our program! When we look at the keyboard the `SHIFT`, `Ctrl` and `Alt` keys form some kind of coordinate system: `Ctrl` is the origin, `SHIFT` is the *y* direction, `Alt` is the *x* direction. So we could assign the `SHIFT` key to vertical zooming, the `Alt` key to horizontal zooming, and "no key" to isotropic zooming -- that's easy to remember.
118118
119119How can we implement this feature? Add two more ZoomMouseWheelTools to the form. The first one will do the vertical zoom, so name it `ChartToolset1ZoomMousewheelTool_vert`, select `ssShift` in the `Shift` property, and set `ZoomRatio = 1.1` (keep `ZoomFactor` at 1). The other tool will be for the horizontal zoom, name it `ChartToolset1ZoomMousewheelTool_hor`, set `Shift` to `ssAlt`, and set `ZoomFactor = 1.1` and `ZoomRatio = 0.90909090909` (which is approximately equal to 1/1.1).
120120
121121When you run the program you may notice that zooming stops working after you have pressed the `Alt` key. This is caused by the fact that the `Alt` key plays a special role for menu key handling. To reactivate the program you have to click into the chart. Or select another activation key for the horizontal zoom tool.
122122
123123## Panning by the mouse-wheel
124124
125125Let's move on the panning. Why don't we use the mousewheel also for panning? Here, panning can go only in one direction -- either *x* or *y*. So let us add two `TPanMouseWheelTool`s and replace numbers at the end of their names by "_vert" and "_hor". The tool for vertical panning should be activated by the `SHIFT` key again, the tool for horizontal panning by the `Alt` key.
126126
127127There is a property `WheelUpDirection` which defaults to `pdUp`. This means that scrolling of the mouse-wheel is translated to a vertical panning direction. This setting is not correct for the horizontal panning tool, select `pdRight` or `pdLeft` instead.
128128
129129Run the program. When you rotate the mouse wheel with `SHIFT` or `Alt` down the chart zooms, but does not pan. What's wrong?
130130
131131The reason is that we are using the same `Shift` settings for the zooming and panning tools. Well, we could use, for example, the `Ctrl` key and assign it additionally to the panning tools. Then vertical panning, for example, would occur by pressing `Ctrl`+`SHIFT`, vertical zooming would occur with `SHIFT` alone.
132132
133133Let's go another way here to demonstrate usage of the `Enabled` property. Add a toolbar to the form with two buttons to activate either zooming or panning. Rename the first button to `ZoomToolbutton` and set `Down` to `true`. Rename the second button to `PanToolbutton`. For both buttons, set the following properties:
134134
135135- `Grouped = true`
136136- `Style = tbsCheck`
137137
138138and assign their `OnClick` to the following event handler:
139139
140140``` pascal
141141procedure TForm1.ZoomPanToolbuttonClick(Sender: TObject);
142142begin
143143 ChartToolset1ZoomMouseWheelTool_iso.Enabled := ZoomToolbutton.Down;
144144 ChartToolset1ZoomMouseWheelTool_vert.Enabled := ZoomToolbutton.Down;
145145 ChartToolset1ZoomMouseWheelTool_hor.Enabled := ZoomToolbutton.Down;
146146
147147 ChartToolset1PanMouseWheelTool_vert.Enabled := PanToolbutton.Down;
148148 ChartToolset1PanMouseWheelTool_hor.Enabled := PanToolbutton.Down;
149149end;
150150```
151151
152152This enables either the zooming or the panning tools, depending on which toolbutton is down. To synchronize the chart tools' `Enabled` with the buttons' `Down` you should disable both panning tools (or call `ZoomPanToolbuttonClick(nil)` in the `OnCreate` event of the form).
153153
154154Some observations when you run the program:
155155
156156- It's a matter of taste, but maybe you feel that the vertical zoom direction is **opposite** to the direction the mouse wheel is rotated. You can change this by setting the `WheelUpDirection` of the vertical panning tool to `pdDown`.
157157- **Empty chart regions without data** can become visible again. This is because the `ExtentSizeLimit` checks only the width and/or height of the extent. To take care of this the PanMousewheelTool has a set of properties `LimitToExtent`. Activate all options to disallow horizontal and vertical panning beyond the original extent with data.
158158- Maybe you want to change the **speed** of panning. This can be done by adapting the `Step` property.
159159- You may also notice that it is quite cumbersome to restore the original extent of the chart. It would be fine to have a button *"Reset"* in the toolbar which undoes any zooming and panning operations. That's easy: add a third button to the toolbar, name it `RestoreToolbutton`, set its `Caption` to *"Reset"*, and assign its `OnClick` event to the following procedure:
160160
161161``` pascal
162162procedure TForm1.ResetToolButtonClick(Sender: TObject);
163163begin
164164 Chart1.ZoomFull;
165165end;
166166```
167167
168168The `ZoomFull` procedure restores the chart extent to its original value. Here's what our program looks like now:
169169
170170![](/wiki-images/1/18/ZoomPan04a.png)
171171
172172## Reading data from the series
173173
174174You can add more zooming and panning tools to the toolset to get a practical user interface. But we will stop here with the extent tools and move on to the data tools.
175175
176176### Using a TDataPointClickTool
177177
178178Our task is to read the x,y coordinates of the series underneath the mouse cursor. A neat tool to achieve this is the `TDatapointClickTool`. Add it to the toolset. Set `Shift` to `ssLeft` to activate it by a left button click. And add a `TStatusbar` to the form where we will display the requested information.
179179
180180Whenever a click occurs on (or sufficiently near) a data point the relevant data are stored in the tool. For example, there is a `Series` property which identifies onto which series the click occurred. Similarly, there is a property `PointIndex` which tells the index of the hit point within its series. The tool provides an `OnPointClick` event which fires when a point is clicked and from where we can query the requested information. We can use the following event handler to extract the information for displaying in the status bar:
181181
182182``` pascal
183183procedure TForm1.ChartToolset1DataPointClickTool1PointClick(
184184 ATool: TChartTool; APoint: TPoint);
185185var
186186 x, y: Double;
187187begin
188188 with ATool as TDatapointClickTool do
189189 if (Series is TLineSeries) then
190190 with TLineSeries(Series) do begin
191191 x := GetXValue(PointIndex);
192192 y := GetYValue(PointIndex);
193193 Statusbar1.SimpleText := Format('%s: x = %f, y = %f', [Title, x, y]);
194194 end
195195 else
196196 Statusbar1.SimpleText := '';
197197end;
198198```
199199
200200The parameter `ATool` passed to the event is rather general, thus we have to type-cast it to `TDatapointClickTool` to get access to the mentioned properties. Similarly, the `Series` is of a very basic type as well, another type-cast is needed. Be careful with type-casts, make sure that the class types are correct. Therefore, we check the types by means of `is`.
201201
202202When you run the program and click on a data point you will see its coordinates along with the title of its series in the status bar.
203203
204204![](/wiki-images/4/49/ZoomPan05.png)
205205
206206### Showing permanent labels
207207
208208Unfortunately, there is no indication where exactly the click occurred. It would be better if we could display a label above the clicked point to show the requested information.
209209
210210Here we can take advantage of the fact that the series in our chart get their data from `TListChartSource`s. They have no special components on the form, because this is the default behavior, and each `TChartSeries` (from which `TLineSeries` inherits) has a non-visual built-in listsource which can be accessed by a (public) property `ListSource`.
211211
212212Why is this important? Because the items stored in a listsource provide extra storage for an additional text:
213213
214214``` pascal
215215type
216216 TChartDataItem = object
217217 X, Y: Double;
218218 Text: String;
219219 // ...
220220 end;
221221```
222222
223223To modify the `Text` assigned to a data point at a given `index` you can call
224224
225225``` pascal
226226ListSource.Item[index]^.Text := 'some text';
227227```
228228
229229or, in later versions of Lazarus, there is a `SetText` method for abbreviation:
230230
231231``` pascal
232232ListSource.SetText(index, 'some text');
233233```
234234
235235(You can learn more about list sources from [[TAChart Tutorial: ListChartSource, Logarithmic Axis, Fitting|the tutorial on them]].)
236236
237237Since we did not use this feature all `Text` entries are empty. But when we click onto a data point, we can transfer the coordinate info into the `Text` member of the ChartDataItem by adding the indicated line to our `OnPointClick` event handler of the datapoint click tool (BTW, we don't need the status bar any longer, so delete it and remove the corresponding code from the event handler):
238238
239239``` pascal
240240procedure TForm1.ChartToolset1DataPointClickTool1PointClick(
241241 ATool: TChartTool; APoint: TPoint);
242242var
243243 x, y: Double;
244244begin
245245 with ATool as TDatapointClickTool do
246246 if (Series <> nil) then
247247 with (Series as TLineSeries) do begin
248248 x := GetXValue(PointIndex);
249249 y := GetYValue(PointIndex);
250250 { --- next line removed --- }
251251// Statusbar1.SimpleText := Format('%s: x = %f, y = %f', [Title, x, y]);
252252 { --- next line added --- }
253253 ListSource.Item[PointIndex]^.Text := Format('x = %f'#13#10'y = %f', [x,y]);
254254 ParentChart.Repaint;
255255 // in newer Lazarus versions you can use (which already contains the Repaint):
256256 // ListSource.SetText(PointIndex, Format('x = %f'#13#10'y = %f', [x,y]));
257257 end;
258258end;
259259```
260260
261261Now we have to make sure that the labels are displayed. For this purpose, the `TChartSeries` which is an ancestor of `TLineSeries` has a property `Marks`. In the sub-properties you find the option `Style` which is set to `smsNone` by default, meaning that no labels are displayed. You see in the object inspector that there is a variety of information than can be displayed in the marks, but you'll need here the option `smsLabel` which shows the text of the ChartDataItems. Another modification may be useful: Set `LinkPen.Color` to some darker color, otherwise the connecting line between label and data point will not be visible on the white background. You may also want to play with some visual enhancements like `CalloutAngle` or `Shape`.
262262
263263You have to do the same changes for all three series in the chart.
264264
265265When you run the project and click on the series you get nice permanent labels. Please note that the markers stay in place even if you change the viewport by zooming or panning.
266266
267267![](/wiki-images/c/c6/ZoomPan06.png)
268268
269269### Removing permanent labels
270270
271271Once in a while you may find that you have clicked at the wrong point and you may want to remove a label.
272272
273273The basic idea for this feature is as follows: add another `TDatapointClickTool`, assign it to the right mouse button and, in the `OnDatapointClick` event handler, we remove the text from the clicked ChartDataItem. Try doing it yourself -- you should now know all the necessary steps.
274274
275275## Related tutorials
276276
277277- [[TAChart Tutorial: Getting started]]: explains how the chart used here is created.
278278- [[TAChart Tutorial: ListChartSource, Logarithmic Axis, Fitting]]: discusses usage of series `Marks`.
279279- [[TAChart Tutorial: ColorMapSeries, Zooming]]: demonstrates other aspects of zooming and panning, like using the ZoomDragTool, PanDragTool and setting up a zoom history.
280280
281281## Source code
282282
283283### project.lpr
284284
285285``` pascal
286286program project1;
287287
288288{$mode objfpc}{$H+}
289289
290290uses
291291 {$IFDEF UNIX}{$IFDEF UseCThreads}
292292 cthreads,
293293 {$ENDIF}{$ENDIF}
294294 Interfaces, // this includes the LCL widgetset
295295 Forms, Unit1, tachartlazaruspkg
296296 { you can add units after this };
297297
298298{$R *.res}
299299
300300begin
301301 RequireDerivedFormResource := True;
302302 Application.Initialize;
303303 Application.CreateForm(TForm1, Form1);
304304 Application.Run;
305305end.
306306```
307307
308308### unit1.pas
309309
310310``` pascal
311311unit Unit1;
312312
313313{$mode objfpc}{$H+}
314314
315315interface
316316
317317uses
318318 Classes, SysUtils, FileUtil, TAGraph, TASeries, TATools, Forms, Controls,
319319 Graphics, Dialogs, ComCtrls, types;
320320
321321type
322322
323323 { TForm1 }
324324
325325 TForm1 = class(TForm)
326326 Chart1: TChart;
327327 ChartToolset1: TChartToolset;
328328 ChartToolset1DataPointClickTool1: TDataPointClickTool;
329329 ChartToolset1DataPointClickTool2: TDataPointClickTool;
330330 ChartToolset1PanMouseWheelTool_Hor: TPanMouseWheelTool;
331331 ChartToolset1PanMouseWheelTool_Vert: TPanMouseWheelTool;
332332 ChartToolset1ZoomMouseWheelTool_iso: TZoomMouseWheelTool;
333333 ChartToolset1ZoomMouseWheelTool_Hor: TZoomMouseWheelTool;
334334 ChartToolset1ZoomMouseWheelTool_Vert: TZoomMouseWheelTool;
335335 SinSeries: TLineSeries;
336336 CosSeries: TLineSeries;
337337 SinCosSeries: TLineSeries;
338338 ToolBar1: TToolBar;
339339 ResetToolButton: TToolButton;
340340 ZoomToolbutton: TToolButton;
341341 PanToolbutton: TToolButton;
342342 procedure ChartToolset1DataPointClickTool1PointClick(
343343 ATool: TChartTool; APoint: TPoint);
344344 procedure ChartToolset1DataPointClickTool2PointClick(
345345 ATool: TChartTool; APoint: TPoint);
346346 procedure FormCreate(Sender: TObject);
347347 procedure ResetToolButtonClick(Sender: TObject);
348348 procedure ZoomPanToolbuttonClick(Sender: TObject);
349349 private
350350 { private declarations }
351351 public
352352 { public declarations }
353353 end;
354354
355355var
356356 Form1: TForm1;
357357
358358implementation
359359
360360{$R *.lfm}
361361
362362{ TForm1 }
363363
364364procedure TForm1.FormCreate(Sender: TObject);
365365const
366366 N = 100;
367367 MIN = -10;
368368 MAX = 10;
369369var
370370 i: Integer;
371371 x: Double;
372372begin
373373 for i:=0 to N - 1 do begin
374374 x := MIN + (MAX - MIN) * i / (N - 1);
375375 SinSeries.AddXY(x, sin(x));
376376 CosSeries.AddXY(x, cos(x));
377377 SinCosSeries.AddXY(x, sin(x)*cos(x));
378378 end;
379379end;
380380
381381procedure TForm1.ResetToolButtonClick(Sender: TObject);
382382begin
383383 Chart1.ZoomFull;
384384end;
385385
386386procedure TForm1.ChartToolset1DataPointClickTool1PointClick(
387387 ATool: TChartTool; APoint: TPoint);
388388var
389389 x,y: Double;
390390begin
391391 with ATool as TDatapointClickTool do
392392 if (Series <> nil) then
393393 with (Series as TLineSeries) do begin
394394 x := GetXValue(PointIndex);
395395 y := GetYValue(PointIndex);
396396// Statusbar1.SimpleText := Format('%s: x = %f, y = %f', [Title, x, y]);
397397 ListSource.Item[PointIndex]^.Text := Format('x = %f'#13#10'y = %f', [x,y]);
398398 ParentChart.Repaint;
399399 end;
400400end;
401401
402402procedure TForm1.ChartToolset1DataPointClickTool2PointClick(
403403 ATool: TChartTool; APoint: TPoint);
404404begin
405405 with ATool as TDatapointClickTool do
406406 if (Series <> nil) then
407407 with (Series as TLineSeries) do begin
408408 ListSource.Item[PointIndex]^.Text := '';
409409 ParentChart.Repaint;
410410 end;
411411end;
412412
413413procedure TForm1.ZoomPanToolbuttonClick(Sender: TObject);
414414begin
415415 ChartToolset1ZoomMouseWheelTool_iso.Enabled := ZoomToolbutton.Down;
416416 ChartToolset1ZoomMouseWheelTool_vert.Enabled := ZoomToolbutton.Down;
417417 ChartToolset1ZoomMouseWheelTool_hor.Enabled := ZoomToolbutton.Down;
418418
419419 ChartToolset1PanMouseWheelTool_vert.Enabled := PanToolbutton.Down;
420420 ChartToolset1PanMouseWheelTool_hor.Enabled := PanToolbutton.Down;
421421end;
422422
423423end.
424424```
425425
426426### unit1.lfm
427427
428-``` pascal
428+``` lfm
429429object Form1: TForm1
430430 Left = 554
431431 Height = 284
432432 Top = 341
433433 Width = 347
434434 Caption = 'Form1'
435435 ClientHeight = 284
436436 ClientWidth = 347
437437 OnCreate = FormCreate
438438 LCLVersion = '1.1'
439439 object Chart1: TChart
440440 Left = 0
441441 Height = 258
442442 Top = 26
443443 Width = 347
444444 AxisList = <
445445 item
446446 Grid.Color = clSilver
447447 Minors = <>
448448 Title.LabelFont.Orientation = 900
449449 Title.LabelFont.Style = [fsBold]
450450 Title.Visible = True
451451 Title.Caption = 'y axis'
452452 end
453453 item
454454 Grid.Color = clSilver
455455 Alignment = calBottom
456456 Minors = <>
457457 Title.LabelFont.Style = [fsBold]
458458 Title.Visible = True
459459 Title.Caption = 'x axis'
460460 end>
461461 BackColor = clWhite
462462 ExtentSizeLimit.UseXMax = True
463463 ExtentSizeLimit.UseXMin = True
464464 ExtentSizeLimit.UseYMax = True
465465 ExtentSizeLimit.XMax = 20
466466 ExtentSizeLimit.XMin = 0.01
467467 ExtentSizeLimit.YMax = 2
468468 Foot.Brush.Color = clBtnFace
469469 Foot.Font.Color = clBlue
470470 Legend.Alignment = laBottomCenter
471471 Legend.ColumnCount = 3
472472 Legend.Visible = True
473473 Title.Brush.Color = clBtnFace
474474 Title.Font.Color = clBlue
475475 Title.Font.Style = [fsBold]
476476 Title.Text.Strings = (
477477 'My first chart'
478478 )
479479 Title.Visible = True
480480 Toolset = ChartToolset1
481481 Align = alClient
482482 ParentColor = False
483483 object SinSeries: TLineSeries
484484 Marks.Format = '%2:s'
485485 Marks.LinkPen.Color = clGray
486486 Marks.Style = smsLabel
487487 Title = 'y=sin(x)'
488488 LinePen.Color = clRed
489489 end
490490 object CosSeries: TLineSeries
491491 Marks.Format = '%2:s'
492492 Marks.LinkPen.Color = clGray
493493 Marks.Style = smsLabel
494494 Title = 'y=cos(x)'
495495 LinePen.Color = clBlue
496496 end
497497 object SinCosSeries: TLineSeries
498498 Marks.Format = '%2:s'
499499 Marks.LinkPen.Color = clGray
500500 Marks.Style = smsLabel
501501 Title = 'y=sin(x)*cos(x)'
502502 LinePen.Color = clGreen
503503 end
504504 end
505505 object ToolBar1: TToolBar
506506 Left = 0
507507 Height = 26
508508 Top = 0
509509 Width = 347
510510 Caption = 'ToolBar1'
511511 EdgeBorders = [ebBottom]
512512 ShowCaptions = True
513513 TabOrder = 1
514514 object ZoomToolbutton: TToolButton
515515 Left = 1
516516 Top = 0
517517 Caption = 'Zoom'
518518 Down = True
519519 Grouped = True
520520 OnClick = ZoomPanToolbuttonClick
521521 Style = tbsCheck
522522 end
523523 object PanToolbutton: TToolButton
524524 Left = 41
525525 Top = 0
526526 Caption = 'Pan'
527527 Grouped = True
528528 OnClick = ZoomPanToolbuttonClick
529529 Style = tbsCheck
530530 end
531531 object ResetToolButton: TToolButton
532532 Left = 69
533533 Top = 0
534534 Caption = 'Reset'
535535 OnClick = ResetToolButtonClick
536536 end
537537 end
538538 object ChartToolset1: TChartToolset
539539 left = 153
540540 top = 66
541541 object ChartToolset1ZoomMouseWheelTool_iso: TZoomMouseWheelTool
542542 ZoomFactor = 1.1
543543 end
544544 object ChartToolset1ZoomMouseWheelTool_Hor: TZoomMouseWheelTool
545545 Shift = [ssAlt]
546546 ZoomFactor = 1.1
547547 ZoomRatio = 0.90909090909091
548548 end
549549 object ChartToolset1ZoomMouseWheelTool_Vert: TZoomMouseWheelTool
550550 Shift = [ssShift]
551551 ZoomRatio = 1.1
552552 end
553553 object ChartToolset1PanMouseWheelTool_Hor: TPanMouseWheelTool
554554 Shift = [ssAlt]
555555 LimitToExtent = [pdLeft, pdUp, pdRight, pdDown]
556556 WheelUpDirection = pdLeft
557557 end
558558 object ChartToolset1PanMouseWheelTool_Vert: TPanMouseWheelTool
559559 Shift = [ssShift]
560560 LimitToExtent = [pdLeft, pdUp, pdRight, pdDown]
561561 WheelUpDirection = pdDown
562562 end
563563 object ChartToolset1DataPointClickTool1: TDataPointClickTool
564564 Shift = [ssLeft]
565565 OnPointClick = ChartToolset1DataPointClickTool1PointClick
566566 end
567567 object ChartToolset1DataPointClickTool2: TDataPointClickTool
568568 Shift = [ssRight]
569569 OnPointClick = ChartToolset1DataPointClickTool2PointClick
570570 end
571571 end
572572end
573573```
574574
575575---
576576*From the Free Pascal wiki, page "TAChart Tutorial: Chart Tools", as it stood on 2022-10-05 after a change by Wp, 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).*

Back to history