Position setting of coordinate axis labels

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Mr.Hu_NotProSupport
Newbie
Newbie
Posts: 9
Joined: Fri Jan 29, 2010 12:00 am

Position setting of coordinate axis labels

Post by Mr.Hu_NotProSupport » Tue Oct 24, 2023 12:20 am

The above figure shows the position of the labels when Axis4. Labels. Angle=315

The following figure shows the position of the labels when Axis4. Labels. Angle=270

How to adjust the position of labels when Axis4. Labels. Angle=315 downwards and rightward
Attachments
2.png
2.png (25.48 KiB) Viewed 5963 times
1.png
1.png (22.68 KiB) Viewed 5963 times

Rubén
Newbie
Newbie
Posts: 18
Joined: Fri Nov 19, 2010 12:00 am

Re: Position setting of coordinate axis labels

Post by Rubén » Wed Oct 25, 2023 7:36 am

Hi,

Thanks for feedback. Which version of "TeeChart" and "Visual Studio" are you using?

Regards,
Ruben

Mr.Hu_NotProSupport
Newbie
Newbie
Posts: 9
Joined: Fri Jan 29, 2010 12:00 am

Re: Position setting of coordinate axis labels

Post by Mr.Hu_NotProSupport » Wed Oct 25, 2023 7:41 am

TeeChart: Steema TeeChart for .NET Source Code 2017 4.1.2017.02140
VS2019 [ VB.NET ]

Mr.Hu_NotProSupport
Newbie
Newbie
Posts: 9
Joined: Fri Jan 29, 2010 12:00 am

Re: Position setting of coordinate axis labels

Post by Mr.Hu_NotProSupport » Mon Nov 20, 2023 12:49 am

TeeChart: Steema TeeChart for .NET Source Code 2017 4.1.2017.02140
VS2019 [ VB.NET +.NET Framework 4.6.2 ]
I am a legitimate registered user of Steema TeeChart for NET Source Code 2017 4.1.2017.02140. I purchased this version for $2400 at that time. I have been asking for a month now. Can the official answer my question

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

Re: Position setting of coordinate axis labels

Post by Marc » Mon Nov 20, 2023 7:41 am

Hello,

Apologies for the delay replying. Currently, non-regular angles, (not 0,90,180,270), are not correctly rendering distance from the axis. We are reviewing the code related to this area.

Regards,
Marc Meumann
Steema Support

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

Re: Position setting of coordinate axis labels

Post by Marc » Tue Nov 21, 2023 6:15 pm

Hello,

The issue has been resolved (issues #2651]) and the solution will be included with the next TeeChart update.

I have ported this code back into the relevant method for the sourcecode version, 4.1.2017.02140, and although I am unable to test all possible usage scenarios for this version, it should work for you if you replace this entire method in the Axis.cs unit.:
DrawAxisLabel(ChartFont f, int x, int y, int angle, string st, TextShape format, bool isTitle)
Code for the method:

Code: Select all

    /// <summary>
    /// Draws Axis Label (string) in font f at specified X,Y co-ordinate at Angle.
    /// </summary>
#if WPF || SILVERLIGHT || STORE
    protected internal void DrawAxisLabel(ChartFont f, double x, double y, int angle, string st, TextShape format, bool isTitle)
#else
    protected internal void DrawAxisLabel(ChartFont f, int x, int y, int angle, string st, TextShape format, bool isTitle)
#endif
    {

      bool is3D = chart.aspect.view3D;

#if WPF || SILVERLIGHT || STORE
      TextAlignment tmpAlign, tmpAlign2;

      Drawing.Graphics3D g = chart.graphics3D;

      TextAlignment OldStrAlign = g.TextAlign;
#else
      StringAlignment tmpAlign, tmpAlign2;

      Drawing.Graphics3D g = chart.graphics3D;

      StringAlignment OldStrAlign = g.TextAlign;
#endif
      if (format == null)
        format = Labels;
      else
        f = format.Font;
      g.Font = f;

      int intHorizontal = horizontal ? 1 : 0;
      int intOtherSide = otherSide ? 1 : 0;
      int notIntOtherSide = otherSide ? 0 : 1;
      int tmpFontHeight = g.FontHeight;

#if WPF || SILVERLIGHT || STORE
      double tmpH = tmpFontHeight / 2;
      double tmpZ = iZPos; 
#else
      int tmpH = tmpFontHeight / 2;
      int tmpZ = iZPos;
#endif
      int n = NumTextLines(st);
      int delta = tmpFontHeight;

      if (horizontal && otherSide)
      {
        if ((isTitle) && (is3D) && (!chart.aspect.orthogonal))
          tmpZ = MaxLabelsWidth() + chart.aspect.Width3D;

        if ((angle > 90) && (angle <= 180))
        {
          y = isTitle ? y : y + delta;
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
        else if ((angle > 0) && (angle <= 90))
        {
          x = isTitle ? x : x - delta;
          if (!isTitle) x = x - (delta * (n) / 2);
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          else
          {
            y = y - this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            y = y - this.MaxLabelsWidth();
            tmpAlign = StringAlignment.Far;
#endif
          }
        }
        else if ((angle > 180) && (angle <= 270))
        {
          if (!isTitle) x = x + delta + (delta * (n) / 2);
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Far;
#endif
          else
          {
            y = y - this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          }
        }
        else
        {

          y = y - delta * (n + 1);
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
      }
      else if (horizontal)
      {
        if ((isTitle) && (is3D) && (!chart.aspect.orthogonal))
          tmpZ = -MaxLabelsWidth();

        if ((angle > 90) && (angle <= 180))
        {
#if WPF || SILVERLIGHT || STORE || PORTABLE
          tmpAlign = TextAlignment.Center;
#else
          if (Labels.Align == AxisLabelAlign.Default)
          {
            tmpAlign = StringAlignment.Far;
          }
          else
          {
            y += MaxLabelsWidth();
            tmpAlign = StringAlignment.Near;
          }
#endif
        }
        else if ((angle > 0) && (angle <= 90))
        {
          x = x - delta;
          x = x - (delta * (n) / 4);
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          else
          {
            y = y + this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          }
        }
        else if ((angle > 180) && (angle <= 270))
        {
          x = x + delta + (delta * (n) / 2);
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          else
          {
            y = y + this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          }
        }
        else if (angle == 0)
        {
          y = y - delta;
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
        else
        {
#if iOS
            if (!isTitle)
#endif
#if WPF || SILVERLIGHT || STORE || PORTABLE
                    tmpAlign = TextAlignment.Center;
#elif ANDROID
          tmpAlign = Android.Graphics.Paint.Align.Center;
#elif iOS
          tmpAlign = CTTextAlignment.Center; 
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
      }
      else if (otherSide)
      {
        if ((isTitle) && (is3D) && (!chart.aspect.orthogonal))
          tmpZ = chart.aspect.Width3D + MaxLabelsWidth();

        if (angle == 0)
        {
          y -= delta;
          y -= (delta * (n)) / 2;
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          else
          {
            x = x + this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          }
        }
        else if ((angle > 270) && (angle < 360))
        {
          tmpAlign = StringAlignment.Center;
        }
        else if ((angle > 90) && (angle <= 180))
        {
          y += delta;
          y += (delta * (n)) / 2;
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          else
          {
            x = x + this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          }
        }
        else if ((angle > 0) && (angle <= 90))
        {
          x -= delta;
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
        else
        {
          x += delta * (n + 1);
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
      }
      else
      {
        if ((isTitle) && (is3D) && (!chart.aspect.orthogonal))
          tmpZ = -MaxLabelsWidth();

        if (((angle > 270) && (angle <= 360)) || (angle == 0))
        {
          y -= delta;
          y -= (delta * (n)) / 2;
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          else
          {
            x = x - this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          }
        }
        else if ((angle > 270) && (angle <= 360))
        {
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          else
          {
            x = x - this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          }
        }
        else if ((angle > 90) && (angle <= 180))
        {
          y += delta;
          y += (delta * (n)) / 2;
          if (this.Labels.Align == AxisLabelAlign.Default)
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Left;
#else
            tmpAlign = StringAlignment.Near;
#endif
          else
          {
            x = x - this.MaxLabelsWidth();
#if WPF || SILVERLIGHT || STORE
            tmpAlign = TextAlignment.Right;
#else
            tmpAlign = StringAlignment.Far;
#endif
          }
        }
        else if ((angle > 0) && (angle <= 90))
        {
          x -= delta * (n + 1);
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
        else
        {
          x += delta;
#if WPF || SILVERLIGHT || STORE
          tmpAlign = TextAlignment.Center;
#else
          tmpAlign = StringAlignment.Center;
#endif
        }
      }


      int tmpNum;
      int tmpSize = Utils.Round(g.TextWidth("W") / 4.0F);  //4 instead 2 so the margin don't be so high

      format.Left = x;

      format.Top = y + delta;

#if WPF || SILVERLIGHT || STORE
      double tmpW = chart.MultiLineTextWidth(st, out tmpNum, format.TextFormat == TextFormat.Html);
#else
      int tmpW = chart.MultiLineTextWidth(st, out tmpNum, format.TextFormat == TextFormat.Html);
#endif
      tmpH = tmpFontHeight * tmpNum;

      tmpAlign2 = tmpAlign;

      format.Bottom = format.Top + tmpH;
      format.Right = format.Left + tmpW;

#if WPF || SILVERLIGHT || STORE
      if (tmpAlign2 == TextAlignment.Right)
#else

      if (tmpAlign2 == StringAlignment.Far)
#endif
      {
        format.Right = format.Left;
        format.Left = format.Right - tmpW;
      }
#if WPF || SILVERLIGHT || STORE
      else if (tmpAlign2 == TextAlignment.Center)
#else

      else if (tmpAlign2 == StringAlignment.Center)
#endif
      {
        tmpW = (format.Right - format.Left) / 2;
        format.Right -= tmpW;
        format.Left -= tmpW;
      }



      format.Left -= tmpSize;
      format.Right += tmpSize / 2;


      if (tmpZ != 0) format.ShapeBounds = g.CalcRect3D(format.ShapeBounds, tmpZ);

#if !WPF && !SILVERLIGHT && !STORE
      int tmpFT = format.Top;
      int tmpFH = format.Height;
#else
      double tmpFT = format.Top;
      double tmpFH = format.Height;
#endif
      bool tmpDraw = true;

      g.TextAlign = tmpAlign;

      int tmpD = delta * n;

      string tmpSt = st;
      int i;
      string tmpSt2 = "";

#if VS2005 && !WPF && !SILVERLIGHT && !REPORTINGSERVICES && !POCKET && !CLIENTPROFILE && !STORE

      if ((horizontal) && ((this.chart.Tools.Count > 0) && (hasScrollTool())))
        g.ClipRectangle(CalcXPosValue(minimumValue), 0,
                        CalcXPosValue(maximumValue), Chart.Height);
#endif
      DoGetAxisDrawLabel(this, ref x, ref y, ref tmpZ, ref tmpSt, ref tmpDraw);

      if (tmpDraw) n = NumTextLines(tmpSt);

      if (tmpDraw)
      {
        for (int tt = 1; tt <= n; tt++)
        {

          double tmpAngle = format.Width / 2;

          if (OtherSide)
            tmpAngle = tmpAngle - 0.25 * format.Height;

          double tmpYDisp = tmpAngle * Math.Abs(Math.Sin(Utils.Deg2Rad(angle)));

          if (angle > 0)
          {
            format.Bottom = tmpFT;

            format.Top = tmpFT + (int)tmpYDisp; // - tmpFH;

            if ((angle >= 0) && (angle <= 90))
            {
#if iOS
              if (!isTitle)
#endif
              if (angle == 90)
                x += delta - (tmpFontHeight / 4);
              else
                x += delta - (int)(tmpFontHeight / 4 * Math.Abs(Math.Sin(Utils.Deg2Rad(angle))));

              format.Left += delta;
              format.Right += delta;
            }
            else if ((angle > 90) && (angle <= 180))
            {
              if (angle == 180)
                x -= format.Width / 2;
              else
                x -= (int)(tmpFontHeight / 2 * Math.Abs(Math.Sin(Utils.Deg2Rad(angle))));

              y += (int)(tmpFontHeight * Math.Abs(Math.Cos(Utils.Deg2Rad(angle))));

              format.Left += delta;
              format.Right += delta;
            }
            else if ((angle > 180) && (angle <= 270))
            {
              x -= delta;

                            y += (int)(tmpFontHeight * Math.Abs(Math.Cos(Utils.Deg2Rad(angle))));

              format.Left -= delta;
              format.Right -= delta;
            }
            else if ((angle > 270) && (angle < 360))
            {
              x += (int)(format.Width / 2 * Math.Abs(Math.Cos(Utils.Deg2Rad(angle))));
              y += (int)(format.Width / 2 * Math.Abs(Math.Sin(Utils.Deg2Rad(angle))));

              format.Top += delta;
              format.Bottom += delta;
            }
          }

          if (!format.Transparent || hasClicked)
          {
#if SILVERLIGHT || WPF || STORE
            if (angle > 0)
            {
              RotateTransform rotate = new RotateTransform();
              rotate.Angle = 360 - angle;
              rotate.CenterX = x;
              rotate.CenterY = y;

              double tmpFW = format.Width;

              format.Left += tmpFW / 2.0;
              format.Right += tmpFW / 2.0;

#if STORE
              format.ShapePolygonBounds = new Point[] { rotate.TransformPoint(new Point(format.ShapeBounds.Left, format.ShapeBounds.Top)),
              rotate.TransformPoint(new Point(format.ShapeBounds.Right, format.ShapeBounds.Top)),
              rotate.TransformPoint(new Point(format.ShapeBounds.Right, format.ShapeBounds.Bottom)), 
              rotate.TransformPoint(new Point(format.ShapeBounds.Left, format.ShapeBounds.Bottom)), 
              rotate.TransformPoint(new Point(format.ShapeBounds.Left, format.ShapeBounds.Top))};
#else
              format.ShapePolygonBounds = new Point[] { rotate.Transform(new Point(format.ShapeBounds.Left, format.ShapeBounds.Top)),
              rotate.Transform(new Point(format.ShapeBounds.Right, format.ShapeBounds.Top)),
              rotate.Transform(new Point(format.ShapeBounds.Right, format.ShapeBounds.Bottom)), 
              rotate.Transform(new Point(format.ShapeBounds.Left, format.ShapeBounds.Bottom)), 
              rotate.Transform(new Point(format.ShapeBounds.Left, format.ShapeBounds.Top))};
#endif
              g.Brush = format.Brush;
              g.Pen = format.Pen;
              g.Polygon(format.ShapePolygonBounds);
            }
            else
            {
              format.DrawRectRotated(g, format.ShapeBounds, 0, tmpZ);
            }
#elif !POCKET

            Matrix m = g.GDIplusCanvas.Transform;
            m.RotateAt((float)(360 - angle), new Point(x, y));

            g.GDIplusCanvas.MultiplyTransform(m);
            format.DrawRectRotated(g, format.ShapeBounds, 0, tmpZ);

            format.ShapePolygonBounds = new Point[] { new Point(format.ShapeBounds.Left, format.ShapeBounds.Top), new Point(format.ShapeBounds.Right, format.ShapeBounds.Top),
                new Point(format.ShapeBounds.Right, format.ShapeBounds.Bottom), new Point(format.ShapeBounds.Left, format.ShapeBounds.Bottom), new Point(format.ShapeBounds.Left, format.ShapeBounds.Top)};

            m.TransformPoints(format.ShapePolygonBounds);
            g.GDIplusCanvas.ResetTransform();
#endif
            labels.labelPos.Add(format.ShapePolygonBounds);
          }
          else
          {
            labels.labelPos.Add(format.ShapeBounds);
          }

          i = tmpSt.IndexOf(Texts.LineSeparator);

          tmpSt2 = (i != -1) ? tmpSt.Substring(0, i) : tmpSt;

          if (angle == 0)
          {
            y += delta;
            g.Font = f;
            if (labels.Exponent)
              DrawExponentLabel(x, y, tmpZ, tmpSt2, angle);
            else if (is3D)
              g.TextOut(x, y, tmpZ, tmpSt2, format.TextFormat == TextFormat.Html);
            else
              g.TextOut(f, x, y, tmpSt2, format.TextFormat == TextFormat.Html);
          }
          else
          {
            if (labels.Exponent && (angle == 90 || angle == 270))
            {
              DrawExponentLabel(x, y, tmpZ, tmpSt2, angle);
            }
            else
            {
              g.RotateLabel(x, y, tmpZ, tmpSt2, angle, format.TextFormat == TextFormat.Html);
            }
          }

          if (i >= 0) tmpSt = tmpSt.Remove(0, i + 1);
        }
      }

      g.TextAlign = OldStrAlign;
    }
Alternatively, you can upgrade to the latest version of TeeChart to access the modification directly.

Regards,
Marc Meumann
Steema Support

Post Reply