We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. (Last updated on: November 16, 2018).
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

Pie Chart with GroupMode enabled, OnSelection returns incorrect SelectedDataPointIndex

Thread ID:

Created:

Updated:

Platform:

Replies:

142618 Feb 12,2019 02:14 PM UTC Feb 14,2019 06:55 AM UTC Xamarin.Forms 4
loading
Tags: SfChart
Nick
Asked On February 12, 2019 02:14 PM UTC

If a pie chart has GroupMode enabled, the returned index does not correspond to the correct data point in selectedSeries.GetChartDataPoints().

It looks like the id returned is that of the selected segment, not the data point index it represents. 

For example, if data point 20 is the largest in a collection, it may become segment ID 5 when grouping is applied. Taking segment ID 5 would return the wrong data point, there needs to be a lookup between segment ID and DataPointIndex.

Bharathiraja K [Syncfusion]
Replied On February 13, 2019 12:35 PM UTC

Hi Nick, 
 
Greetings from Syncfusion. 
 
We would like to tell you that, the selectedSeries.GetChartDataPoints() methods returns only the actual data point collection even if you enabled the GroupMode property in the series. You can get the list of XValues and YValues in the grouped segment using the data marker converter used in the data marker template. Please refer the below code snippet for more details.  
 
Code Snippet [C#]: 
 
public class DataMarkerConverter : IValueConverter
    {
        public object Convert(object valueType targetTypeobject parameterCultureInfo culture)
        {
            var groupedData = new List<object>();
            var groupedXData = new List<object>();

             if (value == null)
                return value;

            if (value is List<Object>)
            {
                var groupedSegment = value as List<object>;

                for (int i = 0i < groupedSegment.Counti++)
                {
                    groupedData.Add((groupedSegment[ias Model).YValue);
                    groupedXData.Add((groupedSegment[ias Model).XValue);
                }

                return string.Format("{0} : {1} \n {2} : {3} \n {4} : {5}"groupedXData[0], groupedData[0], groupedXData[1], groupedData[1], groupedXData[2], groupedData[2]);
            }
            else
            {
                return string.Format("{0} : {1}", (value as Model).XValue, (value as Model).YValue);
            }
        }

        public object ConvertBack(object valueType targetTypeobject parameterCultureInfo culture)
        {
            return value;
        }
    }
 
 
Screenshot: 
 
 
 
 
We have prepared a sample for this. Please download it form the following location. 
 
 
Please let us know, if you need further assistance on this. 
 
Regards, 
Bharathiraja. 


Jonathan Cranford
Replied On February 13, 2019 01:28 PM UTC

Thanks for the reply. Unfortunately the sample project does not work, I get the error 'The project Chart_GettingStarted.Android is missing Android SDKs required for building. Double-click on this message and follow the prompts to install them'. Double-clicking the message does nothing.

Anyway, how does the DataMarkerConverter, which I see can be used to display those values contained within a group as the chart is drawn ,relate to an OnSelection listener that is called when the user taps on a segment? I'm not interested in grouped data, but I do want to get the X and Y value for the ungrouped segment that was tapped. As described, I get an incorrect ID when the listener is called. 


Jonathan Cranford
Replied On February 13, 2019 01:39 PM UTC

In the below example, when grouping is enabled, the .SelectedDataPointIndex does not relate to the dataPoint that was touched. 

E.g.

Collection

DataPoint 1   X:Tony Y:2
DataPoint 2   X:Steve Y:4
DataPoint 3   X:Nick Y:50

Ungrouped

Segment 1 (DataPoint 1) is touched, 1 is returned. GetChartDataPoints()[1] = X:Tony Y:2
Segment 2 (DataPoint 2) is touched, 2 is returned. GetChartDataPoints()[2] = X:Steve Y:4
Segment 3 (DataPoint 3) is touched, 3 is returned. GetChartDataPoints()[3] = X:Nick Y:50

Grouped

Segment 1 (DataPoints 1 & 2) is touched, 1 is returned. GetChartDataPoints()[1] = X:Tony Y:2
Segment 2 (DataPoint 3 only) is touched, 2 is returned.  GetChartDataPoints()[2] = X:Steve Y:4. 

Therefore, how do I access data point 3 when it has been touched on a grouped chart, in order to retrieve X=Nick Y=50?


public static void OnChartSelectionChanged(object sender, ChartSelectionEventArgs args)
        {
            var selectedSeries = args.SelectedSeries;
            var dataPointIndex = args.SelectedDataPointIndex;
            var previousSelectedIndex = args.PreviousSelectedIndex;
            var previousSelectedSeries = args.PreviousSelectedSeries;

            if (dataPointIndex >= 0 && dataPointIndex <= selectedSeries.GetChartDataPoints().Count)
            {

                ChartDataPoint dataPoint = selectedSeries.GetChartDataPoints()[dataPointIndex];

          }
}

Bharathiraja K [Syncfusion]
Replied On February 14, 2019 06:55 AM UTC

Hi Nick, 
 
We have analyzed your query and prepared a sample for your requirement.  You can show the selected data point while enabling the grouping mode using the GroupedData internal property by extending the ChartSelectionBehvaior in the specific project. Please refer the CustomSelectionBehavior class for more details. 
 
Code Snippet: (Android) 
protected override void OnSelectionChanged(Native.ChartSelectionEvent chartSelectionEvent)
        {
            base.OnSelectionChanged(chartSelectionEvent);

            ViewModel chartBindingContext = FormsChart.BindingContext as ViewModel;

            chartBindingContext.GroupedYValues = new ObservableCollection<Model>();

            var segments = chartSelectionEvent.SelectedSeries.Segments;

            if (chartSelectionEvent.SelectedDataPointIndex == -1)
            {
                chartBindingContext.GroupedYValues.Clear();
                return;
            }

            Native.PieSegment selectedSegment = segments[chartSelectionEvent.SelectedDataPointIndexas Native.PieSegment;

            if (chartSelectionEvent.SelectedDataPointIndex == segments.Count - 1)
            {
                PropertyInfo dataPointInfo = typeof(Native.CircularSeries).GetProperty("GroupedData"BindingFlags.NonPublic | BindingFlags.Instance);
                List<objectgroupedDataPoints = dataPointInfo.GetValue(chartSelectionEvent.SelectedSeriesnullas List<object>;

                for (int i = 0i < groupedDataPoints.Counti++)
                {
                    chartBindingContext.GroupedYValues.Add(new Model((groupedDataPoints[ias Model).XValue, (groupedDataPoints[ias Model).YValue));
                }
            }
            else
            {
                int selectedDataPointIndex = 0;
                var itemsource = chartSelectionEvent.SelectedSeries.ItemsSource;

                foreach (Model item in itemsource)
                {
                    if ((item as Model).YValue == selectedSegment.YValue)
                    {
                        selectedDataPointIndex = (itemsource as ObservableCollection<Model>).IndexOf(item);
                        break;
                    }
                }

                chartBindingContext.GroupedYValues.Add(new Model((itemsource as ObservableCollection<Model>)[selectedDataPointIndex].XValueselectedSegment.YValue));
            }

            if (ListView != null)
            {
                ListView.ItemsSource = null;
                ListView.ItemsSource = chartBindingContext.GroupedYValues;
            }
        }  
 
 
iOS: 
public override void DidDataPointSelect(SFChartSelectionInfo selectionInfo)
        {
            base.DidDataPointSelect(selectionInfo);

            ViewModel chartBindingContext = FormsChart.BindingContext as ViewModel;

            chartBindingContext.GroupedYValues = new ObservableCollection<Model>();

            var segments = selectionInfo.SelectedSeries.Segments;

            if (selectionInfo.SelectedDataPointIndex == -1)
            {
                chartBindingContext.GroupedYValues.Clear();
                return;
            }

            SFPieSegment selectedSegment = segments[selectionInfo.SelectedDataPointIndexas SFPieSegment;

            if (selectionInfo.SelectedDataPointIndex == segments.Count - 1)
            {
                PropertyInfo dataPointInfo = typeof(SFCircularSeries).GetProperty("GroupedData"BindingFlags.NonPublic | BindingFlags.Instance);
                List<objectgroupedDataPoints = dataPointInfo.GetValue(selectionInfo.SelectedSeriesnullas List<object>;

                for (int i = 0i < groupedDataPoints.Counti++)
                {
                    chartBindingContext.GroupedYValues.Add(new Model((groupedDataPoints[ias Model).XValue, (groupedDataPoints[ias Model).YValue));
                }
            }
            else
            {
                int selectedDataPointIndex = 0;
                var itemsource = selectionInfo.SelectedSeries.ItemsSource;
                foreach (Model item in itemsource)
                {
                    if ((item as Model).YValue == selectedSegment.YValue)
                    {
                        selectedDataPointIndex = (itemsource as ObservableCollection<Model>).IndexOf(item);
                        break;
                    }
                }

                chartBindingContext.GroupedYValues.Add(new Model((itemsource as ObservableCollection<Model>)[selectedDataPointIndex].XValueselectedSegment.YValue));
            }

            if (ListView != null)
            {
                ListView.ItemsSource = null;
                ListView.ItemsSource = chartBindingContext.GroupedYValues;
            }
        }  
 
 
Screenshot: 
 
 
We have modified the sample with selection. Please download the sample from the following location. 
 
 
Please let us know, if you need further assistance on this. 
 
Regards, 
Bharathiraja.

CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

Please sign in to access our forum

This page will automatically be redirected to the sign-in page in 10 seconds.

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

;