Source code for ete4.smartview.renderer.nodestyle

import re

from ete4.utils import SVG_COLORS

_LINE_TYPE_CHECKER = lambda x: x in (0, 1, 2)  # 0 solid, 1 dashed, 2 dotted
_SIZE_CHECKER = lambda x: isinstance(x, int)
_COLOR_MATCH = re.compile("^#[A-Fa-f\d]{6}$")
_COLOR_CHECKER = lambda x: x.lower() in SVG_COLORS or re.match(_COLOR_MATCH, x)
_NODE_TYPE_CHECKER = lambda x: x in ["triangle", "circle", "square"]
_BOOL_CHECKER = lambda x: isinstance(x, bool) or x in (0, 1)
_FLOAT_CHECKER = lambda x: isinstance(x, float) or isinstance(x, int)


NODE_STYLE_DEFAULT = [
    ["fgcolor",            "#0030c1",     _COLOR_CHECKER],
    ["bgcolor",            "transparent", _COLOR_CHECKER],
    ["fgopacity",          1,             _FLOAT_CHECKER],
    ["outline_line_color", "#000000",     _COLOR_CHECKER],
    ["outline_line_width", 0.5,           _SIZE_CHECKER],
    ["outline_color",      "#e5e5e5",     _COLOR_CHECKER],
    ["outline_opacity",    0.3,           _FLOAT_CHECKER],
    ["vt_line_color",      "#000000",     _COLOR_CHECKER],
    ["hz_line_color",      "#000000",     _COLOR_CHECKER],
    ["hz_line_type",       0,             _LINE_TYPE_CHECKER],
    ["vt_line_type",       0,             _LINE_TYPE_CHECKER],
    ["size",               0,             _SIZE_CHECKER], # node circle size
    ["shape",              "circle",      _NODE_TYPE_CHECKER], # circle, square, triangle
    ["draw_descendants",   True,          _BOOL_CHECKER],
    ["hz_line_width",      0.5,           _SIZE_CHECKER],
    ["vt_line_width",      0.5,           _SIZE_CHECKER]
]


# _smfaces and faces are registered to allow deepcopy to work on nodes
VALID_NODE_STYLE_KEYS = {i[0] for i in NODE_STYLE_DEFAULT} | {"_smfaces"}

[docs] class NodeStyle(dict): """ Dictionary with all valid node graphical attributes. """
[docs] def __init__(self, *args, **kargs): """ For all possible parameters, see NODE_STYLE_DEFAULT. Some descriptions: :param True draw_descendants: Mark an internal node as a leaf. :param 0 hz_line_width: Horizontal line width in pixels. If 0 it is automatic (normally 1 pixel). :param 0 vt_line_width: Vertical line width in pixels. If 0 it is automatic (normally 1 pixel). """ super().__init__(*args, **kargs) self.init()
[docs] def init(self): for key, dvalue, checker in NODE_STYLE_DEFAULT: if key not in self: self[key] = dvalue elif not checker(self[key]): raise ValueError("'%s' attribute in node style has not a valid value: %s" % (key, self[key]))
def __setitem__(self, i, v): if i not in VALID_NODE_STYLE_KEYS: raise ValueError("'%s' is not a valid keyword for a NodeStyle instance" % i) super().__setitem__(i, v)