How to add multiple series to the dynamic chart - c#

I put my all code and trying to create a dynamic chart which series comes from database,i looped through listitem collection and trying to populate series and add to the chart.However even i loop through ("#Plant2", DT.Rows[i][0].ToString()); Plant2 and trying to populate multiple series with
plantseries = DT.Rows[i][0].ToString();
Chart1.Series.Add(plantseries);
and then give series the X and Y valuemembers.Finally i can not get all the series in my chart,result indicates last same values for all items in the loop,like my code overwrites the last value onto the same series name.Please help me,i am lost.
string[] lstBox = HiddenField2.Value.Split(seperator, StringSplitOptions.RemoveEmptyEntries);
ListItemCollection lstItemCollection = new ListItemCollection();
for (int i = 0; i < lstBox.Length; i++)
{
lstItemCollection.Add(new ListItem(lstBox[i]));
}
DataTable DT = new DataTable();
DT.Columns.Add("Plant");
foreach (ListItem item in lstItemCollection)
{
DataRow dr = DT.NewRow();
dr["Plant"] = item.Value;
DT.Rows.Add(dr);
}
String plantseries = "";
Chart1.Legends.Add("Plants");
LegendItem legendItem = new LegendItem();
for (int i = 0; i < lstItemCollection.Count; i++)
{
DataTable monthlychart = new DataTable();
if (cnn.State == ConnectionState.Closed)
{
cnn.Open();
SqlCommand cmd1 = new SqlCommand("prc_Chart_individual_plant", cnn);
cmd1.CommandType = System.Data.CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#Plant", strPlants.ToString());
cmd1.Parameters.AddWithValue("#Configuration", strconfig.ToString());
cmd1.Parameters.AddWithValue("#Startdate", dtstart);
cmd1.Parameters.AddWithValue("#Enddate", dtend);
cmd1.Parameters.AddWithValue("#Plant2", DT.Rows[i][0].ToString());
SqlDataAdapter adapt1 = new SqlDataAdapter(cmd1);
adapt1.Fill(monthlychart);
Chart1.DataSource = monthlychart;
cnn.Close();
}
plantseries = DT.Rows[i][0].ToString();
Chart1.Series.Add(plantseries);
Chart1.Series[plantseries].XValueMember = Convert.ToString(monthlychart.Columns[4]);
Chart1.Series[plantseries].YValueMembers = Convert.ToString(monthlychart.Columns[8]);
Chart1.DataBind();
legendItem.Name = plantseries;
legendItem.BorderWidth = 4;
legendItem.ShadowOffset = 1;
Random random = new Random();
Color c = Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
legendItem.Color = c;
Chart1.ChartAreas[0].AxisX.LabelStyle.Format = "M.yy";
Chart1.Series[plantseries].IsVisibleInLegend = true;
Chart1.Series[plantseries].IsValueShownAsLabel = true;
Chart1.Series[plantseries].ToolTip = "Data Point Y Value: #VALY{G}";
}

This is the best approac and it works
for(int j=0; j<monthlychart.Rows.Count; j++)
{
if(monthlychart.Rows[j][4]!=DBNull.Value)
{
DateTime xvalue = Convert.ToDateTime(monthlychart.Rows[j][4]);
double yvalue = Convert.ToDouble(monthlychart.Rows[j][8]);
Chart1.Series[plantseries].Points.AddXY(xvalue,yvalue);
Chart1.DataBind();
}
}

Related

Creating DataTable from Text File and splitting

This is going to be my text file (30 lines)
OrderNo:37374
OrderQuantity:250
BarcodeQR:584,25478Klkd28
NormalBarcode:1565484864
.......
.......
.......
This is the code :
public DataTable DTforReport()
{
DataTable dt = new DataTable();
DataColumn col = new DataColumn("test");
col.DataType = System.Type.GetType("System.String");
dt.Columns.Add(col);
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
foreach (var line in lines)
{
var segments = line.Split(';');
foreach (var seg in segments)
{
DataRow dr = dt.NewRow();
dr[0] = seg;
dt.Rows.Add(dr);
}
}
return dt;
}
I want my output like this
OrderNo OrderQuantity BarcodeQR
37374 250 584,25478Klkd28
How can I change my code to achieve this?
You have generated only one column. Change your code like below to see your desired result:
public DataTable DTforReport()
{
DataTable dt = new DataTable();
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
DataRow dr = dt.NewRow();
for (int i = 0; i < lines.Length; i++)
{
DataColumn col = new DataColumn(lines[i].Split(':')[0]);
col.DataType = Type.GetType("System.String");
dt.Columns.Add(col);
var segment = lines[i].Split(':')[1];
dr[i] = segment;
}
dt.Rows.Add(dr);
return dt;
}
I suggest you to modify your method like the following:
public DataTable DTforReport()
{
DataTable testTable = new DataTable("Test");
testTable.Columns.Add("OrderNo");
testTable.Columns.Add("OrderQuantity");
testTable.Columns.Add("BarcodeQR");
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
foreach (var line in lines)
{
DataRow dRow = testTable.NewRow();
var segments = line.Split(';');
for (int i = 0; i < segments.Length; i++)
{
var colValues = segments[i].Split(':');
dRow[i] = colValues[1];
}
testTable.Rows.Add(dRow);
}
return testTable;
}
Few suggestions for improvement:
I have given static column names, if you want to add more or they may change in future means you can create dynamic columns in the datatable.
If you have doubts in the input values, make use of proper validation
Validations in the sense, make sure about the splitted values before accessing them through index otherwise they may ends up with IndexOutOfRangeException
DataTable dt = new DataTable();
string[] lines = File.ReadAllLines("C:\\Users\\abc\\Desktop\\abc.txt");
var firstLine = lines.First();
var columns = firstLine.Split(';');
for (var icount = 0; icount < columns.Count(); icount++)
{
var colName = columns[icount].Contains(":") ? columns[icount].Split(':')[0] : "Column" + icount;
var dataCol = new DataColumn(colName);
dataCol.DataType = System.Type.GetType("System.String");
dt.Columns.Add(dataCol);
}
foreach (var line in lines)
{
DataRow dr = dt.NewRow();
var segments = line.Split(';');
for (var icount = 0; icount < segments.Count(); icount++)
{
var colVal = segments[icount].Contains(":") ? segments[icount].Split(':')[1] : "";
dr[icount] = colVal;
}
dt.Rows.Add(dr);
}
*Number of column must be same in each row.

Create dynamic buttons while reading from SQL Server

I'm using this code while reading from SQL Server. The problem is that it runs the loop as many times are my SQL Server results.
SqlCommand sqlCmd = new SqlCommand("Select Name from TablesDesigner", con);
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
while (sqlReader.Read())
{
for (int row = 0; row < NUM_ROWS; row++)
{
TableRow tablerow = new TableRow(this);
TableLayout.LayoutParams linearLayoutParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MatchParent, TableLayout.LayoutParams.MatchParent, 1.0f);
tablerow.LayoutParameters = linearLayoutParams;
table.AddView(tablerow);
for (int col = 0; col < NUM_COLS; col++)
{
int FINAL_COL = col;
int FINAL_ROW = row;
Button btn = new Button(this);
TableRow.LayoutParams linearLayoutParams2 = new TableRow.LayoutParams(TableRow.LayoutParams.MatchParent, TableRow.LayoutParams.MatchParent, 1.0f);
btn.LayoutParameters = linearLayoutParams2;
btn.Text = sqlReader["Name"].ToString();
tablerow.AddView(btn);
}
}
}
My result is below:
And my desired result is:
Where should I place my loop for getting the desired result? Or should I break it somehow?
Thanks.
Also what if I want to use two rows??
When confronted with a difficult problem, break it down into manageable bits (this is good coding practice anyway).
First, get the data you need into a single list. Don't forget to Dispose your DataReader.
public List<string> GetButtonNames()
{
var buttonNames = new List<string>();
SqlCommand sqlCmd = new SqlCommand("Select Name from TablesDesigner", con);
using (var sqlReader = sqlCmd.ExecuteReader())
{
while (sqlReader.Read())
{
buttonNames.Add(sqlReader["Name"].ToString());
}
}
return buttonNames;
}
Then write a function to organize it into a 2D list. I stole the logic for this from this question.
public static List<List<string>> Make2DList(List<string> input, int width=4)
{
var output = new List<List<string>>();
for (int i=0; i < input.Count; i+= width)
{
output.Add(input.GetRange(i, Math.Min(width, input.Count - i)));
}
return output;
}
Now you have a list of lists. The "outer" list corresponds to each table row. The inner list is a list of column values within that row.
Now all you need is code to make it into a table. Because we organized the data into a grid already, we can use normal foreach syntax which makes it very easy.
public void RenderButtonTable(List<List<string>> names)
{
var layout = new TableLayout.LayoutParams
(
TableLayout.LayoutParams.MatchParent,
TableLayout.LayoutParams.MatchParent,
1.0f
);
tablerow.LayoutParameters = layout;
foreach (var row in names)
{
TableRow tablerow = new TableRow(this);
tablerow.LayoutParameters = layout;
table.AddView(tablerow);
foreach (var col in row)
{
Button btn = new Button(this);
btn.Text = col;
tablerow.AddView(btn);
}
}
}
Put it all together:
void CreateDynamicButtonsWhileReadingFromSQLServer()
{
var buttonNames = GetButtonNames();
var gridData = Make2DList(buttonNames, NUM_COLS);
RenderButtonTable(gridData);
}

Populate SQL Server data in Excel (2010) spreadsheet

I'm trying to populate the data extracted from SQL Server into Excel 2010. The code below works fine, but the difficulty is that I don't create an Excel spreadsheet programmatically, it is aleady exists and I make a request for data via plugin in Excel written in C#.
Even though I set the cursor to A10 cell, Excel starts filling-out the data from the very first cell and overwrites the header (that is already exists). Please help to fix.
Code:
OdbcConnection cnn;
cnn = new OdbcConnection(azureConn);
using (OdbcCommand command = cnn.CreateCommand())
{
command.CommandText = "{call sp_Get_Excel_Data(?,?,?,?,?,?,?,?)}";
command.Parameters.AddWithValue("#StartDate", startDate);
command.Parameters.AddWithValue("#EndDate", endDate);
command.Parameters.AddWithValue("#startTime", startTime);
command.Parameters.AddWithValue("#endTime", endTime);
command.Parameters.AddWithValue("#smp", smp);
command.Parameters.AddWithValue("#Reg", reg);
command.Parameters.AddWithValue("#event", events);
command.Parameters.AddWithValue("#userId", userId);
cnn.Open();
//DataTable
OdbcDataAdapter adapter = new OdbcDataAdapter(command);
//DataSet
DataSet ds = new DataSet();
adapter.Fill(ds);
//Cast to DataTable
DataTable dataTable = ds.Tables[0];
string[] colNames = new string[dataTable.Columns.Count];
int col = 0;
foreach (DataColumn dc in dataTable.Columns)
colNames[col++] = dc.ColumnName;
w = this.Application.ActiveWorkbook;
ws = (Worksheet)w.ActiveSheet;
Range hdrRow = (Range)ws.Rows[9];
hdrRow.Value = colNames;
hdrRow.Font.Bold = true;
hdrRow.VerticalAlignment = XlVAlign.xlVAlignCenter;
//Position the cursor
var range = ws.get_Range("A10");
range.Select();
//Inserting the Column and Values into Excel file
string data = null;
int i = 0;
int j = 0;
for (i = 0; i <= dataTable.Rows.Count - 1; i++)
{
for (j = 0; j <= dataTable.Columns.Count - 1; j++)
{
data = dataTable.Rows[i].ItemArray[j].ToString();
ws.Cells[i + 2, j + 1] = data;
}
}
Hate to answer my own questions, but here is the solution (with optimized performance):
int column = 1;
foreach (DataColumn c in dataTable.Columns)
{
//Ninth row, starting from the first cell
ws.Cells[10, column] = c.ColumnName;
column++;
}
// Create a 2D array with the data from the data table
int i = 0;
string[,] data = new string[dataTable.Rows.Count, dataTable.Columns.Count];
foreach (DataRow row in dataTable.Rows)
{
int j = 0;
foreach (DataColumn c in dataTable.Columns)
{
data[i, j] = row[c].ToString();
j++;
}
i++;
}
// Set the range value to the 2D array in Excel (10th row, starting from 1st cell)
ws.Range[ws.Cells[11, 1], ws.Cells[dataTable.Rows.Count + 11, dataTable.Columns.Count]].Value = data;

Passing ListView item on textboxes

i have this code and got error with Object reference not set to an instance of an object.
private void updateRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (ListViewItem list in lvViewEmp.Items)
{
Employee ss = new Employee();
ss.Show();
frmEmp.txtEmpID.Text = lvViewEmp.SelectedItems[0].Text;
}
}
this is the code on getting my data.
ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["MyConnection"];
string MyConnection = conSettings.ConnectionString;
con = new SqlConnection(MyConnection);
cmd = con.CreateCommand();
cmd.CommandText = "Select * From tbl_emp_info";
sda = new SqlDataAdapter(cmd);
ds = new DataSet();
dt = new DataTable();
sda.Fill(ds);
sda.Fill(dt);
if (con.State != ConnectionState.Open)
{
con.Open();
{
lvViewEmp.View = View.Details;
foreach (DataColumn c in ds.Tables[0].Columns)
{
ColumnHeader h = new ColumnHeader();
h.Text = c.ColumnName;
h.Width = 90;
lvViewEmp.Columns.Add(h);
}
string[] str = new string[ds.Tables[0].Columns.Count];
foreach (DataRow rr in dt.Rows)
{
for (int col = 0; col <= ds.Tables[0].Columns.Count - 1; col++)
{
str[col] = rr[col].ToString();
}
ListViewItem ii;
ii = new ListViewItem(str);
lvViewEmp.Items.Add(ii);
lvViewEmp.GridLines = true;
lvViewEmp.FullRowSelect = true;
con.Close();
}
}
}
how can i pass all data from the list view through textboxes on other form?

Retrieve data and display into multiple controls with loop , c# asp.net

net sql server , I want a loop to retrieve data from sql database to different label controls using C# asp.net sql server storedprocedure.
string constrng = ConfigurationManager.ConnectionStrings["baby"].ConnectionString;
SqlConnection conn = new SqlConnection(constrng);
SqlCommand sqlComm;
sqlComm = new SqlCommand("stor_proc", conn);
sqlComm.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
SqlDataReader dr = sqlComm.ExecuteReader();
DataSet ds = new DataSet();
ds.Tables.Add("Home");
ds.Tables[0].Load(dr);
m.Text = ds.Tables[0].Rows[0][1].ToString();
i.Text = ds.Tables[0].Rows[0][2].ToString();
d.Text = ds.Tables[0].Rows[0][3].ToString();
g.Text = ds.Tables[0].Rows[0][4].ToString();
m1.Text = ds.Tables[0].Rows[1][1].ToString();
i1.Text = ds.Tables[0].Rows[1][2].ToString();
d1.Text = ds.Tables[0].Rows[1][3].ToString();
g1.Text = ds.Tables[0].Rows[1][4].ToString();
m2.Text = ds.Tables[0].Rows[2][1].ToString();
i2.Text = ds.Tables[0].Rows[2][2].ToString();
d2.Text = ds.Tables[0].Rows[2][3].ToString();
g2.Text = ds.Tables[0].Rows[2][4].ToString();
conn.Close();
for (int i = 0; i < 3; i++ ) {
m.Text = ds.Tables[0].Rows[i][1].ToString();
i.Text = ds.Tables[0].Rows[i][2].ToString();
d.Text = ds.Tables[0].Rows[i][3].ToString();
g.Text = ds.Tables[0].Rows[i][4].ToString();
}
You can use a foreach loop like this:
foreach (DataRow row in ds.Tables[0].Rows)
{
// Now here, you are iterating through a individual row.
// ItemArray gives an index position of a cell within a row.
m.Text = row.ItemArray[0].ToString();
i.Text = row.ItemArray[1].ToString();
d.Text = row.ItemArray[2].ToString();
g.Text = row.ItemArray[3].ToString();
}

Categories

Resources