size <- unit(.5, "in")
node <- function(text, x, y, fill="grey") {
    grid.circle(x, y, r=size, gp=gpar(fill=fill), name=text)
    grid.text(text, x, y)
}
edge <- function(from, fangle, to, tangle, ends="last") {
    grid.segments(grobX(from, fangle), grobY(from, fangle),
                  grobX(to, tangle), grobY(to, tangle),
                  arrow=arrow(angle=15, type="closed", ends=ends),
                  gp=gpar(fill="black"))
}
curve <- function(from, fangle, to, tangle, curv, ends="last") {
    x1 <- convertX(grobX(from, fangle), "in")
    y1 <- convertY(grobY(from, fangle), "in")
    x2 <- convertX(grobX(to, tangle), "in")
    y2 <- convertY(grobY(to, tangle), "in")
    grid.curve(x1, y1, x2, y2,
               curvature=curv, ncp=5, square=FALSE,
               arrow=arrow(angle=15, type="closed", ends=ends),
               gp=gpar(fill="black"))
}
grid.newpage()
node("grDevices", .5, 3/5)
node("graphics", .5, 4/5)
node("grid", .5, 2/5)
node("lattice", 2/5, 1/5)
node("ggplot2", 3/5, 1/5)
node("grImport", 1/5, 3/5, fill="white")
node("grImport2", 1/5, 1.5/5, fill="white")
node("gridBase", 3.5/5, 3/5, fill="white")
node("gridGraphics", 4.5/5, 2.5/5, fill="white")
node("gridSVG", 4/5, 1.5/5, fill="white")
edge("grDevices", 90, "graphics", 270)
edge("grDevices", 270, "grid", 90)
edge("grid", 240, "lattice", 70)
edge("grid", 300, "ggplot2", 110)
edge("grImport2", 20, "grid", 200)
edge("grid", 340, "gridSVG", 160)
edge("grImport", 35, "graphics", 215)
edge("grImport", 325, "grid", 145)
edge("grid", 45, "gridBase", 225, ends="both")
edge("graphics", 315, "gridBase", 135, ends="both")
edge("gridGraphics", 190, "grid", 10)
curve("graphics", 20, "gridGraphics", 90, -.5)


