- Home
- Forum
- Xamarin.Forms
- Pie Chart with GroupMode enabled, OnSelection returns incorrect SelectedDataPointIndex
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.
SIGN IN To post a reply.
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 value, Type targetType, object parameter, CultureInfo 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 = 0; i < groupedSegment.Count; i++) { groupedData.Add((groupedSegment[i] as Model).YValue); groupedXData.Add((groupedSegment[i] as 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 value, Type targetType, object parameter, CultureInfo 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.SelectedDataPointIndex] as Native.PieSegment; if (chartSelectionEvent.SelectedDataPointIndex == segments.Count - 1) { PropertyInfo dataPointInfo = typeof(Native.CircularSeries).GetProperty("GroupedData", BindingFlags.NonPublic | BindingFlags.Instance); List<object> groupedDataPoints = dataPointInfo.GetValue(chartSelectionEvent.SelectedSeries, null) as List<object>; for (int i = 0; i < groupedDataPoints.Count; i++) { chartBindingContext.GroupedYValues.Add(new Model((groupedDataPoints[i] as Model).XValue, (groupedDataPoints[i] as 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].XValue, selectedSegment.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.SelectedDataPointIndex] as SFPieSegment; if (selectionInfo.SelectedDataPointIndex == segments.Count - 1) { PropertyInfo dataPointInfo = typeof(SFCircularSeries).GetProperty("GroupedData", BindingFlags.NonPublic | BindingFlags.Instance); List<object> groupedDataPoints = dataPointInfo.GetValue(selectionInfo.SelectedSeries, null) as List<object>; for (int i = 0; i < groupedDataPoints.Count; i++) { chartBindingContext.GroupedYValues.Add(new Model((groupedDataPoints[i] as Model).XValue, (groupedDataPoints[i] as 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].XValue, selectedSegment.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.
Sample: http://www.syncfusion.com/downloads/support/forum/142618/ze/PieChart_GroupPoint-645894176.zip
Please let us know, if you need further assistance on this.
Regards,
Bharathiraja.
SIGN IN To post a reply.
- 4 Replies
- 3 Participants
-
NI Nick
- Feb 12, 2019 02:14 PM UTC
- Feb 14, 2019 06:55 AM UTC