\name{diagram}
\Rdversion{1.1}
\alias{diagram}
\alias{dia.rect}
\alias{dia.ellipse}
\alias{dia.ellipse1}
\alias{dia.arrow}
\alias{dia.curve}
\alias{dia.curved.arrow}
\alias{dia.self}
\alias{dia.shape}
\alias{dia.triangle}
\alias{dia.cone}
\alias{multi.rect}
\alias{multi.arrow}
\alias{multi.curved.arrow}
\alias{multi.self}

\title{Helper functions for drawing path model diagrams}
\description{Path models are used to describe structural equation models or cluster analytic output.  These functions provide the primitives for drawing path models.  Used as a substitute for some of the functionality of Rgraphviz.}

\usage{
diagram(fit,...)
dia.rect(x, y = NULL, labels = NULL,  cex = 1,  xlim = c(0, 1), ylim = c(0, 1),
    draw=TRUE, ...)
dia.ellipse(x, y = NULL, labels = NULL, cex=1,e.size=.05, xlim=c(0,1), 
       ylim=c(0,1),draw=TRUE,  ...) 
dia.triangle(x, y = NULL, labels =NULL,  cex = 1, xlim=c(0,1),ylim=c(0,1),...)
dia.ellipse1(x,y,e.size=.05,xlim=c(0,1),ylim=c(0,1),draw=TRUE,...)
dia.shape(x, y = NULL, labels = NULL, cex = 1, 
         e.size=.05, xlim=c(0,1), ylim=c(0,1), shape=1, ...)
dia.arrow(from,to,labels=NULL,scale=1,cex=1,adj=2,both=FALSE,pos=NULL,l.cex,
        gap.size,draw=TRUE,col="black",lty="solid",...)
dia.curve(from,to,labels=NULL,scale=1,...)
dia.curved.arrow(from,to,labels=NULL,scale=1,both=FALSE,dir=NULL,draw=TRUE,...)
dia.self(location,labels=NULL,scale=.8,side=2,draw=TRUE,...)
dia.cone(x=0, y=-2, theta=45, arrow=TRUE,curves=TRUE,add=FALSE,labels=NULL,
      xlim = c(-1, 1), ylim=c(-1,1),... ) 
multi.self(self.list,...)
multi.arrow(arrows.list,...)
multi.curved.arrow(curved.list,l.cex=NULL,...)
multi.rect(rect.list,...)
}

\arguments{
 \item{fit}{The results from a factor analysis \code{\link{fa}}, components analysis  \code{\link{principal}}, omega reliability analysis, \code{\link{omega}}, cluster analysis  \code{\link{iclust}}, topdown (bassAckward) \code{\link{bassAckward}} or confirmatory factor analysis, cfa, or structural equation model,sem, using the lavaan package.}
  \item{x}{x coordinate of a rectangle or ellipse}
  \item{y}{y coordinate of a rectangle or ellipse}
  \item{e.size}{The size of the ellipse (scaled by the number of variables}
  \item{labels}{Text to insert in rectangle, ellipse, or arrow}
  \item{cex}{adjust the text size}
  \item{col}{line color  (normal meaning for plot figures)}
  \item{lty}{line type}
  \item{l.cex}{Adjust the text size in arrows, defaults to 
        cex which in turn defaults to 1}
  \item{gap.size}{Tweak the gap in an arrow to be allow the label to be in a gap}
  \item{adj}{Where to put the label along the arrows (values are then divided by 4)}
  \item{both}{Should the arrows have arrow heads on both ends?}
\item{scale}{modifies size of rectangle and ellipse as well as the curvature of curves.  (For curvature, positive numbers are concave down and to the left}
  \item{from}{arrows and curves go from }
  \item{to}{arrows and curves go to}
  \item{location}{where is the rectangle?}
  \item{shape}{Which shape to draw}
  \item{xlim}{default ranges}
  \item{ylim}{default ranges}
  \item{draw}{Draw the text box}
  \item{side}{Which side of boxes should errors appear}
  \item{theta}{Angle in degrees of vectors}
  \item{arrow}{draw arrows for edges in dia.cone}
  \item{add}{if TRUE, plot on previous plot}
  \item{curves}{if TRUE, draw curves between arrows in dia.cone}
  \item{pos}{The position of the text in . Follows the text positions of 1, 2, 3, 4 or NULL}
  \item{dir}{Should the direction of the curve be calculated dynamically, or set as "up" or "left"}
  \item{\dots}{Most graphic parameters may be passed here}
  \item{self.list}{list saved from dia.self}
  \item{arrows.list}{lst saved from dia.arrow}
  \item{curved.list}{list saved from dia.curved.arrow}
  \item{rect.list}{list saved from dia.rect}
  
  
  

}
\details{The diagram function calls  \code{\link{fa.diagram}}, \code{\link{omega.diagram}},  \code{\link{ICLUST.diagram}}, \code{\link{lavaan.diagram}} or \code{\link{bassAckward}}.diagram depending upon the class of the fit input.  See those functions for particular parameter values.

The remaining functions are the graphic primitives used by \code{\link{fa.diagram}}, \code{\link{structure.diagram}}, \code{\link{omega.diagram}}, \code{\link{ICLUST.diagram}} and \code{\link{het.diagram}}

They create rectangles, ellipses or triangles surrounding text, connect them to straight or curved arrows, and can draw an arrow from and to the same rectangle. 

To speed up the plotting, dia.rect and dia.arrow can suppress the actual drawing and return the locations and values to plot.  These values  can then be directly called by text or rect with matrix input. This leads to an impressive increase in speed when doing many variables. 

The functions \code{\link{multi.rect}}, \code{\link{multi.self}}, \code{\link{multi.arrow}} and \code{\link{multi.curved.arrow}}  will take the saved output from the appropriate primitives and then draw them all at once. 

Each shape (ellipse, rectangle or triangle) has a left, right, top and bottom and center coordinate that may be used to connect the arrows. 

Curves are double-headed arrows.   By default they go from one location to another and curve either left or right (if going up or down) or up or down (going left to right).  The direction of the curve may be set by dir="up" for left right curvature.

The helper functions were developed to get around the infelicities associated with trying to install Rgraphviz and graphviz. 

These functions form the core of \code{\link{fa.diagram}},\code{\link{het.diagram}}. 

Better documentation will be added as these functions get improved.  Currently the helper functions are just a work around for Rgraphviz.

dia.cone draws a cone with (optionally) arrows as sides and centers to show the problem of factor indeterminacy. 

}
\value{Graphic output}

\author{William Revelle
}

\seealso{The diagram functions that use the dia functions:  \code{\link{fa.diagram}}, \code{\link{structure.diagram}}, \code{\link{omega.diagram}}, and \code{\link{ICLUST.diagram}}.
}
\examples{
#first, show the primitives
xlim=c(-2,10)
ylim=c(0,10)
plot(NA,xlim=xlim,ylim=ylim,main="Demonstration of diagram functions",axes=FALSE,xlab="",ylab="")
ul <- dia.rect(1,9,labels="upper left",xlim=xlim,ylim=ylim)
ml <- dia.rect(1,6,"middle left",xlim=xlim,ylim=ylim)
ll <- dia.rect(1,3,labels="lower left",xlim=xlim,ylim=ylim)
bl <- dia.rect(1,1,"bottom left",xlim=xlim,ylim=ylim)
lr <- dia.ellipse(7,3,"lower right",xlim=xlim,ylim=ylim,e.size=.07)
ur <- dia.ellipse(7,9,"upper right",xlim=xlim,ylim=ylim,e.size=.07)
mr <- dia.ellipse(7,6,"middle right",xlim=xlim,ylim=ylim,e.size=.07)
lm <- dia.triangle(4,1,"Lower Middle",xlim=xlim,ylim=ylim)
br <- dia.rect(9,1,"bottom right",xlim=xlim,ylim=ylim) 
dia.curve(from=ul$left,to=bl$left,"double headed",scale=-1)

dia.arrow(from=lr,to=ul,labels="right to left")
dia.arrow(from=ul,to=ur,labels="left to right")
dia.curved.arrow(from=lr,to=ll,labels ="right to left")
dia.curved.arrow(to=ur,from=ul,labels ="left to right")
dia.curve(ll$top,ul$bottom,"right")  #for rectangles, specify where to point 

dia.curve(ll$top,ul$bottom,"left",scale=-1)  #for rectangles, specify where to point 
dia.curve(mr,ur,"up")  #but for ellipses, you may just point to it.
dia.curve(mr,lr,"down")
dia.curve(mr,ur,"up")
dia.curved.arrow(mr,ur,"up")  #but for ellipses, you may just point to it.
dia.curved.arrow(mr,lr,"down")  #but for ellipses, you may just point to it.

dia.curved.arrow(ur$right,mr$right,"3")
dia.curve(ml,mr,"across")
dia.curve(ur$right,lr$right,"top down",scale =2)
dia.curved.arrow(br$top,lr$right,"up")
dia.curved.arrow(bl,br,"left to right")
dia.curved.arrow(br,bl,"right to left",scale=-1)
dia.arrow(bl,ll$bottom)
dia.curved.arrow(ml,ll$right)
dia.curved.arrow(mr,lr$top)

#now, put them together in a factor analysis diagram
v9 <- sim.hierarchical()
f3 <- fa(v9,3,rotate="cluster")
fa.diagram(f3,error=TRUE,side=3) 
}
% Add one or more standard keywords, see file 'KEYWORDS' in the
% R documentation directory.
\keyword{multivariate}
\keyword{hplot }% __ONLY ONE__ keyword per line
