From 847f2800b7417a7f603dae5193b1da01df716df3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 13 Jan 2013 09:12:24 +0000 Subject: Better dot rendering and auto-arrange for graphs with circles. git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@4955 a436a847-0d15-0410-975c-d299462d15a1 --- ganv/node.h | 4 ++++ src/Canvas.cpp | 42 ++++++++++++++++++++++++++++++------------ src/node.c | 12 ++++++++++++ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/ganv/node.h b/ganv/node.h index 13c9e5f..47e27b1 100644 --- a/ganv/node.h +++ b/ganv/node.h @@ -128,6 +128,10 @@ ganv_node_get_draw_properties(const GanvNode* node, const char* ganv_node_get_label(const GanvNode* node); +double ganv_node_get_border_width(const GanvNode* node); + +double ganv_node_get_dash_length(const GanvNode* node); + /** * ganv_node_get_partner: * Return value: (transfer none): The partner of @node. diff --git a/src/Canvas.cpp b/src/Canvas.cpp index 61e4376..fe353fe 100644 --- a/src/Canvas.cpp +++ b/src/Canvas.cpp @@ -478,7 +478,7 @@ GanvCanvasImpl::layout_dot(const std::string& filename) agsafeset(G, (char*)"compound", (char*)"true", NULL); agsafeset(G, (char*)"remincross", (char*)"true", NULL); agsafeset(G, (char*)"overlap", (char*)"scale", NULL); - agsafeset(G, (char*)"nodesep", (char*)"0.0", NULL); + agsafeset(G, (char*)"nodesep", (char*)"0.05", NULL); gv_set(G, "fontsize", ganv_canvas_get_font_size(_gcanvas)); gv_set(G, "dpi", dpi); @@ -597,12 +597,26 @@ GanvCanvasImpl::layout_dot(const std::string& filename) ss.str(""); ss << "n" << id++; Agnode_t* node = agnode(G, strdup(ss.str().c_str())); - agsafeset(node, (char*)"width", (char*)"1.0", NULL); - agsafeset(node, (char*)"height", (char*)"1.0", NULL); - agsafeset(node, (char*)"shape", (char*)"ellipse", NULL); + agsafeset(node, (char*)"shape", (char*)"circle", NULL); + agsafeset(node, (char*)"fixedsize", (char*)"true", NULL); + agsafeset(node, (char*)"margin", (char*)"0.0,0.0", NULL); + + const double radius = ganv_circle_get_radius(GANV_CIRCLE(*i)); + const double penwidth = ganv_node_get_border_width(GANV_NODE(*i)); + const double span = (radius + penwidth) * 2.3 / dpi; + gv_set(node, (char*)"width", span); + gv_set(node, (char*)"height", span); + gv_set(node, (char*)"penwidth", penwidth); + + if (ganv_node_get_dash_length(GANV_NODE(*i)) > 0.0) { + agsafeset(node, (char*)"style", (char*)"dashed", NULL); + } + const char* label = ganv_node_get_label(GANV_NODE(*i)); if (label) { agsafeset(node, (char*)"label", (char*)label, NULL); + } else { + agsafeset(node, (char*)"label", (char*)"", NULL); } nodes.insert(std::make_pair(*i, node)); } else { @@ -617,12 +631,16 @@ GanvCanvasImpl::layout_dot(const std::string& filename) if (tail_i != nodes.end() && head_i != nodes.end()) { Agedge_t* e = agedge(G, tail_i->second, head_i->second); - ss.str(""); - ss << edge->impl->tail << (flow_right ? ":e" : ":s"); - agsafeset(e, (char*)"tailport", (char*)ss.str().c_str(), NULL); - ss.str(""); - ss << edge->impl->head << (flow_right ? ":w" : ":n"); - agsafeset(e, (char*)"headport", (char*)ss.str().c_str(), NULL); + if (GANV_IS_PORT(edge->impl->tail)) { + ss.str(""); + ss << edge->impl->tail << (flow_right ? ":e" : ":s"); + agsafeset(e, (char*)"tailport", (char*)ss.str().c_str(), NULL); + } + if (GANV_IS_PORT(edge->impl->head)) { + ss.str(""); + ss << edge->impl->head << (flow_right ? ":w" : ":n"); + agsafeset(e, (char*)"headport", (char*)ss.str().c_str(), NULL); + } } else { std::cerr << "Unable to find graphviz node" << std::endl; } @@ -2131,7 +2149,7 @@ ganv_canvas_arrange(GanvCanvas* canvas) w = ganv_box_get_width(GANV_BOX(i->first)); h = ganv_box_get_height(GANV_BOX(i->first)); } else { - w = h = ganv_circle_get_radius(GANV_CIRCLE(i->first)); + w = h = ganv_circle_get_radius(GANV_CIRCLE(i->first)) * 2.3; } /* Dot node positions are supposedly node centers, but things only @@ -2171,7 +2189,7 @@ ganv_canvas_arrange(GanvCanvas* canvas) } nodes.cleanup(); - static const double border_width = canvas->impl->_font_size; + static const double border_width = canvas->impl->_font_size * 2.0; canvas->impl->move_contents_to_internal(border_width, border_width, least_x, least_y); ganv_canvas_base_scroll_to(GANV_CANVAS_BASE(canvas->impl->_gcanvas), 0, 0); diff --git a/src/node.c b/src/node.c index 2a44d64..cea0974 100644 --- a/src/node.c +++ b/src/node.c @@ -745,6 +745,18 @@ ganv_node_get_label(const GanvNode* node) return node->impl->label ? node->impl->label->impl->text : NULL; } +double +ganv_node_get_border_width(const GanvNode* node) +{ + return node->impl->border_width; +} + +double +ganv_node_get_dash_length(const GanvNode* node) +{ + return node->impl->dash_length; +} + GanvNode* ganv_node_get_partner(const GanvNode* node) { -- cgit v1.2.1