Best Approach to Draw a Single Arrow Head on a Line Series

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
br&e
Newbie
Newbie
Posts: 3
Joined: Tue Apr 04, 2017 12:00 am

Best Approach to Draw a Single Arrow Head on a Line Series

Post by br&e » Thu Apr 13, 2017 10:46 pm

Hello All,

I have been searching the .NET forum and have a possible approach. Let me explain what is intended on the Chart user interface, and then list some code that could accomplish that. I am looking for assistance on determining if there is a better way (or best) that I am missing.

After (or while) creating new Series and then adding them to a single Chart component, all of them need an arrow head drawn at approximately 75 percent of the traversal along each series. The arrow head points in the direction of how real life things like steam move down a pipe. Only a single point is needed for the arrow head. I am aware of the TeeChart.Styles.Arrow series and its Add method to receive two sets of x, y coordinates to draw the arrow head. The example code I have created is based on this post: TeeChart.Styles.Arrow.LinePen Issues http://www.teechart.net/support/viewtop ... ilit=arrow

Code: Select all

   TeeChart.Styles.Arrow arrowStyle = new TeeChart.Styles.Arrow(tChart1.Chart);
   arrowStyle.ArrowHeight = 20;
   arrowStyle.ArrowWidth = 20;
   arrowStyle.Pointer.Pen.Width = 3;
   arrowStyle.Pointer.Pen.Style = System.Drawing.Drawing2D.DashStyle.Solid;
   arrowStyle.Add(13, 24, 13.8, 23, Color.LimeGreen);
   tChart1.Series.Add(arrowStyle);
To see the "one point" arrowStyle appear, the button click event has to fire twice. It does not matter if

Code: Select all

tChart1.Invalidate()
is called after the

Code: Select all

tChart1.Series.Add(arrowStyle)
line either. Two button click events will cause the one arrowStyle to appear. I am not sure if I am missing something in a property on the tChart1. It is possible.

Regardless, is there a better way to have a single arrow head appear on a line series, approximately 75 percent of the traversal along the series? For example, The above approach would mean that if there are 3000 independent line series, there would be 3000 independent single point "arrow head" TeeChart.Styles.Arrow series, for a grand total of 6000 series on a single chart.

If a single method exists within one of the series objects, it would be ideal if a single x, y coordinate can be given and the respective angle to match the line series directly beneath it. In other words, the arrow has to be pointing in the correct flow direction. The closest method I can find that is similar to the description is TeeChart.Drawing.TextShape.DrawRectRotated here: http://www.teechart.net/docs/teechart/n ... Method.htm. This special x, y coordinate and angle parameters method is definitely not a requirement. I would like to know if it exists to draw an arrow head as described above. Thank you all for your assistance.

Sincerely,

BR&E

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Best Approach to Draw a Single Arrow Head on a Line Series

Post by Christopher » Tue Apr 18, 2017 9:21 am

Hello,
br&e wrote:This special x, y coordinate and angle parameters method is definitely not a requirement. I would like to know if it exists to draw an arrow head as described above. Thank you all for your assistance.
possibly the easiest way to achieve this would be to custom draw an arrow onto the TeeChart canvas - this can be done using one of the TeeChart events and the canvas Arrow method, as in this example:

Code: Select all

    Line line;
    private void InitializeChart()
    {
      tChart1.Aspect.View3D = false;

      line = new Line(tChart1.Chart);
      line.FillSampleValues();

      tChart1.AfterDraw += TChart1_AfterDraw;
    }

    private void TChart1_AfterDraw(object sender, Graphics3D g)
    {
      int x = line.CalcXPos(5);
      int y = line.CalcYPos(5);

      Point from = new Point(x - 25, y);
      Point to = new Point(x + 25, y);

      g.Brush.Color = line.Color;
      g.Arrow(true, from, to, 25, 25, 0);
    }
is this a satisfactory solution for you?
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

br&e
Newbie
Newbie
Posts: 3
Joined: Tue Apr 04, 2017 12:00 am

Re: Best Approach to Draw a Single Arrow Head on a Line Series

Post by br&e » Wed Apr 19, 2017 7:39 pm

Thank you Christopher. I have tested the implementation. The g.Arrow is much larger than what is needed.

I have attached a screen capture of the desired look. The added arrow head is inside the red circle. Generally, the arrow head looks like two lines at the correct orientation relative to the line segment slope. The line and arrow series' widths are the same.

Note that I have to force the TeeChart.Invalidate() method to be called twice to render the arrow series' single point. The two Invalidate() invocations occur regardless of using the Graphics3DDirect2D object. When the line series is added, a single Invalidate() call renders the new line. Nearly all TeeChart properties are the default values. Is there a property value I need to set differently in the Windows Form constructor, after the .Net InitializeComponent method returns?
Attachments
ArrowHeadOnLineSeriesDemo.png
ArrowHeadOnLineSeriesDemo.png (35.07 KiB) Viewed 10814 times

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Best Approach to Draw a Single Arrow Head on a Line Series

Post by Christopher » Thu Apr 20, 2017 12:37 pm

You're welcome.

Well, another alternative is to draw your own arrows - this simple example draws an arrow orientated along the vector to the specified series point (AtPoint) from the previous series point (AtPoint - 1):

Code: Select all

    Line line;
    private void InitializeChart()
    {
      tChart1.Aspect.View3D = false;

      line = new Line(tChart1.Chart);
      line.LinePen.Width = 3;
      line.FillSampleValues();

      tChart1.AfterDraw += TChart1_AfterDraw;
    }

    private void TChart1_AfterDraw(object sender, Graphics3D g)
    {
      Action<int, int> Arrow = (AtPoint, Size) =>
      {
        Point to = new Point(line.CalcXPos(AtPoint), line.CalcYPos(AtPoint));
        Point from = new Point(line.CalcXPos(AtPoint - 1), line.CalcYPos(AtPoint - 1));

        Point difference = new Point(to.X - from.X, to.Y - from.Y);
        double tmp = Math.Sqrt(Math.Pow(difference.X, 2) + Math.Pow(difference.Y, 2));
        PointF vector = new PointF((difference.X / (float)tmp), ((difference.Y / (float)tmp)));
        PointF perpendicular = new PointF(vector.Y, -vector.X);

        Point online = new Point(Utils.Round(to.X - Utils.Round(vector.X * Size)), Utils.Round(to.Y - Utils.Round(vector.Y * Size)));
        Point topleft = new Point(Utils.Round(online.X - Utils.Round(perpendicular.X * Size)), Utils.Round(online.Y - Utils.Round(perpendicular.Y * Size)));
        Point bottomleft = new Point(Utils.Round(online.X + Utils.Round(perpendicular.X * Size)), Utils.Round(online.Y + Utils.Round(perpendicular.Y * Size)));

        g.Line(topleft, to);
        g.Line(bottomleft, to);
      };

      g.Pen.Color = line.Color;
      g.Pen.Width = line.LinePen.Width;
      Arrow(5, 10);
    }
TChart636282886363181283.png
TChart636282886363181283.png (21.94 KiB) Viewed 10808 times
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

br&e
Newbie
Newbie
Posts: 3
Joined: Tue Apr 04, 2017 12:00 am

Re: Best Approach to Draw a Single Arrow Head on a Line Series

Post by br&e » Tue May 02, 2017 9:28 pm

Thank you again, Christopher.

Your first approach is what is in use now. The zooming in and out scaling works best with that. The initial rendering zoom setting is set such that the user will see the double line style in the first example. If the user zooms in for a close up view, the arrow expands to the larger style. It turns out that that automatic response helps our end users the most.

Sincerely,

BR&E

Post Reply