0
votes

An instance of TChart in Delphi does a nice job of making a graph showing points. This is the "Point" series in the TeeChart gallery.

I would like to draw lines between some, but not all, of the points.

For example, image a scatter diagram of points, which is easy to make with Delphi/TChart. My objective is to draw straight lines between some of the points.

Is this possible?

This code works:

With Chart2.ChartRect do
  begin
    Canvas.MoveTo(0,0);
    Canvas.LineTo(500,500);
  end;

The line crosses over the graph, except the line is not visible over the graph. It seems as if the graph much have its own canvas but I can't find any documentation about finding and using it.

So, I need to find the coordinates of some points, as created by TChart, then draw a line between them.

3
You could add LineSeries and let the Chart do the drawing.bummi
Shouldn't you let the chart draw the lines? Lines between points on a graph is... a line graph :) And TChart definitely supports that.David

3 Answers

2
votes

Some options:

  1. As David Heffernan said, the best option may be to use a series that supports both line segments and pointers. TLineSeries seems to be the perfect series to do this.

    The problem here is that this series draws a line segment between each two consecutive points. You can make a point to be null with setNull(index) method and this will make the pointer at that index to disappear, but the predecessor and successor line segments will disappear with it.

    The easiest solution could be creating a TMyLineSeries inheriting from TLineSeries to override DrawValue method as explained here.

  2. Add a null point after each point you want to be visible. In this option, the only points not followed by a null point would be those where you want a line segment to be drawn.

  3. Add a TLineSeries per line segment to be drawn.

  4. You always have the possibility to use custom drawing techniques as LU RD said.

1
votes

Attempting to paint lines yourself is not the way to proceed. The design basis of charting controls is that you define the chart in logical terms and let the control deal with painting it.

So, the way to proceed is to add some line series that represent the lines you wish to be drawn. You can perfectly well add these line series in addition to the other series of your chart.


Regarding your code that attempts to paint on the chart canvas, you should be aware that painting is a delicate process. The design of the system is such that control surfaces are not persistent. Controls are painted in response to the WM_PAINT message. So, whilst you may be able to paint on a control's canvas as you please, what you paint will survive only until the next cycle. Once the control becomes invalid, it needs to repaint itself. The lesson here is, as a general rule, only to paint in response to WM_PAINT messages. Or, in OnPaint events or overridden Paint methods which are called by the VCL in response to WM_PAINT.

0
votes

To interconnect some points you must follow the drawing principle, all drawing must be done in a paint event.

In TChart, best option here is to do custom drawing in the OnAfterDraw event.

procedure TForm1.Chart2AfterDraw(Sender: TObject);
begin
  With Chart2.ChartRect do
  begin
    Canvas.MoveTo(0,0);
    Canvas.LineTo(500,500);
  end;
end; 

If you need to know the canvas coordinates for a given point in your array of points.

MyYPosX := Series1.CalcXPos( Series1.XValue[ 0 ] ); { <-- first point }
MyYPosY := Series1.CalcYPos( Series1.YValue[ 0 ] ); { <-- first point }

There is a chapter in the TChart help that is a good introduction to custom drawing: "Custom drawing on the Chart".

From the help:

When to draw ?

The order in which you draw to the Canvas is important.

If you wish Custom drawn items to appear above Chart Series you should use the Chart OnAfterDraw event. The Chart1.OnAfterDraw event is fired each time the Chart component is redrawn, just before copying the internal bitmap to screen.

You can place Custom drawn items above the Chart grid and below the Chart Series by placing your code in the Chart OnBeforeDrawSeries event.

Key Chart Paint events:

  • OnBeforeDrawChart
  • OnBeforeDrawAxes
  • OnBeforeDrawSeries
  • OnAfterDraw