I am creating stackedbar chart for may following datatable did search over google for all possible solutions and modified my code but i dont know if my logic is going wrong this is my datatable
and this is my Code:
private void fillStackedChart()
{
dt = new DataTable();
cmd = new MySqlCommand("SELECT STATUS , count( resultstatus ) AS Total_Count, clashresult.floor_srno, floor_master.floor_Name FROM clashresult INNER JOIN floor_master ON clashresult.floor_srno = floor_master.floor_srno WHERE floor_master.project_srno =2 GROUP BY STATUS , clashresult.floor_srno, floor_master.floor_Name ORDER BY floor_master.floor_Name", con);
da = new MySqlDataAdapter(cmd);
dt = new DataTable();
da.Fill(dt);
StackedChart.DataSource = dt;
DataTable dt2 = new DataTable();
MySqlDataAdapter adp = new MySqlDataAdapter("SELECT Distinct status from clashresult inner join floor_master on clashresult.floor_srno=floor_master.floor_srno where floor_master.project_srno=2 group by STATUS,clashresult.floor_srno,floor_master.floor_Name", con);
adp.Fill(dt2);
int amountofrows = Convert.ToInt32(dt2.Rows.Count);
for (int i = 0; i < amountofrows; i++)
{
List<string> xvals = new List<string>();
List<decimal> yvals = new List<decimal>();
string serieName = dt2.Rows[i]["status"].ToString();
StackedChart.Series.Add(serieName);
StackedChart.Series[i].ChartType = SeriesChartType.StackedBar;
//FORMATTING THE CHART
StackedChart.Series[i].Label = dt.Rows[i]["Total_Count"].ToString();
StackedChart.Legends.Add(new Legend(dt2.Rows[i]["status"].ToString()) { Docking = Docking.Right });
StackedChart.Series[i].BorderWidth = 0;
StackedChart.Series[i].BorderColor = Color.Black;
StackedChart.Series[i]["PixelPointWidth"] = "30";
StackedChart.Series[i].LabelForeColor = Color.White;
StackedChart.BackColor = Color.LightSkyBlue;
foreach (DataRow dr in dt.Rows)
{
try
{
if (String.Equals(serieName, dr["status"].ToString(), StringComparison.Ordinal))
{
xvals.Add(dr["floor_Name"].ToString());
yvals.Add(Convert.ToDecimal(dr["Total_Count"].ToString()));
}
}
catch (Exception)
{
throw new InvalidOperationException("Diagrammet kunde inte ritas upp");
}
}
try
{
StackedChart.Series[serieName].XValueType = ChartValueType.String;
StackedChart.Series[serieName].YValueType = ChartValueType.Auto;
StackedChart.Series[serieName].Points.DataBindXY(xvals.ToArray(), yvals.ToArray());
}
catch (Exception)
{
throw new InvalidOperationException("Diagram Cannnot Be displayed!");
}
}
StackedChart.DataBind();
StackedChart.Visible = true;
}
and I am getting the out put like this
but the output i am looking for is like this: all bars should look like the following bars
This is just single stacked bar but i want the same in above chart.
Please help where i am going wrong.
Thanks in advance
Related
I'm new to C#, so I apologize in advance if this question is inappropriate.
I have a method with the following code:
if (activeReservation != 0)
{
SqlDataAdapter da = new SqlDataAdapter(cmd2);
DataTable dt = new DataTable();
da.Fill(dt);
con.Close();
List<Reservation> resList = new List<Reservation>();
resList = (from DataRow dr in dt.Rows
select new Reservation()
{
roomType = dr["Room Type"].ToString(),
roomNumber = dr["Room Number"].ToString(),
date = dr["Date"].ToString(),
time = dr["Time"].ToString(),
numStudents = Convert.ToInt32(dr["Number of Students"]),
duration = dr["Duration"].ToString(),
}).ToList();
}
What would be the return type of this method if I want to return the list of object resList ?
If you want to return the whole list of resList, then return the list itself:
public List<Reservation> Reservations()
{
List<Reservation> resList = new List<Reservation>();
if (activeReservation != 0)
{
SqlDataAdapter da = new SqlDataAdapter(cmd2);
DataTable dt = new DataTable();
da.Fill(dt);
con.Close();
resList = (from DataRow dr in dt.Rows
select new Reservation()
{
roomType = dr["Room Type"].ToString(),
roomNumber = dr["Room Number"].ToString(),
date = dr["Date"].ToString(),
time = dr["Time"].ToString(),
numStudents = Convert.ToInt32(dr["Number of Students"]),
duration = dr["Duration"].ToString(),
}).ToList();
}
return resList;
}
The return type of this method should be
List<Reservation>
And method should return resList
I am working a project and i need to display on a form (frmCaterlogs) a list of items. I have successfully implimented a custom list using a user control & FlowLayOutPanel. However now i am stuck on how i can bind my caterlogs that sits on a sql database to my custom list: Here is my code. on the custome_list(CatList), i have 4 controls, Id, Titile, Description, Icon stored in database as binarydata in the sqldb. I am lost on how i can bind data to the custom list control that can look thought all the records in my database. Thanking you all in advace for your kind advices.
private void PopulateCatelog()// This code is triggered when frmcaterlogs loads.
{
int l;
string query = "SELECT * from ServicesCaterlogs";
SqlConnection con = new SqlConnection(cn);
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
ListView Items = new ListView()
sda.Fill(dt);
l = dt.Rows.Count;
foreach(DataRow dr in dt.Rows) // This is where i am stuck
{
CatList iList = new CatList(dr["Item"].ToString());
iList.Title = dr;
}
CatList[] ListItem = new CatList[l];
//Loop though to check each item
for (int i = 0; i < ListItem.Length; i++)
{
ListItem[i] = new CatList();
ListItem[i].Title = fetch data for a list;
ListItem[i].Message = "fetch data for a lis";
ListItem[i].icon = Resources.Warning;
ListItem[i].IconBackground1 = Color.DarkGoldenrod;
if (FlowLayoutPanel.Controls.Count < 0)
{
FlowLayoutPanel.Controls.Clear();
}
else
{
FlowLayoutPanel.Controls.Add(ListItem[i]);
}
}
I got the desired result after altering the code as seen below
private void FrmCatalogs_Load(object sender, EventArgs e)
{
PopulateCatelog();
}
private void PopulateCatelog()
{
//Populate your listitem here
int l;
string query = "SELECT * from ServicesCaterlogs";
SqlConnection con = new SqlConnection(cn);
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
l = dt.Rows.Count;
foreach(DataRow dr in dt.Rows)
{
ListViewItem item = new ListViewItem(dr["Item"].ToString());
ListViewItem des = new ListViewItem(dr["Item_Description"].ToString());
CatList[] ListItem = new CatList[l];
for (int i = 0; i < ListItem.Length - l +1 ; i++)
{
ListItem[i] = new CatList();
ListItem[i].Title = item.Text;
ListItem[i].Message = des.Text;
ListItem[i].icon = Resources.Warning;
ListItem[i].IconBackground1 = Color.DarkGoldenrod;
if (FlowLayoutPanel.Controls.Count < 0)
{
FlowLayoutPanel.Controls.Clear();
}
else
{
FlowLayoutPanel.Controls.Add(ListItem[i]);
}
}
}
}
My chart doesn't seem to display the right values when it's a really small number (less than one). When I have big values (greater than one) it seems to chart and scale everything just fine. Any idea what I'm doing wrong?
My Charting Code:
private void do_chart_Conc(RunningTests rt, Chart c)
{
c.Series.Clear();
set_chart_alignment(c);
DataTable dt = SQL.get_Conc(rt);
c.DataSource = dt;
Series s = new Series("Conc");
s.XValueMember = "Time_Stamp";
s.YValueMembers = "Conc";
s.ChartType = SeriesChartType.Line;
s.BorderWidth = 2;
s.MarkerSize = 5;
s.MarkerStyle = MarkerStyle.Circle;
s.IsValueShownAsLabel = true;
s.Label = "#VALY{0.0000}";
c.ChartAreas[0].AxisY.IsStartedFromZero = false;
c.ChartAreas[0].AxisX.LabelStyle.Format = "yyyy-MM-dd\nHH:mm:ss";
c.ChartAreas[0].AxisY.LabelStyle.Format = "0.0000";
c.ChartAreas[0].RecalculateAxesScale();
c.Series.Add(s);
c.Legends.Clear();
}
My SQL Code:
static public DataTable get_Conc(RunningTests rt)
{
DataTable dt = new DataTable();
using (SqlConnection cs = new SqlConnection(connString))
{
string query = string.Empty;
if (rt.StopTime.Ticks > 0)
{
query = string.Format("SELECT Time_Stamp, RawConc FROM Test WHERE Unit_ID = '{0}' AND Time_Stamp > '{1}' AND Time_Stamp < '{2}'", rt.Unit_ID, rt.StartTime.Ticks, rt.StopTime.Ticks);
}
else
{
query = string.Format("SELECT Time_Stamp, RawConc FROM Test WHERE Unit_ID = '{0}' AND Time_Stamp > '{1}'", rt.Unit_ID, rt.StartTime.Ticks);
}
SqlCommand cmd = new SqlCommand(query, cs);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
//Person stored the date time to ticks, have to convert back to DateTime
DataTable dtCloned = new DataTable();
dtCloned.Clear();
dtCloned.Columns.Add("Time_Stamp", typeof(DateTime));
dtCloned.Columns.Add("Conc", typeof(int));
foreach (DataRow dr in dt.Rows)
{
DataRow r = dtCloned.NewRow();
r[0] = new DateTime((long)dr[0]);
r[1] = dr[1];
dtCloned.Rows.Add(r);
}
dtCloned.DefaultView.Sort = "Time_Stamp DESC";
dtCloned = dtCloned.DefaultView.ToTable();
return dtCloned;
}
Example Chart I'm getting:
Zoomed:
The example Data:
I would like it to chart the actual values and display them (instead of zero). IE: -0.0021
You are losing precision because you are feeding in a table with y-values as int.
Change
dtCloned.Columns.Add("Conc", typeof(int));
to
dtCloned.Columns.Add("Conc", typeof(double));
and all should be well..
This value (val1) I'm passing through url (I mean this operation as jobong filter option in checkbox list, filtering by selection index then passing through another page and retrieve through database):
Default Page 3: /WebSite4/Default4.aspx?vaL1=blue,red
This retrieving form page to view in page.
Default Page 2:
public void grid()
{
con.Open();
cmd = new SqlCommand("select * from lady_cloth where color in('" + Request.QueryString["vaL1"] + "')", con);
SqlDataAdapter da1 = new SqlDataAdapter(cmd);
DataSet ds3 = new DataSet();
da1.Fill(ds3);
con.Close();
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
SqlConnection con = new SqlConnection("Data Source=xxxx;Initial Catalog=e_commerce;User ID=sa;Password=xxx");
SqlCommand cmd = new SqlCommand();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Label1.Text = Request.QueryString["Item"];
//Label2.Text = Request.QueryString["Color"];
//grid();
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
}
string sql = "SELECT * FROM lady_cloth WHERE color IN (SELECT Value FROM #Colours)";
cmd = new SqlCommand(sql, con);
DataSet ds3 = new DataSet();
using (var adapter = new SqlDataAdapter(sql, con))
{
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
//parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
cmd.Parameters.Add(parameter);
con.Open();
adapter.Fill(ds3);
}
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
I think your problem is that you are not separating your items, so your SQL ends up looking like:
select *
from lady_cloth
where color in('blue,red')
Whereas what you would really want is
select *
from lady_cloth
where color in('blue','red')
If you are using SQL Server 2008 or later then I would recommend using table-valued parameters. The first step would be to create your type:
CREATE TYPE dbo.StringList TABLE (Value NVARCHAR(MAX));
I tend to just create generic types that can be easily reused, but this would be your call.
Then in your method you would need to split your values into an array and add them to a datatable:
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
You can then add this table to your command as a parameter:
string sql = "SELECT * FROM lady_clock WHERE Color IN (SELECT Value FROM #Colours)"
cmd = new SqlCommand(sql, con);
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
cmd.Parameters.Add(parameter);
Finally, You can reduce your code by just initialising the SqlDataAdapter with your SQL and connection:
public void grid()
{
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
string sql = "SELECT * FROM lady_clock WHERE Color IN (SELECT Value FROM #Colours)"
DataSet ds3 = new DataSet();
using (var adapter = new SqlDataAdapter(sql, con))
{
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
adapter.Parameters.Add(parameter);
con.Open();
da1.Fill(ds3);
}
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
At this line of code dr = dt.Rows[k]; I am getting the exception Object reference not set to an instance of an object. where I am going wrong?
public partial class EditEngClgList : Form
{
public EditEngClgList()
{
InitializeComponent();
try
{
acccon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb");
acccon.Open();
}
catch (Exception err)
{
MessageBox.Show("Error:" + err);
}
string sql = "Select * From EngColeges order by EngClgID";
da = new OleDbDataAdapter(sql, acccon);
cmdb = new OleDbCommandBuilder(da);
dt1 = new DataTable();
da.Fill(dt1);
bs = new BindingSource();
bs.DataSource = dt1;
dataGridView1.DataSource = bs;
dataGridView1.Columns[1].Visible = false;
}
private void button4_Click(object sender, EventArgs e)
{
List<int> checkedclg = new List<int>();
DataRow dr;
List<int> checkedclgid = new List<int>();
for (int i = 0; i <= dataGridView1.RowCount - 1; i++)
{
if (Convert.ToBoolean(dataGridView1.Rows[i].Cells["Delete"].Value) == true)
{
checkedclg.Add(i);
checkedclgid.Add(Convert.ToInt16(dataGridView1.Rows[i].Cells["Delete"].Value));
}
}
foreach (int k in checkedclg)
{
dr = dt.Rows[k]; //this datatable object I hae created in another function
dt.Rows[k].Delete();
foreach (int j in checkedclgid)
{
OleDbCommand oleDbCommand = new OleDbCommand("DELETE FROM EngColeges WHERE EngClgID = #clgID", acccon);
oleDbCommand.Parameters.Add("#clgID", OleDbType.Integer).Value = j;
oleDbCommand.Prepare();
oleDbCommand.ExecuteNonQuery();
}
}
}
Thanks for any help
Place a breakpoint on that line - most likely the dt object is null.
To address the comment that k may be larger than Rows.Count, I would think if the problem was with k, you'd get an exception indicating the index is out of bounds (IndexOutOfBoundsException).