diff --git a/b_asic/schedule.py b/b_asic/schedule.py
index 7b8ad21dd39cf061465c57bbc94a3f64395ed25f..8c7e4e468df9f616c11f8deb81c29532df5514ef 100644
--- a/b_asic/schedule.py
+++ b/b_asic/schedule.py
@@ -78,19 +78,21 @@ class Schedule:
         else:
             self._schedule_time = schedule_time
 
-    def start_time_of_operation(self, op_id: GraphID) -> int:
+    def start_time_of_operation(self, graph_id: GraphID) -> int:
         """
-        Get the start time of the operation with the specified by the op_id.
+        Get the start time of the operation with the specified by *graph_id*.
         """
-        if op_id not in self._start_times:
-            raise ValueError(f"No operation with op_id {op_id} in schedule")
-        return self._start_times[op_id]
+        if graph_id not in self._start_times:
+            raise ValueError(
+                f"No operation with graph_id {graph_id} in schedule"
+            )
+        return self._start_times[graph_id]
 
     def get_max_end_time(self) -> int:
         """Returns the current maximum end time among all operations."""
         max_end_time = 0
-        for op_id, op_start_time in self._start_times.items():
-            op = cast(Operation, self._sfg.find_by_id(op_id))
+        for graph_id, op_start_time in self._start_times.items():
+            op = cast(Operation, self._sfg.find_by_id(graph_id))
             for outport in op.outputs:
                 max_end_time = max(
                     max_end_time,
@@ -98,11 +100,13 @@ class Schedule:
                 )
         return max_end_time
 
-    def forward_slack(self, op_id: GraphID) -> int:
-        if op_id not in self._start_times:
-            raise ValueError(f"No operation with op_id {op_id} in schedule")
+    def forward_slack(self, graph_id: GraphID) -> int:
+        if graph_id not in self._start_times:
+            raise ValueError(
+                f"No operation with graph_id {graph_id} in schedule"
+            )
         slack = sys.maxsize
-        output_slacks = self._forward_slacks(op_id)
+        output_slacks = self._forward_slacks(graph_id)
         # Make more pythonic
         for signal_slacks in output_slacks.values():
             for signal_slack in signal_slacks.values():
@@ -110,11 +114,11 @@ class Schedule:
         return slack
 
     def _forward_slacks(
-        self, op_id: GraphID
+        self, graph_id: GraphID
     ) -> Dict["OutputPort", Dict["Signal", int]]:
         ret = {}
-        start_time = self._start_times[op_id]
-        op = cast(Operation, self._sfg.find_by_id(op_id))
+        start_time = self._start_times[graph_id]
+        op = cast(Operation, self._sfg.find_by_id(graph_id))
         for output_port in op.outputs:
             output_slacks = {}
             available_time = start_time + cast(int, output_port.latency_offset)
@@ -130,11 +134,13 @@ class Schedule:
             ret[output_port] = output_slacks
         return ret
 
-    def backward_slack(self, op_id: GraphID) -> int:
-        if op_id not in self._start_times:
-            raise ValueError(f"No operation with op_id {op_id} in schedule")
+    def backward_slack(self, graph_id: GraphID) -> int:
+        if graph_id not in self._start_times:
+            raise ValueError(
+                f"No operation with graph_id {graph_id} in schedule"
+            )
         slack = sys.maxsize
-        input_slacks = self._backward_slacks(op_id)
+        input_slacks = self._backward_slacks(graph_id)
         # Make more pythonic
         for signal_slacks in input_slacks.values():
             for signal_slack in signal_slacks.values():
@@ -142,11 +148,11 @@ class Schedule:
         return slack
 
     def _backward_slacks(
-        self, op_id: GraphID
+        self, graph_id: GraphID
     ) -> Dict[InputPort, Dict[Signal, int]]:
         ret = {}
-        start_time = self._start_times[op_id]
-        op = cast(Operation, self._sfg.find_by_id(op_id))
+        start_time = self._start_times[graph_id]
+        op = cast(Operation, self._sfg.find_by_id(graph_id))
         for input_port in op.inputs:
             input_slacks = {}
             usage_time = start_time + cast(int, input_port.latency_offset)
@@ -162,10 +168,12 @@ class Schedule:
             ret[input_port] = input_slacks
         return ret
 
-    def slacks(self, op_id: GraphID) -> Tuple[int, int]:
-        if op_id not in self._start_times:
-            raise ValueError(f"No operation with op_id {op_id} in schedule")
-        return self.backward_slack(op_id), self.forward_slack(op_id)
+    def slacks(self, graph_id: GraphID) -> Tuple[int, int]:
+        if graph_id not in self._start_times:
+            raise ValueError(
+                f"No operation with graph_id {graph_id} in schedule"
+            )
+        return self.backward_slack(graph_id), self.forward_slack(graph_id)
 
     def print_slacks(self) -> None:
         raise NotImplementedError
@@ -212,9 +220,9 @@ class Schedule:
         self._start_times = {
             k: factor * v for k, v in self._start_times.items()
         }
-        for op_id in self._start_times:
+        for graph_id in self._start_times:
             cast(
-                Operation, self._sfg.find_by_id(op_id)
+                Operation, self._sfg.find_by_id(graph_id)
             )._increase_time_resolution(factor)
         self._schedule_time *= factor
         return self
@@ -227,8 +235,8 @@ class Schedule:
         # Local values
         ret = [self._schedule_time, *self._start_times.values()]
         # Loop over operations
-        for op_id in self._start_times:
-            op = cast(Operation, self._sfg.find_by_id(op_id))
+        for graph_id in self._start_times:
+            op = cast(Operation, self._sfg.find_by_id(graph_id))
             ret += [cast(int, op.execution_time), *op.latency_offsets.values()]
         # Remove not set values (None)
         ret = [v for v in ret if v is not None]
@@ -265,26 +273,28 @@ class Schedule:
         self._start_times = {
             k: v // factor for k, v in self._start_times.items()
         }
-        for op_id in self._start_times:
+        for graph_id in self._start_times:
             cast(
-                Operation, self._sfg.find_by_id(op_id)
+                Operation, self._sfg.find_by_id(graph_id)
             )._decrease_time_resolution(factor)
         self._schedule_time = self._schedule_time // factor
         return self
 
-    def move_operation(self, op_id: GraphID, time: int) -> "Schedule":
-        if op_id not in self._start_times:
-            raise ValueError(f"No operation with op_id {op_id} in schedule")
+    def move_operation(self, graph_id: GraphID, time: int) -> "Schedule":
+        if graph_id not in self._start_times:
+            raise ValueError(
+                f"No operation with graph_id {graph_id} in schedule"
+            )
 
-        (backward_slack, forward_slack) = self.slacks(op_id)
+        (backward_slack, forward_slack) = self.slacks(graph_id)
         if not -backward_slack <= time <= forward_slack:
             raise ValueError
 
-        tmp_start = self._start_times[op_id] + time
+        tmp_start = self._start_times[graph_id] + time
         new_start = tmp_start % self._schedule_time
 
         # Update input laps
-        input_slacks = self._backward_slacks(op_id)
+        input_slacks = self._backward_slacks(graph_id)
         for in_port, signal_slacks in input_slacks.items():
             tmp_usage = tmp_start + cast(int, in_port.latency_offset)
             new_usage = tmp_usage % self._schedule_time
@@ -311,7 +321,7 @@ class Schedule:
                 self._laps[signal.graph_id] = laps
 
         # Update output laps
-        output_slacks = self._forward_slacks(op_id)
+        output_slacks = self._forward_slacks(graph_id)
         for out_port, signal_slacks in output_slacks.items():
             tmp_available = tmp_start + cast(int, out_port.latency_offset)
             new_available = tmp_available % self._schedule_time
@@ -327,7 +337,7 @@ class Schedule:
                 self._laps[signal.graph_id] = laps
 
         # Set new start time
-        self._start_times[op_id] = new_start
+        self._start_times[graph_id] = new_start
         return self
 
     def _remove_delays(self) -> None:
@@ -434,8 +444,8 @@ class Schedule:
 
     def _get_memory_variables_list(self) -> List['Process']:
         ret: List['Process'] = []
-        for op_id, start_time in self._start_times.items():
-            slacks = self._forward_slacks(op_id)
+        for graph_id, start_time in self._start_times.items():
+            slacks = self._forward_slacks(graph_id)
             for outport, signals in slacks.items():
                 reads = {
                     cast(InputPort, signal.destination): slack
@@ -450,8 +460,8 @@ class Schedule:
                 )
         return ret
 
-    def _get_y_position(self, op_id):
-        y_location = self._y_locations[op_id]
+    def _get_y_position(self, graph_id):
+        y_location = self._y_locations[graph_id]
         if y_location == None:
             # Assign the lowest row number not yet in use
             used = set(
@@ -459,7 +469,7 @@ class Schedule:
             )
             possible = set(range(len(self._start_times))) - used
             y_location = min(possible)
-            self._y_locations[op_id] = y_location
+            self._y_locations[graph_id] = y_location
         return OPERATION_GAP + y_location * (1 + OPERATION_GAP)
 
     def _plot_schedule(self, ax):
@@ -559,9 +569,9 @@ class Schedule:
         yticklabels = []
         ax.set_axisbelow(True)
         ax.grid()
-        for op_id, op_start_time in self._start_times.items():
-            ypos = -self._get_y_position(op_id)
-            op = self._sfg.find_by_id(op_id)
+        for graph_id, op_start_time in self._start_times.items():
+            ypos = -self._get_y_position(graph_id)
+            op = self._sfg.find_by_id(graph_id)
             # Rewrite to make better use of NumPy
             latency_coords, execution_time_coords = op.get_plot_coordinates()
             _x, _y = zip(*latency_coords)
@@ -581,12 +591,12 @@ class Schedule:
                     linewidth=3,
                 )
             ytickpositions.append(ypos + 0.5)
-            yticklabels.append(self._sfg.find_by_id(op_id).name)
+            yticklabels.append(self._sfg.find_by_id(graph_id).name)
 
-        for op_id, op_start_time in self._start_times.items():
-            op = self._sfg.find_by_id(op_id)
+        for graph_id, op_start_time in self._start_times.items():
+            op = self._sfg.find_by_id(graph_id)
             _, out_coords = op.get_io_coordinates()
-            source_ypos = -self._get_y_position(op_id)
+            source_ypos = -self._get_y_position(graph_id)
 
             for output_port in op.outputs:
                 for output_signal in output_port.signals:
@@ -604,7 +614,7 @@ class Schedule:
                         dest_in_coords[output_signal.destination.index],
                         [op_start_time, source_ypos],
                         [dest_start_time, dest_ypos],
-                        name=op_id,
+                        name=graph_id,
                         laps=self._laps[output_signal.graph_id],
                     )
 
@@ -612,8 +622,8 @@ class Schedule:
         ax.set_yticklabels(yticklabels)
 
         # Get operation with maximum position
-        max_pos_op_id = max(self._y_locations, key=self._y_locations.get)
-        yposmin = -self._get_y_position(max_pos_op_id) - OPERATION_GAP
+        max_pos_graph_id = max(self._y_locations, key=self._y_locations.get)
+        yposmin = -self._get_y_position(max_pos_graph_id) - OPERATION_GAP
         ax.axis([-1, self._schedule_time + 1, yposmin, 1])
         ax.xaxis.set_major_locator(MaxNLocator(integer=True))
         ax.add_line(
diff --git a/b_asic/scheduler_gui/axes_item.py b/b_asic/scheduler_gui/axes_item.py
index adea4568f3cecae757f6ca2d20eb173198653b20..bd695698f02116497a2edb3228c9af2610ab9cf4 100644
--- a/b_asic/scheduler_gui/axes_item.py
+++ b/b_asic/scheduler_gui/axes_item.py
@@ -129,10 +129,10 @@ class AxesItem(QGraphicsItemGroup):
         """
         return self._height
 
-    # @height.setter
-    # def height(self, height: int) -> None:
-    #     if self._height != height:
-    #         self.update_axes(height = height)
+    @height.setter
+    def height(self, height: int) -> None:
+        if self._height != height:
+            self.update_axes(height=height)
 
     # @property
     # def width_indent(self) -> float:
@@ -154,12 +154,13 @@ class AxesItem(QGraphicsItemGroup):
         self._event_items.append(item)
 
     def set_height(self, height: int) -> "AxesItem":
-        # TODO: implement, docstring
+        # TODO: docstring
         if height < 0:
             raise ValueError(
                 f"'height' greater or equal to 0 expected, got: {height}."
             )
-        raise NotImplementedError
+        self._height = height
+        self._update_yaxis()
 
     def set_width(self, width: int) -> "AxesItem":
         # TODO: docstring
@@ -275,6 +276,20 @@ class AxesItem(QGraphicsItemGroup):
             self._x_scale_labels[index + 1].setText(str(index + 1))
             self._x_scale[index + 1].setX(self._x_scale[index + 1].x() + 1)
 
+    def _update_yaxis(self) -> None:
+        self._y_axis.setLine(
+            0,
+            0,
+            0,
+            -(
+                self._height_indent
+                + self._height
+                + self._height_padding
+                + 0.05
+            ),
+        )
+        self._y_axis.setPen(self._base_pen)
+
     def _make_base(self) -> None:
         # x axis
         self._x_axis.setLine(0, 0, self._width_indent + self._width_padding, 0)
@@ -322,16 +337,5 @@ class AxesItem(QGraphicsItemGroup):
         )  # move timeline
 
         # y-axis
-        self._y_axis.setLine(
-            0,
-            0,
-            0,
-            -(
-                self._height_indent
-                + self._height
-                + self._height_padding
-                + 0.05
-            ),
-        )
-        self._y_axis.setPen(self._base_pen)
+        self._update_yaxis()
         self.addToGroup(self._y_axis)
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index 936d4ebcbc8630e55192649f1b4371372f0bd2c5..f94f80c392f040414806b2ff95123dbe2261b390 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -10,6 +10,7 @@ Start main-window with start_gui().
 import inspect
 import os
 import sys
+import webbrowser
 from copy import deepcopy
 from importlib.machinery import SourceFileLoader
 from typing import Optional, Union, cast
@@ -123,8 +124,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.menu_quit.triggered.connect(self.close)
         self.menu_node_info.triggered.connect(self.show_info_table)
         self.menu_exit_dialog.triggered.connect(self.hide_exit_dialog)
+        self.actionReorder.triggered.connect(self._actionReorder)
         self.actionT.triggered.connect(self._actionTbtn)
         self.splitter.splitterMoved.connect(self._splitter_moved)
+        self.actionDocumentation.triggered.connect(self._open_documentation)
 
         # Setup event member functions
         self.closeEvent = self._close_event
@@ -170,6 +173,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             print(f"filtersChildEvents(): {self._graph.filtersChildEvents()}")
         # self._printButtonPressed('callback_pushButton()')
 
+    @Slot()
+    def _open_documentation(self) -> None:
+        webbrowser.open_new_tab("https://da.gitlab-pages.liu.se/B-ASIC/")
+
+    @Slot()
+    def _actionReorder(self) -> None:
+        # TODO: remove
+        if self.schedule is None:
+            return
+        if self._graph is not None:
+            self._graph._redraw_from_start()
+        # self._printButtonPressed('callback_pushButton()')
+
     @Slot()
     def _load_schedule_from_pyfile(self) -> None:
         """SLOT() for SIGNAL(menu_load_from_file.triggered)
@@ -345,15 +361,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self._splitter_pos = width
 
     @Slot(str)
-    def info_table_update_component(self, op_id: GraphID) -> None:
+    def info_table_update_component(self, graph_id: GraphID) -> None:
         """
         SLOT(str) for SIGNAL(_graph._signals.component_selected)
         Takes in an operator-id, first clears the 'Operator' part of the info
         table and then fill in the table with new values from the operator
-        associated with 'op_id'.
+        associated with *graph_id*.
         """
         self.info_table_clear_component()
-        self._info_table_fill_component(op_id)
+        self._info_table_fill_component(graph_id)
 
     @Slot()
     def info_table_update_schedule(self) -> None:
@@ -508,15 +524,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         )
         self.info_table.setItem(2, 1, QTableWidgetItem(str(schedule.cyclic)))
 
-    def _info_table_fill_component(self, op_id: GraphID) -> None:
+    def _info_table_fill_component(self, graph_id: GraphID) -> None:
         """
         Take an operator-id and fill in the 'Operator' part of the info
-        table with values from the operator associated with *op_id*.
+        table with values from the operator associated with *graph_id*.
         """
         if self.schedule is None:
             return
         op: GraphComponent = cast(
-            GraphComponent, self.schedule.sfg.find_by_id(op_id)
+            GraphComponent, self.schedule.sfg.find_by_id(graph_id)
         )
         si = self.info_table.rowCount()  # si = start index
 
diff --git a/b_asic/scheduler_gui/main_window.ui b/b_asic/scheduler_gui/main_window.ui
index 38ac4579de59f9a08b50802562500aab0b5a8d4a..539d3281f3904e94a6988b4b0a6c56904ac849a9 100644
--- a/b_asic/scheduler_gui/main_window.ui
+++ b/b_asic/scheduler_gui/main_window.ui
@@ -18,7 +18,7 @@
    </sizepolicy>
   </property>
   <property name="windowIcon">
-   <iconset resource="icons/basic.qrc">
+   <iconset>
     <normaloff>:/icons/basic/small_logo.png</normaloff>:/icons/basic/small_logo.png</iconset>
   </property>
   <widget class="QWidget" name="centralwidget">
@@ -108,6 +108,12 @@
         <property name="text">
          <string>Property</string>
         </property>
+        <property name="font">
+         <font>
+          <weight>50</weight>
+          <bold>false</bold>
+         </font>
+        </property>
         <property name="textAlignment">
          <set>AlignLeading|AlignVCenter</set>
         </property>
@@ -126,7 +132,9 @@
         </property>
         <property name="font">
          <font>
-          <bold>true</bold>
+          <weight>50</weight>
+          <bold>false</bold>
+          <kerning>true</kerning>
          </font>
         </property>
         <property name="background">
@@ -157,7 +165,8 @@
         </property>
         <property name="font">
          <font>
-          <bold>true</bold>
+          <weight>50</weight>
+          <bold>false</bold>
          </font>
         </property>
         <property name="background">
@@ -224,10 +233,19 @@
     </property>
     <addaction name="menu_exit_dialog"/>
    </widget>
+   <widget class="QMenu" name="menuHelp">
+    <property name="title">
+     <string>&amp;Help</string>
+    </property>
+    <addaction name="actionDocumentation"/>
+    <addaction name="separator"/>
+    <addaction name="actionAbout"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menu_Edit"/>
    <addaction name="menuView"/>
    <addaction name="menuWindow"/>
+   <addaction name="menuHelp"/>
   </widget>
   <widget class="QStatusBar" name="statusbar"/>
   <widget class="QToolBar" name="toolBar">
@@ -246,6 +264,7 @@
    <addaction name="separator"/>
    <addaction name="menu_node_info"/>
    <addaction name="actionT"/>
+   <addaction name="actionReorder"/>
   </widget>
   <action name="menu_load_from_file">
    <property name="icon">
@@ -291,7 +310,7 @@
     <bool>true</bool>
    </property>
    <property name="icon">
-    <iconset resource="icons/misc.qrc">
+    <iconset>
      <normaloff>:/icons/misc/right_panel.svg</normaloff>
      <normalon>:/icons/misc/right_filled_panel.svg</normalon>:/icons/misc/right_panel.svg</iconset>
    </property>
@@ -364,6 +383,25 @@
     <string>&amp;Close Schedule</string>
    </property>
   </action>
+  <action name="actionAbout">
+   <property name="text">
+    <string>About</string>
+   </property>
+  </action>
+  <action name="actionDocumentation">
+   <property name="text">
+    <string>Documentation</string>
+   </property>
+  </action>
+  <action name="actionReorder">
+   <property name="text">
+    <string>Reorder</string>
+   </property>
+   <property name="toolTip">
+    <string>Reorder schedule based on start time</string>
+   </property>
+  </action>
  </widget>
+ <resources/>
  <connections/>
 </ui>
diff --git a/b_asic/scheduler_gui/operation_item.py b/b_asic/scheduler_gui/operation_item.py
index b67a38402c44a2e0c561aab4f7e17eb5f833ee7c..5321b7224dcd6d0575fc5a915b9edaecf626b30d 100644
--- a/b_asic/scheduler_gui/operation_item.py
+++ b/b_asic/scheduler_gui/operation_item.py
@@ -90,7 +90,7 @@ class OperationItem(QGraphicsItemGroup):
             del item
 
     @property
-    def op_id(self) -> GraphID:
+    def graph_id(self) -> GraphID:
         """Get the op-id."""
         return self._operation.graph_id
 
diff --git a/b_asic/scheduler_gui/scheduler_event.py b/b_asic/scheduler_gui/scheduler_event.py
index 5dc2a4d4c65fdb8b78b90bbefa5767a7392fcf4a..645eafba8fb98aebfc07a6a863e83f731c0c596f 100644
--- a/b_asic/scheduler_gui/scheduler_event.py
+++ b/b_asic/scheduler_gui/scheduler_event.py
@@ -215,7 +215,7 @@ class SchedulerEvent:  # PyQt5
         allows the item to receive future move, release and double-click events.
         """
         item: OperationItem = self.scene().mouseGrabberItem()
-        self._signals.component_selected.emit(item.op_id)
+        self._signals.component_selected.emit(item.graph_id)
         self._current_pos = item.mapToParent(event.pos())
         self.set_item_active(item)
         event.accept()
diff --git a/b_asic/scheduler_gui/scheduler_item.py b/b_asic/scheduler_gui/scheduler_item.py
index 810c568bf2b3305df7332959e53dedc02794a91b..804b2b9d7fee4e47b18f4b933acb2bd4caf0c653 100644
--- a/b_asic/scheduler_gui/scheduler_item.py
+++ b/b_asic/scheduler_gui/scheduler_item.py
@@ -34,7 +34,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
     """
 
     _axes: Optional[AxesItem]
-    _components: List[OperationItem]
+    _operation_items: Dict[str, OperationItem]
     _x_axis_indent: float
     _event_items: List[QGraphicsItem]
     _signal_dict: Dict[OperationItem, Set[SignalItem]]
@@ -53,7 +53,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
         #     super().__init__(parent=self)
         self._schedule = schedule
         self._axes = None
-        self._components = []
+        self._operation_items = {}
         self._x_axis_indent = 0.2
         self._event_items = []
         self._signal_dict = defaultdict(set)
@@ -74,8 +74,8 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
         assert self.schedule is not None, "No schedule installed."
         end_time = item.end_time
         new_start_time = floor(pos) - floor(self._x_axis_indent)
-        slacks = self.schedule.slacks(item.op_id)
-        op_start_time = self.schedule.start_time_of_operation(item.op_id)
+        slacks = self.schedule.slacks(item.graph_id)
+        op_start_time = self.schedule.start_time_of_operation(item.graph_id)
         if not -slacks[0] <= new_start_time - op_start_time <= slacks[1]:
             # Cannot move due to dependencies
             return False
@@ -94,6 +94,13 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
 
         return True
 
+    def _redraw_all_lines(self):
+        s = set()
+        for signals in self._signal_dict.values():
+            s.update(signals)
+        for signal in s:
+            signal.update_path()
+
     def _redraw_lines(self, item: OperationItem):
         """Update lines connected to *item*."""
         for signal in self._signal_dict[item]:
@@ -112,11 +119,11 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
     def set_new_starttime(self, item: OperationItem) -> None:
         """Set new starttime for *item*."""
         pos = item.x()
-        op_start_time = self.schedule.start_time_of_operation(item.op_id)
+        op_start_time = self.schedule.start_time_of_operation(item.graph_id)
         new_start_time = floor(pos) - floor(self._x_axis_indent)
         move_time = new_start_time - op_start_time
         if move_time:
-            self.schedule.move_operation(item.op_id, move_time)
+            self.schedule.move_operation(item.graph_id, move_time)
 
     def is_valid_delta_time(self, delta_time: int) -> bool:
         """Takes in a delta time and returns true if the new schedule time is
@@ -139,9 +146,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
         )
         self._axes.set_width(self._axes.width + delta_time)
         # Redraw all lines
-        for signals in self._signal_dict.values():
-            for signal in signals:
-                signal.update_path()
+        self._redraw_all_lines()
 
     @property
     def schedule(self) -> Schedule:
@@ -154,53 +159,72 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup):  # PySide2 / PyQt5
 
     @property
     def components(self) -> List[OperationItem]:
-        return self._components
+        return list(component for component in self._operation_items.values())
 
     @property
     def event_items(self) -> List[QGraphicsItem]:
         """Return a list of objects that receives events."""
         return self._event_items
 
-    def _make_graph(self) -> None:
-        """Makes a new graph out of the stored attributes."""
-        # build components
-        _components_dict = {}
-        # print('Start times:')
-        for op_id, op_start_time in self.schedule.start_times.items():
-            operation = cast(Operation, self.schedule.sfg.find_by_id(op_id))
-            component = OperationItem(operation, parent=self)
-            component.setPos(
-                self._x_axis_indent + op_start_time,
-                self.schedule._get_y_position(op_id),
+    def _set_position(self, graph_id) -> None:
+        op_item = self._operation_items[graph_id]
+        op_item.setPos(
+            self._x_axis_indent + self.schedule.start_times[graph_id],
+            self.schedule._get_y_position(graph_id),
+        )
+
+    def _redraw_from_start(self) -> None:
+        self.schedule._reset_y_locations()
+        for graph_id in {
+            k: v
+            for k, v in sorted(
+                self.schedule.start_times.items(), key=lambda item: item[1]
             )
-            self._components.append(component)
-            _components_dict[operation] = component
-            self._event_items += component.event_items
+        }:
+            self._set_position(graph_id)
+        self._redraw_all_lines()
 
+    def _update_axes(self, build=False):
         # build axes
         schedule_time = self.schedule.schedule_time
-        max_pos_op_id = max(
+        max_pos_graph_id = max(
             self.schedule._y_locations, key=self.schedule._y_locations.get
         )
-        yposmin = self.schedule._get_y_position(max_pos_op_id)
+        yposmin = self.schedule._get_y_position(max_pos_graph_id)
 
-        self._axes = AxesItem(schedule_time, yposmin + 0.5)
+        if self._axes is None or build:
+            self._axes = AxesItem(schedule_time, yposmin + 0.5)
+            self._event_items += self._axes.event_items
+        else:
+            self._axes.set_height(yposmin + 0.5)
         self._axes.setPos(0, yposmin + 1 + OPERATION_GAP)
-        self._event_items += self._axes.event_items
+
+    def _make_graph(self) -> None:
+        """Makes a new graph out of the stored attributes."""
+        # build components
+        for graph_id in self.schedule.start_times.keys():
+            operation = cast(Operation, self.schedule.sfg.find_by_id(graph_id))
+            component = OperationItem(operation, parent=self)
+            self._operation_items[graph_id] = component
+            self._set_position(graph_id)
+            self._event_items += component.event_items
+
         # self._axes.width = schedule_time
 
         # add axes and components
+        self._update_axes(build=True)
         self.addToGroup(self._axes)
-        for component in self._components:
+        for component in self.components:
             self.addToGroup(component)
-        # self.addToGroup(self._components)
 
         # add signals
-        for component in self._components:
+        for component in self.components:
             for output_port in component.operation.outputs:
                 for signal in output_port.signals:
                     destination = cast(InputPort, signal.destination)
-                    dest_component = _components_dict[destination.operation]
+                    dest_component = self._operation_items[
+                        destination.operation.graph_id
+                    ]
                     gui_signal = SignalItem(
                         component, dest_component, signal, parent=self
                     )
diff --git a/b_asic/scheduler_gui/ui_main_window.py b/b_asic/scheduler_gui/ui_main_window.py
index 3364516c1306edb1c3cb1d0c4405d015c11f0f06..f42657c3d7b4f2066c3d72e06c4e76096c8ae22f 100644
--- a/b_asic/scheduler_gui/ui_main_window.py
+++ b/b_asic/scheduler_gui/ui_main_window.py
@@ -81,13 +81,19 @@ class Ui_MainWindow(object):
         self.info_table.setVerticalHeaderItem(1, item)
         item = QtWidgets.QTableWidgetItem()
         item.setTextAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignVCenter)
+        font = QtGui.QFont()
+        font.setBold(False)
+        font.setWeight(50)
+        item.setFont(font)
         self.info_table.setHorizontalHeaderItem(0, item)
         item = QtWidgets.QTableWidgetItem()
         item.setTextAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignVCenter)
         self.info_table.setHorizontalHeaderItem(1, item)
         item = QtWidgets.QTableWidgetItem()
         font = QtGui.QFont()
-        font.setBold(True)
+        font.setBold(False)
+        font.setWeight(50)
+        font.setKerning(True)
         item.setFont(font)
         brush = QtGui.QBrush(QtGui.QColor(160, 160, 164))
         brush.setStyle(QtCore.Qt.SolidPattern)
@@ -105,7 +111,8 @@ class Ui_MainWindow(object):
         self.info_table.setItem(0, 0, item)
         item = QtWidgets.QTableWidgetItem()
         font = QtGui.QFont()
-        font.setBold(True)
+        font.setBold(False)
+        font.setWeight(50)
         item.setFont(font)
         brush = QtGui.QBrush(QtGui.QColor(160, 160, 164))
         brush.setStyle(QtCore.Qt.SolidPattern)
@@ -138,6 +145,8 @@ class Ui_MainWindow(object):
         self.menu_Edit.setObjectName("menu_Edit")
         self.menuWindow = QtWidgets.QMenu(self.menubar)
         self.menuWindow.setObjectName("menuWindow")
+        self.menuHelp = QtWidgets.QMenu(self.menubar)
+        self.menuHelp.setObjectName("menuHelp")
         MainWindow.setMenuBar(self.menubar)
         self.statusbar = QtWidgets.QStatusBar(MainWindow)
         self.statusbar.setObjectName("statusbar")
@@ -193,6 +202,12 @@ class Ui_MainWindow(object):
         icon = QtGui.QIcon.fromTheme("view-close")
         self.menu_close_schedule.setIcon(icon)
         self.menu_close_schedule.setObjectName("menu_close_schedule")
+        self.actionAbout = QtWidgets.QAction(MainWindow)
+        self.actionAbout.setObjectName("actionAbout")
+        self.actionDocumentation = QtWidgets.QAction(MainWindow)
+        self.actionDocumentation.setObjectName("actionDocumentation")
+        self.actionReorder = QtWidgets.QAction(MainWindow)
+        self.actionReorder.setObjectName("actionReorder")
         self.menuFile.addAction(self.menu_load_from_file)
         self.menuFile.addAction(self.menu_close_schedule)
         self.menuFile.addAction(self.menu_save)
@@ -201,16 +216,21 @@ class Ui_MainWindow(object):
         self.menuFile.addAction(self.menu_quit)
         self.menuView.addAction(self.menu_node_info)
         self.menuWindow.addAction(self.menu_exit_dialog)
+        self.menuHelp.addAction(self.actionDocumentation)
+        self.menuHelp.addSeparator()
+        self.menuHelp.addAction(self.actionAbout)
         self.menubar.addAction(self.menuFile.menuAction())
         self.menubar.addAction(self.menu_Edit.menuAction())
         self.menubar.addAction(self.menuView.menuAction())
         self.menubar.addAction(self.menuWindow.menuAction())
+        self.menubar.addAction(self.menuHelp.menuAction())
         self.toolBar.addAction(self.menu_load_from_file)
         self.toolBar.addAction(self.menu_save)
         self.toolBar.addAction(self.menu_save_as)
         self.toolBar.addSeparator()
         self.toolBar.addAction(self.menu_node_info)
         self.toolBar.addAction(self.actionT)
+        self.toolBar.addAction(self.actionReorder)
 
         self.retranslateUi(MainWindow)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
@@ -236,6 +256,7 @@ class Ui_MainWindow(object):
         self.menuView.setTitle(_translate("MainWindow", "&View"))
         self.menu_Edit.setTitle(_translate("MainWindow", "&Edit"))
         self.menuWindow.setTitle(_translate("MainWindow", "&Window"))
+        self.menuHelp.setTitle(_translate("MainWindow", "&Help"))
         self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
         self.menu_load_from_file.setText(
             _translate("MainWindow", "&Load Schedule From File...")
@@ -267,3 +288,11 @@ class Ui_MainWindow(object):
         self.menu_close_schedule.setText(
             _translate("MainWindow", "&Close Schedule")
         )
+        self.actionAbout.setText(_translate("MainWindow", "About"))
+        self.actionDocumentation.setText(
+            _translate("MainWindow", "Documentation")
+        )
+        self.actionReorder.setText(_translate("MainWindow", "Reorder"))
+        self.actionReorder.setToolTip(
+            _translate("MainWindow", "Reorder schedule based on start time")
+        )