how to retrive the blob image - c#

i have written a code but its not working properly.first i a trying to make a folder and store the image there but as my database is hosted it creating a problem so i store the image as a blob.kindly help me out where i am doing the mistake. thanks.
public void ItemList_with_images(string value)
{
flowLayoutPanelItemList.Controls.Clear();
// string img_directory = Application.StartupPath + #"\ITEMIMAGE\";
// string[] files = Directory.GetFiles(img_directory, "*.png *.jpg");
try
{
conn.Open();
string sql =
"select distinct Item.Item_id,Item.name,Item.image,Item.cost,Item.price, Category.Name as cat_name from Item" +
" INNER JOIN Category ON Item.Category_id=Category.Category_id" +
" INNER JOIN Ingredients ON Item.Item_id=Ingredients.item_id" +
" INNER JOIN Inventory ON Inventory.Inventory_id = Ingredients.invenotry_id" +
" INNER JOIN inventory_detail ON inventory_detail.inventory_id = Inventory.Inventory_id" +
" where(Item.name like '" + value + "%' and inventory_detail.Quantity > 0 and inventory_detail.loc_id =" + UserInfo.Loc_id + ") " +
"OR (Category.Name like '" + value + "%' and inventory_detail.Quantity > 0 and inventory_detail.loc_id =" + UserInfo.Loc_id + ") ";
dataexe.ExecuteSQL(sql, conn);
DataTable dt = dataexe.GetDataTable(sql, conn);
int currentImage = 0;
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dataReader = dt.Rows[i];
Button b = new Button();
//Image i = Image.FromFile(img_directory + dataReader["name"]);
b.Tag = dataReader["Item_id"];
b.Click += new EventHandler(b_Click);
string details = dataReader["Item_id"] +
"\n Name: " + dataReader["name"].ToString() +
"\n Buy price: " + dataReader["cost"].ToString() +
"\n Sell price: " + dataReader["price"].ToString();
b.Name = details;
ImageList il = new ImageList();
il.ColorDepth = ColorDepth.Depth32Bit;
il.TransparentColor = Color.Transparent;
il.ImageSize = new Size(78, 80);
// here i am getting error
il.Images.Add(Image.FromStream(new MemoryStream((byte[]) dataReader["image"])));
// il.Images.Add(Image.FromFile(img_directory + dataReader["image"]));
b.Image = il.Images[0];
b.Margin = new Padding(3, 3, 3, 3);
b.Size = new Size(208, 100);
b.Text.PadRight(4);
b.Text += dataReader["name"].ToString();
b.Text += "\n Price: " + dataReader["price"];
b.Font = new Font("Arial", 9, FontStyle.Bold, GraphicsUnit.Point);
b.TextAlign = ContentAlignment.MiddleLeft;
b.TextImageRelation = TextImageRelation.ImageBeforeText;
flowLayoutPanelItemList.Controls.Add(b);
currentImage++;
}
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
conn.Close();
}
''''
images are not retriving correctly

I'm not sure why you are using an ImageList, if there is a reason please let me know. That being said, here is a very short (and tested) method which loads an image from a file and assigns it to a button's Image property. Below it is an adaptation of the first method, using the datareader as per your code. this method has not been tested.
public void GetImage()
{
MemoryStream stream = new MemoryStream(File.ReadAllBytes(#"C:\Users\Shai Cohen\Pictures\banana.jpg"));
Image image = Image.FromStream(stream);
button1.Image = image;
}
public void GetImageFromDatareader()
{
MemoryStream stream = new MemoryStream((byte[]) dataReader["image"]));
Image image = Image.FromStream(stream);
button1.Image = image;
}

Related

How to add Get.Attribute(src) values into List<string> or am i add values to other list method c#?

I am coding with C# selenium. I need your help. I can find an attribute src and can write it. But I need to add these values to an existing List, because I will use it for adding these values to the database. But when I run the provided code, it never updated the List, so it is always empty.
// FIND ELEMENT WHICH WILL BE USE FOR GET.ATTRIBUTE(SRC)
IReadOnlyCollection<IWebElement> imageelements = driver.FindElements(By.CssSelector("div.product-slide"));
List<IWebElement> elements = new List<IWebElement>(imageelements) ;
int a = elements.Count;
string b = Convert.ToString(a);
label5.Text = b;
// LIST FOR STORE THE GET.ATTRIBUTE VALUES
List<string> srclist = new List<string>();
int c = srclist.Count;
int i = 1;
foreach (IWebElement element in elements)
{
// GET ATRRIBUTE(SRC) OF ELEMENT
var imagetag = element.FindElement (By.TagName("img"));
string imagesrc = imagetag.GetAttribute("src");
Thread.Sleep(1000);
// ADDING VALUES TO LIST ------- IT IS MY PROBLEM: VALUES NOT ADDING TO LIST
srclist.Add(imagesrc);
label6.Text = "src " + imagesrc + " " + c;
Thread.Sleep(1000);
label5.Text = "src islenir" + i;
i++;
if (a == i) break;
}
label6.Text = ">>>>>" + c;
EDIT
string currenturl = driver.Url;
// item Name
var itemName = driver.FindElement(By.CssSelector(".pr-new-br")).Text;
// item Price
var itemPrice = driver.FindElement(By.ClassName("prc-dsc")).Text;
label2.Text = itemName + itemPrice;
// FIND ELEMENT WHICH WILL BE USE FOR GET.ATTRIBUTE(SRC)
IReadOnlyCollection<IWebElement> imageelements = driver.FindElements(By.CssSelector("div.product-slide"));
List<IWebElement> elements = new List<IWebElement>(imageelements) ;
int a = elements.Count;
string b = Convert.ToString(a);
label5.Text = b;
// LIST FOR STORE THE GET.ATTRIBUTE VALUES
List<string> srclist = new List<string>();
int c = srclist.Count;
int i = 1;
foreach (IWebElement element in elements)
{
// GET ATRRIBUTE(SRC) OF ELEMENT
var imagetag = element.FindElement (By.TagName("img"));
string imagesrc = imagetag.GetAttribute("src");
Thread.Sleep(1000);
// ADDING VALUES TO LIST ------- IT IS MY PROBLEM: VALUES NOT ADDING TO LIST
srclist.Add(imagesrc);
label6.Text = "src " + imagesrc + " " + c;
Thread.Sleep(1000);
label5.Text = "src islenir" + i;
i++;
if (a == i) break;
}
int gg = srclist.Count;
label6.Text = ">>>>>" + gg;
string combinsrc = string.Join(",", srclist.ToArray());
string connetionstring = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\vsss\veri\veri\excel\veridatabase.mdf;Integrated Security=True";
con = new SqlConnection(connetionstring);
cmd = new SqlCommand();
cmd.Connection = con;
// INSERT INTO DATABASE === ALL CORRECTLY INSERTING JUST ---COMBINSRC--- VALUES NOT INSERT
cmd.CommandText = "INSERT INTO urun (ismi, fiyati, link, hiperlink ) VALUES ('" + itemName + "','" + itemPrice + "','" + currenturl + "','" + combinsrc + "')";
label5.Text = "src alindi";
Thread.Sleep(2000);
con.Open();
cmd.ExecuteNonQuery();
As I could understand your problem, you think that the srclist is never updated, because your variable c is always 0. This is the supposed behavoiur, because you set its value by counting elements in the empty (just created) List and never update it.
The solution is easy, so you just can add the following code line after the srclist.Add(imagesrc);:
c = srclist.Count;
This is not the best practice, but it should help you.

How to obtain data from UserControl to Form? C# WinForms and SQLite

I know that this question has been asked, but unfortunately most of the answers did not solve the problem. So hopefully someone can help me :)
So here is my problem.
I want to get this data from StudentLedgerControl (I encircled it with red). Then transfer this data to a form called StudentLedgerWindow.
Although before all of this, a button must be clicked to show the StudentLedgerWindow, which once showed, the transferred data will appear.
StudentLedgerControl.cs
public void LoadStudentLedger(SQLiteConnection conn)
{
SQLiteCommand sqlite_cmd;
sqlite_cmd = new SQLiteCommand("SELECT * FROM Student", conn);
SQLiteDataReader read = sqlite_cmd.ExecuteReader();
StudentFlowPanel.SuspendLayout();
StudentFlowPanel.Controls.Clear();
while (read.Read())
{
sc = new StudentControl();
sc.StudentIDLabel.Text = "Student ID: " + read.GetInt32(0).ToString(); // id
sc.StudentNameLabel.Text = read.GetString(1) + " " + read.GetString(2) + " " + read.GetString(3); // fullname
sc.StudentSectionLabel.Text = "Section: " + read.GetString(4); // section
sc.StudentLevelLabel.Text = "Level: " + read.GetInt32(5).ToString(); // level
StudentFlowPanel.Controls.Add(sc);
}
StudentFlowPanel.ResumeLayout();
}
StudentLedgerWindow (expected outcome)
Show Window Button Event and User Interface
private void ViewLedgerButton_Click(object sender, EventArgs e)
{
// Once clicked, the data should show on StudentLedgerWindow
}
Thank You in Advance :)
P.S. I'm new here, so if there are any problems with my post pls tell me so that I can change it.
I think I solved it... idk probably...
All I did is create getters and setters (kek, I should have tried this first)
Then calling the getters and setters. (if that makes sense, hopefully it does)
Old Code
public void LoadStudentLedger(SQLiteConnection conn)
{
SQLiteCommand sqlite_cmd;
sqlite_cmd = new SQLiteCommand("SELECT * FROM Student", conn);
SQLiteDataReader read = sqlite_cmd.ExecuteReader();
StudentFlowPanel.SuspendLayout();
StudentFlowPanel.Controls.Clear();
while (read.Read())
{
sc = new StudentControl();
sc.StudentIDLabel.Text = "Student ID: " + read.GetInt32(0).ToString(); // id
sc.StudentNameLabel.Text = read.GetString(1) + " " + read.GetString(2) + " " + read.GetString(3); // fullname
sc.StudentSectionLabel.Text = "Section: " + read.GetString(4); // section
sc.StudentLevelLabel.Text = "Level: " + read.GetInt32(5).ToString(); // level
StudentFlowPanel.Controls.Add(sc);
}
StudentFlowPanel.ResumeLayout();
}
New Code
public void LoadStudentLedger(SQLiteConnection conn)
{
SQLiteCommand sqlite_cmd;
sqlite_cmd = new SQLiteCommand("SELECT * FROM Student", conn);
SQLiteDataReader read = sqlite_cmd.ExecuteReader();
StudentFlowPanel.SuspendLayout();
StudentFlowPanel.Controls.Clear();
while (read.Read())
{
sc = new StudentControl();
sc.StudentId = "Student ID: " + read.GetInt32(0).ToString(); // id
sc.StudentName = read.GetString(1) + " " + read.GetString(2) + " " + read.GetString(3); // fullname
sc.StudentSection = "Section: " + read.GetString(4); // section
sc.StudentLevel = "Level: " + read.GetInt32(5).ToString(); // level
sc.StudentIDLabel.Text = "Student ID: " + read.GetInt32(0).ToString(); // id
sc.StudentNameLabel.Text = read.GetString(1) + " " + read.GetString(2) + " " + read.GetString(3); // fullname
sc.StudentSectionLabel.Text = "Section: " + read.GetString(4); // section
sc.StudentLevelLabel.Text = "Level: " + read.GetInt32(5).ToString(); // level
StudentFlowPanel.Controls.Add(sc);
}
StudentFlowPanel.ResumeLayout();
}
Getters and Setters
public string _StudentName;
public string _StudentSection;
public string _StudentLevel;
public string _StudentId;
public string StudentName
{
get { return _StudentName; }
set { _StudentName = value; }
}
public string StudentSection
{
get { return _StudentSection; }
set { _StudentSection = value; }
}
public string StudentLevel
{
get { return _StudentLevel; }
set { _StudentLevel = value; }
}
public string StudentId
{
get { return _StudentId; }
set { _StudentId = value; }
}
Thank You :)
And also if there are any code improvements I can do please let me know :)

Visual Studio Database Not Updating

I am working on a school project and for some reason my mysql database doesn't update despite no of row changed is more than 0 and triggering the Update sucessful alert. It also manage to only update my image data from my fileupload.
**admin_products_details_edit.aspx.cs**
protected void btn_ProdEdit_Click(object sender, EventArgs e)
{
int result = 0;
string image = "";
if (FileUpload_ProdImg.HasFile == true)
{
image = "images\\" + FileUpload_ProdImg.FileName;
img_result.ImageUrl = FileUpload_ProdImg.FileName;
}
else
{
image = img_result.ImageUrl;
}
Product Prod = new Product();
string datProdID = lbl_ProdID.Text;
string datProdName = tb_ProdName.Text;
string datProdDesc = tb_ProdDesc.Text;
string datProdImg = img_result.ImageUrl;
decimal datProdPrice = decimal.Parse(tb_ProdPrice.Text);
int datProdCal = int.Parse(tb_ProdCal.Text);
int datStockLvl = int.Parse(tb_StockLvl.Text);
result = Prod.ProductUpdate(datProdID, datProdName, datProdDesc, datProdImg, datProdPrice, datProdCal, datStockLvl);
if (result > 0)
{
string saveimg = Server.MapPath(" ") + "\\" + image;
FileUpload_ProdImg.SaveAs(saveimg);
Response.Write("<script>alert('Update successful');</script>");
Response.Redirect("admin_products_details.aspx?ProdID=" + datProdID);
}
else
{
Response.Write("<script>alert('Update fail');</script>");
}
}<-The code for the button edit event trigger
**Product.cs**
...public int ProductUpdate(string upID, string upName, string upDesc, string upImg, decimal upPrice, int upCal, int upstkLvl)
{
string queryStr = "UPDATE Products SET" + " ProdName = #productName, " + " ProdDesc = #productDesc, " + " ProdImg = #productImage, " + " ProdPrice = #productPrice, " + " ProdCalorie = #productCal, " + " StockLevel = #productStkLvl " + " WHERE ProdID = #productID";
SqlConnection conn = new SqlConnection(_connStr);
SqlCommand cmd = new SqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("#productID", upID);
cmd.Parameters.AddWithValue("#productName", upName);
cmd.Parameters.AddWithValue("#productDesc", upDesc);
cmd.Parameters.AddWithValue("#productImage", upImg);
cmd.Parameters.AddWithValue("#productPrice", upPrice);
cmd.Parameters.AddWithValue("#productCal", upCal);
cmd.Parameters.AddWithValue("#productStkLvl", upstkLvl);
conn.Open();
int nofRow = 0;
nofRow = cmd.ExecuteNonQuery();
conn.Close();
return nofRow;
}<-The code for updating the mysql database,located in a different cs file,titled Product.cs
My mysql database table is called Products
Thank you very much for your help in advance.

Foreach loop not reaching going further than first panel items

It seems to me that my foreach loop is not reaching my second panel or something is making it skip the items in the loop.
Here is the creating of the panels and loop(I know the SQL is vulnerable to injections but for the sake of making the question shorter I just used SQL):
This is what is created for every product in the product table:
Label lbName = new Label();
lbName.Text = name + "\n" + row[7].ToString();
lbName.Height = 40;
lbName.Width = 150;
lbName.Name = name + row[7].ToString();
lbName.Location = new Point(ptX, ptY);
pt.Controls.Add(lbName);
Label lbID = new Label();
lbID.Text = row[0].ToString();
lbID.Height = 40;
lbID.Width = 150;
lbID.Name = "ID" + name + row[7].ToString();
lbID.Location = new Point(ptX, ptY);
lbID.Visible = false;
pt.Controls.Add(lbID);
TextBox txtStockCount = new TextBox();
txtStockCount.Text = "0";
txtStockCount.Height = 40;
txtStockCount.Width = 100;
txtStockCount.Name = "txtTS" + name + row[7].ToString();
txtStockCount.Location = new Point(ptX + 150, ptY);
txtStockCount.GotFocus += txtStockCount_GotFocus;
txtStockCount.KeyPress += txtStockCount_KeyPress;
txtStockCount.LostFocus += txtStockCount_LostFocus;
pt.Controls.Add(txtStockCount);
TextBox txtBroken = new TextBox();
txtBroken.Text = "0";
txtBroken.Height = 40;
txtBroken.Width = 100;
txtBroken.Name = "txtTB" + name + row[7].ToString();
txtBroken.Location = new Point(ptX + 300, ptY);
txtBroken.GotFocus += txtStockCount_GotFocus;
txtBroken.KeyPress += txtStockCount_KeyPress;
txtBroken.LostFocus += txtStockCount_LostFocus;
pt.Controls.Add(txtBroken);
TextBox txtRecieve = new TextBox();
txtRecieve.Text = "0";
txtRecieve.Height = 40;
txtRecieve.Width = 100;
txtRecieve.Name = "txtTR" + name + row[7].ToString();
txtRecieve.Location = new Point(ptX + 450, ptY);
txtRecieve.GotFocus += txtStockCount_GotFocus;
txtRecieve.KeyPress += txtStockCount_KeyPress;
txtRecieve.LostFocus += txtStockCount_LostFocus;
pt.Controls.Add(txtRecieve);
Label lbDifference = new Label();
lbDifference.Text = " 0 ";
lbDifference.Height = 40;
lbDifference.Width = 150;
lbDifference.Name = "lblDiff" + name + row[7].ToString();
lbDifference.Location = new Point(ptX + 600, ptY);
pt.Controls.Add(lbDifference);
Button btnConfirm = new Button();
btnConfirm.Text = "Confirm";
btnConfirm.Height = 30;
btnConfirm.Width = 80;
btnConfirm.Name = "btnConfirm" + name + row[7].ToString();
btnConfirm.Location = new Point(ptX + 750, ptY);
btnConfirm.Click += btnConfirm_Click;
pt.Controls.Add(btnConfirm);
and the reading the panels to update the database from the text boxes:
private void txtStockCount_LostFocus(object sender, EventArgs e)
{
TextBox txtB = (sender as TextBox);
string name = txtB.Name.Remove(0,5);
string prodID = "";
string QtyToday = "";
string QtyBD = "";
string QtyRev = "";
string table = "";
foreach (Panel p in pnls)
{
IEnumerable<Label> labels = p.Controls.OfType<Label>();
foreach (Label label in labels)
{
string Compare = label.Name.Remove(0, 2);
if (name == Compare)
{
prodID = label.Text;
if (Regex.IsMatch(Compare, #"^[a-hA-H]"))
{
table = "ProductHistoryAH";
}
else if (Regex.IsMatch(Compare, #"^[i-qI-Q]"))
{
table = "ProductHistoryIQ";
}
else if (Regex.IsMatch(Compare, #"^[r-zR-Z]"))
{
table = "ProductHistoryRZ";
}
}
}
string sql = "Select * From Product WHERE ProdID = '" + prodID + "'";
DataTable dtP = db.GetDataTable(sql);
IEnumerable<TextBox> textBoxes = p.Controls.OfType<TextBox>();
foreach (TextBox textBox in textBoxes)
{
string name1 = textBox.Name.Remove(0, 5);
label2.Text = name1;
if (name == name1)
{
if (textBox.Name == "txtTS" + dtP.Rows[0][1].ToString() + dtP.Rows[0][7].ToString())
{
QtyToday = textBox.Text;
}
if (textBox.Name == "txtTB" + dtP.Rows[0][1].ToString() + dtP.Rows[0][7].ToString())
{
QtyBD = textBox.Text;
}
if (textBox.Name == "txtTR" + dtP.Rows[0][1].ToString() + dtP.Rows[0][7].ToString())
{
QtyRev = textBox.Text;
}
}
}
string sql1 = "Select * From " + table + " WHERE ProdID = '" + prodID + "' AND ProdHDate = '" + DateTime.Today.Date.ToShortDateString() + "'";
DataTable dt = db.GetDataTable(sql1);
if (dt.Rows.Count == 0)
{
dbh.addnewstockhistory(ph);
}
else if (dt.Rows.Count > 0)
{
dbh.updatestockhistory(ph);
}
}
}
Everything works 100%, it inserts and updates data with ease, with the first panel but no other textboxes on the other panels work.
The error lies in the foreach panel loop, the foreach loops inside the panel loop. It says there is a syntax error near the where of string sql1. But what i dont understand is that it works for the first panel but non of the other panels and it does have the prodID, I know this cause i placed the statement in a label just to see how it looks.
Please help. Ask for anything if you need.
I think I solved it. All I had to do was check if the panel is the panel hosting the control by checking if the panel was the buttons parent and it worked.
if(p == btn.Parent)
{
//Do my stuff
}
in my foreach panel loop.

Is it possible to match two series of data in a chart from two different datasets in c# winforms

I am working on a application to chart boards inspected and board with defects based on work order number. I realize after looking at the chart and comparing the actual data, that the series do not match up for work order number. I am at a loss on how to match both series to the work order number to get a correct chart.
Here is my code for the data pull Boards_Inspected pulled first
public DataSet Get_Boards_Inspected(string startDate, string endDate, int location)
{
DataSet ds = new DataSet();
NpgsqlConnection conn = DatabaseConnection.getConnectionString();
try
{
conn.Open();
NpgsqlDataAdapter da = new NpgsqlDataAdapter("select new_table.top_or_bottom, new_table.board_wo_number, count(new_table.board_serial_number) from" +
" (select distinct master_board.board_serial_number, board_wo.board_wo_number,board_wo.board_part_number, board_time.top_or_bottom from master_board" +
" inner join board_time on board_time.board_time_id = master_board.id" +
" inner join board_wo on board_wo.board_wo_number = master_board.board_wo_number" +
" where time_in between '" + startDate + "' and '" + endDate + "'" +
" and board_time.location_id = '" + location + "')" +
" as new_table" +
" group by new_table.top_or_bottom, new_table.board_wo_number" +
" order by top_or_bottom;", conn);
ds.Reset();
da.Fill(ds);
da.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("An unexpected error has occured with the application. \n" +
"An email has been sent to the software developer for analysis. \n" +
"this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
eMessageBody = ex.ToString();
Mail sendMessage = new Mail();
sendMessage.SendSMTP(eMessageBody, eMessageSubject);
Application.Exit();
}
finally
{
conn.Close();
}
return ds;
}
Board with defects
public DataSet Get_Boards_With_Issue(string startDate, string endDate, int location)
{
DataSet ds = new DataSet();
NpgsqlConnection conn = DatabaseConnection.getConnectionString();
try
{
conn.Open();
NpgsqlDataAdapter da = new NpgsqlDataAdapter("select new_table.top_or_bottom, new_table.board_wo_number, count(new_table.defect_id) from" +
" (select distinct defect_id, top_or_bottom, board_wo_number from defect" +
" inner join master_board on defect.defect_id = master_board.id" +
" where defect_time between '" + startDate + "' and '" + endDate + " 23:59:59'" +
" and location_id = '" + location + "')" +
" as new_table" +
" group by new_table.top_or_bottom, new_table.board_wo_number" +
" order by top_or_bottom;", conn);
ds.Reset();
da.Fill(ds);
da.Dispose();
}
catch(Exception ex)
{
MessageBox.Show("An unexpected error has occured with the application. \n" +
"An email has been sent to the software developer for analysis. \n" +
"this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
eMessageBody = ex.ToString();
Mail sendMessage = new Mail();
sendMessage.SendSMTP(eMessageBody, eMessageSubject);
Application.Exit();
}
finally
{
conn.Close();
}
return ds;
}
Here is my chart series assignment code
private void Boards_Without_Issue_Chart(string starDate, string endDate, int location)
{
try
{
#region Chart Setup
chart1.Series.Clear();
chart1.Series.Add("Boards Inspected");
chart1.Series.Add("Boards Without Issue");
chart1.Series.Add("Boards With Issue");
chart1.Series["Boards Inspected"].Points.Clear();
chart1.Series["Boards Without Issue"].Points.Clear();
chart1.Series["Boards With Issue"].Points.Clear();
chart1.Series["Boards Inspected"]["LabelStyle"] = "Top";
chart1.Series["Boards Without Issue"]["LabelStyle"] = "Top";
chart1.Series["Boards With Issue"]["LabelStyle"] = "Top";
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.Series["Boards Inspected"].ChartType = SeriesChartType.Column;
chart1.Series["Boards Without Issue"].ChartType = SeriesChartType.Column;
chart1.Series["Boards With Issue"].ChartType = SeriesChartType.Column;
chart1.Series["Boards Inspected"]["DrawingStyle"] = "LightToDark";
chart1.Series["Boards Without Issue"]["DrawingStyle"] = "LightToDark";
chart1.Series["Boards With Issue"]["DrawingStyle"] = "LightToDark";
if (chart1.Titles.Contains(t1))
{
t1.Font = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
t1.Text = titleText + " - Boards Without Issue - (" + startDate + " - " +endDate+ ")";
}
else
{
t1.Name = "tTitle1";
t1.Font = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
t1.Text = titleText + " - Boards Without Issue - (" + startDate + " - " + endDate + ")";
chart1.Titles.Add(t1);
}
chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0;
chart1.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
chart1.ChartAreas[0].AxisY.Title = "Amount of Boards";
chart1.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
chart1.ChartAreas[0].AxisX.Title = "Work Order";
chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
chart1.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("Microsoft Sans serif", 12, FontStyle.Regular);
chart1.Series["Boards Inspected"].IsValueShownAsLabel = true;
chart1.Series["Boards With Issue"].IsValueShownAsLabel = true;
#endregion
#region Chart Data Assignment
DataAccess DA = new DataAccess();
DataAccess DA2 = new DataAccess();
DataSet mda = new DataSet();
if ((DA.Get_Boards_Inspected(startDate, endDate, location).Tables[0].Rows.Equals(0)) &&
(DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables[0].Rows.Equals(0)))
lblError.Text = "No information Availiable";
else
{
foreach (DataTable tb in DA.Get_Boards_Inspected(startDate, endDate, location).Tables)
{
foreach (DataRow dr in tb.Rows)
{
object tpn = dr["top_or_bottom"];
var ct = (dr["count"].ToString());
var wo = (dr["board_wo_number"].ToString());
if (tpn == DBNull.Value)
chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
else
chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
}
}
DA.Get_Boards_Inspected(startDate, endDate, location).Clear();
DA.Get_Boards_Inspected(startDate, endDate, location).Dispose();
foreach (DataTable tb2 in DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables)
{
foreach (DataRow dr2 in tb2.Rows)
{
object tpn2 = dr2["top_or_bottom"];
var ct = (dr2["count"].ToString());
var wo = (dr2["board_wo_number"].ToString());
if (tpn2 == DBNull.Value)
chart1.Series["Boards With Issue"].Points.AddXY(wo, ct);
else
chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn2, ct);
}
}
DA2.Get_Boards_With_Issue(startDate, endDate, location).Clear();
DA2.Get_Boards_With_Issue(startDate, endDate, location).Dispose();
}
#endregion
}
catch(Exception ex)
{
MessageBox.Show("An unexpected error has occured with the application. \n" +
"An email has been sent to the software developer for analysis. \n" +
"this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
eMessageBody = ex.ToString();
Mail sendMessage = new Mail();
sendMessage.SendSMTP(eMessageBody, eMessageSubject);
Application.Exit();
MessageBox.Show(ex.ToString());
}
}
EDIT: Here is the code for the chart data
DataAccess DA = new DataAccess();
DataAccess DA2 = new DataAccess();
DataSet mda = new DataSet();
if ((DA.Get_Boards_Inspected(startDate, endDate, location).Tables[0].Rows.Equals(0)) &&
(DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables[0].Rows.Equals(0)))
lblError.Text = "No information Availiable";
else
{
foreach (DataTable tb in DA.Get_Boards_Inspected(startDate, endDate, location).Tables)
{
foreach (DataRow dr in tb.Rows)
{
object tpn = dr["top_or_bottom"];
var ct = (dr["count"].ToString());
var wo = (dr["board_wo_number"].ToString());
if (tpn == DBNull.Value)
chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
else
chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
}
}
DA.Get_Boards_Inspected(startDate, endDate, location).Clear();
DA.Get_Boards_Inspected(startDate, endDate, location).Dispose();
foreach (DataTable tb2 in DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables)
{
foreach (DataRow dr2 in tb2.Rows)
{
object tpn2 = dr2["top_or_bottom"];
var ct = (dr2["count"].ToString());
var wo = (dr2["board_wo_number"].ToString());
if (tpn2 == DBNull.Value)
chart1.Series["Boards With Issue"].Points.AddXY(wo, ct);
else
chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn2, ct);
}
}
DA2.Get_Boards_With_Issue(startDate, endDate, location).Clear();
DA2.Get_Boards_With_Issue(startDate, endDate, location).Dispose();
EDIT: Links
Both data sets, trying to line them up in a chart
Recent chart
This is a classic mistake when working with Chart controls.
They seem to do everything automagically right until you get a little closer and hit upon problems.
Here is the rule:
All Values, both X-Values and all Y-Values are internally stored as doubles.
If you feed in numbers all works fine. If you feed in any other data type you are heading for trouble somewhere down the line.
At first all seems to work and the stuff you feed into shows up nicely in the labels.
But when you want to use any advanced ability of the Chart, chances are it won't work..
This can be something as simple as formatting the labels, which works with string formats only. If you want to use a number format you need to feed in numbers!
You are hitting upon the problem of matching up points in different series.
You have fed in the X-Values as strings and so the trouble starts as soon as the data points need matching beyond the order in which you add them.
You could feed them in the precise order but you need to understand what happens..
Lets have a look behind the scenes..: If you use the debugger to look into the x-Values of your series' datapoints, you will be amazed to see that they all are 0! The strings you fed in, have gone into the labels, but the X-Values are all the result of the failed conversion to double, resulting in 0. This means all datapoint have the same X-Value!
You have two options:
Either add them all in synch, all in the same order and the same number of points in all series.
Use numbers for X-Values.
Your workOrder looks like a number; if it is you can use it, if you want to, but it will then spread out the data according to those numbers. Probably not a good idea. Instead you can assign each workorder an index and use this instead.
To create nice labels use the AxisLabel property for each data point!
It is easiest, imo to create a DataPoint first with values and axislabel and maybe tooltips and colors and whatnot and then add it to the points collection.
Now to let this sink in, have a look at this chart:
This is the code to create it:
private void Form1_Load(object sender, EventArgs e)
{
Random R = new Random(1);
List<Tuple<Series, int>> misses = new List<Tuple<Series, int>>();
chart1.Series.Clear();
for (int i = 0; i < 3; i++ )
{
Series s = new Series("S" + (i + 1));
s.ChartType = SeriesChartType.Column;
chart1.Series.Add(s);
}
chart1.ChartAreas[0].AxisX.Interval = 1;
foreach(Series s in chart1.Series)
{
for (int i = 0; i < 30; i+=3)
{
if (R.Next(3) > 0) s.Points.AddXY(i, i+1);
else misses.Add(new Tuple<Series, int>(s, i));
}
}
foreach (Tuple<Series, int> m in misses)
{
if (m.Item1.Name == "S1") m.Item1.Points.AddXY(m.Item2 + "X", m.Item2 + 5);
else m.Item1.Points.AddXY(m.Item2, m.Item2 + 5);
}
for (int i = 0; i < chart1.Series[0].Points.Count - 1; i++)
{
chart1.Series[0].Points[i].AxisLabel = chart1.Series[0].Points[i].XValue + "%";
}
}
Let's have a look at the things that happen:
I first create three series and then fill a few points into them. However I randomly leave a few slots empty.
I store these in a List of Tuples, so I can later add them out of order.
And you can see that they all match up, except for the blue series 'S1'.
Can you see why?
I always use a nice number for the X-Values, but not for the missed points in the blues series, where I have attached an "X" to the number.
Now these points are added too, but all with an X-Value of 0 and so they all sit at position 0.
Note: Note that the above is not code you can use. It is code to study to learn about the data types of Chart values and the consequences of adding strings as X-Values!
I figured it out, I first changed my DataSets into DataTables. I then created a new column in DataTable 1 that will hold the count field in DataTable 2. I then looped through all the row in DataTable 1 and looped through DataTable 2 and put a select condition to match the top_or_bottom and board_wo_fields and pulled the count value for each match out of DataTable 2 and put them in DataTable 1.
DataTable dt1 = DA.Get_Boards_Inspected(startDate, endDate, location);
DataTable dt2 = DA2.Get_Boards_With_Issue(startDate, endDate, location);
DataColumn newCol = new DataColumn("dcount", typeof(System.Object));
newCol.AllowDBNull = true;
dt1.Columns.Add(newCol);
foreach(DataRow r in dt1.Rows)
{
object wo = (r["board_wo_number"]).ToString();
object tp = (r["top_or_bottom"]).ToString();
if (tp == "")
{
foreach (DataRow r1 in dt2.Select("board_wo_number = '" + wo + "'"))
{
if (r1["count"] == DBNull.Value)
r["dcount"] = 0;
else
r["dcount"] = (r1["count"]);
}
}
else
{
foreach (DataRow r1 in dt2.Select("board_wo_number = '" + wo + "' and top_or_bottom = '" + tp + "'"))
{
if (r1["count"] == DBNull.Value)
r["dcount"] = 0;
else
r["dcount"] = (r1["count"]);
}
}
}
foreach (DataRow dr in dt1.Rows)
{
object tpn = (dr["top_or_bottom"]);
object ct = (dr["count"]).ToString();
object wo = (dr["board_wo_number"]).ToString();
object ct2 = (dr["dcount"]).ToString();
if (tpn == DBNull.Value)
{
chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
chart1.Series["Boards With Issue"].Points.AddXY(wo, ct2);
}
else
{
chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn, ct2);
}
}

Categories