I have some data that comes via messages to my chart. It's a electric current over time (seconds) chart. How can I change the behaviour of the FitToView mode (or write a different one) so that the plotter doesn't zoom out and scale to fit the whole line graph, but move left instead, showing for example only the 100 last seconds?
I thought of calculating minimums and maximums every message and changing the plotters restraints explicitly but it doesn't seem very optimal. Also due to the fact that I would have to set the restraints in code-behind but all the data is in the ViewModel (using MVVM with caliburn).
Edit: I've found the functionality for this (adding WidthFollowConstraint to the FitToView constraints) but the linegraph gets moved more than the axis and after that it compensates back to where it should be, making the whole graph glitch out on every iteration. How can this be fixed?
Apperently I forgot to answer this.
I made the graph move instead of scale by adding a MinimalSizeConstraint and a FollowWidthConstraint to the ConstraintCollection in the constructor of the D3 Viewport2D class. The names are pretty selfexplanitory. Basically this changes the FitToView funtion of the graph to the desired behaviour
I am trying to create a WPF application using C# to run on Pixelsense that is basic version of the tangram puzzle. I am able to draw my 7 shapes and translate and rotate them all around the screen.
Could anyone give me advise regarding how I should go about saving the pattern (with shapes in specific positions and orientations) so that when a user creates the pattern next time, the application can match it to the saved one and tell the user if it's correct.
It's a pattern matching and recognition problem that I am trying to solve.
I have been stuck on this for a while now :(
Define the solution as a collection of objects with shapeType, position, and orientation properties. Have the solution include one shape at position 0, 0 and an orientation of 0. Now loop over all the shapes the user has actually placed to find the ones with a shapeType that matches the shape your solution has at 0,0,0. Calculate the position and orientation of every other shape relative to where the user put this one. Compare those values to the rest of your solution. You'll need to experiment with how much tolerance to allow because this stuff is not precise - to make the game fun, err on the side of having high tolerances. If needed, you can follow this up with some performance optimizations to only re-evaluate pieces that moved.
Hopefully you are using physical shape prices with tags on them instead of this purely a virtual game. I always wanted to build this when I was on the Surface team but it never happened. One challenge you will run into is defining how the tag's position/orientation relates to the actual shape. If you'll be putting tag stickers on multiple tangram sets, you almost certainly won't get the on precisely the same each time so you may need to add a "calibration" mode to your app (have the user place each piece in a specific spot and then push a button so you can record where the tag is relative to those spots). The TagVisualizer WPF control should help a lot for building your UI - definitely look into using it (this scenario was top of mind when we designed that API). The default behavior of that control (if you tell it the ID of a tag to look for but not how to visualize it) is a "crosshair" that can help you find tune your offset values.
Good luck! If you wouldn't mind recording a YouTube video when you are done and posting a comment here linking to it, I'd really appreciate that
You can use ObservableCollection or List of a custom class. That class can consist of various values such as position, orientation etc as properties.
When a new pattern is drawn or when the pattern change its position you can update that particular object stored in the collection. As you have all the details of the pattern(positions and orientation) you can iterate the for loop and check the position of the new pattern when added.
I see CacheMode in Pivot control (and other controls) like this:
<phone:PivotItem CacheMode="{x:Null}" Margin="0,-5,0,0">
I knew that Windows Phone just has BitmapCache value for it. anyway, what is RenderAtScale property of it for?
I have an app which will has lots of values in memory and I fear that a memory leak will occur. Should I use this cache? and what is the best value for RenderAtScale for my scenario?
A question with a link to the answer in it? Sorry but have to poke fun at that. RenderAtScale would be for example if you have a UIElement that you're applying a ScaleTransform or Zooming in/out to make it larger than it is naturally, than you would also want to apply your RenderAtScale property. See this example for more info.
As for the best value for your scenario, well you're not messing with any Scale so I don't think you'll use it.
Careful with how you use CacheMode since it can kill performance if not used correctly. If I remember right, a lot of the WP stuff implements it automatically for elements animating things where caching helps for like Translates/Opacity/Rotates, etc etc. Also keep in mind, all the children will inherit that declaration if you set it, so you could end up with a lot of stuff cached you may not even need to.
Hope this helps.
I have a WinForms application that allows you to edit documents. Each document is made of chapters and each chapter holds a collection of RTF blocks. The RTF blocks are loaded in a PanelControl using Dock = DockStyle.Top.
The problem is that when the total height of a chapter gets too large (estimating > 32768 pixels) the lower blocks are not properly docked: they appear behind one another. When trying to isolate the problem I noticed that this also happens with simpler controls like a LabelControl.
Things I tried are methods like Refresh(), Invalidate() and PerformLayout: they will not resolve the issue.
What does help is resizing the form. After that all controls are laid out correctly.
Can anyone help on how to solve this without resizing the form?
Attached a simple demo-project that illustrates the problem.
From my comment above (seems really to be the problem here):
WinForms (and the GDI in general) is often behaving unpredictably if one tries to use coordinates outside a 16 bit range. Try to avoid that. In the range of possible problems are things just not getting drawn at all, OverflowExceptions at unexpected code positions etc.
If it's possible to you take decision to change this layout, I suggest you to take another approach on showing/editing the documents chapters with some kind of pagination or collapsing RTF blocks into a menu and showing only current.
You see.. it makes a sense the height value be a integer 16-bit value.
A screen is way more tiny than this.
As panel height increases to such a high size. You see that using scroll bar will become very very sensible.. and it's not a good thing.
Content with size 2x, 3x, 5x being scrolled is usable to user. But scrolling a content with height (~32768) of at least (using good resolution monitor w/ window maximized) in optimal case 32x the size of window is very uncomfortable.
Plus, I believe that the productivity of user will decrease due to brain difficulty in locate "things" in a increasing collection of "things".
I have written a chart that displays financial data. Performance was good while I was drawing less than 10.000 points displayed as a connected line using PathGeometry together with PathFigure and LineSegments. But now I need to display up to 100.000 points at the same time (without scrolling) and it's already very slow with 50.000 points. I was thinking of StreamGeometry, but I am not sure since it's basically the same as a PathGeometry stroring the information as byte stream. Does any one have an idea to make this much more performant or maybe someone has even done something similar already?
EDIT: These data points do not change once drawn so if there is potential optimizing it, please let me know (line segments are frozen right now).
EDIT: I tried StreamGeometry. Creating the graphic took even longer for some reason, but this is not the issue. Drawing on the chart after drawing all the points is still as slow as the previous method. I think it's just too many data points for WPF to deal with.
EDIT: I've experimented a bit and I noticed that performance improved a bit by converting the coordinates which were previously in double to int to prevent WPF anti-aliasing sub-pixel lines.
EDIT: Thanks for all the responses suggesting to reduce the number of line segments. I have reduced them to at most twice the horizontal resolution for stepped lines and at most the horizontal resolution for simple lines and the performance is pretty good now.
I'd consider downsampling the number of points you are trying to render. You may have 50,000 points of data but you're unlikely to be able to fit them all on the screen; even if you charted every single point in one display you'd need 100,000 pixels of horizontal resolution to draw them all! Even in D3D that's a lot to draw.
Since you are more likely to have something like 2,048 pixels, you may as well reduce the points you are graphing and draw an approximate curve that fits onto the screen and has only a couple thousand verts. If for example the user graphs a time frame including 10000 points, then downsample those 10000 points to 1000 before graphing. There are numerous techniques you could try, from simple averaging to median-neighbor to Gaussian convolution to (my suggestion) bicubic interpolation. Drawing any number of points greater than 1/2 the screen resolution will simply be a waste.
As the user zooms in on a part of a graph, you can resample to get higher resolutions and more accurate curve fitting.
When you start dealing with hundreds of thousands of distinct vertices and vectors in your geometry, you should probably consider migrating your graphics code to use a graphics framework instead of depending on WPF (which, while built on top of Direct3D and therefore capable of remarkably efficient vector graphics rendering, has a lot of extra overhead going on that hampers its efficiency). It's possible to host both Direct3D and OpenGL graphics rendering windows within WPF -- I'd suggest moving that direction instead of continuing to work solely within WPF.
(EDIT: changed "DirectX" in original answer to "Direct3D")
Just ran into this question, but as I mentioned in this thread, the most performant approach might be to program against WPF's Visual layer.
Everything Visual in WPF eventually goes against this layer ... and so it is the most lightweight approach of them all.
See this and this for more info. Chapter 14 of Matthew MacDonald's Pro WPF in C# 2008 book also has a good section on it.
As another reference ... see Chapter 2 of Pavan Podila's book WPF Control Development Unleashed. On page 13, he discusses how DrawingVisuals would be an excellent choice for a charting component.
Finally, I just noticed that Charles Petzold wrote an MSDN Magazine article where the best overall (performant anyway) solution (to a scatter plot) was a DrawingVisual approach.
Another idea would be to use the Image control with the Source property set to a DrawingImage that you've dynamically created.
According to Pavan Podila in WPF Control Development Unleashed, this approach can be very helpful when you have thousands and thousands of visuals that don't need any interactivity. Check out page 25 of his book for more info.
This is an old thread, but I thought it was worth mentioning that you could attain interactivity with the above method by using the MouseUp() event. You know the size of the image's viewport, the resolution of the image, and the mouse's position. For example, you could maintain the collection actualScreenPoints through a timer attached to your UserControl_SizeChanged event:
double xworth = viewport.ActualWidth / (XEnd - XStart);
double xworth = viewport.ActualHeight / (YEnd - YStart);
List<Point> actualScreenPoints = new List<Point>();
for (var i = 0; i < points.Count; i++)
{
double posX = points[i].X * xworth;
double posY = points[i].Y * yworth;
actualScreenPoints.Add(posX, posY);
}
And then when your MouseUp() event fires, check if any of the points in the collection are within +-2px. There's your MouseUp on a given point.
I don't know how well it scales, but I've had some success using ZedGraph in WPF (WinForms control inside a WindowsFormsPresenter). I'm surprised no one mentioned it yet. It's worth taking a look at, even if you're not planning on using it for your current project.
ZedGraph
Good luck!
I believe the only method that might be faster while remaining in the WPF framework would be to override OnRender in a custom control. You can then render your geometry directly to the persisted scene, culling anything out of view. If the user can only see a small part of the data set at a time, culling could be enough on its own.
With this many data points, it's unlikely that the user can see full detail when the entire dataset is in view. So it might also be worthwhile to consider simplifying the dataset for full view and then showing a more detailed view if and when they zoom in.
Edit: Also, give StreamGeometry a shot. Its whole reason for existing is performance, and you never know until you try.
This is a very good question, and at it's heart begs the question "Can any user make practical use of, or business descisions from, a screen containing 100,000 discrete points?".
Following best practice in GUI design philosphy, the answer should be No, which would lead me to question whether there isn't a different way to meet the requirement for the application.
If there really is a bona-fide case for displaying 100,000 points on screen, with no scrolling, then using an off-screen buffer is the way to go. Composite your image to a bitmap, than whack that bitmap onto your Window / Page as needed. This way the heavy lifting is only done once, after which the hardware acceleration can be used every time the window needs to be drawn.
Hope this helps.
I haven't worked with WPF (disclaimer), but I suspect that your performance problem is because your code is trying to fit a smooth curved line through all of your data, and the time required increases geometrically (or worse) with the number of data points.
I don't know if this would be acceptable appearance-wise, but try graphing your data by connecting each point to the last with a straight line. This should make the time-to-graph proportional to the number of data points, and with as many points as you have the graph may end up looking exactly the same anyway.
Another idea would be to use the Image control with the Source property set to a DrawingImage that you've dynamically created.
According to Pavan Podila in WPF Control Development Unleashed, this approach can be very helpful when you have thousands and thousands of visuals that don't need any interactivity. Check out page 25 of his book for more info.