diff --git a/CBSVisualizer/CBSVisualizer.Core/RegionNames.cs b/CBSVisualizer/CBSVisualizer.Core/RegionNames.cs
index 4c12cfccee4734569196cc0fd19d5d59113dba12..8665e11825c97566c9c0da808328d8686823b6c1 100644
--- a/CBSVisualizer/CBSVisualizer.Core/RegionNames.cs
+++ b/CBSVisualizer/CBSVisualizer.Core/RegionNames.cs
@@ -5,5 +5,6 @@
         public const string MenuBarRegion = "MenuBar";
         public const string QueueGroupRegion = "QueueGroup";
         public const string LinkRegion = "Link";
+        public const string ChartsRegion = "Charts";
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/CreditChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/CreditChangedEvent.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6eea1f8e5bd287facb5615b9dabb4d8b8ff7a3e8
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/CreditChangedEvent.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Prism.Events;
+
+namespace CBSVisualizer.Messaging.Events
+{
+    public class CreditChangedEvent : PubSubEvent<(int Prio, long Credit)>
+    {
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/PacketCountChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/PacketCountChangedEvent.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c61db7740b1e74d2ec4159ea62222d9435e3a9cf
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/PacketCountChangedEvent.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Prism.Events;
+
+namespace CBSVisualizer.Messaging.Events
+{
+    public class PacketCountChangedEvent : PubSubEvent<(int Prio, long NewCount)>
+    {
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/CBSVisualizer.Modules.Charts.csproj b/CBSVisualizer/CBSVisualizer.Modules.Charts/CBSVisualizer.Modules.Charts.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..c8aace383614431cd8ff3fac64f0569571453e81
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/CBSVisualizer.Modules.Charts.csproj
@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+    <UseWPF>true</UseWPF>
+    <AssemblyName>CBSVisualizer.Modules.Charts</AssemblyName>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="LiveCharts.Wpf" Version="0.9.7" />
+    <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" />
+    <ProjectReference Include="..\CBSVisualizer.MessagingCore\CBSVisualizer.Messaging.csproj" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/ChartsModule.cs b/CBSVisualizer/CBSVisualizer.Modules.Charts/ChartsModule.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a631601f189124f6d9128b5123c183ae033d8946
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/ChartsModule.cs
@@ -0,0 +1,28 @@
+using CBSVisualizer.Core;
+using CBSVisualizer.Modules.Charts.Views;
+using Prism.Ioc;
+using Prism.Modularity;
+using Prism.Regions;
+
+namespace CBSVisualizer.Modules.Charts
+{
+    public class ChartsModule : IModule
+    {
+        private readonly IRegionManager regionManager;
+
+        public ChartsModule(IRegionManager regionManager)
+        {
+            this.regionManager = regionManager;
+        }
+
+        public void OnInitialized(IContainerProvider containerProvider)
+        {
+            regionManager.RequestNavigate(RegionNames.ChartsRegion, "Charts");
+        }
+
+        public void RegisterTypes(IContainerRegistry containerRegistry)
+        {
+            containerRegistry.RegisterForNavigation<Views.Charts>();
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs
new file mode 100644
index 0000000000000000000000000000000000000000..dfaa317b871f6cc17a920020f67f8606d1c9266d
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using CBSVisualizer.Core.Mvvm;
+using CBSVisualizer.Messaging.Events;
+using LiveCharts;
+using LiveCharts.Defaults;
+using LiveCharts.Wpf;
+using Prism.Events;
+using Prism.Regions;
+
+namespace CBSVisualizer.Modules.Charts.ViewModels
+{
+    public class ChartsViewModel : RegionViewModelBase
+    {
+
+        public Func<double, string> Formatter { get; } = x => new DateTime((long) x).ToString("HH:mm:ss");
+
+        public Dictionary<int, SeriesCollection> CombinedCollectionDictionary { get; private set; }
+
+        public SeriesCollection CreditValuesCollections { get; set; }
+
+        public SeriesCollection PacketCountCollections { get; set; }
+
+        public ChartsViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) 
+            : base(regionManager)
+        {
+            InitCharts();
+            InitPacketHandler(eventAggregator);
+            InitCreditHandler(eventAggregator);
+        }
+
+        private void InitCreditHandler(IEventAggregator eventAggregator)
+        {
+            eventAggregator.GetEvent<CreditChangedEvent>().Subscribe(tuple =>
+            {
+                var (prio, credit) = tuple;
+                CreditValuesCollections[prio].Values.Add(new DateTimePoint(DateTime.Now, credit));
+            });
+        }
+
+        private void InitPacketHandler(IEventAggregator eventAggregator)
+        {
+            eventAggregator.GetEvent<PacketCountChangedEvent>().Subscribe(tuple =>
+            {
+                var (prio, newCount) = tuple;
+                PacketCountCollections[prio].Values.Add(new DateTimePoint(DateTime.Now, newCount));
+            });
+        }
+
+        private void InitCharts()
+        {
+            CreditValuesCollections = new SeriesCollection
+            {
+                new LineSeries {
+                    Title = "Queue 0 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 1 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 2 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 3 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 4 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 5 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 6 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 7 Credit",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                }
+            };
+
+            PacketCountCollections = new SeriesCollection
+            {
+                new LineSeries {
+                    Title = "Queue 0 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 1 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 2 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 3 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 4 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 5 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 6 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                },
+                new LineSeries {
+                    Title = "Queue 7 Packets",
+                    Values = new ChartValues<DateTimePoint>{new DateTimePoint(DateTime.Now, 0)}
+                }
+            };
+
+            CombinedCollectionDictionary = new Dictionary<int, SeriesCollection>();
+            for (var idx = 0; idx < PacketCountCollections.Count; idx++)
+            {
+                CombinedCollectionDictionary[idx] = new SeriesCollection()
+                {
+                    PacketCountCollections[idx],
+                    CreditValuesCollections[idx],
+                };
+            }
+        }
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml
new file mode 100644
index 0000000000000000000000000000000000000000..10eaeb1da07671fc5b350b674e1fd2096dabeb25
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml
@@ -0,0 +1,89 @@
+<UserControl x:Class="CBSVisualizer.Modules.Charts.Views.Charts"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             mc:Ignorable="d" 
+             d:DesignHeight="300" d:DesignWidth="300"
+             xmlns:prism="http://prismlibrary.com/"
+             xmlns:wpf="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
+             prism:ViewModelLocator.AutoWireViewModel="True" >
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+            <RowDefinition Height="*"/>
+        </Grid.RowDefinitions>
+
+        <wpf:CartesianChart Grid.Row="0" Series="{Binding CombinedCollectionDictionary[7]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="1" Series="{Binding CombinedCollectionDictionary[6]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="2" Series="{Binding CombinedCollectionDictionary[5]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="3" Series="{Binding CombinedCollectionDictionary[4]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="4" Series="{Binding CombinedCollectionDictionary[3]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="5" Series="{Binding CombinedCollectionDictionary[2]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="6" Series="{Binding CombinedCollectionDictionary[1]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+        <wpf:CartesianChart Grid.Row="7" Series="{Binding CombinedCollectionDictionary[0]}" LegendLocation="Left">
+            <wpf:CartesianChart.AxisX>
+                <wpf:Axis Title="Timestamp" LabelFormatter="{Binding Formatter}"/>
+            </wpf:CartesianChart.AxisX>
+            <wpf:CartesianChart.AxisY>
+                <wpf:Axis Title="Packet Count / Credit"/>
+            </wpf:CartesianChart.AxisY>
+        </wpf:CartesianChart>
+
+    </Grid>
+</UserControl>
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e6f990c7737a92ad595b26c8b3a15a8c7957b86e
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace CBSVisualizer.Modules.Charts.Views
+{
+    /// <summary>
+    /// Interaction logic for Charts.xaml
+    /// </summary>
+    public partial class Charts : UserControl
+    {
+        public Charts()
+        {
+            InitializeComponent();
+        }
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
index 995c0f51dc1010bdffd7935bb805e6b17dc43e1a..bcddad19a7889aca97cad20ea922c046e01312f2 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs
@@ -193,7 +193,6 @@ namespace CBSVisualizer.Modules.Link.ViewModels
                         {
                             await Task.Delay(REFRESH_TIME_MS, tokenSource.Token);
                             transmittedBytes += REFRESH_TIME_MS * (bitrate / 1000);
-                            log.Info($"Transmitted {transmittedBytes} of {packetInTransit.Size} bytes of packet {packetInTransit}.");
                         }
                     } catch (TaskCanceledException) { }
                     finally
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.FrozenLinkCallback.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.FrozenLinkCallback.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b8445caa64618a1da553957bc35bf02aa14c376b
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.FrozenLinkCallback.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Linq;
+using CBSVisualizer.Messaging;
+using CBSVisualizer.Messaging.Events;
+
+namespace CBSVisualizer.Modules.Queue.ViewModels
+{
+    public partial class QueueViewModel
+    {
+        private class FrozenLinkCallback : LinkCallbackBase
+        {
+            public FrozenLinkCallback(QueueViewModel parent)
+                : base(parent)
+            {
+            }
+
+            public override void Initialize()
+            {
+                Parent.StartCreditThread(Parent.IdleSlope);
+            }
+
+            public override void GateClosed()
+            {
+                // Nothing special happens here. The credit handling is done in the GateOpened method.
+            }
+
+            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
+            {
+                // Start the credit thread.
+                Parent.StartCreditThread(Parent.IdleSlope);
+
+                // Try to submit the latest packet. If it was denied due to pre-closing, freeze the credit.
+                TrySendPacket(
+                    trySubmitFirstPacket, null, 
+                    (packet) =>
+                    {
+                        Parent.StopCreditThread();
+                    }, null);
+
+            }
+
+            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
+            {
+                // Put the leftovers of the packet back into the queue.
+                lock (Parent.queueLock)
+                {
+                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
+                }
+            }
+
+            public override void TransmissionCompleted()
+            {
+                // Stop and restart the credit thread.
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(Parent.IdleSlope);
+            }
+
+            public override void TransmissionStarted(long bytesPerSecondRate)
+            {
+                // Decrease the credit by the idle slope.
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbackBase.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbackBase.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f40834a250d09480fdafb84c38016c4412015c50
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbackBase.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Linq;
+using CBSVisualizer.Messaging;
+using CBSVisualizer.Messaging.Events;
+
+namespace CBSVisualizer.Modules.Queue.ViewModels
+{
+    public partial class QueueViewModel
+    {
+        private abstract class LinkCallbackBase : ILinkCallback
+        {
+            protected readonly QueueViewModel Parent;
+
+            protected LinkCallbackBase(QueueViewModel parentViewModel)
+            {
+                Parent = parentViewModel;
+            }
+
+            protected long GetSendSlope(long rate)
+            {
+                return Parent.IdleSlope - rate;
+            }
+
+            public int GetPriority()
+            {
+                return Parent.Priority;
+            }
+
+            public virtual void Initialize()
+            {
+                // Do nothing by default.
+            }
+
+            protected bool CanSend()
+            {
+                lock (Parent.queueLock)
+                {
+                    return Parent.Queue.Count > 0 && Parent.CurrentCredit >= 0;
+                }
+            }
+
+
+            protected void TrySendPacket(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket, Action<PriorityPacket> additionalAcceptedAction,
+                Action<PriorityPacket> deniedPreClosingAction, Action<PriorityPacket> deniedHigherPrioAction)
+            {
+                lock (Parent.queueLock)
+                {
+                    lock (Parent.creditLock)
+                    {
+                        if (!CanSend())
+                        {
+                            return;
+                        }
+
+                        var firstPacket = Parent.Queue.First();
+
+                        switch (trySubmitFirstPacket.Invoke(firstPacket))
+                        {
+                            case PacketSubmitResult.Accepted:
+                                Parent.Queue.Remove(firstPacket);
+                                additionalAcceptedAction?.Invoke(firstPacket);
+                                break;
+
+                            case PacketSubmitResult.DeniedHigherPrio:
+                                deniedHigherPrioAction?.Invoke(firstPacket);
+                                break;
+
+                            case PacketSubmitResult.DeniedPreClosing:
+                                deniedPreClosingAction?.Invoke(firstPacket);
+                                break;
+                        }
+                    }
+                }
+            }
+
+            public abstract void GateClosed();
+
+            public abstract void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket);
+
+            public abstract void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes);
+
+            public abstract void TransmissionCompleted();
+
+            public abstract void TransmissionStarted(long bytesPerSecondRate);
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs
deleted file mode 100644
index 505317183a826de3767fb4d741c5988c90edbb97..0000000000000000000000000000000000000000
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs
+++ /dev/null
@@ -1,350 +0,0 @@
-using CBSVisualizer.Messaging;
-using CBSVisualizer.Messaging.Events;
-using System;
-using System.Diagnostics;
-using System.Linq;
-
-namespace CBSVisualizer.Modules.Queue.ViewModels
-{
-    public partial class QueueViewModel
-    {
-        public enum CreditBehaviour
-        {
-            // This is selected when there should be no credit-based shaper for this queue.
-            NoCbs,
-
-            // Frozen credit behaviour
-            Frozen,
-
-            // The standard credit behaviour
-            Standard,
-
-            // Return to zero.
-            ReturnToZero
-        }
-
-        private abstract class LinkCallbackBase : ILinkCallback
-        {
-            protected readonly QueueViewModel Parent;
-
-            protected LinkCallbackBase(QueueViewModel parentViewModel)
-            {
-                Parent = parentViewModel;
-            }
-
-            protected long GetSendSlope(long rate)
-            {
-                return Parent.IdleSlope - rate;
-            }
-
-            public int GetPriority()
-            {
-                return Parent.Priority;
-            }
-
-            public virtual void Initialize()
-            {
-                // Do nothing by default.
-            }
-
-            protected bool CanSend()
-            {
-                lock (Parent.queueLock)
-                {
-                    return Parent.Queue.Count > 0 && Parent.CurrentCredit >= 0;
-                }
-            }
-
-
-            protected void TrySendPacket(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket, Action<PriorityPacket> additionalAcceptedAction,
-                Action<PriorityPacket> deniedPreClosingAction, Action<PriorityPacket> deniedHigherPrioAction)
-            {
-                lock (Parent.queueLock)
-                {
-                    lock (Parent.creditLock)
-                    {
-                        if (Parent.Queue.Count <= 0 || Parent.CurrentCredit < 0)
-                        {
-                            return;
-                        }
-
-                        var firstPacket = Parent.Queue.First();
-
-                        switch (trySubmitFirstPacket.Invoke(firstPacket))
-                        {
-                            case PacketSubmitResult.Accepted:
-                                Parent.Queue.Remove(firstPacket);
-                                additionalAcceptedAction?.Invoke(firstPacket);
-                                break;
-
-                            case PacketSubmitResult.DeniedHigherPrio:
-                                deniedHigherPrioAction?.Invoke(firstPacket);
-                                break;
-
-                            case PacketSubmitResult.DeniedPreClosing:
-                                deniedPreClosingAction?.Invoke(firstPacket);
-                                break;
-                        }
-                    }
-                }
-            }
-
-            public abstract void GateClosed();
-
-            public abstract void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket);
-
-            public abstract void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes);
-
-            public abstract void TransmissionCompleted();
-
-            public abstract void TransmissionStarted(long bytesPerSecondRate);
-        }
-
-        #region NoCbsLinkCallback
-        private class NoCbsLinkCallback : LinkCallbackBase
-        {
-            public NoCbsLinkCallback(QueueViewModel parent)
-                : base(parent)
-            {
-            }
-
-            public override void GateClosed()
-            {
-                // Nothing to be done.
-            }
-
-            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
-            {
-                // Try to submit the "oldest" packet.
-                lock (Parent.queueLock)
-                {
-                    // If the queue is empty, return.
-                    if (Parent.Queue.Count <= 0)
-                    {
-                        return;
-                    }
-
-                    // If the packet was accepted, remove it from the queue.
-                    var firstPacket = Parent.Queue.First();
-
-                    if (trySubmitFirstPacket.Invoke(firstPacket) == PacketSubmitResult.Accepted)
-                    {
-                        Parent.Queue.Remove(firstPacket);
-                    }
-
-                    // Otherwise, just don't do anything :-)
-                }
-            }
-
-            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
-            {
-                // Build a new packet that just contains the leftover bytes and put it into the queue.
-                lock (Parent.queueLock)
-                {
-                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
-                }
-            }
-
-            public override void TransmissionStarted(long bytesPerSecondRate)
-            {
-                // Just write some log.
-                Debug.WriteLine($"Packet of Queue {Parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s.");
-            }
-            
-            public override void TransmissionCompleted()
-            {
-                // Nothing to be done.
-            }
-        }
-        #endregion
-
-        #region StandardLinkCallback
-        private class StandardLinkCallback : LinkCallbackBase
-        {
-            public StandardLinkCallback(QueueViewModel parentViewModel)
-                : base(parentViewModel)
-            {
-            }
-
-            public override void Initialize()
-            {
-                Parent.StartCreditThread(Parent.IdleSlope);
-            }
-
-            public override void GateClosed()
-            {
-                // Stop the credit thread.
-                Parent.StopCreditThread();
-            }
-
-            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
-            {
-                // Start the credit thread
-                Parent.StartCreditThread(Parent.IdleSlope);
-
-                // Try to send the packet if we can.
-                TrySendPacket(trySubmitFirstPacket, null, null, null);
-            }
-
-            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
-            {
-                lock (Parent.queueLock)
-                {
-                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
-                }
-            }
-
-            public override void TransmissionCompleted()
-            {
-                Log.Info("Transmission Completed");
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(Parent.IdleSlope);
-            }
-
-            public override void TransmissionStarted(long bytesPerSecondRate)
-            {
-                Log.Info("TransmissionStarted");
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate));
-            }
-        }
-        #endregion
-
-        #region FrozenLinkCallback
-        private class FrozenLinkCallback : LinkCallbackBase
-        {
-            public FrozenLinkCallback(QueueViewModel parent)
-                : base(parent)
-            {
-            }
-
-            public override void Initialize()
-            {
-                Parent.StartCreditThread(Parent.IdleSlope);
-            }
-
-            public override void GateClosed()
-            {
-                // Nothing special happens here. The credit handling is done in the GateOpened method.
-            }
-
-            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
-            {
-                // Try to submit first packet.
-                lock (Parent.queueLock)
-                {
-                    if (!CanSend())
-                    {
-                        return;
-                    }
-
-                    var firstPacket = Parent.Queue.First();
-                    var submitResult = trySubmitFirstPacket.Invoke(firstPacket);
-
-                    // If the packet was accepted, remove it from the queue.
-                    if (submitResult == PacketSubmitResult.Accepted)
-                    {
-                        Parent.Queue.Remove(firstPacket);
-
-                        // If my packet was denied due to pre-closing, freeze my credit.
-                    }
-                    else if (submitResult == PacketSubmitResult.DeniedPreClosing)
-                    {
-                        Parent.StopCreditThread();
-                    }
-                }
-
-                // Otherwise, just let the credit grow for now.
-            }
-
-            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
-            {
-                // Put the leftovers of the packet back into the queue.
-                lock (Parent.queueLock)
-                {
-                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
-                }
-            }
-
-            public override void TransmissionCompleted()
-            {
-                // Stop and restart the credit thread.
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(Parent.IdleSlope);
-            }
-
-            public override void TransmissionStarted(long bytesPerSecondRate)
-            {
-                // Decrease the credit by the idle slope.
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate));
-            }
-        }
-        #endregion
-
-        #region ReturnToZeroLinkCallback
-        private class ReturnToZeroLinkCallback : LinkCallbackBase
-        {
-            public ReturnToZeroLinkCallback(QueueViewModel parentViewModel)
-                : base(parentViewModel)
-            {
-            }
-
-            public override void Initialize()
-            {
-                Parent.StartCreditThread(Parent.IdleSlope);
-            }
-
-            public override void GateClosed()
-            {
-                // Nothing special to be done here.
-            }
-
-            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
-            {
-                lock (Parent.queueLock)
-                {
-                    // Again, check if we can submit anything.
-                    if (!CanSend())
-                    {
-                        return;
-                    }
-
-                    var firstPacket = Parent.Queue.First();
-                    var submitResult = trySubmitFirstPacket.Invoke(firstPacket);
-
-                    if (submitResult == PacketSubmitResult.Accepted)
-                    {
-                        Parent.Queue.Remove(firstPacket);
-                    }
-                    else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero.
-                    {
-                        Parent.StopCreditThread();
-                        Parent.StartCreditThread(Parent.IdleSlope, 0);
-                    }
-                }
-            }
-
-            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
-            {
-                lock (Parent.queueLock)
-                {
-                    Parent.Queue.Insert(0, new PriorityPacket(GetPriority(), leftoverBytes));
-                }
-            }
-
-            public override void TransmissionCompleted()
-            {
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(Parent.IdleSlope, 0);
-            }
-
-            public override void TransmissionStarted(long bytesPerSecondRate)
-            {
-                Parent.StopCreditThread();
-                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0);
-            }
-        }
-        #endregion
-    }
-}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.NoCbsLinkCallback.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.NoCbsLinkCallback.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5439a2e746bc5df6b3ae97c98b0acb7a5fee9625
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.NoCbsLinkCallback.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CBSVisualizer.Messaging;
+using CBSVisualizer.Messaging.Events;
+
+namespace CBSVisualizer.Modules.Queue.ViewModels
+{
+    partial class QueueViewModel
+    {
+        private class NoCbsLinkCallback : LinkCallbackBase
+        {
+            public NoCbsLinkCallback(QueueViewModel parent)
+                : base(parent)
+            {
+            }
+
+            public override void GateClosed()
+            {
+                // Nothing to be done.
+            }
+
+            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
+            {
+                // Try to submit the "oldest" packet.
+                lock (Parent.queueLock)
+                {
+                    // If the queue is empty, return.
+                    if (Parent.Queue.Count <= 0)
+                    {
+                        return;
+                    }
+
+                    // If the packet was accepted, remove it from the queue.
+                    var firstPacket = Parent.Queue.First();
+
+                    if (trySubmitFirstPacket.Invoke(firstPacket) == PacketSubmitResult.Accepted)
+                    {
+                        Parent.Queue.Remove(firstPacket);
+                    }
+
+                    // Otherwise, just don't do anything :-)
+                }
+            }
+
+            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
+            {
+                // Build a new packet that just contains the leftover bytes and put it into the queue.
+                lock (Parent.queueLock)
+                {
+                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
+                }
+            }
+
+            public override void TransmissionStarted(long bytesPerSecondRate)
+            {
+                // Just write some log.
+                Log.Debug($"Packet of Queue {Parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s.");
+            }
+
+            public override void TransmissionCompleted()
+            {
+                // Nothing to be done.
+            }
+        }
+
+    }
+}
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.ReturnToZeroLinkCallback.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.ReturnToZeroLinkCallback.cs
new file mode 100644
index 0000000000000000000000000000000000000000..90ee54b23794bc5af77af3e21e572c429c12b1d7
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.ReturnToZeroLinkCallback.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Linq;
+using CBSVisualizer.Messaging;
+using CBSVisualizer.Messaging.Events;
+
+namespace CBSVisualizer.Modules.Queue.ViewModels
+{
+    public partial class QueueViewModel
+    {
+        private class ReturnToZeroLinkCallback : LinkCallbackBase
+        {
+            public ReturnToZeroLinkCallback(QueueViewModel parentViewModel)
+                : base(parentViewModel)
+            {
+            }
+
+            public override void Initialize()
+            {
+                Parent.StartCreditThread(Parent.IdleSlope);
+            }
+
+            public override void GateClosed()
+            {
+                // Nothing special to be done here.
+            }
+
+            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
+            {
+                lock (Parent.queueLock)
+                {
+                    // Again, check if we can submit anything.
+                    if (!CanSend())
+                    {
+                        return;
+                    }
+
+                    var firstPacket = Parent.Queue.First();
+                    var submitResult = trySubmitFirstPacket.Invoke(firstPacket);
+
+                    if (submitResult == PacketSubmitResult.Accepted)
+                    {
+                        Parent.Queue.Remove(firstPacket);
+                    }
+                    else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero.
+                    {
+                        Parent.StopCreditThread();
+                        Parent.StartCreditThread(Parent.IdleSlope, 0);
+                    }
+                }
+            }
+
+            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
+            {
+                lock (Parent.queueLock)
+                {
+                    Parent.Queue.Insert(0, new PriorityPacket(GetPriority(), leftoverBytes));
+                }
+            }
+
+            public override void TransmissionCompleted()
+            {
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(Parent.IdleSlope, 0);
+            }
+
+            public override void TransmissionStarted(long bytesPerSecondRate)
+            {
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.StandardLinkCallback.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.StandardLinkCallback.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7da22685df2d1f38eabd388f9dc0a55e04a0ddf5
--- /dev/null
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.StandardLinkCallback.cs
@@ -0,0 +1,59 @@
+using System;
+using CBSVisualizer.Messaging;
+using CBSVisualizer.Messaging.Events;
+
+namespace CBSVisualizer.Modules.Queue.ViewModels
+{
+    public partial class QueueViewModel
+    {
+        private class StandardLinkCallback : LinkCallbackBase
+        {
+            public StandardLinkCallback(QueueViewModel parentViewModel)
+                : base(parentViewModel)
+            {
+            }
+
+            public override void Initialize()
+            {
+                Parent.StartCreditThread(Parent.IdleSlope);
+            }
+
+            public override void GateClosed()
+            {
+                // Stop the credit thread.
+                Parent.StopCreditThread();
+            }
+
+            public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket)
+            {
+                // Start the credit thread
+                Parent.StartCreditThread(Parent.IdleSlope);
+
+                // Try to send the packet if we can.
+                TrySendPacket(trySubmitFirstPacket, null, null, null);
+            }
+
+            public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes)
+            {
+                lock (Parent.queueLock)
+                {
+                    Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes));
+                }
+            }
+
+            public override void TransmissionCompleted()
+            {
+                Log.Info("Transmission Completed");
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(Parent.IdleSlope);
+            }
+
+            public override void TransmissionStarted(long bytesPerSecondRate)
+            {
+                Log.Debug($"Packet of Queue {Parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s.");
+                Parent.StopCreditThread();
+                Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
index e3b9186fbf62cfba98648c931e9bcd7aa7cef90d..2be1aebf4c0256a81d3706070f8d1a567a8c627c 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs
@@ -2,9 +2,6 @@
 using CBSVisualizer.Messaging;
 using CBSVisualizer.Messaging.Events;
 using CBSVisualizer.Services.PacketService.Interface;
-using LiveCharts;
-using LiveCharts.Defaults;
-using LiveCharts.Wpf;
 using log4net;
 using Prism.Commands;
 using Prism.Events;
@@ -17,8 +14,23 @@ using System.Threading.Tasks;
 
 namespace CBSVisualizer.Modules.Queue.ViewModels
 {
-    public partial class QueueViewModel : RegionViewModelBase
+    public sealed partial class QueueViewModel : RegionViewModelBase, IDisposable
     {
+        public enum CreditBehaviour
+        {
+            // This is selected when there should be no credit-based shaper for this queue.
+            NoCbs,
+
+            // Frozen credit behaviour
+            Frozen,
+
+            // The standard credit behaviour
+            Standard,
+
+            // Return to zero.
+            ReturnToZero
+        }
+
         private const int ThreadJoinTimeoutS = 1;
 
         private const long CreditRefreshRateS = 5;
@@ -80,8 +92,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
         /// </summary>
         public int IdleSlope { get; set; } = 100;
 
-        public SeriesCollection Series { get; set; }
-
         public DelegateCommand GeneratePacketOnClick { get; private set; }
 
         public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio, IPacketService packetProvider) :
@@ -100,8 +110,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
             Queue.CollectionChanged += QueueChangedHandler;
 
             eventAggregator.GetEvent<RegisterLinkCallbackEvent>().Publish(GetLinkCallback());
-
-            InitCharts();
         }
 
         private void HandleLabels()
@@ -120,29 +128,16 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
 
         private void QueueChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
         {
+            eventAggregator.GetEvent<PacketCountChangedEvent>().Publish((Priority, Queue.Count));
+
             // Add the new value to the series.
             if (selectedCreditBehaviour != CreditBehaviour.NoCbs)
             {
-                Series[0].Values.Add(new DateTimePoint(DateTime.Now, CurrentCredit));
+                eventAggregator.GetEvent<CreditChangedEvent>().Publish((Priority, CurrentCredit));
             }
-            Series[1].Values.Add(new DateTimePoint(DateTime.Now, Queue.Count));
         }
 
-        private void InitCharts()
-        {
-            Series = new SeriesCollection
-            {
-                new LineSeries {
-                    Title = "Credit Values",
-                    Values = new ChartValues<DateTimePoint>() { new DateTimePoint(DateTime.Now, 0) }
-                },
-
-                new LineSeries {
-                    Title = "Packet Count",
-                    Values = new ChartValues<DateTimePoint>() { new DateTimePoint(DateTime.Now, 0) }
-                }
-            };
-        }
+
 
         private void HandleCreditBehaviourChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
         {
@@ -190,6 +185,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
 
         private void StartCreditThread(long bytesPerSecondSlope, long limit = long.MaxValue)
         {
+            StopCreditThread();
+
             // Init new cancellation token.
             creditGrowthCancellationSource = new CancellationTokenSource();
 
@@ -225,7 +222,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
         {
             creditGrowthCancellationSource?.Cancel();
 
-            if (creditUpdateThread != null)
+            if (creditUpdateThread != null && creditUpdateThread.IsAlive)
             {
                 Log.Info(creditUpdateThread.Join(TimeSpan.FromSeconds(ThreadJoinTimeoutS))
                     ? $"Queue {Priority}: Unable to stop credit thread."
@@ -266,5 +263,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels
                 });
             });
         }
+
+        public void Dispose()
+        {
+            StopCreditThread();
+            creditGrowthCancellationSource?.Dispose();
+        }
     }
 }
\ No newline at end of file
diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
index 13428af22fec25fd6cfea6b91ea44b90a5ae6289..7d34ca0c094b942e11bdf17a51b5afb0663683bf 100644
--- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
+++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml
@@ -20,7 +20,6 @@
             <ColumnDefinition Width="*"/>
             <ColumnDefinition Width="*"/>
             <ColumnDefinition Width="*"/>
-            <ColumnDefinition Width="3*"/>
         </Grid.ColumnDefinitions>
         <TextBlock Text="{Binding PrioLabel}" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
         <TextBlock Text="{Binding Priority}" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
@@ -40,14 +39,5 @@
             materialDesign:TextFieldAssist.UnderlineBrush="{DynamicResource SecondaryAccentBrush}"
             materialDesign:HintAssist.Hint="Credit Behaviour"
             x:Name="CreditBehaviourBox" SelectedItem="{Binding SelectedCreditBehaviour}" Grid.Column="3"  Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"/>
-        
-        <lvc:CartesianChart Series="{Binding Series}" LegendLocation="Right" Grid.Column="4" Grid.RowSpan="2">
-            <lvc:CartesianChart.AxisX>
-                <lvc:Axis Title="Time" LabelFormatter="{Binding XFormatter}" />
-            </lvc:CartesianChart.AxisX>
-            <lvc:CartesianChart.AxisY>
-                <lvc:Axis Title="Credit"/>
-            </lvc:CartesianChart.AxisY>
-        </lvc:CartesianChart>
     </Grid>
 </UserControl>
diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
index 3be0dffa2a4ad4d9c86d27bd977ff8e1e5f87906..884097646dcfa51fd725c1d7c34e3ffaa2f35547 100644
--- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
+++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs
@@ -46,8 +46,8 @@ namespace CBSVisualizer.Services.SettingsService.Implementation
             schedulersGroupMembers.Add(new SelectionSetting("scheduler", "Used Scheduler", schedulers.First(), schedulers));
 
             // Random Scheduler: Max & Min delays.
-            schedulersGroupMembers.Add(new StringSetting("random_scheduler_min_delay", "Random Scheduler: Minimum Delay [ms]", "500"));
-            schedulersGroupMembers.Add(new StringSetting("random_scheduler_max_delay", "Random Scheduler: Maximum Delay [ms]", "5000"));
+            schedulersGroupMembers.Add(new StringSetting("random_scheduler_min_delay", "Random Scheduler: Minimum Gate Opened Time [ms]", "500"));
+            schedulersGroupMembers.Add(new StringSetting("random_scheduler_max_delay", "Random Scheduler: Maximum Gate Opened Time [ms]", "5000"));
 
             settingGroups.Add(new SettingGroup("Schedulers", schedulersGroupMembers));
         }
diff --git a/CBSVisualizer/CBSVisualizer.sln b/CBSVisualizer/CBSVisualizer.sln
index ccf16e17435bdb3c9dd3020208640f94ca44a4ad..a35220e25683621ccb5e98381308bf9758335be9 100644
--- a/CBSVisualizer/CBSVisualizer.sln
+++ b/CBSVisualizer/CBSVisualizer.sln
@@ -36,7 +36,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CBSVisualizer.Core", "CBSVi
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CBSVisualizer.Common", "CBSVisualizer.Common\CBSVisualizer.Common.csproj", "{9B1B603C-601C-4F31-ADD9-D0962C0011AF}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBSVisualizer.Services.PacketService", "CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj", "{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CBSVisualizer.Services.PacketService", "CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj", "{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBSVisualizer.Modules.Charts", "CBSVisualizer.Modules.Charts\CBSVisualizer.Modules.Charts.csproj", "{CC0C2DDE-D058-4075-84A6-016C0518724A}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -92,6 +94,10 @@ Global
 		{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CC0C2DDE-D058-4075-84A6-016C0518724A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CC0C2DDE-D058-4075-84A6-016C0518724A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CC0C2DDE-D058-4075-84A6-016C0518724A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CC0C2DDE-D058-4075-84A6-016C0518724A}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -106,6 +112,7 @@ Global
 		{AB9EA79C-F11F-4B93-A08E-8C52A9716666} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA}
 		{61B7FF00-1B9D-4ABF-B3BF-667A1505415F} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA}
 		{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA}
+		{CC0C2DDE-D058-4075-84A6-016C0518724A} = {6D2194E0-E17B-44D6-AD8C-F3699549D259}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {EE8EFE44-67AF-451F-9DFD-7B458AA3B3B3}
diff --git a/CBSVisualizer/CBSVisualizer/App.xaml.cs b/CBSVisualizer/CBSVisualizer/App.xaml.cs
index dfe06d67ea0b4a22bbb891d7d3700fa8282a2f58..7aaf0bf5dec77f4e8309916b9396c08bc451d1e2 100644
--- a/CBSVisualizer/CBSVisualizer/App.xaml.cs
+++ b/CBSVisualizer/CBSVisualizer/App.xaml.cs
@@ -10,6 +10,7 @@ using CBSVisualizer.Modules.Link;
 using CBSVisualizer.Modules.SettingsDialog;
 using CBSVisualizer.Modules.MenuBar;
 using System.IO;
+using CBSVisualizer.Modules.Charts;
 using CBSVisualizer.Services.PacketService.Implementation;
 using CBSVisualizer.Services.PacketService.Interface;
 using CBSVisualizer.Services.SchedulingService.Interface;
@@ -41,6 +42,7 @@ namespace CBSVisualizer
             moduleCatalog.AddModule<LinkModule>();
             moduleCatalog.AddModule<QueueGroupModule>();
             moduleCatalog.AddModule<MenuBarModule>();
+            moduleCatalog.AddModule<ChartsModule>();
         }
     }
 }
diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
index 3a731bff7ba3bd2a27daaa261a8d5559858f9eae..a34f54c868506f60c713a2343f501a8f50e037fa 100644
--- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
+++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj
@@ -12,6 +12,7 @@
     <PackageReference Include="Prism.DryIoc" Version="7.2.0.1422" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\CBSVisualizer.Modules.Charts\CBSVisualizer.Modules.Charts.csproj" />
     <ProjectReference Include="..\CBSVisualizer.Modules.Link\CBSVisualizer.Modules.Link.csproj" />
     <ProjectReference Include="..\CBSVisualizer.Modules.MenuBar\CBSVisualizer.Modules.MenuBar.csproj" />
     <ProjectReference Include="..\CBSVisualizer.Modules.Queue.QueueGroup\CBSVisualizer.Modules.QueueGroup.csproj" />
diff --git a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
index 1d124522c5525de76cc46166a5d4519982551b33..e8f27f4db3919e229369693c8ae02230b5e07b50 100644
--- a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
+++ b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml
@@ -10,8 +10,7 @@
         Background="{DynamicResource MaterialDesignPaper}"
         TextElement.FontWeight="Medium"
         TextElement.FontSize="14"
-        FontFamily="{materialDesign:MaterialDesignFont}"
-        >
+        FontFamily="{materialDesign:MaterialDesignFont}">
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"/>
@@ -20,9 +19,11 @@
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="Auto"/>
             <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="*"/>
         </Grid.ColumnDefinitions>
-        <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuBarRegion}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"/>
-        <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.QueueGroupRegion}" Grid.Column="1" Grid.Row="1"/>
+        <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuBarRegion}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"/>
         <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.LinkRegion}" Grid.Column="0" Grid.Row="1" Margin="30, 0, 0, 0"/>
+        <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.QueueGroupRegion}" Grid.Column="1" Grid.Row="1"/>
+        <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.ChartsRegion}" Grid.Column="2" Grid.Row="1"/>
     </Grid>
 </Window>