diff --git a/doc/display.xml b/doc/display.xml
index d11894daa..df8da62f4 100644
--- a/doc/display.xml
+++ b/doc/display.xml
@@ -102,6 +102,7 @@ gap> Splash(DotDigraph(RandomDigraph(4)));
+
@@ -124,6 +125,13 @@ gap> Splash(DotDigraph(RandomDigraph(4)));
are not the appropriate size, or have holes then the function will return
an error.
+ DotColoredEdgeLabelledDigraph differs from DotColoredDigraph
+ only in that the values given in the third list labels is used to
+ label the edges of the graph when displayed. The list labels should
+ be a list of equal length to the lists for vertex and edge colours. If the
+ lists are not the appropriate size, or have holes, then the function will
+ return an error.
+
DotVertexColoredDigraph differs from DotDigraph only in
that the values in given in the list are used to color the vertices
of the graph when displayed. The list for vertex colours should be
@@ -152,6 +160,8 @@ gap> Splash(DotDigraph(RandomDigraph(4)));
The string returned by DotDigraph or
DotVertexLabelledDigraph can be written to a file using
the command .
+
+ See also .
D := CompleteDigraph(4);
diff --git a/doc/weights.xml b/doc/weights.xml
index 7d918606d..cc569a088 100644
--- a/doc/weights.xml
+++ b/doc/weights.xml
@@ -364,3 +364,70 @@ gap> RandomUniqueEdgeWeightedDigraph(IsEulerianDigraph, 5, 1 / 3);
<#/GAPDoc>
+
+<#GAPDoc Label="DotEdgeWeightedDigraph">
+
+
+ A string.
+
+ This operation produces a graphical representation of the edge-weighted
+ digraph digraph, in dot format. Its output will be similar to
+ that of , but the diagram will also show the weights
+ of the digraph's edges.
+
+ If the optional argument path is specified, it should be a list of
+ lists describing a path in digraph, in the format described in . If specified, the path's edges will be highlighted in
+ the diagram, as will its start and end vertices.
+
+ If the optional argument colors is specified, it should be a record
+ containing any of the following components:
+
+
+ -
+ vert: the colour of ordinary vertices (default "grey");
+
+ -
+ edge: the colour of ordinary edges (default "black");
+
+ -
+ highlight: the colour of any edges on path, if any
+ (default "blue");
+
+ -
+ source: the colour of the first vertex in path, if any
+ (default "yellowgreen");
+
+ -
+ dest: the colour of the final vertex in path, if any
+ (default "lightpink").
+
+
+
+ Each value in the record should be a string representing a colour understood
+ by the GraphViz software. For details about this format, see
+ https://www.graphviz.org. If any of the above components are not
+ specified, or if no colors argument is given, the default value will
+ be used.
+
+ The output of this operation can be passed to to
+ attempt to display it graphically on the computer's screen.
+
+ gr := EdgeWeightedDigraph([[2], [3], []], [[10], [15], []]);
+
+gap> path := EdgeWeightedDigraphShortestPath(g, 2, 3);
+[ [ 2, 3 ], [ 1 ] ]
+gap> Print(DotEdgeWeightedDigraph(gr, path));
+//dot
+digraph hgn{
+node [shape=circle]
+1[color=gray, style=filled]
+2[color=yellowgreen, style=filled]
+3[color=lightpink, style=filled]
+1 -> 2[color=black, label=10]
+2 -> 3[color=blue, label=15]
+}]]>
+
+
+<#/GAPDoc>
diff --git a/doc/z-chap5.xml b/doc/z-chap5.xml
index 21576bc93..b79417821 100644
--- a/doc/z-chap5.xml
+++ b/doc/z-chap5.xml
@@ -35,6 +35,7 @@
<#Include Label="DigraphMinimumCut">
<#Include Label="DigraphMinimumCutSet">
<#Include Label="RandomUniqueEdgeWeightedDigraph">
+ <#Include Label="DotEdgeWeightedDigraph">
Orders
diff --git a/gap/display.gd b/gap/display.gd
index 5916ef9b9..5e0f381e5 100644
--- a/gap/display.gd
+++ b/gap/display.gd
@@ -10,6 +10,8 @@
DeclareAttribute("DotDigraph", IsDigraph);
DeclareOperation("DotColoredDigraph", [IsDigraph, IsList, IsList]);
+DeclareOperation("DotColoredEdgeLabelledDigraph",
+ [IsDigraph, IsList, IsList, IsList]);
DeclareOperation("DotVertexColoredDigraph", [IsDigraph, IsList]);
DeclareOperation("DotEdgeColoredDigraph", [IsDigraph, IsList]);
DeclareOperation("DotVertexLabelledDigraph", [IsDigraph]);
diff --git a/gap/display.gi b/gap/display.gi
index 44db21e7f..55e048bea 100644
--- a/gap/display.gi
+++ b/gap/display.gi
@@ -157,6 +157,21 @@ function(D, vert, edge)
fi;
end);
+InstallMethod(DotColoredEdgeLabelledDigraph,
+"for a digraph by out-neighbours and three lists",
+[IsDigraphByOutNeighboursRep, IsList, IsList, IsList],
+function(D, vert, edge, weight)
+ local vert_func, edge_func;
+ # See https://graphs.grevian.org/example
+ if DIGRAPHS_ValidVertColors(D, vert)
+ and DIGRAPHS_ValidEdgeColors(D, edge) then
+ vert_func := i -> StringFormatted("[color={}, style=filled]", vert[i]);
+ edge_func := {i, j} -> StringFormatted("[color={}, label={}]",
+ edge[i][j], weight[i][j]);
+ return DIGRAPHS_DotDigraph(D, [vert_func], [edge_func]);
+ fi;
+end);
+
InstallMethod(DotVertexColoredDigraph,
"for a digraph by out-neighbours and a list",
[IsDigraphByOutNeighboursRep, IsList],
diff --git a/gap/weights.gd b/gap/weights.gd
index 25991e48b..f97d94e1f 100644
--- a/gap/weights.gd
+++ b/gap/weights.gd
@@ -52,3 +52,9 @@ DeclareOperation("RandomUniqueEdgeWeightedDigraph",
[IsFunction, IsPosInt, IsFloat]);
DeclareOperation("RandomUniqueEdgeWeightedDigraph",
[IsFunction, IsPosInt, IsRat]);
+
+# 7. Drawing edge weighted digraphs
+DeclareOperation("DotEdgeWeightedDigraph", [IsDigraph]);
+DeclareOperation("DotEdgeWeightedDigraph", [IsDigraph, IsList]);
+DeclareOperation("DotEdgeWeightedDigraph", [IsDigraph, IsRecord]);
+DeclareOperation("DotEdgeWeightedDigraph", [IsDigraph, IsList, IsRecord]);
diff --git a/gap/weights.gi b/gap/weights.gi
index b55cf13e0..979acda3d 100644
--- a/gap/weights.gi
+++ b/gap/weights.gi
@@ -895,3 +895,63 @@ DIGRAPHS_RandomEdgeWeightedDigraphFilt);
InstallMethod(RandomUniqueEdgeWeightedDigraph,
"for a function, a pos int, and a rational", [IsFunction, IsPosInt, IsRat],
DIGRAPHS_RandomEdgeWeightedDigraphFilt);
+
+#############################################################################
+# 7. Drawing edge weighted digraphs
+#############################################################################
+
+InstallMethod(DotEdgeWeightedDigraph, "for a digraph",
+[IsDigraph],
+digraph -> DotEdgeWeightedDigraph(digraph, [[], []], rec()));
+
+InstallMethod(DotEdgeWeightedDigraph, "for a digraph and a list",
+[IsDigraph, IsList],
+{digraph, path} -> DotEdgeWeightedDigraph(digraph, path, rec()));
+
+InstallMethod(DotEdgeWeightedDigraph, "for a digraph and a record",
+[IsDigraph, IsRecord],
+{digraph, colors} -> DotEdgeWeightedDigraph(digraph, [[], []], colors));
+
+InstallMethod(DotEdgeWeightedDigraph, "for a digraph, a list, and a record",
+[IsDigraph, IsList, IsRecord],
+function(digraph, path, colors)
+ local default_colors, edge, vert, source, dest, name, vertColours,
+ edgeColours, path_verts, path_edge_indices, path_length, i;
+
+ # Use default colours for any that aren't specified
+ default_colors := rec(highlight := "blue",
+ edge := "black",
+ vert := "gray",
+ source := "yellowgreen",
+ dest := "lightpink");
+ for name in RecNames(colors) do
+ if IsBound(default_colors.(name)) then
+ default_colors.(name) := colors.(name);
+ else
+ Error("3rd arg contains unsupported option named '", name, "'");
+ fi;
+ od;
+ colors := default_colors;
+
+ # fill with basic colours
+ vertColours := ListWithIdenticalEntries(DigraphNrVertices(digraph),
+ colors.vert);
+ edgeColours := List(OutNeighbours(digraph),
+ outs_u -> List(outs_u, _ -> colors.edge));
+
+ # highlight the path
+ path_verts := path[1];
+ path_edge_indices := path[2];
+ path_length := Length(path_edge_indices);
+ if not IsEmpty(path_verts) then
+ for i in [1 .. path_length] do
+ edgeColours[path_verts[i]][path_edge_indices[i]] := colors.highlight;
+ od;
+ vertColours[path_verts[1]] := colors.source;
+ vertColours[path_verts[path_length + 1]] := colors.dest;
+ fi;
+
+ # draw with the weights as labels
+ return DotColoredEdgeLabelledDigraph(digraph, vertColours, edgeColours,
+ EdgeWeights(digraph));
+end);
diff --git a/tst/standard/weights.tst b/tst/standard/weights.tst
index 739a12a70..c88f4c101 100644
--- a/tst/standard/weights.tst
+++ b/tst/standard/weights.tst
@@ -9,7 +9,7 @@
#############################################################################
##
-#@local D, d, distances, edges, gr, m, parents, r, tree
+#@local D, d, distances, edges, gr, m, parents, path, r, tree
gap> START_TEST("Digraphs package: standard/weights.tst");
gap> LoadPackage("digraphs", false);;
@@ -503,6 +503,74 @@ true
gap> SortedList(Flat(EdgeWeights(D))) = [1 .. DigraphNrEdges(D)];
true
+#############################################################################
+# 7. Drawing edge-weighted digraphs
+#############################################################################
+
+# Trivial example
+gap> gr := EdgeWeightedDigraph([[2], []], [[10], []]);;
+gap> Print(DotEdgeWeightedDigraph(gr));
+//dot
+digraph hgn{
+node [shape=circle]
+1[color=gray, style=filled]
+2[color=gray, style=filled]
+1 -> 2[color=black, label=10]
+}
+
+# Cycle example
+gap> gr := EdgeWeightedDigraph(CycleDigraph(5), [[10], [4], [8], [2], [8]]);;
+gap> path := DigraphPath(gr, 3, 1);
+[ [ 3, 4, 5, 1 ], [ 1, 1, 1 ] ]
+gap> Print(DotEdgeWeightedDigraph(gr, path, rec(highlight := "red")));
+//dot
+digraph hgn{
+node [shape=circle]
+1[color=lightpink, style=filled]
+2[color=gray, style=filled]
+3[color=yellowgreen, style=filled]
+4[color=gray, style=filled]
+5[color=gray, style=filled]
+1 -> 2[color=black, label=10]
+2 -> 3[color=black, label=4]
+3 -> 4[color=red, label=8]
+4 -> 5[color=red, label=2]
+5 -> 1[color=red, label=8]
+}
+
+# Large example
+gap> gr := EdgeWeightedDigraph(
+> [[5, 7], [5], [1, 3, 6], [1, 3], [4, 5], [1, 2], [6]],
+> [[8, 4], [12], [11, 2, 10], [3, 7], [9, 13], [1, 6], [5]]);
+
+gap> path := EdgeWeightedDigraphShortestPath(gr, 1, 2);
+[ [ 1, 7, 6, 2 ], [ 2, 1, 2 ] ]
+gap> Print(DotEdgeWeightedDigraph(gr, path));
+//dot
+digraph hgn{
+node [shape=circle]
+1[color=yellowgreen, style=filled]
+2[color=lightpink, style=filled]
+3[color=gray, style=filled]
+4[color=gray, style=filled]
+5[color=gray, style=filled]
+6[color=gray, style=filled]
+7[color=gray, style=filled]
+1 -> 5[color=black, label=8]
+1 -> 7[color=blue, label=4]
+2 -> 5[color=black, label=12]
+3 -> 1[color=black, label=11]
+3 -> 3[color=black, label=2]
+3 -> 6[color=black, label=10]
+4 -> 1[color=black, label=3]
+4 -> 3[color=black, label=7]
+5 -> 4[color=black, label=9]
+5 -> 5[color=black, label=13]
+6 -> 1[color=black, label=1]
+6 -> 2[color=blue, label=6]
+7 -> 6[color=blue, label=5]
+}
+
#
gap> DIGRAPHS_StopTest();
gap> STOP_TEST("Digraphs package: standard/weights.tst", 0);