简体   繁体   中英

WPF Path's Geometry Transform performance gets worse with LineGeometries' length increase

I'm currently trying to create a little plot interactive editor, using WPF. On maximized window the plot dragging with mouse is not responsive enough because of the plot grid.

I got a path for my plot grid lying inside a Canvas control (render transform just shifts it to the bottom of the canvas)

<Path Name="VisualGrid" RenderTransform="{StaticResource PlotTechnicalAdjust}" Style="{DynamicResource ResourceKey=GridStyle}" Panel.ZIndex="1"/>

Here is how grid is created; _curState has actual camera "viewport" metadata

  if (_curState.Changes.ScaleStepXChanged)
     {
        foreach (TextBlock item in _xLabels)
        {
           DeleteLabel(item);
        }
        _xLabels.Clear();
        double i = _curState.LeftEdgeLine;
        _gridGeom.Children[(int)GridGeomIndexes.VerticalLines] = new GeometryGroup { Transform = _verticalLinesShift};
        var verticalLines =(GeometryGroup)_gridGeom.Children[(int)GridGeomIndexes.VerticalLines];
        while (i <= _curState.RightEdgeLine * (1.001))
        {
           verticalLines.Children.Add(new LineGeometry(new Point(i * _plotParameters.PixelsPerOneX, 0),
                                                       new Point(i * _plotParameters.PixelsPerOneX,
                                                                 -_wnd.ContainerGeneral.Height)));
           _xLabels.Add(CreateLabel(i, Axis.X));
           i += _curState.CurrentScaleStepX;
        }
        _curState.Changes.ScaleStepXChanged = false;
     }
     if (_curState.Changes.ScaleStepYChanged)
     {
        foreach (TextBlock item in _yLabels)
        {
           DeleteLabel(item);
        }
        _yLabels.Clear();
        double i = _curState.BottomEdgeLine;
        _gridGeom.Children[(int)GridGeomIndexes.HorizontalLines] = new GeometryGroup { Transform = _horizontalLinesShift};
        var horizontalLines = (GeometryGroup)_gridGeom.Children[(int)GridGeomIndexes.HorizontalLines];
        while (i <= _curState.TopEdgeLine * (1.001))
        {
           horizontalLines.Children.Add(new LineGeometry(new Point(0, -i * _plotParameters.PixelsPerOneY),
                                                           new Point(_wnd.ContainerGeneral.Width,
                                                                    -i * _plotParameters.PixelsPerOneY)));
           _yLabels.Add(CreateLabel(i, Axis.Y));
           i += _curState.CurrentScaleStepY;
        }
        _curState.Changes.ScaleStepYChanged = false;
     }

Where Transforms are composition of TranslateTransform and ScaleTransform (for vertical lines I only use X components and only Y for horizontal lines). After beeing created those GeometryGroups are only edited if a new line apears into camera or an existing line exits viewable space. Grid is only recreated when axis graduations have to be changed after zooming.

I have a dragging option implemented like this:

private Point _cursorOldPos = new Point();
private void OnDragPlotMouseMove(object sender, MouseEventArgs e)
{
   if (e.Handled)
      return;
   Point cursorNewPos = e.GetPosition(ContainerGeneral);
   _plotView.TranslateShiftX.X += cursorNewPos.X - _cursorOldPos.X;
   _plotView.TranslateShiftY.Y += cursorNewPos.Y - _cursorOldPos.Y;
   _cursorOldPos = cursorNewPos;
   e.Handled = true;
}

This works perfectly smooth with a small window (1200x400 units) for a large amount of points (like 100+). But for a large window (fullscreen 1920x1080) it happens pretty jittery even without any data-point controls on canvas. The strange moment is that lags don't appear when I order my GridGenerator to keep around 100+ lines for small window and drag performance suffers when I got less than 50 lines on maximezed. It makes me think that it might somehow depend not on a number of elements inside a geometry, but on their linear size. I suppose I should mention that OnSizeChanged I adjust the ContainerGeneral canvas' height and width and simply re-create the grid.

Checked the number of lines stored in runtime to make sure I don't have any extras. Tried using Image with DrawingVisual instead of Path. Nothing helped.

Appearances for clearer understanding

It was all about stroke dashes and WPF's unhealthy desire to count them all while getting hit test bounds for DrawingContext.

The related topic is Why does use of pens with dash patterns cause huge (!) performance degredation in WPF custom 2D drawing?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM