Search code examples
c#chartslegendmschartmouseclick-event

How to pick up Mschart legend item on MouseClick?


enter image description here

When I click on an item in the legend, I want to be output to Text (The legend of the items) Click on the "Projected" Legend Items, I want it to be put as "Projected" in the textbox.

Is there a way to do that?


Solution

  • Here is the crude calculation I mentioned in the comment:

    First we use a function that converts the Legend.Position from percent to pixels:

    RectangleF LegendClientRectangle(Chart chart, Legend L)
    {
        RectangleF LAR = L.Position.ToRectangleF();
        float pw = chart.ClientSize.Width / 100f;
        float ph = chart.ClientSize.Height / 100f;
        return new RectangleF(pw * LAR.X, ph * LAR.Y, pw * LAR.Width, ph * LAR.Height);
    }
    

    Next we code the MouseClick to get at the Series that belongs to the clicked position:

    private void chart1_MouseClick(object sender, MouseEventArgs e)
    {
        Point mp = e.Location;
        Legend L = chart1.Legends[0];
        RectangleF LCR = LegendClientRectangle(chart1, L);
    
        if ( LCR.Contains(mp) )
        {
            int yh = (int) (LCR.Height / chart1.Series.Count);
            int myRel = (int)(mp.Y - LCR.Y);
            int ser = myRel / yh;             // <--- this is the series index
            Series S = chart1.Series[ser];    // add check here!
            // decide which you have set and want to use..:
            string text = S.LegendText != "" ?  S.LegendText : S.Name;
            Console.WriteLine("Series # " + ser + " ->  " + text);
        }
    }
    

    Note that this code assumes that there is only one column of legenditems without extras like a Legend title.. If the layout has more columns or is a row-based layout you will have to adapt the code, which may not be so simple..

    Also note that the text in a LegendItem may be set separately or be the default, i.e. the Series.Name. You should either know or test if the LegendText is set!

    Update

    I wonder why I didn't simply use HitTest for my answer:

    private void chart1_MouseClick(object sender, MouseEventArgs e)
    {
        HitTestResult hit = chart1.HitTest(e.X, e.Y);
        Series s = null;
        if (hit != null) s = hit.Series;
        if (s != null) 
        {
           string text = s.LegendText != "" ?  s.LegendText : s.Name;
           Console.WriteLine("Series # " + chart1.Series.IndexOf(s) + " ->  " + text);
        }
    }