【问题标题】:C# - scroll down a Chart without first ChartAreaC# - 向下滚动没有第一个 ChartArea 的图表
【发布时间】:2017-09-18 07:50:50
【问题描述】:

我想要的结果是一个主图表和几个与主图表同步的子图表。 (子图表必须与主图表共享相同的 x 轴。)

起初,我尝试使用多个chartAreas。我可以将子chartAreas 与主chartArea 同步。 (使用这个:How to align two (or more) charts in size, scroll and grid)这正是我想要的。但我不能只垂直滚动 sub-chartAreas。如果我滚动,所有图表都会滚动。我只想垂直滚动子chartAreas。 (即使滚动条向下,也可以随时在顶部显示主要的chartArea

所以,我推翻了使用多个图表(不是图表区域)的决定。我可以将它们放入 TableLayoutPanel。每行一张图表。然后,我无法同步他们的 x 轴...

有什么方法可以将 x 轴与多个图表同步? 还是使用多个chartAreas 只滚动子chartAreas?

“滚动”是指垂直滚动。见这里:

【问题讨论】:

  • 嗯,您希望它们对齐但独立滚动它们吗?这不只是意味着您需要保持 x 轴的比例相等吗?
  • 抱歉表达不明确。我的意思是,我希望所有人都对齐。我想(一次)滚动除第一个图表区域之外的其他内容。我不确定什么是“简单地保持比例”,但我想要的是上面链接中的答案 gif。
  • 如果你想让一个(主)图表区域保持不变,那就不要在AxisViewChanged 事件中为它编写代码!
  • 按比例我的意思基本上是轴上显示的数据量。您可以通过设置最小值和最大值来控制它。放大后就是.ScaleView.ViewMinimum&Maximum。
  • 糟糕,您认为“滚动”是水平的,对吧?我没有具体说明。我很抱歉...滚动是垂直滚动。我用快照更新了我的问题。

标签: c# winforms scroll mschart


【解决方案1】:

根据我收集的图像和 cmets,您实际上想要向下滚动包含多个 ChartArea 的图表,但将一个固定在顶部。

((如果是这样,您应该更正问题标题!))

默认情况下,Chart 只能滚动缩放 ChartArea 内的数据,不能滚动Chart 内的多个ChartAreas

这是一个伪造ChartArea 滚动冻结顶部ChartArea的示例。

以下是必要的步骤:

  • 我们需要一个 VerticalScrollbar 控件并将其锚定在图表的右侧。

  • 我们需要将其最小和最大字段设置为合适的值;我将最小值留在0 并用几个参数计算最大值..

  • 然后我们可以编码它的Scroll事件..:


private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
    float h = (100 - yOffTop - yOffBottom) / visibleCount;
    ChartArea main = chart1.ChartAreas[0];

    for (int i = 1; i < chart1.ChartAreas.Count; i++)
    {
        ChartArea ca = chart1.ChartAreas[i];
        ca.Position = new ElementPosition(0, h * i - vScrollBar1.Value + mainExtra, 80, h);
        ca.Visible = ca.Position.Y  >= main.Position.Bottom ;
    }
}

visibleCount 控制有多少 ChartAreas 可见。在这个例子中,我有一个年度,固定在顶部,另外 12 个月份......:

为此,您需要设置图表,以便图表区域以合适的方式初始化。

我使用了这段代码,请使用您自己的代码来处理右侧空间(我为图例留出 20%)等内容:

    int visibleCount = 5;
    float yOffTop = 0;     // no extra top space for a chart title
    float yOffBottom = 0;  // no extra  bottom space either
    float mainExtra = 6;   // a few extra% for the main CA's axis labels

    private void Init_button_Click(object sender, EventArgs e)
    {
        chart1.Series.Clear();
        chart1.ChartAreas.Clear();
        chart1.BackColor = Color.Snow;
        float h = (100 - yOffTop - yOffBottom) / visibleCount;
        for (int i = 0; i < 13; i++)
        {
            float yOff = i != 0 ? mainExtra : 0;
            float yExtra = i == 0 ? mainExtra : 0;
            ChartArea ca = chart1.ChartAreas.Add("ca" + i);
            ca.Position = new ElementPosition(0, h * i + yOff , 80, h + yExtra);
            ca.BackColor = Color.FromArgb(i * 20, 255 - i * 3, 255);
            ca.AxisX.IntervalOffset = 1;

            Series s = chart1.Series.Add("s" + i);
            s.ChartArea = ca.Name;
            for (int j = 1; j < 30; j++)
            {
                s.Points.AddXY(j, rnd.Next(100) - rnd.Next(20));
            }
            chart1.ChartAreas[0].BackColor = Color.Silver;
            ca.AxisY.Title = i == 0 ? "Year" :
                                       DateTimeFormatInfo.CurrentInfo.GetMonthName(i);
            ca.AxisX.Enabled = (i == 0) ? AxisEnabled.True :  AxisEnabled.False;
        }
        vScrollBar1.Minimum = 0;// (int)( h);
        vScrollBar1.Maximum = (int)((chart1.ChartAreas.Count - visibleCount + 0.5f) * h
                                   + mainExtra );
    }

我在每个 CA 周围画了额外的矩形,只是为了测试;请忽略它们!

注意:使用这些百分比总是有点棘手,可能需要一些调整!

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    相关资源
    最近更新 更多