private MilestonesRender()

in src/gantt.ts [2338:2405]


    private MilestonesRender(
        taskSelection: Selection<Task>,
        taskConfigHeight: number): void {
        let taskMilestones: Selection<any> = taskSelection
            .selectAll(Selectors.TaskMilestone.selectorName)
            .data((d: Task) => {
                const nestedByDate = d3.nest().key((d: Milestone) => d.start.toDateString()).entries(d.Milestones);
                let updatedMilestones: MilestonePath[] = nestedByDate.map((nestedObj) => {
                    const oneDateMilestones = nestedObj.values;
                    // if there 2 or more milestones for concrete date => draw only one milestone for concrete date, but with tooltip for all of them
                    let currentMilestone = [...oneDateMilestones].pop();
                    const allTooltipInfo = oneDateMilestones.map((milestone: MilestonePath) => milestone.tooltipInfo);
                    currentMilestone.tooltipInfo = allTooltipInfo.reduce((a, b) => a.concat(b), []);

                    return {
                        type: currentMilestone.type,
                        start: currentMilestone.start,
                        taskID: d.index,
                        tooltipInfo: currentMilestone.tooltipInfo
                    };
                });

                return [{
                    key: d.index, values: <MilestonePath[]>updatedMilestones
                }];
            });


        taskMilestones
            .exit()
            .remove();

        const taskMilestonesAppend = taskMilestones
            .enter()
            .append("g");

        const taskMilestonesMerged = taskMilestonesAppend
            .merge(taskMilestones);

        taskMilestonesMerged.classed(Selectors.TaskMilestone.className, true);

        const transformForMilestone = (id: number, start: Date) => {
            return SVGManipulations.translate(this.timeScale(start) - Gantt.getBarHeight(taskConfigHeight) / 4, Gantt.getBarYCoordinate(id, taskConfigHeight) + (id + 1) * this.getResourceLabelTopMargin());
        };

        let taskMilestonesSelection = taskMilestonesMerged.selectAll("path");
        let taskMilestonesSelectionData = taskMilestonesSelection.data(milestonesData => <MilestonePath[]>milestonesData.values);

        // add milestones: for collapsed task may be several milestones of its children, in usual case - just 1 milestone
        let taskMilestonesSelectionAppend = taskMilestonesSelectionData.enter()
            .append("path");

        taskMilestonesSelectionData
            .exit()
            .remove();

        let taskMilestonesSelectionMerged = taskMilestonesSelectionAppend
            .merge(<any>taskMilestonesSelection);

        if (this.hasNotNullableDates) {
            taskMilestonesSelectionMerged
                .attr("d", (data: MilestonePath) => this.getMilestonePath(data.type, taskConfigHeight))
                .attr("transform", (data: MilestonePath) => transformForMilestone(data.taskID, data.start))
                .attr("fill", (data: MilestonePath) => this.getMilestoneColor(data.type));
        }

        this.renderTooltip(taskMilestonesSelectionMerged);
    }