none
VS2015c# chartのスクロールのズームリセットボタンの位置を変更したい RRS feed

  • 質問

  • VS2015 c#

    chartのスクロールのズームリセットボタン 丸にマイナスのボタンです

    Y軸はスクロールバー の 上側

    X軸はスクロールバー の 左側 に 位置されますが

    順にマウスを移動させるのが面倒です

    Y軸のほうを スクロールバー の 下側 に 位置したいのです

    どうすれば よいでしょうか?

    2016年6月16日 4:52

回答

  • WinFormのChartという前提で、移動は難しいのでボタンのようなものを追加してみる。
    #Chartのスクロールバーなどはすべて画像として描かれているので、無理やり描画をずらすとマウスの座標とズレるので。

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            private System.Windows.Forms.DataVisualization.Charting.Chart chart;
            private PictureBox verticalResetButton;
            public Form1()
            {
                //InitializeComponent();
                this.Width = 600;
                this.Height = 600;
    
                ChartArea area = new ChartArea();
                area.AxisX.ScrollBar.Enabled = true;
                area.AxisY.ScrollBar.Enabled = true;
                area.AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.All;
                //area.AxisY.ScrollBar.Size = 20;
    
                area.AxisX.ScaleView.Zoomable = true;
                area.AxisX.ScaleView.Zoom(10, 20);
                area.AxisY.ScaleView.Zoomable = true;
                area.AxisY.ScaleView.Zoom(10, 50);
                area.BackColor = Color.LightBlue;
                var style = area.Area3DStyle;
                style.IsRightAngleAxes = true;
                style.Perspective = 20;
                style.Rotation = 60;
    
                chart = new Chart();
                chart.ChartAreas.Add(area);
    
                Random rnd = new Random();
                for (int i = 0; i < 5; i++)
                {
                    var seri = new System.Windows.Forms.DataVisualization.Charting.Series();
                    seri.ChartType = SeriesChartType.Spline;
                    chart.Series.Add(seri);
    
                    for (int x = 1; x <= 50; x++)
                    {
                        seri.Points.AddXY(x, rnd.Next(100));
                    }
                }
    
                chart.Dock = DockStyle.Fill;
                this.Controls.Add(chart);
    
                verticalResetButton = new PictureBox();
                chart.Controls.Add(verticalResetButton);
                verticalResetButton.Click += verticalResetButton_Click;
    
                chart.PostPaint += chart_PostPaint;
    
            }
    
            void verticalResetButton_Click(object sender, EventArgs e)
            {
                chart.ChartAreas[0].AxisY.ScaleView.ZoomReset();
            }
    
            private void chart_PostPaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
            {
                if (e.ChartElement is Chart)
                {
                    var axisX = e.Chart.ChartAreas[0].AxisX;
                    var axisY = e.Chart.ChartAreas[0].AxisY;
                    var scrollbarY = axisY.ScrollBar;
                    if (scrollbarY.IsVisible)
                    {
                        //スクロールバーの位置を計算
                        //第2軸の場合はMin,Maxを逆に
                        var yMin = Math.Min(axisY.ValueToPixelPosition(axisY.ScaleView.ViewMinimum), axisY.ValueToPixelPosition(axisY.ScaleView.ViewMaximum));
                        var yMax = Math.Max(axisY.ValueToPixelPosition(axisY.ScaleView.ViewMinimum), axisY.ValueToPixelPosition(axisY.ScaleView.ViewMaximum));
                        var xMin = Math.Min(axisX.ValueToPixelPosition(axisX.ScaleView.ViewMinimum), axisX.ValueToPixelPosition(axisX.ScaleView.ViewMaximum)) - scrollbarY.Size;
                        
                        //リセットボタンの位置
                        var r = new Rectangle((int)Math.Round(xMin), (int)Math.Round(yMin), (int)Math.Round(scrollbarY.Size), (int)Math.Round(scrollbarY.Size));
    
                        if (verticalResetButton.Image == null || verticalResetButton.Image.Width != r.Width)
                        {
                            chart.PostPaint -= chart_PostPaint;
    
                            //リセットボタンを含む画像を取得する
                            Bitmap bmpFull = new Bitmap(chart.Width, chart.Height);
                            Bitmap bmpButton = new Bitmap(r.Width, r.Height);
                            verticalResetButton.Visible = false;
    
                            chart.DrawToBitmap(bmpFull, new Rectangle(0, 0, chart.Width, chart.Height));
                            chart.PostPaint += chart_PostPaint;
                            verticalResetButton.Visible = true;
                            
                            using (Graphics g = Graphics.FromImage(bmpButton))
                            {
                                //ボタン部分だけを切り出し
                                g.DrawImage(bmpFull, new Rectangle(0, 0, r.Width, r.Height), r, GraphicsUnit.Pixel);
                            }
                            verticalResetButton.Image = bmpButton;
                            verticalResetButton.Size = verticalResetButton.Image.Size;
                        }
    
                        verticalResetButton.Left = r.X;
                        verticalResetButton.Top = (int)yMax+1;
                        verticalResetButton.Size = r.Size;
                      
                    }
                    else
                    {
                        verticalResetButton.Visible = false;
                    }
                }
            }
        }
    }
    Imageコントロールを載せていますがChartのGraphicsに直接ボタンを描画して、Chartへクリックがその範囲内である場合にリセットすることも可能でしょう。
    #VScrollBarを被せても可能だろうけどスクロール中のリサイズに追随するのが面倒

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

    2016年6月16日 10:42