How to increase markers perfomance?

Feb 3, 2011 at 10:41 AM

Hello. In my program i need to display graphs with a hude number of points (over 130,000 for one LineGraph). There is a button wich sets 

LineAndMarker<MarkerPointsGraph>.MarkerGraph.Visibility = Visibility.Visible;

When user click this button program hangs for few seconds and CPU usage extremly increase. Then every moving or zooming of graph hangs program for a few seconds. 

Is there any way to show markers only for visible points in Viewport?

Feb 4, 2011 at 4:47 AM

What i exactly need: there are several line graphs on plot with a huge number of points, But when user zoom in, the number of points in viewport not so huge. In fact, when users clicks "Show markers" button the number of visible point is less 1000. How can i draw markers only for this visible points?

PS. Sorry for my english...

Feb 4, 2011 at 9:31 PM
Edited Feb 4, 2011 at 9:32 PM

A line graph can use a frequency filter, this helps performance by omitting the graphing of points that would not be visible.

Now, I am thinking about your problem...there is no frequency filter for a marker graph, I believe, because a marker is probably larger than a single point, so it may be problematic to come up with a frequency filter in this situation - some work may be required to determine if a marker would be visible, so perhaps not any real savings. I am not sure. It seems to me that while graphing thousands of points in a line graph is probably a very common requirement, needing to graph 130,000 markers is probably not so common.

You could step into the source code for MarkerPointsGraph and try to understand exactly what it is doing, and why it is so slow for this many points, then think about deriving your own graph class that is more optimized for your situation (so, ,just copy the source for MarkerPointsGraph as MyMarkerPointsGraph, for example); then in your class you can perhaps have a way to avoid trying to render unnecessary markers, etc. This is just a suggestion; someone else may have a better idea.

PointsGraphBase
Feb 15, 2011 at 4:53 AM

Thank you for reply. I found simple solution. In my case, user need to see markers only when he or she zoom in graph. 

 

public class FilteredMarkerPointsGraph : MarkerPointsGraph
    {
        public FilteredMarkerPointsGraph()
            : base()
        {
            ;
        }

        public FilteredMarkerPointsGraph(IPointDataSource dataSource)
            : base(dataSource)
        {
            ;
        }

        protected override void OnRenderCore(DrawingContext dc, RenderState state)
        {
            // base.OnRenderCore
            if (DataSource == nullreturn;
            if (Marker == nullreturn;

            var left  = Viewport.Visible.Location.X;
            var right = Viewport.Visible.Location.X + Viewport.Visible.Size.Width;
            var top = Viewport.Visible.Location.Y;
            var bottom = Viewport.Visible.Location.Y + Viewport.Visible.Size.Height;

            var transform = Plotter2D.Viewport.Transform;

            DataRect bounds = DataRect.Empty;
            using (IPointEnumerator enumerator = DataSource.GetEnumerator(GetContext()))
            {
                Point point = new Point();
                while (enumerator.MoveNext())
                {
                    enumerator.GetCurrent(ref point);

                    
                    if (point.X >= left && point.X <= right && point.Y >= top && point.Y <= bottom) // <-- magic
                    {
                        enumerator.ApplyMappings(Marker);

                        Point screenPoint = point.DataToScreen(transform);

                        bounds = DataRect.Union(bounds, point);
                        Marker.Render(dc, screenPoint);
                    }
                }
            }

            Viewport2D.SetContentBounds(this, bounds);
        }
    }
Feb 19, 2011 at 8:09 PM

There you go, nice work.