Skip to content

Commit

Permalink
Merge pull request #16 from bonsai-rx/feature-dev
Browse files Browse the repository at this point in the history
Support mashup of both rolling and 2D graph panels
  • Loading branch information
glopesdev authored Mar 25, 2024
2 parents 0c1da09 + 359d9a9 commit 86c0b7f
Show file tree
Hide file tree
Showing 23 changed files with 1,280 additions and 248 deletions.
11 changes: 8 additions & 3 deletions src/Bonsai.Gui.Visualizers/BarGraphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ internal class VisualizerController
internal string IndexLabel;
internal string[] ValueLabels;
internal CurveConfiguration[] CurveSettings;
internal Action<object, IBarGraphVisualizer> AddValues;
internal Action<DateTime, object, IBarGraphVisualizer> AddValues;
internal BarBase BaseAxis;
internal BarType BarType;
}
Expand All @@ -103,6 +103,7 @@ public override Expression Build(IEnumerable<Expression> arguments)
{
var source = arguments.First();
var parameterType = source.Type.GetGenericArguments()[0];
var timeParameter = Expression.Parameter(typeof(DateTime));
var valueParameter = Expression.Parameter(typeof(object));
var viewParameter = Expression.Parameter(typeof(IBarGraphVisualizer));
var elementVariable = Expression.Variable(parameterType);
Expand All @@ -116,7 +117,7 @@ public override Expression Build(IEnumerable<Expression> arguments)
CurveSettings = CurveSettings.ToArray()
};

var selectedIndex = GraphHelper.SelectIndexMember(elementVariable, IndexSelector, out Controller.IndexLabel);
var selectedIndex = GraphHelper.SelectIndexMember(timeParameter, elementVariable, IndexSelector, out Controller.IndexLabel);
Controller.IndexType = selectedIndex.Type;
if (selectedIndex.Type != typeof(double) && selectedIndex.Type != typeof(string))
{
Expand All @@ -127,7 +128,11 @@ public override Expression Build(IEnumerable<Expression> arguments)
var addValuesBody = Expression.Block(new[] { elementVariable },
Expression.Assign(elementVariable, Expression.Convert(valueParameter, parameterType)),
Expression.Call(viewParameter, nameof(IBarGraphVisualizer.AddValues), null, selectedIndex, selectedValues));
Controller.AddValues = Expression.Lambda<Action<object, IBarGraphVisualizer>>(addValuesBody, valueParameter, viewParameter).Compile();
Controller.AddValues = Expression.Lambda<Action<DateTime, object, IBarGraphVisualizer>>(
addValuesBody,
timeParameter,
valueParameter,
viewParameter).Compile();
return Expression.Call(typeof(BarGraphBuilder), nameof(Process), new[] { parameterType }, source);
}

Expand Down
8 changes: 4 additions & 4 deletions src/Bonsai.Gui.Visualizers/BarGraphOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Bonsai.Expressions;
using ZedGraph;

[assembly: TypeVisualizer(typeof(BarGraphOverlay), Target = typeof(MashupSource<GraphPanelVisualizer, BarGraphVisualizer>))]
[assembly: TypeVisualizer(typeof(BarGraphOverlay), Target = typeof(MashupSource<RollingGraphPanelVisualizer, BarGraphVisualizer>))]


namespace Bonsai.Gui.Visualizers
Expand All @@ -18,7 +18,7 @@ namespace Bonsai.Gui.Visualizers
/// </summary>
public class BarGraphOverlay : BufferedVisualizer, IBarGraphVisualizer
{
GraphPanelVisualizer visualizer;
RollingGraphPanelVisualizer visualizer;
BarGraphBuilder.VisualizerController controller;
BoundedPointPairList[] series;

Expand Down Expand Up @@ -83,7 +83,7 @@ void AddBaseY()
/// <inheritdoc/>
public override void Load(IServiceProvider provider)
{
visualizer = (GraphPanelVisualizer)provider.GetService(typeof(MashupVisualizer));
visualizer = (RollingGraphPanelVisualizer)provider.GetService(typeof(MashupVisualizer));
var context = (ITypeVisualizerContext)provider.GetService(typeof(ITypeVisualizerContext));
var barGraphBuilder = (BarGraphBuilder)ExpressionBuilder.GetVisualizerElement(context.Source).Builder;
controller = barGraphBuilder.Controller;
Expand Down Expand Up @@ -141,7 +141,7 @@ public override void Show(object value)
/// <inheritdoc/>
protected override void Show(DateTime time, object value)
{
controller.AddValues(value, this);
controller.AddValues(time, value, this);
}

/// <inheritdoc/>
Expand Down
18 changes: 12 additions & 6 deletions src/Bonsai.Gui.Visualizers/BarGraphVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,6 @@ public override void Load(IServiceProvider provider)
}
}

/// <inheritdoc/>
public override void Show(object value)
{
controller.AddValues(value, this);
}

/// <inheritdoc/>
protected override void ShowBuffer(IList<Timestamped<object>> values)
{
Expand All @@ -164,6 +158,18 @@ protected override void ShowBuffer(IList<Timestamped<object>> values)
}
}

/// <inheritdoc/>
public override void Show(object value)
{
Show(DateTime.Now, value);
}

/// <inheritdoc/>
protected override void Show(DateTime time, object value)
{
controller.AddValues(time, value, this);
}

/// <inheritdoc/>
public override void SequenceCompleted()
{
Expand Down
8 changes: 4 additions & 4 deletions src/Bonsai.Gui.Visualizers/Bonsai.Gui.Visualizers.csproj.user
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
<Compile Update="GraphControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="GraphPanel.cs">
<Compile Update="RollingGraphPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="GraphPanel2D.cs">
<Compile Update="GraphPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="GraphPanelView.cs">
<Compile Update="RollingGraphPanelView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="GraphPanelView2D.cs">
<Compile Update="GraphPanelView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="LineGraph.cs">
Expand Down
2 changes: 1 addition & 1 deletion src/Bonsai.Gui.Visualizers/GraphHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ internal static Expression SelectDataPoints(Expression expression, string valueS
if (memberNames.Length == 1)
{
var memberName = memberNames[0];
valueLabels = memberName != ExpressionHelper.ImplicitParameterName ? new[] { memberName } : null;
valueLabels = new[] { memberName };
var member = ExpressionHelper.MemberAccess(expression, memberNames[0]);
if (member.Type.IsArray)
{
Expand Down
75 changes: 53 additions & 22 deletions src/Bonsai.Gui.Visualizers/GraphPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,87 @@ namespace Bonsai.Gui.Visualizers
{
internal class GraphPanel : BoundedGraphPanel
{
bool autoScale;
bool autoScaleX;
bool autoScaleY;

public GraphPanel()
{
autoScale = true;
autoScaleX = true;
autoScaleY = true;
}

public Axis ScaleAxis => GraphPane.BarSettings.Base switch
public double XMin
{
BarBase.Y => GraphPane.XAxis,
BarBase.Y2 => GraphPane.X2Axis,
BarBase.X2 => GraphPane.Y2Axis,
_ => GraphPane.YAxis
};
get { return GraphPane.XAxis.Scale.Min; }
set
{
GraphPane.XAxis.Scale.Min = value;
GraphPane.AxisChange();
Invalidate();
}
}

public double Min
public double XMax
{
get { return ScaleAxis.Scale.Min; }
get { return GraphPane.XAxis.Scale.Max; }
set
{
ScaleAxis.Scale.Min = value;
GraphPane.XAxis.Scale.Max = value;
GraphPane.AxisChange();
Invalidate();
}
}

public double Max
public double YMin
{
get { return ScaleAxis.Scale.Max; }
get { return GraphPane.YAxis.Scale.Min; }
set
{
ScaleAxis.Scale.Max = value;
GraphPane.YAxis.Scale.Min = value;
GraphPane.AxisChange();
Invalidate();
}
}

public bool AutoScale
public double YMax
{
get { return GraphPane.YAxis.Scale.Max; }
set
{
GraphPane.YAxis.Scale.Max = value;
GraphPane.AxisChange();
Invalidate();
}
}

public bool AutoScaleX
{
get { return autoScaleX; }
set
{
var changed = autoScaleX != value;
autoScaleX = value;
if (changed)
{
GraphPane.XAxis.Scale.MaxAuto = autoScaleX;
GraphPane.XAxis.Scale.MinAuto = autoScaleX;
if (autoScaleX) Invalidate();
}
}
}

public bool AutoScaleY
{
get { return autoScale; }
get { return autoScaleY; }
set
{
var changed = autoScale != value;
autoScale = value;
var changed = autoScaleY != value;
autoScaleY = value;
if (changed)
{
var baseAxis = ScaleAxis;
baseAxis.Scale.MaxAuto = autoScale;
baseAxis.Scale.MinAuto = autoScale;
if (autoScale) Invalidate();
GraphPane.YAxis.Scale.MaxAuto = autoScaleY;
GraphPane.YAxis.Scale.MinAuto = autoScaleY;
if (autoScaleY) Invalidate();
}
}
}
Expand Down
84 changes: 23 additions & 61 deletions src/Bonsai.Gui.Visualizers/GraphPanelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reactive;
using Bonsai.Expressions;
using ZedGraph;

namespace Bonsai.Gui.Visualizers
{
Expand All @@ -14,86 +12,50 @@ namespace Bonsai.Gui.Visualizers
/// </summary>
[TypeVisualizer(typeof(GraphPanelVisualizer))]
[Description("Specifies a mashup graph panel that can be used to combine multiple plots sharing the same axes.")]
public class GraphPanelBuilder : ZeroArgumentExpressionBuilder, INamedElement
public class GraphPanelBuilder : GraphPanelBuilderBase
{
/// <summary>
/// Gets or sets the name of the visualizer window.
/// </summary>
[Category(nameof(CategoryAttribute.Design))]
[Description("The name of the visualizer window.")]
public string Name { get; set; }

/// <summary>
/// Gets or sets a value specifying the axis on which the bars in the graph will be displayed.
/// </summary>
[TypeConverter(typeof(BaseAxisConverter))]
[Category(nameof(CategoryAttribute.Appearance))]
[Description("Specifies the axis on which the bars in the graph will be displayed.")]
public BarBase BaseAxis { get; set; }

/// <summary>
/// Gets or sets a value specifying how the different bars in the graph will be visually arranged.
/// </summary>
[Category(nameof(CategoryAttribute.Appearance))]
[Description("Specifies how the different bars in the graph will be visually arranged.")]
public BarType BarType { get; set; }

/// <summary>
/// Gets or sets a value specifying whether the scale values are reversed on the X-axis.
/// </summary>
[Category(nameof(CategoryAttribute.Appearance))]
[Description("Specifies whether the scale values are reversed on the X-axis.")]
public bool ReverseX { get; set; }

/// <summary>
/// Gets or sets a value specifying whether the scale values are reversed on the Y-axis.
/// </summary>
[Category(nameof(CategoryAttribute.Appearance))]
[Description("Specifies whether the scale values are reversed on the Y-axis.")]
public bool ReverseY { get; set; }

/// <summary>
/// Gets or sets the optional maximum span of data displayed at any one moment in the graph.
/// If no span is specified, all data points will be displayed.
/// Gets or sets a value specifying a fixed lower limit for the X-axis range.
/// If no fixed range is specified, the graph limits can be edited online.
/// </summary>
[Category("Range")]
[Description("The optional maximum span of data displayed at any one moment in the graph. " +
"If no span is specified, all data points will be displayed.")]
public double? Span { get; set; }
[Description("Specifies the optional fixed lower limit of the X-axis range.")]
public double? XMin { get; set; }

/// <summary>
/// Gets or sets the optional capacity used for rolling line graphs. If no capacity is specified, all data points will be displayed.
/// Gets or sets a value specifying a fixed upper limit for the X-axis range.
/// If no fixed range is specified, the graph limits can be edited online.
/// </summary>
[Category("Range")]
[Description("The optional capacity used for rolling line graphs. If no capacity is specified, all data points will be displayed.")]
public int? Capacity { get; set; }
[Description("Specifies the optional fixed upper limit of the X-axis range.")]
public double? XMax { get; set; }

/// <summary>
/// Gets or sets a value specifying a fixed lower limit for the axis range.
/// Gets or sets a value specifying a fixed lower limit for the Y-axis range.
/// If no fixed range is specified, the graph limits can be edited online.
/// </summary>
[Category("Range")]
[Description("Specifies the optional fixed lower limit of the axis range.")]
public double? Min { get; set; }
[Description("Specifies the optional fixed lower limit of the Y-axis range.")]
public double? YMin { get; set; }

/// <summary>
/// Gets or sets a value specifying a fixed upper limit for the axis range.
/// Gets or sets a value specifying a fixed upper limit for the Y-axis range.
/// If no fixed range is specified, the graph limits can be edited online.
/// </summary>
[Category("Range")]
[Description("Specifies the optional fixed upper limit of the axis range.")]
public double? Max { get; set; }
[Description("Specifies the optional fixed upper limit of the Y-axis range.")]
public double? YMax { get; set; }

internal VisualizerController Controller { get; set; }

internal class VisualizerController
{
internal BarBase BaseAxis;
internal BarType BarType;
internal double? Span;
internal int? Capacity;
internal double? Min;
internal double? Max;
internal double? XMin;
internal double? XMax;
internal double? YMin;
internal double? YMax;
internal bool ReverseX;
internal bool ReverseY;
}
Expand All @@ -107,12 +69,12 @@ public override Expression Build(IEnumerable<Expression> arguments)
{
Controller = new VisualizerController
{
BaseAxis = BaseAxis,
BarType = BarType,
Span = Span,
Capacity = Capacity,
Min = Min,
Max = Max,
XMin = XMin,
XMax = XMax,
YMin = YMin,
YMax = YMax,
ReverseX = ReverseX,
ReverseY = ReverseY
};
Expand Down
Loading

0 comments on commit 86c0b7f

Please sign in to comment.