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
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-30 15:13 +0000
1# plotting/plot_responsibility_chain_base.py
3import matplotlib.pyplot as plt
4from typing import Optional
6class PlotResponsibilityChainBase():
7 """
8 Base class for implementing the responsibility chain pattern for plotting.
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 """
17 __next_chain_link: 'PlotResponsibilityChainBase' = None
19 def plot(self, data) -> Optional[plt.Axes]:
20 """
21 Attempts to plot data by finding an appropriate handler in the chain.
23 Parameters:
24 data (dict): Dictionary containing 'key' identifying the plot type
25 and 'plot_data' containing the actual data to be plotted.
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 """
32 key = data['key']
33 plot_data = data['plot_data']
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
43 def add_next_chain_link(self, next_chain_link: 'PlotResponsibilityChainBase'):
44 """
45 Adds the next handler to the responsibility chain.
47 Parameters:
48 next_chain_link (PlotResponsibilityChainBase): The next handler to process
49 requests if this handler cannot.
50 """
52 self.__next_chain_link = next_chain_link
54 def _can_plot(self, key: str) -> bool:
55 """
56 Determines if this handler can plot the given plot type.
58 This is an abstract method that should be implemented by all subclasses.
60 Parameters:
61 key (str): String identifier of the plot type.
63 Returns:
64 bool: True if this handler can process the plot request, False otherwise.
66 Raises:
67 NotImplementedError: If the method is not implemented by a subclass.
68 """
70 raise NotImplementedError("Subclasses must implement this method")
72 def _plot(self, plot_data: dict) -> plt.Axes:
73 """
74 Generates the actual plot from the provided data.
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.
80 Parameters:
81 plot_data (dict): Dictionary containing the data needed for plotting.
83 Returns:
84 plt.Axes: Matplotlib Axes object containing the generated plot.
86 Raises:
87 NotImplementedError: If the method is not implemented by a subclass.
88 """
90 raise NotImplementedError("Subclasses must implement this method")