none
MSChart上で選択範囲を取得する方法 RRS feed

  • 質問

  • 表題の通り、Chartコントロールで選択範囲の座標位置、Pointsのデータなどを取得して、拡大表示やデータの集計などを行いたいと考えております。

    拡大/縮小については、ScaleView.Zoomを利用して行うことが可能でしたが、以下の点についてご教授頂けないでしょうか。

    ・Chart上で右クリックにより選択範囲を視覚化する(WindowsのExplorerのような)

    ・Chart上で右クリックDown⇒Upで開始/終了の座標位置からSeriesのPointsをフィルタリング

    2017年2月10日 1:46

回答

  • こんな?

    using System;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
    
                var chart1 = new Chart();
                chart1.ChartAreas.Add(new ChartArea());
                chart1.Series.Add(new Series());
                chart1.Series[0].ChartType = SeriesChartType.Line;
                chart1.Dock = DockStyle.Fill;
    
                chart1.MouseDown += chart1_MouseDown;
                chart1.MouseUp += chart1_MouseUp;
                chart1.MouseMove += chart1_MouseMove;
                chart1.PostPaint += chart1_PostPaint;
                this.Controls.Add(chart1);
                chart1.BringToFront();
    
                Random r = new Random();
                for (int x = 0; x < 100; x++)
                {
                    chart1.Series[0].Points.Add(new DataPoint(x, r.NextDouble() * 300));
                }
            }
    
    
            bool isDown;
            Point p1;
            Point p2;
    
            void chart1_MouseDown(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                isDown = true;
                p1 = e.Location;
                p2 = e.Location;
    
    
            }
            void chart1_MouseUp(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                var area = chart.ChartAreas[0];
                p2 = e.Location;
                if (isDown && p1.X != p2.X)
                {
                    isDown = false;
    
                    var valueX1 = area.AxisX.PixelPositionToValue(p1.X);
                    var valueY1 = area.AxisY.PixelPositionToValue(p1.Y);
                    var valueX2 = area.AxisX.PixelPositionToValue(p2.X);
                    var valueY2 = area.AxisY.PixelPositionToValue(p2.Y);
    
                    var points = chart.Series[0].Points.Where(_ => valueX1 <= _.XValue && _.XValue <= valueX2).ToArray();
                    chart.Series[0].Points.Clear();
                    foreach(var dp in points)
                    {
                        chart.Series[0].Points.Add(dp);
                    }
                }
            }
            void chart1_MouseMove(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                var area = chart.ChartAreas[0];
                var valueX = area.AxisX.PixelPositionToValue(e.Location.X);
                var valueY = area.AxisY.PixelPositionToValue(e.Location.Y);
                System.Diagnostics.Debug.WriteLine("{0} , {1}", valueX, valueY);
    
                p2 = e.Location;
                chart.Invalidate();
            }
    
            void chart1_PostPaint(object sender, ChartPaintEventArgs e)
            {
                var chart = (Chart)sender;
    
                if (e.ChartElement == chart)
                {
                    if (isDown)
                    {
                        float x = Math.Min(p1.X, p2.X);
                        float y = Math.Min(p1.Y, p2.Y);
                        float w = Math.Abs(p1.X - p2.X);
                        float h = Math.Abs(p1.Y - p2.Y);
                        e.ChartGraphics.Graphics.DrawRectangle(Pens.Red, x, y, w, h);
                    }
                }
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年2月10日 3:38

すべての返信

  • こんな?

    using System;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
    
                var chart1 = new Chart();
                chart1.ChartAreas.Add(new ChartArea());
                chart1.Series.Add(new Series());
                chart1.Series[0].ChartType = SeriesChartType.Line;
                chart1.Dock = DockStyle.Fill;
    
                chart1.MouseDown += chart1_MouseDown;
                chart1.MouseUp += chart1_MouseUp;
                chart1.MouseMove += chart1_MouseMove;
                chart1.PostPaint += chart1_PostPaint;
                this.Controls.Add(chart1);
                chart1.BringToFront();
    
                Random r = new Random();
                for (int x = 0; x < 100; x++)
                {
                    chart1.Series[0].Points.Add(new DataPoint(x, r.NextDouble() * 300));
                }
            }
    
    
            bool isDown;
            Point p1;
            Point p2;
    
            void chart1_MouseDown(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                isDown = true;
                p1 = e.Location;
                p2 = e.Location;
    
    
            }
            void chart1_MouseUp(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                var area = chart.ChartAreas[0];
                p2 = e.Location;
                if (isDown && p1.X != p2.X)
                {
                    isDown = false;
    
                    var valueX1 = area.AxisX.PixelPositionToValue(p1.X);
                    var valueY1 = area.AxisY.PixelPositionToValue(p1.Y);
                    var valueX2 = area.AxisX.PixelPositionToValue(p2.X);
                    var valueY2 = area.AxisY.PixelPositionToValue(p2.Y);
    
                    var points = chart.Series[0].Points.Where(_ => valueX1 <= _.XValue && _.XValue <= valueX2).ToArray();
                    chart.Series[0].Points.Clear();
                    foreach(var dp in points)
                    {
                        chart.Series[0].Points.Add(dp);
                    }
                }
            }
            void chart1_MouseMove(object sender, MouseEventArgs e)
            {
                var chart = (Chart)sender;
                var area = chart.ChartAreas[0];
                var valueX = area.AxisX.PixelPositionToValue(e.Location.X);
                var valueY = area.AxisY.PixelPositionToValue(e.Location.Y);
                System.Diagnostics.Debug.WriteLine("{0} , {1}", valueX, valueY);
    
                p2 = e.Location;
                chart.Invalidate();
            }
    
            void chart1_PostPaint(object sender, ChartPaintEventArgs e)
            {
                var chart = (Chart)sender;
    
                if (e.ChartElement == chart)
                {
                    if (isDown)
                    {
                        float x = Math.Min(p1.X, p2.X);
                        float y = Math.Min(p1.Y, p2.Y);
                        float w = Math.Abs(p1.X - p2.X);
                        float h = Math.Abs(p1.Y - p2.Y);
                        e.ChartGraphics.Graphics.DrawRectangle(Pens.Red, x, y, w, h);
                    }
                }
            }
        }
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2017年2月10日 3:38
  • ご回答ありがとうございます。ご質問させて頂きました2点について求めていた内容でした。


    2017年2月10日 4:29