榆树自动甘特线编号

问题描述 投票:0回答:1

我很早以前就已经使用python完成了一项功能。

我以无法用榆树复制的特定方式绘制甘特图。

这是我的代码:https://ellie-app.com/8sYLsxTZHk5a1

问题出在“ calcTaskPosition”函数中,我尝试在其中设置任务的行。

calcTaskPosition : Int -> Task -> List(Task)
calcTaskPosition row task =
    let
        precs = List.concatMap (calcTaskPosition (row+1)) (taskPrecs task)
    in
        { task  | col        = (Maybe.withDefault -1 <|
                                    List.maximum <|
                                        List.map (\t -> t.col) precs) + 1
                --, row        = row
        }
        :: precs

在我的示例中,任务行由initTask函数设置。我希望得到相同的任务顺序,而不必在initTask函数中设置明确的行位置。

recursion elm gantt-chart
1个回答
0
投票

[第一个线索是,当您查看svg时,您会注意到“ task1”实际上已渲染两次。如果您在所发布的代码段中取消注释行--, row = row,则更易于查看。

使用Elm(和其他功能语言)时,您的任务不会就地进行操作,但是当您对它们进行突变时,它们会被复制。因此(现在)将col和row值保留在模型中并不是真正有用的。另外,使用任务ID比直接链接对象更有意义。


考虑到这一点,我将创建两个不同的任务记录:一个用于将其保存在模型中(在我的示例中为Task),另一个用于呈现它(我称为DrawableTask)。然后您需要一个像

这样的转换函数

toDrawableListOfTasks : List Task -> List DrawableTask

将在视图中调用。

转换功能本质上是使用tasksNotInTaskPrecs,在此处选择可以立即绘制的所有任务(因为其任务列表为空)。我对其进行了概括,并将其称为allDependenciesMet,并在每次迭代中都使用它来选择可以绘制的任务。

所有可以绘制的任务将被添加到一个临时列表(在我的情况下是一个字典,用于快速查找已输入的任务),然后下一次迭代将从所有尚未绘制的任务开始。如果没有任务,则可以返回列表,渲染过程将再次遍历该列表。

order : Temp -> List Task -> List DrawableTask
order temp todo =
    case List.partition (allDependenciesMet temp) todo of
        ( [], [] ) ->
            -- We are done and can return the list
            Dict.values temp
                |> List.sortBy .row

        ( [], _ ) ->
            Debug.todo "An invalid list of tasks was passed"

        ( drawableTasks, nextTodo ) ->
            let
                nextTemp =
                    List.indexedMap (toDrawable temp) drawableTasks
                        |> List.map (\t -> ( t.id, t ))
                        |> Dict.fromList
                        |> Dict.union temp
            in
            order nextTemp nextTodo

我不确定这是否可以理解,但是您应该可以遵循https://ellie-app.com/8tdzrgLfBfya1

© www.soinside.com 2019 - 2024. All rights reserved.