job-shop-lib 1.0.0a3__py3-none-any.whl → 1.0.0a4__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. job_shop_lib/_job_shop_instance.py +104 -38
  2. job_shop_lib/_operation.py +12 -3
  3. job_shop_lib/_schedule.py +10 -12
  4. job_shop_lib/_scheduled_operation.py +15 -16
  5. job_shop_lib/dispatching/_dispatcher.py +12 -15
  6. job_shop_lib/dispatching/_dispatcher_observer_config.py +15 -2
  7. job_shop_lib/dispatching/_factories.py +2 -2
  8. job_shop_lib/dispatching/feature_observers/_composite_feature_observer.py +0 -1
  9. job_shop_lib/dispatching/feature_observers/_factory.py +21 -18
  10. job_shop_lib/dispatching/feature_observers/_is_completed_observer.py +1 -0
  11. job_shop_lib/dispatching/rules/_dispatching_rule_solver.py +1 -1
  12. job_shop_lib/generation/_general_instance_generator.py +33 -34
  13. job_shop_lib/generation/_instance_generator.py +14 -17
  14. job_shop_lib/generation/_transformations.py +11 -8
  15. job_shop_lib/graphs/__init__.py +3 -0
  16. job_shop_lib/graphs/_build_disjunctive_graph.py +41 -3
  17. job_shop_lib/graphs/graph_updaters/_graph_updater.py +11 -13
  18. job_shop_lib/graphs/graph_updaters/_residual_graph_updater.py +17 -20
  19. job_shop_lib/reinforcement_learning/__init__.py +16 -7
  20. job_shop_lib/reinforcement_learning/_multi_job_shop_graph_env.py +69 -57
  21. job_shop_lib/reinforcement_learning/_single_job_shop_graph_env.py +42 -31
  22. job_shop_lib/reinforcement_learning/_types_and_constants.py +2 -2
  23. job_shop_lib/visualization/__init__.py +24 -5
  24. job_shop_lib/visualization/_gantt_chart_creator.py +118 -80
  25. job_shop_lib/visualization/_gantt_chart_video_and_gif_creation.py +15 -11
  26. job_shop_lib/visualization/_plot_disjunctive_graph.py +382 -0
  27. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/METADATA +5 -5
  28. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/RECORD +31 -31
  29. job_shop_lib/visualization/_disjunctive_graph.py +0 -210
  30. /job_shop_lib/visualization/{_agent_task_graph.py → _plot_agent_task_graph.py} +0 -0
  31. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/LICENSE +0 -0
  32. {job_shop_lib-1.0.0a3.dist-info → job_shop_lib-1.0.0a4.dist-info}/WHEEL +0 -0
@@ -45,6 +45,7 @@ class SingleJobShopGraphEnv(gym.Env):
45
45
 
46
46
  Observation Space:
47
47
  A dictionary with the following keys:
48
+
48
49
  - "removed_nodes": Binary vector indicating removed graph nodes.
49
50
  - "edge_list": Matrix of graph edges in COO format.
50
51
  - Feature matrices: Keys corresponding to the composite observer
@@ -54,43 +55,76 @@ class SingleJobShopGraphEnv(gym.Env):
54
55
  MultiDiscrete space representing (job_id, machine_id) pairs.
55
56
 
56
57
  Render Modes:
57
- - "human": Displays the current Gantt chart.
58
- - "save_video": Saves a video of the complete Gantt chart.
59
- - "save_gif": Saves a GIF of the complete Gantt chart.
58
+
59
+ - "human": Displays the current Gantt chart.
60
+ - "save_video": Saves a video of the complete Gantt chart.
61
+ - "save_gif": Saves a GIF of the complete Gantt chart.
60
62
 
61
63
  Attributes:
62
64
  dispatcher:
63
65
  Manages the scheduling process. See
64
66
  :class:`~job_shop_lib.dispatching.Dispatcher`.
67
+
65
68
  composite_observer:
66
69
  A :class:`~job_shop_lib.dispatching.feature_observers.
67
70
  CompositeFeatureObserver` which aggregates features from multiple
68
71
  observers.
72
+
69
73
  graph_updater:
70
74
  Updates the graph representation after each action. See
71
75
  :class:`~job_shop_lib.graphs.GraphUpdater`.
76
+
72
77
  reward_function:
73
78
  Computes rewards for actions taken. See
74
79
  :class:`~job_shop_lib.reinforcement_learning.RewardObserver`.
80
+
75
81
  action_space:
76
82
  Defines the action space. The action is a tuple of two integers
77
83
  (job_id, machine_id). The machine_id can be -1 if the selected
78
84
  operation can only be scheduled in one machine.
85
+
79
86
  observation_space:
80
87
  Defines the observation space. The observation is a dictionary
81
88
  with the following keys:
89
+
82
90
  - "removed_nodes": Binary vector indicating removed graph nodes.
83
91
  - "edge_list": Matrix of graph edges in COO format.
84
92
  - Feature matrices: Keys corresponding to the composite observer
85
93
  features (e.g., "operations", "jobs", "machines").
94
+
86
95
  render_mode:
87
96
  The mode for rendering the environment ("human", "save_video",
88
97
  "save_gif").
98
+
89
99
  gantt_chart_creator:
90
100
  Creates Gantt chart visualizations. See
91
101
  :class:`~job_shop_lib.visualization.GanttChartCreator`.
102
+
92
103
  use_padding:
93
104
  Whether to use padding in observations. Padding maintains the
105
+ observation space shape when the number of nodes changes.
106
+
107
+ Args:
108
+ job_shop_graph:
109
+ The JobShopGraph instance representing the job shop problem.
110
+ feature_observer_configs:
111
+ A list of FeatureObserverConfig instances for the feature
112
+ observers.
113
+ reward_function_config:
114
+ The configuration for the reward function.
115
+ graph_updater_config:
116
+ The configuration for the graph updater.
117
+ ready_operations_filter:
118
+ The function to use for pruning dominated operations.
119
+ render_mode:
120
+ The mode for rendering the environment ("human", "save_video",
121
+ "save_gif").
122
+ render_config:
123
+ Configuration for rendering (e.g., paths for saving videos
124
+ or GIFs). See :class:`~job_shop_lib.visualization.RenderConfig`.
125
+ use_padding:
126
+ Whether to use padding in observations. Padding maintains the
127
+ observation space shape when the number of nodes changes.
94
128
  """
95
129
 
96
130
  metadata = {"render_modes": ["human", "save_video", "save_gif"]}
@@ -116,29 +150,6 @@ class SingleJobShopGraphEnv(gym.Env):
116
150
  render_config: RenderConfig | None = None,
117
151
  use_padding: bool = True,
118
152
  ) -> None:
119
- """Initializes the SingleJobShopGraphEnv environment.
120
-
121
- Args:
122
- job_shop_graph:
123
- The JobShopGraph instance representing the job shop problem.
124
- feature_observer_configs:
125
- A list of FeatureObserverConfig instances for the feature
126
- observers.
127
- reward_function_config:
128
- The configuration for the reward function.
129
- graph_updater_config:
130
- The configuration for the graph updater.
131
- ready_operations_filter:
132
- The function to use for pruning dominated operations.
133
- render_mode:
134
- The mode for rendering the environment ("human", "save_video",
135
- "save_gif").
136
- render_config:
137
- Configuration for rendering (e.g., paths for saving videos
138
- or GIFs).
139
- use_padding:
140
- Whether to use padding for the edge index.
141
- """
142
153
  super().__init__()
143
154
  # Used for resetting the environment
144
155
  self.initial_job_shop_graph = deepcopy(job_shop_graph)
@@ -236,16 +247,16 @@ class SingleJobShopGraphEnv(gym.Env):
236
247
 
237
248
  Returns:
238
249
  A tuple containing the following elements:
250
+
239
251
  - The observation of the environment.
240
252
  - The reward obtained.
241
253
  - Whether the environment is done.
242
254
  - Whether the episode was truncated (always False).
243
255
  - A dictionary with additional information. The dictionary
244
- contains the following keys:
245
- - "feature_names": The names of the features in the
246
- observation.
247
- - "available_operations": The operations that are ready to be
248
- scheduled.
256
+ contains the following keys: "feature_names", the names of the
257
+ features in the observation; "available_operations", the
258
+ operations that are ready to be scheduled.
259
+
249
260
  """
250
261
  job_id, machine_id = action
251
262
  operation = self.dispatcher.next_operation(job_id)
@@ -8,7 +8,7 @@ import numpy as np
8
8
 
9
9
  from job_shop_lib.dispatching.feature_observers import FeatureType
10
10
  from job_shop_lib.visualization import (
11
- GanttChartWrapperConfig,
11
+ PartialGanttChartPlotterConfig,
12
12
  GifConfig,
13
13
  VideoConfig,
14
14
  )
@@ -17,7 +17,7 @@ from job_shop_lib.visualization import (
17
17
  class RenderConfig(TypedDict, total=False):
18
18
  """Configuration needed to initialize the `GanttChartCreator` class."""
19
19
 
20
- gantt_chart_wrapper_config: GanttChartWrapperConfig
20
+ partial_gantt_chart_plotter_config: PartialGanttChartPlotterConfig
21
21
  video_config: VideoConfig
22
22
  gif_config: GifConfig
23
23
 
@@ -1,4 +1,19 @@
1
- """Package for visualization."""
1
+ """Contains functions and classes for visualizing job shop scheduling problems.
2
+
3
+ .. autosummary::
4
+
5
+ plot_gantt_chart
6
+ get_partial_gantt_chart_plotter
7
+ PartialGanttChartPlotter
8
+ create_gantt_chart_video
9
+ create_gantt_chart_gif
10
+ plot_disjunctive_graph
11
+ plot_agent_task_graph
12
+ GanttChartCreator
13
+ GifConfig
14
+ VideoConfig
15
+
16
+ """
2
17
 
3
18
  from job_shop_lib.visualization._plot_gantt_chart import plot_gantt_chart
4
19
  from job_shop_lib.visualization._gantt_chart_video_and_gif_creation import (
@@ -8,17 +23,19 @@ from job_shop_lib.visualization._gantt_chart_video_and_gif_creation import (
8
23
  get_partial_gantt_chart_plotter,
9
24
  create_video_from_frames,
10
25
  create_gif_from_frames,
26
+ PartialGanttChartPlotter,
11
27
  )
12
- from job_shop_lib.visualization._disjunctive_graph import (
28
+ from job_shop_lib.visualization._plot_disjunctive_graph import (
13
29
  plot_disjunctive_graph,
30
+ duration_labeler,
14
31
  )
15
- from job_shop_lib.visualization._agent_task_graph import (
32
+ from job_shop_lib.visualization._plot_agent_task_graph import (
16
33
  plot_agent_task_graph,
17
34
  three_columns_layout,
18
35
  )
19
36
  from job_shop_lib.visualization._gantt_chart_creator import (
20
37
  GanttChartCreator,
21
- GanttChartWrapperConfig,
38
+ PartialGanttChartPlotterConfig,
22
39
  GifConfig,
23
40
  VideoConfig,
24
41
  )
@@ -35,7 +52,9 @@ __all__ = [
35
52
  "plot_agent_task_graph",
36
53
  "three_columns_layout",
37
54
  "GanttChartCreator",
38
- "GanttChartWrapperConfig",
55
+ "PartialGanttChartPlotterConfig",
39
56
  "GifConfig",
40
57
  "VideoConfig",
58
+ "PartialGanttChartPlotter",
59
+ "duration_labeler",
41
60
  ]
@@ -1,7 +1,6 @@
1
1
  """Home of the `GanttChartCreator` class and its configuration types."""
2
2
 
3
3
  from typing import TypedDict
4
-
5
4
  import matplotlib.pyplot as plt
6
5
 
7
6
  from job_shop_lib.dispatching import (
@@ -15,57 +14,87 @@ from job_shop_lib.visualization import (
15
14
  )
16
15
 
17
16
 
18
- class GanttChartWrapperConfig(TypedDict, total=False):
19
- """Configuration for creating the plot function with the
20
- `plot_gantt_chart_wrapper` function."""
17
+ class PartialGanttChartPlotterConfig(TypedDict, total=False):
18
+ """A dictionary with the configuration for creating the
19
+ :class:`PartialGanttChartPlotter` function.
20
+
21
+ .. seealso::
22
+
23
+ - :class:`PartialGanttChartPlotter`
24
+ - :func:`get_partial_gantt_chart_plotter`
25
+ """
21
26
 
22
27
  title: str | None
28
+ """The title of the Gantt chart."""
29
+
23
30
  cmap: str
31
+ """The colormap to use in the Gantt chart."""
32
+
24
33
  show_available_operations: bool
34
+ """Whether to show available operations in each step."""
25
35
 
26
36
 
27
- # We can't use Required here because it's not available in Python 3.10
28
- class _GifConfigRequired(TypedDict):
29
- """Required configuration for creating the GIF."""
37
+ class GifConfig(TypedDict, total=False):
38
+ """A dictionary with the configuration for creating the GIF using the
39
+ :func:`create_gantt_chart_gif` function.
30
40
 
31
- gif_path: str | None
41
+ .. seealso::
32
42
 
43
+ :func:`create_gantt_chart_gif`
44
+ """
33
45
 
34
- class _GifConfigOptional(TypedDict, total=False):
35
- """Optional configuration for creating the GIF."""
46
+ gif_path: str | None
47
+ """The path to save the GIF. It must end with '.gif'."""
36
48
 
37
49
  fps: int
50
+ """The frames per second of the GIF. Defaults to 1."""
51
+
38
52
  remove_frames: bool
39
- frames_dir: str | None
40
- plot_current_time: bool
53
+ """Whether to remove the frames after creating the GIF."""
41
54
 
55
+ frames_dir: str | None
56
+ """The directory to store the frames."""
42
57
 
43
- class GifConfig(_GifConfigRequired, _GifConfigOptional):
44
- """Configuration for creating the GIF using the `create_gannt_chart_video`
45
- function."""
58
+ plot_current_time: bool
59
+ """Whether to plot the current time in the Gantt chart."""
46
60
 
47
61
 
48
62
  class VideoConfig(TypedDict, total=False):
49
63
  """Configuration for creating the video using the
50
- `create_gannt_chart_video` function."""
64
+ :func:`create_gantt_chart_video` function.
65
+
66
+ .. seealso::
67
+
68
+ :func:`create_gantt_chart_video`
69
+ """
51
70
 
52
71
  video_path: str | None
72
+ """The path to save the video. It must end with a valid video extension
73
+ (e.g., '.mp4')."""
74
+
53
75
  fps: int
76
+ """The frames per second of the video. Defaults to 1."""
77
+
54
78
  remove_frames: bool
79
+ """Whether to remove the frames after creating the video."""
80
+
55
81
  frames_dir: str | None
82
+ """The directory to store the frames."""
83
+
56
84
  plot_current_time: bool
85
+ """Whether to plot the current time in the Gantt chart."""
57
86
 
58
87
 
59
88
  class GanttChartCreator:
60
89
  """Facade class that centralizes the creation of Gantt charts, videos
61
90
  and GIFs.
62
91
 
63
- It leverages a `HistoryObserver` to keep track of the operations being
64
- scheduled and provides methods to plot the current state
65
- of the schedule as a Gantt chart and to create a GIF that shows the
66
- evolution of the schedule over time.
92
+ It leverages a :class:`HistoryObserver` to keep track of the operations
93
+ being scheduled and provides methods to plot the current state
94
+ of the schedule as a Gantt chart and to create a GIF or video that shows
95
+ the evolution of the schedule over time.
67
96
 
68
- It adds a new `HistoryObserver` to the dispatcher if it does
97
+ It adds a new :class:`HistoryObserver` to the dispatcher if it does
69
98
  not have one already. Otherwise, it uses the observer already present.
70
99
 
71
100
  Attributes:
@@ -81,72 +110,80 @@ class GanttChartCreator:
81
110
  Configuration for creating the video.
82
111
  plot_function:
83
112
  The function used to plot the Gantt chart when creating the GIF
84
- or video. Created using the `plot_gantt_chart_wrapper` function.
113
+ or video. Created using the :func:`get_partial_gantt_chart_plotter`
114
+ function.
115
+
116
+ Args:
117
+ dispatcher:
118
+ The :class:`Dispatcher` class that will be tracked using a
119
+ :class:`HistoryObserver`.
120
+ partial_gantt_chart_plotter_config:
121
+ Configuration for the Gantt chart wrapper function through the
122
+ :class:`PartialGanttChartPlotterConfig` class. Defaults to
123
+ ``None``. Valid keys are:
124
+
125
+ - title: The title of the Gantt chart.
126
+ - cmap: The name of the colormap to use.
127
+ - show_available_operations: Whether to show available
128
+ operations in each step.
129
+
130
+ If ``title`` or ``cmap`` are not provided here and
131
+ ``infer_gantt_chart_config`` is set to ``True``, the values from
132
+ ``gantt_chart_config`` will be used if they are present.
133
+
134
+ .. seealso::
135
+
136
+ - :class:`PartialGanttChartPlotterConfig`
137
+ - :func:`get_partial_gantt_chart_plotter`
138
+ - :class:`PartialGanttChartPlotter`
139
+
140
+ gif_config:
141
+ Configuration for creating the GIF. Defaults to ``None``.
142
+ Valid keys are:
143
+
144
+ - gif_path: The path to save the GIF.
145
+ - fps: The frames per second of the GIF.
146
+ - remove_frames: Whether to remove the frames after creating
147
+ the GIF.
148
+ - frames_dir: The directory to store the frames.
149
+ - plot_current_time: Whether to plot the current time in the
150
+ Gantt chart.
151
+ video_config:
152
+ Configuration for creating the video. Defaults to ``None``.
153
+ Valid keys are:
154
+
155
+ - video_path: The path to save the video.
156
+ - fps: The frames per second of the video.
157
+ - remove_frames: Whether to remove the frames after creating
158
+ the video.
159
+ - frames_dir: The directory to store the frames.
160
+ - plot_current_time: Whether to plot the current time in the
161
+ Gantt chart.
85
162
  """
86
163
 
87
164
  def __init__(
88
165
  self,
89
166
  dispatcher: Dispatcher,
90
- gantt_chart_wrapper_config: GanttChartWrapperConfig | None = None,
167
+ partial_gantt_chart_plotter_config: (
168
+ PartialGanttChartPlotterConfig | None
169
+ ) = None,
91
170
  gif_config: GifConfig | None = None,
92
171
  video_config: VideoConfig | None = None,
93
172
  ):
94
- """Initializes the GanttChartCreator with the given configurations
95
- and history observer.
96
-
97
- This class adds a new `HistoryObserver` to the dispatcher if it does
98
- not have one already. Otherwise, it uses the observer already present.
99
-
100
- Args:
101
- dispatcher:
102
- The `Dispatcher` class that will be tracked using a
103
- `HistoryObserver`.
104
- gantt_chart_wrapper_config:
105
- Configuration for the Gantt chart wrapper function. Valid keys
106
- are:
107
- - title: The title of the Gantt chart.
108
- - cmap: The name of the colormap to use.
109
- - show_available_operations: Whether to show available
110
- operations in each step.
111
-
112
- If `title` or `cmap` are not provided here and
113
- `infer_gantt_chart_config` is set to True, the values from
114
- `gantt_chart_config` will be used if they are present.
115
- gif_config:
116
- Configuration for creating the GIF. Defaults to None.
117
- Valid keys are:
118
- - gif_path: The path to save the GIF.
119
- - fps: The frames per second of the GIF.
120
- - remove_frames: Whether to remove the frames after creating
121
- the GIF.
122
- - frames_dir: The directory to store the frames.
123
- - plot_current_time: Whether to plot the current time in the
124
- Gantt chart.
125
- video_config:
126
- Configuration for creating the video. Defaults to None.
127
- Valid keys are:
128
- - video_path: The path to save the video.
129
- - fps: The frames per second of the video.
130
- - remove_frames: Whether to remove the frames after creating
131
- the video.
132
- - frames_dir: The directory to store the frames.
133
- - plot_current_time: Whether to plot the current time in the
134
- Gantt chart.
135
- """
136
173
  if gif_config is None:
137
- gif_config = {"gif_path": None}
138
- if gantt_chart_wrapper_config is None:
139
- gantt_chart_wrapper_config = {}
174
+ gif_config = {}
175
+ if partial_gantt_chart_plotter_config is None:
176
+ partial_gantt_chart_plotter_config = {}
140
177
  if video_config is None:
141
178
  video_config = {}
142
179
 
143
180
  self.gif_config = gif_config
144
- self.gannt_chart_wrapper_config = gantt_chart_wrapper_config
181
+ self.gannt_chart_wrapper_config = partial_gantt_chart_plotter_config
145
182
  self.video_config = video_config
146
183
  self.history_observer: HistoryObserver = (
147
184
  dispatcher.create_or_get_observer(HistoryObserver)
148
185
  )
149
- self.plot_function = get_partial_gantt_chart_plotter(
186
+ self.partial_gantt_chart_plotter = get_partial_gantt_chart_plotter(
150
187
  **self.gannt_chart_wrapper_config
151
188
  )
152
189
 
@@ -169,37 +206,38 @@ class GanttChartCreator:
169
206
  """Plots the current Gantt chart of the schedule.
170
207
 
171
208
  Returns:
172
- tuple[plt.Figure, plt.Axes]:
173
- The figure and axes of the plotted Gantt chart.
209
+ The figure of the plotted Gantt chart.
174
210
  """
175
- return self.plot_function(
211
+ a = self.partial_gantt_chart_plotter(
176
212
  self.schedule,
177
213
  None,
178
214
  self.dispatcher.available_operations(),
179
215
  self.dispatcher.current_time(),
180
216
  )
217
+ return a
181
218
 
182
219
  def create_gif(self) -> None:
183
220
  """Creates a GIF of the schedule being built using the recorded
184
221
  history.
185
222
 
186
223
  This method uses the history of scheduled operations recorded by the
187
- `HistoryTracker` to create a GIF that shows the progression of the
188
- scheduling process.
224
+ :class:`HistoryTracker` to create a GIF that shows the progression of
225
+ the scheduling process.
189
226
 
190
227
  The GIF creation process involves:
228
+
191
229
  - Using the history of scheduled operations to generate frames for
192
230
  each step of the schedule.
193
231
  - Creating a GIF from these frames.
194
232
  - Optionally, removing the frames after the GIF is created.
195
233
 
196
234
  The configuration for the GIF creation can be customized through the
197
- `gif_config` attribute.
235
+ ``gif_config`` attribute.
198
236
  """
199
237
  create_gantt_chart_gif(
200
238
  instance=self.history_observer.dispatcher.instance,
201
239
  schedule_history=self.history_observer.history,
202
- plot_function=self.plot_function,
240
+ plot_function=self.partial_gantt_chart_plotter,
203
241
  **self.gif_config
204
242
  )
205
243
 
@@ -208,12 +246,12 @@ class GanttChartCreator:
208
246
  history.
209
247
 
210
248
  This method uses the history of scheduled operations recorded by the
211
- `HistoryTracker` to create a video that shows the progression of the
212
- scheduling process.
249
+ :class:`HistoryTracker` to create a video that shows the progression
250
+ of the scheduling process.
213
251
  """
214
252
  create_gantt_chart_video(
215
253
  instance=self.history_observer.dispatcher.instance,
216
254
  schedule_history=self.history_observer.history,
217
- plot_function=self.plot_function,
255
+ plot_function=self.partial_gantt_chart_plotter,
218
256
  **self.video_config
219
257
  )
@@ -38,16 +38,6 @@ class PartialGanttChartPlotter(Protocol):
38
38
 
39
39
  This kind of functions are created using the
40
40
  :func:`plot_gantt_chart_wrapper` function.
41
-
42
- The function should take the following arguments:
43
-
44
- - schedule: The schedule to plot.
45
- - makespan: The makespan of the schedule if known. Can be used to fix the
46
- x-axis limits.
47
- - available_operations: A list of available operations. If ``None``,
48
- the available operations are not shown.
49
- - current_time: The current time in the schedule. If provided, a red
50
- vertical line is plotted at this time.
51
41
  """
52
42
 
53
43
  def __call__(
@@ -57,7 +47,21 @@ class PartialGanttChartPlotter(Protocol):
57
47
  available_operations: list[Operation] | None = None,
58
48
  current_time: int | None = None,
59
49
  ) -> Figure:
60
- pass
50
+ """Plots a Gantt chart for an unfinished schedule.
51
+
52
+ Args:
53
+ schedule:
54
+ The schedule to plot.
55
+ makespan:
56
+ The makespan of the schedule if known. Can be used to fix
57
+ the x-axis limits.
58
+ available_operations:
59
+ A list of available operations. If ``None``,
60
+ the available operations are not shown.
61
+ current_time:
62
+ The current time in the schedule. If provided, a red
63
+ vertical line is plotted at this time.
64
+ """
61
65
 
62
66
 
63
67
  def get_partial_gantt_chart_plotter(