Convert WpfPlot to CustomControl#2526
Conversation
- add propertie to show / hide legend - add propertie to define legend position - add propertie to select traces palette - add propertie to select plot style - remove dead code
|
Hi @KroMignon, thanks for this PR! I won't be able to review it thoroughly until tonight, but I'm happy to see you figured out the PR process and the tests are passing and I look forward to merging this soon! 🚀 I have one bit of feedback about a feature that was added:
I'm extremely hesitant to allow plot customizations from XAML. There are potentially thousands of little customizations that could be added (e.g., axis tick mark length), and if we allow some it will open the door for others to request more. Also, if we add XAML customizations to WPF then I would think we need to add the same to WinUI, Avalonia, Eto, Blazor, etc., and the maintenance burden grows as the number of supported controls grows. Although I think what you did here with properties and XAML is elegant and would be an ideal solution if ScottPlot were a WPF-only control, for the sake of maintainability I would feel better not customizing plots using styling, but instead interacting with the However, I custom XAML customizations are the type of thing that will be enabled by the new inherit-and-extend functionality that the core of this PR now allows 😉 Thanks again for your work on this, and I'm looking forward to hearing your thoughts! |
- move style and palette enumeration into base classe
|
Hello @swharden , creating PR was easier as expected 🤓 I understand your arguments about the plot customization. I was not really aware about all the other backends. It was something I'd like to have for my purpose, but I could implement it on application side with this modification 😄 It would be great if the enumeration + dictionary in |
This reverts commit fd4f56d.
…into CustomControl * 'CustomControl' of https://github.com/KroMignon/ScottPlot: fix formating issues
|
Good morning @swharden I can now open the ScottPlot 5 solution and I have started to look at the code. I have first to understand how the WPF control has been design before I implement my modification. SkiaSharp is new to me. Is it okay if I do some modification on |
revert changes not central to the primary goal of ScottPlot#2526 the WPF control is not functioning as expected -- it does not display plots in the cookbook or sandbox apps
This reverts commit 46e99ab.
revert changes not central to the primary goal of ScottPlot#2526
|
Hi @KroMignon, thanks again for your work on this! To try to keep this PR clean and isolated to a single purpose I reverted some of your changes related to styling enhancements. This makes it easier to do a line-by-line evaluation of https://github.com/ScottPlot/ScottPlot/pull/2526/files I don't have a lot of experience with WPF. Can you advise us about the purpose of Thanks for your input! I think we're getting pretty close to being ready to merge this in 🚀 EDIT: After this is merged we can revisit styling and palette improvements in a separate issue/PR |
That's fine for me 👍
A WPF Control requires at least a default style, which will be loaded by The difference with a
Your welcome 😉
|
|
Thanks for the clarification @KroMignon! I read some more information about custom controls and WPF templates and it makes a lot more sense now - thanks for pointing me in the right direction. I plan to release a new package today on NuGet, but I'm still hesitant to merge this in. I found one bug that I'll try to fix now, and depending on how easy it is to correct and/or how many other bugs I find, I may push this back until I have more time to review and test it thoroughly. Here's the bug I found this morning. I suspect it relates to events not being handled as expected... <Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
Title="ScottPlot Sandbox - WPF"
WindowStartupLocation="CenterScreen"
Height="450"
Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ScottPlot:WpfPlot Name="WpfPlot1" Grid.Row="0"/>
<ScottPlot:WpfPlot Name="WpfPlot2" Grid.Row="1"/>
</Grid>
</Window>using System.Windows;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
WpfPlot1.Plot.AddSignal(ScottPlot.DataGen.Sin(51, 2));
WpfPlot2.Plot.AddSignal(ScottPlot.DataGen.Cos(51, 2));
WpfPlot1.Refresh();
WpfPlot2.Refresh();
WpfPlot1.Configuration.AddLinkedControl(WpfPlot2); // update plot 2 when plot 1 changes
WpfPlot2.Configuration.AddLinkedControl(WpfPlot1); // update plot 1 when plot 2 changes
}
}
}
|
demonstrate issue described in ScottPlot#2526
|
Maybe this is a niche case, because this works... so I'm guessing it's some type of difference in window size evaluation inside the initializer? The size of the control is evaluated to determine how large to make the plot area. using System.Windows;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += (s, e) =>
{
WpfPlot1.Plot.AddSignal(ScottPlot.DataGen.Sin(51, 2));
WpfPlot2.Plot.AddSignal(ScottPlot.DataGen.Cos(51, 2));
WpfPlot1.Refresh();
WpfPlot2.Refresh();
WpfPlot1.Configuration.AddLinkedControl(WpfPlot2);
WpfPlot2.Configuration.AddLinkedControl(WpfPlot1);
};
}
}
}However, it's these type of unexpected changes in behavior that concern me considering how many existing users have code in the wild that depends on the functionality of WpfPlot to remain stable 😅 |
|
Looking at the original WpfPlot control, I'm probably going to have to put this down for a while because I don't want it to consume a disproportionate amount of time considering the other issues I'm trying to clear today 😅 Let me know if you have any thoughts or suggestions for how to track this down, otherwise I'll pick it up again in a day or two! Thanks again for your work on this |
I am not a WPF specialist, so maybe I am wrong. You cannot use the
As I am really new to PR, could you please tell me how I can import the changes you have done into my clone (I create a branch to test the changes)? |
No worries! There are tons of little corner cases and it's hard to catch everything. The things that I frequently miss are when I make a change that breaks support for display scaling, because that's really difficult to test 😅
I recommend using the GitHub Desktop app. It's really easy to use (command line git and git inside Visual Studio can both be pretty confusing) https://desktop.github.com/ Using the GitHub desktop you can open this repository, switch to the branch for this PR, and click "fetch" or "pull" to bring the latest code onto your computer. I recognize dealing with multi-author branches and pull requests is pretty confusing at first, but once you figure it out once it gets a lot easier! 🚀 |
I think I found what's going wrong after reading Microsoft documentation. |
I gave this a quick try, but the control crashes maybe because of some type of infinite loop 😅 |
- update WpfPlot to override properties to handle size change and mouse events - update Backend::Resize() to avoid unneeded updates - update Plot::Add(IPlottable) to force axes rescalling on first added signal (maybe a bad idea)
- revert Plot..Add() change - fix WpfPlot initialisation: always initialize backend with 1x1 pixel and resize it at least during OnApplyTemplate().
|
Hello @swharden, I made some changes to try to fix the issue with WPF Sandbox app. Now it looks good for me 🚀 😄 Hope it is okay for you:
|
|
Fantastic work @KroMignon! That was a complicated behavior to figure out. I'm excited to try this out and merge it in! 🚀 |
if the MouseWheel action is called, a direction must be supplied
|
This works great - merging it in now! I made one small change so the scroll wheel respects direction: 8d3c065 I learned a lot about WPF by studying the topics discussed above - thanks again for the initial suggestion and creating the PR! |
|
Very good news this morning 🎉, I am excited to use new ScottPlotV4 release ! |



Purpose:
Use
Controlas base class forWpfPlotinstead ofUserControlto enable customization. (cf #2509)It is now possible to select WpfPlot palette and style directly from XAML
This control replace the previous without any change on existing XAML or C# code.
NOTE I could not change the ScottPlot5 version, because I am not able to load the solution (cf #2525)