I have a complex diagram and in order to help follow the paths I would like to have an arrow in the middle of the connector as well as the end to indicate direction. If I can have multiple arrows along the path that would be great as well.
I'm using Visio 2010 now but if there is a solution for any version I am open to it.
Thanks,
Clint
What kind of connectors are you using? Only straight arrows or the automatic connector that goes right angled around other shapes?
Because in the last case a second arrowhead in the middle of the path won't look nice, because the middle of the path does not mean the middle of the segment that is in the middle of the path. I had problems with that, too and solved it with a shape, that is only an arrowhead. When I drag it from a stencil and unto a connector line, it will place itself in the middle of the path segment, with VBA.
Worked fine for me, but I can use it only, when the drawing is in its final stages, because when a connector is adjusted, the new arrowhead won't follow it, because it is still a different shape.
When you think, that could help you I can post the VBA code on tuesday
You may want to use line patterns.
Cheers
Yacine
More examples of what can be done with custom line patterns in Visio, and links to further resources:
Release the Power of Visio Custom Line Patterns (http://www.visguy.com/2008/03/03/release-the-power-of-visio-custom-line-patterns/)
Chris,
what settings would you recommend to put exactly one arrow head at the middle of a line/connector with line patterns.
Creating a group could be a possibility, but would be hard to implement for connectors.
I thought someone mentioned about group.
Here is a kind of his idea.
A connector is a group that has arrows.
Unfortunately, you need to run macro,"testArrows", if number of segments changed.
The connectors need to be rectangle conectors.
Enhancement.
Added right click menu "Update Arrows" to each connector shape.
Now you can update arrows on a connector, when you changed the number of segments.
Number of maximum segment is increased from 6 to 9.
I think putting just one arrowhead directly in the middle of the connector is only possible in Visio 2010 (without code, that is)
Visio 2010 has some new ways to access geometry sections arbitrarily, and locate stuff certain percentages along a path.
Made an example by the best suggestion of Visio Guy, though for only Visio 2010.
Thanks for all the help guys! Line patterns are exactly what I was looking for. I knew I couldn't be the only one who had this problem. Thanks to Yacine for giving me the pattern. I modified it to make the arrows more spaced out but it works perfectly!
Nice job, June, very cool!
thougth about that group idea... here's a first sketch.
The laborious part remains to calculate how the grouped connectors bend first, so to orient the arrow accordingly.
My sample has a problem, when the corners of connector are rounded with menu Rounding.
This is because the PATHSEGMENT function counts a corner as 1 segment,
but on the other hand the number of rows of Geometry section does not increase by rounding.
Here is a modified example that re-calculates geometry's rows from the the result of PATHSEGMENT function.
Now you can round the corner of connectors.
And more, shape sheet formulas are simplified using INDEX function.
Above drawing file was replaced after a modification.
Here is the most interesting example that uses POINTALONGPATH function at Visio Insights.
"The Point Along Path ShapeSheet Functions in Visio 2010" at
http://blogs.msdn.com/b/visio/archive/2010/01/15/the-point-along-path-shapesheet-functions-in-visio-2010.aspx
Please, visit there and check the example drawing.
You need to move arrow on the connector back or forth, when connectors are crossing each other.
Here is adjustable arrow on connector.
Right click menu on a connector moves arrow back or forth, and resets to the center.
You might need more functionality, when one segment is too long.
You wish to move arrow on one segment back and forth.
Here added menues "Back on Segment", and so on.
If you need more quick access to arrow on connecotor,
please, enable VBA macro and press direct shortcut keys.
Hello June,
very nice solution, that makes me rethink, what I have done in my solution. Maybe I generate sth. new of both ways, when there's time, because I'm not satisfied with the current version.
I used a filled triangle shape (my "arrowhead"), which calls a makro on drop, to see, if the arrow is placed on a certain type of connector ("Leitung"). It then turns the arrowhead in the right direction and places it in the centre of the connector segment it was droped on. It is still a separate shape, so when moving the connector the arrowhead stays behind. Therefore it is only used in the final stages of a drawing, when the layout is complete. The reason, why I stay with an extra shape (not grouped to the connector) is that I can move the shape slightly afterwards if neccessary and align it with a arrowhead on a connector that runs parallel(?alongside?) the first connector. Also I can place more than one arrowhead on the same path segment (if it's a long one that may become neccessary).
Here's the code I use for this. Maybe someone gets an idea:
Public Sub Pfeil_Drop(dropee As Visio.Shape)
'*********************************************************
'* Drop Makro für Arrow-Heads *
'* Startet from Callthis-Fkt. in Arrowhead-Shape *
'* Makro only tests, if arrowhead is droped on connector *
'* ("Leitung"). If yes is starts a further makro *
'*********************************************************
Dim shp As Visio.Shape
On Error Resume Next
For Each shp In ActivePage.Shapes
If shp.DistanceFrom(dropee, 0) <= 0 And shp <> dropee Then 'Hit
If shp.CellExists("User.Typ", False) Then
If shp.Cells("User.Typ").ResultStr(0) = "Leitung" Then
Pfeil_Leitung dropee, shp
Exit Sub
End If
End If
End If
Next
End Sub
Public Sub Pfeil_Leitung(ByVal Pfeil As Visio.Shape, ByVal Leitung As Visio.Shape, Optional Range As Integer = 2)
'******************************************************
'* Makro for arrowhead placement on connector segment *
'* Startet from Makro Pfeil_Drop *
'******************************************************
Dim vsoShape As Visio.Shape
Dim adblXYPoints() As Double
Dim strPointsList As String
Dim intOuterLoopCounter As Integer
Dim intInnerLoopCounter, Pfadsegment, Segmentanzahl, a, b, i As Integer
Dim X(50), Y(50), PX, PY As Double
Pfadsegment = 0
PX = Pfeil.Cells("PinX").Result("MM")
PY = Pfeil.Cells("PinY").Result("MM")
'Here the points along the path are sored in X(i)/Y(i) Variables
'---------------------------------------------------------------------------------------
Set vsoShape = Leitung
For intOuterLoopCounter = 1 To vsoShape.Paths.Count
vsoShape.Paths(intOuterLoopCounter).Points 0.5, adblXYPoints
a = 1
b = 1
For intInnerLoopCounter = LBound(adblXYPoints) To UBound(adblXYPoints)
If a Mod 2 = 1 Then
X(b) = (adblXYPoints(intInnerLoopCounter) * 25.4)
Else
Y(b) = (adblXYPoints(intInnerLoopCounter) * 25.4)
b = b + 1
End If
strPointsList = strPointsList & a & ": " & (adblXYPoints(intInnerLoopCounter) * 25.4) & Chr(10)
a = a + 1
Next intInnerLoopCounter
If Trim(X(1)) = Trim(Leitung.Cells("BeginX").Result("MM")) And Trim(Y(1)) = Trim(Leitung.Cells("BeginY").Result("MM")) Then
intOuterLoopCounter = vsoShape.Paths.Count
End If
Next intOuterLoopCounter
Segmentanzahl = b - 2
'---------------------------------------------------------------------------------------
'Now analyse, on witch segment of the connector the arrowhead was droped
'---------------------------------------------------------------------------------------
For i = 1 To Segmentanzahl
If X(i + 1) - X(i) = 0 Then 'vertical Segment
If PX > X(i) - Range And PX < X(i) + Range Then 'Test if arrowhead on X coordinate
If Y(i + 1) - Y(i) > 0 Then 'Direction "up"
If PY < Y(i + 1) And PY > Y(i) Then 'arrowhead in Y Intervall
Pfadsegment = i
i = Segmentanzahl
End If
ElseIf Y(i + 1) - Y(i) < 0 Then 'Direction "down"
If PY > Y(i + 1) And PY < Y(i) Then 'arrowhead in Y Intervall
Pfadsegment = i
i = Segmentanzahl
End If
Else
'Nix tun
End If
End If
ElseIf Y(i + 1) - Y(i) = 0 Then 'horizontal Segment
If PY > Y(i) - Range And PY < Y(i) + Range Then 'Test if arrowhead on Y coordinate
If X(i + 1) - X(i) > 0 Then 'Direction "right"
If PX < X(i + 1) And PX > X(i) Then 'arrowhead in X Intervall
Pfadsegment = i
i = Segmentanzahl
End If
ElseIf X(i + 1) - X(i) < 0 Then 'Direction "left"
If PX > X(i + 1) And PX < X(i) Then 'arrowhead in X Intervall
Pfadsegment = i
i = Segmentanzahl
End If
Else
'Nix tun
End If
End If
Else 'Diagonales Segment
'is ignored, but could be captured
End If
Next i
'---------------------------------------------------------------------------------------
'Now place arrowhead in the middle of the Pathsegment (in the right direction)
'---------------------------------------------------------------------------------------
If Pfadsegment = 0 Then Exit Sub '...oder auch nicht ;-)
If X(Pfadsegment) - X(Pfadsegment + 1) = 0 Then 'vertical Segment
Pfeil.Cells("PinX").Result("MM") = X(Pfadsegment)
Pfeil.Cells("PinY").Result("MM") = Y(Pfadsegment) + (Y(Pfadsegment + 1) - Y(Pfadsegment)) / 2
If Y(Pfadsegment + 1) - Y(Pfadsegment) > 0 Then 'up
Pfeil.Cells("Angle").Result("deg") = 0
Else 'down
Pfeil.Cells("Angle").Result("deg") = 180
End If
Else 'horizontal Segment
Pfeil.Cells("PinY").Result("MM") = Y(Pfadsegment)
Pfeil.Cells("PinX").Result("MM") = X(Pfadsegment) + (X(Pfadsegment + 1) - X(Pfadsegment)) / 2
If X(Pfadsegment + 1) - X(Pfadsegment) > 0 Then 'right
Pfeil.Cells("Angle").Result("deg") = -90
Else 'left
Pfeil.Cells("Angle").Result("deg") = 90
End If
End If
'Give it the right color based on temperature (interesting only for my solution)
Pfeil.Cells("Prop.Temperatur").Result("") = Leitung.Cells("Prop.Temperatur").Result("")
'---------------------------------------------------------------------------------------
End Sub