TransWikia.com

Vertex Labelling and Word wrap

Mathematica Asked by Gordon Coale on March 24, 2021

I am having trouble formatting vertex labels, explicitly adding line breaks to Vertex labels for word wrapping and other purposes. I have explored the pane option suggested here but when I include StringReplace it starts throwing errors although still gives the required result. I suspect its due to incomplete understanding of what “Names” does.

My example is as follows – note I’m creating an Org chart hence the custom (and somewhat “wordy” EdgeLayout.

I realise I can probably get a more complex Vertex label by using Table and a replacement rule – but I’ll also need a simpler form for other purposes so it would be good to fix this one first.

So 2 parts to my question.

How to avoid the errors?
Whats actually passed to a function when “Names” is used?

    wrapLabel[lbl_] := StringReplace[lbl, ":" -> "n"];

    Graph[{"Melvyn:GRU"-> "Gordon:Minion 1","Melvyn:GRU"->"Philip:Minion 2"},
    {GraphStyle->"SmallNetwork",
    EdgeShapeFunction->  (*Edges consist of 3 pairs of 2d cords to create a typical Org Chart style 3 Line Edge *)({Line[{#1[[1]](*1st pair*),{#1[[1,1]],#1[[1,2]]-(#1[[1,2]]-#1[[2,2]])/2}(*2nd pair*),{#1[[1,1]],#1[[1,2]]-(#1[[1,2]]-#1[[2,2]])/2}(*3rd pair*),{#1[[2,1]],(#1[[1,2]]-(#1[[1,2]]-#1[[2,2]])/2)}(*4th pair*),{#1[[2,1]],(#1[[1,2]]-(#1[[1,2]]-#1[[2,2]])/2)}(*5th pair*),#1[[2]] (*6th pair*)}]}&),
    EdgeStyle-> {DirectedEdge["Melvyn:GRU","Gordon:Minion 1"]->Dashed },
    ImageSize->{1200,Automatic},
    GridLinesStyle->Directive[GrayLevel[0.5,0.4]],
    VertexLabels->{Placed["Name",Center,wrapLabel]},
    VertexShapeFunction->{"RoundedRectangle"},
    VertexStyle->{"Philip:Minion 2"-> Green}}]

Error given

    String or list of strings expected at position 1 in StringReplace[!(#2, ":" -> "\n")].

One Answer

ClearAll[wrapLabel];
wrapLabel[lbl_] := StringReplace[lbl, ":" -> "n"];
vlist={"Melvyn:GRU", "Gordon:Minion 1",  "Philip:Minion 2"};

options = {GraphStyle -> "SmallNetwork", 
   EdgeShapeFunction ->
  (*Edges consist of 3 pairs of 2d cords to create a typical Org Chart style 3 Line Edge*)
   ({Line[{#1[[1]](*1st pair*), 
     {#1[[1, 1]], #1[[1, 2]] - (#1[[1, 2]] - #1[[2, 2]])/ 2}(*2nd pair*), 
     {#1[[1, 1]], #1[[1, 2]] - (#1[[1, 2]] - #1[[2, 2]])/ 2}(*3rd pair*),
     {#1[[2, 1]], (#1[[1, 2]] - (#1[[1, 2]] - #1[[2, 2]])/2)}(*4th pair*),
     {#1[[2, 1]], (#1[[1, 2]] - (#1[[1, 2]] - #1[[2, 2]])/2)}(*5th pair*),
      #1[[2]] (*6th pair*)}]} &), 
   EdgeStyle -> {DirectedEdge["Melvyn:GRU", "Gordon:Minion 1"] -> Dashed}, 
   (* ImageSize -> {1200, Automatic},  removed *)
   ImageSize -> {500, 200}, (* added  *)
   VertexSize -> Large, (* added *)
   GridLinesStyle -> Directive[GrayLevel[0.5, 0.4]],
   VertexLabels -> Placed["Name", Center, wrapLabel],
   VertexShapeFunction -> {"RoundedRectangle"}, 
   VertexStyle -> {"Philip:Minion 2" -> Green}};

The function wrapLabel in the third argument of Placed:

gg = Graph[{"Melvyn:GRU" -> "Gordon:Minion 1", "Melvyn:GRU" -> "Philip:Minion 2"}, options]

gives (without an error message in Version 9, and accompanied by error messages in Version 10)

enter image description here

The easiest solution is to change the definition of wrapLabel to wrapLabel[lbl_String]:=... as suggested by Bob Hanlon in the comments.

Here are some additional methods that work with OP's definition as is:

Use an alternative syntax for setting VertexLabels

Graph[{"Melvyn:GRU" -> "Gordon:Minion 1", "Melvyn:GRU" -> "Philip:Minion 2"}, 
      VertexLabels -> {x_ :> Placed[wrapLabel[x], Center]}, options]
(* or VertexLabels -> {x_ :> Placed[x, Center,wrapLabel]} *)

or

Graph[{"Melvyn:GRU" -> "Gordon:Minion 1", "Melvyn:GRU" -> "Philip:Minion 2"}, 
      VertexLabels ->  Placed[# ,Center,wrapLabel]&/@vlist, options]
(* or VertexLabels ->  Placed[wrapLabel@#,Center]&/@vlist *)

Post-process to set the VertexLabels using SetProperty

wrappedLabelsF = Fold[SetProperty[{#, #2},  VertexLabels -> 
                       Placed[wrapLabel[#2], Center]] &, #, VertexList[#]] &;
wrappedLabelsF@gg

Use the first argument of Graph to provide a labeled vertex list using Property

Graph[Property[#,  VertexLabels -> Placed[wrapLabel[#], Center]] & /@ vlist,
      {"Melvyn:GRU" -> "Gordon:Minion 1", "Melvyn:GRU" -> "Philip:Minion 2"}, options]

All give

enter image description here

Correct answer by kglr on March 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP