You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET实现甘特图条形重叠时PosIndex排序调整问题求解

甘特视图预约条形位置重排实现问题

核心需求

正在开发预约类应用,采用甘特视图可视化预约数据,根据预约起止时间范围绘制对应矩形条形,条形通过PosIndex属性定位(第1行对应PosIndex为0)。
条形位置分配规则:

  • 同一PosIndex下若两个条形存在时间范围重叠,需将重叠条形的PosIndex加1下移1位,同时该位置下方所有条形的PosIndex同步加1下移
  • 代码迭代过程中若检测到同PosIndex的其他重叠(非上方条形挤压导致),重复上述下移操作
  • 同索引下无时间重叠的条形PosIndex保持不变,仅受上方重叠条形挤压时才向下偏移
  • 后续会调整网格与床位行线宽度,适配同一行容纳多个条形的场景

此前尝试使用Rectangle.IntersectsWith方法做相交检测,编写多版排序逻辑,但始终无法正确完成所有条形的位置分配,仍有部分重叠条形未被正确分离。

简化版测试模块代码

Module ttest

    Public Class barAllocations

        Dim lstBars As List(Of barAllocations)
        Public Property barText As String
        Public Property FromTime() As DateTime
        Public Property ToTime() As DateTime
        Public Property PosIndex() As Integer

        Public Sub addAlloBar(ByVal setBarText As String, ByVal FromTime As DateTime, ToTime As DateTime, PosIndex As Integer)

            Dim alloBar As New barAllocations
            alloBar.barText = setBarText
            alloBar.FromTime = FromTime
            alloBar.ToTime = ToTime
            alloBar.PosIndex = PosIndex

            lstBars.Add(alloBar)

        End Sub

        Public Sub sortList()
            Dim prevIndex As Integer
            Dim prevFromDT As DateTime
            Dim prevToDT As DateTime

            For Each bar As barAllocations In lstBars

                If bar.ToTime > prevFromDT And bar.FromTime < prevToDT And bar.PosIndex = prevIndex Then

                    bar.PosIndex += 1

                    For Each bars As barAllocations In lstBars

                        If bar.PosIndex > prevIndex Then bars.PosIndex += 1

                    Next

                End If

                prevFromDT = bar.FromTime
                prevToDT = bar.ToTime
                prevIndex = bar.PosIndex

            Next

        End Sub

    End Class


    Private Sub barAdd()

        Dim startDT As DateTime = Now().AddHours(-48)
        Dim endDT As DateTime = startDT.AddHours(12)

        Dim allogrid As New barAllocations

        allogrid.addAlloBar("test1", startDT, endDT, 0)
        allogrid.addAlloBar("test2", startDT, endDT, 0)
        allogrid.addAlloBar("test3", startDT.AddHours(12), endDT.AddHours(12), 0)
        allogrid.addAlloBar("test4", startDT.AddHours(24), endDT.AddHours(24), 0)

        allogrid.addAlloBar("test5", startDT.AddHours(5), endDT.AddHours(5), 5)
        allogrid.addAlloBar("test6", startDT.AddHours(2), endDT.AddHours(2), 5)

        allogrid.addAlloBar("test7", startDT.AddHours(1), endDT.AddHours(1), 6)
        allogrid.addAlloBar("test8", startDT.AddHours(5), endDT.AddHours(5), 6)

        allogrid.addAlloBar("test9", startDT.AddHours(7), endDT.AddHours(7), 7)
        allogrid.addAlloBar("test10", startDT.AddHours(8), endDT.AddHours(8), 7)

        allogrid.addAlloBar("test11", startDT.AddHours(10), endDT.AddHours(10), 8)
        allogrid.addAlloBar("test12", startDT.AddHours(1), endDT.AddHours(1), 8)
        allogrid.addAlloBar("test13", startDT.AddHours(22), endDT.AddHours(34), 8)
        allogrid.addAlloBar("test14", startDT.AddHours(20), endDT.AddHours(32), 8)

        allogrid.addAlloBar("test15", startDT.AddHours(6), endDT.AddHours(6), 9)
        allogrid.addAlloBar("test16", startDT.AddHours(11), endDT.AddHours(11), 9)

        allogrid.sortList()

    End Sub


End Module

旧版问题描述与实现代码

同一床位同一时间可存在两个预约,最初实现逻辑为:若存在时间重叠,将对应条形向下移动1位,同时所有下方条形也同步移动1位,后续调整网格与床位行线宽度适配同一行同时容纳多个条形的场景。最初尝试使用矩形相交检测方法,检测效果符合预期,但排序逻辑始终存在问题,部分重叠条形未被分离,留存有对应应用效果示例截图。
旧版实现代码如下:

Dim lst As List(Of barAllocation) = lstBars

Dim prevIndex As Integer
Dim prevRec As Rectangle
Dim msg As String = ""

lst = lst.OrderBy(Function(x) x.PosIndex).ThenBy(Function(y) y.FromTime).ToList

For Each bar In lst

    Dim tsDate As TimeSpan = bar.ToTime - bar.FromTime
    Dim recstart As Integer = bar.ToTime.Month & bar.ToTime.Day & bar.ToTime.Hour & bar.ToTime.Minute

    Dim barRec As New Rectangle(recstart, bar.PosIndex * 10, tsDate.TotalMinutes, 10)

    If prevRec.IntersectsWith(barRec) Then
        If prevIndex = bar.PosIndex Then
            If bar.PosIndex = 0 Then
                bar.PosIndex += 1
                barChanged = bar.PosIndex
            Else
                barChanged = bar.PosIndex
                bar.PosIndex += 1
            End If
        End If
    End If

    If bar.PosIndex > barChanged Then bar.PosIndex += 1

    prevRec = barRec
    prevIndex = bar.PosIndex

内容的提问来源于stack exchange,提问作者cyberblitz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:27:17