Page 1 of 1

Custom y axis labels

Posted: Thu Feb 27, 2025 7:37 am
by 21099317
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.

Re: Custom y axis labels

Posted: Thu Feb 27, 2025 9:17 am
by Marc
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

Re: Custom y axis labels

Posted: Thu Feb 27, 2025 11:21 am
by 21099317
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

Re: Custom y axis labels

Posted: Fri Feb 28, 2025 12:14 pm
by edu
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