How can I zoom from years to minutes?

33 posts, 0 answers
  1. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 21 Feb 2018 Link to this post

    Hello everyone! I need zoom from years to months, months to days, days to hours, hours to minutes. But with this XAML snippet:

    <telerik:RadTimeline PeriodStart="01/01/2010"
                         PeriodEnd="01/01/2015"
                         StartPath="Date"
                         DurationPath="Duration">
        <telerik:RadTimeline.Intervals>
            <telerik:YearInterval/>
            <telerik:MonthInterval/>
            <telerik:DayInterval />
            <telerik:HourInterval/>
            <telerik:MinuteInterval/>
        </telerik:RadTimeline.Intervals>
    </telerik:RadTimeline>

     

    I can't see hours and minutes. Maximum zoom is day. How can I do that, if my maximum period will be 5 years?

     

    Sorry for my poor English. I'm from Russia...

  2. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 21 Feb 2018 Link to this post

    Anyone can help me?
  3. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 23 Feb 2018 Link to this post

    Hello Maxim,

    I already answered your question in the forum. Basically, you can set the MinZoomRange property of the RadTimeline control. This will allow you to avoid the zooming restriction. If you have further questions please let me know.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  4. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 23 Feb 2018 in reply to Martin Ivanov Link to this post

    Exactly what is needed! Thanks!

    I still have several questions:

    1. How do I configure MinZoom so that with a minimal approximation I can see 3 days, as in the picture that I attached? 

    2. The RadTimeLine is displaying hours in 12-hour format. I need change this in 24-hour format, but I don't know how to do that?

  5. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 23 Feb 2018 in reply to Максим Link to this post

    3. I would not use the slider, but scroll through the RadTimeLine by holding down the left mouse button and moving the mouse. But I can not understand how to programmatically manage the slider
  6. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 26 Feb 2018 Link to this post

    Hello Maxim,

    To configure the min zoom to show a minimal range of 3 days you can set the property to a TimeSpan of 3 days. Here is an example:
    this.timeline.MinZoomRange = TimeSpan.FromDays(3);

    To see how to change the display format you can check the Formatter Provider article.

    To scroll programmatically you can use the VisiblePeriodStart and VisiblePeriodEnd properties of RadTimeline.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  7. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 03 Mar 2018 in reply to Martin Ivanov Link to this post

    I have taught my RadTimeLine scroll by holding down the left mouse button and moving that. I have done it by this code:

    private void TimeLine_MouseMove(object sender, MouseEventArgs e)
    {
        var control = (Control)sender;
     
        if(e.LeftButton == MouseButtonState.Pressed)
        {
            var currentMousePos = e.GetPosition(control);
            var deltaX = (int)(currentMousePos.X - oldMousePos.X);
             
            TimeSpan timeInterval = TimeLine.VisiblePeriodEnd - TimeLine.VisiblePeriodStart;
            TimeSpan deltaTime;
            switch(TimeLine.CurrentItemInterval.MinimumPeriodLength.TotalHours)
            {
                // When we see only days
                case 24: deltaTime = new TimeSpan(0, deltaX, 0, 0); break;
     
                // When we see only hours
                case 1: deltaTime = new TimeSpan(0, 0, deltaX, 0); break;
                 
                // When we see only months
                default: deltaTime = new TimeSpan(deltaX, 0, 0, 0); break;
            }
     
            if(deltaX >= 0)
            {
                TimeLine.VisiblePeriodEnd += deltaTime;
                TimeLine.VisiblePeriodStart = TimeLine.VisiblePeriodEnd - timeInterval;
            }
            else
            {
                TimeLine.VisiblePeriodStart += deltaTime;
                TimeLine.VisiblePeriodEnd = TimeLine.VisiblePeriodStart + timeInterval;
            }
        }
     
        oldMousePos = e.GetPosition(control);
    }

    But it seems for me, that this code is very difficult. Anyone knows how to fix that?

    I still have a question:

    How can I animate Line Items in RadTimeLine? For example, I want to animation moving my line items. 

  8. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 06 Mar 2018 Link to this post

    Hello Maxim,

    I am not sure what you mean by that the code is very difficult. Can you clarify this? The only thing I noticed that could be improved is the "deltaTime" calculation. Instead of using the CurrentItemInterval and manually decide what TimeSpan to use, you can try the ConvertPointToDateTime() method of RadTimeline. This way you can use the current and the previous mouse position to calculate the delta.

    As for the moving items animation you can use the WPF animation support and animate the start time and duration properties of the timeline item models.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  9. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 07 Mar 2018 in reply to Martin Ivanov Link to this post


    I am not sure what you mean by that the code is very difficult. Can you clarify this? The only thing I noticed that could be improved is the "deltaTime" calculation. Instead of using the CurrentItemInterval and manually decide what TimeSpan to use, you can try the ConvertPointToDateTime() method of RadTimeline. This way you can use the current and the previous mouse position to calculate the delta.

    You made my code easier. Thanks. Here is:

    private void TimeLine_MouseMove(object sender, MouseEventArgs e)
    {
        var control = (Control)sender;
     
        if(e.LeftButton == MouseButtonState.Pressed)
        {
            var currentMousePos = e.GetPosition(control);
     
            DateTime currentDate = TimeLine.ConvertPointToDateTime(currentMousePos);
            DateTime oldDate = TimeLine.ConvertPointToDateTime(oldMousePos);
     
            TimeSpan deltaTime = (currentDate - oldDate);
            TimeSpan timeInterval = TimeLine.VisiblePeriodEnd - TimeLine.VisiblePeriodStart;
            if(deltaTime >= TimeSpan.Zero)
            {
                TimeLine.VisiblePeriodEnd += deltaTime;
                TimeLine.VisiblePeriodStart = TimeLine.VisiblePeriodEnd - timeInterval;
            }
            else
            {
                TimeLine.VisiblePeriodStart += deltaTime;
                TimeLine.VisiblePeriodEnd = TimeLine.VisiblePeriodStart + timeInterval;
            }
        }
         
        oldMousePos = e.GetPosition(control);
    }

     

     

    As for the moving items animation you can use the WPF animation support and animate the start time and duration properties of the timeline item models.

    I'll try to explain to you what I want to do. For example, I have two time item, as in image #1.

    Suppose, I want to add new time item on the 8th day, which have 1:12:00:00 duration.

    By default, the new item added like in image #2. it will overlap the item which name is Order 1. 

    I want to avoid this behavior. I want to move intersection time items. It is shown in image #3.

    I wrote a complex recursive algorithm for moving time items, if it needed. 

    Now, I want to animate my moving behavior, but it is in ViewModel, where I can't apply animation, because my ViewModel does not know anything about View.

    Any idea?:)

    Sorry for my English:(

     

  10. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 08 Mar 2018 Link to this post

    Hello Maxim,

    The animations are responsibility of the view so it won't be very straightforward to start one from the view model. However, there are two approaches that I could suggest you to try.
    • The first approach is to define an event in the view model and subscribe to it in the view code (code-behind). The event can be raised when you request position change. Then you can animate the Position property using the WPF animation support.
    • The other approach would be to use a DispatcherTimer. You can define a filed of type DispatcherTimer in the viewmodel, and when you add a new item, you can start the timer. Than in its Tick event handler update the Position of each model. In this case you will need to update the Position on portions. For example, if you want to update the Position of an item from 8 to 10 o'clock, you can do it on 4 different portions. Each tick of the timer could update the item with 30 minutes. This item will go from 8:00 to 8:30, 9:00, 9:30, 10:00. Of course this won't be very smooth animation so you can consider adding smaller step. For example, one minute or 10 minutes or something like this.
    I hope this helps.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  11. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 09 Mar 2018 in reply to Martin Ivanov Link to this post

    The first approach is to define an event in the view model and subscribe to it in the view code (code-behind). The event can be raised when you request position change. Then you can animate the Position property using the WPF animation support.

    I prefer this option. But I can not understand, what do you mean by the property Position? Time Item has only duration and datestart. What do I sent to the event? How does View knows what the time item changed?

  12. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 09 Mar 2018 Link to this post

    Hello Maxim,

    I mislead you with the Position property. With Position I meant the start date + the duration. The event can send the model instance of the timeline time and the target position (start date + duration) for example. In the event handler you can start animating the start date + the duration until they get to the final position.

    However, in order to use the native animations support the properties that will be animated should be dependency properties. In my opinion the approach with the DispatcherTimer would be easier to implement.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  13. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 09 Mar 2018 Link to this post

    The event can send the model instance of the timeline time and the target position (start date + duration) for example. In the event handler you can start animating the start date + the duration until they get to the final position.

    Ok, I create an event

    public event Action<TimeBlock, Order> UpdateOrderPeriod;

    where the Order is my Model. Do you think it's wise to let the View knows about the Model? The Order:

    class Order
    {
        public string Name { get; set; }
        public TimeBlock Period { get; set; }
        //anything else
        ...
    }

    and how can I apply native animation to the Period property in the event handler? It should be Dependency property. But I don't want to implement dependency property in the Model. That's bullshit.

    In my opinion the approach with the DispatcherTimer would be easier to implement.

    Could you set an example? 

     

  14. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 09 Mar 2018 in reply to Максим Link to this post

    Here is my code to added the new item:

    private void AddOrderViewModel_AddOrderRequest(Order newOrder)
    {
        // Gets all orders, which the period intersects the period of the new order
        var orders = (from order in Orders
                      where order.Spindle.Id == newOrder.Spindle.Id && newOrder.Period.OverlapsWith(order.Period)
                      select order).ToList();
     
        // Find the place where we insert the new order
        FindNewOrderPeriod(orders, newOrder);
     
        // Gets all intersect orders and future visible period
        var intersectOrder = new List<OrderItemViewModel>();
        var visiblePeriod = new TimeRange(newOrder.Period);
        ComputeIntersectOrder(visiblePeriod, CheckSpindle, intersectOrder);
     
        // Sort all intersect order by period
        intersectOrder.Sort((order1, order2) => order2.Period.CompareTo(order1.Period, new TimePeriodEndComparer()));
     
        // Move the intersect orders   
        // Here I would like to animation
        TimeSpan timeOffset = newOrder.Period.Duration;
        foreach (var order in intersectOrder)
        {
            order.Period.Move(newOrder.Period.End - order.Period.End - timeOffset);
            timeOffset += order.Period.Duration;
        }          
     
        // Update visible period
        UpdateVisiblePeriod(visiblePeriod);
     
        // Add new order
        Orders.Add(newOrder);
    }

     

    How do I use a DispatcherTimer, which you suggested?

  15. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 09 Mar 2018 Link to this post

    Hello Maxim,

    Indeed, adding dependency properties in the model is not a good idea. In general implementing an animation in the viewmodel won't come with a pretty solution. I attached a small example showing my idea with the DispatcherTimer. I hope it helps.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  16. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 10 Mar 2018 in reply to Martin Ivanov Link to this post

    I have done it. Thanks. But i don't like that animation occurs in the VM. Because the animation refers to the View.

    And how to make sure that when playing the animation, the time items don't overlap with each other, like the gif? 

  17. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 11 Mar 2018 Link to this post

    I have a question. How do I know when a time item is selected in his template?

    I created a UserControl like this:

    <Border Style="{DynamicResource BorderStyle}">
        <TextBlock Style="{DynamicResource TextBlockStyle}"/>
    </Border>

     

    and I use it in my TimeLineItemTemplate:

    <DataTemplate x:Key="TimelineItemTemplate">
        <!-- There is my UserControl -->
        <local:TimeItem Height="60"/>
    </DataTemplate>

    For example, I want to change the Background property in the BorderStyle, and change the Foreground in the TextBlockStyle, when the timeline item is selected, but I can't. How can I do that?

     

  18. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 11 Mar 2018 Link to this post

    How can I check whether the RadTimeLine got or lost focus? IsKeyboardFocusWithinChanged event is not occurs...
  19. Stefan
    Admin
    Stefan avatar
    1073 posts

    Posted 14 Mar 2018 Link to this post

    Hello Maxim,

    The focus events of RadTimeLine are not fired as when you click on the control, some other visual element (interval, border) intercepts the mouse/keyboard and receives the focus. What might be a possible solution would be to force the focus to be on control level by calling the Focus method of RadTimeLine. Would such an approach be working for you? Also, can you please clarify the need to use the focus events?

    Regards,
    Stefan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  20. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 19 Mar 2018 in reply to Stefan Link to this post

    Also, can you please clarify the need to use the focus events?

    Of course! I enable a selection mode in my RadTimeLine. And I want reset a selected timeline item, when I switch to another control in my window. And I don't want to do that in my ViewModel, because I think the ViewModel doesn't know anything about the View.

  21. Stefan
    Admin
    Stefan avatar
    1073 posts

    Posted 21 Mar 2018 Link to this post

    Hello Maxim,

    Thank you for the clarification.

    Indeed, the focus events of the control could be used in such manner. Would forcing the focus on control level by calling the RadTimeLine.Focus() method be a feasible solution for you?

    Regards,
    Stefan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  22. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 26 Mar 2018 in reply to Stefan Link to this post


    Indeed, the focus events of the control could be used in such manner. Would forcing the focus on control level by calling the RadTimeLine.Focus() method be a feasible solution for you? 

    Sorry, but I don't understand you. I don't know much English. You meant to call the method RadTimeLine.Focus() straight?

    And how can I control overlapping my time item? They overlap each other, not as I want. How to get to Panel.ZIndex from TimeItem?

  23. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 26 Mar 2018 Link to this post

    I have one more question. Do I force RadTimeLine.DurationPath to use a property from a VM with type Int32, denoting minutes? Not TimeSpan
  24. Stefan
    Admin
    Stefan avatar
    1073 posts

    Posted 28 Mar 2018 Link to this post

    Hello Maxim,

    Indeed, forcing the focus to be on RadTimeline level can be achieved by calling the RadTimeline.Focus() method.

    In order to avoid the overlapping, you can control the vertical position of the items. This topic is discussed in greater detail in the Vertical Position of the RadTimeline Items help article. Can you please take a look at it?

    As for the DurationPath property, it is of string type. Binding it to an int property would not be possible.

    I would also like to clarify, that we are constantly trying to keep our support communication consistent. Having in mind that these topics differentiate from the initial one of this thread, I would kindly ask you to open a new thread if further assistance regarding this questions arises.

    Thank you in advance for your cooperation.

    Regards,
    Stefan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  25. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 29 Mar 2018 in reply to Stefan Link to this post


    Indeed, forcing the focus to be on RadTimeline level can be achieved by calling the RadTimeline.Focus() method. 

    Ok, Thanks

     

    In order to avoid the overlapping, you can control the vertical position of the items. This topic is discussed in greater detail in the Vertical Position of the RadTimeline Items help article. Can you please take a look at it?

    I didn't mean that. I have time items, which aligned in one line. And I move them animatedly. Sometimes I see, that my time items overrlap each other not as I would like. I want control this overlap processing, but I can't, because I don't find Panel.ZIndex property.

     

    As for the DurationPath property, it is of string type. Binding it to an int property would not be possible.

    I know that the DurationPath property has string type. But this string means name of the property in a ViewModel, the type of which is TimeSpan. In my ViewModel, this property has int type means minutes. How can I binding that to RadTimeLine, without DTO?

     

    I would also like to clarify, that we are constantly trying to keep our support communication consistent. Having in mind that these topics differentiate from the initial one of this thread, I would kindly ask you to open a new thread if further assistance regarding this questions arises.

    Ok:)

  26. Stefan
    Admin
    Stefan avatar
    1073 posts

    Posted 02 Apr 2018 Link to this post

    Hi Maxim,

    Thank you for the clarification.

    By default, the items in the panel are stacked in the order they are added in it. In order to manipulate this order, you can use the approach demonstrated in the Overlapping items forum thread.

    Since you are not convenient of defining an additional string property for the DurationPath one, you can utilize an IValueConverter and apply the needed conversion through it.

    Hope this helps.

    Regards,
    Stefan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  27. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 03 Apr 2018 in reply to Stefan Link to this post


    By default, the items in the panel are stacked in the order they are added in it. In order to manipulate this order, you can use the approach demonstrated in the Overlapping items forum thread.

    Exactly what is needed! Thanks!


    Since you are not convenient of defining an additional string property for the DurationPath one, you can utilize an IValueConverter and apply the needed conversion through it.

    This will not work, because I should set the name of the property the type of witch is TimeSpan! How should such a converter look like? That I did not quite understand you

  28. Stefan
    Admin
    Stefan avatar
    1073 posts

    Posted 06 Apr 2018 Link to this post

    Hi Maxim,

    Indeed, internally the control fetches the property to which the DurationPath points and converts it to a TimeSpan type. If it is not a TimeSpan type, the TimeSpan.Zero value is used. So, using an int value for the DurationPath would not be possible. Please, excuse me for misleading you.

    Regards,
    Stefan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  29. Максим
    Максим avatar
    21 posts
    Member since:
    Feb 2018

    Posted 07 Apr 2018 in reply to Stefan Link to this post

    Please, excuse me for misleading you.

    That's all right. Is it planned in the future to make a DurationPath property with a TimeSpan type, not a string? So that I can apply the converter

  30. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2361 posts

    Posted 10 Apr 2018 Link to this post

    Привет Максим,

    The DurationPath, and also the StartPath, GroupPath, etc. (more or less all properties that ends with "Path"),  work with a string. What those properties do is that they are trying to find a property with the same name as the path's value in the data item business class. Let's take for example the following business model that describes the timeline items.
    public class TimelineItemInfo
    {
        public DateTime MyStartDateProperty { get; set; }
        public TimeSpan MyDurationProperty { get; set; }
    }
    In this case you would like to use the properties to define the start of the item and its duration. To tell the timeline control which properties should be used, you will need to set the DurationPath and the StartPath to string values that matches the names of the properties in the business object. For example:
    <telerik:RadTimeline StartPath="MyStartDateProperty " DurationPath="MyDurationProperty" />

    I went through the forum and I see that you understand this concept but I just wanted to have it summarized somewhere in this thread.

    Changing this concept and allow to set binding to the property would be a breaking change so currently, we don't plan to alter this behavior. However, in your case (with the Int32 duration) I could suggest an approach with an additional property. The property will be of type TimeSpan and it will have a getter only. In the getter you can return a new TimeSpan instance based on the original Int32 property. Here is an example of this model:
    public class TimelineItemInfo
    {
        public DateTime MyStartDateProperty { get; set; }
         
        private int myDurationProperty;
        public int MyDurationProperty
        {
            get
            {
                return this.myDurationProperty;
            }      
            set
            {
                this.myDurationProperty = value;
                 
                //If you want to have a runtime change of the duration you can implement the INotifyPropertyChanged interface and raise the PropertyChanged event for the TimeSpan property when you change the int32 duration.
                RaisePropertyChanged("TimeSpanDurationProperty");
            }
        }
         
        public TimeSpan TimeSpanDurationProperty
        {
            get
            {
                return TimeSpan.FromMinutes(this.myDurationProperty);
            }
        }
    }

    <telerik:RadTimeline StartPath="MyStartDateProperty " DurationPath="TimeSpanDurationProperty" />

    I hope this helps.

    Regards,
    Martin Ivanov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Back to Top