I've got a function to draw a line graph as shown below. The data points are obtained from a MySQL table. However, how can I number each data point in the x axis 1,2,3,4...?
In the example below, the query returns two results and the graph displays the two points so the graph should have 1 and 2 marked on the axis.
EDIT: Initial problem solved. However, for the example above, there are 2 data points but the max x value is 3. Is there a way of setting the maximum x value to equal the number of data points?
protected void chart(int moduleID)
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
string comm = "SELECT * FROM scores WHERE test_id=0 AND module_id=#ModuleID AND user_id=#UserID";
MySqlCommand mySqlCommand = new MySqlCommand(comm, conn);
mySqlCommand.Parameters.Add(new MySqlParameter("#ModuleID", moduleID));
mySqlCommand.Parameters.Add(new MySqlParameter("#UserID", Session["UserID"]));
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(mySqlCommand);
DataTable ds = new DataTable();
Chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
Chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = false;
Chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 1;
Chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = false;
Chart1.ChartAreas["ChartArea1"].AxisX.Title = "attempt no.";
Chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 0;
Chart1.ChartAreas["ChartArea1"].AxisY.Maximum = 100;
Chart1.ChartAreas["ChartArea1"].AxisY.Title = "%";
Chart1.ChartAreas["ChartArea1"].AxisY.TextOrientation = TextOrientation.Horizontal;
try
{
conn.Open();
dataAdapter.Fill(ds);
if (ds.Rows.Count > 0)
{
Chart1.DataSource = ds;
Chart1.Series["Series1"].YValueMembers = "score";
Chart1.DataBind();
}
else
{
Chart1.Visible = false;
lblError2.Text = "No results found.";
}
}
catch
{
lblError.Text = "Database connection error. Unable to obtain data at the moment.";
}
finally
{
conn.Close();
}
}
There is problem with:
Chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Enabled = false;
You have disbled AxisX labels
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.labelstyle.enabled%28v=vs.110%29.aspx
Related
I want to create chart that read the Extra_Process column in my database..It only have two value. "Rush Order" and "Normal Order"
i have this code...
chart1.Series["Order Process"].Points.Clear();
MySqlCommand cmd = new MySqlCommand("SELECT Extra_Process, sum(Extra_Process) qty FROM sketchit.monitoring GROUP BY Extra_Process; ", dc.con);
MySqlDataReader myreader;
try
{
dc.con.Open();
myreader = cmd.ExecuteReader();
while (myreader.Read())
{
this.chart1.Series["Order Process"].Points.AddXY(myreader.GetString("Extra_Process"), myreader.GetInt32("qty"));
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
dc.con.Close();
I want to know how many rush order and normal order in my column but it doesn't show any result. I don't know what to do.
here's the pic
Steps:
Query and get the Count value of both RushOrder and NormalOrder.
Once you get the both count pass it to the following function to generate the PieChart
private void btnChart_Click(object sender, EventArgs e)
{
//Make your Query , Get Count Value for RushOrder and NormalOrder
//Check for Null Value
//Pass the Count to the DrawPieChart() function
//Sample Chart Generation
int nRushOrderCount = Convert.ToInt32(txtRushOrder.Text);
int nNormalOrderCount = Convert.ToInt32(txtNormalOrder.Text);
DrawPieChart(nRushOrderCount, nNormalOrderCount);
}
private void DrawPieChart(int nRushOrder, int nNormalOrder)
{
//reset your chart series and legends
chart1.Series.Clear();
chart1.Legends.Clear();
//Add a new Legend(if needed) and do some formating
chart1.Legends.Add("MyLegend");
chart1.Legends[0].LegendStyle = LegendStyle.Table;
chart1.Legends[0].Docking = Docking.Bottom;
chart1.Legends[0].Alignment = StringAlignment.Center;
chart1.Legends[0].Title = "Order Details";
chart1.Legends[0].BorderColor = Color.Black;
//Add a new chart-series
string seriesname = "MySeriesName";
chart1.Series.Add(seriesname);
//set the chart-type to "Pie"
chart1.Series[seriesname].ChartType = SeriesChartType.Pie;
//Add some datapoints so the series. in this case you can pass the values to this method
chart1.Series[seriesname].Points.AddXY("Rush Order", nRushOrder);
chart1.Series[seriesname].Points.AddXY("Normal Order", nNormalOrder);
chart1.Series[seriesname].IsValueShownAsLabel = true;
}
So I am developing an application in WinForms and I am populating data from an Access database into a Combobox. After populating it I will use the items from the Combobox to display data on my labels. This is what I have to populate data:
public void AutoCompleteBrand()
{
OleDbConnection con = new OleDbConnection(cs.DBConn);
con.Open();
adapter = new OleDbDataAdapter();
adapter.SelectCommand = new OleDbCommand(#"SELECT DISTINCT RTRIM(Phone) FROM tblPhone", con);
ds = new DataSet("ds");
adapter.Fill(ds);
dtable = ds.Tables[0];
cmbPhone.Items.Clear();
foreach (DataRow drow in dtable.Rows)
{
cmbPhone.Items.Add(drow[0].ToString());
}
}
Then inside of Combobox selected index event I will use this code:
private void cmbPhone_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
OleDbConnection con = new OleDbConnection(cs.DBConn);
con.Open();
cmd = new OleDbCommand(#"SELECT DISTINCT
Brand, Phone, Tecnology
FROM tblPhone", con);
OleDbDataAdapter mAdapter = new OleDbDataAdapter(cmd);
DataSet mDataSet = new DataSet();
OleDbDataReader mReader;
mReader = cmd.ExecuteReader();
while (mReader.Read())
{
string sBrand = mReader.GetString(0);
string sPhone = mReader.GetString(1);
string sTec = mReader.GetString(2);
lblBrand.Text = sBrand;
lblPhone.Text = sPhone;
lblTec.Text = sTec;
}
}
catch (Exception ex)
{
MessageBox.Show("Erro\nDetalhes: " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Basically the technology label is too big and when it reaches a length changes line. It is doable?
you just need to set two properties to your label: AutoSize and MaximumSize. AutoSizetells label to grow (both horizontally and vertically) but MaximumSize limits it to certain Width and Height. So. just do something like this:
label1.AutoSize = true;
label1.MaximumSize = new Size(100, 600);
label1.Text = "test string which is pretty long";
Your question is not very clear. You are working with WPF or Winforms ?
Basicly you can try a few things like :
-If winforms, you can set the autosize property = true of your label.
you can try Something like this :
while (mReader.Read())
{
string sBrand = mReader.GetString(0);
string sPhone = mReader.GetString(1);
string sTec = mReader.GetString(2);
lblBrand.Text = sBrand;
lblPhone.Text = sPhone;
lblTec.Text = sTec;
int wdth = sTec.Length * 16; //you can put another value depending your charachter size.
lblTech.Size = new Size(wdth, 22);
}
Or if you can give a fix width to your label and you can check the length of your string to add a new line :
int lngth = 100;
if(sTech.Length > lngth)
{
sTech = sTech.SubString(0, lngth) + Environment.NewLine + sTech.SubString(lngth);
lblTech.Text = sTech;
}
Tell me if it works.
I've done some research and I've managed to found information about drawing a graph where you hard code a Data Table with fixed values.
This is the link: How to create chart using data table
My problem is however;
I don't have a Data Table like that. I have DataAccess class that call the data from a database then stores it in a Data Table;
public DataTable select_top_sheep(string farmerid)
{
dt = new DataTable();
try
{
conn.Open();
SqlCommand cmd =
new SqlCommand("SELECT TOP 10
S.SheepID
,W.Weight
FROM[Farmstat_V1.0].[dbo].[Sheep] S
INNER JOIN[Farmstat_V1.0].[dbo].[Weight] W
ON S.SheepID = W.SheepID
WHERE S.FarmerID = '" + farmerid + "'
ORDER BY W.Weight DESC", conn);
SqlDataReader reader = cmd.ExecuteReader();
dt.Load(reader);
}
catch (Exception)
{
throw;
}
finally
{
conn.Close();
}
return dt;
}
Then on my form I call this method to get the data, but how can I from here display it in a graph? I can see that the data stores successfully in the DataTable when I run the program in debug mode.
I just want to use the basic Chart tool from the toolbox to display the data graphically.
I have managed to figure out the answer with the use of the link I provided in my question.
This is what I did;
protected void Page_Load(object sender, EventArgs e)
{
// Initializes a new instance of the DataAccess class
DataAccess da = new DataAccess();
// The styling of the graph
chart1.Series["Series1"].ChartType = SeriesChartType.Column;
chart1.Series["Series1"].IsValueShownAsLabel = true;
// The required lines for getting the data from the method in the DataAccess
chart1.DataSource = da.select_top_sheep(farmerID);
chart1.Series["Series1"].XValueMember = "SheepID";
chart1.Series["Series1"].YValueMembers = "Weight";
chart1.DataBind();
}
Just need to google it:
Chart sample
public void SampleCode()
{
// some code
foreach (DataRow row in myDataSet.Tables["Query"].Rows)
{
// For each Row add a new series
string seriesName = row["SalesRep"].ToString();
Chart1.Series.Add(seriesName);
Chart1.Series[seriesName].ChartType = SeriesChartType.Line;
Chart1.Series[seriesName].BorderWidth = 2;
for (int colIndex = 1; colIndex < myDataSet.Tables["Query"].Columns.Count; colIndex++)
{
// For each column (column 1 and onward) add the value as a point
string columnName = myDataSet.Tables["Query"].Columns[colIndex].ColumnName;
int YVal = (int)row[columnName];
Chart1.Series[seriesName].Points.AddXY(columnName, YVal);
}
}
DataGrid.DataSource = myDataSet;
DataGrid.DataBind();
}
I keep getting the following error:
"Index was out of range. Must be non-negative and less than the size of the collection", while executing the following code:
try
{
string connectionstring = "server=localhost;user id=root;database=itemdb;password=root";
MySqlConnection conn = new MySqlConnection(connectionstring);
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT item.item_name,location.city,time.month,SUM(unit_sales) FROM sales_fact,time,item,location WHERE(sales_fact.item_key = item.item_key AND sales_fact.location_key = location.location_key AND sales_fact.time_key = time.time_key) GROUP BY item.item_name", conn);
MySqlDataReader dr = cmd.ExecuteReader();
int c = 0;
List<Cube1> cubelist = new List<Cube1>();
while (dr.Read())
{
//i++;
cubelist[c].itemname = dr.GetValue(0).ToString();
cubelist[c].city = dr.GetValue(1).ToString();
cubelist[c].month = dr.GetValue(2).ToString();
cubelist[c].totalsales = (int)dr.GetValue(3);
MessageBox.Show(cubelist[0].totalsales.ToString());
c++;
}
dr.Close();
MySqlDataAdapter da = new MySqlDataAdapter(connectionstring, conn);
DataSet dt = new DataSet();
da.Fill(dt);
dataGridView1.DataSource = dt;
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Where I'm going wrong?
Your list is empty, but you are trying to access it's elements.You should use List<T>.Add method first. In your code:
new List<Cube1>(100);
100 only specifies the Capacity, it isn't the size of your list.It is used to allocate an array with specified length to avoid re-allocation every time you add a new item to your list.
cubelist.Add(new Cube());
cubelist[c].itemname = dr.GetValue(0).ToString();
cubelist[c].city = dr.GetValue(1).ToString();
...
You create a new (empty) List<Cube1> and then try to assign to properties of elements that don't exist because the list is empty. Instead of using cubelist[c], you need to be doing var cube = new Cube1() to instantiate a new Cube1, then assigning the values to its properties, then adding that to the list using cubelist.Add(cube).
List<Cube1> cubelist = new List<Cube1>();
while (dr.Read())
{
// Create a new Cube1 instance
var cube = new Cube1();
// Set its properties
cube.itemname = dr.GetValue(0).ToString();
cube.city = dr.GetValue(1).ToString();
cube.month = dr.GetValue(2).ToString();
cube.totalsales = (int)dr.GetValue(3);
// Add it to the list
cubelist.Add(cube);
MessageBox.Show(cube.totalsales.ToString());
}
You don't need your c variable at all.
I have 1000 markers displayed on map which are retrieved from datagridview. Thats working fine but I want to display text as client name on these markers when clicked. is it possible to do that....
if (comboBox5.SelectedIndex == 4)//(REGION 1)
{
gMapControl1.MapProvider = GMap.NET.MapProviders.GoogleMapProvider.Instance; ;
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerOnly;
GMapOverlay markersOverlay = new GMapOverlay("VCS MAP");
gMapControl1.MaxZoom = 11;
gMapControl1.MinZoom = 1;
gMapControl1.Zoom = 1;
SqlDataReader myReader;
String Query = " SELECT top 200 Latitude,Longitude,client name FROM [ICPS].[dbo].[agreement latlongkir] where region ='5' ";
SqlConnection conDataBase = new SqlConnection(conString);
conDataBase.Open();
SqlCommand cmdDatabase = new SqlCommand(Query, conDataBase);
myReader = cmdDatabase.ExecuteReader();
gMapControl1.HoldInvalidation = true;
while (myReader.Read())
{
string Latitude = myReader["Latitude"].ToString();
string Longitude = myReader["Longitude"].ToString();
string ClientName = myReader["client name"].ToString();
gMapControl1.Position = new PointLatLng(float.Parse(Latitude), float.Parse(Longitude));
GMarkerGoogle marker = new GMarkerGoogle(gMapControl1.Position, GMarkerGoogleType.pink);
markersOverlay.Markers.Add(marker);
gMapControl1.Overlays.Add(markersOverlay);
marker.ToolTip = new GMapRoundedToolTip(marker);
marker.ToolTipText = myReader("ClientName");
}
}
Looks like your missing this. I have implemented something similar with no issue. I have some working code you can take a look at if this doesnt help.
marker.ToolTipMode = MarkerTooltipMode.Always;