Skip to content

Commit

Permalink
Add index and curve settings to line graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
glopesdev committed Mar 25, 2024
1 parent c413d1e commit edc20b7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 17 deletions.
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
46 changes: 41 additions & 5 deletions src/Bonsai.Gui.Visualizers/LineGraphBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Bonsai.Expressions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
Expand All @@ -17,6 +18,13 @@ namespace Bonsai.Gui.Visualizers
[Description("A visualizer that plots each element of the sequence as a line graph.")]
public class LineGraphBuilder : SingleArgumentExpressionBuilder
{
/// <summary>
/// Gets or sets the name of the property that will be used as index for the graph.
/// </summary>
[Editor("Bonsai.Design.MemberSelectorEditor, Bonsai.Design", DesignTypes.UITypeEditor)]
[Description("The name of the property that will be used as index for the graph.")]
public string IndexSelector { get; set; }

/// <summary>
/// Gets or sets the names of the properties to be displayed in the graph.
/// Each selected property must have a point pair compatible type.
Expand All @@ -39,6 +47,13 @@ public class LineGraphBuilder : SingleArgumentExpressionBuilder
[Description("The width, in points, to be used for the line graph. Use a value of zero to hide the line.")]
public float LineWidth { get; set; } = 1;

/// <summary>
/// Gets the optional settings for each line added to the graph.
/// </summary>
[Category(nameof(CategoryAttribute.Appearance))]
[Description("Specifies optional settings for each line added to the graph.")]
public Collection<CurveConfiguration> CurveSettings { get; } = new();

/// <summary>
/// Gets or sets the optional capacity used for rolling line graphs. If no capacity is specified, all data points will be displayed.
/// </summary>
Expand Down Expand Up @@ -87,11 +102,14 @@ internal class VisualizerController
internal double? XMax;
internal double? YMin;
internal double? YMax;
internal Type IndexType;
internal string IndexLabel;
internal bool LabelAxes;
internal string[] ValueLabels;
internal SymbolType SymbolType;
internal float LineWidth;
internal Action<object, LineGraphVisualizer> AddValues;
internal CurveConfiguration[] CurveSettings;
internal Action<DateTime, object, ILineGraphVisualizer> AddValues;
}

/// <summary>
Expand All @@ -103,8 +121,9 @@ 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(LineGraphVisualizer));
var viewParameter = Expression.Parameter(typeof(ILineGraphVisualizer));
var elementVariable = Expression.Variable(parameterType);
Controller = new VisualizerController
{
Expand All @@ -114,18 +133,30 @@ public override Expression Build(IEnumerable<Expression> arguments)
YMin = YMin,
YMax = YMax,
SymbolType = SymbolType,
LineWidth = LineWidth
LineWidth = LineWidth,
CurveSettings = CurveSettings.ToArray()
};

var selectedIndex = GraphHelper.SelectIndexMember(timeParameter, elementVariable, IndexSelector, out Controller.IndexLabel);
Controller.IndexType = selectedIndex.Type;
if (selectedIndex.Type != typeof(double) && selectedIndex.Type != typeof(string))
{
selectedIndex = Expression.Convert(selectedIndex, typeof(double));
}

var selectedValues = GraphHelper.SelectDataPoints(
elementVariable,
ValueSelector,
out Controller.ValueLabels,
out Controller.LabelAxes);
var addValuesBody = Expression.Block(new[] { elementVariable },
Expression.Assign(elementVariable, Expression.Convert(valueParameter, parameterType)),
Expression.Call(viewParameter, nameof(LineGraphVisualizer.AddValues), null, selectedValues));
Controller.AddValues = Expression.Lambda<Action<object, LineGraphVisualizer>>(addValuesBody, valueParameter, viewParameter).Compile();
Expression.Call(viewParameter, nameof(ILineGraphVisualizer.AddValues), null, selectedIndex, selectedValues));
Controller.AddValues = Expression.Lambda<Action<DateTime, object, ILineGraphVisualizer>>(
addValuesBody,
timeParameter,
valueParameter,
viewParameter).Compile();
return Expression.Call(typeof(LineGraphBuilder), nameof(Process), new[] { parameterType }, source);
}

Expand All @@ -134,4 +165,9 @@ static IObservable<TSource> Process<TSource>(IObservable<TSource> source)
return source;
}
}

interface ILineGraphVisualizer
{
void AddValues(double index, params PointPair[] values);
}
}
24 changes: 15 additions & 9 deletions src/Bonsai.Gui.Visualizers/LineGraphVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Bonsai.Gui.Visualizers
/// <summary>
/// Provides a type visualizer to display an object as a line graph.
/// </summary>
public class LineGraphVisualizer : BufferedVisualizer
public class LineGraphVisualizer : BufferedVisualizer, ILineGraphVisualizer
{
LineGraphBuilder.VisualizerController controller;
LineGraphView view;
Expand Down Expand Up @@ -55,7 +55,7 @@ public class LineGraphVisualizer : BufferedVisualizer
/// </summary>
public bool AutoScaleY { get; set; } = true;

internal void AddValues(PointPair[] values)
void ILineGraphVisualizer.AddValues(double index, params PointPair[] values)
{
if (view.Graph.NumSeries != values.Length || reset)
{
Expand All @@ -65,7 +65,7 @@ internal void AddValues(PointPair[] values)
reset);
reset = false;
}
view.Graph.AddValues(values);
view.Graph.AddValues(index, values);
}

/// <inheritdoc/>
Expand Down Expand Up @@ -157,12 +157,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 @@ -173,6 +167,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
4 changes: 2 additions & 2 deletions src/Bonsai.Gui.Visualizers/RollingGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@ public void AddValues(double index, string label, params double[] values)
}
}

public void AddValues(params PointPair[] values)
public void AddValues(double index, params PointPair[] values)
{
for (int i = 0; i < series.Length; i++)
{
series[i].Add(values[i]);
series[i].Add(values[i].X, values[i].Y, index, values[i].Tag);
}
}

Expand Down

0 comments on commit edc20b7

Please sign in to comment.