x 轴上自定义标签的奇怪行为

Strange behaviour with custom labels on x axis

我对 x 轴上的自定义标签有疑问。如果我添加点 [10;1][20;2][30;3][40;4][50;5][60;6][70;7][80;8][90;9] 没有标签,x 轴如下所示:

如果我用标签 [10;1;A][20;2;B][30;3;C][40;4;D][50;5;E][60;6;F][70 ;7;G][80;8;H][90;9;I] 我明白了:

如果我将分数更改为 [100;1][200;2][300;3][400;4][500;5][600;6][700;7][800;8 ][900;9] 我得到:

如果我添加标签 [100;1;A][200;2;B][300;3;C][400;4;D][500;5;E][600;6;F][700;7 ;G][800;8;H][900;9;I] 我得到:

我尝试使用 Add(double x, double y, string text) 以及 DataSourceLabelMember 添加带有点的标签 - 两者的结果相同。如您所见,所有数字都显示在那里应该没有问题(在这两种情况下,标签数量实际上是可见数字的一半)。
正如您所看到的,根据数字之间的实际差异,可见的标签数量也不同——如果差异为 10,则显示 2 个标签和一些刻度,但如果差异为 100,则只有第一个标签没有任何其他标签标签甚至刻度。
如果差异为 1,我可以看到所有自定义标签(在此轴宽度上)。

对于这个例子,我使用了这个代码:

var serie = new Line(tChart1.Chart);
for (var i = 1; i < 10; i++)
{
    serie.Add(i * 10, i, ((char)(64 + i)).ToString()); //points with labels
    //serie.Add(i * 10, i); //points without labels
}

编辑
我尝试了 GetAxisLabels 事件,但它仅针对已显示的标签触发,因此如果我想显示更多标签,我将无法更改。
我还尝试手动将标签添加到底轴,但如果标签足够宽,它们就会开始重叠,所以我尝试了 here 中的代码,经过一些修改后它起作用了。不知何故。因为,它只有在我不使用缩放功能时才有效。而且我必须使用变焦,所以这对我不利。我试着做一些更多的修改,但对于这样的东西来说,这将是非常难看的代码...

我想建议您使用自定义标签,使用 GetAxisLabels 事件或将新项目添加到底部轴。
请参阅下面的两种方法:

GetAxisLabels 事件:

private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;

            tChart1.Dock = DockStyle.Fill;
            Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
            rnd = new Random();
            for (int i = 0; i < 10; i++)
            {
                                line1.Add(i * 10, i); //points without labels
                        }

            tChart1.GetAxisLabel += TChart1_GetAxisLabel;

            tChart1.Axes.Bottom.Labels.Style = Steema.TeeChart.AxisLabelStyle.Text;
        }

        private void TChart1_GetAxisLabel(object sender, Steema.TeeChart.GetAxisLabelEventArgs e)
        {
            if (sender == tChart1.Axes.Bottom)
            {
                if (e.ValueIndex != -1)
                {
                    e.LabelText = ((char)(64 + e.ValueIndex)).ToString();
                }
            }
        }

将项目添加到底轴:

private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;

            tChart1.Dock = DockStyle.Fill;
            Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
            rnd = new Random();
            for (int i = 0; i < 10; i++)
            {
                line1.Add(i * 10, i); //points without labels
            }

            //tChart1.GetAxisLabel += TChart1_GetAxisLabel;
            tChart1.Axes.Bottom.Labels.Items.Clear();
            for (int i = 0; i < line1.Count; ++i)
            {
                tChart1.Axes.Bottom.Labels.Items.Add(line1.XValues[i], ((char)(64 + i)).ToString());
            }


        }

我终于找到了适合我需要的一切的解决方案。不完全如我所愿,但不知何故......

我只需要处理底轴,所以我从 johnk 中获取代码并根据需要进行更改。
我删除了与下一个标签的比较并改变了方式,我如何找到正确的标签索引。
TeeChart 有一些不愉快的问题(例如标签使用与我预期不同的 Font - tChart1.Graphics3D.Font 而不是 axis.Labels.Font - e.LabelValue 总是0).所以如果你想做一些改变,请记住这些问题。下面是我的,不完美但或多或少工作的解决方案:

限制

  • 仅适用于水平轴。
  • 仅适用于不同的标签文本。
  • 有时显示的标签与未显示的标签数量不同。

特征

  • 您可以使用缩放和平移功能。
  • 标签之间更大 space(两侧 +3 像素)。
  • 许多标签的网格线数量较少。

代码
辅助词典

//Label index and true, if the label is visible.
private Dictionary<int, bool> _visibleLabels = new Dictionary<int, bool>();

正在重置字典

private void TChart1_BeforeDrawAxes(object sender, Graphics3D g)
    {
        //Clear shown labels before showing axis.
        _visibleLabels.Clear();
    }

选择可见标签

private void GetAxisDrawLabel(object sender, GetAxisDrawLabelEventArgs e)
    {
        bool overlapPrv = false;            
        Axis axis = (Axis)sender;

        //Get the size of the label text. We have to use tcharts font, not axis font.
        SizeF currentSize = tChart1.Graphics3D.MeasureString(tChart1.Graphics3D.Font, e.Text);
        Rectangle currentRect = new Rectangle(e.X - 3, e.Y, (int)currentSize.Width + 6, (int)currentSize.Height);

        var index = FindLabel(tChart1.Axes.Bottom.Labels.Items, e.Text);

        //Get the AxisLabelItem we are trying to draw.
        AxisLabelItem currentLabel = axis.Labels.Items[index];

        //If we set visible to false before GetAxisDrawLabel then set e.DrawLabel to false.
        if (currentLabel.Visible == false)
        {
            _visibleLabels.Add(index, false);
            e.DrawLabel = false;
        }

        //Get the previous visible label.
        AxisLabelItem prev = null;
        var prevPair = _visibleLabels.LastOrDefault(x => x.Value == true);
        var prevIndex = -1;

        if (prevPair.Value)
        {
            prevIndex = prevPair.Key;

            tChart1.Axes.Bottom.Grid.DrawEvery = index - prevIndex;
        }
        else
        {
            //Current label is the first visible label.
            _visibleLabels.Add(index, true);
            e.DrawLabel = true;
            return;
        }

        if (prevIndex >= 0)
        {
            prev = axis.Labels.Items[prevIndex];
        }

        //If this axis is horizontal then the concern is the width of the label.
        //If there is no previous label, we draw this one.
        //TODO implementation for the vertical.
        if (axis.Horizontal == true && prev != null)
        {
            //if previous is visible we need to see if it will overlap with the current.
            if (prev.Visible == true)
            {
                //Get the previous labels text size.
                SizeF prevSize = tChart1.Graphics3D.MeasureString(tChart1.Graphics3D.Font, prev.Text);
                //Get the previous label rectangle.
                Rectangle prvRect = new Rectangle(
                   axis.CalcXPosValue(prev.Value) - 3, e.Y, (int)prevSize.Width + 6, (int)prevSize.Height);
                //Set the overlapPrv flag by checking IntersectsWith
                overlapPrv = currentRect.IntersectsWith(prvRect);
            }

            //if any overlap or if e.DrawLabel is false set e.DrawLabel to false.
            if (overlapPrv || e.DrawLabel == false)
            {
                _visibleLabels.Add(index, false);
                e.DrawLabel = false;
            }
            else
            {
                _visibleLabels.Add(index, true);
            }
        }
    }

找到正确的标签索引

private static int FindLabel(AxisLabelsItems items, string labelText)
    {
        for (var i = 0; i < items.Count; i++)
        {
            if (items[i].Text == labelText)
            {
                return i;
            }
        }

        return -1;
    }