Unplanned
Last Updated: 24 Oct 2024 05:59 by ADMIN
Sebastian
Created on: 21 Sep 2022 07:00
Category: Chart
Type: Feature Request
4
Chart: Support for multi axes
I would like to visualize a secondary vertical Axis for the series. 
3 comments
ADMIN
Didi
Posted on: 24 Oct 2024 05:59

Hi Fred, 

We do not have a time-frame when this feature will be implemented. The status is Unplanned. You can check the Telerik MAUI RoadMap at the following link: https://www.telerik.com/support/whats-new/maui-ui/roadmap 

Regards,
Didi
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Fred
Posted on: 23 Oct 2024 22:20

Bump, 

this is an important feature of a charting system. The workaround of placing multiple charts overlayed on top of each other is limited, it only works for 2 axes and requires some shenanigans to keep the charts aligned nevermind the fact that you need to set the chart size from a content view because of bugs in the chart rendering on android.

This Sample lets you have a chart with two Y axis 

-----------------------------------------------------

xaml  

-----------------------------------------------------

 <Grid MinimumWidthRequest="300">
     <Grid.ColumnDefinitions>
         <ColumnDefinition Width="Auto" />
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="Auto" />
     </Grid.ColumnDefinitions>
     <Grid.RowDefinitions>
         <RowDefinition Height="Auto" />
         <RowDefinition Height="*" />
         <RowDefinition Height="Auto" />
         <RowDefinition Height="Auto" />
     </Grid.RowDefinitions>
     <ContentView
         Grid.Row="1"
         Grid.Column="1"
         BackgroundColor="Black"
         HorizontalOptions="Start"
         WidthRequest="{Binding Y1AxisWidth}" />
     <ContentView
         Grid.Row="1"
         Grid.Column="1"
         BackgroundColor="Black"
         HorizontalOptions="End"
         WidthRequest="{Binding Y2AxisWidth}" />
     <Label
         Grid.ColumnSpan="3"
         FontSize="Small"
         HorizontalOptions="Center"
         Text="{Binding ChartTitle}"
         TextColor="{x:StaticResource CSTShadowColor}" />

     <!--<telerik:RadButton
         Grid.ColumnSpan="3"
         Margin="0,5,10,5"
         Padding="-10"
         BackgroundColor="{StaticResource CSTShadowColor}"
         HeightRequest="25"
         HorizontalOptions="End"
         Text="🗗"
         WidthRequest="25" />-->
     <Label
         Grid.Row="1"
         Grid.Column="0"
         Rotation="-90"
         Text="{Binding Y1AxisTitle}"
         TextColor="{x:StaticResource CSTShadowColor}"
         VerticalOptions="Center" />
     <Label
         Grid.Row="1"
         Grid.Column="2"
         Rotation="90"
         Text="{Binding Y2AxisTitle}"
         TextColor="{x:StaticResource CSTShadowColor}"
         VerticalOptions="Center" />
     <ContentView
         x:Name="CV1"
         Grid.Row="1"
         Grid.Column="1"
         Padding="{Binding Chart1Margin}"
         BackgroundColor="Transparent">
         <telerik:RadCartesianChart
             x:Name="Chart1"
             Margin="0,-5,0,-5"
             BackgroundColor="Transparent"
             HeightRequest="{Binding Source={x:Reference CV1}, Path=Height}">
             <telerik:RadCartesianChart.HorizontalAxis>
                 <telerik:DateTimeContinuousAxis
                     x:Name="AxisTime"
                     LabelFontSize="{Binding TextSize}"
                     LabelTextColor="{StaticResource CSTShadowColor}"
                     LineColor="{StaticResource CSTShadowColor}"
                     MajorStep="{Binding XAxisMajorStep}"
                     MajorStepUnit="Second"
                     Maximum="{Binding XAxisMax}"
                     Minimum="{Binding XAxisMin}"
                     PlotMode="OnTicks" />
             </telerik:RadCartesianChart.HorizontalAxis>
             <telerik:RadCartesianChart.VerticalAxis>
                 <telerik:NumericalAxis
                     x:Name="AxisY1"
                     LabelFontSize="{Binding TextSize}"
                     LabelTextColor="{StaticResource CSTShadowColor}"
                     LineColor="{StaticResource CSTShadowColor}"
                     Location="Left"
                     MajorStep="{Binding Y1AxisMajorStep}"
                     Maximum="{Binding Y1AxisMax}"
                     Minimum="{Binding Y1AxisMin}"
                     RangeExtendDirection="None"
                     ShowLabels="True" />
             </telerik:RadCartesianChart.VerticalAxis>
             <telerik:RadCartesianChart.Series>
                 <telerik:LineSeries
                     CategoryBinding="Time"
                     DisplayName="{Binding Y1AxisTitle}"
                     ItemsSource="{Binding Data1}"
                     Stroke="{StaticResource CSTSecondaryColor}"
                     ValueBinding="Value" />
             </telerik:RadCartesianChart.Series>
             <telerik:RadCartesianChart.Grid>
                 <telerik:CartesianChartGrid MajorLineColor="{StaticResource CSTShadowColor}" MajorLinesVisibility="X" />

             </telerik:RadCartesianChart.Grid>
         </telerik:RadCartesianChart>
     </ContentView>



     <ContentView
         x:Name="CV2"
         Grid.Row="1"
         Grid.Column="1"
         Padding="{Binding Chart2Margin}"
         BackgroundColor="Transparent">
         <telerik:RadCartesianChart
             x:Name="Chart2"
             Margin="0,-5,0,-5"
             BackgroundColor="Transparent"
             HeightRequest="{Binding Source={x:Reference CV2}, Path=Height}">
             <telerik:RadCartesianChart.HorizontalAxis>
                 <telerik:DateTimeContinuousAxis
                     x:Name="AxisTime2"
                     LabelFontSize="{Binding TextSize}"
                     LabelTextColor="Transparent"
                     LineColor=" Transparent"
                     MajorStep="{Binding XAxisMajorStep}"
                     MajorStepUnit="Second"
                     Maximum="{Binding XAxisMax}"
                     Minimum="{Binding XAxisMin}"
                     PlotMode="OnTicks" />
             </telerik:RadCartesianChart.HorizontalAxis>
             <telerik:RadCartesianChart.VerticalAxis>
                 <telerik:NumericalAxis
                     x:Name="AxisY2"
                     LabelFontSize="{Binding TextSize}"
                     LabelTextColor="{StaticResource CSTShadowColor}"
                     LineColor="{StaticResource CSTShadowColor}"
                     Location="Right"
                     MajorStep="{Binding Y2AxisMajorStep}"
                     Maximum="{Binding Y2AxisMax}"
                     Minimum="{Binding Y2AxisMin}"
                     ShowLabels="True" />
             </telerik:RadCartesianChart.VerticalAxis>
             <telerik:RadCartesianChart.Series>
                 <telerik:LineSeries
                     CategoryBinding="Time"
                     DisplayName="{Binding Y2AxisTitle}"
                     ItemsSource="{Binding Data2}"
                     Stroke="{StaticResource CSTAccentColor}"
                     ValueBinding="Value" />
             </telerik:RadCartesianChart.Series>
             <!--<telerik:RadCartesianChart.Grid>
             <telerik:CartesianChartGrid
                 MajorLineColor="{StaticResource CSTShadowColor}"
                 MajorLinesVisibility="XY"
                 StripLinesVisibility="XY"
                 XStripeColor="Red"
                 YStripeColor="Red" />
         </telerik:RadCartesianChart.Grid>-->
         </telerik:RadCartesianChart>
     </ContentView>
     <Label
         Grid.Row="2"
         Grid.ColumnSpan="3"
         HorizontalOptions="Center"
         Text="{Binding XAxisTitle}"
         TextColor="{x:StaticResource CSTShadowColor}" />
     <FlexLayout
         Grid.Row="3"
         Grid.Column="1"
         Grid.ColumnSpan="0"
         Wrap="Wrap">
         <telerik:RadLegend
             LegendItemFontColor="{x:StaticResource CSTShadowColor}"
             LegendProvider="{x:Reference Chart1}"
             WidthRequest="300" />
         <telerik:RadLegend
             LegendItemFontColor="{x:StaticResource CSTShadowColor}"
             LegendProvider="{x:Reference Chart2}"
             WidthRequest="300" />

     </FlexLayout>
 </Grid>

---------------------------------------------------------------------------

View Model

--------------------------------------------------------------------------

 

        [ObservableProperty]
        private double _TextSize = 12;

        private double multiplier = 0.57;
        public TwinYAxisTemporalChartViewModel()
        {
            //#if ANDROID
            //multiplier = 0.2;
            //#endif
        }

        //this class uses source generators private fields are annotated with [ObservableProperty]
        [ObservableProperty]
        private string _ChartTitle = "Chart Title";

        [ObservableProperty]
        private bool _IsChartStacked = true;

        [ObservableProperty]
        private string _XAxisTitle = "X Axis Title";
        [ObservableProperty]
        private DateTime _XAxisMin;
        [ObservableProperty]
        private DateTime _XAxisMax;



        [ObservableProperty]
        private double _XAxisMajorStep;




        [ObservableProperty]
        private string _Y1AxisTitle = "Y Axis 1 Title";
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(Y1AxisWidth))]
        [NotifyPropertyChangedFor(nameof(Chart2Margin))]
        private double _Y1AxisMin;
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(Y1AxisWidth))]
        [NotifyPropertyChangedFor(nameof(Chart2Margin))]
        private double _Y1AxisMax;
        [ObservableProperty]
        private double _Y1AxisMajorStep;

        public double Y1AxisWidth => CalcY1Width();
#if ANDROID
      public Thickness Chart2Margin => new Thickness(Y1AxisWidth - 27, 0, 0, 0);
#else
        public Thickness Chart2Margin => new Thickness(Y1AxisWidth, 0, 0, 0);
#endif



        public ObservableCollection<TemporalDataNumeric>? Data1 { get; set; }


        [ObservableProperty]
        private string _Y2AxisTitle = "Y Axis 2 Title";
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(Y2AxisWidth))]
        [NotifyPropertyChangedFor(nameof(Chart1Margin))]
        private double _Y2AxisMin;
        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(Y2AxisWidth))]
        [NotifyPropertyChangedFor(nameof(Chart1Margin))]
        private double _Y2AxisMax;
        [ObservableProperty]
        private double _Y2AxisMajorStep;

        public double Y2AxisWidth => CalcY2Width();

#if ANDROID
        public Thickness Chart1Margin => new Thickness(0, 0, Y2AxisWidth -27, 0);
#else
        public Thickness Chart1Margin => new Thickness(0, 0, Y2AxisWidth - 22, 0);
#endif

        public ObservableCollection<TemporalDataNumeric>? Data2 { get; set; }

        private double CalcY1Width()
        {
            string min = Y1AxisMin.ToString();
            double minlen = min.Length;
            if (min.StartsWith("-"))
            {
                minlen -= 0.5;
            }
            string max = Y1AxisMin.ToString();
            double maxlen = max.Length;
            if (max.StartsWith("-"))
            {
                maxlen -= 0.5;
            }

            return TextSize * multiplier * (Math.Max(minlen, maxlen)) + 8;
        }
        private double CalcY2Width()
        {
            string min = Y2AxisMin.ToString();
            double minlen = min.Length;
            if (min.StartsWith("-"))
            {
                minlen -= 0.3;
            }
            string max = Y2AxisMin.ToString();
            double maxlen = max.Length;
            if (max.StartsWith("-"))
            {
                maxlen -= 0.3;
            }

            return TextSize * multiplier * (Math.Max(minlen, maxlen)) + 5;
        }

    }

 

Clint
Posted on: 08 Dec 2022 17:52
I also need a second vertical axis for my charts.  In fact I have a situation where I could use more than 2 vertical axes.