C# - 在没有第一个 ChartArea 的情况下向下滚动图表
C# - scroll down a Chart without first ChartArea
我要的结果是一张主图和几张与主图同步的子图。 (子图表必须与主图表共享相同的 x 轴。)
起初,我尝试使用多个chartAreas
。我可以将子 chartAreas
与主 chartArea
同步。 (使用这个:)这个正是我想要的。但我不能只 垂直 滚动子 chartAreas
。如果我滚动,所有图表都会滚动。我只想垂直滚动 sub-chartAreas
。 (即使滚动条向下,也可以随时在顶部显示主要 chartArea
)
所以,我推翻了使用多个图表(不是图表区域)的决定。我可以将它们放入 TableLayoutPanel 中。每行一个图表。然后,我无法同步他们的 x 轴...
有什么方法可以将一个 x 轴与多个图表同步吗?
或者使用多个 chartAreas 只滚动子 chartAreas?
'scroll' 我的意思是垂直滚动。看这里:
根据我收集到的图像和评论,您实际上想要向下滚动包含多个 ChartArea
的图表,但将其中一个固定在顶部。
((如果是这样你应该更正问题标题!))
默认一个Chart
只能滚动一个zoomedChartArea
内的数据,不能滚动Chart
内的几个ChartAreas
].
这是一个伪造 ChartArea
滚动 和 冻结 顶部 ChartArea
的示例。
以下是必要的步骤:
我们需要一个 VerticalScrollbar 控件并将其锚定在图表的右侧。
我们需要将其Minumum和Maximum字段设置为合适的值;我将最小值保留在 0
并使用一些参数计算最大值..
然后我们可以编写它的Scroll
事件..:[=23=]
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 个月份..:[=23=]
为此,您需要设置图表,以便以合适的方式初始化图表区域。
我使用了这段代码,请使用您自己的代码来处理右边的内容 space(我为图例留了 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 周围画了额外的矩形,只是为了测试;不要理会他们!
注意:使用这些百分比总是有点棘手,可能需要进行一些调整!
我要的结果是一张主图和几张与主图同步的子图。 (子图表必须与主图表共享相同的 x 轴。)
起初,我尝试使用多个chartAreas
。我可以将子 chartAreas
与主 chartArea
同步。 (使用这个:chartAreas
。如果我滚动,所有图表都会滚动。我只想垂直滚动 sub-chartAreas
。 (即使滚动条向下,也可以随时在顶部显示主要 chartArea
)
所以,我推翻了使用多个图表(不是图表区域)的决定。我可以将它们放入 TableLayoutPanel 中。每行一个图表。然后,我无法同步他们的 x 轴...
有什么方法可以将一个 x 轴与多个图表同步吗? 或者使用多个 chartAreas 只滚动子 chartAreas?
'scroll' 我的意思是垂直滚动。看这里:
根据我收集到的图像和评论,您实际上想要向下滚动包含多个 ChartArea
的图表,但将其中一个固定在顶部。
((如果是这样你应该更正问题标题!))
默认一个Chart
只能滚动一个zoomedChartArea
内的数据,不能滚动Chart
内的几个ChartAreas
].
这是一个伪造 ChartArea
滚动 和 冻结 顶部 ChartArea
的示例。
以下是必要的步骤:
我们需要一个 VerticalScrollbar 控件并将其锚定在图表的右侧。
我们需要将其Minumum和Maximum字段设置为合适的值;我将最小值保留在
0
并使用一些参数计算最大值..然后我们可以编写它的
Scroll
事件..:[=23=]
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 个月份..:[=23=]
为此,您需要设置图表,以便以合适的方式初始化图表区域。
我使用了这段代码,请使用您自己的代码来处理右边的内容 space(我为图例留了 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 周围画了额外的矩形,只是为了测试;不要理会他们!
注意:使用这些百分比总是有点棘手,可能需要进行一些调整!