【C#】Chart折れ線グラフ2
前回の続き
shinopikapi.hateblo.jp
todo
1. 折れ線
2. 1000msec毎にグラフが更新
3. データ数は10、最大100、最小0とする
4. 新しいデータは右側、前のデータはどんどん左側に移動するように表示
5. 表示するデータは、3の範囲で設定した乱数
1-3までは大体完了したので、4,5に取り掛かります。
コンストラクタでTimerの設定をしておいて、Timerイベントを定期的に呼び出します。
以下の関数の中で0-100の範囲で乱数を作成し、作成した関数updateChartでChartを4のように更新していきます。
private void timer1_Tick(object sender, EventArgs e) { // 0-100で乱数 // Random m_r1 = new Random(); int add = m_r1.Next(0, 100); updateChart(chart1, m_value, add); }
updateChartの中身は以下のような感じ。
Chart表示用配列を作っておき、配列コピーで最新の値AddをChartの一番右に表示するようにしています。
private void updateChart(Chart chart, int[] val, int Add) { int[] cpVal = new int[val.Length]; // cpValの要素0-8に、valの要素1-9までをコピー Array.Copy(val, 1, cpVal, 0, val.Length - 1); // cpValの要素の末尾に新しく追加したい値を挿入 cpVal[cpVal.Length - 1] = Add; // 元の配列に更新したデータを戻す Array.Copy(cpVal, val, val.Length); // 一旦Chartデータをクリア chart.Series[Name1].Points.Clear(); // データ設定 for (int i = 0; i < 10; i++) { chart.Series[Name1].Points.AddXY(i, val[i]); } }
Chart表示では、一旦データクリアしてAddXYしています。
配列のように要素指定して値更新出来ないかなと思ったのですが、今のところ探せていません……。
Array.Copyも要素移動する、みたいなこと出来るかもしれませんが探せていないので、とりあえず配列作ってコピーして……みたいなことをしています。
わかりにくいですが、表示した値が左に移動してる図です。
ソース全体は、以下のようになっています。
public partial class Form1 : Form { const string Name1 = "Bar1"; const string AreaName1 = "chartArea1"; private int[] m_value = new int[10]; Random m_r1 = new Random(); public Form1() { // コンストラクタ InitializeComponent(); // chart initChart(chart1, SeriesChartType.Line);//折れ線 // timer timer1.Interval = 1000; timer1.Enabled = true; timer1.Start(); } private void initChart(Chart chart, SeriesChartType type) { // 初期化 chart.Series.Clear(); chart.ChartAreas.Clear(); // chart設定 //string Name1 = "Bar1"; //string AreaName1 = "chartArea1"; chart.Series.Add(Name1);// Series追加 chart.ChartAreas.Add(AreaName1); chart.Series[Name1].ChartType = type; //max, min 目盛設定 chart.ChartAreas[AreaName1].AxisY.Maximum = 100; chart.ChartAreas[AreaName1].AxisY.Minimum = 0; chart.ChartAreas[AreaName1].AxisY.Interval = 20; // 目盛線ちょっと出てるところがなくなる chart.ChartAreas[AreaName1].AxisX.MajorTickMark.Enabled = false; // データ設定 for (int i = 0; i < 10; i++) { chart.Series[Name1].Points.AddXY(i, i * 10); } } private void timer1_Tick(object sender, EventArgs e) { // 0-100で乱数 int add = m_r1.Next(0, 100); updateChart(chart1, m_value, add); } private void updateChart(Chart chart, int[] val, int Add) { int[] cpVal = new int[val.Length]; // cpValの要素0-8に、valの要素1-9までをコピー Array.Copy(val, 1, cpVal, 0, val.Length - 1); // cpValの要素の末尾に新しく追加したい値を挿入 cpVal[cpVal.Length - 1] = Add; // 元の配列に更新したデータを戻す Array.Copy(cpVal, val, val.Length); // 一旦Chartデータをクリア chart.Series[Name1].Points.Clear(); // データ設定 for (int i = 0; i < 10; i++) { chart.Series[Name1].Points.AddXY(i, val[i]); } } }
参考
https://docs.microsoft.com/ja-jp/dotnet/api/system.random.next?view=net-5.0