对齐左右垂直轴

时间:2018-01-31 09:57:48

标签: c# teechart

我有一个系列连接到左垂直轴,另一个连接到右垂直轴。如何在两个轴上对齐TicksGrids

原始状态:
Original state

如您所见,垂直轴的网格线位于不同的位置。我想如果我在两侧设置相同数量的刻度,它可以对齐网格。我使用这段代码:

private void AlignAxes()
{
   if (tChart1.Axes.Left.CalcIncrement != 0)
   {
      var ticksNum = (tChart1.Axes.Left.Maximum - tChart1.Axes.Left.Minimum) / 
                     tChart1.Axes.Left.CalcIncrement;
      tChart1.Axes.Right.Increment = 
                     (tChart1.Axes.Right.Maximum - tChart1.Axes.Right.Minimum) / ticksNum;
   }
}

但它没有按预期工作:
Unsuccessful try
我想有这样的事情:
Desired state
但显然有正确计算和对齐的值。

1 个答案:

答案 0 :(得分:0)

<强>解释
我尝试了几乎所有可以想象到的东西并找到了解决方案(尽我所能)。结果至少对我来说足够好了。
我尝试的每一项计算都不是100%正常工作。如果自动创建标签,则Axis.Labels.Items没有项目。最后,我发现存在名为ArrayList的私有labelPos,并且标签应该有矩形。所以我必须使用System.Reflection来获取此列表。从该矩形的位置然后计算另一个y轴上的值并将它们作为自定义标签插入。

代码:

private bool _redrawAgain = false;

private void AlignAxes()
{
    if (_redrawAgain)
    {
        _redrawAgain = false;
    }
    else
    {
        _redrawAgain = true;
        var tmpl = new AxisLabels(tChart1.Axes.Left);
        var privateField = tmpl.GetType().GetField("labelPos", 
                           BindingFlags.NonPublic | BindingFlags.Instance);
        var labelPos = (ArrayList)privateField.GetValue(tChart1.Axes.Left.Labels);

        tChart1.Axes.Right.Labels.Items.Clear();

        for (var i = 0; i < labelPos.Count; i++)
        {
            var rect = (Rectangle)labelPos[i];
            tChart1.Axes.Right.Labels.Items.Add(
                              tChart1.Axes.Right.CalcPosPoint(rect.Y + (rect.Height / 2)));
        }

        tChart1.Axes.Right.Grid.DrawEvery = tChart1.Axes.Left.Grid.DrawEvery;

        tChart1.Refresh();
    }
}

我从AlignAxes();事件中调用了TChart.AfterDraw,所以我必须再次刷新图表,但如果没有刷新我尝试过的任何图表事件,我就无法正常工作。
当在运行时切换轴并且即使左轴没有任何内容时,此代码也有效,因为它只是从右轴清除自定义标签并让库关注标签。

<强>结果:
Chart with only one grid
我唯一无法解决的问题是MinimumOffsetMaximumOffset,但我认为它在TeeChart库中被破坏了。我在两个轴上都将偏移设置为10,并且在显示图表时它们会正确显示,但在缩放或滚动后,右轴上的标签会随着偏移消失而在左轴上消失,就好像有偏移是设置为0.您可以在x轴附近的y轴上的图像上看到这种奇怪的行为 - 右轴上没有标签,左边有标签。

<强>更新
我也想拥有轴标题,所以我不得不像这样更新代码:

private void AlignAxes(Graphics3D g)
{
    if (_redrawAgain)
    {
        _redrawAgain = false;
    }
    else
    {
        _redrawAgain = true;
        var tmpl = new AxisLabels(tChart1.Axes.Left);
        var privateField = tmpl.GetType().GetField("labelPos", 
                           BindingFlags.NonPublic | BindingFlags.Instance);
        var labels = (ArrayList)privateField.GetValue(tChart1.Axes.Left.Labels);

        tChart1.Axes.Right.Labels.Items.Clear();

        var gratestWidth = 0;

        for (var i = 0; i < labels.Count; i++)
        {
            var rect = (Rectangle)labels[i];
            tChart1.Axes.Right.Labels.Items.Add(
                              tChart1.Axes.Right.CalcPosPoint(rect.Y + (rect.Height / 2)));
            var width = g.MeasureString(tChart1.Axes.Right.Labels.Font, 
                        tChart1.Axes.Right.Labels.Items
                        [tChart1.Axes.Right.Labels.Items.Count - 1].
                        Value.ToString(
                        tChart1.Axes.Right.Labels.ValueFormat)).
                        ToSize().Width;
            if (width > gratestWidth)
            {
                gratestWidth = width;
            }
        }

        if (labels.Count > 0)
        {
            tChart1.Axes.Right.Labels.CustomSize = gratestWidth + 10;
        }
        else
        {
            tChart1.Axes.Right.Labels.CustomSize = 0;
        }

        tChart1.Axes.Right.Grid.DrawEvery = tChart1.Axes.Left.Grid.DrawEvery;

        tChart1.Refresh();
    }
}  

我必须自己计算标签的宽度,否则会有另一个图表刷新。