Revision history for Graph::Easy (formerly known as Graph::Simple):
2005-08-12 v0.25 Tels 885 tests - Speed, speed, speed, speed up the code...
Added:
* $graph->add_edge('A','B') works now and is documented
* $graph->add_edge('A','B') in list context returns nodes and edge
* $graph->add_cluster('A') works and returns created cluster object
* Graph::Easy: timeout(): get/set timeout in seconds for layouter
* Layout: calculate chains-of-nodes, and lay out path along these chains
longest one first. This greatly detangles many layouts.
Fixed:
* as_ascii(): Drawing line crossings now works. Really! Believe me!
* as_ascii(): labels on horizontal edge pieces are now included
* rename "todo/" to "todos/" because case-insensitive OS have problems
with "TODO" and "todo/"...
* layout: move the alarm(0) to where it belongs and propagate
fatal errors to the outside
* Layout: calculating positions needs an int() to have nodes not fall
between the cell-grid
* Node: move the assignment to {id} into new(), so that subclasses
like Graph::Easy::Edge etc get a unique ID, too
* use Scalar::Util's weaken so that the Node's references back to their graph
do not prevent the graph from being freed
* Upon DESTROY, reset the appropriate fields in node/edge objects, so they
can be reused safely in other graphs
* A*: fixed an endless-loop in the path-backtracking code
* adding node clusters as well as managing them is now easier
* No longer uses Graph. We store nodes/edges in a hash in Graph::Easy object
as opposed to the Graph object. In addition we store per-node the edges
this node is involved in. This all results in less code, great speed and
memory improvements (see bench/no_graph.txt): v0.25 uses only about 50% of
the memory as 0.24!
Even the testsuite is much much faster, despite the new tests:
0.24: Files=23, Tests=820, 5 secs ( 4.37 cusr + 0.50 csys = 4.87 CPU)
0.25: Files=23, Tests=859, 4 secs ( 2.37 cusr + 0.31 csys = 2.68 CPU)
Loading Graph::Easy now takes less time & memory, too (output from top):
VIRT RES SHR
0.24: 8252 5712 1444
0.25: 5840 3376 1432
2005-08-07 v0.24 Tels 820 tests - Fix, fix, fix, fix the bugs...
Added:
* node attribute: "point-style" - set style for nodes with "shape: point"
* remappig of attributes can take code-ref for special handling
* A*: create crossings, and proper edge end/start pieces, fix bias
Fixed:
* Graph::Easy POD: add note to add_edge() about multi-edges
* correct POD in Graph::Easy::Node::Cell
* Graph::Easy::Edge->new( label => 'foo' ); did not work
* remap_attributes(): suppress empty attributes (fixes as_graphviz)
* as_graphviz: suppress "border-style" on edges and nodes
* as_graphviz: properly remap edge attribute "style"
* as_graphviz: do not include class as attribute in output
* as_graphviz: fix broken comment (graphviz uses //, not #)
* as_graphviz: default node settings are included in class "node"
* as_graphviz: escape '"' (double quoting char) to avoid issues with node
names like '2"'. Also avoid quoting plain node names when
possible.
* as_graphviz: output nodes with their name, not their label
* as_graphviz: multi-edged graphs work now correctly
* as_ascii: implement rendering of nodes with "shape: point"
* as_ascii: render edges with style 'bold'
* as_ascii: properly render edge pieces without gaps
* as_ascii: render edges seemless (".-.-.-.-" vs. ".-.--.-.-.-")
* as_ascii: render all combinations of edge pieces and start/end points
* as_svg_file: did not pass $self to _as_svg(), inducing a fatal failure
* Parser: drop support for parsing reversed edges ("<--"), this never
worked reliable and made parsing of normal edges with labels
much harder and error-prone due to ambigitous cases.
* Parser: fix parsing of bidirectional edges
* Parser: fix parsing of edges with labels containing "-", "[" etc
(edges labels can now contain any character unescaped except ">",
which must be escaped with "\" as "\>")
* Layouter: weed out positions for a node that are too close to a successor
2005-07-31 v0.23 Tels 765 tests - Fix, fix, fix, fix the bugs...
Fixed:
* update POD to reflect that the overall placement strategy is now better
* warn on broken Graph 0.66
* t/parser.t: sort edges on label to avoid hash key ordering tripping us up
* sorted_nodes(): use "name" as second field if a non-unique first field
sorting was requested (like sorted_nodes("layer"))
* _near_places() works correctly on multi-cell nodes and add a
parameter $d to it, so that the distance can be adjusted by the caller.
It can also return direction of place from/to node via third paremeter.
* Layout/Scout: removed _find_path_u_shaped() (use A* instead)
* cleaned up path finding/scoring/handling code
* EDGE_SHORT_N vs EDGE_SHORT_S to be 0,1,2,3 in order E,S,W,N
* self-loop paths (from A to A) correctly set EDGE_LABEL_CELL on the HOR
edge pice
* finding paths is now slightly faster:
self-loop : 20,000 tries/s (vs. 15,000 tries/s)
short edge: 74,000 tries/s (vs. 21,000 tries/s)
* Paths with one bend now have always the correct edge piece.
* Placement of node with two predecessors in a straigght line was wrong
(instead of trying to place the node in the center, it placed it 1/2
the distance to the right/bottom - Thanx to Scott Beuker for providing
a testcase!)
* as_ascii(): align the different edges better
* as_ascii(): the border is now drawn into a framebuffer, this makes it
possible for collating borders or to have "border-top: none"
* Edge are nown drawn seemless, except these pieces:
CROSS
S_W
N_W
In addition, the seems break sometimes on edge styles "- ", "= ", ".-"
and "..-" due to non-alignment.
* move color checking/converting code to Graph::Easy::Attributes
* check border-styles against list of valid names
* as_ascii(): added the ability to have different pieces for corners
* as_ascii(): border styles 'wave' and 'dot-dot-dash' have now two different
vertical characters, rendering these borders now like:
*~~~~~~~~* +..-..-..+
{ Test { | Test |
} Node } : Node :
*~~~~~~~~* +..-..-..+
Added:
* border-style: double-dash:
#= = = = #
" Test "
" Node "
#= = = = #
* edge style: double-dash: "= = = >"
* Graph::Easy::Attributes and tests for it
* Node: is_multicelled()
* Graph: is_simple_graph(), debug()
* A* implementation to find arbitrary paths (even with multi-celled nodes)
2005-07-13 v0.22 Tels 686 tests - Fix, fix, fix, fix the bugs...
Fixed:
* Edge/Parser: edge style '~~' (wave)
* Layouter: assign layers, process nodes sorted by layers
(fixes the '"[B] [A]->[B]" being laid out different from "[A]->[B]"' bug)
* Edge.pm: remove needless new()
* Makefile.PL check for As_svg was borked
Added:
* Node.pm: add columns(), rows(), grow(), connections()
* Layout.pm: add _assign_layers()
* Easy.pm: sorted_nodes() takes 1 or 2 optional field names to sort on
* _near_places() moved into Graph::Easy::Node, make it multi-cell aware
* started laying down the foundation for multi-celled nodes support
in Path.pm/Scout.pm
2005-07-10 v0.21 Tels 605 tests - Fix, fix, fix, fix the bugs...
* As_graphviz: default nodes to filled, fontsize 11
* As_graphviz: quote attribute values if nec.
* As_graphviz: remap attribute names (background => fillcolor etc)
* As_graphviz: output edge attributes
* As_txt: use remap_attribute()
* Easy: add remap_attributes(), as_svg_file(), as_ascii_file()
* Easy: fix POD for add_node(), rem doc about add_vertex(), vertices()
* Easy: add_node() returns newly added node and copes with ("name")
2005-06-25 v0.20 Tels 589 tests - Fix, fix, fix, fix the bugs...
* put SVG code into a seperate package, see there for CHANGES
* add some details to POD
* border-style "dotdashed" renamed to "dot-dash"
* added border and edge-styles: "dot-dot-dash", "wave"
* make "border" set the attributes border-width, border-style, border-color
* as_txt(): output "border" as it used to, even though only
/border-(style|width|color)/ exist now
* as_txt(): sort attributes by name on output to make it more predictable
* as_ascii(): render border styles: double, wave, dot-dash, dot-dot-dash
* as_ascii(): render edge styles: wave, dot-dash, dot-dot-dash
* as_html(): fix overly big circles on labels with line breaks
* as_html(): fix edge style on edges with labels
* Easy: add_edge() returns the newly added edge
* Parser: handle edge styles "~~" (wave), ".-" (dot-dash) and "..-" (dot-dot-dash)
* Parser: recognize all official W3C color names from SVG spec as input
* Parser: reject invalid colors and node shapes
* Parser: allow 'Graph::Easy::Parser->from_file(...);'
* Parser: improve POD
* Node: streamline attribute() and title()
2005-06-12 v0.19 Tels 573 tests - Shape, shape, shape, shape the nodes...
* moved manual and Pod2HTML to Graph::Easy::Manual to avoid dependency
on Pod::Simple
* Graph/Easy.pm: add seed(), randomize(), as_ascii_html()
* Graph/Easy.pm: rem stray debug print in add_edge()
* fix POD about limitations, multi-edges are possible since v0.18
* Parser: allow GLOB and similiar things as file to from_file()
* Easy: add/del of clusters/groups invalidates the current layout
* as_ascii(): fix output of nodes with "border: none;"
* as_ascii(): implement border "dashed;", "dotdashed" and "bold"
* Easy: add _framebuffer(): generate empty framebuffer for as_ascii()
* Easy: make _framebuffer() twice as fast
Renamed to Graph::Easy:
2005-06-11 v0.18 Tels 573 tests - Shape, shape, shape, shape the nodes...
* renamed from Graph::Simple to Graph::Easy
* small cleanups (bumping $VERSIONS, remove unnec. error() routines etc)
* fix =begin graph/end graph in doc/manual/*
* Graph::Easy::Pod2HTML and examples/pod2html support outputformat,
especially "html" and "src,html"
* fix Graph::Easy::Pod2HTML to work almost (the graphs still appear
somewhat out-of-order in the output...)
* forgot to include doc/manual/index.pod
* add one more test for ASCII rendering of autosplit nodes (with hole)
* Parser: do not create empty nodes on autosplit clusters
* re-factor code to allow multi-edges (more than one edge from A to B)
* add tests for multiedges
* call "_correct_size_$format()" if possible
* As_svg: add _correct_size_svg() for Nodes and Edge/Cells
* As_svg: correctly center text for node labels
* As_svg: draw hor/ver lines for edges
* As_svg: draw arrow heads for edges
* As_svg: include a comment with edge type and source/target node
* As_svg: fix position/size for nodes with shape diamond/circle/ellipse
* _prepare_layout() expands cells sizes to maximum column/row size
* Node: add shape()
2005-05-29 v0.17 Tels 559 tests - Edge, edge, edge, edge towards the node...
* rename examples/txt2ascii to examples/as_ascii
* fix examples/as_ascii to actually work
* add examples/as_html
* amend INSTALL, README
* add complete manual (doc/manual/*) and doc/gen_manual to generate HTML
version of the manual
* add Graph::Simple::Pod2HTML
* include tests for different node shapes
* suppress attribute "shape" in HTML output
* as_html: for "shape: invisible", output empty table cell
* as_html: for shape rounded and circle, use moz-rounded-border
* as_html: treat "\n" in edge labels properly
* as_svg: handle shape: invisible
* as_svg: fix output for "shape: rounded;"
* as_svg: fix general output to be valid
* as_txt: output [ name ], not wrongly [ label ]
* as_ascii: node size depends on label, not name
* as_ascii: handle multiline labels correctly
* as_ascii: avoid framebuffer underruns on certain layouts
* added Graph::Simple::Cluster - list of relatively positioned nodes
* Node : added add_to_cluster(), origin(), cluster(), relpos(), place(),
dimensions()
* Node : allow label => 'label' to be passed to new()
* Node : move as_graphviz() to As_graphviz.pm
* Node : _correct_w() to _correct_size() and pass it the format name
(ascii, svg etc)
* Simple: amended LIMITATIONS in pod
* Simple: added output_format(), output(), cluster(), clusters(),
add_clusters()
* Parser: support clusters and autosplit nodes like "[ A | | B || C ]"
* Parser: remove multiple spaces in node names to normalize them
* Parser: fix parse_error() and add tests for that
* Layout: make layouter more robust (better placement of nodes)
* Layout: finally find paths with one bend properly
* Layout: move pathfinding code to Graph::Simple::Layout::Scout
* Layout: move path management code to Graph::Simple::Layout::Path
* Layout: find path loops (from one node back to same node again)
* Layout: find U-shaped paths
* Edge : add styles for EDGE_x_y (x = N/S, y = E/W)
2005-05-17 v0.16 Tels 426 tests - Make, make, make, make the invisible nodes...
* forgot to include As_svg.pm
* Simple.pm: Note other formats in NAME and SYNOPSIS sections
* As_svg: small cleanups
2005-05-16 v0.15 Tels 422 tests - Make, make, make, make the invisible nodes...
* load the As_*() modules on-demand
* fixed NAME in As_graphviz
* add basic support for node shapes
* Node: add del_attribute(), as_svg(), title()
* Parser: check attributes more closely
* Parser: support [] for anonymous, invisible nodes
* added Graph::Simple::Node::Anon
* Graph: move code to prepare layout from as_ascii() to _prepare_layout()
since it can be reused by as_svg()
* as_html: deal better with empty graphs
* as_graphviz: default node shape is rectangular
* Node: successor/predecessor did corrupt nodes w/o a graph
* Node: add _reset_id() for testsuite
* require Graph 0.65
2005-04-11 v0.14 Tels 354 tests - Lay, lay, lay, lay out the edges...
* add experimental graphviz output
* require Graph 0.61
2005-02-12 v0.13 Tels 345 tests - Group, group, group, group the nodes...
* shorten CSS considerable (especially for graphs with groups)
* fix CSS for Opera/Firefox for vertical edges
* fix node-borders for Firefox/Opera by inserting dummy cells at each row
2005-02-07 v0.12 Tels 345 tests - Group, group, group, group the nodes...
* register groups with the graph when adding them
* Parser: parse attributes on groups like: "( Group [ Node ] ) { ... }"
* Parser: parse attributes on edges like: "[ 1 ] -> { ... } [ 2 ]"
* Group: handle attribute "nodeclass" - put nodes into that class
* Node: handle attribute "group" - puts node into that group
* Node: query "node.class" from graph before trying just "node"
* Node: convert literal "\n" in label/name to "<br>"
* Layout: padd around all cells with filler cells (to make group backgrounds
really work)
* Layout: cleanup on group output
* as_txt(): output attributes of a group
* add Graph::Simple::Node::Cell, Graph::Simple::Group::Cell
* moved Graph::Simple::Path to Graph::Simple::Edge::Cell
* Graph: shorten HTML output by combining table cells with colspan=X
* Graph: use CSS child selectors to shorten classnames (and remove
class='fill' or class='' from output)
* Graph: as_html(): fix IDs on labels, lines etc
* Graph: fix layout code for edges with labels: no longer needs position:
relative, allows better copy&paste and is not garbled on scrolling
* syntax.pl: support custom template name
* simplifiy and generalize t/simple.t
* always run test files under -w
* don't use warnings (for older perls)
* remove needless routines in subclasses of "Node"
* use Test::Differences if t/ascii.t fails
2005-01-31 v0.11 Tels 294 tests - Close, close, close, close the ugly holes...
* Parser: add parsing of groups like in "( Groupname [ Node ] )"
* Parser: fix for "[1] -> [2] -> [3] { ... }" to not lose attributes on 3
* Parser: can now handle "[1], [2], [3] -> [4]" correctly
* Parser: cut out rendundant parsing code
* Graph: add group(), add_group(), del_group(), groups()
* Graph: fix css(): 'link', 'label' and 'title' do not need to appear in CSS
* Graph: suppress default attributes from groups, too
* Graph: close "holes" in "arrows" (edges) with line-height & letter-spacing
* Graph: inherit background from page, no border as default
* Graph: as_html() - remove trailing empty tags for shorter output
* Node: add group(), groups(), add_to_groups()
* Node: rename as_txt_node() to as_pure_txt(), document it
* Node: add label() and the handling of the label-attribute
* Node: support "label" as property in autolink/autotitle
* Node: as_txt(): no need to quote ":" and " " in attribute values
* Node: as_html(): quote " " in URLs
* Move as_txt() to As_txt.pm to reduce code size
* Group: keep nodes indexed by their name
* Group: fix as_txt() to quote group name, and include nodes
* Group: fix: add_nodes() did include the group itself by accident
* include examples/base.css for output of syntax.pl
* fix examples/syntax.tpl to have a non-scrolling menu
* add command-line dirnames to syntax.pl
* include t/fun/ - fun with graph-examples
* added Graph::Simple::Path and refactored Edge code - an edge now only
knows as_txt(); The other two, as_html() and as_ascii() are handled by
Path.pm (for each element of the edge seperately)
* more syntax examples
2005-01-24 v0.10 Tels 248 tests - Color, color, color, color the pretty graph...
* added more stress/syntax tests
* fix parser to not treat colors in attributes as comments (like in
"color: #808080")
* use a pre-compiled regexp to match edges (cut down code-duplication)
* parser now handles successfully node chains like:
[ Ulm ] -> [ Lahn ] -> [ Bonn ]
-> [ Trier ]
[ Stein ] -> [ Wahns ]
* Simple.pm: fix edges() in list context to actually work
* require Graph v0.55 (to be safe)
* Node: add attributes_as_txt(), as_txt_node() to allow $graph->as_txt() to
output node attributes only once
* Graph: as_txt(): output node attributes only once
* Graph: add set_attribute()
* examples/syntax.pl: generate headlines from comments in input, add footer
* Graph: support attributes: linkbase, autolink, autotitle, link, title
* Graph: as_html(): output title attributes, as well as links
2005-01-12 v0.09 Tels 147 tests - Place, place, place, place the pesky nodes...
* Layout: try to place node with only one predecessor around the predecessor
* add a stress test with a star-shaped graph (5 nodes)
* add a syntax test with newlines and one without any spaces
* Parser: accumulate left-over fragments to parse examples broken by newlines
* Parser: use compiled regexps for nodes, attributes etc
* Parser: finally handle trailing attributes on nodes
* Node: add set_attributes() for setting multiple ones at once
* Node: setting attribute "class" will set subclass instead
* add tests for parsing:
[ node ] { attribute: value; }
[ node ] { attribute: value; } -> [ node2] { attribute: value }
* fix edges going to the left
* tests for quoting in node names
2005-01-10 v0.08 Tels 133 tests - Fix, fix, fix, fix the stupid bugs...
* grapher tries to place nodes without any incoming edges into first column
(this fixes all the examples which have groups of not-connected nodes)
* in HTML, use monospaced font for edges (prepare for box-art)
* Layout: set error if layout stage fails
* Edge: add EDGE_N_E, EDGE_N_W, EDGE_N_E_W etc for corner pieces
* Edge: add clear_cells()
* make _trace_path() more general by having _trace_straight_path() creating
the edge types
* Node: as_html(): no longer outputs 'style="border: none"' for class="edge"
* Node: include attributes in as_txt() as well as classes (for subclasses)
* Node: add class()
* Graph: always register nodes/edges with the graph
* Graph: as_txt() includes attributes (unless they are the defaults)
* Node: postpone calculation of 'w' (called by as_ascii() from Graph)
* add a stress test with a bend edge
2005-01-09 v0.07 Tels 124 tests
* Parser: ignore empty lines
* Parser: unquote all special chars, not only the first
* Node: quote node name in as_txt()
* Parser: _parse_attributes();
* Graph: added attribute(), set_attributes()
* Graph: added id() to set/get a unique ID per graph
* Graph: default ID is '', CSS code contains ID in class names
* Parser: teach it to parse CSS and call $graph->set_attributes()
* Edge: output name in as_txt()
* Layout: use strict, fix _trace_straight_path()
* t/layout.t: add tests for _trace_straight_path()
* Layout: simplify _trace_path() by using _trace_straight_path()
* Layout: can trace straight edges occupying multiple cells
2005-01-08 v0.06 Tels 94 tests
* fix version in Layout
* Edge: add EDGE_START, EDGE_END, EDGE_HOR, EDGE_VER, EDGE_CROSS
* Edge: add cell_type(), add_cell()
* fix pod with "=end graph" (vs. "=end") sections
* fix error message in t/ascii.t when reading file fails
* fix parser: did not add edge if both nodes already existed
* Layout: add _trace_straight_path() - trace a path horizontal/vertical
* Layout: add _remove_path() - remove a traced path
* tests: add t/layout.t, t/syntax/*
* add examples/syntax.pl, examples/syntax.tpl to create automatic
syntax test page for website
* Parser: add reset() and call it from from_text()
* Parser: handle quoted characters in node names
* Parser: handle comments
2005-01-03 v0.05 Tels 87 tests
* fix special paragraphs in pod to use =begin instead of =for
* typos in pod
* some more clarifications for LIMITATIONS
* move the layout code to Graph::Simple::Layout
* add a testcase with two not-connected node-pools in one graph
* amend README, INSTALL
2005-01-03 v0.04 Tels 84 tests
* change code to work with Graph 0.50
* require Graph 0.50
* added: Group.pm -- a group of nodes
* added: examples/html.pl, examples/common.pl and TODO
* tests: use strict;, add t/edge.t
* Parser: document the different edge directions and styles
* Parser: construct edges with the proper style
* Parser: allow '..>' style
* Node:
+ document successorts()/predecessors(), as_txt(), as_html()
+ implement as_html($tag)
* Graph:
+ _trace_path() can also trace short, straight paths upwards
+ as_txt() uses $edge->as_txt() to render edge
+ as_ascii() generates proper output for edges with the right style
+ as_ascii() no longer generates trailing whitespace on lines
+ add css(), as_html_page(), html_page_footer(), html_page_header()
+ extend documentation, fix typos, add list of limitations
Renamed to Graph::Simple:
2004-12-29 v0.03 Tels 52 tests
* is a subclass of Graph::Directed, so add it as prereq again :o)
* Graph::Layout::Simple::Parser - parse graph from text
* Graph::Layout::Simple::Edge - an edge between two nodes
* Graph: added node() - find node by name
* Graph: add quite some more documentation
* Graph, Node: added as_txt()
* Node: added incoming(), and track incoming edges from other nodes
* added t/parser.t - test text parser
* added t/ascii.t - parse various text files to ascii
2004-12-28 v0.02 Tels 20 tests
* added a stack-based, backtracking layout routine, that stuffs nodes and
paths between them into cells
* Simple.pm: as_ascii: deal with cell-layout and convert this to ASCII
* Simple.pm: add doc stub for METHODS
* Simple.pm: add score(), as_XXX() do layout if it hasn't done before
* Node.pm: revised code, and better parameter handling
* no longer needs Graph::Directed or Graph::Layout::Aesthetic as prereq
* added examples/ascii.pl
* forgot to add graph.t to MANIFEST
2004-12-27 v0.01 Tels 18 tests
* original version; created by h2xs 1.23 with options
-A -X -n Graph::Layout::Simple -b 5.6.1 --skip-autoloader