C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

折れ線グラフ /たか (23/11/01(Wed) 19:09) #102494
Re[1]: 折れ線グラフ /魔界の仮面弁士 (23/11/01(Wed) 21:34) #102495
  └ Re[2]: 折れ線グラフ /たか (23/11/02(Thu) 11:02) #102496 解決済み
    └ Re[3]: 折れ線グラフ /たか (23/11/22(Wed) 19:47) #102590
      └ Re[4]: 折れ線グラフ /魔界の仮面弁士 (23/11/24(Fri) 11:13) #102602


親記事 / ▼[ 102495 ]
■102494 / 親階層)  折れ線グラフ
□投稿者/ たか (1回)-(2023/11/01(Wed) 19:09:05)

分類:[C#] 

c# Windowsフォームアプリ .NET Framework

宜しくお願いします

現在C#でフォーム上の折れ線グラフを2つ表示させています
1秒毎に右から左に移動させて一番左から消えていきます

その時X軸の表示も右から左に秒数が移動しているのですが
X軸の一番左を0で一番右は指定した数値で固定したいのです

ちなみに左を0で右を60としたら グラフは移動していくのですが
X軸の表示は0と60のままの表示にしたいのです

説明が分かりずらいと思いますがご教示宜しくお願い致します


using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace 折れ線グラフ
{
    public partial class Form1 : Form
    {
        private OpcClient client;
        private DateTime startTime;
        private Timer timer;
        private Random random;
        private int dataCounter;
        private Chart upperChart;
        private Chart lowerChart;

        int cycletime = 6;
       
        public Form1()
        {
            InitializeComponent();

            labelValue.Text = cycletime.ToString();

            random = new Random();
            
            upperChart = CreateChart();
            upperChart.Location = new System.Drawing.Point(280, 250);
            this.Controls.Add(upperChart);

            lowerChart = CreateChart();
            lowerChart.Location = new System.Drawing.Point(280, 530);
            this.Controls.Add(lowerChart);

            dataCounter = -1;

        }
        public void UpdateValue(int value)
        {
            labelValue.Text = value.ToString();
            cycletime = value;
        }

        private void btnStart1_Click(object sender, EventArgs e)
        {
            startTime = DateTime.UtcNow;
            timer = new Timer();
            timer.Interval = 1000; // 1秒
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void btnStop1_Click(object sender, EventArgs e)
        {
            timer.Stop();
        }

        private Chart CreateChart()
        {
            Chart chart = new Chart();
            chart.Size = new System.Drawing.Size(1200, 250);
            chart.ChartAreas.Add(new ChartArea());
            chart.Series.Add("DataSeries");
            chart.Series["DataSeries"].ChartType = SeriesChartType.Line;
            chart.Series["DataSeries"].BorderWidth = 2; 
            chart.ChartAreas[0].AxisX.LabelStyle.Enabled = true; 

            chart.ChartAreas[0].AxisY.Minimum = 0; 
            chart.ChartAreas[0].AxisY.Maximum = 100; 

            return chart;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {

            int upperData = random.Next(40, 80);
            int lowerData = random.Next(0, 100);
            
            upperChart.Series["DataSeries"].Points.AddXY(dataCounter+1, upperData);
            lowerChart.Series["DataSeries"].Points.AddXY(dataCounter+1, lowerData);

            dataCounter++;

            upperChart.ChartAreas[0].AxisX.Minimum = dataCounter >= cycletime ? dataCounter - cycletime : 0;
            upperChart.ChartAreas[0].AxisX.Maximum = dataCounter;

            lowerChart.ChartAreas[0].AxisX.Minimum = dataCounter >= cycletime ? dataCounter - cycletime : 0;
            lowerChart.ChartAreas[0].AxisX.Maximum = dataCounter;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

[ □ Tree ] 返信 編集キー/

▲[ 102494 ] / ▼[ 102496 ]
■102495 / 1階層)  Re[1]: 折れ線グラフ
□投稿者/ 魔界の仮面弁士 (3704回)-(2023/11/01(Wed) 21:34:58)
No102494 (たか さん) に返信
> その時X軸の表示も右から左に秒数が移動しているのですが
> X軸の一番左を0で一番右は指定した数値で固定したいのです

現状、Series.Points.AddXY が繰り返されることで、
Series.Points.Count が延々と増加していますね。


cycletime の値は固定的ですか? それとも表示中に変動しますか?

固定的であれば、チャート側は、横軸として表示される件数だけを保有する形として、
データの蓄積と表示を分けた方が良いかもしれません。

X 値は 0〜秒数 の数値のみとし、
Y 値だけを順にシフトしてみる。

//private OpcClient client;
private DateTime startTime;
private Timer timer;
private Random random;
private Chart upperChart;
private Chart lowerChart;

int cycletime = 6;

private List<double> upperList;
private List<double> lowerList;

public Form1()
{
  InitializeComponent();
  labelValue.Text = cycletime.ToString();

  random = new Random();

  IEnumerable<double> doubles = Enumerable.Repeat(double.NaN, cycletime + 1);

  upperChart = CreateChart(upperList = new List<double>(doubles));
  upperChart.Location = new System.Drawing.Point(280, 250);
  this.Controls.Add(upperChart);

  lowerChart = CreateChart(lowerList = new List<double>(doubles));
  lowerChart.Location = new System.Drawing.Point(280, 530);
  this.Controls.Add(lowerChart);
}

private Chart CreateChart(IList<double> doubles)
{
  Chart chart = new Chart();
  chart.Size = new System.Drawing.Size(1200, 250);
  chart.ChartAreas.Add(new ChartArea());
  chart.Series.Add("DataSeries");
  chart.Series["DataSeries"].ChartType = SeriesChartType.Line;
  chart.Series["DataSeries"].BorderWidth = 2;
  chart.ChartAreas[0].AxisX.LabelStyle.Enabled = true;
  for (int i = 0; i < doubles.Count; i++)
  {
    chart.Series["DataSeries"].Points.AddXY(i, doubles[i]);
  }
  chart.ChartAreas[0].AxisX.Minimum = 0;
  chart.ChartAreas[0].AxisX.Maximum = doubles.Count - 1;
  chart.ChartAreas[0].AxisY.Minimum = 0;
  chart.ChartAreas[0].AxisY.Maximum = 100;
  return chart;
}

private void SlideData(Chart chart, List<double> list, double newData)
{
  list.Add(newData);
  list.RemoveAt(0);

  chart.Series["DataSeries"].Points.Clear();
  for (int x = 0; x < list.Count; x++)
  {
    chart.Series["DataSeries"].Points.AddXY(x, list[x]);
  }
}

private void Timer_Tick(object sender, EventArgs e)
{
  int upperData = random.Next(40, 80);
  int lowerData = random.Next(0, 100);

  SlideData(upperChart, upperList, upperData);
  SlideData(lowerChart, lowerList, lowerData);
}
[ 親 102494 / □ Tree ] 返信 編集キー/

▲[ 102495 ] / ▼[ 102590 ]
■102496 / 2階層)  Re[2]: 折れ線グラフ
□投稿者/ たか (2回)-(2023/11/02(Thu) 11:02:08)
No102495 (魔界の仮面弁士 さん) に返信
> ■No102494 (たか さん) に返信

ありがとうございます
できました!!
自分の思い描いている様にできました
ありがとうございました
今後とも宜しくお願い致します
解決済み
[ 親 102494 / □ Tree ] 返信 編集キー/

▲[ 102496 ] / ▼[ 102602 ]
■102590 / 3階層)  Re[3]: 折れ線グラフ
□投稿者/ たか (3回)-(2023/11/22(Wed) 19:47:10)
魔界の仮面弁士 さん

また続きで教えて頂きたいことがありますので
宜しくお願い致します

x軸の表示を固定して表示は出来たのですが
表示している最中にcycletime(横軸の値)を変更させたいのですが
どうすればいいでしょうか

今作ったのがform5のラジオボタンで選択した値をform1にまで
持ってきています

(form5)
using System;
using System.Windows.Forms;

namespace 折れ線グラフ
{
public partial class Form5 : Form
{
private Form1 _form1;

public Form5(Form1 form1)
{
InitializeComponent();
_form1 = form1;
}
private void setButton_Click(object sender, EventArgs e)
{
int selectedValue = 0;

if (radioButton1.Checked)
{
selectedValue = 150;
textBox1.Text = "150";
}
else if (radioButton2.Checked)
{
selectedValue = 200;
textBox1.Text = "200";
}
else if (radioButton3.Checked)
{
selectedValue = 250;
textBox1.Text = "250";
}
else if (radioButton4.Checked)
{
selectedValue = 300;
textBox1.Text = "300";
}

_form1.UpdateValue(selectedValue);
Close();
}
}
}

それをform1で受けています
    public void UpdateValue(int value)
{
cycletime = value;
}

宜しくお願い致します
[ 親 102494 / □ Tree ] 返信 編集キー/

▲[ 102590 ] / 返信無し
■102602 / 4階層)  Re[4]: 折れ線グラフ
□投稿者/ 魔界の仮面弁士 (3716回)-(2023/11/24(Fri) 11:13:29)
No102590 (たか さん) に返信
> 魔界の仮面弁士 さん
> また続きで教えて頂きたいことがありますので
> 宜しくお願い致します

いや指名されましても。


> 表示している最中にcycletime(横軸の値)を変更させたいのですが
> どうすればいいでしょうか
方針としては、前回の回答と同じですよ。
「データの蓄積」と「データの表示」を分けて管理するだけです。


public sealed partial class Form1 : Form
{
  // 蓄積するデータ
  private List<double> upperList = new List<double>();
  private List<double> lowerList = new List<double>();
  private Random random;
  private Timer timer;

  // チャート
  private Chart upperChart;
  private Chart lowerChart;

  // チャートに表示するデータ数。今回は TrackBar を利用しましたが、
  // 自前で、「CycleTime プロパティ」を設けて管理しても良いでしょう。
  private Label labelValue;
  private TrackBar cycleTimeBar;
  private const int CycleTimeMinValue = 1;
  private const int CycleTimeMaxValue = 20;
  private const int CycleTimeIniValue = 5;

  public Form1()
  {
    InitializeComponent();
    this.random = new Random();
    (this.components ?? (this.components = new System.ComponentModel.Container())).Add(this.timer = new Timer() { Interval = 1000 });
    this.Controls.Add(this.cycleTimeBar = new TrackBar() { Name = "trackBar", Minimum = CycleTimeMinValue, Maximum = CycleTimeMaxValue, Value = CycleTimeIniValue, Dock = DockStyle.Top });
    this.Controls.Add(this.labelValue = new Label() { Name = "labelValue", Text = this.cycleTimeBar.Value.ToString(), Dock = DockStyle.Top });
    this.labelValue.DataBindings.Add("Text", this.cycleTimeBar, "Value");

    this.upperChart = this.CreateChart(this.cycleTimeBar.Value);
    this.upperChart.Location = new System.Drawing.Point(280, 250);
    this.lowerChart = this.CreateChart(this.cycleTimeBar.Value);
    this.lowerChart.Location = new System.Drawing.Point(280, 530);

    this.Controls.AddRange(new[] { upperChart, lowerChart });
    this.timer.Tick += this.timer_Tick;
    this.timer.Start();
    this.cycleTimeBar.ValueChanged += delegate { this.UpdateCharts(); };
    this.UpdateCharts();
  }

  private Chart CreateChart(int MaxCycle)
  {
    Chart chart = new Chart { Size = new System.Drawing.Size(1200, 250) };
    Series series = chart.Series.Add("DataSeries");
    series.ChartType = SeriesChartType.Line;
    series.BorderWidth = 2;
    chart.ChartAreas.Add(new ChartArea() {
      AxisY = { Minimum = 0, Maximum = 100 },
      AxisX = { Minimum = 0, Maximum = MaxCycle, LabelStyle = { Enabled = true } }
    });
    return chart;
  }

  private void UpdateCharts()
  {
    UpdateChart(upperChart, upperList, cycleTimeBar.Value);
    UpdateChart(lowerChart, lowerList, cycleTimeBar.Value);
  }
  private void UpdateChart(in Chart chart, in List<double> list, int cycleTime)
  {
    Stack<double> viewData = new Stack<double>();
    for (int i = list.Count - 1; i >= (list.Count - cycleTime - 1); i--)
    {
      viewData.Push((i < 0) ? double.NaN : list[i]);
    }
    Series series = chart.Series["DataSeries"];
    var points = series.Points;
    points.Clear();
    chart.ChartAreas[0].AxisX.Maximum = cycleTime;
    for (int x = 0; x <= cycleTime; x++)
    {
      points.AddXY(x, viewData.Pop());
    }
  }

  private void timer_Tick(object sender, EventArgs e)
  {
    int upperData = random.Next(40, 80);
    int lowerData = random.Next(0, 100);
    this.upperList.Add(upperData);
    this.lowerList.Add(lowerData);
    this.UpdateCharts();
  }
}
[ 親 102494 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -