Selecting multiple sections on a chart in c#

后端 未结 1 574
既然无缘
既然无缘 2021-01-23 11:06

I am trying to make a simple WindowsFormAplication with data displayed in charts with type column.

Now, the idea is for the user to select a part of the chart, and for t

1条回答
  •  鱼传尺愫
    2021-01-23 12:01

    There can only be one range selected at any time.

    So you need to ..

    • ..collect the ranges and
    • ..probably also collect the selected DataPoints.
    • Finally you also need to decide on a UI to clear the selections.

    An simple way to display several selections, very similar to the cursor selection is adding Striplines..:

    Here is the code for the above result; note that it assumes that your values will fit in a float and abuses the SizeF structure to store the start and end values of the selections. If you want to be more precise you can replace it with a Tuple..:

    First three class level variables to hold the data, the ongoing selection, the list of ranges and a list of DataPoint indices:

    SizeF curRange = SizeF.Empty;
    List ranges = new List();
    List selectedIndices = new List();
    

    This event holds the new selections in the param e, so we can store them:

    private void chart1_SelectionRangeChanging(object sender, CursorEventArgs e)
    {
        curRange = new SizeF((float)e.NewSelectionStart, (float)e.NewSelectionEnd);
    }
    

    Now the selection process is done; the selection data is lost by now, but we have stored them. So we can add the new range, collect the newly selected DataPoint indices and finally create and display a new StripLine:

    private void chart1_SelectionRangeChanged(object sender, CursorEventArgs e)
    {
        ranges.Add(curRange);
        selectedIndices.Union(collectDataPoints(chart1.Series[0], 
                              curRange.Width, curRange.Height))
                       .Distinct();
    
        StripLine sl = new StripLine();
        sl.BackColor = Color.FromArgb(255, Color.LightSeaGreen);
        sl.IntervalOffset = Math.Min(curRange.Width, curRange.Height);
        sl.StripWidth = Math.Abs(curRange.Height - curRange.Width);
        chart1.ChartAreas[0].AxisX.StripLines.Add(sl);
    }
    

    This little routine should collect all DataPoint indices in a range:

    List collectDataPoints(Series s, double min, double max)
    {
        List hits = new List();
        for (int i = 0; i < s.Points.Count ; i++)
            if (s.Points[i].XValue >= min && s.Points[i].XValue <= max) hits.Add(i);
        return hits;
    }
    

    To clear the selection you clear the two lists, the StripLines collection, and the curRange structure.

    0 讨论(0)
提交回复
热议问题