How to show graphics efficiently in WPF?

We have a temporary feature of our software. It shows rows of small drops that indicate data at different points in time. The code is C #,. Net 4 and WPF. To show the blob, we are currently creating a border (giving it a brush) and adding it to the grid. This grid is then added to the parent grid, which forms the rows.

This is good when a relatively small number of blocks are displayed on the timeline, but when the data is very busy, rendering slows down, the use of mem increases, and the user interface becomes unresponsive. (Not surprising).

I know that we are not doing it in the best way - my question is the best way to display graphics like this in wpf?

EDIT: Thanks for the answers below - I will investigate these parameters. However, each of them requires a lot of conversion, and my question here is simpler; Is there some kind of control or effect that I can use to replace the border, which is the lower cost of resources?

+7
source share
2 answers

For data visualization, I like DynamicDataDisplay . The component is currently only supported / developed for Silverlight, but WPF has an open source version (in the link), which is really a great library.

The library uses IObservable collections and supports DateTime axis values.

There is a built-in type of marker graph (example below).

You can use custom markers, it supports scaling and scrolling, many other nice features, etc. It is also very fast, even with fairly large datasets.

Since the datasets are IObservable , the chart component dynamically responds to changes in the underlying dataset, so your chart is updated whenever the data collection is updated.

EDIT

Here is an example:

uses:

 using System.ComponentModel; using Microsoft.Research.DynamicDataDisplay; using Microsoft.Research.DynamicDataDisplay.Charts; using Microsoft.Research.DynamicDataDisplay.DataSources; using Microsoft.Research.DynamicDataDisplay.PointMarkers; 

main:

  public Window1() { InitializeComponent(); // const int N = 100; List<double> x = new List<double>(); List<double> y = new List<double>(); DateTimeAxis dtAxis = new DateTimeAxis(); _plotter.HorizontalAxis = dtAxis; Random rand = new Random(); for (int i = 0; i < N; i++) { //generate some random data x.Add(dtAxis.ConvertToDouble(DateTime.Now.AddDays(i))); y.Add(rand.Next(N)); } EnumerableDataSource<double> gX = new EnumerableDataSource<double>(x); EnumerableDataSource<double> gY = new EnumerableDataSource<double>(y); _MarkerGraph.DataSource = new CompositeDataSource(gX,gY); //no scaling - identity mapping gX.XMapping = xx => xx; gY.YMapping = yy => yy; CirclePointMarker mkr = new CirclePointMarker(); mkr.Fill = new SolidColorBrush(Colors.Red); mkr.Pen = new Pen(new SolidColorBrush(Colors.Black),2.0); _MarkerGraph.Marker = mkr; } 

XAML:

 <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay" Title="Window1" Height="481" Width="651"> <Grid> <d3:ChartPlotter Name="_plotter"> <d3:MarkerPointsGraph Name="_MarkerGraph"/> </d3:ChartPlotter> </Grid> 

Exit: Program runs ...

the DateTime axis scales perfectly, adjusting ticks for days, months, hours, seconds ... whatever fits. Easy as a pie!

If you use this package, I highly recommend downloading the source code and adding it as a second project to your solution. The documentation is very bad for D3, and having a source in your project helps you figure out how everything works. It also simplifies adding / expanding if you need to. Be sure to check out the in-solutions project if you do, rather than a compiled DLL.

Please note that many of the available documents and online examples are for the supported Silverlight component, and not for the open WPF component. Many of the components differ between the two versions, so you need to dig through the WPF component to see what's there. The above example applies to the WPF v0.3 component.

+4
source

If you want to draw a lot of ever-changing visual effects, the fastest way WPF can offer is to override OnRender and draw in DrawingContext .

If the visual effects are mostly static, but can sometimes change, the quickest way is to create a DrawingVisual for each of them, which can then be changed as needed.

More on this question , related article and answers.

+3
source

All Articles