|
分類:[C#]
WindowsフォームアプリのChartコントロールに対して、以下対応を行いたいです。 ・X軸またはY軸の最小値と最大値をいずれか変更したときに、グラフ表示領域をセンタリングさせて表示させたい (このとき、グリッドラインのアスペクト比は常に1:1(グリッドラインがすべて正方形)の状態を維持させたい)
そこで以下サンプルコードを作成してみましたが、センタリングさせることができませんでした。 以下サンプルコードですと、InnerPlotPositionとPositionの座標関係がわからないため、参考となるサイトや、 他に良い方法があれば教えていただけないでしょうか。宜しくお願い致します。
public partial class Main : Form { ChartArea ca; ElementPosition ipp;
public Main() { InitializeComponent();
//初期値(固定) textBox_xMin.Text = "-40"; textBox_xMax.Text = "40"; textBox_yMin.Text = "-10"; textBox_yMax.Text = "190";
// ElementPositionの初期値(特に指定はありません) textBox_ElementPositionX.Text = "13"; textBox_ElementPositionY.Text = "0";
// Positionの初期値(特に指定はありません) textBox_PositionX.Text = "10"; textBox_PositionY.Text = "10"; textBox_PositionWidth.Text = "50"; textBox_PositionHeight.Text = "50";
//描画 DrawGraph(double.Parse(textBox_xMin.Text), double.Parse(textBox_xMax.Text), double.Parse(textBox_yMin.Text), double.Parse(textBox_yMax.Text), 40);
}
private void DrawGraph(double xMin, double xMax, double yMin, double yMax, double cntDist) {
int Width = chart2.Size.Width; int Height = chart2.Size.Height;
chart2.Series.Clear(); chart2.ChartAreas.Clear(); chart2.Titles.Clear();
Series Series0 = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2, MarkerStyle = MarkerStyle.Circle, MarkerSize = 2 }; chart2.Series.Add(Series0); chart2.Series[0].Points.Clear(); chart2.Series[0].Points.AddXY(xMin, 60); chart2.Series[0].Points.AddXY(xMax, 60);
//--------------------------------- // X軸、Y軸のラベル設定 //--------------------------------- ChartArea ChartArea2 = new ChartArea(); ChartArea2.AxisY.IsReversed = false; ChartArea2.AxisX.TitleForeColor = Color.Black; chart2.ChartAreas.Add(ChartArea2);
//グラフのアスペクト比調整 //グラフの「縦:横」が、「2.5:1」の場合に、縦の縮尺と横の縮尺がほぼ同一となるため、以下実装した // Xの長さとYの長さを求める double xLen = xMax - xMin; double yLen = yMax - yMin;
// Xの長さが基準の「80」に対して何%の値か float xp = (float)(xLen / 80); xp *= 84; // 初期値:84%
// Yの長さが基準の「200」に対して何%の値か float yp = (float)(yLen / 200); yp *= 97; // 初期値:97%
// xpまたはypいずれかが上限値超える場合は調整する // ypはラベル表示が消えないように100以外の値をセットしている if (xp > 100 || yp > 98) { if (xp > yp) { yp *= (98 / xp); xp = 100; } else if (yp > xp) { xp *= (100 / yp); yp = 98; } else { yp *= (98 / xp); xp = 100; } }
ca = chart2.ChartAreas[0]; ipp = ca.InnerPlotPosition; ipp.Auto = false; ipp.Height = yp; ipp.Width = xp;
//以下コメントアウト部分のセンタリング対応ではダメだった //float elementPositionX = 0; //float elementPositionY = 0;
//if (xLen < 100) //{ // //0〜99の範囲ではy = (n - 1) * (-0.5) + 49.5の等差数列でセンタリング可能 // //ただし、xLenとyLenの値の組み合わせ次第ではラベルの影響?によりセンタリングとならなかった // elementPositionX = (float)(((-0.5) * xLen) + 50); //} //else //{ // elementPositionX = 0; //}
//if (yLen < 200) //{ // //0〜200の範囲ではy = (n - 1) * (0.5) + 45.5の等差数列でセンタリングとならなかった // //elementPositionY = (float)(((0.5) * yLen) + 45); //} //else //{ // elementPositionY = 0; //}
//ipp.X = elementPositionX; //ipp.Y = elementPositionY; ipp.X = float.Parse(textBox_ElementPositionX.Text); // 初期値:13pxl ipp.Y = float.Parse(textBox_ElementPositionY.Text); // 初期値: 0pxl
//--------------------------------- // X軸設定 //--------------------------------- chart2.ChartAreas[0].AxisX.Minimum = xMin; chart2.ChartAreas[0].AxisX.Maximum = xMax; chart2.ChartAreas[0].AxisX.Interval = 10; chart2.ChartAreas[0].AxisX.MajorTickMark.LineWidth = 0; chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Silver;
// Minor Grid chart2.ChartAreas[0].AxisX.MinorGrid.Enabled = true; chart2.ChartAreas[0].AxisX.MinorGrid.Interval = 2; chart2.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.WhiteSmoke;
//--------------------------------- // Y軸設定 //--------------------------------- chart2.ChartAreas[0].AxisY.Minimum = yMin; chart2.ChartAreas[0].AxisY.Maximum = yMax; chart2.ChartAreas[0].AxisY.Interval = 10; chart2.ChartAreas[0].AxisY.MajorTickMark.LineWidth = 0; chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Silver;
// Minor Grid chart2.ChartAreas[0].AxisY.MinorGrid.Enabled = true; chart2.ChartAreas[0].AxisY.MinorGrid.Interval = 2; chart2.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.WhiteSmoke;
// センタリング対応 // テキストボックスからPositionを変更するだけではセンタリングがうまくいかなかった chart2.ChartAreas[0].Position.Auto = false; chart2.ChartAreas[0].Position.X = float.Parse(textBox_PositionX.Text); chart2.ChartAreas[0].Position.Y = float.Parse(textBox_PositionY.Text); chart2.ChartAreas[0].Position.Width = float.Parse(textBox_PositionWidth.Text); chart2.ChartAreas[0].Position.Height = float.Parse(textBox_PositionHeight.Text);
Series Series1 = new Series { ChartType = SeriesChartType.Line, Color = Color.Red }; chart2.Series.Add(Series1); chart2.Series[1].Points.Clear(); chart2.Series[1].Points.AddXY(xMin, cntDist); chart2.Series[1].Points.AddXY(xMax, cntDist); } }
|