Recent

Author Topic: Chart tools[SOLVED]  (Read 1138 times)

jbmckim

  • Full Member
  • ***
  • Posts: 131
Chart tools[SOLVED]
« on: December 04, 2019, 07:56:48 pm »
Trying to add a PointClick event to 4 line series.  Couldn't find an example that spoke to what I'm trying to do. I therefore seem to be missing a property association or some such.   The attached project contains the following:

Code: Pascal  [Select]
  1. procedure TForm1.ChartToolset1DataPointClickTool1PointClick(ATool: TChartTool;
  2.   APoint: TPoint);
  3. var
  4.   i : integer = 0;
  5. begin
  6.   i := 1;
  7. end;        

The line:

Code: Pascal  [Select]
  1. i := 1;

isn't executing no matter how much I swear at my monitor and threaten it with grievous bodily harm.

Thanks.
« Last Edit: December 10, 2019, 08:25:43 pm by jbmckim »

wp

  • Hero Member
  • *****
  • Posts: 6645
Re: Chart tools
« Reply #1 on: December 04, 2019, 10:38:35 pm »
I don't know what you want to happen you click.

A datapoint click tool is for clicking on a data point. Usually you provide a handler for its OnClick event. The event has the tool used (there may be other tools as well) as a parameter, but that is a very general TChartTool type (because the OnClick event is available also for aother chart tools). Therefore, you must cast it to TDataPointClickTool. The TDataPointClickTool, in turn, has a variety of properties which are set after the click and that you can query in the event handler:
- Series - the series clicked, again very general so that you must cast it to the type that you expect
- PointIndex - index of the clicked data point
- GraphPoint - coordinates of the point clicked

Modify the OnClick handler of your example in the following way, then a message box will popup whenever you click onto a datapoint:
Code: Pascal  [Select]
  1. procedure TForm1.ChartToolset1DataPointClickTool1PointClick(ATool: TChartTool;
  2.   APoint: TPoint);
  3. var
  4.   tool: TDataPointClicktool;
  5.   series: TLineSeries;
  6. begin
  7.   if not (ATool is TDataPointClickTool) then
  8.     exit;
  9.  
  10.   tool := TDatapointClickTool(ATool);
  11.   if tool <> nil then begin
  12.     if not (tool.Series is TLineSeries) then
  13.       exit;
  14.     series := TLineSeries(tool.Series);
  15.     if series <> nil then
  16.       ShowMessage(
  17.         Format('Series "%s" clicked at data point #%d.'+LineEnding+'X is %f, and Y is %f',
  18.           [series.Title, tool.PointIndex, series.XValue[tool.PointIndex], series.YValue[tool.PointIndex]]
  19.         ));
  20.   end;
  21. end;

The tool requires a non-empty Shift combination to determine when it should become active. For a left-click, therefore, you must check the ssLeft element of the Shift property.

Since you must click on data points here, I'd recommend to display the data point symbols by setting the series' ShowPoints to true. Otherwise most clicks will miss the points.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jbmckim

  • Full Member
  • ***
  • Posts: 131
Re: Chart tools
« Reply #2 on: December 05, 2019, 09:01:17 pm »
The good news:

I got your code to execute after setting this to Shift: 

Quote
The tool requires a non-empty Shift combination to determine when it should become active. For a left-click, therefore, you must check the ssLeft element of the Shift property.

And experimented with:
Quote
Since you must click on data points here, I'd recommend to display the data point symbols by setting the series' ShowPoints to true. Otherwise most clicks will miss the points.

That second point might get me where I want to be if I can set the color of the data point (I assume this is possible...and has a nomenclature not obvious to me).  It just seems a little inelegant when thousands of points are plotted as will be the case here.

Is there anyway to (at least fairly) easily override/expand the sensitivity of the OnPointClick event such that it reads a wider area?  This would avoid the need to use ShowPoints.

In case you have a better idea, I'm trying to provide the user with a one click extrapolation of "what happened at <clickpoint> in time."  I'll be displaying x & y values certainly and possibly some other data stored in a list of records that corresponds to the data points.


Last is that the standard, upper left to lower right drag style zoom seems to have gone away.  Where did that get off to?

Thanks.



wp

  • Hero Member
  • *****
  • Posts: 6645
Re: Chart tools
« Reply #3 on: December 06, 2019, 12:13:20 am »
[...] if I can set the color of the data point (I assume this is possible...and has a nomenclature not obvious to me). 
The data point of a line series is represented by the Pointer property. Use the properties Brush.Color, HorizSize/VertSize and Style to set its color, horizontal/vertical size (in pixels) and shape (rectangle, cirlce etc). Set Pointer.Visible or the series' ShowPoints to true in order to show the data point symbols.

It just seems a little inelegant when thousands of points are plotted as will be the case here.
I agree. But I don't know the shape of your plotted curves. When they really are as horizontal as those of your demo you absolutely need the data points. If you can identify the points by kinks in the plotted curve you don't need them.

Is there anyway to (at least fairly) easily override/expand the sensitivity of the OnPointClick event such that it reads a wider area?
Increase the GrabRadius of the ClickTool.

In case you have a better idea, I'm trying to provide the user with a one click extrapolation of "what happened at <clickpoint> in time."  I'll be displaying x & y values certainly and possibly some other data stored in a list of records that corresponds to the data points.
You could also use a DataPointHint tool where you simply move the mouse over a data point (without clicking) and a popup hint window appears with the desired information. Use the OnHint event to construct the Hint text to be displayed. Please search the forum for examples that I constructed for other users.

Last is that the standard, upper left to lower right drag style zoom seems to have gone away.  Where did that get off to?
This happens whenever a ChartTools component is assigned to the chart because the new tools disable the built-in chart tools which make zooming and panning available. But you can add a ZoomDragTool and a PanDragTool to the ChartTools component that you added for the ClickTool. Use the ssLeft for the zoom tool Shift and the ssRight for the pan tool Shift, and you'll get the same behaviour as with the built-in tools. You even have better control over these tools - just look at their properties in the object inspector. But please note that when zooming is activated by the left mouse button you cannot use the same Shift value for the ClickTool. Maybe you add also ssCtrl to the Shift property of the click tool - now you activate the click tool by a Ctrl-left click.


Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jbmckim

  • Full Member
  • ***
  • Posts: 131
Re: Chart tools
« Reply #4 on: December 06, 2019, 09:03:27 pm »
Well damn!

Great info.  Now I've got something to check out this weekend.

Thanks!

jbmckim

  • Full Member
  • ***
  • Posts: 131
Re: Chart tools
« Reply #5 on: December 10, 2019, 02:01:24 am »
This very good.  I think I'll end up using a combination of MouseWheelZoop, PanDrag and  DataPointClick as kicking up the grab Radius some results in a successful grab virtually every time after the signals start to have a realistic number of data points.  I have a couple questions that I think are the last ones ::)

1)  Is there a setting or best practice to "reset" things like "MouseWheelZoom" and "PanDrag" to the normal extents?  I'm thinking of using these two to let the user drill down on a specific time.

2)  Do you happen to know the algorithm for GrabRadius?  Specifically, I'm interested in knowing what happens when >= 2 data points are within the GrabRadius.  I'm guessing the closest is returned.  It's possible that things might get a little indistinct if the user clicks near an intersection of >= 2 signals but that's fine since the display will include the title of signal/curve.

Thanks.

wp

  • Hero Member
  • *****
  • Posts: 6645
Re: Chart tools
« Reply #6 on: December 10, 2019, 11:25:03 am »
1)  Is there a setting or best practice to "reset" things like "MouseWheelZoom" and "PanDrag" to the normal extents?  I'm thinking of using these two to let the user drill down on a specific time.
Resetting to the unzoomed extent is normally done by the ZoomDragTool, property "RestoreExtentOn", by default a simple mouse click. If the ZoomDrag tool is not contained in your selection of tools you can add a button, toolbutten or similar which executes the following OnClick code:

Code: Pascal  [Select]
  1. procedure TForm1.btnUnzoom(Sender: TObject);
  2. begin
  3.   Chart1.ZoomFull;
  4. end;

2)  Do you happen to know the algorithm for GrabRadius?  Specifically, I'm interested in knowing what happens when >= 2 data points are within the GrabRadius.  I'm guessing the closest is returned.  It's possible that things might get a little indistinct if the user clicks near an intersection of >= 2 signals but that's fine since the display will include the title of signal/curve.
The data point tools call the function GetNearestPoint of each series to determine the distance of the (visible) data points from the clicked point. GrabRadius is the minimum distance within which points are considered. If several points are found within the GrabRadius distance only the closest one is selected. In the rare case that two points have equal distance from the clicked point I think the one in the series with the lower index (in the collection of all series) is selected.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jbmckim

  • Full Member
  • ***
  • Posts: 131
Re: Chart tools[SOLVED]
« Reply #7 on: December 10, 2019, 08:26:27 pm »
Outstanding.

We're done here.

Thanks again for all the help.