1

I am trying to highlight the ellipse point marker when the mouse is middle clicked on the marker. I want to redraw the marker when the graph is zoomed or panned with the point marker selection chart modifier(PointMarkerSelectionModifier). How do I translate the points when the graph is zoomed or panned or is there a better way to do this.

<sciChart:SciChartSurface x:Name="sciChartDetail">    <sciChart:SciChartSurface x:Name="sciChartDetail">
    <sciChart:SciChartSurface.Annotations>
        <sciChart:HorizontalLineAnnotation HorizontalAlignment="Stretch" LabelPlacement="Axis" LabelTextFormatting="0.00" Stroke="Blue" StrokeThickness="2" Y1="{Binding DataContext.DetailData.Mean, RelativeSource={RelativeSource AncestorType=UserControl}}" IsHidden="{Binding DataContext.DetailData.DisplayOptions.IsMeanHidden, RelativeSource={RelativeSource AncestorType=UserControl}}" ShowLabel="True" />
        <sciChart:HorizontalLineAnnotation HorizontalAlignment="Stretch" LabelPlacement="Axis" LabelTextFormatting="0.00" Stroke="Brown" StrokeThickness="2" Y1="{Binding DataContext.DetailData.SigmaPlusThree, RelativeSource={RelativeSource AncestorType=UserControl}}" IsHidden="{Binding DataContext.DetailData.DisplayOptions.IsSigmaLineHidden, RelativeSource={RelativeSource AncestorType=UserControl}}" ShowLabel="True" />
        <sciChart:HorizontalLineAnnotation HorizontalAlignment="Stretch" LabelPlacement="Axis" LabelTextFormatting="0.00" Stroke="Brown" StrokeThickness="2" Y1="{Binding DataContext.DetailData.SigmaMinusThree, RelativeSource={RelativeSource AncestorType=UserControl}}" IsHidden="{Binding DataContext.DetailData.DisplayOptions.IsSigmaLineHidden, RelativeSource={RelativeSource AncestorType=UserControl}}" ShowLabel="True" />
        <sciChart:BoxAnnotation HorizontalAlignment="Stretch" Background="#3349E20E" BorderBrush="#7749E20E" BorderThickness="1" CornerRadius="3" IsEditable="False" X1="{Binding DataContext.DetailData.DateStart, RelativeSource={RelativeSource AncestorType=UserControl}}" X2="{Binding DataContext.DetailData.DateStop, RelativeSource={RelativeSource AncestorType=UserControl}}" Y1="{Binding DataContext.DetailData.LSL, RelativeSource={RelativeSource AncestorType=UserControl}}" Y2="{Binding DataContext.DetailData.USL, RelativeSource={RelativeSource AncestorType=UserControl}}" IsHidden="{Binding DataContext.DetailData.DisplayOptions.IsSpecLimitsHiddden, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </sciChart:SciChartSurface.Annotations>

    <sciChart:SciChartSurface.RenderableSeries>
        <sciChart:XyScatterRenderableSeries  DataSeries="{Binding DataContext.DetailData.DataSeries, RelativeSource={RelativeSource AncestorType=UserControl}}" IsVisible="{Binding DataContext.DetailData.DisplayOptions.LineScatter, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource enumBooleanConverter}, ConverterParameter= {x:Static local:LineScatterRender.Scatter}}">
            <sciChart:XyScatterRenderableSeries.PointMarker>
                <sciChart:EllipsePointMarker Width="5" Height="5" Stroke="Blue" Fill="Green" StrokeThickness="3">
                </sciChart:EllipsePointMarker>
            </sciChart:XyScatterRenderableSeries.PointMarker>
        </sciChart:XyScatterRenderableSeries>
    </sciChart:SciChartSurface.RenderableSeries>

    <sciChart:SciChartSurface.XAxes>
        <sciChart:DateTimeAxis AutoRange="Once"  GrowBy="0.01, 0.01" AxisTitle="{Binding DataContext.DetailData.DateRangeAxisLabel, RelativeSource={RelativeSource AncestorType=UserControl}}" VisibleRangeChanged="OnDateTimeAxisVisibleRangeChanged">
        </sciChart:DateTimeAxis>
    </sciChart:SciChartSurface.XAxes>

    <sciChart:SciChartSurface.YAxes>
        <sciChart:NumericAxis VisibleRange="{Binding DataContext.DetailData.SharedYVisibleRange, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}" GrowBy="0.05, 0.05" Visibility="Hidden" AutoRange="Once" AxisAlignment="Left" AxisTitle="WF:Y" Style="{ets:ETStyleRef ResourceKey=AxisStyle}"/>
    </sciChart:SciChartSurface.YAxes>

    <sciChart:SciChartSurface.ChartModifier>
        <sciChart:ModifierGroup>
            <sciChart:RubberBandXyZoomModifier IsEnabled="True" IsXAxisOnly="False" ZoomExtentsY="False" IsAnimated="True" ExecuteOn="MouseRightButton"/>
            <sciChart:MouseWheelZoomModifier ActionType="Zoom" Tag="SecondYAxis" ReceiveHandledEvents="True"/>
            <sciChart:ZoomExtentsModifier XyDirection="XYDirection"/>
            <sciChart:ZoomPanModifier Tag="SecondYAxis" IsEnabled="True" ExecuteOn="MouseLeftButton" XyDirection="XYDirection" ReceiveHandledEvents="True" ZoomExtentsY="True"/>
            <util:PointMarkerSelectionModifier/>
        </sciChart:ModifierGroup>
    </sciChart:SciChartSurface.ChartModifier>
</sciChart:SciChartSurface>

public class PointMarkerSelectionModifier : ChartModifierBase
{
    private Point? selectedPoint;
    private Point _lastMousePoint;
    public static readonly DependencyProperty LineBrushProperty = DependencyProperty.Register("LineBrush", typeof(Brush), typeof(PointMarkerSelectionModifier), new PropertyMetadata(new SolidColorBrush(Colors.LimeGreen), OnLineBrushChanged));
    public static readonly DependencyProperty TextForegroundProperty = DependencyProperty.Register("TextForeground", typeof(Brush), typeof(PointMarkerSelectionModifier), new PropertyMetadata(new SolidColorBrush(Colors.White)));

    public Brush TextForeground
    {
        get { return (Brush)GetValue(TextForegroundProperty); }
        set { SetValue(TextForegroundProperty, value); }
    }

    public Brush LineBrush
    {
        get { return (Brush)GetValue(LineBrushProperty); }
        set { SetValue(LineBrushProperty, value); }
    }

    public override void OnParentSurfaceRendered(SciChartRenderedMessage e)
    {
        base.OnParentSurfaceRendered(e);
    }

    public override void OnModifierMouseDown(ModifierMouseArgs e)
    {
        base.OnModifierMouseDown(e);
        var allSeries = this.ParentSurface.RenderableSeries;

        // Translates the mouse point to chart area, e.g. when you have left axis
        selectedPoint = GetPointRelativeTo(e.MousePoint, this.ModifierSurface);

        ClearModifierSurface();

        // Add the rollover points to the surface
        var hitTestResults = allSeries.Select(x => x.HitTest(selectedPoint.Value)).ToArray();

        foreach (var hitTestResult in hitTestResults)
        {
            const int markerSize = 10;

            // Create one ellipse per HitTestResult and position on the canvas
            var ellipse = new Ellipse()
            {
                Width = markerSize,
                Height = markerSize,
                Stroke = Brushes.Red,
                StrokeThickness = 2,
                IsHitTestVisible = false,
                Tag = typeof(PointMarkerSelectionModifier)
            };

            Canvas.SetLeft(ellipse, hitTestResult.HitTestPoint.X - markerSize * 0.5);
            Canvas.SetTop(ellipse, hitTestResult.HitTestPoint.Y - markerSize * 0.5);
            this.ModifierSurface.Children.Add(ellipse);
        }
    }

    public override void OnModifierMouseMove(ModifierMouseArgs e)
    {
        // TODO : how to translate the selected point when the graph is zoomed or panned
    }

    private void ClearModifierSurface()
    {
        for (int i = ParentSurface.ModifierSurface.Children.Count - 1; i >= 0; --i)
        {

            if (((FrameworkElement)ParentSurface.ModifierSurface.Children[i]).Tag == typeof(PointMarkerSelectionModifier))
            {

                ParentSurface.ModifierSurface.Children.RemoveAt(i);

            }
        }
    }
}
Chubosaurus Software
  • 8,133
  • 2
  • 20
  • 26
TrustyCoder
  • 4,749
  • 10
  • 66
  • 119
  • 3
    Take a moment to read through the [editing help](http://stackoverflow.com/editing-help) in the help center. Formatting on Stack Overflow is different than other sites. The better your post looks, the easier it will be for users to help you (like you don't need an empty line between each code line). – gunr2171 Sep 30 '14 at 16:38

1 Answers1

1

Disclosure: I am the lead developer on the SciChart WPF Chart team

Hi there!

What you need to do is in the override of OnParentSurfaceRendered, reposition your markers.

What we do for all the core modifiers in SciChart is we set up some condition in the MouseDown, MouseMove events (such as log the recent mouse movements) and then in OnParentSurfaceRendered, reposition markers or overlays.

This allows us to update UI such as tooltips and markers if the underlying graph changes (e.g. data changes, or graph is resized, or zoomed or panned) then we would re-run the HitTest or re-translate the placed point to new location.

Some useful APIs / articles

Hope this helps!

Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178