Modified code to deal better with splitting chain groups across pages. It
still chokes if a single chain won't fit on a page, but what to do there is complicated and non-obvious. git-svn-id: https://samskivert.googlecode.com/svn/trunk@205 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Driver.java,v 1.5 2001/07/17 07:18:09 mdb Exp $
|
||||
// $Id: Driver.java,v 1.6 2001/07/24 18:07:35 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool;
|
||||
|
||||
@@ -31,6 +31,7 @@ public class Driver
|
||||
|
||||
// run ourselves on the classpath
|
||||
String classpath = System.getProperty("java.class.path");
|
||||
// System.err.println("Scanning " + classpath + ".");
|
||||
ClassEnumerator enum = new ClassEnumerator(classpath);
|
||||
|
||||
// print out the warnings
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ChainGroup.java,v 1.6 2001/07/17 06:01:08 mdb Exp $
|
||||
// $Id: ChainGroup.java,v 1.7 2001/07/24 18:07:35 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -28,13 +28,60 @@ public class ChainGroup
|
||||
|
||||
// process the classes provided by our enumerator
|
||||
_roots = ChainUtil.buildChains(pkgroot, iter);
|
||||
// System.err.println(_roots.size() + " chains for " + pkg + ".");
|
||||
}
|
||||
|
||||
protected ChainGroup (String pkg, ArrayList roots)
|
||||
{
|
||||
_pkg = pkg;
|
||||
_roots = roots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lays out the chains in this group and returns the total size.
|
||||
* Returns the dimensions of this chain group. This value is only
|
||||
* valid after <code>layout</code> has been called.
|
||||
*/
|
||||
public Rectangle2D layout (Graphics2D gfx, double pageWidth,
|
||||
double pageHeight)
|
||||
public Rectangle2D getBounds ()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the upper left coordinate of this group. The group itself
|
||||
* never looks at this information, but it will be made available as
|
||||
* the x and y coordinates of the rectangle returned by
|
||||
* <code>getBounds</code>.
|
||||
*/
|
||||
public void setPosition (double x, double y)
|
||||
{
|
||||
_size.setRect(x, y, _size.getWidth(), _size.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page on which this group should be rendered.
|
||||
*/
|
||||
public int getPage ()
|
||||
{
|
||||
return _page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the page on which this group should be rendered.
|
||||
*/
|
||||
public void setPage (int page)
|
||||
{
|
||||
_page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lays out the chains in this group and returns the total size. If
|
||||
* the layout process requires that this chain group be split across
|
||||
* multiple pages, a new chain group containing the overflow chains
|
||||
* will be returned. If the group fits in the allotted space, null
|
||||
* will be returned.
|
||||
*/
|
||||
public ChainGroup layout (
|
||||
Graphics2D gfx, double pageWidth, double pageHeight)
|
||||
{
|
||||
// lay out the internal structure of our chains
|
||||
ChainVisualizer clay = new CascadingChainVisualizer();
|
||||
@@ -58,19 +105,28 @@ public class ChainGroup
|
||||
|
||||
// arrange them on the page
|
||||
ElementLayout elay = new PackedColumnElementLayout();
|
||||
Rectangle2D[] dims = elay.layout(_roots, pageWidth, pageHeight);
|
||||
|
||||
// for now we're punting and assume that no group will exceed a
|
||||
// single page in size
|
||||
double width = dims[0].getWidth();
|
||||
double height = dims[0].getHeight() + titleAscent;
|
||||
ArrayList overflow = new ArrayList();
|
||||
_size = elay.layout(_roots, pageWidth, pageHeight, overflow);
|
||||
|
||||
// make sure we're wide enough for our title
|
||||
width = Math.max(width, layout.getAdvance() + 4);
|
||||
double width = Math.max(_size.getWidth(), layout.getAdvance() + 4);
|
||||
|
||||
_size = new Rectangle2D.Double();
|
||||
// adjust for our border and title
|
||||
double height = _size.getHeight() + titleAscent;
|
||||
_size.setRect(0, 0, width + 2*BORDER, height + 2*BORDER);
|
||||
return _size;
|
||||
|
||||
// if we have overflow elements, create a new chain group with
|
||||
// these elements, remove them from our roots list and be on our
|
||||
// way
|
||||
if (overflow.size() > 0) {
|
||||
// remove the overflow roots from our list
|
||||
for (int i = 0; i < overflow.size(); i++) {
|
||||
_roots.remove(overflow.get(i));
|
||||
}
|
||||
return new ChainGroup(_pkg, overflow);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,9 +188,17 @@ public class ChainGroup
|
||||
return (Chain)_roots.get(index);
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "[pkg=" + _pkg + ", roots=" + _roots.size() +
|
||||
", size=" + _size + ", page=" + _page + "]";
|
||||
}
|
||||
|
||||
protected String _pkg;
|
||||
protected ArrayList _roots;
|
||||
|
||||
protected Rectangle2D _size;
|
||||
protected int _page;
|
||||
|
||||
protected static final double BORDER = 72/8;
|
||||
}
|
||||
|
||||
+36
-27
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: HierarchyVisualizer.java,v 1.7 2001/07/17 07:18:09 mdb Exp $
|
||||
// $Id: HierarchyVisualizer.java,v 1.8 2001/07/24 18:07:35 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -45,6 +45,7 @@ public class HierarchyVisualizer implements Printable
|
||||
}
|
||||
_classes.add(name);
|
||||
}
|
||||
// System.err.println("Scanned " + _classes.size() + " classes.");
|
||||
|
||||
// compile a list of all packages in our collection
|
||||
HashSet pkgset = new HashSet();
|
||||
@@ -60,18 +61,15 @@ public class HierarchyVisualizer implements Printable
|
||||
_packages[i] = (String)iter.next();
|
||||
}
|
||||
Arrays.sort(_packages, Comparators.STRING);
|
||||
// System.err.println("Scanned " + _packages.length + " packages.");
|
||||
|
||||
// now create chain groups for each package
|
||||
_groups = new ChainGroup[_packages.length];
|
||||
for (int i = 0; i < _groups.length; i++) {
|
||||
_groups = new ArrayList();
|
||||
for (int i = 0; i < _packages.length; i++) {
|
||||
PackageEnumerator penum = new PackageEnumerator(
|
||||
_packages[i], _classes.iterator(), false);
|
||||
_groups[i] = new ChainGroup(pkgroot, _packages[i], penum);
|
||||
_groups.add(new ChainGroup(pkgroot, _packages[i], penum));
|
||||
}
|
||||
|
||||
// we'll need these for later
|
||||
_bounds = new Rectangle2D.Double[_packages.length];
|
||||
_pagenos = new int[_packages.length];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,12 +96,16 @@ public class HierarchyVisualizer implements Printable
|
||||
|
||||
// render the groups on the requested page
|
||||
int rendered = 0;
|
||||
for (int i = 0; i < _groups.length; i++) {
|
||||
for (int i = 0; i < _groups.size(); i++) {
|
||||
ChainGroup group = (ChainGroup)_groups.get(i);
|
||||
|
||||
// skip groups not on this page
|
||||
if (_pagenos[i] != pageIndex) {
|
||||
if (group.getPage() != pageIndex) {
|
||||
continue;
|
||||
}
|
||||
_groups[i].render(gfx, _bounds[i].getX(), _bounds[i].getY());
|
||||
|
||||
Rectangle2D bounds = group.getBounds();
|
||||
group.render(gfx, bounds.getX(), bounds.getY());
|
||||
rendered++;
|
||||
}
|
||||
|
||||
@@ -113,26 +115,32 @@ public class HierarchyVisualizer implements Printable
|
||||
public void layout (Graphics2D gfx, double x, double y,
|
||||
double width, double height)
|
||||
{
|
||||
double starty = x;
|
||||
double starty = y;
|
||||
int pageno = 0;
|
||||
|
||||
// lay out our groups
|
||||
for (int i = 0; i < _groups.length; i++) {
|
||||
for (int i = 0; i < _groups.size(); i++) {
|
||||
ChainGroup group = (ChainGroup)_groups.get(i);
|
||||
|
||||
// lay out the group in question
|
||||
Rectangle2D bounds = _groups[i].layout(gfx, width, height);
|
||||
ChainGroup ngrp = group.layout(gfx, width, height);
|
||||
// if the process of laying this group out caused it to become
|
||||
// split across pages, insert this new group into the list
|
||||
if (ngrp != null) {
|
||||
_groups.add(i+1, ngrp);
|
||||
}
|
||||
|
||||
// determine if we need to skip to the next page or not
|
||||
if ((y > 0) && (y + bounds.getHeight() > height)) {
|
||||
Rectangle2D bounds = group.getBounds();
|
||||
if ((y > starty) && (y + bounds.getHeight() > height + starty)) {
|
||||
y = starty;
|
||||
pageno++;
|
||||
}
|
||||
|
||||
// assign x and y coordinates to this group
|
||||
bounds.setRect(x, y, bounds.getWidth(), bounds.getHeight());
|
||||
// and store it
|
||||
_bounds[i] = bounds;
|
||||
// also make a note of our page index
|
||||
_pagenos[i] = pageno;
|
||||
group.setPosition(x, y);
|
||||
// make a note of our page index
|
||||
group.setPage(pageno);
|
||||
|
||||
// increment our y location
|
||||
y += (bounds.getHeight() + GAP);
|
||||
@@ -142,13 +150,16 @@ public class HierarchyVisualizer implements Printable
|
||||
public void paint (Graphics2D gfx, int pageIndex)
|
||||
{
|
||||
// render the groups on the requested page
|
||||
for (int i = 0; i < _groups.length; i++) {
|
||||
for (int i = 0; i < _groups.size(); i++) {
|
||||
ChainGroup group = (ChainGroup)_groups.get(i);
|
||||
|
||||
// skip groups not on this page
|
||||
if (_pagenos[i] != pageIndex) {
|
||||
if (group.getPage() != pageIndex) {
|
||||
continue;
|
||||
}
|
||||
_groups[i].render((Graphics2D)gfx,
|
||||
_bounds[i].getX(), _bounds[i].getY());
|
||||
|
||||
Rectangle2D bounds = group.getBounds();
|
||||
group.render((Graphics2D)gfx, bounds.getX(), bounds.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +167,9 @@ public class HierarchyVisualizer implements Printable
|
||||
protected ArrayList _classes = new ArrayList();
|
||||
|
||||
protected String[] _packages;
|
||||
protected ChainGroup[] _groups;
|
||||
protected ArrayList _groups;
|
||||
|
||||
protected PageFormat _format;
|
||||
protected Rectangle2D[] _bounds;
|
||||
protected int[] _pagenos;
|
||||
|
||||
protected static final int PAGE_WIDTH = (int)(72 * 7.5);
|
||||
protected static final int PAGE_HEIGHT = (int)(72 * 10);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ElementLayout.java,v 1.2 2001/07/17 01:54:19 mdb Exp $
|
||||
// $Id: ElementLayout.java,v 1.3 2001/07/24 18:07:35 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -15,12 +15,13 @@ import java.util.List;
|
||||
public interface ElementLayout
|
||||
{
|
||||
/**
|
||||
* Lay out the supplied list of elements. Page numbers should be
|
||||
* assigned to all elements if the layout spans multiple pages.
|
||||
* Lay out the supplied list of elements. Any elements that do not fit
|
||||
* into the allotted space should be added to the overflow list. The
|
||||
* supplied elements list should not be modified.
|
||||
*
|
||||
* @return an array of rectangle objects representing the width and
|
||||
* height of each page that was laid out.
|
||||
* @return the bounding dimensions of the collection of elements that
|
||||
* were laid out.
|
||||
*/
|
||||
public Rectangle2D[] layout (List elements,
|
||||
double pageWidth, double pageHeight);
|
||||
public Rectangle2D layout (List elements, double pageWidth,
|
||||
double pageHeight, List overflow);
|
||||
}
|
||||
|
||||
+15
-23
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: PackedColumnElementLayout.java,v 1.4 2001/07/17 05:16:16 mdb Exp $
|
||||
// $Id: PackedColumnElementLayout.java,v 1.5 2001/07/24 18:07:35 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -13,19 +13,16 @@ import java.util.*;
|
||||
public class PackedColumnElementLayout implements ElementLayout
|
||||
{
|
||||
// docs inherited from interface
|
||||
public Rectangle2D[] layout (List elements,
|
||||
double pageWidth, double pageHeight)
|
||||
public Rectangle2D layout (List elements, double pageWidth,
|
||||
double pageHeight, List overflow)
|
||||
{
|
||||
// create a new list containing the elements whose order we can
|
||||
// manipulate willy nilly
|
||||
// sort the elements first by height then alphabetically
|
||||
Element[] elems = new Element[elements.size()];
|
||||
elements.toArray(elems);
|
||||
Arrays.sort(elems, HEIGHT_COMP);
|
||||
|
||||
// lay out the elements across the page
|
||||
ArrayList pagedims = new ArrayList();
|
||||
double x = 0, y = 0, rowheight = 0, maxwidth = 0;
|
||||
int pageno = 0;
|
||||
|
||||
for (int i = 0; i < elems.length; i++) {
|
||||
Rectangle2D bounds = elems[i].getBounds();
|
||||
@@ -42,26 +39,25 @@ public class PackedColumnElementLayout implements ElementLayout
|
||||
// move down to the next row
|
||||
x = 0;
|
||||
y += (rowheight + GAP);
|
||||
// reset our max rowheight
|
||||
rowheight = bounds.getHeight();
|
||||
// reset our max rowheight (we set it to -GAP because we
|
||||
// will add rowheight to our last y position to compute
|
||||
// the total height and if no more elements are laid out,
|
||||
// we'll want to remove that trailing gap)
|
||||
rowheight = -GAP;
|
||||
}
|
||||
|
||||
// make sure we fit on this page (but force placement if we're
|
||||
// currently at the top margin)
|
||||
if ((y > 0) && ((y + bounds.getHeight()) > pageHeight)) {
|
||||
// make a note of how big the current page is
|
||||
pagedims.add(new Rectangle2D.Double(0, 0, maxwidth, y));
|
||||
// move to the next page
|
||||
x = 0;
|
||||
y = 0;
|
||||
rowheight = bounds.getHeight();
|
||||
maxwidth = 0;
|
||||
pageno++;
|
||||
// if we didn't fit, we go onto the overflow list
|
||||
overflow.add(elems[i]);
|
||||
// and continue on because maybe some shorter elements
|
||||
// further down the list will fit
|
||||
continue;
|
||||
}
|
||||
|
||||
// lay this element out at our current coordinates
|
||||
elems[i].setBounds(x, y, bounds.getWidth(), bounds.getHeight());
|
||||
// elems[i].setPage(pageno);
|
||||
|
||||
// keep track of the maximum row height
|
||||
if (bounds.getHeight() > rowheight) {
|
||||
@@ -78,11 +74,7 @@ public class PackedColumnElementLayout implements ElementLayout
|
||||
maxwidth = x;
|
||||
}
|
||||
|
||||
// make a note of how big the final page is
|
||||
pagedims.add(new Rectangle2D.Double(0, 0, maxwidth, y+rowheight));
|
||||
Rectangle2D[] dims = new Rectangle2D[pagedims.size()];
|
||||
pagedims.toArray(dims);
|
||||
return dims;
|
||||
return new Rectangle2D.Double(0, 0, maxwidth, y+rowheight);
|
||||
}
|
||||
|
||||
protected static class HeightComparator implements Comparator
|
||||
|
||||
Reference in New Issue
Block a user