Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am trying to define a graph using my own VertexShapeFunction with an ActionMenu button being the vertex and a custom EdgeShapeFunction defining the edges as arrows.

My problem is that I am unable to get the arrows to finish exactly at the border of the ActionMenu as it is when I leave EdgeShapeFunction to Automatic. The coordinates and relative size of the ActionMenu button depends on the number of vertices and their layout, so I cannot compute once the coordinates and hardcode them in my definition of the EdgeShapeFunction.

I was wondering if there is a function or a way to get the relative size to the graph coordinate system of the ActionMenu button or some dimensions.

Here is an image of what I am trying to get: as seen from the image, the arrows are ending just before they reach the vertex:

picture

Here is part of the code:

ef[el_, __] := {Blue, 
  Which[First[el][[1]] < Last[el][[1]], 
   Arrow[{First[el], First[el] + {Last[el][[1]] - 0.5, 0}, 
     Last[el] - {0.5, 0}, Last[el] - {0.400, 0}}],

   First[el][[1]] >= Last[el][[1]], 
   Arrow[{First[el], First[el] + {1.5, 0}, First[el] + {1.5, -0.5}, 
     Last[el] + {-1.5, -0.5 + First[el][[2]] - Last[el][[2]]}, 
     Last[el] - {1.5, 0}, Last[el] - {0.400, 0}}]]}

g = Graph[{1 \[DirectedEdge] 2, 3 \[DirectedEdge] 2}, 
   VertexShapeFunction -> (Inset[
       ActionMenu[
        icon, {"Print" :> Print[#2]}], #] &), 
   EdgeShapeFunction -> ef, 
   VertexLabelStyle -> Directive[Italic, 20]];
share|improve this question
    
It looks like all the edges are drawn before the vertices, so it's going to be difficult to draw them finishing in the right place. I've tried playing with the Inset options and the arguments passed to the vertex shape function, but got nowhere... –  cormullion Aug 16 '13 at 10:24

1 Answer 1

up vote 2 down vote accepted

Here's the related question: Can I stop edges in graphs from drawing on top of the vertices?

In your example, you could manually set DynamicName using vertex index.

If we assume vertex names and vertex indices of the given graph are the same, you could modify your function like the below:

ef[el_, DirectedEdge[a_, b_]] := {Blue, 
    Which[First[el][[1]] < Last[el][[1]], 
       Arrow[{First[el], First[el] + {Last[el][[1]] - 0.5, 0}, 
         Last[el] - {0.5, 0}, 
         DynamicLocation["VertexID$" <> ToString[b], Automatic, Center]}],
             First[el][[1]] >= Last[el][[1]], 
           Arrow[{First[el], First[el] + {1.5, 0}, First[el] + {1.5, -0.5}, 
             Last[el] + {-1.5, -0.5 + First[el][[2]] - Last[el][[2]]}, 
             Last[el] - {1.5, 0}, 
             DynamicLocation["VertexID$" <> ToString[b], Automatic, 
         Center]}]]}

g = Graph[{1,2,3}, {1 \[DirectedEdge] 2, 3 \[DirectedEdge] 2}, 
    VertexShapeFunction -> (Inset[
    ActionMenu[icon, {"Print" :> Print[#2]}], #] &), 
    EdgeShapeFunction -> ef, VertexLabelStyle -> Directive[Italic, 20]]

enter image description here

note: this works on v9.0.1, but cannot guarantee it will work in the future version of Mathematica (since boxform could be changed)

share|improve this answer
    
Is there anywhere I can read more about DynamicLocation, since I would like to make the length of how much the edge goes in/out of the ActionMenu before changing direction proportional to the size of the button. –  user9068 Aug 16 '13 at 20:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.