我正在Visual Studio 2013中使用Chart类来可视化一些数据。但是,我的数据很快产生了许多系列,将所有这些都放在一张图表中非常重要。我将图例区域限制为整个图表区域的20%,因此当我将图表拉伸到最大尺寸时,我几乎不能显示超过7-8个图例项。控件仅在将图例项用完之后才放...。
而不是仅仅写...,是否可以在图例中添加滚动条并能够查看所有项目?我知道我可以通过某种方式实现自己的图例,但我想从Chart类提供的内容中获得最大的收益。我还想在每个图例项旁边添加复选框,以指示该系列是否应该在图表上隐藏。如果没有我自己的图例实现,这有可能吗?
此外,我还想在右键单击图例项目时扩展菜单,其中有几个选项,但这是完全可选的。滚动条和复选框是我现在的主要问题。
谢谢。
总体思路:您必须创建两个图表。一个是主要的,第二个仅用于传奇。如果系列顺序相同,您将具有相同的系列样式。
要显示弹出窗口,请右键单击图例项目:
将ContextMenu(工具箱中的ContextMenuStrip类)连接到图例的图表。
用于显示图例的隐藏系列:
您必须实现MouseClick
事件处理程序,并使用数学GetChildAtPoint()
方法检查鼠标光标下的对象(该方法不适用于图例项目)。公式:是series_index = control_relative_mouse_y / c_legendItemHeight
这里c_legendItemHeight
是您所提供的计算控制高度(图例项目的高度)值。您必须将图例图表配置为包含LegendStyle
到Row
,MaximumAutoSize
到100
,Docking
到Left
,IsTextAutoFit
到false
和IsEquallySpacedItems
到true
。您在图例中定义了3列(一列用于系列样式,第二列用于复选框,第三列用于系列名称)。使用系列CustomProperties
保持可见性状态。在检查列中使用此自定义属性(文本="#CUSTOMPROPERTY(...)"
)以显示检查状态。图表不支持自动调整大小。您可以手动执行。在系列加载期间,将图表高度设置为计算值。该值等于_stock.Shares.Count * c_legendItemHeight + 9
。其中:_stock.Shares.Count
是图例中的项目数,项目的c_legendItemHeight
高度恒定(整数值,大于18的数字似乎对我有用),9
(似乎是恒定的)。我知道这不好,但找不到更好的解决方案。我在示例中添加了502系列,效果很好。确保图表中没有任何边距,否则将无法正确计算序列号。
对于“传奇中的许多系列”问题:
将图例图表放到启用了AutoScroll属性的面板中。使用上面描述中的表达式设置面板和图例的高度。
源代码:
public partial class Form1 : Form
{
private const int c_legendItemHeight = 20;
private const string c_checkCustomPropertyName = "CHECK";
private const string c_checkedString = "✔"; // see http://www.edlazorvfx.com/ysu/html/ascii.html for more
private const string c_uncheckedString = "✘";
private Stock _stock;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_stock = Stock.Load();
// mainChart
mainChart.Legends.Clear();
foreach (Share share in _stock.Shares)
{
Series series = mainChart.Series.Add(share.Name);
series.ChartType = SeriesChartType.Line;
foreach (ShareQuotation shareQuotation in share.Quotations)
{
series.Points.AddXY(shareQuotation.Date.ToString(), shareQuotation.Close);
}
}
// LegendChart
Legend legend = legendChart.Legends[0];
legendChart.Series.Clear();
legend.IsTextAutoFit = false;
legend.IsEquallySpacedItems = true;
legend.MaximumAutoSize = 100;
legend.Docking = Docking.Left;
legend.LegendStyle = LegendStyle.Column;
legend.Position.Auto = true;
legend.Position.Width = 100;
legend.Position.Height = 100;
legend.CellColumns[1].Text = "#CUSTOMPROPERTY(" +c_checkCustomPropertyName+ ")";
foreach (Share share in _stock.Shares)
{
Series series = legendChart.Series.Add(share.Name);
series.SetCustomProperty(c_checkCustomPropertyName,c_checkedString);
}
legendChart.Height = _stock.Shares.Count * c_legendItemHeight + 9; // 9 - seems to be constant value
legendPanel.Height = legendChart.Height;
}
private void legendChart_MouseClick(object sender, MouseEventArgs e)
{
Point mousePosition = legendChart.PointToClient(Control.MousePosition);
int seriesNo = mousePosition.Y / c_legendItemHeight;
Series series = legendChart.Series[seriesNo]; // TODO - check if not out of range
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
// check uncheck series
if (series.GetCustomProperty(c_checkCustomPropertyName) == c_checkedString)
{
// if checked
// uncheck
series.SetCustomProperty(c_checkCustomPropertyName, c_uncheckedString);
series.CustomProperties = series.CustomProperties; // workaround - trigger change - is this a bug?
// hide in mainChart
mainChart.Series[seriesNo].Enabled = false;
}
else
{
// if unchecked
legendChart.Series[seriesNo].SetCustomProperty(c_checkCustomPropertyName, c_checkedString);
series.CustomProperties = series.CustomProperties; // workaround - trigger change - is this a bug?
// show in mainChart
mainChart.Series[seriesNo].Enabled = true;
}
}
}
private void contextMenu_Opening(object sender, CancelEventArgs e)
{
Point mousePosition = legendChart.PointToClient(Control.MousePosition);
int seriesNo = mousePosition.Y / c_legendItemHeight;
Series series = legendChart.Series[seriesNo]; // TODO - check if not out of range
contextMenu.Items.Clear();
string state = series.GetCustomProperty(c_checkCustomPropertyName) == c_checkedString ? "visible" : "hidden";
contextMenu.Items.Add("&Some strange action for " + state + " item named " + series.Name);
contextMenu.Items.Add("&Another action ...");
}
}
结果应如下所示:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句