value given to <B>height</B> will be the final value.
:href:E:lblString:""; map,ps,svg
Synonym for <A HREF=#d:URL>URL</A>.
+:id:GNE:lblString:""; map,ps,svg
+Allows the graph author to provide an id for graph objects which is to be included in the output.
+If no id is provided, then the internal id is used in the outputs, however this value is unpredictable by the graph writer.
+An externally provided id is not used internally.
+If provided, it is the reponsiblity of the provider to keep
+its values sufficiently unique for its intended downstream use.
:image:N:string:"";
Gives the name of a file containing an image to be displayed inside
a node. The image file must be in one of the recognized formats,
if ((flags & GVRENDER_DOES_LABELS) && lbl)
obj->label = lbl;
if (flags & GVRENDER_DOES_MAPS) {
- obj->id = strdup_and_subst_obj(id, gobj);
+ obj->id = strdup(id);
if (url && url[0]) {
obj->url = strdup_and_subst_obj(url, gobj);
assigned = 1;
}
static void
-initGraphMapData (GVJ_t* job, textlabel_t *lab, void* gobj)
+initObjMapData (GVJ_t* job, textlabel_t *lab, char *otyp, long int idnum, void* gobj)
{
char* lbl;
char* url = agget(gobj, "href");
char* tooltip = agget(gobj, "tooltip");
char* target = agget(gobj, "target");
+ char* id = agget(gobj, "id");
+ char buf[50];
if (lab) lbl = lab->text;
else lbl = NULL;
- if (!url || !*url) url = agget(gobj, "URL");
- initMapData (job, lbl, url, tooltip, target, "\\G", gobj);
-}
-
-static void
-initNodeMapData (GVJ_t* job, textlabel_t *lab, void* gobj)
-{
- char* lbl;
- char* url = agget(gobj, "href");
- char* tooltip = agget(gobj, "tooltip");
- char* target = agget(gobj, "target");
-
- if (lab) lbl = lab->text;
- else lbl = NULL;
- if (!url || !*url) url = agget(gobj, "URL");
- initMapData (job, lbl, url, tooltip, target, "\\N", gobj);
+ if (!url || !*url) /* try URL as an alias for href */
+ url = agget(gobj, "URL");
+ if (!id || !*id) { /* no external id, so use the internal one */
+ sprintf(buf, "%s%ld", otyp, idnum);
+ id = buf;
+ }
+ initMapData (job, lbl, url, tooltip, target, id, gobj);
}
static void map_point(GVJ_t *job, pointf pf)
else
obj->z = 0.0;
}
- initNodeMapData (job, ND_label(n), n);
+ initObjMapData (job, ND_label(n), "node", n->id, n);
if ((flags & (GVRENDER_DOES_MAPS | GVRENDER_DOES_TOOLTIPS))
&& (obj->url || obj->explicit_tooltip)) {
{
obj_state_t *obj;
int flags = job->flags;
- char *s;
+ char *s, buf[50];
textlabel_t *lab = NULL, *tlab = NULL, *hlab = NULL;
pointf *pbs = NULL;
int i, nump, *pbs_n = NULL, pbs_poly_n = 0;
}
if (flags & GVRENDER_DOES_MAPS) {
- obj->id = strdup_and_subst_obj("\\E", (void*)e);
+ s = agget(e, "id");
+ if (!s || !*s) { /* no external id, so use the internal one */
+ sprintf(buf,"edge%d", e->id);
+ s = buf;
+ }
+ obj->id = strdup(s);
if (((s = agget(e, "href")) && s[0]) || ((s = agget(e, "URL")) && s[0]))
dflt_url = strdup_and_subst_obj(s, (void*)e);
if (((s = agget(e, "edgehref")) && s[0]) || ((s = agget(e, "edgeURL")) && s[0]))
obj->u.g = g;
obj->emit_state = EMIT_GDRAW;
- initGraphMapData (job, GD_label(g), g);
+ initObjMapData (job, GD_label(g), "graph", job->common->viewNum, g);
#ifdef WITH_CODEGENS
Obj = NONE;
obj->u.sg = sg;
obj->emit_state = EMIT_CDRAW;
- initGraphMapData (job, GD_label(sg), sg);
+ initObjMapData (job, GD_label(sg), "cluster", sg->meta_node->id, sg);
#ifdef WITH_CODEGENS
Obj = CLST;
/* its really just a page of the graph, but its still a graph,
* and it is the entire graph if we're not currently paging */
- gvprintf(job, "<g id=\"graph%d\" class=\"graph\"", job->common->viewNum);
+ gvprintf(job, "<g id=\"%s\" class=\"graph\"", obj->id);
gvprintf(job, " transform=\"scale(%g %g) rotate(%d) translate(%g %g)\">\n",
job->scale.x, job->scale.y, -job->rotation,
job->translation.x, -job->translation.y);
{
obj_state_t *obj = job->obj;
- gvprintf(job, "<g id=\"cluster%ld\" class=\"cluster\">",
- obj->u.sg->meta_node->id);
+ gvprintf(job, "<g id=\"%s\" class=\"cluster\">", obj->id);
gvputs(job, "<title>");
gvputs(job, xml_string(obj->u.sg->name));
gvputs(job, "</title>\n");
{
obj_state_t *obj = job->obj;
- gvprintf(job, "<g id=\"node%ld\" class=\"node\">", obj->u.n->id);
+ gvprintf(job, "<g id=\"%s\" class=\"node\">", obj->id);
gvputs(job, "<title>");
gvputs(job, xml_string(obj->u.n->name));
gvputs(job, "</title>\n");
obj_state_t *obj = job->obj;
char *edgeop;
- gvprintf(job, "<g id=\"edge%ld\" class=\"edge\">", obj->u.e->id);
+ gvprintf(job, "<g id=\"%s\" class=\"edge\">", obj->id);
if (obj->u.e->tail->graph->root->kind & AGFLAG_DIRECTED)
edgeop = "->";
else
assert (id && id[0]); /* there should always be an id available */
if (href && href[0])
gvprintf(job, " xlink:href=\"%s\"", xml_url_string(href));
+#if 0
+ /* linking to itself, jut so that it can have a link in the anchor, seems wrong.
+ * it changes the behavior in browsers, the link apears in the bottinm information bar */
else
gvprintf(job, " xlink:href=\"#%s\"", xml_url_string(id));
+#endif
if (tooltip && tooltip[0])
gvprintf(job, " xlink:title=\"%s\"", xml_string(tooltip));
if (target && target[0])