Draw Ellipse, Points, and Lines

I have tried to draw a picture similar to the screenshot using TAdvChartView, but have had no luck.  I am able to calculate everything needed for the shapes and lines, but I do not know how to then draw these on the chart.
I need to draw the following on the same chart:
-An ellipse
-A cross within the ellipse
-Markers/points
-Arrows from the points to the ellipse

Is there an easy way to draw these shapes?

Hi, 


You could use the OnAfterDrawSeries event and copy the DrawArrow procedure from the AdvChart unit. We will expose it in the next version.



procedure DrawArrow(Canvas : TCanvas; ArrowColor: TColor; ArrowSize: integer; origin, target : TPoint; ScaleX, ScaleY: Double);
var
  quarter: byte;
  fx, px: Integer;
  fy, py: Integer;
  x, y: integer;
  arrowpts: array[0..3] of Tpoint;
  p: tpoint;
  ar: TPoint;
  h: Integer;
  arx, ary: integer;
begin


  arx := Round(ArrowSize * ScaleX);
  ary := Round(ArrowSize * ScaleY);


  arrowpts[0] := target;


  x := target.x - origin.x;
  y := target.y - origin.y;
  h := round(sqrt(sqr(x) + sqr(y)));


  if h = 0 then
    h := 1;


  // quarter?
  if origin.x < target.x then
  begin
    if origin.y < target.y then
      quarter := 1
    else
      quarter := 3;
  end
  else
  begin
    if origin.y < target.y then
      quarter := 2
    else
      quarter := 4;
  end;


  // calculate the actual P position using the adjustments px and py.
  px := x * arx div h;
  py := y * ary div h;
  case quarter of
    1 :
      begin
        p.x := target.x - px;
        p.y := target.y - py;
        ar.x := target.x - (x * arx div h);
        ar.y := target.y - (y * ary div h);
      end;
    2 :
      begin
        p.x := target.x - px;
        p.y := target.y - py;
        ar.x := target.x - (x * arx div h);
        ar.y := target.y - (y * ary div h);
      end;
    3 :
      begin
        p.x := target.x - px;
        p.y := target.y - py;
        ar.x := target.x - (x * arx div h);
        ar.y := target.y - (y * ary div h);
      end;
    4 :
      begin
        p.x := Target.x - px;
        p.y := Target.y - py;
        ar.x := target.x - (x * arx div h);
        ar.y := target.y - (y * ary div h);
      end;
  end;


  //calculate pts[1] and pts[2] from the P position to give us the back of the arrow.
  fx := y * (arx div 2) div h;
  fy := x * (ary div 2) div h;
  case quarter of
    1 :
      begin
        arrowpts[1].x := p.x - fx;
        arrowpts[1].y := p.y + fy;
        arrowpts[3].x := p.x + fx;
        arrowpts[3].y := p.y - fy;
      end;
    2 :
      begin
        arrowpts[1].x := p.x + fx;
        arrowpts[1].y := p.y - fy;
        arrowpts[3].x := p.x - fx;
        arrowpts[3].y := p.y + fy;
      end;
    3 :
      begin
        arrowpts[1].x := p.x + fx;
        arrowpts[1].y := p.y - fy;
        arrowpts[3].x := p.x - fx;
        arrowpts[3].y := p.y + fy;
      end;
    4 :
      begin
        arrowpts[1].x := p.x + fx;
        arrowpts[1].y := p.y - fy;
        arrowpts[3].x := p.x - fx;
        arrowpts[3].y := p.y + fy;
      end;
  end;


  arrowpts[2] := ar;
  if ArrowColor <> clNone then
    canvas.Brush.color := ArrowColor
  else
    canvas.Brush.Style := bsClear;


  Canvas.polygon(arrowpts);
end;


For the markers, ellipsis and cross you can use the default canvas functionality and for calculation from pixel to value you can use YToValue and ValueToY or the XToValue and ValueToX equivalent on series level, with the series rectangle. The code below for example will convert a value of 100 to Y pixel values based on the Y-Scale of the first series.



procedure TForm1.AdvGDIPChartView1AfterDrawSeries(Sender: TObject;
  ARect: TRect; ACanvas: TCanvas; APaneIndex: Integer);
var
  s: TChartSerie;
begin
  s := AdvGDIPChartView1.Panes[APaneIndex].Series[0];
  s.ValueToY(100, s.Chart.Series.SeriesRectangle);
end;


Kind Regards, 
Pieter

Pieter Scheldeman2015-09-16 08:41:11

What do you use to draw the ellipse.  I am still struggling with that aspect of the task.

You have the VCL TCanvas at your disposition to do any drawing you want, including drawing an ellipse.