-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #76 from glopesdev/timeline-visualizer
Add timeline visualizer for Harp message streams
- Loading branch information
Showing
14 changed files
with
1,072 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> | ||
|
||
<PropertyGroup> | ||
<Title>Bonsai - Harp Visualizers Library</Title> | ||
<Description>Bonsai Design Library containing operators for visualizing Harp message streams.</Description> | ||
<PackageTags>Bonsai Rx Harp Visualizers</PackageTags> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
<UseWindowsForms>true</UseWindowsForms> | ||
<TargetFramework>net472</TargetFramework> | ||
<Version>0.1.0</Version> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Bonsai.Design.Visualizers" Version="2.8.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Bonsai.Harp.Design\Bonsai.Harp.Design.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using System; | ||
using ZedGraph; | ||
|
||
namespace Bonsai.Harp.Visualizers | ||
{ | ||
internal class BoundedPointPairList : IPointListEdit | ||
{ | ||
double minValue = double.MinValue; | ||
double maxValue = double.MaxValue; | ||
readonly QueueList<PointPair> points = new(); | ||
|
||
public BoundedPointPairList() | ||
{ | ||
} | ||
|
||
public BoundedPointPairList(IPointList points) | ||
{ | ||
for (int i = 0; i < points.Count; i++) | ||
{ | ||
Add(points[i]); | ||
} | ||
} | ||
|
||
public void SetBounds(double min, double max) | ||
{ | ||
if (max < min) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(max)); | ||
} | ||
|
||
minValue = min; | ||
maxValue = max; | ||
while (points.Count > 0 && points[0].X < min) | ||
{ | ||
points.TryDequeue(out _); | ||
} | ||
|
||
while (points.Count > 0 && points[points.Count - 1].X > max) | ||
{ | ||
points.TryDequeueLast(out _); | ||
} | ||
} | ||
|
||
public PointPair this[int index] | ||
{ | ||
get => points[index]; | ||
set => points[index] = value; | ||
} | ||
|
||
PointPair IPointList.this[int index] => this[index]; | ||
|
||
public int Count => points.Count; | ||
|
||
public void Add(PointPair point) | ||
{ | ||
if (point.X >= minValue && point.X <= maxValue) | ||
{ | ||
points.Enqueue(point); | ||
} | ||
} | ||
|
||
public void Add(double x, double y) | ||
{ | ||
if (x >= minValue && x <= maxValue) | ||
{ | ||
points.Enqueue(new PointPair(x, y)); | ||
} | ||
} | ||
|
||
public void Clear() | ||
{ | ||
points.Clear(); | ||
} | ||
|
||
public object Clone() | ||
{ | ||
return new BoundedPointPairList(this); | ||
} | ||
|
||
public void RemoveAt(int index) | ||
{ | ||
points.RemoveAt(index); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using ZedGraph; | ||
|
||
namespace Bonsai.Harp.Visualizers | ||
{ | ||
static class GraphHelper | ||
{ | ||
internal static void SetAxisLabel(Axis axis, string label) | ||
{ | ||
axis.Title.Text = label; | ||
axis.Title.IsVisible = !string.IsNullOrEmpty(label); | ||
} | ||
|
||
internal static void FormatTimeAxis(Axis axis) | ||
{ | ||
axis.Type = AxisType.Linear; | ||
axis.Scale.MaxAuto = false; | ||
axis.Scale.MinAuto = false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using Bonsai; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: XmlNamespacePrefix("clr-namespace:Bonsai.Harp.Visualizers", "harpviz")] | ||
[assembly: WorkflowNamespaceIcon("Bonsai:ElementIcon.Visualizer")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"profiles": { | ||
"Bonsai": { | ||
"commandName": "Executable", | ||
"executablePath": "$(registry:HKEY_CURRENT_USER\\Software\\Bonsai Foundation\\Bonsai@InstallDir)Bonsai.exe", | ||
"commandLineArgs": "--lib:\"$(TargetDir).\"", | ||
"nativeDebugging": true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace Bonsai.Harp.Visualizers | ||
{ | ||
internal class QueueList<T> : IReadOnlyList<T> | ||
{ | ||
int head; | ||
int tail; | ||
int count; | ||
T[] buffer; | ||
|
||
public QueueList() : this(capacity: 4) | ||
{ | ||
} | ||
|
||
public QueueList(int capacity) | ||
{ | ||
if (capacity < 0) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(capacity)); | ||
} | ||
|
||
EnsureCapacity(capacity); | ||
} | ||
|
||
private void EnsureCapacity(int capacity) | ||
{ | ||
var array = new T[capacity]; | ||
if (count > 0) | ||
{ | ||
if (head < tail) | ||
{ | ||
Array.Copy(buffer, head, array, 0, count); | ||
} | ||
else | ||
{ | ||
Array.Copy(buffer, head, array, 0, buffer.Length - head); | ||
Array.Copy(buffer, 0, array, buffer.Length - head, tail); | ||
} | ||
} | ||
|
||
buffer = array; | ||
head = 0; | ||
tail = count; | ||
} | ||
|
||
private int GetIndexInternal(int index) | ||
{ | ||
return (head + index) % buffer.Length; | ||
} | ||
|
||
public T this[int index] | ||
{ | ||
get | ||
{ | ||
if (index < 0 || index >= count) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(index)); | ||
} | ||
|
||
return buffer[GetIndexInternal(index)]; | ||
} | ||
set | ||
{ | ||
if (index < 0 || index >= count) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(index)); | ||
} | ||
|
||
buffer[GetIndexInternal(index)] = value; | ||
} | ||
} | ||
|
||
public int Count => count; | ||
|
||
public void Enqueue(T item) | ||
{ | ||
if (count >= buffer.Length) | ||
{ | ||
EnsureCapacity(buffer.Length * 2); | ||
} | ||
|
||
buffer[tail] = item; | ||
tail = (tail + 1) % buffer.Length; | ||
count++; | ||
} | ||
|
||
public bool TryDequeue(out T result) | ||
{ | ||
if (count == 0) | ||
{ | ||
result = default; | ||
return false; | ||
} | ||
|
||
result = buffer[head]; | ||
buffer[head] = default; | ||
head = (head + 1) % buffer.Length; | ||
count--; | ||
return true; | ||
} | ||
|
||
public bool TryDequeueLast(out T result) | ||
{ | ||
if (count == 0) | ||
{ | ||
result = default; | ||
return false; | ||
} | ||
|
||
var index = tail - 1; | ||
if (index < 0) index += buffer.Length; | ||
result = buffer[index]; | ||
buffer[index] = default; | ||
tail = index; | ||
count--; | ||
return true; | ||
} | ||
|
||
public void Clear() | ||
{ | ||
if (head < tail) | ||
{ | ||
Array.Clear(buffer, head, count); | ||
} | ||
else | ||
{ | ||
Array.Clear(buffer, head, buffer.Length - head); | ||
Array.Clear(buffer, 0, tail); | ||
} | ||
|
||
head = 0; | ||
tail = 0; | ||
count = 0; | ||
} | ||
|
||
public IEnumerator<T> GetEnumerator() | ||
{ | ||
for (int i = 0; i < count; i++) | ||
{ | ||
yield return buffer[GetIndexInternal(i)]; | ||
} | ||
} | ||
|
||
public void RemoveAt(int index) | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
|
||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return GetEnumerator(); | ||
} | ||
} | ||
} |
Oops, something went wrong.