I have code that generates data in the DataGridView and I want to also push this to a chart from the same button click.
Process:
Text is put into a text box myInputBox
then the button processButton
is pressed to split the text up and output it to the DataGridView myOutputDGV
the button has the following code:
private void processButton_Click(object sender, EventArgs e)
{
List<string> mySplit = new List<string>(myInputBox.Text.Split(new string[] { "XN" }, StringSplitOptions.None));
DataGridViewTextBoxColumn myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Line";
myOutputGrid.Name = "Line";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Section";
myOutputGrid.Name = "Section";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Range";
myOutputGrid.Name = "Range";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Total";
myOutputGrid.Name = "Total";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
foreach (string item in mySplit)
{
myOutputDGV.Rows.Add(item.Trim(),
item.Split(new string[] { "(cost=" }, StringSplitOptions.None).First(),
Regex.Match(item, @"cost=(.+?) rows").Groups[1].Value,
Regex.Match(item, @"cost=(.+?)\.\.").Groups[1].Value,
}
}
I want to populate my chart myChart
with the values from column[1] (Line) on the X axis and column[3] (Total) on the Y axis.
EDIT:
I have tried adding the following code in the button processButton
click code but the chart isn't populated:
ChartArea chartArea1 = new ChartArea();
chartArea1.AxisX.MajorGrid.LineColor = Color.LightGray;
chartArea1.AxisY.MajorGrid.LineColor = Color.LightGray;
chartArea1.AxisX.LabelStyle.Font = new Font("Consolas", 8);
chartArea1.AxisY.LabelStyle.Font = new Font("Consolas", 8);
myChart.ChartAreas.Add(chartArea1);
myChart.Series.Add(new Series());
myChart.Series[0].XValueMember = myOutputDGV.Columns[1].DataPropertyName;
myChart.Series[0].YValueMembers = myOutputDGV.Columns[3].DataPropertyName;
myChart.DataSource = myOutputDGV.DataSource;
myChart.Series[0].ChartType = SeriesChartType.Line;
EDIT 2:
I have also tried this to no avail:
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChartArea.AxisX.MajorGrid.LineColor = Color.Red;
myChartArea.AxisY.MajorGrid.LineColor = Color.Red;
myChartArea.AxisX.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChartArea.AxisY.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
EDIT 3 FULL CODE:
private void ProcessButton_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(myInputBox.Text) || myInputBox.Text == "")
{
MessageBox.Show("Please enter data", "Info");
}
else
{
myOutputDGV.Rows.Clear();
myOutputDGV.Columns.Clear();
myOutputDGV.Refresh();
myChart.ChartAreas.Clear();
myChart.Series.Clear();
List<string> mySplit = new List<string>(myInputBox.Text.Split(new string[] { "XN" }, StringSplitOptions.None));
DataGridViewTextBoxColumn myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Line";
myOutputGrid.Name = "Line";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Section";
myOutputGrid.Name = "Section";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost Range";
myOutputGrid.Name = "Cost Range";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost First Row";
myOutputGrid.Name = "Cost First Row";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Cost All Rows";
myOutputGrid.Name = "Cost All Rows";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Rows";
myOutputGrid.Name = "Rows";
myOutputDGV.Columns.Add(myOutputGrid);
myOutputGrid = new DataGridViewTextBoxColumn();
myOutputGrid.HeaderText = "Width";
myOutputGrid.Name = "Width";
myOutputDGV.Columns.Add(myOutputGrid);
foreach (string item in mySplit)
{
myOutputDGV.Rows.Add(item.Trim(),
item.Split(new string[] { "(cost=" }, StringSplitOptions.None).First(),
Regex.Match(item, @"cost=(.+?) rows").Groups[1].Value,
Regex.Match(item, @"cost=(.+?)\.\.").Groups[1].Value,
Regex.Match(item, @"\.\.(.+?) ").Groups[1].Value,
Regex.Match(item, @"rows=(.+?) ").Groups[1].Value,
Regex.Match(item, @"width=(.+?)\)").Groups[1].Value);
}
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChartArea.AxisX.MajorGrid.LineColor = Color.Red;
myChartArea.AxisY.MajorGrid.LineColor = Color.Red;
myChartArea.AxisX.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChartArea.AxisY.LabelStyle.Font = new System.Drawing.Font("Consolas", 10);
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
myChart.Series[0].XValueMember = myOutputDGV.Columns[1].DataPropertyName;
myChart.Series[0].YValueMembers = myOutputDGV.Columns[3].DataPropertyName;
myChart.DataSource = myOutputDGV.DataSource;
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
}
}
EDIT 4 i have grids and half a line:
var datax = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[1].Value).ToList();
var datay = myOutputDGV.Rows.Cast<DataGridViewRow>().Select(x => x.Cells[4].Value).ToList();
string dataxx = datax.ToString();
string datayy = datay.ToString();
System.Windows.Forms.DataVisualization.Charting.ChartArea myChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
myChart.ChartAreas.Add(myChartArea);
myChart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series());
myChart.Series[0].Points.AddXY(dataxx, datayy);
If you want to preserve your code as much as possible, you can fill a DataTable
instead of the DataGridView
and use that as the DataSource
in both the DataGridView
and Chart
.
Following code is roughly what you need to do for this case: Declare the DataTable
, create Columns
(of correct types, I just guessed them!), fill the Rows
, and use it as DataSource
.
The benefits are clear: You will have forced data-types and you can use a breakpoint and VS Data Visualizer to check, if the content looks as expected (but you'll see it in this case in DataGridView
too). It might be the data type giving you a trouble in the chart
.
C# (translated):
private DataTable dt;
private void MyForm_Load()
{
LoadDefaults();
}
private void LoadDefaults()
{
dt.Columns.Add("Line", typeof(Int16));
dt.Columns.Add("Section", typeof(string));
dt.Columns.Add("Range", typeof(string));
dt.Columns.Add("Total", typeof(float));
}
private void processButton_Click(object sender, EventArgs e)
{
foreach (var Item in mySplit) {
dt.Rows.Add({Item.Trim(), ......});
}
this.DataGridView1.DataSource = dt;
...
myChart.DataSource = dt;
}
VB.NET
Dim dt As DataTable
Private Sub MyForm_Load()
Call LoadDefaults()
End Sub
Private Sub LoadDefaults()
dt.Columns.Add("Line", GetType(Int16))
dt.Columns.Add("Section", GetType(String))
dt.Columns.Add("Range", GetType(String))
dt.Columns.Add("Total", GetType(Single))
End Sub
Private Sub processButton_Click(sender As Object, e As EventArgs) Handles BtnExcel.Click
For Each Item In mySplit
dt.Rows.Add({Item.Trim(), Item.Split("(cost=", StringSplitOptions.None).First(), Regex.Match(Item, @"cost=(.+?) rows").Groups[1].Value, Regex.Match(Item, @"cost=(.+?)\.\.").Groups[1].Value})
Next
Me.DataGridView1.DataSource = dt
...
myChart.DataSource = dt
End Sub
EDIT - debugging charts example:
There are many ways to use Chart DataBinding . - I suggest, when binding, not to bind to the chart but to the Points
of a Series
! - This way you can control things better, like choosing which Series
to bind to.
An example..:
var datax = dataGridView1.Rows
.Cast<DataGridViewRow>().Select(x => x.Cells[ixName].Value).ToList();
var datay = dataGridView1.Rows
.Cast<DataGridViewRow>().Select(x => x.Cells[yName].Value).ToList();
aSeries.Points.DataBindXY(datax, datay);
..where xName
and yName
can be names or indices of the DGV Columns
.
But, as has been suggested, using a DataTable
is recommended. In any case you need an IEnumerable
to bind.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.