Coverage for /home/deng/Projects/ete4/hackathon/ete4/ete4/smartview/renderer/layouts/default_layouts.py: 22%

91 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-03-21 09:19 +0100

1from ..treelayout import TreeLayout 

2from ..nodestyle import NodeStyle 

3from ..faces import AttrFace, TextFace, OutlineFace, AlignLinkFace 

4 

5from ..draw_helpers import summary, Padding 

6 

7 

8__all__ = ['LayoutLeafName', 'LayoutNumberLeaves', 

9 'LayoutBranchLength', 'LayoutBranchSupport', 

10 'LayoutOutline'] 

11 

12 

13class LayoutLeafName(TreeLayout): 

14 def __init__(self, name='Leaf name', 

15 pos='branch_right', color='black', 

16 ftype='sans-serif', 

17 min_fsize=4, max_fsize=15, 

18 padding_x=5, padding_y=0): 

19 super().__init__(name) 

20 self.pos = pos 

21 self.aligned_faces = self.pos == 'aligned' 

22 self.color = color 

23 self.ftype = ftype 

24 self.min_fsize = min_fsize 

25 self.max_fsize = max_fsize 

26 self.padding = Padding(padding_x, padding_y) 

27 

28 self.face = AttrFace( 

29 attr='name', name='leaf_name', 

30 ftype=self.ftype, 

31 min_fsize=self.min_fsize, max_fsize=self.max_fsize, 

32 color=self.color, padding_x=self.padding.x, padding_y=self.padding.y) 

33 

34 def set_node_style(self, node): 

35 if node.is_leaf: 

36 node.add_face(self.face, position=self.pos, column=1) 

37 else: 

38 # Collapsed face 

39 names = summary(node.children) 

40 texts = names if len(names) < 6 else (names[:3] + ['...'] + names[-2:]) 

41 for i, text in enumerate(texts): 

42 node.add_face(TextFace(text, name='leaf_name', 

43 color=self.color, ftype=self.ftype, 

44 min_fsize=self.min_fsize, max_fsize=self.max_fsize, 

45 padding_x=self.padding.x, padding_y=self.padding.y), 

46 position=self.pos, column=2, collapsed_only=True) 

47 

48 

49class LayoutNumberLeaves(TreeLayout): 

50 def __init__(self, name='Number of leaves', 

51 pos='branch_right', collapsed_only=True, 

52 formatter='(%s)', color='black', 

53 min_fsize=4, max_fsize=15, ftype='sans-serif', 

54 padding_x=5, padding_y=0): 

55 super().__init__(name) 

56 self.pos = pos 

57 self.aligned_faces = self.pos == 'aligned' 

58 self.color = color 

59 self.formatter = formatter 

60 self.ftype = ftype 

61 self.min_fsize = min_fsize 

62 self.max_fsize = max_fsize 

63 self.padding = Padding(padding_x, padding_y) 

64 

65 self.active = False 

66 

67 self.collapsed_only = collapsed_only 

68 

69 def set_node_style(self, node): 

70 if not node.is_leaf: 

71 face = TextFace( 

72 self.formatter % len(node), # number of leaves 

73 color=self.color, 

74 min_fsize=self.min_fsize, max_fsize=self.max_fsize, 

75 ftype=self.ftype, 

76 padding_x=self.padding.x, padding_y=self.padding.y) 

77 

78 node.add_face(face, position=self.pos, column=1, collapsed_only=True) 

79 

80 if not self.collapsed_only: 

81 node.add_face(face, position=self.pos, column=0) 

82 

83 

84def _get_layout_branch_attr(attr, pos, name=None, 

85 formatter=None, color='black', 

86 ftype='sans-serif', 

87 min_fsize=6, max_fsize=15, 

88 padding_x=0, padding_y=0): 

89 branch_attr_face = AttrFace(attr, 

90 formatter=formatter, 

91 name=name or f'branch_{attr}', 

92 color=color, ftype=ftype, 

93 min_fsize=min_fsize, max_fsize=max_fsize, 

94 padding_x=padding_x, 

95 padding_y=padding_y) 

96 

97 def layout_fn(node): 

98 # Skip adding faces in the following cases: 

99 if (attr not in node.props or # missing property 

100 node.dist == 0 or # no space for drawing 

101 node.is_leaf and attr == 'support'): # should be 1 

102 return # do not add faces 

103 

104 node.add_face(branch_attr_face, position=pos, column=0) 

105 node.add_face(branch_attr_face, position=pos, column=0, 

106 collapsed_only=True) 

107 

108 return layout_fn 

109 

110 

111class LayoutBranchLength(TreeLayout): 

112 def __init__(self, name='Branch length', 

113 pos='branch_top', 

114 formatter='%0.5s', 

115 color='#8d8d8d', ftype="sans-serif", 

116 min_fsize=6, max_fsize=15, 

117 padding_x=2, padding_y=0): 

118 super().__init__(name) 

119 self.pos = pos 

120 self.aligned_faces = self.pos == 'aligned' 

121 self.color = color 

122 self.formatter = formatter 

123 self.ftype = ftype 

124 self.min_fsize = min_fsize 

125 self.max_fsize = max_fsize 

126 self.padding = Padding(padding_x, padding_y) 

127 

128 self.set_node_style = _get_layout_branch_attr(attr='dist', 

129 formatter=formatter, 

130 name='Branch length', 

131 pos=pos, 

132 color=color, ftype=self.ftype, 

133 min_fsize=min_fsize, max_fsize=max_fsize, 

134 padding_x=padding_x, padding_y=padding_y) 

135 

136 

137class LayoutBranchSupport(TreeLayout): 

138 def __init__(self, name='Branch support', 

139 pos='branch_bottom', 

140 formatter='%0.4s', 

141 color='#fa8072', ftype="sans-serif", 

142 min_fsize=6, max_fsize=15, 

143 padding_x=2,padding_y=0): 

144 super().__init__(name) 

145 self.pos = pos 

146 self.aligned_faces = self.pos == 'aligned' 

147 self.color = color 

148 self.formatter = formatter 

149 self.ftype = ftype 

150 self.min_fsize = min_fsize 

151 self.max_fsize = max_fsize 

152 self.padding = Padding(padding_x, padding_y) 

153 

154 self.set_node_style = _get_layout_branch_attr(attr='support', 

155 formatter=formatter, 

156 name="Branch support", 

157 pos=pos, 

158 color=color, ftype=self.ftype, 

159 min_fsize=min_fsize, max_fsize=max_fsize, 

160 padding_x=padding_x, padding_y=padding_y) 

161 

162 

163class LayoutOutline(TreeLayout): 

164 def __init__(self, name=None, 

165 stroke_color="black", stroke_width=0.5, 

166 color="lightgray", opacity=0.3, collapsing_height=5): 

167 super().__init__(None) 

168 

169 self.always_render = True 

170 

171 self.face = OutlineFace(stroke_color="black", stroke_width=stroke_width, 

172 color=color, opacity=opacity, collapsing_height=collapsing_height) 

173 

174 def set_node_style(self, node): 

175 if not node.is_leaf: 

176 node.add_face(self.face, 

177 position="branch_right", column=0, 

178 collapsed_only=True) 

179 

180 

181def get_layout_align_link(stroke_color='gray', stroke_width=0.5, 

182 line_type=1, opacity=0.8): 

183 align_link_face = AlignLinkFace(stroke_color=stroke_color, 

184 stroke_width=stroke_width, 

185 line_type=line_type, 

186 opacity=opacity) 

187 def layout_fn(node): 

188 if node.is_leaf: 

189 node.add_face(align_link_face, 

190 position='branch_right', 

191 column=1e9) 

192 else: 

193 node.add_face(align_link_face, 

194 position='branch_right', 

195 column=1e9, 

196 collapsed_only=True) 

197 layout_fn.__name__ = 'Aligned panel link' 

198 layout_fn._module = 'default' 

199 return layout_fn