簡體   English   中英

C#.NET圖表-添加圖例滾動條和復選框

[英]C# .NET Chart - Adding a legend scrollbar and checkboxes

我正在Visual Studio 2013中使用Chart類來可視化一些數據。 但是,我的數據很快產生了許多系列,將所有這些都放在一張圖表中非常重要。 我將圖例區域限制為整個圖表區域的20%,因此當我將圖表拉伸到最大大小時,我幾乎不能顯示超過7-8個圖例項。 該控件在圖例項目的空間用盡后才放入...。

而不是僅僅寫...,是否可以在圖例中添加滾動條並能夠查看所有項目? 我知道我可以通過某種方式實現自己的圖例,但我想從Chart類提供的內容中獲得最大的收益。 我還想在每個圖例項旁邊添加復選框,以指示該系列是否應該在圖表上隱藏。 如果沒有我自己的圖例實現,這有可能嗎?

另外,我還想在右鍵單擊圖例項目時擴展菜單,其中有幾個選項,但這是完全可選的。 滾動條和復選框是我現在的主要問題。

謝謝。

總體思路:您必須創建兩個圖表。 一個是主要的,第二個僅用於傳奇。 如果系列順序相同,您將具有相同的系列樣式。

要顯示彈出窗口,請右鍵單擊圖例項目:

將ContextMenu(工具箱中的ContextMenuStrip類)連接到圖例的圖表。

用於顯示圖例的隱藏系列:

您必須實現MouseClick事件處理程序,並使用數學檢查鼠標光標下的對象( GetChildAtPoint()方法不適用於圖例項目)。 公式:is series_index = control_relative_mouse_y / c_legendItemHeight ,其中c_legendItemHeight是您提供的用於計算控件高度(單個圖例項的高度)的值。 您必須將圖例圖表配置為包含LegendStyleRowMaximumAutoSize100DockingLeftIsTextAutoFitfalseIsEquallySpacedItemstrue 您在圖例中定義了3列(一列用於系列樣式,第二列用於復選框,第三列用於系列名稱)。 使用系列CustomProperties保持可見性狀態。 在檢查列中,使用此自定義屬性(Text = "#CUSTOMPROPERTY(...)" )顯示檢查狀態。 圖表不支持自動調整大小。 您可以手動執行。 在系列加載期間,將圖表高度設置為計算值。 此值等於_stock.Shares.Count * c_legendItemHeight + 9 其中: _stock.Shares.Count是圖例中的項目數, c_legendItemHeight項的高度恆定(整數值,數值大於18的數字似乎對我c_legendItemHeight ), 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 ...");
        }
    }

主要表單代碼。在表格上添加了2個圖表,一個是主要(<code> mainChart </ code>),第二個僅是圖例(<code> legendChart </ code>)。圖例圖放置在面板內(“ legendPanel”)

結果應如下所示:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM