Diagramma di Gantt

Forse può essere utile una funzione per disegnare un diagramma di Gantt un pò più sofisticato della funzione gantt.chart del package plotrix; la funzione è facilmente modificabile ed adattabile.

diagramma di gantt

gantt.png

Di seguito lo script.

Un invito: nello script è compresa la gestione della legend del grafico principale ( la parte è evidenziata ); il terzo elemento della legenda comprende la fusione di un simbolo (freccia)  e di un testo; non è possibile gestire questo testo con una variabile (e quindi occorre cambiarlo manualmente al bisogno)  perchè l’espressione quote(paste(symbol(“\336″),.(xxx))) , che consente di usare la variabile xxx,  in questo caso non funziona; invece è valida ad esempio in : plot(0,0,main=bquote(paste(symbol(“\336″),.(xxx)))) con xxx=”aaaa” ad esempio.
Qualcuno ha una soluzione ?

Filippo Pinzone

script:

#diagramma di Gantt
#Gantt diagram

#dati

#data

gantt_data<-data.frame(
start_date=c(“03/02/2001″,”11/04/2001″,”21/05/2001″,”21/06/2001″,”17/06/2001″,”01/08/2001″,”01/08/2001″,”01/03/2001″),
length_day=c(10,20,10,20,20,10,10,20),
group=c(1,2,3,3,4,4,4,3),
precedent=c(0,1,0,3,0,3,2,1),
startmax=c(0,4,0,0,0,0,0,0),
endmax=c(5,6,5,2,0,0,0,0),
prog=c(1,1,1,1,1,1,2,1)
)

#Nel caso che una attivitàe abbia più di un predecessore obbligato per evidenziare le dipendenze  si può duplicare la attività tante volte qunati sono i predecessori, indicando in prog l’ordine della attivitàe duplicata: 1,2 3……

#if an activity ha more than a compulsory precedent activity, in order to show the dependencies you can duplicate activity as many times as the number of precedent activities, inserting in prog the order od duplicated activity: 1,2,3….

#argomenti facoltativi della funzione
#function optional arguments

attivita=paste(“attività”,letters[seq(1,7)],sep=”_”)
gruppi=c(“prima fase”,”seconda fase”,”terza fase”,”quarta fase”)
titolo=”Diagramma di Gantt”
legenda=c(“inizio, al massimo”,”fine, al massimo”)
xlabel=” Numero di settimane dal ”

gantt<-function(x,pos_leg=”bottomleft”,activities=NA,groups=NA,main=”Gantt Diagram”,
legend=c(“late start”,”late end”),xlab=”number of weeks from “)
a=b=c=d=e=0
dat<<-x[,1]
y<<-x[,2]
pos<<-x[,3]
s=x[,4]
x1<<-x[,5]
x2<<-x[,6]
dd=x[,7]
x1[x1==0]=NA
x2[x2==0]=NA
if(is.na(activities[1])) actvities=rep(NA,nrow(x))
if(is.na(groups[1])) groups=rep(NA,max(pos))
if(!is.na(activities[1])) layout(matrix(c(1,2),1,2),c(0.75,.25))
ll=length(s)
x<-as.Date(dat,format=”%d/%m/%Y”)
xl<-c(min(x)[1],max(x)[1]+y[which(x==max(x)[1])[1]])
for(i in 1:ll) {
a[i]=x[i]
b[i]=pos[i]
c[i]=x[i]+y[i]
if(s[i]>0 ){
if(x[i]>(x[s[i]]+y[s[i]]-.2)){
d[i]=pos[s[i]]
e[i]=x[s[i]]+y[s[i]]
} else {
d[i]=e[i]=0
}
} else {
d[i]=e[i]=0
}
}
par=par(c(“mar”,”lwd”))
par(mar=c(4,.2,3,0.2) )
par(lwd=2)
xmin=min(x)
datap<-as.POSIXlt(xmin)
ori<-as.Date(paste(“01/01/”,1900+datap$year,sep=”"),format=”%d/%m/%Y”)
int<-seq(from=ori,to=xl[2],7)
ylab=”"
xlab=paste(xlab,format(ori,”%d/%m/%Y”))
plot(0,0,xlim=xl,ylim=c(.9,max(pos)),type=”p”,axes=FALSE,main=main,xlab=xlab,ylab=ylab)
rect(par(“usr”)[1],par(“usr”)[3],par(“usr”)[2],par(“usr”)[4],col=”aquamarine1″)
st=as.numeric(strwidth(groups,unit=”user”))
for(i in 1:max(pos)[1]){
if(as.numeric(min(x[pos==i])-xl[1])>(st[i]+10)){
text(min(x[pos==i])-10,max(pos)-i+1-.1,groups[i],adj=1,col=”red”)
} else {
pp<-which(x==max(x[pos==i]))
text(max(x[pos==i])+y[pp]+ifelse(is.na(x2[pp]),0,x2[pp])+10,max(pos)-i+1-.1,groups[i],adj=0,col=”red”)
}
}
set.seed(123456)
coli=colors()[sample(c(1:200,300:500),30,replace=FALSE)]
col=coli[1:ll]
col2=colors()[pos*10+2]
for(i in 1:ll){
if(dd[i]==1){
rect(a[i],max(pos)-b[i]+1-.1,c[i],max(pos)-b[i]+1+.1,col=col[i],border=col2[i],lwd=5,
angle=45,density=15,bg=”white”)
}
if(d[i]>0){
if(b[i]>d[i]){
segments(e[i],max(pos)-d[i]+1,a[i]+(c[i]-a[i])/10,max(pos)-d[i]+1,lwd=2)
arrows(a[i]+(c[i]-a[i])/10+.2,max(pos)-d[i]+1,a[i]+(c[i]-a[i])/10+.1,max(pos)-b[i]+1+.12,length=.1,lwd=2)
} else {
arrows(e[i],max(pos)-d[i]+1+.1,a[i]-.05,max(pos)-d[i]+1+.1,length=.1,lwd=2)
}
}
}
points(x+x1,max(pos)-pos+1,col=”blue”,pch=18,bg=”blue”)
points(x+y+x2,max(pos)-pos+1,col=”red”,pch=16
)
box()
axis(1,at=int,labels=1:length(int),cex.axis=.8)
axis(2,tick=FALSE)
abline(v=seq(ori,xl[2],7),lty=3,lwd=.5)
xx=expression(paste(symbol(“\336″),”   precedent”,sep=”"))
legend(x=pos_leg,pch=c(18,16,NA),col=c(“blue”,”red”),legend=c(legend[1:2],xx),bg=”white”)
if(!is.na(activities[1])){
plot(c(0,1),c(0,1),type=”n”,axes=FALSE,xlab=”",ylab=”")
ll2=sum(dd[dd==1])
col3=col[dd==1]
legend(x=c(0,1),y=c(1,0),legend=activities,fill=col3,angle=45,density=20,border=col2,cex=1.1,bty=”n”)
}
par(par)
layout(matrix(1,1,1))
#fine funzione
#function end
}

gantt(gantt_data,”bottomleft”,attivita,gruppi,titolo,legenda,xlabel)

#stampa
#print
png(“c:\\gantt.png”,width=960,height=720,type=”cairo”,pointsize=18)
gantt(gantt_data,”bottomleft”,attivita,gruppi,titolo,legenda,xlabel)
dev.off()

#La immagine può essere ottimizzata variando i parametri di larghezza, altezza e pointsize
#Imagin can be optimized varying width,height and pointsize