Reusability of diagram adorners

9 posts, 0 answers
  1. Clint Singer
    Clint Singer avatar
    133 posts
    Member since:
    Oct 2012

    Posted 15 Feb 2012 Link to this post

    Hi,

    I was wondering about the reusability of the controls and adorners that have been introduced with the diagramming.  Specifically I have a scenario where I need to draw shapes on a RadMap and use that information to determine the area and shape vertex points of the shape. 

    For example I would like to draw a rectangle on the map, resize it with the handles and rotate it to fit a specific area.  Then I would take the points of the four corners and translate them to geographic cooridinates.

    The diagramming has exactly the behavior that I am looking for for this scenario.

    Cheers,
    Clint
  2. Miro Miroslavov
    Admin
    Miro Miroslavov avatar
    588 posts

    Posted 16 Feb 2012 Link to this post

    Hi,

     The RadDiagram itself is designed to be really light-weight control (very skim visual tree) - so you could use it directly over the map.
    I managed to do exactly what you need with this peace of code.

    <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadMap x:Name="radMap" />
        <telerik:RadDiagram Background="{x:Null}" IsBackgroundSurfaceVisible="False" IsSnapEnabled="False">
            <telerik:RadDiagramShape Geometry="{telerik:CommonShape ShapeType=RectangleShape}" Background="Transparent"
                    BorderBrush="Red" BorderThickness="2" />
            <telerik:RadDiagramShape Geometry="{telerik:CommonShape ShapeType=RectangleShape}" Background="Transparent"
                    BorderBrush="Red" BorderThickness="2" />
        </telerik:RadDiagram>
    </Grid>

    You can also see the attached image with the result of the code. Note that you can also do lots more with the different types of shapes and connections.
    Hope this helps. Kind regards,
    Miro Miroslavov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. DevCraft banner
  4. Clint Singer
    Clint Singer avatar
    133 posts
    Member since:
    Oct 2012

    Posted 16 Feb 2012 Link to this post

    Hi,

    That looks like the right direction and I will have to give it a try.  I noticed that RadDiagram is sitting on top of the RadMap so obviously I would have do some work to attach the panning and zooming (assuming that is something the RadDiagram supports) so that they can stay in sync.

    Cheers,
    Clint
  5. Miro Miroslavov
    Admin
    Miro Miroslavov avatar
    588 posts

    Posted 17 Feb 2012 Link to this post

    Hi,

     Yes Diagram sits on top of the map, so that you should sync them manually, which can be very tricky. Also the diagram can be added to the InformationLayer of the Map, but this also needs a lot of effort to make it work as you expected. Currently we don't have a real sample for integrating both the Map and the Diagram, but we'll definitely work in that direction.
    If we can be of further help on this, please let us know.

    Kind regards,
    Miro Miroslavov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  6. Laszlo
    Laszlo avatar
    6 posts
    Member since:
    Apr 2012

    Posted 01 Apr 2012 Link to this post

    Hi Miro!

    Seems like a bug: When RadDiagram is placed on InformationLayer, the size of bounding box on the selected diagram item is not good, it's about the half of the expected size.

    It would be very useful to combine Diagram with Map. As you said, now we have to handle panning and zooming manually:

    - We have to store items' Locations and Sizes (in km/mile) and update them on every panning and zooming. Subscribing to radMap.ZoomChanging and radMap.PanningFinished only works well if I set radmap.UseSpringAnimations to False. 
    
    - I have to store Location and Size in my custom collection, and update it on diagram_Resize and diagram_Drag
    - How can I set Transparent background to a shape? I mean on User Interface, not code-behind.

    What is the easyest way to add/remove items in expandertoolbox:DiagramToolbox? By default I use featureControls:HierarchicalItemsSourceCollection.

    Thanks
    Laszlo
  7. Miro Miroslavov
    Admin
    Miro Miroslavov avatar
    588 posts

    Posted 03 Apr 2012 Link to this post

    Hello Laszlo,
    • Can you give us some more details on how to reproduce the bug with the shape on the information layer? I'm not sure if I understand you correctly.
    • You're right that it is good to integrate the Map and the Diagram and we're working on such an integration example. (I'll send it to you very soon.)
    • About the transparent background - if you are using the "Settings Pane" that is part of the Features project, than you should manually get the code from there and update this little control so that it has transparent color. (The colors are added in one xaml resource dictionary).
    • And same for the Toolbox. You should manually get the code and update the source so that it has the shapes you need. 
    We understand that this is not very straight forward and we're working on this. With Q2 in a few months, the Features assembly will be part of the distribution and will be easier to modify the Settings Pane, the Toolbox and so forth. 

    All the best,
    Miro Miroslavov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  8. Mark Jakes
    Mark Jakes avatar
    27 posts
    Member since:
    Feb 2010

    Posted 07 Jul 2012 Link to this post

    Hello All

    I have exactly the same scenario.  In our application we use RadMap and have already implemented drawing areas on the map, but I like the new features in Diagramming and we could definately use these features.

    Can you let me know if the pan/zoom was resolved or if there are any workarounds you found?

    Many thanks.

    Mark.
  9. Laszlo
    Laszlo avatar
    6 posts
    Member since:
    Apr 2012

    Posted 07 Jul 2012 Link to this post

    When you save a diagram, the XML contains the location and size of the shapes, but these are in diagram's own coordinate system (pixels), not Lat/Long Locations. I decided to 
    1. create an own list (shapes) where I store the "Map Size" and "Map Location", and 
         a) when I save the diagram, put the "Map Size" and "Map Location" into it
         b) when loading, get "Map Size" and "Map Location", and transform to diagram's coordinate system.
       So I only need to save this XML, not more.
    2. Place diagram on top of RadMap, hook up on some events and move diagram shapes with map
    3. turn on/off diagram.IsHittestVisible, when I want to edit items.
    4. I had to modify the diagram edit panel:
       - hide SIZE and POSITION coordinate input (they were in pixels)
       - Add Transparent background colors to the color selection.

    The result is not perfect but fair enough: when you pan/zoom map, diagram shapes pan/zoom too, but you can notice the redwawings a little bit. 

    My list:

    public class ShapeInfo
    {
        public IShape Shape { get; set; }
        public Location Location { get; set; }
        public Size SizeKm { get; set; }
    }
    List<ShapeInfo> shapes = new List<ShapeInfo>();

    Events:

    _radMap.ZoomChanging += (_radMap_ZoomChanging);
    _radMap.PanningFinished += (_radMap_PanningFinished);
     
    diagram.Resize += (diagram_Resize);
    diagram.Drag += (diagram_Drag);
    diagram.ItemsChanged += (diagram_ItemsChanged);

    void diagram_Drag(object sender, DragRoutedEventArgs e)
    {
        foreach (var shape in e.Items.OfType<RadDiagramShape>())
        {
            var shapeInfo = shapes.SingleOrDefault(s => s.Equals(shape));
            if (shapeInfo != null)
            {
                shapeInfo.Location = Location.GetCoordinates(_radMap, shape.Position);
            }
        }
    }
     
    void diagram_Resize(object sender, ResizeRoutedEventArgs e)
    {
        foreach (var shape in e.Items.OfType<RadDiagramShape>())
        {
            var shapeInfo = shapes.SingleOrDefault(s => s.Equals(shape));
            if (shapeInfo != null)
            {
                var loc = Location.GetCoordinates(_radMap, shape.Position);
                var loc2 = Location.GetCoordinates(_radMap, new Point(shape.Position.X + shape.Width, shape.Position.Y + shape.Height));
                var area = new LocationRect(loc, loc2) { MapControl = _radMap };
                shapeInfo.SizeKm = new Size(area.Width, area.Height);
     
            }
        }
    }
     
    void _radMap_PanningFinished(object sender, RoutedEventArgs e)
    {
        SetDiagramShapesPositions();
    }
     
    void _radMap_ZoomChanging(object sender, Telerik.Windows.Controls.Map.PropertyChangingEventArgs e)
    {
        SetDiagramShapesPositions();
    }

    Loading and Saving:
    I has some problems with saving Connection Lines, so they are disabled now.

    string saveText = null;
    private void LoadButton_Click(object sender, RoutedEventArgs e)
    {
        if (saveText != null)
        {
            diagram.Clear();
            shapes.Clear();
            diagram.Load(saveText);
     
            foreach (var shape in diagram.Shapes)
            {
                shapes.Add(new ShapeInfo()
                {
                    Shape = shape,
                    Location = new Location(shape.Position.Y, shape.Position.X),
                    SizeKm = new Size(shape.Width, shape.Height)
                });
            }
            SetDiagramShapesPositions();
        }
    }
     
    private void SaveButton_Click(object sender, RoutedEventArgs e)
    {
     
        foreach (var shape in diagram.Shapes)
        {
            var dShape = shape as RadDiagramShape;
            if (dShape != null)
            {
                var loc = Location.GetCoordinates(_radMap, dShape.Position);
                var loc2 = Location.GetCoordinates(_radMap, new Point(dShape.Position.X + dShape.ActualWidth, dShape.Position.Y + dShape.ActualHeight));
                var area = new LocationRect(loc, loc2) { MapControl = _radMap };
                var size = new Size(area.Width, area.Height);
     
                dShape.Width = size.Width;
                dShape.Height = size.Height;
     
                dShape.Position = new Point(loc.Longitude, loc.Latitude);
            }
            var dConn = shape as RadDiagramConnection;
            if (dConn != null && dConn.Source == null)
            {
                var loc = Location.GetCoordinates(_radMap, dConn.EndPoint);
                dConn.EndPoint = new Point(loc.Longitude, loc.Latitude);
            }
            if (dConn != null && dConn.Target == null)
            {
                var loc = Location.GetCoordinates(_radMap, dConn.StartPoint);
            }
            shapes.Add(new ShapeInfo()
            {
                Shape = shape,
                Location = Location.GetCoordinates(_radMap, shape.Position),
                SizeKm = new Size(shape.Width, shape.Height)
            });
        }
        saveText = diagram.Save();
        LoadButton_Click(null, null);
    }

    Setting positions:

    private void SetDiagramShapesPositions()
    {
     
        foreach (var shape in diagram.Shapes)
        {
            var shapeInfo = shapes.SingleOrDefault(s => s.Shape.Id == shape.Id);
            var dShape = shape as RadDiagramShape;
            if (shapeInfo != null && dShape != null)
            {
                var loc = shapeInfo.Location;
                var pos = loc.GetPoint(_radMap);
     
                var area = new LocationRect(loc.Latitude, loc.Longitude, shapeInfo.SizeKm.Width, shapeInfo.SizeKm.Height) { MapControl = _radMap };
                var posSE = area.Southeast.GetPoint(_radMap);
                var w = Math.Abs(posSE.X - pos.X);
                var h = Math.Abs(posSE.Y - pos.Y);
     
                shape.Width = w;
                shape.Height = h;
     
                shape.Position = pos;
            }
            var dConn = shape as RadDiagramConnection;
            if (shapeInfo != null && dConn != null && dConn.Source == null)
            {
                dConn.EndPoint = new Location(dConn.EndPoint.Y, dConn.EndPoint.X).GetPoint(_radMap);
            }
            if (shapeInfo != null && dConn != null && dConn.Target == null)
            {
                dConn.StartPoint = new Location(dConn.StartPoint.Y, dConn.StartPoint.X).GetPoint(_radMap);
            }
        }
    }

  10. Mark Jakes
    Mark Jakes avatar
    27 posts
    Member since:
    Feb 2010

    Posted 08 Jul 2012 Link to this post

    Excellent, thanks to Lazlo for sharing.

    I'll give this a try and let you know how I get on.

    Many thanks again

    Mark.
Back to Top
DevCraft banner