This is a migrated thread and some comments may be shown as answers.

Polyline Tool

13 Answers 282 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Maurício
Top achievements
Rank 1
Maurício asked on 28 Jan 2015, 01:17 PM
Hi

I am building a custom polyline tool, all I want is to add points and have a preview of the line that is going to be added (check the GIF to see what I am trying to achieve).

Here is the tool:
public class PolylineShapeTool : ToolBase, IMouseListener
  {
      private LineSegment _currentLineSegment;
      private PathFigure _currentPathFigure;
      private PathSegmentCollection _currentPathSegmentCollection;
      private RadDiagramShape _currentShape;
 
      public PolylineShapeTool()
          : base("PolylineShapeTool")
      {
      }
 
      private RadDiagram Diagram
      {
          get { return Graph as RadDiagram; }
      }
 
      public bool MouseDown(PointerArgs e)
      {
          return false;
      }
 
      public bool MouseDoubleClick(PointerArgs e)
      {
          return false;
      }
 
      public bool MouseMove(PointerArgs e)
      {
          if (IsActive && _currentShape != null)
          {
              if (_currentLineSegment != null)
              {
                  var rect = CalculateRectFromBasePoint(e.TransformedPoint);
 
                  _currentLineSegment.Point = e.TransformedPoint;
                  _currentShape.Width = rect.Width;
                  _currentShape.Height = rect.Height;
              }
 
              return true;
          }
 
          return false;
      }
 
      public bool MouseUp(PointerArgs e)
      {
          if (IsActive)
          {
              _currentLineSegment = new LineSegment { Point = e.TransformedPoint };
 
              if (_currentPathSegmentCollection == null)
              {
                  _currentPathSegmentCollection = new PathSegmentCollection();
 
                  _currentPathFigure = new PathFigure
                  {
                      StartPoint = e.TransformedPoint,
                      Segments = _currentPathSegmentCollection,
                      IsFilled = false,
                      IsClosed = false
                  };
                   
                  var pathGeometry = new PathGeometry { Figures = new PathFigureCollection { _currentPathFigure } };
 
                  _currentShape = new RadDiagramShape { Geometry = pathGeometry};
 
                  Diagram.AddShape(_currentShape);
              }
 
              _currentPathSegmentCollection.Add(_currentLineSegment);
              _currentPathFigure.Segments = _currentPathSegmentCollection;
 
              return true;
          }
 
          return false;
      }
 
      protected override void OnDeactivated()
      {
          base.OnDeactivated();
 
          _currentShape = null;
          _currentLineSegment = null;
          _currentPathFigure = null;
          _currentPathSegmentCollection = null;
      }
 
      private Rect CalculateRectFromBasePoint(Point transformedPoint)
      {
          var width = Math.Abs(_currentShape.X - transformedPoint.X);
          var height = Math.Abs(_currentShape.Y - transformedPoint.Y);
          var x = Math.Min(_currentShape.X, transformedPoint.X);
          var y = Math.Min(_currentShape.Y, transformedPoint.Y);
 
          return new Rect(x, y, width, height);
      }
  }

The problem is that it isn't working as expected, despite setting the StartPoint of the PathFigure, the first line starts at (0,0).
What do I have to change in this or how could I create such tool?

Why I don't use the Path tool? Because I don't need Bezier curves and there's no preview for the current line.

13 Answers, 1 is accepted

Sort by
0
Pavel R. Pavlov
Telerik team
answered on 02 Feb 2015, 12:02 PM
Hi Maurício,

Currently I am trying to find a better and an easier approach to achieve your requirement. I am researching if you can use any other tools for this purpose. I will write back if I find something. 

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 02 Feb 2015, 12:07 PM
Cool!!

Thank you Pavel!
0
Accepted
Pavel R. Pavlov
Telerik team
answered on 02 Feb 2015, 03:35 PM
Hi Maurício,

I managed to achieve your requirement by creating a fully customized tool. The approach that I used follows these steps:

- Subscribe to the MouseDown, MouseMove and KeyDown events
- On MouseDown I create a RadDiagramConnection and on MouseMove I update the EndPoint property of the connection
- The KeyDown event serves to complete the shape that you have created (use Enter Key) 
- When the custom tool is Deactivated I remove the connection and create a RadDiagramShape with the same Geometry and Position

I believe this achieves your requirement. One behavior that is not addressed in the attached project is that the created shape is only 1 pixel in width. This means that you need to click directly on the shape in order to select it or mode it around. There is no login in the RadDigram to select shapes that are in some radius around the click position. You can overcome this behavior by creating custom HitTestService. In that servie you will be able to check if there are any shapes near the click position and return them.

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 02 Feb 2015, 04:16 PM
Yes! It works just fine, the way I needed. 

I will create my own HitTestSv for the selection. Yet I would like to know whats the use of the Telerik.Windows.Diagrams.Core.DiagramConstants.SelectionHitTestRadius property?

Thank you very much for your support Pavel!!
0
Pavel R. Pavlov
Telerik team
answered on 03 Feb 2015, 01:10 PM
Hello,

That property is respected only for the RadDiagramConnections. By design the connections are 1px in width which makes their selection hard. This is why we created that constat. But in the current implementation of the default HitTestService we do not respect the shapes of the diagram. By design the shapes are not 1px in width and this is why we filter the results and take the items that implement the  IConnection interface.

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 03 Feb 2015, 01:20 PM
Ah ok! Thank you for the explanation Pavel.
0
Maurício
Top achievements
Rank 1
answered on 10 Feb 2015, 12:11 PM
Hello

I have found some flaws in our approach to create a polyline tool that I am not being able to find a way to fix it.

Situation 1: When you create a straight line, it moves the second point a few pixels to the right.

Situation 2: Anything that you draw will slightly move from its original position.

I've attached a GIF where you'll be able to easily comprehend what are the situations I'm talking about.

I already checked the final points before the shape is added to the diagram and everything seems fine. This doesn't happen to the original PathTool.

Thankss
0
Pavel R. Pavlov
Telerik team
answered on 12 Feb 2015, 12:25 PM
Hi Maurício,

We were able to address the reported issues regarding the custom tool.

First let me try to explain why this was happening. The reason behind the issues was that I did not respect the actual size of the generated geometry. Since you will need to create shapes that are 1 pixel in width or height you need to set the minimum allowed size of the shapes to be 1 pixel. 

This can be done by setting the MinHeight and MinWidth properties of the shapes to 1. Furthermore you need to set two of the constants of the RadDiagram to 1. These are the MinimumShapeSize and MinimumAdornerSize. These constants will allow you to resize the shapes to 1 pixel.

This is implemented in the attached project. Please take a look at it and let me know if you need any further assistance.

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 12 Feb 2015, 01:06 PM
Hello Pavel,

I've tested your attached project and I also changed the constants and shape style in my own project. The behavior kept the same, it moves after I finish to build the line.
I've added a GIF where I reproduce the situation directly from this last project you've attached.
0
Pavel R. Pavlov
Telerik team
answered on 12 Feb 2015, 02:57 PM
Hi,

In the attached project I also updated the implementation of the PolylineShapeTool class. Have you tried the new implementation? 

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 12 Feb 2015, 04:45 PM
Yes, I have copied all the changes from your project to mine. The GIF I added in the last post was made while I tested your project.

There are two different situations:
Creating a straight line: Click once to set the first point, move down and press Enter to finish. 

Creating a random polyline:
Click in some points and press Enter. The whole shape moves 1px from the position it's supposed to be created.

0
Pavel R. Pavlov
Telerik team
answered on 13 Feb 2015, 02:28 PM
Hello Maurício,

The behavior that is reproduced when you try to draw a straight line was addressed by my previous project. The reason behind it was that I did not consider the size of the shape. This is why you actually set the MinHeight and MinWidth properties along with the DiagramConstants.

The reason behind the second issue is the fact that the geometry of the RadDiagramShape is always drawn in the bounds of the visual object. However the geometry of the RadDiagramConnection does not respect such bounds. This is why you need to compensate the position and the size of the newly created RadDiagramShape with the strokethickness of the RadDiagramConnection.

Check the attached project for more details.

Regards,
Pavel R. Pavlov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Maurício
Top achievements
Rank 1
answered on 13 Feb 2015, 04:47 PM
Hello Pavel,

It works very well!

Thank you so much for your attention and support!!!!!
Tags
Diagram
Asked by
Maurício
Top achievements
Rank 1
Answers by
Pavel R. Pavlov
Telerik team
Maurício
Top achievements
Rank 1
Share this question
or