I can not set the minimum of RadCartesianChart.LinearAxis.

4 posts, 1 answers
  1. Yaroslav
    Yaroslav avatar
    123 posts
    Member since:
    Jan 2016

    Posted 06 Sep Link to this post

    Hello. I try to set the scale of RadCartesianChart.LinearAxis and I can't. How I try to do it, please see the following. Below is XAML of the RadCartesianChart:

    <!--Sound velocity [meter/second] chart for each ultrasonic beam.-->
    <telerik:RadCartesianChart Visibility="{Binding IsAbsoluteSplineChartVisible}">
        <telerik:RadCartesianChart.HorizontalAxis>
            <telerik:DateTimeContinuousAxis MajorStepUnit="Second" LabelInterval="5" LabelFormat="hh:mm:ss" FontFamily="Segoe UI" PlotMode="OnTicks" TickOrigin="{Binding AlignmentDate}"/>
        </telerik:RadCartesianChart.HorizontalAxis>
        <telerik:RadCartesianChart.VerticalAxis>
           <telerik:LinearAxis FontFamily="Segoe UI" Title="Meters per second [m/s]" Minimum="{Binding ChartMinimum}" Maximum="{Binding ChartMaximum}"/>
        </telerik:RadCartesianChart.VerticalAxis>
        <!--Provider for each series-->
        <telerik:RadCartesianChart.SeriesProvider>
           <telerik:ChartSeriesProvider Source="{Binding SeriesData}">
              <telerik:ChartSeriesProvider.SeriesDescriptors>
                 <telerik:CategoricalSeriesDescriptor CategoryPath="Category" ValuePath="Value" ItemsSourcePath="ChartPoints">
                     <telerik:CategoricalSeriesDescriptor.TypeConverter>
                         <local:SeriesTypeConverter/>
                     </telerik:CategoricalSeriesDescriptor.TypeConverter>
                 </telerik:CategoricalSeriesDescriptor>
              </telerik:ChartSeriesProvider.SeriesDescriptors>
           </telerik:ChartSeriesProvider>
        </telerik:RadCartesianChart.SeriesProvider>
        <!--Zooming and Panning-->
        <telerik:RadCartesianChart.Behaviors>
           <telerik:ChartPanAndZoomBehavior ZoomMode="Vertical"  PanMode="Vertical"/>
        </telerik:RadCartesianChart.Behaviors>
    </telerik:RadCartesianChart>

    Below is handler of ticks of sound velocity values polling timer.

    private void Timer_Tick(object sender, EventArgs e)
    {
        // Сharts filling:
        // get minimal value of sound velocity,
        double min_1_2 = Math.Min(GlobalStaticMembers.FirstBeamSoundVelocity, GlobalStaticMembers.SecondBeamSoundVelocity);
        double min_3_4 = Math.Min(GlobalStaticMembers.ThirdBeamSoundVelocity, GlobalStaticMembers.FourthBeamSoundVelocity);
        this.ChartMinimum = Math.Floor(Math.Min(min_1_2, min_3_4));
        // get maximal value of sound velocity,
        double max_1_2 = Math.Max(GlobalStaticMembers.FirstBeamSoundVelocity, GlobalStaticMembers.SecondBeamSoundVelocity);
        double max_3_4 = Math.Max(GlobalStaticMembers.ThirdBeamSoundVelocity, GlobalStaticMembers.FourthBeamSoundVelocity);
        this.ChartMaximum = Math.Ceiling(Math.Max(max_1_2, max_3_4));
        // adjust the value of the time on X-axis,
        this._currentDate = this._currentDate.AddMilliseconds(TIMER_INTERVAL);
        this.SeriesData.SuspendNotifications();
        // get the first beam chart new point where newPoint.Value is sound velocity itself,
        ChartPoint newPoint = new ChartPoint();
        newPoint.Value = GlobalStaticMembers.FirstBeamSoundVelocity;
        newPoint.Category = this._currentDate;
        if (this.SeriesData[0].ChartPoints.Count > 50)
            this.SeriesData[0].ChartPoints.RemoveAt(0);
        this.SeriesData[0].ChartPoints.Add(newPoint);
        // get the second beam chart new point where newPoint.Value is sound velocity itself,
        newPoint = new ChartPoint();
        newPoint.Value = GlobalStaticMembers.SecondBeamSoundVelocity;
        newPoint.Category = this._currentDate;
        if (this.SeriesData[1].ChartPoints.Count > 50)
            this.SeriesData[1].ChartPoints.RemoveAt(0);
        this.SeriesData[1].ChartPoints.Add(newPoint);
        // get the third beam chart new point where newPoint.Value is sound velocity itself,
        newPoint = new ChartPoint();
        newPoint.Value = GlobalStaticMembers.ThirdBeamSoundVelocity;
        newPoint.Category = this._currentDate;
        if (this.SeriesData[2].ChartPoints.Count > 50)
            this.SeriesData[2].ChartPoints.RemoveAt(0);
        this.SeriesData[2].ChartPoints.Add(newPoint);
        // get the fourth beam chart new point where newPoint.Value is sound velocity itself.
        newPoint = new ChartPoint();
        newPoint.Value = GlobalStaticMembers.FourthBeamSoundVelocity;
        newPoint.Category = this._currentDate;
        this.SeriesData[3].ChartPoints.Add(newPoint);
        if (this.SeriesData[3].ChartPoints.Count > 50)
            this.SeriesData[3].ChartPoints.RemoveAt(0);
        this.SeriesData.ResumeNotifications();
    }

    Below is ChartMinimum and ChartMaximum properties definitions:

    public double ChartMinimum
    {
       get { return this._chartMinimum; }
       set { this.SetProperty(ref this._chartMinimum, value); }
    }
     
    public double ChartMaximum
    {
       get { return this._chartMaximum; }
       set { this.SetProperty(ref this._chartMaximum, value); }
    }

    Below is ChartPoint class definition:

    /// <summary>
    /// Point for spline series.
    /// </summary>
    public class ChartPoint
    {
        private double _value;
        private DateTime _category;
        public ChartPoint() { }
        public ChartPoint(DateTime category, double value)
        {
            this.Category = category;
            this.Value = value;
        }
        public double Value
        {
            get { return this._value; }
            set { this._value = value; }
        }
        public DateTime Category
        {
            get { return this._category; }
            set { this._category = value; }
        }
    }

    Below is the collection containing all series. This collection is used as datasource for telerik:ChartSeriesProvider.

    /// <summary>
    /// Gets or sets the collection containing series.
    /// </summary>
    public RadObservableCollection<SeriesModel> SeriesData { get; set; }

    And below is SeriesModel class definition:

    /// <summary>
    /// The model of series (chart's curve).
    /// </summary>
    public class SeriesModel
    {
        #region Constructors
        public SeriesModel() { }
        public SeriesModel(RadObservableCollection<ChartPoint> chartPoints, string seriesType = "Spline")
        {
            this.ChartPoints = chartPoints;
            this.SeriesType = seriesType;
        }
        #endregion
     
        #region Properties
     
        /// <summary>
        /// Series type
        /// </summary>
        public string SeriesType { get; set; }
        /// <summary>
        /// Series points collection.
        /// </summary>
        public RadObservableCollection<ChartPoint> ChartPoints { get; set; }
     
        #endregion
    }

    I also show you the converter definition:

    /// <summary>
    /// Series type converter.
    /// </summary>
    public class SeriesTypeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            SeriesModel seriesItem = value as SeriesModel;
     
            if (seriesItem.SeriesType == "Spline")
            {
                return typeof(SplineSeries);
            }
            else if (seriesItem.SeriesType == "Line")
            {
                return typeof(LineSeries);
            }
            else
            {
                return typeof(BarSeries);
            }
        }
     
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            /*throw new NotImplementedException()*/return null;
        }
    }

    As you know, the value of sound is hundreds of meters per second. Say, for example, 345.55 meters per second (I especially take the value with  hundredths of a meter). The value of sound velocity in a good flowmeter can varies from a few hundredths to a tenth of a meter not more. So, each timer tick, I take four sound velocity values (because the flowmeter has four ultrasonic beams), find minimal value of them and take floor for this value (Math.Floor). Then I find maximal value of these four velocity values and take ceiling for this maximal value (Math.Ceiling). So I'd like to limit the vertical axis by these minimum and maximum (ChartMinimum and ChartMaximum properties). But unfortunately I can't. Supports only the maximum (please see 'SoundVelocity.PNG' file attached and 'SoundVelocity2.PNG file attached, the second one has zoomed in chart). Minimum is not supported. Why? The folowing is What I need. So. I need that the vertical axis limited by minimum and maximum and with MajorStep == 0.01. For example, if minimal value of sound velocity (obtained on timer tick) is 325.7 then limiting minimum of vertical axis must be 325, if maximal value of the sound velocity obtained is, for example, 326.2 then limiting maximum of vertical axis must be 327. So in this case the vertical axis must be from 325 to 327 with MajorStep == 0.01 (!!! but not from 0 to 327 with MajorStep==0.01 !!!). Is this possible to do ofcourse. If yes, please show me how it can be implemented. Thank you very much in advance.

    P.S. If you need some aditional information for answering on this my post, please write me.

  2. Yaroslav
    Yaroslav avatar
    123 posts
    Member since:
    Jan 2016

    Posted 07 Sep in reply to Yaroslav Link to this post

    And why does RadCartesianChart not set (in my case) appropriate minimum and maximum limits on Y-axis automatically as it does when only one SplineSeries is shown (when SeriesProvider is not used)?
  3. UI for WPF is Visual Studio 2017 Ready
  4. Answer
    Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 09 Sep Link to this post

    Hi Yaroslav,

    I created a small project based on the code you provided. Not everything was there so I had to improvise in order to get it working. After doing so, I must say that everything looks as expected. I see a live-data chart with both axes getting updated properly.

    The only thing that comes to my mind is that the PropertyChanged notification is missing in your view model. I see that you use a SetProperty method, but it is not obvious if the method invokes the PropertyChanged event so that the chart can hear about the minimum changing.

    I am attaching a short video to demonstrate that this works as expected and the project I tested with. If I did not address the issue you are experiencing please give us some more information.

    Regards,
    Petar Marchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  5. Yaroslav
    Yaroslav avatar
    123 posts
    Member since:
    Jan 2016

    Posted 12 Sep Link to this post

    Thank you, Petar. Your help is great.
Back to Top