How do I add a Vertical Scrollbar to Telerik RadLegendControl within RadCartesianChart?

429 Views Asked by At

I am developing a program within UWP that will have the ability to chart data on-screen, and must support the potential that a user may want to chart a large number of series on it.

The Chart that I am using is Telerik's RadCartesianChart and I am using a RadLegendControl for showing the legend for the chart. This is laid out on a Grid that has two Columns and one Row. In the first Column (0) is the RadLegendControl. In the second Column (1) is the RadCartesianChart.

When a large number of Series are drawn, this can result in the Legend going down below the bottom of the app, cutting off the remaining items in the legend. This is basically an "excessive" example of the usage of this chart and I'm wanting to make sure it can function effectively when put under this kind of use.

Is there a way to add a scrollbar to the Legend Control so that a user can scroll through the legend? Or should I be looking at a different method for showing the legend?

This is for a program made within UWP that is currently targeting a minimum version of Windows 10 1803 and aiming for 1809, using Visual Studio 2019.

I made a post over on Telerik's forum asking this question and it was suggested that there is possibly an external component that is letting the legend extend to its full height off-screen and they provided a possible solution in trying to set an explicit maximum height to see the scrollbar appear when it reaches that upper bound. As such, in the XAML I set MaxHeight="300", which is much smaller than the average Chart's legend would require, such that I could easily see if the Scrollbar appeared. When I tried this, no Scrollbar appeared.

Originally I was having the RadLegendControl being drawn utilising a StackPanel to reorder the Legend to display from top-down instead of left-to-right so that it could fit alongside the Chart. I suspected that the StackPanel's internal ScrollViewer may have been conflicting with the RadLegendControl's internal ScrollViewer. I removed the StackPanel layout to ensure that it could not conflict to see if a ScrollViewer would then appear. It did not (I tested a horizontal one as well, to no success).

I have tried other solutions such as binding the MaxHeight property of the RadLegendControl to the Height or ActualHeight of the Grid row that it is on, explicitly setting VerticalScrollMode to Enabled and VerticalScrollVisibility to Visible.

This is the RadLegendControl code within XAML, still with the MaxHeight set explicitly to 300:

<telerikPrimitives:RadLegendControl
    x:Name="LegendForChart"
    LegendProvider="{Binding ElementName=MainChart}"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    HorizontalContentAlignment="Left"
    VerticalContentAlignment="Top"
    MaxHeight="300"
    >
    <telerikPrimitives:RadLegendControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical"/>
        </ItemsPanelTemplate>
    </telerikPrimitives:RadLegendControl.ItemsPanel>
</telerikPrimitives:RadLegendControl>

Where telerikPrimitives is defined with the following:

xmlns:telerikPrimitives="using:Telerik.UI.Xaml.Controls.Primitives"

I have tried adding/modifying the following lines:

MaxHeight="{Binding ElementName=ChartGrid, Path=Height, Mode=Oneway}"
MaxHeight="{Binding ElementName=ChartGrid, Path=ActualHeight, Mode=Oneway}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"

Currently with my file that can display ~332 Series on my Chart, the Legend does not have a Scrollbar showing, with the items disappearing off-screen. (Unfortunately I don't have enough rep to show an image).

I would like to find a solution where, if there are sufficient Series showing, a vertical Scrollbar would appear and allow the user to scroll down through the Legend.

I realise this may appear as excessive, but I would like to ensure that my program behaves appropriately if a user would, for any reason, decide to display a large number of Series on the chart.

1

There are 1 best solutions below

1
Xie Steven On BEST ANSWER

Since you just provide the RadLegendControl XAML code, I did not see your whole XAML code sample. I'm not sure what the issue is on your side.

So, I made a simple code sample according to the Telerik's official document.

I just use a ScrollViewer control to wrap the RadLegendControl, then it will be scrollable.

Please see my code sample:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"></ColumnDefinition>
        <ColumnDefinition Width="8*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <telerikChart:RadCartesianChart x:Name="chart" Grid.Column="1">
        <telerikChart:RadCartesianChart.HorizontalAxis>
            <telerikChart:CategoricalAxis />
        </telerikChart:RadCartesianChart.HorizontalAxis>
        <telerikChart:RadCartesianChart.VerticalAxis>
            <telerikChart:LinearAxis />
        </telerikChart:RadCartesianChart.VerticalAxis>
        <telerikChart:RadCartesianChart.SeriesProvider>
            <telerikChart:ChartSeriesProvider x:Name="provider">
                <telerikChart:ChartSeriesProvider.SeriesDescriptors>
                    <telerikChart:CategoricalSeriesDescriptor ItemsSourcePath="GetData" ValuePath="Value" CategoryPath="Category" LegendTitlePath="LegendTitle">
                        <telerikChart:CategoricalSeriesDescriptor.Style>
                            <Style TargetType="telerikChart:BarSeries">
                                <Setter Property="CombineMode" Value="Cluster" />
                            </Style>
                        </telerikChart:CategoricalSeriesDescriptor.Style>
                    </telerikChart:CategoricalSeriesDescriptor>
                </telerikChart:ChartSeriesProvider.SeriesDescriptors>
            </telerikChart:ChartSeriesProvider>
        </telerikChart:RadCartesianChart.SeriesProvider>
    </telerikChart:RadCartesianChart>
    <ScrollViewer>
        <telerikPrimitives:RadLegendControl x:Name="LegendForChart" LegendProvider="{Binding ElementName=chart}">
            <telerikPrimitives:RadLegendControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsStackPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </telerikPrimitives:RadLegendControl.ItemsPanel>
        </telerikPrimitives:RadLegendControl>
    </ScrollViewer>
</Grid>
private Random r = new Random();

    public List<ViewModel> GenerateCollection()
    {
        List<ViewModel> collection = new List<ViewModel>();
        for (int i = 0; i < 500; i++)
        {
            ViewModel vm = new ViewModel();
            vm.GetData = GenerateData();
            vm.LegendTitle = "ViewModel " + i;
            collection.Add(vm);
        }

        return collection;
    }

    public List<Data> GenerateData()
    {
        List<Data> data = new List<Data>();
        data.Add(new Data { Category = "Apple", Value = r.Next(1, 20) });
        data.Add(new Data { Category = "Orange", Value = r.Next(10, 30) });
        data.Add(new Data { Category = "Lemon", Value = r.Next(20, 40) });

        return data;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        this.provider.Source = GenerateCollection();
    }
public class ViewModel
{
    public List<Data> GetData { get; set; }

    public string LegendTitle { get; set; }
}

public class Data
{
    public double Value { get; set; }

    public string Category { get; set; }
}