Custom y axis labels

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
TomAgos
Newbie
Newbie
Posts: 8
Joined: Thu Jan 16, 2025 12:00 am

Custom y axis labels

Post by TomAgos » Thu Feb 27, 2025 7:37 am

im adding a few custom y axes, im creating them like that:

Code: Select all

     private Axis CreateCustomYAxis(SignalVectorPair svPair)
     {
         var color = ChartDataToZData.MColorToDColor(svPair.VectorM.Color);
         var yAxis = new Axis
         {
             Visible             = false,
             Horizontal          = false,
             Grid                = { Visible = false },
             Labels              = { Font = { Color = color } },
             AxisPen             = { Color = color, Visible = true },
             Ticks               = { Color = color, Visible = true },
             PositionUnits       = PositionUnits.Pixels
         };            

         yAxis.SetMinMax(svPair.SignalM.MinOrFactor, svPair.SignalM.MaxOrOffset);
         return yAxis;
     }
then, im adding my own labels to the axis like that:

Code: Select all

       private void SetAxisLabelsToGridTicks(Axis axis)
       {
           double diff = (axis.Maximum - axis.Minimum) / OscilNumOfGridLines;

           axis.Labels.Items.Clear();
           for (int j = 0; j <= OscilNumOfGridLines; j++)
           {
               double val      = axis.Minimum + (diff * j);
               string valStr   = val.ValToString(true, false, 4);
               axis.Labels.Items.Add(val, valStr);
           }
       }
when zooming and panning, this function (SetAxisLabelsToGridTicks) is called again and updating the labels according to the new axis range.
but sometimes some of the labels are disappear, i wanted to add a photo but i dont know how.
i have checked and 'val.ValToString(true, false, 4);' doesnt return null or empty string.

Marc
Site Admin
Site Admin
Posts: 1289
Joined: Thu Oct 16, 2003 4:00 am
Location: Girona
Contact:

Re: Custom y axis labels

Post by Marc » Thu Feb 27, 2025 9:17 am

Hello,

If you run a cross-check you can confirm that the Labels have been added for the plot. For example, with a Listbox on the form:

Code: Select all

    private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.IGraphics3D g)
    {
      listBox1.Items.Clear();
      for (int i=0; i < tChart1.Axes.Bottom.Labels.Items.Count; i++)
      {
        listBox1.Items.Add(tChart1.Axes.Bottom.Labels.Items[i].Text);
      }
    }
If all the items are present but not plotted, if there is a way you could get a demo project to us that reproduces the problem, it will help us to try and identify the cause of the problem.

With thanks.
Regards,
Marc Meumann
Steema Support

TomAgos
Newbie
Newbie
Posts: 8
Joined: Thu Jan 16, 2025 12:00 am

Re: Custom y axis labels

Post by TomAgos » Thu Feb 27, 2025 11:21 am

Hey, i have checked and the labels are added but not plotted.

try this code (wpf project with MainWindow only):
MainWindow.xaml.cs:

Code: Select all

using Steema.TeeChart;
using Steema.TeeChart.Drawing;
using Steema.TeeChart.Styles;
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Forms.Integration;

namespace YAxisLabelsDemo
{
    public partial class MainWindow : Window
    {
        private TChart _TChart;
        private Axis   _YAxis;
        private Graphics3D Graphics => _TChart.Graphics3D;
        private System.Drawing.Rectangle ChartRect => _TChart.Chart.ChartRect;

        public MainWindow()
        {
            InitializeComponent();

            _TChart = new TChart();

            var chart = new TChart();

            var wfh = new WindowsFormsHost { Child = chart };
            CC_TChart.Content = wfh;
            _TChart = chart;

            InitChart();
        }

        private void InitChart()
        {
            _YAxis = CreateCustomYAxis();
            var line = CreateConstantLine();

            line.CustomVertAxis = _YAxis;

            _TChart.Axes.Custom.Add(_YAxis);
            _TChart.Series.Add(line);

            _TChart.Legend.Visible = false;
            _TChart.Header.Visible = false;

            _TChart.Axes.Left.AxisPen.Visible   = false;
            _TChart.Axes.Left.Grid.Visible      = false;

            _TChart.Axes.Top.AxisPen.Visible    = false;
            _TChart.Axes.Right.AxisPen.Visible  = false;

            _TChart.Axes.Bottom.AxisPen.Visible = false;
            _TChart.Axes.Bottom.Grid.Visible    = false;

            _TChart.Panel.MarginLeft    = 60;
            _TChart.Panel.MarginTop     = 20;
            _TChart.Panel.MarginUnits   = PanelMarginUnits.Pixels;

            _TChart.Zoom.Direction      = ZoomDirections.None;
            _TChart.Panning.MouseButton = MouseButtons.Left;

            _TChart.MouseWheel  += TChart_MouseWheel;
            _TChart.Scroll      += (s, e) => SetAxisLabelsToGridTicks(); 
            _TChart.AfterDraw   += (s, e) => DrawOscilloscopeGridLines(); 
        }

        private void TChart_MouseWheel(object sender, MouseEventArgs e)
        {
            bool    zoomIn = e.Delta > 0;
            double  factor = zoomIn ? 0.1 : -0.1;

            // Get mouse position relative to the chart
            double mouseX = _TChart.Axes.Bottom.CalcPosPoint(e.X);
            double mouseY = _TChart.Axes.Left.CalcPosPoint(e.Y);

            void AdjustAxis(Axis axis, double mousePos)
            {
                double min      = axis.Minimum;
                double max      = axis.Maximum;
                double range    = max - min;

                // Calculate new min and max based on mouse position
                double newMin = min + (mousePos - min) * factor;
                double newMax = max - (max - mousePos) * factor;

                axis.SetMinMax(newMin, newMax);
            }

            AdjustAxis(_TChart.Axes.Bottom, mouseX);
            AdjustAxis(_TChart.Axes.Left, mouseY);

            foreach (Axis yAxis in _TChart.Axes.Custom)
            {
                double axisMouseY = yAxis.CalcPosPoint(e.Y);
                AdjustAxis(yAxis, axisMouseY);
            }

            SetAxisLabelsToGridTicks();

            if (e is HandledMouseEventArgs handledMouseEventArgs)
                handledMouseEventArgs.Handled = true; // Prevent default scrolling behavior
        }

        private Axis CreateCustomYAxis()
        {
            var yAxis = new Axis
            {
                Visible         = true,
                Horizontal      = false,
                Grid            = { Visible = false },
                AxisPen         = { Color = System.Drawing.Color.Red, Visible = true },
                Ticks           = { Color = System.Drawing.Color.Red, Visible = true },
            };

            yAxis.SetMinMax(-100, 100);

            return yAxis;
        }

        private FastLine CreateConstantLine()
        {
            var l = new FastLine();

            for (int i = 0; i < 10; i++)
                l.Add(i, 50);

            return l;
        }

        private void DrawOscilloscopeGridLines()
        {
            double chartWidth   = ChartRect.Right - ChartRect.Left;
            double chartHeight  = ChartRect.Bottom - ChartRect.Top;

            // Calculate step size for the grid
            double horizontalStep   = chartWidth / 10;
            double verticalStep     = chartHeight / 10;

            Graphics.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash;

            for (int i = 0; i <= 10; i++)
            {
                double x = ChartRect.Left + i * horizontalStep;
                double y = ChartRect.Top + i * verticalStep;

                Graphics.HorizontalLine(ChartRect.Left, ChartRect.Right, (int)Math.Round(y));  
                Graphics.VerticalLine((int)Math.Round(x), ChartRect.Top, ChartRect.Bottom);   
            }
        }

        private void SetAxisLabelsToGridTicks()
        {
            double diff = (_YAxis.Maximum - _YAxis.Minimum) / 10;

            _YAxis.Labels.Items.Clear();
            for (int i = 0; i <= 10; i++)
            {
                double val = _YAxis.Minimum + (diff * i);

                _YAxis.Labels.Items.Add(val, val.ToString("F2"));
            }
        }
    }
}

MainWindow.xaml:

Code: Select all

<Window x:Class="YAxisLabelsDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:YAxisLabelsDemo"
        mc:Ignorable="d"
        Title="MainWindow">
    
    <Grid>
        <ContentControl x:Name="CC_TChart"/>
    </Grid>
</Window>

try panning and zooming and you will see that the top label sometimes disappear

Edu
Newbie
Newbie
Posts: 44
Joined: Tue Nov 28, 2023 12:00 am

Re: Custom y axis labels

Post by Edu » Fri Feb 28, 2025 12:14 pm

Hello,

Thank you for providing the code sample. I was able to reproduce the issue successfully.

The problem occurs when the max value set using axis.SetMinMax(newMin, newMax); is slightly lower than the actual maximum value that should be displayed. This can happen even when the difference is very small—sometimes just a few units (e.g., 179 vs. 181) or even within the decimals (e.g., 73.91683473 vs. 73.92). In some cases, the difference appears beyond the 11th decimal place, causing the top label to be omitted.

One possible solution is to introduce a small tolerance when setting the max value to ensure it does not unintentionally exclude the top label. The appropriate tolerance depends on your project’s requirements, but a slight buffer (e.g., rounding up or adding a small margin) might resolve the issue.

Would this approach work for your use case? Let me know if you need further clarification.

Best regards,
Edu
Edu
Steema Support

Post Reply