From b8d719298ae17adb3e58e819bbc81bad4ffb97a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9cile=20An=C3=A9?=
 <cecileane@users.noreply.github.com>
Date: Sun, 17 Oct 2021 19:10:12 -0500
Subject: [PATCH] bug fixes: (#17)

- label placement of minor edges other than first
- show minor edges in gadfly-based plots
---
 .github/workflows/doccleanup.yml | 28 ++++++++++
 Project.toml                     |  2 +-
 src/phylonetworksPlots.jl        | 89 ++++++++++++++++++++++----------
 src/plotGadfly.jl                | 27 ++++++----
 4 files changed, 108 insertions(+), 38 deletions(-)
 create mode 100644 .github/workflows/doccleanup.yml

diff --git a/.github/workflows/doccleanup.yml b/.github/workflows/doccleanup.yml
new file mode 100644
index 0000000..1568024
--- /dev/null
+++ b/.github/workflows/doccleanup.yml
@@ -0,0 +1,28 @@
+name: Doc Preview Cleanup
+
+on:
+  pull_request:
+    types: [closed]
+
+jobs:
+  doc-preview-cleanup:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout gh-pages branch
+        uses: actions/checkout@v2
+        with:
+          ref: gh-pages
+
+      - name: Delete preview and history
+        run: |
+            git config user.name "Documenter.jl"
+            git config user.email "documenter@juliadocs.github.io"
+            git rm -rf "previews/PR$PRNUM"
+            git commit -m "delete preview"
+            git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree})
+        env:
+            PRNUM: ${{ github.event.number }}
+
+      - name: Push changes
+        run: |
+            git push --force origin gh-pages-new:gh-pages
diff --git a/Project.toml b/Project.toml
index 306d7ec..f6f3d44 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "PhyloPlots"
 uuid = "c0d5b6db-e3fc-52bc-a87d-1d050989ed3b"
 license = "MIT"
-version = "0.3.0"
+version = "0.3.1"
 
 [deps]
 ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
diff --git a/src/phylonetworksPlots.jl b/src/phylonetworksPlots.jl
index 7006264..461f8a6 100644
--- a/src/phylonetworksPlots.jl
+++ b/src/phylonetworksPlots.jl
@@ -2,12 +2,46 @@
 # calculate plotting coordinates of nodes & edges for PhyloNetworks objects
 
 """
-    getEdgeNodeCoordinates(net, useEdgeLength)
+    getEdgeNodeCoordinates(net, useEdgeLength::Bool, useSimpleHybridLines::Bool)
 
 Calculate coordinates for plotting later with Gadfly or RCall.
 
 Actually modifies some (minor) attributes of the network,
-as it calls `directEdges!`, `preorder!` and `cladewiseorder!`.
+as it calls `directEdges!` and `preorder!`.
+
+output: tuple with the following elements, in which the order of
+nodes corresponds to the order in `net.node`, and the order of
+edges corresponds to that in `net.edge` (filtered to minor edges as needed).
+
+1. `edge_xB`: x coordinate for the Beginning and ...
+2. `edge_xE`: ...  End of each edge, in the same order as in `net.edge`
+3. `edge_yB`: y coordinate for edges, Begin ...
+4. `edge_yE`: ... and End.
+   Each major edge is drawn as a single horizontal line. Minor hybrid edges are
+   drawn as: a single diagonal segment if `useSimpleHybridLines` is true,
+   or as 2 connected segments otherwise: one horizontal (whose length on the
+   x axis can be used to represent the edge length), and the other diagonal to
+   connect the horizontal segment to the child node.
+   `edge_*` contains the coordinates for the horizontal segment only, which is
+   reduced to a single point (Begin = End) when using "SimpleHybridLines".
+   `minoredge_*` (see below) contains information for the diagonal segment.
+   Agreed, `edge_yB` = `edge_yE` always (relic from before v0.3:
+   no minoredge output back then, and simple diagonal lines only)
+5. `node_x`: x and ...
+6. `node_y`: ... y coordinate at the middle of the vertical bar that represents a node.
+   The (or each) parent edge of the node connects to this middle point,
+   but the node itself is drawn as a vertical bar connected to all it children edges.
+   order: same as in `net.node`
+7. `node_yB`: y coordinates of the Beginning and the ...
+8. `node_yE`: ... End of the vertical bar representing each node.
+   The x coordinate (Begin & End) of the end points of the vertical bar is
+   the same as that of the mid-point, given by `node_x`.
+9. `minoredge_xB`: x coordinate for the Beginning and ...
+10. `minoredge_xE`: ... End of the diagonal segment of each minor hybrid edge,
+   in the same order as in `filter(e -> !e.isMajor, net.edge)`.
+11. `minoredge_yB`: y coordinate for the beginning and ...
+12. `minoredge_yE`: ... end of the diagonal segment of each minor hybrid edge.
+13-16. `xmin`, `xmax`, `ymin`, `ymax`: ranges for the x and y axes.
 """
 function getEdgeNodeCoordinates(net::HybridNetwork, useEdgeLength::Bool, useSimpleHybridLines::Bool)
     try
@@ -319,7 +353,7 @@ function prepareEdgeDataFrame(net::HybridNetwork, edgeLabel::DataFrame, mainTree
         edge_yB::Array{Float64,1}, edge_yE::Array{Float64,1},
         minoredge_xB::Array{Float64,1}, minoredge_xE::Array{Float64,1},
         minoredge_yB::Array{Float64,1}, minoredge_yE::Array{Float64,1})
-    nrows = net.numEdges - (mainTree ? net.numHybrids : 0)
+    nrows = net.numEdges - (mainTree ? length(minoredge_xB) : 0)
     edf = DataFrame(:len => Vector{String}(undef,nrows),
         :gam => Vector{String}(undef,nrows), :num => Vector{String}(undef,nrows),
         :lab => Vector{String}(undef,nrows), :hyb => Vector{Bool}(undef,nrows),
@@ -343,32 +377,33 @@ function prepareEdgeDataFrame(net::HybridNetwork, edgeLabel::DataFrame, mainTree
         @warn msg
       end
     end
-    j=1
+    j=1   # index of row in edf
+    imh=1 # index of minor hybrid edge in filter(ee -> !ee.isMajor, net.edge)
     for i = 1:length(net.edge)
-        if (!mainTree || !net.edge[i].hybrid || net.edge[i].isMajor)
-            edf[j,:len] = (net.edge[i].length==-1.0 ? "" : @sprintf("%0.3g",net.edge[i].length))
-            # @sprintf("%c=%0.3g",'γ',net.edge[i].length)
-            edf[j,:gam] = (net.edge[i].gamma==-1.0  ? "" : @sprintf("%0.3g",net.edge[i].gamma))
-            edf[j,:num] = string(net.edge[i].number)
-            if labeledges
-              je = findfirst(isequal(net.edge[i].number), edgeLabel[!,1])
-              edf[j,:lab] = (je===nothing || ismissing(edgeLabel[je,2]) ? "" :  # edge label not found in table
-                (nonmissingtype(eltype(edgeLabel[!,2])) <: AbstractFloat ?
-                  @sprintf("%0.3g",edgeLabel[je,2]) : string(edgeLabel[je,2])))
-            end
-            edf[j,:hyb] = net.edge[i].hybrid
-            edf[j,:min] = !net.edge[i].isMajor
-            minorIndex = 1;
-            if net.edge[i].isMajor
-                edf[j,:y] = (edge_yB[i] + edge_yE[i])/2
-                edf[j,:x] = (edge_xB[i] + edge_xE[i])/2
-            else
-                edf[j,:y] = (minoredge_yB[minorIndex] + minoredge_yE[minorIndex])/2
-                edf[j,:x] = (minoredge_xB[minorIndex] + minoredge_xE[minorIndex])/2
-                minorIndex += 1
-            end
-            j += 1
+        ee = net.edge[i]
+        # skip the edge if it's minor and we only want the main tree:
+        mainTree && !ee.isMajor && continue
+        edf[j,:len] = (ee.length==-1.0 ? "" : @sprintf("%0.3g",ee.length))
+        # @sprintf("%c=%0.3g",'γ',ee.length)
+        edf[j,:gam] = (ee.gamma==-1.0  ? "" : @sprintf("%0.3g",ee.gamma))
+        edf[j,:num] = string(ee.number)
+        if labeledges
+            je = findfirst(isequal(ee.number), edgeLabel[!,1])
+            edf[j,:lab] = (je===nothing || ismissing(edgeLabel[je,2]) ? "" :  # edge label not found in table
+            (nonmissingtype(eltype(edgeLabel[!,2])) <: AbstractFloat ?
+                @sprintf("%0.3g",edgeLabel[je,2]) : string(edgeLabel[je,2])))
+        end
+        edf[j,:hyb] = ee.hybrid
+        edf[j,:min] = !ee.isMajor
+        if ee.isMajor
+            edf[j,:y] = (edge_yB[i] + edge_yE[i])/2
+            edf[j,:x] = (edge_xB[i] + edge_xE[i])/2
+        else
+            edf[j,:y] = (minoredge_yB[imh] + minoredge_yE[imh])/2
+            edf[j,:x] = (minoredge_xB[imh] + minoredge_xE[imh])/2
+            imh += 1
         end
+        j += 1
     end
     # @show edf
     return labeledges, edf
diff --git a/src/plotGadfly.jl b/src/plotGadfly.jl
index 7b558eb..f67b04f 100644
--- a/src/plotGadfly.jl
+++ b/src/plotGadfly.jl
@@ -50,18 +50,25 @@ function Gadfly.plot(net::HybridNetwork; useEdgeLength=false::Bool,
 
     mylayers = Layer[] # gadfly layers
     # one layers for each edge
+    imh=1 # index of minor hybrid edge in filter(ee -> !ee.isMajor, net.edge)
     for i=1:net.numEdges
-        if (!mainTree || net.edge[i].isMajor)
-            col = edgeColor
-            if net.edge[i].hybrid
-              if (net.edge[i].isMajor) col = majorHybridEdgeColor;
-              else col = minorHybridEdgeColor; end
-            end
-            push!(mylayers,
-              layer(x = [edge_xB[i],edge_xE[i]],
-                    y = [edge_yB[i],edge_yE[i]], Geom.line,
-                    Theme(default_color=col))[1])
+        e = net.edge[i]
+        if mainTree && !e.isMajor continue; end # don't draw minor edges
+        col = edgeColor
+        if e.hybrid
+          if e.isMajor col = majorHybridEdgeColor;
+          else col = minorHybridEdgeColor; end
         end
+        if e.isMajor # tree edge or major hybrid edge: horizontal segment only
+          xe = [edge_xB[i], edge_xE[i]]
+          ye = [edge_yB[i], edge_yE[i]]
+        else # minor edge: draw diagonal segment only
+          xe = [hybridedge_xB[imh], hybridedge_xE[imh]]
+          ye = [hybridedge_yB[imh], hybridedge_yE[imh]]
+          imh += 1
+        end
+        push!(mylayers,
+          layer(x = xe, y = ye, Geom.line, Theme(default_color=col))[1])
     end
     # one layer for each (vertical) clade
     for i=1:net.numNodes