(**Note,this uses JoinedCurve and Texture which are Mathematica 8 primitives.In Mathematica 7,JoinedCurve is not needed and can be removed*)

(**Global variables**)
textureSS=1; (* sampling to use for texture *)
scale=50;
lineThickness=1/2;(*line thickness in regular coordinates*)(**Global utilities**)(*test if 3 points are collinear,needed to work around difference in how colinear Line endpoints are rendered*)collinear[points_]:=Length[points]==3&&(Det[Transpose[points]~Append~{1,1,1}]==0)

(*tales list of point coordinates,returns plotRange bounding box,uses global "scale" and "lineThickness" to get bounding box*)

getPlotRange[lst_]:=({xs,ys}=Transpose[lst];
(*two extra 1/scale offsets needed for exact match*){{Min[xs]-lineThickness/2,Max[xs]+lineThickness/2+1/scale},{Min[ys]-lineThickness/2-1/scale,Max[ys]+lineThickness/2}});

(*Gets image size for given plot range*)

getImageSize[{{xmin_,xmax_},{ymin_,ymax_}}]:=(imsize=scale*{xmax-xmin,ymax-ymin}+{1,1});

(*converts plot range to vertices of rectangle*)

pr2verts[{{xmin_,xmax_},{ymin_,ymax_}}]:={{xmin,ymin},{xmax,ymin},{xmax,ymax},{xmin,ymax}};

(*lifts two dimensional coordinates into 3d*)

lift[h_,coords_]:=Append[#,h]&/@coords
(*convert Raster object to array specification of texture*)

raster2texture[raster_]:=Reverse[raster[[1,1]]/255]

Subset[a_,b_]:=(a⋂b==a);
inducedGraph[set_]:=Select[edges,#⊂set&];
values[dict_]:=Map[#[[-1]]&,DownValues[dict]];


(**Graph Specific Stuff*)
graphName={"Grid",{3,3}};
verts=Range[GraphData[graphName,"VertexCount"]];
edges=GraphData[graphName,"EdgeIndices"];
vcoords=Thread[verts->GraphData[graphName,"VertexCoordinates"]];
jedges={{{1,2,4},{2,4,5,6}},{{2,3,6},{2,4,5,6}},{{4,5,6},{2,4,5,6}},{{4,5,6},{4,5,6,8}},{{4,7,8},{4,5,6,8}},{{6,8,9},{4,5,6,8}}};
jnodes=Union[Flatten[jedges,1]];


(*Generate diagram with explicit PlotRange,ImageSize and AbsoluteThickness*)
plotHL[verts_,color_]:=(coords=verts/.vcoords;
obj=JoinedCurve[Line[coords],CurveClosed->Not[collinear[coords]]];
(*Figure out PlotRange and ImageSize needed to respect scale*)pr=getPlotRange[verts/.vcoords];
{{xmin,xmax},{ymin,ymax}}=pr;
imsize=scale*{xmax-xmin,ymax-ymin};
lineForm={Opacity[.3],color,JoinForm["Round"],CapForm["Round"],AbsoluteThickness[scale*lineThickness]};
g=Graphics[{Directive[lineForm],obj}];
gg=GraphPlot[Rule@@@inducedGraph[verts],VertexCoordinateRules->vcoords];
Show[g,gg,PlotRange->pr,ImageSize->imsize]);

(*Initialize all graph plot images*)
SeedRandom[1];colors=RandomChoice[ColorData["WebSafe","ColorList"],Length[jnodes]];
Clear[bags];
MapThread[(bags[#1]=plotHL[#1,#2])&,{jnodes,colors}];

(**Ploting parent graph of subgraphs**)

(*figure out coordinates of subgraphs close to edges of bounding box,use them to anchor parent GraphPlot*)

bagCentroid[bag_]:=Mean[bag/.vcoords];
findExtremeBag[vec_]:=(vertList=First/@vcoords;
coordList=Last/@vcoords;
extremePos=First[Ordering[jnodes,1,bagCentroid[#1].vec>bagCentroid[#2].vec&]];
jnodes[[extremePos]]);

extremeDirs={{1,1},{1,-1},{-1,1},{-1,-1}};
extremeBags=findExtremeBag/@extremeDirs;
extremePoses=bagCentroid/@extremeBags;

(*figure out new plot range needed to contain all objects*)

fullPR=getPlotRange[verts/.vcoords];
fullIS=getImageSize[fullPR];

(***Show bags together merged***)
image1=Show[values[bags],PlotRange->fullPR,ImageSize->fullIS]

(***Show bags as vertices of another GraphPlot***)
GraphPlot[Rule@@@jedges,EdgeRenderingFunction->({Gray,Thick,Arrowheads[.05],Arrow[#1,0.22]}&),VertexCoordinateRules->Thread[Thread[extremeBags->extremePoses]],VertexRenderingFunction->(Inset[bags[#2],#]&),PlotRange->fullPR,ImageSize->3*fullIS]

(***Show bags as 3d slides***)
makeSlide[graphics_,pr_,h_]:=(
rasterIMsize=-scale*(Subtract@@@pr);
raster=Rasterize[graphics,Background->None,ImageSize->rasterIMsize,RasterSize->textureSS*rasterIMsize];
Graphics3D[{Texture[raster2texture[raster]],EdgeForm[None],Polygon[lift[h,pr2verts[pr]],VertexTextureCoordinates->pr2verts[{{0,1},{0,1}}]]}]

)

yoffset=1/2;
slides=MapIndexed[makeSlide[bags[#],getPlotRange[#/.vcoords],yoffset*First[#2]]&,jnodes];
imageDiag=Show[slides,ImageSize->3*fullIS,Lighting->"Neutral"]

(***Show 3d slides in orthographic projection***)
image2=Show[slides,ViewPoint->{0,0,Infinity},ImageSize->fullIS,Boxed->False,Lighting->"Neutral"]

(***Check that 3d and 2d images rasterize to identical resolution***)
(*Dimensions[Rasterize[image1][[1,1]]]==Dimensions[Rasterize[image2][[1,1]]]*)

diagSize=381;
SetDirectory[NotebookDirectory[]];
Export["exploded.png",Rasterize[imageDiag,ImageSize->381,RasterSize->diagSize*4]]