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

时间:2018-04-18 08:13:26

标签: c# teechart

我在x轴上遇到自定义标签问题。如果我加点[10; 1] [20; 2] [30; 3] [40; 4] [50; 5] [60; 6] [70; 7] [80; 8] [90; 9]标签,x轴看起来像这样:
correct x axis
如果我添加标签[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;我]我得到了这个:
enter image description here

如果我将点数更改为[100; 1] [200; 2] [300; 3] [400; 4] [500; 5] [600; 6] [700; 7] [800; 8] [ 900; 9]我得到:
enter image description here
如果我添加标签[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;我]我得到:
enter image description here

我尝试使用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的代码,经过一些修改后它就可以了。不知何故。因为,只有在我不使用缩放功能时才有效。而且我必须使用变焦,这对我来说并不好。我尝试做一些更多的修改,但对于像这样的东西来说它真的很难看......

2 个答案:

答案 0 :(得分:0)

我建议您使用自定义标签,使用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());
            }


        }

希望这对您有所帮助,否则请不要犹豫与我们联系。

提前致谢

此致

桑德拉

答案 1 :(得分:0)

我终于找到了一些适合我需要的解决方案。不是我想要的,但不知怎的......

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

限制

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

功能

  • 您可以使用缩放和平移功能。
  • 标签之间的空间更大(两侧+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;
    }