69#define NEW_EDGE(e) (ED_to_virt(e) == 0)
88 int isRoot = rg == infop->
rootg;
101 for (
size_t i = 1; i <
LIST_SIZE(cc); ++i) {
133 if (isRoot || isEmpty)
137 pt.
x = -bb.
LL.
x + margin;
141 bb.
UR.
x += pt.
x + margin;
147 for (
size_t i = 0; i <
LIST_SIZE(cc); ++i) {
208 for (
size_t i = 0; i <
LIST_SIZE(cc); ++i) {
311 if (g != infop->
rootg) {
318 if (sscanf(p,
"%lf,%lf,%lf,%lf%c",
334 agwarningf(
"graph %s, coord %s, expected four doubles\n",
391 fprintf(stderr,
"derive graph _dg_%d of %s\n", infop->
gid,
agnameof(g));
410 boxf fix_bb = {{DBL_MAX, DBL_MAX}, {-DBL_MAX, -DBL_MAX}};
418 chkPos(subg, dn, infop, &fix_bb);
485 if ((pp = PORTS(g))) {
491 PORTS(dg) =
pq =
gv_calloc(sz + 1,
sizeof(bport_t));
514 pq->alpha = pp->alpha;
528static int ecmp(
const void *v1,
const void *v2)
573 qsort(erecs, deg,
sizeof(
erec),
ecmp);
578 double a, inc,
delta, bnd;
581 while (i < deg - 1) {
584 while (j < deg && erecs[j].
alpha == a)
592 bnd = erecs[j].
alpha;
593 delta = fmin((bnd - a) / (j - i),
ANG);
596 erecs[i].
alpha += inc;
645 for (j = 0; j <
ED_count(e); j++, ep++) {
674 bport_t *pp =
gv_calloc(sz + 1,
sizeof(bport_t));
686 idx =
genPorts(n, ep, pp, idx, bnd);
753 vertices[1].
x = -
ND_lw(n);
755 vertices[2].
x = -
ND_lw(n);
816 fprintf (stderr,
"layout %s\n",
agnameof(g));
826 graphs_t cc =
findCComp(dg, &pinned, counter);
828 for (
size_t i = 0; i <
LIST_SIZE(&cc); ++i) {
837 int r =
layout(sg, infop, counter);
847 }
else if (IS_PORT(n))
853 if (g == infop->
rootg)
886 finalCC(dg, &cc, pts, g, infop);
896 BB(sg).UR.x = BB(sg).LL.x +
ND_width(dn);
897 BB(sg).UR.y = BB(sg).LL.y +
ND_height(dn);
898 }
else if ((n = ANODE(dn))) {
905 if (g == infop->
rootg)
916 fprintf (stderr,
"end %s\n",
agnameof(g));
967 if (pclist ==
NULL) {
981 LEVEL(subg) = LEVEL(
parent) + 1;
990 if (pclist ==
NULL) {
1051 "splines and cluster edges not supported - using line segments\n");
int normalize(graph_t *g)
static void out(agerrlevel_t level, const char *fmt, va_list args)
Report messages using a user-supplied or default write function.
Dynamically expanding string buffers.
static void agxbfree(agxbuf *xb)
free any malloced resources
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
int compoundEdges(graph_t *g, expand_t *pm, int edgetype)
void setEdgeType(graph_t *g, int defaultValue)
int late_int(void *obj, attrsym_t *attr, int defaultValue, int minimum)
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
double get_inputscale(graph_t *g)
void compute_bb(graph_t *g)
bool is_a_cluster(Agraph_t *g)
graphs_t findCComp(graph_t *g, int *pinned, size_t *counter)
#define DEFAULT_NODEHEIGHT
#define DEFAULT_NODEPENWIDTH
#define DEFAULT_NODEWIDTH
#define EDGETYPE_COMPOUND
static void del(Dict_t *d, Dtlink_t **set, Agedge_t *e)
void fdp_init_node_edge(Agraph_t *g)
#define PS2INCH(a_points)
#define INCH2PS(a_inches)
static int cnt(Dict_t *d, Dtlink_t **set)
int agnnodes(Agraph_t *g)
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
int agxset(void *obj, Agsym_t *sym, const char *value)
char * agxget(void *obj, Agsym_t *sym)
Agsym_t * agattr_html(Agraph_t *g, int kind, char *name, const char *value)
agattr_text, but creates HTML-like values
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Agdesc_t Agstrictdirected
strict directed. A strict graph cannot have multi-edges or self-arcs.
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
#define ND_outline_width(n)
#define ND_outline_height(n)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Agraph_t * agroot(void *obj)
void * agbindrec(void *obj, const char *name, unsigned int recsize, int move_to_front)
attaches a new record of the given size to the object
int agdelrec(void *obj, const char *name)
deletes a named record from one object
int aghtmlstr(const char *)
Agraph_t * agparent(Agraph_t *g)
Agraph_t * agfstsubg(Agraph_t *g)
Agraph_t * agnxtsubg(Agraph_t *subg)
static erec * getEdgeList(node_t *n, graph_t *g)
static void fdpSplines(graph_t *g)
static void setBB(graph_t *g)
set point box g->bb from inch box BB(g)
static void init_info(graph_t *g, layout_info *infop)
static void fdp_init_graph(Agraph_t *g)
void fdp_layout(graph_t *g)
static void evalPositions(graph_t *g, graph_t *rootg)
static int genPorts(node_t *n, erec *er, bport_t *pp, int idx, double bnd)
static int ecmp(const void *v1, const void *v2)
sort edges by angle, then distance
static void addEdge(edge_t *de, edge_t *e)
static void chkPos(graph_t *g, node_t *n, layout_info *infop, boxf *bbp)
static node_t * mkDeriveNode(graph_t *dg, char *name)
static graph_t * expandCluster(node_t *n, graph_t *cg)
static void freeDeriveNode(node_t *n)
static int fdpLayout(graph_t *g)
static void freeDerivedGraph(graph_t *g, const graphs_t *cc)
static void copyAttr(graph_t *g, graph_t *dg, char *attr)
copy given attribute from g to dg
static void freeGData(graph_t *g)
static void setClustNodes(graph_t *root)
static void mkClusters(graph_t *g, clist_t *pclist, graph_t *parent)
static void finalCC(graph_t *g, const graphs_t *cc, pointf *pts, graph_t *rg, layout_info *infop)
static graph_t * deriveGraph(graph_t *g, layout_info *infop)
static int layout(graph_t *g, layout_info *infop, size_t *counter)
type-generic dynamically expanding list
#define LIST_DETACH(list, datap, sizep)
#define LIST_APPEND(list, item)
#define LIST_SHRINK_TO_FIT(list)
#define LIST_IS_EMPTY(list)
#define LIST_GET(list, index)
#define HAS_CLUST_EDGE(g)
NEATOPROCS_API bool neato_set_aspect(graph_t *g)
NEATOPROCS_API int splineEdges(graph_t *, int(*edgefn)(graph_t *, expand_t *, int), int)
NEATOPROCS_API int spline_edges1(graph_t *g, int)
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
pointf * putGraphs(size_t ng, Agraph_t **gs, Agraph_t *root, pack_info *pinfo)
support for connected components
void gv_postprocess(Agraph_t *g, int allowTranslation)
static double cg(SparseMatrix A, const double *precond, int n, int dim, double *x0, double *rhs, double tol, double maxit)
void fdp_initParams(graph_t *g)
initialize parameters based on root graph attributes
void fdp_tLayout(graph_t *g, xparams *xpms)
void fdp_xLayout(graph_t *g, xparams *xpms)