RadPieChart - Programmatic selection

6 posts, 0 answers
  1. Michael
    Michael avatar
    13 posts
    Member since:
    Jan 2016

    Posted 04 Apr Link to this post

    Hi there,

     

    I am looking for a way to select a slice of the piechart from code-behind. I have have looked into the chart and series properties but found no selectable datapoints property. The chartSelectionBehavior offers a ClearSelection method and the readonly SelectedPoints property, but nothing to add a selected point.

    Is there any possibility to add a selected slice from code-behind?

     

    Regards,

    Michael

  2. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1048 posts

    Posted 05 Apr Link to this post

    Hi Michael,

    You're correct, the SelectedPoints is an IEnumerable that itself doesn't provide a method to programmatically adding points. The ChartSelectionBehavior class is the driver of selection mechanism (i.e. the ClearSelection method), however there's not currently a method to programmatically add points there yet.

    In some cases, I could write a custom Platform Effect or Custom renderer to use features of the native platform's control. However in this case, there is not a way to do this in all the native charts yet. Therefore, it will require the development team to build it and I suggest opening the feedback item.

    You can add a feature request in the UI for Xamarin Feedback Portal for the development team to consider adding it to a future release I apologize for any inconvenience this may case.

    Regards,
    Lance | Technical Support Engineer, Principal
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Michael
    Michael avatar
    13 posts
    Member since:
    Jan 2016

    Posted 08 Apr Link to this post

    Hi Lance,

     

    that's a pity. As posted in a different thread I have created my own chart legend and in case that I select a certain entry in the legend I would like to highlight/select or somehow mark the corresponding chart element. That works pretty well for the line series, because there I can just get the one desired line series for my chart and put a higher stroke on the line to show the selected item.

    While working with the pie series I have only the one series and I would have to get the according slice to show any kind of selection. Even though I really would like to have the same selection behavior when selecting the pie chart directly or via the legend I could also live with the workaround to have the selection only via the legend. In this case it would be fine if I could show the selection for the slice in any way (different border, highlight etc.). Do you see any workaround to accomplish this?

  4. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1048 posts

    Posted 08 Apr Link to this post

    Hello Michael,

    You could skip using the selection behavior and just change the styling of the slices to increase the border thickness and color to make it clear that slice appears "focused".

    Review the Custom Chart Palette article to see how to define your own palette colors. These palette objects have both a Fill and Stroke color properties. The stroke is the border brush and can be used to visually distinguish it from the rest of the slices.

    Because palette colors are applied in order (and loops back to the beginning if there are more data points than colors), you can match it up to the palette color that slice will receive and modify that palette item's border property. Note that you may need to reload the chart in order for palette changes to be observed after it's been initially rendered.

    Example

    Here's an example to get you started on the concept, this logic is based off the original "RadListView as Legend" example:

    Due to the complexity and customization level of such an approach, I ask that you open a support ticket if you have any further trouble with implementation. Share the code so that the developers can reproduce the problem and provide you with a directly applicable solution.


    private void LegendListView_OnSelectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // Pick the slice that you want to highlight
        if (e.NewItems?.Count > 0 && e.NewItems[0] is LegendItem selectedItem)
        {
            // Find the item in the series that matches that legend item
            var itemToHighlight = ViewModel.PieSeriesItems.FirstOrDefault(si => si.Category == selectedItem.Title);
             
            // Get the index of that series item
            var indexToHighlight = ViewModel.PieSeriesItems.IndexOf(itemToHighlight);
     
            // Highlight that slice to make it appear selected
            HighlightSlice(indexToHighlight);
        }
    }
     
    private void HighlightSlice(int indexToHighlight)
    {
        // In order to update the chart visually, an easy trick is to remove it from the UI and then add it back after modifications have been made
        var pieChart = MyPieChart;
        RootGrid.Children.Remove(MyPieChart);
         
        // make changes
        for (int i = 0; i < MyPieChart.Palette.Entries.Count; i++)
        {
            var originalFillColor = MyPieChart.Palette.Entries[i].FillColor;
            MyPieChart.Palette.Entries.RemoveAt(i);
     
            if (i == indexToHighlight)
            {
                MyPieChart.Palette.Entries.Insert(i, new PaletteEntry(originalFillColor, Color.Red));
            }
            else
            {
                MyPieChart.Palette.Entries.Insert(i, new PaletteEntry(originalFillColor, Color.Transparent));
     
            }
        }
     
        // Add it back
        RootGrid.Children.Add(pieChart);
    }

    <Grid x:Name="RootGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
     
        <telerikChart:RadPieChart x:Name="MyPieChart" >
            <telerikChart:RadPieChart.Palette>
                <telerikChart:ChartPalette>
                    <telerikChart:ChartPalette.Entries>
                        <telerikChart:PaletteEntry StrokeColor="Transparent" FillColor="LightBlue" />
                        <telerikChart:PaletteEntry StrokeColor="Transparent" FillColor="LightGreen" />
                        <telerikChart:PaletteEntry StrokeColor="Transparent" FillColor="LightCoral" />
                    </telerikChart:ChartPalette.Entries>
                </telerikChart:ChartPalette>
            </telerikChart:RadPieChart.Palette>
            <telerikChart:RadPieChart.Series>
                <telerikChart:PieSeries x:Name="MyPieSeries"
                                        AllowSelect="True"
                                        ItemsSource="{Binding PieSeriesItems}"
                                        ValueBinding="Value"
                                        ShowLabels="True"
                                        RadiusFactor="0.8" />
            </telerikChart:RadPieChart.Series>
        </telerikChart:RadPieChart>
     
        <!-- The custom legend -->
        <dataControls:RadListView x:Name="LegendListView" SelectionChanged="LegendListView_OnSelectionChanged" Grid.Row="1">
            <dataControls:RadListView.LayoutDefinition>
                <listView:ListViewLinearLayout Orientation="Horizontal" HorizontalItemSpacing="2" />
            </dataControls:RadListView.LayoutDefinition>
            <dataControls:RadListView.ItemTemplate>
                <DataTemplate>
                    <listView:ListViewTemplateCell>
                        <StackLayout Orientation="Horizontal">
                            <Grid BackgroundColor="{Binding SeriesPaletteEntry.FillColor}" Margin="5" Padding="5,0">
                                <Label Text="{Binding Title}" TextColor="White" VerticalOptions="Center" />
                            </Grid>
                        </StackLayout>
                    </listView:ListViewTemplateCell>
                </DataTemplate>
            </dataControls:RadListView.ItemTemplate>
        </dataControls:RadListView>
    </Grid>

    Important Note:  The main problem you might encounter is there are more slices than palette entries. When you highlight it, you'll get the highlight on all the slices that use that palette entry. Therefore, I recommend you always have more palette colors that expected slices to avoid this situation.

    Here's the result at runtime:





    Regards,
    Lance | Technical Support Engineer, Principal
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  5. Michael
    Michael avatar
    13 posts
    Member since:
    Jan 2016

    Posted 09 Apr Link to this post

    Hi Lance,

     

    thanks for the example and all your efforts. But especially the constraint to have more palette colors then slices looks like one possible error reason, which might occur, to much for me. I really would like to have a more build-in support for the programmatic selection, therefore I will open a support ticket as suggested.

     

    Thanks.

  6. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1048 posts

    Posted 09 Apr Link to this post

    Hello Micahel,

    Correct, the opened Feature Request is the right way to go about this because there's no built-in way to do this ansd it would need to be implemented on the native controls. I've linked this thread with the feature request so that the dev team can review our conversation when they consider the feature.

    Regarding the Palette colors, you don't need to programmatically manange it depending on how many data points you have. Just pick a top number that you cannot imagine the pie series having more than that, then just use a helper class to load up 15-20 colors and forget about it.

    For example, this approach keeps your XAML clean and still provide plenty of palette colors for every chart in the application.

    public static class PaletteHelper
    {
        static PaletteHelper()
        {
            MyPalette = new ChartPalette();
            LoadColors();
        }
     
        public static ChartPalette MyPalette { get; set; }
     
        private static void LoadColors()
        {
            var rand = new Random();
     
            // Loads 30 colors
            for (int i = 0; i < 30; i++)
            {
                MyPalette.Entries.Add(new PaletteEntry
                {
                    StrokeColor = Color.Transparent,
                    FillColor = Color.FromRgb(rand.Next(0,255), rand.Next(0, 255), rand.Next(0, 255))
                });
            }
        }
    }

    and that can be used in any chart:

    <chart:RadPieChart Palette="{x:Static helpers:PaletteHelper.MyPalette}">
        <chart:RadPieChart.Series>
            <chart:PieSeries ... />
        </chart:RadPieChart.Series>
    </chart:RadPieChart>

    The key takeaway is that, you can safely have more colors than you need, the issue would only arise if any colors needed to be reused. In the above example I use a Random color, but you can design alist of the same colors that will always be used.

    Regards,
    Lance | Technical Support Engineer, Principal
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top