SyncfusionExamples / How-to-highlight-selected-data-points-by-using-GetDataPoints-method-in-.NET-MAUI-Cartesian-Charts

This article in the Syncfusion Knowledge Base explains how to highlight selected data points by using GetDataPoints method in .NET MAUI Cartesian Charts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to highlight selected data points by using GetDataPoints method in .NET MAUI Cartesian Charts

The .NET MAUI Cartesian Chart provides customization options for enhancing data visualization. One of its key features is the ability to interact with data through the GetDataPoints method of the Cartesian series. This method allows retrieval of data points that lie within a specified rectangular area or within defined X and Y coordinate ranges. This article aims to demonstrate how to highlight selected data points using the GetDataPoints method, detailing two effective methods:

Method 1: Custom Rectangular Area Selection

This way handling touch points to draw a custom rectangle and highlight data points that fall within it:

Step 1: Create the Extension Class

Create an extension class inherited from the ChartInteractiveBehavior class to handle the custom touch interactions on the chart. Define fields for storing the starting and ending coordinates of the touch and a flag to indicate when the rectangle should be shown. Implement the IDrawable interface to draw the selection rectangle. Override the OnTouchDown, OnTouchMove, and OnTouchUp methods to manage the drawing and selection process.

OnTouchDown Method : Capture the initial touch point when the user touches down on the chart.

OnTouchMove Method : Update the end coordinates of the selection rectangle dynamically.

OnTouchDown Method : Finalize the rectangle dimensions by utilizing the SeriesBounds, which provides the actual rendering bounds of chart series. Then, get the data points that fall inside the rectangle using the GetDataPoints method. Update the indexes of these data points to the SelectedIndexes property of ChartSelectionBehavior.

Here's the complete code for the custom interaction class:

[C#]

public class ChartInteractionExt : ChartInteractiveBehavior, IDrawable, INotifyPropertyChanged
{
    float startX;
    float startY;
    float endX;
    float endY;
    bool showRect = false;
    public GraphicsView Graphics { get; set; }

    public void Draw(ICanvas canvas, RectF dirtyRect)
    {
        if (showRect)
        {
            canvas.StrokeColor = Colors.Black;
            canvas.StrokeSize = 2;
            canvas.DrawRectangle(startX, startY, endX, endY);
        }
    }

    protected override void OnTouchDown(ChartBase chart, float pointX, float pointY)
    {
        var seriesBounds = chart.SeriesBounds;
        startX = pointX - seriesBounds.Left;
        startY = pointY - seriesBounds.Top;
        showRect = true;
        Graphics.Invalidate();
    }

    protected override void OnTouchMove(ChartBase chart, float pointX, float pointY)
    {
        if (showRect)
        {
            var seriesBounds = chart.SeriesBounds;
            endX = pointX - startX - seriesBounds.Left;
            endY = pointY - startY - seriesBounds.Top;
            Graphics.Invalidate();
        }
    }

    protected override void OnTouchUp(ChartBase chart, float pointX, float pointY)
    {
        if (showRect && chart is SfCartesianChart cartesianChart)
        {
            var viewModel = chart.BindingContext as ScatterSeriesViewModel;
            var rect = new Rect(startX, startY, endX, endY);

            var selectedIndexes = new List<int>();
            foreach (var series in cartesianChart.Series)
            {
                if (series is ScatterSeries scatterSeries)
                {
                    var dataPoints = scatterSeries.GetDataPoints(rect);
                    if (dataPoints != null && viewModel != null)
                    {
                        for (int i = 0; i < viewModel.Data.Count; i++)
                        {
                            if (dataPoints.Contains(viewModel.Data[i]))
                                selectedIndexes.Add(i);
                        }
                        scatterSeries.SelectionBehavior.SelectedIndexes = selectedIndexes;
                    }
                }
            }
            showRect = false;
            Graphics.Invalidate();
        }
    }
}

Step 2: Assign the Extension Class to the Chart

Assign the ChartInteractionExt class to the InteractiveBehavior property of the SfCartesianChart. Define the GraphicsView in the PlotAreaBackgroundView to handle custom drawing.

[XAML]

<chart:SfCartesianChart>
    <chart:SfCartesianChart.PlotAreaBackgroundView>
        <GraphicsView Drawable="{x:Reference InteractionExt}" x:Name="graphicsView" InputTransparent="True" ZIndex="1"/>
    </chart:SfCartesianChart.PlotAreaBackgroundView>
    
    <chart:SfCartesianChart.InteractiveBehavior>
        <local:ChartInteractionExt x:Name="InteractionExt" Graphics="{x:Reference graphicsView}"/>
    </chart:SfCartesianChart.InteractiveBehavior>
    . . .
    <chart:SfCartesianChart.Series>
        <chart:ScatterSeries ItemsSource="{Binding Data}" XBindingPath="XValue" YBindingPath="YValue" PointWidth="8" Opacity="0.8" Fill="#FE7A36" PointHeight="8" >
            <chart:ScatterSeries.SelectionBehavior>
                <chart:DataPointSelectionBehavior Type="Multiple"  SelectionBrush="#3652AD"/>
            </chart:ScatterSeries.SelectionBehavior>
        </chart:ScatterSeries>

    </chart:SfCartesianChart.Series>
</chart:SfCartesianChart>

Output GetDataPoints.gif

Method 2: Selection Zoom Events

This method involves handling selection zoom events to draw a custom rectangle and highlight data points that fall within it:

Zoom and Pan Events:

  • ZoomStart: Triggered when the user initiates a zoom action. Can be canceled to interrupt the action.
  • ZoomDelta: Activated during the zooming process and can be canceled.
  • ZoomEnd: Triggered when the zooming action finishes.
  • SelectionZoomStart: Occurs when the user begins box selection zooming.
  • SelectionZoomDelta: Activated during the process of selecting a region for zooming and can be canceled.
  • SelectionZoomEnd: Triggered after the selection zooming ends.
  • Scroll: Triggered during panning and can be canceled.
  • ResetZoom: Triggered after the chart is reset by double-tapping.

Step 1: Initialize Selection Zoom Events

Initialize the SelectionZoomDelta and SelectionZoomEnd events in the SfCartesianChart. Initialize the ZoomPanBehavior and enable selection zoom using the EnableSelectionZooming API available in ChartZoomPanBehavior.

<chart:SfCartesianChart x:Name="cartesianChart"           
                       SelectionZoomDelta="Chart_SelectionZoomDelta"
                       SelectionZoomEnd="Chart_SelectionZoomEnd">

   <chart:SfCartesianChart.ZoomPanBehavior>
       <chart:ChartZoomPanBehavior EnableSelectionZooming="True" />
   </chart:SfCartesianChart.ZoomPanBehavior>
   
   <chart:SfCartesianChart.XAxes>
       <chart:NumericalAxis x:Name="primaryAxis" />
   </chart:SfCartesianChart.XAxes>
   
   <chart:SfCartesianChart.YAxes>
       <chart:NumericalAxis x:Name="secondaryAxis" />
   </chart:SfCartesianChart.YAxes>
   
   <chart:SfCartesianChart.Series>
       <chart:ScatterSeries ItemsSource="{Binding Data}"
                            XBindingPath="XValue" 
                            YBindingPath="YValue">
           <chart:ScatterSeries.SelectionBehavior>
               <chart:DataPointSelectionBehavio  
                                Type="Multiple"  
                                SelectionBrush="#3652AD"/>
           </chart:ScatterSeries.SelectionBehavior>
       </chart:ScatterSeries>
   </chart:SfCartesianChart.Series>
   
</chart:SfCartesianChart> 

Step 2: Handle the interaction

The SelectionZoomDelta event is activated during the process of selecting a region in the chart area. Inside the event handler, retrieve the selecting area rectangle values. Then, use the GetDataPoints method to retrieve the data points that fall inside the rectangle. Update the indexes of these data points in the SelectedIndexes property of ChartSelectionBehavior.

private void Chart_SelectionZoomDelta(object sender, ChartSelectionZoomDeltaEventArgs e)
{
    var selectedIndexes = new List<int>();

    foreach (var series in cartesianChart.Series)
    {
        if (series is ScatterSeries scatterSeries)
        {
            var rect = new Rect(e.ZoomRect.X - cartesianChart.SeriesBounds.Left, e.ZoomRect.Y, e.ZoomRect.Width, e.ZoomRect.Height);
            var dataPoints = scatterSeries.GetDataPoints(rect);

            if (dataPoints != null && viewModel != null)
            {
                for (int i = 0; i < viewModel.Data.Count; i++)
                {
                    if (dataPoints.Contains(viewModel.Data[i]))
                        selectedIndexes.Add(i);
                }
                scatterSeries.SelectionBehavior.SelectedIndexes = selectedIndexes;
            }
        }
    }
}

Step 3: Cancel the zoom

The SelectionZoomEnd event is invoked when selecting a region from the chart area. Inside the event handler, set the ZoomFactor to 1 and the ZoomPosition to 0. This helps cancel the zoom.

private void Chart_SelectionZoomEnd(object sender, ChartSelectionZoomEventArgs e)
{
    primaryAxis.ZoomFactor = 1;
    primaryAxis.ZoomPosition = 0;
    secondaryAxis.ZoomFactor = 1;
    secondaryAxis.ZoomPosition = 0;
} 

Selection_zoom.gif

Troubleshooting

If you are facing a path too long exception when building this example project, close Visual Studio and rename the repository to short and build the project.

For a step by step procedure, refer to the BenchMark KB article.

About

This article in the Syncfusion Knowledge Base explains how to highlight selected data points by using GetDataPoints method in .NET MAUI Cartesian Charts


Languages

Language:C# 100.0%