Coverage for source/plotting/plot_responsibility_chain_base.py: 100%

16 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-30 15:13 +0000

1# plotting/plot_responsibility_chain_base.py 

2 

3import matplotlib.pyplot as plt 

4from typing import Optional 

5 

6class PlotResponsibilityChainBase(): 

7 """ 

8 Base class for implementing the responsibility chain pattern for plotting. 

9 

10 This class provides a framework for creating a chain of plotting handlers where 

11 each handler can decide whether it can handle a specific plot request. If a handler 

12 cannot process the request, it passes the request to the next handler in the chain. 

13 All plotting chain implementations should inherit from this class and implement 

14 the _can_plot and _plot methods. 

15 """ 

16 

17 __next_chain_link: 'PlotResponsibilityChainBase' = None 

18 

19 def plot(self, data) -> Optional[plt.Axes]: 

20 """ 

21 Attempts to plot data by finding an appropriate handler in the chain. 

22 

23 Parameters: 

24 data (dict): Dictionary containing 'key' identifying the plot type 

25 and 'plot_data' containing the actual data to be plotted. 

26 

27 Returns: 

28 Optional[plt.Axes]: The matplotlib Axes object if plotting was successful, 

29 None if no handler in the chain could process the request. 

30 """ 

31 

32 key = data['key'] 

33 plot_data = data['plot_data'] 

34 

35 if (self._can_plot(key)): 

36 return self._plot(plot_data) 

37 else: 

38 if self.__next_chain_link is not None: 

39 return self.__next_chain_link.plot(data) 

40 else: 

41 return None 

42 

43 def add_next_chain_link(self, next_chain_link: 'PlotResponsibilityChainBase'): 

44 """ 

45 Adds the next handler to the responsibility chain. 

46 

47 Parameters: 

48 next_chain_link (PlotResponsibilityChainBase): The next handler to process 

49 requests if this handler cannot. 

50 """ 

51 

52 self.__next_chain_link = next_chain_link 

53 

54 def _can_plot(self, key: str) -> bool: 

55 """ 

56 Determines if this handler can plot the given plot type. 

57 

58 This is an abstract method that should be implemented by all subclasses. 

59 

60 Parameters: 

61 key (str): String identifier of the plot type. 

62 

63 Returns: 

64 bool: True if this handler can process the plot request, False otherwise. 

65 

66 Raises: 

67 NotImplementedError: If the method is not implemented by a subclass. 

68 """ 

69 

70 raise NotImplementedError("Subclasses must implement this method") 

71 

72 def _plot(self, plot_data: dict) -> plt.Axes: 

73 """ 

74 Generates the actual plot from the provided data. 

75 

76 This is an abstract method that should be implemented by all subclasses. 

77 The implementation should create and return a matplotlib plot based on 

78 the provided data. 

79 

80 Parameters: 

81 plot_data (dict): Dictionary containing the data needed for plotting. 

82 

83 Returns: 

84 plt.Axes: Matplotlib Axes object containing the generated plot. 

85 

86 Raises: 

87 NotImplementedError: If the method is not implemented by a subclass. 

88 """ 

89 

90 raise NotImplementedError("Subclasses must implement this method")