B4J Question Prevent panel overlapping in a scheduler with events

Alexander Stolte

Expert
Licensed User
Longtime User
I need a dynamic solution to adjust panels in width and left so that they are displayed without colliding.
In my example i have 4 Appointements, 3 Appointments start at the same time but end at different times. The 4th appointment "Test3" starts after the 2 other appointments, but still collides with the "Test1" appointment. I need a dynamic function that detects this and adjusts the panels to it.
1660424287978.png


My picture was taken with the following code:
B4X:
Private Sub CheckOverlapping(i As Int,xlbl_Appointment As B4XView,Appointment1 As Appointment)
    
    Dim Appointment2 As Appointment = IIf(i > 0,lst_Appointments.Get(i -1),lst_Appointments.Get(i)) 'Get the Appointment that is before Appointment1
    
    Dim Go As Boolean = False 'If Go = True then no more collissions detected
                        
    If CheckKolission(Appointment1,Appointment2) Then
                
        lstCollission.Add(i) 'If the previous appointment conflicts with our appointment, add the index to the list.
    
        If i > 0 Then
            'Checks if the item is already in the list
            Dim Found As Boolean = False
            For Each test As Int In lstCollission
                If test = (i -1) Then Found = True
            Next
            If Found = False Then lstCollission.Add(i-1)
        End If
    
    Else
        Go = True 'no more collissions detected
    End If
                    
    If i = (lst_Appointments.Size -1) Then Go = True 'or the appointment is the last item in the list
                    
    If Go = True Then
                        
                        
        lstCollission.Sort(True)
        'Adjusts the appointments in width and left
        For app2 = 0 To lstCollission.Size -1
            Dim xlbl_Item As B4XView = Root.GetView(lstCollission.Get(app2))
                        
            Dim ListSize As Int = lstCollission.Size
                        
            xlbl_Item.Left = (Root.Width/ListSize)*app2
            xlbl_Item.Width = Root.Width/ListSize
                        
        Next
        lstCollission.Clear
    End If
    
End Sub

I have written a 2nd function that looks a bit simpler but still has problems with the right width
1660425025249.png

The function thinks that Test1 was divided by 2 and not by 3, so Test3 is too short.
B4X:
Private Sub CheckOverlapping2(xlbl_Appointment As B4XView,Appointment1 As Appointment)

    Dim Divider As Int = 1
    For test = 0 To lst_Appointments.Size -1
                
        Dim Appointment2 As Appointment = lst_Appointments.Get(test)
                
        If Appointment1.id <> Appointment2.Id And CheckKolission(Appointment1,Appointment2) Then

            Dim Appointment3 As Appointment = IIf((test -1) >= 0,lst_Appointments.Get(test -1),lst_Appointments.Get(test +1))
                        
            If  CheckKolission(Appointment3,Appointment2) = True Then
                Divider = Divider +1
                    
                If  CheckKolission(Appointment3,Appointment1) = False Then
                    LeftPosition = 0
                End If

            End If
                                
        End If
                
    Next
            
    LeftPosition = LeftPosition +1
    If Divider = 0 Or Divider = 1 Then LeftPosition = 0
                        
    xlbl_Appointment.Width = ((Root.Width)/Divider)
    xlbl_Appointment.Left = xlbl_Appointment.Width * LeftPosition
                    
End Sub
 

Attachments

  • DayView Problems.zip
    4.1 KB · Views: 86
Solution
I have attached the code to you.

This morning I made another simpler code but sometimes it left an empty column to the right of the space, so I reworked the algorithm, complicating it a little.
If you have any doubts contact me, if I know the answer I will definitely give it to you

PS. If you want the simplest one, ask for it, with some tricks you could remove the extra column

Star-Dust

Expert
Licensed User
Longtime User
Like what do you get such a thing?

B4X:
    lst_Appointments.Add(CreateAppointment(1,DateUtils.SetDateAndTime(2022,8,12,11,30,0),DateUtils.SetDateAndTime(2022,8,12,14,30,0),"Test1"))
    lst_Appointments.Add(CreateAppointment(3,DateUtils.SetDateAndTime(2022,8,12,11,30,0),DateUtils.SetDateAndTime(2022,8,12,12,30,0),"Test2"))
    lst_Appointments.Add(CreateAppointment(3,DateUtils.SetDateAndTime(2022,8,12,12,30,0),DateUtils.SetDateAndTime(2022,8,12,13,30,0),"Test3"))
    lst_Appointments.Add(CreateAppointment(4,DateUtils.SetDateAndTime(2022,8,12,12,0,0),DateUtils.SetDateAndTime(2022,8,12,13,15,0),"Test4"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,11,30,0),DateUtils.SetDateAndTime(2022,8,12,12,30,0),"Test5"))
 
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,15,00,0),DateUtils.SetDateAndTime(2022,8,12,16,00,0),"Test6"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,15,00,0),DateUtils.SetDateAndTime(2022,8,12,16,00,0),"Test7"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,16,00,0),DateUtils.SetDateAndTime(2022,8,12,17,00,0),"Test7c"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,15,00,0),DateUtils.SetDateAndTime(2022,8,12,18,00,0),"Test8"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,15,00,0),DateUtils.SetDateAndTime(2022,8,12,19,00,0),"Test9"))
    lst_Appointments.Add(CreateAppointment(2,DateUtils.SetDateAndTime(2022,8,12,18,00,0),DateUtils.SetDateAndTime(2022,8,12,19,00,0),"Test10"))

1660464284533.png


1660465975209.png
 
Last edited:
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
Exactly that, are the results I need 👀

Like what do you get such a thing?
I don't really know what you mean by that. But it can happen that a user creates this constellation of appointments. I was made aware that dayview does not cover these cases, so I tried to find a solution.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
Exactly that, are the results I need 👀


I don't really know what you mean by that. But it can happen that a user creates this constellation of appointments. I was made aware that dayview does not cover these cases, so I tried to find a solution.
I wrote a little code this morning before going to sea. Now I'm out because I'm on vacation, in the afternoon I'll try to explain how I got that result automatically
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Longtime User
I wrote a little code this morning before going to sea. Now I'm out because I'm on vacation, in the afternoon I'll try to explain how I got that result automatically
I caught a perfect timing.That would be very nice, I have already invested more than 12 hours in this bug and would be very grateful if this finally works.
Thanks!
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
I have attached the code to you.

This morning I made another simpler code but sometimes it left an empty column to the right of the space, so I reworked the algorithm, complicating it a little.
If you have any doubts contact me, if I know the answer I will definitely give it to you

PS. If you want the simplest one, ask for it, with some tricks you could remove the extra column
 

Attachments

  • DayView Solution2.zip
    3.7 KB · Views: 89
Upvote 1
Solution

Alexander Stolte

Expert
Licensed User
Longtime User
Sorry to bother you again, I just got a constellation from the customer that doesn't work properly and I don't understand why.

Test2 Starts: 11:00 Ends: 11:30
Test1 Starts: 11:30 Ends: 13:30
Test3 Starts: 12:00 Ends: 12:30
Test4 Starts: 12:00 Ends: 12:30
Result:
1660555921533.png

Test1 is not recognized
 

Attachments

  • DayView Solution2.zip
    4.1 KB · Views: 81
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
There is a case that I had not foreseen, that a label did not overlap the second but covered it completely and therefore no corner of the first was inside the second.
I believe this code solves the problem, but must be tested in all cases

1660561753103.png


B4X:
Private Sub CheckExtendibleView(V As VirtualView,ListOfView As List,width As Int, MaxWidth As Int) As Boolean
    Dim B As Boolean = False
    Log(V.Title)
    If v.Right+width>MaxWidth Then Return True
    For Each v2 As VirtualView In ListOfView
        If v2<>v Then
            If (V.Left<v2.Right And V.Top<v2.Top+v2.Height) Then
                If (V.Right+width>v2.Left And V.Top+V.Height>v2.Top) Then B=True
            End If
        End If
    Next
    Return b
End Sub
 

Attachments

  • DayView Solution3.zip
    3.7 KB · Views: 82
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
A tip:
You are sorting the appointments / events in ascending order of the start date / time. This is correct, but to improve readability they should also be sorted by event duration.

To give an example, if it were an SQL table, the search would be: SELECT * FROM Events ORDER BY DateTimeStart, Durate DESC;
 
Upvote 0
Top