RadLegend scrollbar needed

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

    Posted 26 Mar Link to this post

    Hi there,
    I would like to use the legend for my pie chart. Since it might happen that around 10-20 different slices are being populated the according legend items need a lot of space. So I have tried to put the legend inside a scrollview, but no matter which constellation I have tested (grid row with fixed height, with * height, with auto height, stackview instead of grid, fixed size on the scrollview etc.) the scrollbar is almost never shown. Only when I manually set the height of the legend higher then the height of the scrollview a scrollbar is shown, but in this case I cannot really estimate what a correct size for the legend would be.

     

    Is there any possiblity at all to make the legend scrollable?

     

    Here is my xaml example:

    <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="0">
            <Grid AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1"
                  Padding="0" Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="300" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <telerikChart:RadPieChart x:Name="performanceChart" Grid.Row="0" Grid.Column="0" Margin="30,30,30,30">
                    <telerikChart:RadPieChart.Series>
                        <telerikChart:PieSeries DisplayName="RequestsTotal" LegendTitleBinding="ServiceNameWithRequestsTotal"
                                                ItemsSource="{Binding GraphDataByServiceName}" ValueBinding="RequestsTotal"/>
                    </telerikChart:RadPieChart.Series>
                </telerikChart:RadPieChart>

                <ScrollView Grid.Row="1" Grid.Column="0" Margin="15,0,15,0" HorizontalScrollBarVisibility="Never"
                            VerticalOptions="FillAndExpand" Orientation="Vertical">
                        <telerikChart:RadLegend LegendItemFontColor="{StaticResource ListItemTextBright}" HorizontalOptions="FillAndExpand"
                                                VerticalOptions="FillAndExpand" LegendItemFontSize="15"
                                                LegendProvider="{x:Reference Name=performanceChart}" Orientation="Vertical"/>
                </ScrollView>
            </Grid>
            <StackLayout AbsoluteLayout.LayoutFlags="PositionProportional"
                        AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
                <ActivityIndicator VerticalOptions="Center" HorizontalOptions="Center" IsVisible="{Binding IsLoading}"
                                    IsRunning="{Binding IsLoading}"/>
            </StackLayout>
        </AbsoluteLayout>

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

    Posted 26 Mar Link to this post

    Hello Michael,

    The chart and legend controls are not Xamarin.Forms component, thus there's no ScrollViewer to access directly from Xamarin.Forms.

    You can access the native control by using a custom renderer and try to manipulate the Legend Control on the native platform. See the Register Chart Renderers article in the documentation to get started (be sure to read the note section on where to find actual examples).

    Another option is use a custom Xamarin.Forms Platform Effect to access the native component instead.  We don't have official demos for this, but I do have a set of custom demos on GitHub and this one uses a Platform Effect to create custom labels. That will show you how to access a native control using an Effect (in your case you'll want an effect for the Legend control and not the chart).

    Ultimately, you can probably just keep this in the Xamarin.Forms project. Count how many series/items you're going to be loading in the chart, then programmatically set the height of the Legend's parent container at the same time (you can change the RowDefinition Height if you give it an x:Name).

    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 27 Mar in reply to Lance | Team Lead - US DevTools Support Link to this post

    Hi Lance,

     

    thanks for the information.

     

    Would it be possible to get the used color for each of the items which are used to populate the chart? If that would be possible I could easily build my own legend, since I only need to draw the used color and append any custom legend text I would like to have. That would also solve a second issue I am facing. In case that a slice of the chart is pretty small it is hard to select this one, but if I could build my own legend I could also make the legend items selectable and handle this in the same way as a selection in the chart would be treated.

     

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

    Posted 27 Mar Link to this post

    Hello Michael,

    It's easier to just set a custom palette (see: Custom Chart Palette), then access the PaletteEntries via the chart's Palette property:

    foreach (var paletteEntry in MyPieChart.Palette.Entries)
    {
        // get the color via paletteEntry.FillColor
    }

    Example

    In the following example, I iterate over the ItemsSource of the PieSeries and create custom Legend items for a RadListView. Using the index of the item in the original series data to match up with the series slice (it goes back to the first custom palette color when it reaches the end).

    public void CreateLegend()
    {
        var legendItems = new List<LegendItem>();
     
        foreach (var seriesItem in ViewModel.PieSeriesItems)
        {
            // Use a modulus to prevent going over-index
            var colorIndex = ViewModel.PieSeriesItems.IndexOf(seriesItem) % MyPieChart.Palette.Entries.Count;
     
            // Create a custom Legend item and add it to the source for the ListView
            legendItems.Add(new LegendItem
            {
                Title = seriesItem.Category,
                SeriesPaletteEntry = MyPieChart.Palette.Entries[colorIndex]
            });
        }
     
        LegendListView.ItemsSource = legendItems;
    }


    You'll get a result like this:



    I've attached all the code for the above example.

    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 28 Mar in reply to Lance | Team Lead - US DevTools Support Link to this post

    Hi Lance,

     

    thanks a lot for your assistance, that's exactly what I was looking for.

Back to Top