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);
}