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. Image for the cookie policy date

Pie Chart with GroupMode enabled, OnSelection returns incorrect SelectedDataPointIndex

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.

4 Replies

BK Bharathiraja K Syncfusion Team 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}  {2} : {3}  {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. 



JC Jonathan Cranford 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. 



JC Jonathan Cranford 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];

          }
}


BK Bharathiraja K Syncfusion Team 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.

Loader.
Live Chat Icon For mobile
Up arrow icon