Position of shape's text

18 posts, 0 answers
  1. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 11 Sep Link to this post

    I'd like to position a Shape's text outside of the shape itself. Can this be accomplished?

    Initially I thought I might have to have a separate Label shape associated with every shape, to achieve this. I also need to apply alignment, e.g. left, center, right, so perhaps a separate Label shape would be better, then group it with its shape (as they are inseparable).

     

    Example

     

  2. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 12 Sep Link to this post

    Hello Tino,

    To achieve this you can create a custom shape, add a second text element and set its position offset:
    class MyDiagramShape : RadDiagramShape
    {
        LightVisualElement label = new LightVisualElement();
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
            label.Text = "Test Label";
            label.PositionOffset = new SizeF(-100, 0);
            this.DiagramShapeElement.Children.Add(label);
        }
    }

    I hope this will be useful. Let me know if you have additional questions.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 12 Sep in reply to Dimitar Link to this post

    Sounds like a great idea. I will experiment with this and see if it's a good solution for me.

    Would the shape bounds then encompass the label as well?

  4. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 13 Sep Link to this post

    Hi Tino,

    The text will be outside of the shape bounds but will be moved with the shape. I have attached a small video that shows the result.

    Should you have any other questions do not hesitate to ask. 

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 14 Sep in reply to Dimitar Link to this post

    What I meant is whether the shape's bounding box are considered to encompass both shape and label.

    Anyway I have tried this and it looks like a possibility. It seems there is text alignment, which I need.

    Further, will I able to do the following:

    1. Allow in-place editing of this additional text

    2. Set the bounds for the text (currently I'm seeing long text cut off). Do I use the TextBlock property?

    3. Display an outline to show where the bounds of the text are

     

    Thanks

  6. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 14 Sep Link to this post

    Hi Tino,

    You can use the following approach to achieve the desired layout:
    class MyDiagramShape : RadDiagramShape
    {
        RadTextBox label = new RadTextBox();
        RadHostItem hostItem;
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
     
             hostItem = new RadHostItem(label);
     
            hostItem.StretchVertically = false;
            hostItem.ShouldHandleMouseInput = true;
            hostItem.NotifyParentOnMouseInput = false;
            hostItem.Text = "Test Label";       
           
            this.Children.Add(hostItem);
          
        }
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            var result = base.ArrangeOverride(finalSize);
            var recatangle = new RectangleF(finalSize.Width / 2, 0,  (finalSize.Width / 2), finalSize.Height);
            var rectangle2 = new RectangleF(0, 0, finalSize.Width / 2, 25);
     
            this.hostItem.Arrange(rectangle2);
            this.DiagramShapeElement.Arrange(recatangle);
     
            return result;
        }
    }

    Should you have any other questions do not hesitate to ask.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  7. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 14 Sep in reply to Dimitar Link to this post

    Thanks for the extra option. I've tried it, but at the moment I'm going with the other method. Having the TextBox always active and with a border (although I'm sure I could customize that) wasn't quite what I wanted. I need behaviour similar to the standard shape's text editing.

    You've also answered another question I was going to ask, which is how to have compound shapes. Now I know the technique for doing that. For instance I need to display radio buttons, as a single group (they don't have to be functional, just visual). Unless there's another way, I'll just add circle objects and offset them from each other.

     

  8. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 14 Sep in reply to Tino Link to this post

    Actually no that would be done in my ElementShape derived classes CreateGeometry() ?
  9. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 14 Sep in reply to Tino Link to this post

    Correction CreatePath()
  10. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 18 Sep Link to this post

    Hello Tino,

    The approach from my previous post shows how you can add the text box within the bounds of the shape as well. And this will work with a label element as well. 

    This approach is suitable for adding and arranging any controls or elements. If you want you can add another LightVisualElement that has its own shape. For example:
    class MyDiagramShape : RadDiagramShape
    {
     
        LightVisualButtonElement secondShape = new LightVisualButtonElement();
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
     
            secondShape.ShouldHandleMouseInput = true;
            secondShape.NotifyParentOnMouseInput = false;
            secondShape.Text = "Test Label";
            secondShape.DrawFill = true;
            secondShape.BackColor = System.Drawing.Color.Red;
     
            StarShape starShape = new StarShape();
            starShape.Arms = 12;
            starShape.InnerRadiusRatio = .5f;
     
            secondShape.Shape = starShape;
     
            this.Children.Add(secondShape);
          
        }
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            var result = base.ArrangeOverride(finalSize);
            var recatangle = new RectangleF(finalSize.Width / 2, 0,  (finalSize.Width / 2), finalSize.Height);
            var rectangle2 = new RectangleF(0, 0, finalSize.Width / 2, finalSize.Height);
     
            this.secondShape.Arrange(rectangle2);
            this.DiagramShapeElement.Arrange(recatangle);
     
            return result;
        }
         
    }

    Please let me know if there is something else I can help you with. 

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  11. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 18 Sep in reply to Dimitar Link to this post

    It seems there's more than one way to do this

    What I'm trying to achieve overall, is a kind of UI form designer.

    I will have checkbox, radio button, combobox, text field, table, etc.

    I thought the way was to have one ElementShape-derived class for each of my element types, and override CreatePath. This is working reasonably well. Is this a reasonable approach? It seems to be recommended in the Custom Shapes docs.

  12. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 19 Sep Link to this post

    Hi Tino,

    If you want to add controls and the user should be able to interact with them, use my approach and add elements. If you want to have only shapes that can be drawn by using a path, use the element shape. However please note that each element can have one shape only. Both approaches are valid and you should choose the one more suitable for your case.

    Should you have any other questions do not hesitate to ask.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  13. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 21 Sep Link to this post

    Thanks I will consider the options.
  14. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 21 Sep Link to this post

    Also, if you could please explain how to use RadHostItem , CreateChildElements, ArrangeOverride and LightVisualElement to get the desired result, or point to some docs or sample code, that would be great. I don't seem to have seem seen a good explanation combining all of these. Tomorrow I will try an approach using these.
  15. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 22 Sep Link to this post

    So I've put together the following based on various suggestions. This is pretty much the same result as I had with the CreatePath technique, but now I actually have a filled triangle in my sample 'dropdown' shape. I also have an offset Label.

    A few things though:

    1. I can't drag the shape by the text
    2. I'm not sure how to get a border around my rectangle; I set 'DrawBorder' to true and got a rounded rectangle border

    Otherwise, this seems ok. Please comment on the code below.

     

    using System.Drawing;
    using System.Drawing.Drawing2D;
    using Telerik.WinControls;
    using Telerik.WinControls.UI;
     
    namespace TestDiagram
    {
        class DropdownShape : RadDiagramShape
        {
     
            LightVisualElement rectangle = new LightVisualElement();
            LightVisualElement triangle = new LightVisualElement();
            LightVisualElement label = new LightVisualElement();
     
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
     
                this.Size = new Size(150, 15);
    //            this.DrawBorder = true;
     
                label.Text = "Test Label";
                label.PositionOffset = new Size(-120, 0);
     
                rectangle.ShouldHandleMouseInput = true;
                rectangle.NotifyParentOnMouseInput = false;
     
                rectangle.DrawFill = true;
                rectangle.BackColor = Color.LightGray;
     
                triangle.DrawFill = true;
                triangle.BackColor = Color.Black;
     
                var rectangleShape = new CustomShape();
                rectangleShape.CreateRectangleShape(0, 0, 150, 15);
     
                var triangleShape = new TriangleShape();
     
                rectangle.Shape = rectangleShape;
                triangle.Shape = triangleShape;
     
                this.Children.Add(rectangle);
                this.Children.Add(triangle);
                this.Children.Add(label);
            }
     
            protected override SizeF ArrangeOverride(SizeF finalSize)
            {
                var result = base.ArrangeOverride(finalSize);
                var rectTriangle = new RectangleF(finalSize.Width - 10, finalSize.Height / 2 -3 , 15, 15);
                var rectRectangle = new RectangleF(0, 0, finalSize.Width, finalSize.Height);
                var rectMain = new RectangleF(0, 0, finalSize.Width, finalSize.Height);
     
                this.rectangle.Arrange(rectRectangle);
                this.triangle.Arrange(rectTriangle);
                this.DiagramShapeElement.Arrange(rectMain);
     
                return result;
            }
     
        }
     
        class TriangleShape : ElementShape
        {
            public override GraphicsPath CreatePath(Rectangle bounds)
            {
                var path = new GraphicsPath();
     
                Point[] points =
                {
                    new Point( bounds.X, bounds.Y ),
                    new Point( bounds.X + 6, bounds.Y),
                    new Point( bounds.X + 3, bounds.Y + 6)
                };
     
                path.AddPolygon(points);
     
                return path;
            }
        }
    }

     

     

  16. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017

    Posted 22 Sep in reply to Tino Link to this post

    And also..

     

    using Telerik.Windows.Diagrams.Core;
     
    namespace TestDiagram
    {
        public partial class RadForm1 : Telerik.WinControls.UI.RadForm
        {
            public RadForm1()
            {
                InitializeComponent();
     
                var dropdownShape = new DropdownShape()
                {
                    Position = new Point(100, 100)
                };
                radDiagram1.AddShape(dropdownShape);
            }
        }
    }
  17. Tino
    Tino avatar
    37 posts
    Member since:
    Jul 2017
  18. Dimitar
    Admin
    Dimitar avatar
    1871 posts

    Posted 25 Sep Link to this post

    Hello Tino,

    We can continue to discuss this in the other thread and I will close this one for now.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top