Source code for manim_extensions.mindmap.algorithms.layout_config

__all__ = [
    'LayoutConfig',
    'LayoutDirection',
    'LayoutType'
]
from enum import Enum
from typing import List,Dict
import numpy as np
from manim.constants import LEFT, RIGHT, UP, DOWN,PI

class LayoutDirection(Enum):
    '''Layout direction.

    '''
    LeftToRight = 'left to right'
    RightToLeft = 'right to left'
    TopToBottom = 'top to bottom'
    BottomToTop = 'bottom to top'

[docs] class LayoutType(Enum): '''Layout algorithm. ''' MindMap = 'tidytree' TimeLine = 'timeline' Standard = 'standard' Catalog = 'catalog'
[docs] class LayoutConfig: """ """
[docs] def __init__( self, direction:np.ndarray = RIGHT, node_spacing:float = 0.5, level_spacing:float = 0.5, sides:np.ndarray | List[np.ndarray] = (UP,DOWN) ): '''Layout parameters Parameters ---------- direction : np.ndarray, optional Layout direction. Defaults to RIGHT. node_spacing : float, optional Spacing between nodes. Defaults to 0.5. level_spacing : float, optional Spacing between layers. Defaults to 0.5. sides : np.ndarray | List[np.ndarray], optional Sides used for alternating timeline layouts; a single value means single-sided. Defaults to (UP,DOWN). ''' if not any(np.array_equal(direction, d) for d in [UP, DOWN, LEFT, RIGHT]): raise ValueError(f'direction must be one of {LEFT,RIGHT,UP,DOWN}') if not isinstance(sides, (list,tuple)): sides = (sides,) for side in sides: if not any(np.array_equal(side, d) for d in [UP, DOWN]): raise ValueError(f'side must be one of {UP,DOWN}') self.sides = tuple(self.get_layout_direction(side) for side in sides) self.layout_direction = self.get_layout_direction(direction) self.node_spacing = node_spacing self.level_spacing = level_spacing self.direction = direction
[docs] def get_layout_direction(self,direction:np.ndarray) -> LayoutDirection: """Convert a direction vector to a LayoutDirection enum.""" string = None if np.array_equal(direction,UP): string = LayoutDirection.BottomToTop elif np.array_equal(direction,DOWN): string = LayoutDirection.TopToBottom elif np.array_equal(direction,LEFT): string = LayoutDirection.RightToLeft elif np.array_equal(direction,RIGHT): string = LayoutDirection.LeftToRight return string
@property def catalog(self): return { 'node_spacing':self.node_spacing, 'level_spacing':self.level_spacing, } @catalog.setter def catalog( self, catalog:Dict = { 'node_spacing':0.5, 'level_spacing':0.5, } ): self.node_spacing = catalog.get('node_spacing',0.5) self.level_spacing = catalog.get('level_spacing',0.5) @property def mindmap(self): return { 'direction':self.layout_direction, 'node_spacing':self.node_spacing, 'level_spacing':self.level_spacing, } @mindmap.setter def mindmap( self, mindmap:Dict = { 'direction':RIGHT, 'node_spacing':0.5, 'level_spacing':0.5 } ): direction = mindmap.get('direction',RIGHT) if not any(np.array_equal(direction, d) for d in [UP, DOWN, LEFT, RIGHT]): raise ValueError(f'direction must be one of {LEFT,RIGHT,UP,DOWN}') self.direction = direction self.layout_direction = self.get_layout_direction(direction) self.node_spacing = mindmap.get('node_spacing',0.5) self.level_spacing = mindmap.get('level_spacing',0.5) @property def timeline(self): return { 'node_spacing':self.node_spacing, 'level_spacing':self.level_spacing, 'sides':self.sides, } @timeline.setter def timeline( self, timeline:Dict = { 'node_spacing':0.5, 'level_spacing':0.5, 'sides':(UP,DOWN) } ): self.node_spacing = timeline.get('node_spacing',0.5) self.level_spacing = timeline.get('level_spacing',0.5) sides = timeline.get('sides',(UP,DOWN)) if not isinstance(sides, (list,tuple)): sides = (sides,) for side in sides: if not any(np.array_equal(side, d) for d in [UP, DOWN]): raise ValueError(f'side must be one of {UP,DOWN}') self.sides = tuple(self.get_layout_direction(side) for side in sides)