Generate a Graphviz digraph structure for the DAG.
dot
: dot -Tpdf -o test.pdf test.dot
,
where test.dot
is str
written to a file.Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(dag), | intent(in) | :: | me | |||
character(len=*), | intent(in), | optional | :: | rankdir |
right to left orientation (e.g. 'RL') |
|
integer(kind=ip), | intent(in), | optional | :: | dpi |
resolution (e.g. 300) |
function dag_generate_digraph(me,rankdir,dpi) result(str) class(dag),intent(in) :: me character(len=:),allocatable :: str character(len=*),intent(in),optional :: rankdir !! right to left orientation (e.g. 'RL') integer(ip),intent(in),optional :: dpi !! resolution (e.g. 300) integer(ip) :: i,j !! counter integer(ip) :: n_edges !! number of edges character(len=:),allocatable :: attributes !! full attributes string for node or edge logical :: compress !! if we can write all the edges on one line character(len=*),parameter :: tab = ' ' !! for indenting character(len=*),parameter :: newline = new_line(' ') !! line break character if (me%n == 0) return str = 'digraph G {'//newline//newline if (present(rankdir)) & str = str//tab//'rankdir='//rankdir//newline//newline if (present(dpi)) & str = str//tab//'graph [ dpi = '//integer_to_string(dpi)//' ]'//newline//newline ! define the vertices: do i=1,me%n attributes = get_attributes_string(me%vertices(i)%label, & me%vertices(i)%attributes) str = str//tab//integer_to_string(i)//' '//attributes//newline if (i==me%n) str = str//newline end do ! define the dependencies: do i=1,me%n if (allocated(me%vertices(i)%edges)) then n_edges = size(me%vertices(i)%edges) ! if none of the edges have attributes, ! then we can write them all on one line ! otherwise, write them line by line compress = .true. do j = 1, n_edges if (allocated(me%vertices(i)%edges(j)%label) .or. & allocated(me%vertices(i)%edges(j)%attributes)) then compress = .false. exit end if end do if (.not. compress) then ! Example: 1 -> 2 [penwidth=2, arrowhead=none] do j=1,n_edges attributes = get_attributes_string(me%vertices(i)%edges(j)%label, & me%vertices(i)%edges(j)%attributes) str = str//tab//integer_to_string(i)//' -> '//& integer_to_string(me%vertices(i)%edges(j)%ivertex)//' '//attributes//newline end do else ! Example: 1 -> 2,5,10 str = str//tab//integer_to_string(i)// merge(' -> ',' ',n_edges/=0) do j=1,n_edges ! comma-separated list: str = str//integer_to_string(me%vertices(i)%edges(j)%ivertex) if (n_edges>1 .and. j<n_edges) str = str//',' end do str = str//';'//newline end if end if end do str = str//newline//'}' contains function get_attributes_string(label, attributes) result(str) !! create the full attributes string for an edge or node. character(len=:),allocatable,intent(in) :: label !! if not allocated or blank, then not used character(len=:),allocatable,intent(in) :: attributes !! if not allocated or blank, then not used character(len=:),allocatable :: str !! the attributes string, enclosed in brackets character(len=:),allocatable :: tmp_label logical :: has_label, has_attributes has_label = allocated(label) if (has_label) has_label = label /= '' if (has_label) tmp_label = 'label="'//trim(adjustl(label))//'"' has_attributes = allocated(attributes) if (has_attributes) has_attributes = attributes /= '' if (has_label .and. has_attributes) then str = '['//trim(adjustl(attributes))//','//tmp_label//']' elseif (has_label .and. .not. has_attributes) then str = '['//tmp_label//']' elseif (.not. has_label .and. has_attributes) then str = '['//trim(adjustl(attributes))//']' else ! neither str = '' end if end function get_attributes_string end function dag_generate_digraph