1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  | 
ganttR <- function(df, type = 'all') {
    nameMilestones <- unique(df$milestones)
    nMilestones <- length(nameMilestones)
    rbPal <- colorRampPalette(c("#3fb3b2", "#ffdd55", "#c7254e", "#1b95e0", "#8555b4")) # Color palette
    cols <- data.frame(milestones = nameMilestones,
                       col = rbPal(nMilestones),
                       stringsAsFactors = FALSE)
    cols <- cols[1:nMilestones, ]
    # Let's organize our dataset to produce the graph
    df <- df %>%
          group_by(milestones) %>% # group by milestones
          summarise(startDate = min(startDate),
                    dueDate = max(dueDate)) %>% # Determine the beginning and end date of milestones
          mutate(tasks = milestones, status = 'M') %>% # Give a name and a status
          bind_rows(df) %>% # Bind milestones with tasks
          mutate(lwd = ifelse(milestones == tasks, 8, 6)) %>% # Add line width for graph
          left_join(cols, by = 'milestones') %>% # add colors
          mutate(col = ifelse(status == 'I', paste0(col, 'BB'), col)) %>% # change colors according to status
          mutate(col = ifelse(status == 'C', paste0(col, '33'), col)) %>% # change colors according to status
          mutate(cex = ifelse(status == 'M', 0.8, 0.75)) %>%
          mutate(adj = ifelse(status == 'M', 0, 1)) %>%
          mutate(line = ifelse(status == 'M', 8, 0.5)) %>%
          mutate(font = ifelse(status == 'M', 2, 1)) %>%
          arrange(milestones,desc(startDate),dueDate) # sort table
    # We need a date range for which we wish to crete the graph.
    # Let's select the duration of the milestone
    dateRange <- c(min(df$startDate), max(df$dueDate))
    # We also need a date sequence that will be used as one of our axes
    # We select the date range divided into 7 days periods
    # dateSeq <- seq.Date(dateRange[1], dateRange[2], by = 7)
    forced_start <- as.Date(paste0(format(dateRange[1], "%Y-%m"), "-01"))
    yEnd <- format(dateRange[2], "%Y")
    mEnd <- as.numeric(format(dateRange[2], "%m")) + 1
    if (mEnd == 13) {
        yEnd <- as.numeric(yEnd) + 1
        mEnd <- 1
    }
    forced_end <- as.Date(paste0(yEnd, "-", mEnd,"-01"))
    dateSeq <- seq.Date(forced_start, forced_end, by = "month")
    lab <- format(dateSeq, "%B")
    # Gantt chart for 'all' type
    if(type == 'all') {
        nLines <- nrow(df)
        par(family = "serif", mar = c(6,9,2,0))
        plot(x = 1, y = 1, col = 'transparent',
          xlim = c(min(dateSeq), max(dateSeq)),
          ylim = c(1, nLines), bty = "n",
          ann = FALSE, xaxt = "n", yaxt = "n", type = "n", bg = 'grey')
        mtext(lab[-length(lab)], side = 1, at = dateSeq[-length(lab)], las = 0,
          line = 1.5, cex = 0.75, adj = 0)
        axis(1, dateSeq, labels = FALSE, line = 0.5)
        extra <- nLines * 0.03
        for(i in seq(1,length(dateSeq - 1), by = 2)) {
            polygon(x = c(dateSeq[i], dateSeq[i + 1], dateSeq[i + 1], dateSeq[i]),
                    y = c(1 - extra, 1 - extra, nLines + extra, nLines + extra),
                    border = 'transparent',
                    col = '#f1f1f155')
        }
        for(i in 1:nLines) {
            lines(c(i,i) ~ c(df$startDate[i], df$dueDate[i]),
                  lwd = df$lwd[i],
                  col = df$col[i])
            mtext(df$tasks[i],
                  side = 2,
                  at = i,
                  las = 1,
                  adj = df$adj[i],
                  line = df$line[i],
                  cex = df$cex[i],
                  font = df$font[i])
        }
        abline(h = which(df$status == 'M') + 0.5, col = '#634d42')
        abline(v = as.Date(format(Sys.time(), format = "%Y-%m-%d")), lwd = 2, lty = 2)
    }
    # Gantt chart for 'milestones' only
    if(type == 'milestones') {
        nLines <- nMilestones
        ms <- which(df$status == 'M')
        par(family = "serif", mar = c(6,9,2,0))
        plot(x = 1, y = 1, col = 'transparent', xlim = c(min(dateSeq), max(dateSeq)), ylim = c(1,nLines), bty = "n",ann = FALSE, xaxt = "n", yaxt = "n",type = "n",bg = 'grey')
        mtext(lab[-length(lab)], side = 1, at = dateSeq[-length(lab)], las = 0, line = 1.5, cex = 0.75, adj = 0)
        axis(1, dateSeq, labels = FALSE, line = 0.5)
        extra <- nLines * 0.03
        for(i in seq(1,length(dateSeq-1), by = 2)) {
            polygon(x = c(dateSeq[i], dateSeq[i + 1], dateSeq[i + 1], dateSeq[i]),
                    y = c(1 - extra, 1 - extra, nLines + extra, nLines + extra),
                    border = 'transparent',
                    col = '#f1f1f155')
        }
        for(i in 1:nLines) {
            lines(c(i,i) ~ c(df$startDate[ms[i]], df$dueDate[ms[i]]),
                  lwd = df$lwd[ms[i]],
                  col = df$col[ms[i]])
            mtext(df$tasks[ms[i]],
                  side = 2,
                  at = i,
                  las = 1,
                  adj = 1,
                  line = 0.5,
                  cex = df$cex[ms[i]],
                  font = df$font[ms[i]])
        }
        abline(v = as.Date(format(Sys.time(), format = "%Y-%m-%d")), lwd = 2, lty = 2)
    }
}
# Single milestone
ganttR(df)
  |