Skip to content

Commit 63c42d4

Browse files
authored
Merge pull request #218 from reactivemarbles/UpdatePlot
Improve WPF plot UI performance and documentation
2 parents b35b309 + c165ff8 commit 63c42d4

34 files changed

+1422
-683
lines changed

Directory.Build.props

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@
3535
<XamarinReactiveUIVersion>19.6.12</XamarinReactiveUIVersion>
3636
<WebViewVersion>1.0.3650.58</WebViewVersion>
3737
<CoreNetVersion>9.0.11</CoreNetVersion>
38-
<CrissCrossCoreTargetFrameworks>netstandard2.0;net8.0;net9.0;net10.0</CrissCrossCoreTargetFrameworks>
38+
<CrissCrossCoreTargetFrameworks>net8.0;net9.0;net10.0</CrissCrossCoreTargetFrameworks>
39+
<CrissCrossAvaloniaTargetFrameworks>net8.0;net9.0;net10.0</CrissCrossAvaloniaTargetFrameworks>
3940
<CrissCrossWinTargetFrameworks>net472;net48;net8.0-windows10.0.19041.0;net9.0-windows10.0.19041.0;net10.0-windows10.0.19041.0</CrissCrossWinTargetFrameworks>
4041
<CrissCrossWebviewTargetFrameworks>net472;net48;net8.0-windows;net9.0-windows;net10.0-windows</CrissCrossWebviewTargetFrameworks>
4142
</PropertyGroup>
43+
<PropertyGroup Condition="$([MSBuild]::IsOsPlatform('Windows'))">
44+
<CrissCrossCoreTargetFrameworks>$(CrissCrossCoreTargetFrameworks);net472;net48</CrissCrossCoreTargetFrameworks>
45+
</PropertyGroup>
4246
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
4347
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
4448
</PropertyGroup>

src/CrissCross.Avalonia.UI/Appearance/SystemThemeManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ private static SystemTheme DetectSystemTheme()
8888

8989
private static SystemTheme DetectWindowsTheme()
9090
{
91+
#if WINDOWS
9192
try
9293
{
9394
using var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
@@ -100,7 +101,7 @@ private static SystemTheme DetectWindowsTheme()
100101
{
101102
// Registry access might fail on some systems
102103
}
103-
104+
#endif
104105
return SystemTheme.Light;
105106
}
106107

src/CrissCross.Avalonia.UI/Controls/SymbolRegular.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace CrissCross.Avalonia.UI.Controls;
77
/// <summary>
88
/// Represents Fluent System Icons regular symbols.
99
/// </summary>
10+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1069:Enums values should not be duplicated", Justification = "By design for mirroring purposes.")]
1011
public enum SymbolRegular
1112
{
1213
/// <summary>

src/CrissCross.Avalonia.UI/CrissCross.Avalonia.UI.csproj

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
4+
<TargetFrameworks>$(CrissCrossAvaloniaTargetFrameworks);</TargetFrameworks>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -44,16 +44,12 @@
4444
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.*" />
4545
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.*" />
4646
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.*" />
47-
<PackageReference Include="ReactiveList" Version="2.4.5" />
47+
<PackageReference Include="ReactiveList" Version="3.0.2" />
4848
<PackageReference Include="AngleSharp" Version="1.4.0" />
4949
<PackageReference Include="Markdig" Version="0.44.0" />
5050
<!-- Source generators / analyzers isolated from consumers -->
5151
<PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
52-
<PackageReference Include="ReactiveUI.SourceGenerators" Version="2.5.1" PrivateAssets="all" />
53-
<PackageReference Include="PolySharp" Version="1.15.0">
54-
<PrivateAssets>all</PrivateAssets>
55-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
56-
</PackageReference>
52+
<PackageReference Include="ReactiveUI.SourceGenerators" Version="2.6.1" PrivateAssets="all" />
5753
</ItemGroup>
5854

5955
<ItemGroup>

src/CrissCross.Avalonia/CrissCross.Avalonia.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>$(CrissCrossCoreTargetFrameworks);</TargetFrameworks>
4+
<TargetFrameworks>$(CrissCrossAvaloniaTargetFrameworks);</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>

src/CrissCross.WPF.Plot.Test/CrissCross.WPF.Plot.Test.csproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>WinExe</OutputType>
5-
<TargetFrameworks>net8.0-windows10.0.19041.0;net9.0-windows10.0.19041.0</TargetFrameworks>
5+
<TargetFrameworks>$(CrissCrossWinTargetFrameworks)</TargetFrameworks>
66
<Nullable>enable</Nullable>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<UseWPF>true</UseWPF>
@@ -11,7 +11,14 @@
1111

1212
<ItemGroup>
1313
<PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
14-
<PackageReference Include="ReactiveUI.SourceGenerators" Version="2.5.1" PrivateAssets="all" />
14+
<PackageReference Include="ReactiveUI.SourceGenerators" Version="2.6.1" PrivateAssets="all" />
15+
</ItemGroup>
16+
17+
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
18+
<PackageReference Include="Polyfill" Version="9.7.0">
19+
<PrivateAssets>all</PrivateAssets>
20+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
21+
</PackageReference>
1522
</ItemGroup>
1623

1724
<ItemGroup>

src/CrissCross.WPF.Plot/Controls/AxisLinesUI.cs

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414
namespace CrissCross.WPF.Plot;
1515

1616
/// <summary>
17-
/// Nice for continuous live data.
17+
/// Provides UI functionality for displaying and managing axis lines on a WPF plot, supporting both horizontal and
18+
/// vertical orientations with customizable appearance and reactive updates.
1819
/// </summary>
19-
/// <seealso cref="AxisLinesUI" />
20+
/// <remarks>AxisLinesUI enables dynamic creation and updating of axis lines on a WpfPlot, allowing integration
21+
/// with observable data sources for real-time position changes. The class supports customization of line style, color,
22+
/// label text, and axis selection. It is intended for use on Windows platforms and manages resources appropriately
23+
/// through disposal. Thread safety is considered when updating UI elements via observables.</remarks>
2024
[SupportedOSPlatform("windows")]
2125
public partial class AxisLinesUI : RxObject
2226
{
@@ -36,15 +40,22 @@ public partial class AxisLinesUI : RxObject
3640
private LinePattern _linePattern1;
3741

3842
/// <summary>
39-
/// Initializes a new instance of the <see cref="AxisLinesUI" /> class.
43+
/// Initializes a new instance of the <see cref="AxisLinesUI"/> class, configuring axis lines on the specified plot with.
44+
/// customizable orientation, appearance, and label text. Subscribes to an observable to update the axis line's
45+
/// position and name dynamically.
4046
/// </summary>
41-
/// <param name="plot">if set to <c>true</c> [paused].</param>
42-
/// <param name="observable">The observable.</param>
43-
/// <param name="orientation">The orientation ["Horizontal"] or ["Vertical"].</param>
44-
/// <param name="axis">The axis.</param>
45-
/// <param name="color">The color.</param>
46-
/// <param name="text">The text.</param>
47-
/// <param name="linePattern">The line pattern.</param>
47+
/// <remarks>If the orientation is set to "Horizontal", a horizontal axis line is created; if set to
48+
/// "Vertical", a vertical axis line is created. The observable parameter allows the axis line's position and name
49+
/// to be updated in real time as new values are emitted. This constructor is intended for use in interactive or
50+
/// dynamic plotting scenarios where axis lines need to reflect changing data.</remarks>
51+
/// <param name="plot">The WpfPlot control on which the axis lines will be rendered.</param>
52+
/// <param name="observable">An observable sequence that provides updates for the axis line's name and position. Each tuple contains an
53+
/// optional name and an optional position value.</param>
54+
/// <param name="linePattern">The line pattern to use for rendering the axis line, such as solid or dashed.</param>
55+
/// <param name="orientation">The orientation of the axis line. Specify "Horizontal" or "Vertical". Defaults to "Horizontal".</param>
56+
/// <param name="axis">The index of the axis to which the line is associated. Defaults to 0.</param>
57+
/// <param name="color">The color of the axis line. Specify a color name or value. Defaults to "Blue".</param>
58+
/// <param name="text">The label text to display alongside the axis line. Defaults to "---".</param>
4859
public AxisLinesUI(
4960
WpfPlot plot,
5061
IObservable<(string? Name, double? Position)> observable,
@@ -74,15 +85,20 @@ public AxisLinesUI(
7485
}
7586

7687
/// <summary>
77-
/// Initializes a new instance of the <see cref="AxisLinesUI" /> class.
88+
/// Initializes a new instance of the <see cref="AxisLinesUI"/> class, adding a horizontal or vertical axis line to the specified.
89+
/// plot at the given position with customizable appearance and label.
7890
/// </summary>
79-
/// <param name="plot">if set to <c>true</c> [paused].</param>
80-
/// <param name="position">The position.</param>
81-
/// <param name="linePattern">The line pattern.</param>
82-
/// <param name="type">The type.</param>
83-
/// <param name="axis">The axis.</param>
84-
/// <param name="color">The color.</param>
85-
/// <param name="text">The text.</param>
91+
/// <remarks>If the type parameter is set to "Horizontal", a horizontal axis line is created; if set to
92+
/// "Vertical", a vertical axis line is created. The appearance and label of the line can be customized using the
93+
/// provided parameters.</remarks>
94+
/// <param name="plot">The WpfPlot control to which the axis line will be added. Cannot be null.</param>
95+
/// <param name="position">The position, in plot coordinates, where the axis line will be drawn.</param>
96+
/// <param name="linePattern">The line pattern to apply to the axis line, such as solid or dashed.</param>
97+
/// <param name="type">The orientation of the axis line. Specify "Horizontal" to create a horizontal line or "Vertical" for a vertical
98+
/// line. Defaults to "Horizontal".</param>
99+
/// <param name="axis">The index of the axis to which the line is associated. Defaults to 0.</param>
100+
/// <param name="color">The color of the axis line. Specify a color name or value. Defaults to "Blue".</param>
101+
/// <param name="text">The label text to display with the axis line. Defaults to "---".</param>
86102
public AxisLinesUI(
87103
WpfPlot plot,
88104
double position,
@@ -110,53 +126,56 @@ public AxisLinesUI(
110126
}
111127

112128
/// <summary>
113-
/// Gets or sets the plot.
129+
/// Gets or sets the WPF plot control used to display graphical data within the application.
114130
/// </summary>
115-
/// <value>
116-
/// The plot.
117-
/// </value>
131+
/// <remarks>Assigning a new value to this property replaces the current plot control instance. This
132+
/// property is typically used to embed interactive plots in WPF user interfaces.</remarks>
118133
public WpfPlot Plot { get; set; }
119134

120135
/// <summary>
121-
/// Gets or sets the streamer.
136+
/// Gets or sets the visual properties of the axis line, such as color, thickness, and style.
122137
/// </summary>
123-
/// <value>
124-
/// The streamer.
125-
/// </value>
138+
/// <remarks>Set this property to customize the appearance of the axis line in the chart. If the value is
139+
/// <see langword="null"/>, the axis line will not be displayed.</remarks>
126140
public AxisLine? AxisLine { get; set; }
127141

128142
/// <summary>
129-
/// Creates the stream.
143+
/// Adds a vertical line to the plot at the specified position.
130144
/// </summary>
131-
/// <param name="position">The position.</param>
145+
/// <remarks>The line's appearance, including color and width, is determined by the current chart
146+
/// settings. The line will display the label text specified by the LabelText property.</remarks>
147+
/// <param name="position">The x-coordinate at which to place the vertical line. The default value is 0.0.</param>
132148
public void CreateVerticalLine(double position = 0.0)
133149
{
134150
var color = ScottPlot.Color.FromColor(System.Drawing.Color.FromName(ChartSettings.Color!));
135151
AxisLine = Plot.Plot.Add.VerticalLine(x: position, width: (float)ChartSettings.LineWidth, color: color);
136-
////AxisLine.Text = LabelText;
137152
AxisLine.LabelText = LabelText;
138-
////AxisLine.LabelBackgroundColor = color;
139153
}
140154

141155
/// <summary>
142-
/// Creates the stream.
156+
/// Adds a horizontal line to the plot at the specified vertical position.
143157
/// </summary>
144-
/// <param name="position">The position.</param>
158+
/// <remarks>The line's appearance, including color, width, label text, and alignment, is determined by
159+
/// the current chart settings. Use this method to highlight a specific value or threshold on the plot.</remarks>
160+
/// <param name="position">The vertical position, in plot coordinates, where the horizontal line will be drawn. Defaults to 0.0.</param>
145161
public void CreateHorizontalLine(double position = 0.0)
146162
{
147163
var color = ScottPlot.Color.FromColor(System.Drawing.Color.FromName(ChartSettings.Color!));
148164
AxisLine = Plot.Plot.Add.HorizontalLine(y: position, width: (float)ChartSettings.LineWidth, color: color);
149-
////AxisLine.Text = LabelText;
150165
AxisLine.LabelText = LabelText;
151166
AxisLine.LabelAlignment = Alignment.MiddleCenter;
152167
AxisLine.LinePattern = LinePattern1;
153-
////AxisLine.LabelBackgroundColor = color;
154168
}
155169

156170
/// <summary>
157-
/// Updates the stream.
171+
/// Subscribes to an observable sequence that provides axis line updates and applies changes to the chart
172+
/// accordingly.
158173
/// </summary>
159-
/// <param name="observable">The observable.</param>
174+
/// <remarks>Updates to the axis line position and chart name are processed on a background thread and
175+
/// applied to the UI thread. The chart is refreshed only if it is not paused. The subscription is disposed
176+
/// automatically with the object's disposables.</remarks>
177+
/// <param name="observable">An observable sequence emitting tuples containing the axis line name and its position. The name may be null or
178+
/// empty, and the position may be null; updates are only applied when both are valid.</param>
160179
public void UpdateAxisLineSubscription(IObservable<(string? Name, double? Position)> observable) =>
161180
observable
162181
.SubscribeOn(RxSchedulers.TaskpoolScheduler) // Procesa en un hilo de fondo

0 commit comments

Comments
 (0)