I want my graph to start at 0,0 but right now it is starting at the time that the data starts (because i don't know what a better alternative for xdatamember would be to get my desired results. any suggestions?
private void Form1_Load(object sender, EventArgs e)
{
dataAdapter = new SqlDataAdapter(strSQL, strCon);
commandBuilder = new SqlCommandBuilder(dataAdapter);
// Populate a new data table and bind it to the BindingSource.
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
bindingSource.DataSource = table;
// Resize the DataGridView columns to fit the newly loaded content.
dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
// you can make it grid readonly.
dataGridView.ReadOnly = true;
// finally bind the data to the grid
dataGridView.DataSource = bindingSource;
GraphPane myPane = height.GraphPane;
// Create a new DataSourcePointList to handle the database connection
DataSourcePointList dspl = new DataSourcePointList();
// Specify the table as the data source
dspl.DataSource = table;
dspl.XDataMember = "age";
dspl.YDataMember = "height";
LineItem Curve1 = myPane.AddCurve("student 1", dspl, Color.pink, SymbolType.None);
height.AxisChange();
myPane.Chart.Fill = new Fill(Color.White, Color.LightGray, 45.0F);
// set the title and axis labels
myPane.Title.Text = "student heights";
myPane.XAxis.Title.Text = "age";
myPane.YAxis.Title.Text = "height";
myPane.XAxis.Type = AxisType.Date;
}
First, I did a quick search for this sort of thing and found this: Lock axis in ZedGraph
You can set the XAxis.Min and YAxis.Min to whichevers value you want shown as the min of the respective Axes. My code from my test looked like this:
//static ZedGraph.ZedGraphControl graph = new ZedGraph.ZedGraphControl();
ZedGraph.GraphPane pane = graph.GraphPane;
pane.XAxis.Scale.Min = 0.0;
graph.AxisChange();
graph.RestoreScale(pane);
graph.ZoomOut(pane);
Related
Hello I am searching for a graph that will allow me to make Z Line Graph control now I have X (Payment_Date) & Y (collected) line how to make Z (username) line
I want every username to have his line alone
Can someone help me?
I want to make the program on normal C# win form application
My Form
SqlDataReader reader = sqlcomm.ExecuteReader();
DataTable sd = new DataTable();
sd.Load(reader);
dataGridView1.DataSource = sd;
reader.Close();
chart1.Series["collected"].XValueMember = "Payment_Date";
chart1.Series["collected"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
chart1.Series["collected"].YValueMembers = "collected";
chart1.Series["collected"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
chart1.DataSource = sd;
chart1.DataBind();
Step one: Create a separate BindingSource for each element you want to bind and set an appropriate Filter so it will only display the data of one user each.
Step two: Show and hide the Series you want to.
I have created a DataTable dt with 3 columns:
dt.Columns.Add("User", typeof(string));
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Value", typeof(double));
and filled it randomly. Next I pull out the distinct users:
var users = dt.Rows.Cast<DataRow>()
.Select(x => x.Field<string>("User"))
.Distinct()
.OrderBy(x => x)
.ToList();
Most likely you will reverse this and start with a list of users.
Now I create a Series with its own filtered BindingSource for each user:
for (int i = 0; i < users.Count; i++)
{
Series s = chart1.Series.Add(users[i]);
s.ChartType = SeriesChartType.Line;
BindingSource bs = new BindingSource();
bs.DataSource = dt;
bs.Filter = "User='" + users[i] + "'";
s.Points.DataBindXY(bs, "Date", bs, "Value");
}
Now I bind my DGV:
BindingSource bsdgv = new BindingSource();
bsdgv.DataSource = dt;
bsdgv.Filter = "";
dataGridView1.DataSource = bsdgv;
I have hidden the Series by making them Transparent. This way the names still show in the Legend. The trick is to keep the original colors in the Series' Tags..:
void hideAllSeries(Chart chart)
{
chart.ApplyPaletteColors();
foreach (Series s in chart.Series)
{
if (s.Color != Color.Transparent) s.Tag = s.Color;
s.Color = Color.Transparent;
}
}
To show or hide a Series I code the MouseClick event:
private void Chart1_MouseClick(object sender, MouseEventArgs e)
{
var hitt = chart1.HitTest(e.X, e.Y);
if (hitt.ChartElementType == ChartElementType.LegendItem)
{
Series s = hitt.Series;
if (s.Color == Color.Transparent)
{
s.Color = (Color)s.Tag;
}
else
{
s.Tag = s.Color;
s.Color = Color.Transparent;
}
}
}
Let's see it at work:
Instead of this solution you may want to add a User selection Checklist and set the DGV's BindingSource's Filter..
I am building a winform point chart using C# where the data comes from a datatable. I've created the points like this:
chart1.Series.Add("series1");
chart1.Series["series1"].ChartType = SeriesChartType.Point;
chart1.Series["series1"].YValueMembers = "VALUE";
chart1.Series["series1"].XValueMember = "DATE";
chart1.DataSource = dt;
I'd like to be able make a legend of the points on the chart using different colors/symbols based on a third column in the datatable dt called product. I've tried a number of things to get this done but nothing is working. How can I accomplish this?
You can use this code I got from msdn page
// Create a new legend called "Legend2".
chart1.Legends.Add(new Legend("Legend2"));
// Set Docking of the Legend chart to the Default Chart Area.
chart1.Legends["Legend2"].DockToChartArea = "Default";
// Assign the legend to Series1.
chart1.Series["Series1"].Legend = "Legend2";
chart1.Series["Series1"].IsVisibleInLegend = true;
Part of my problem was first understanding how to construct charts in the first place. I realized I needed to create a series for each unique product in my datatable and add those to the chart. I first made a list of unique products in the datatable:
List<string> products = new List<string>();
foreach (DataRow row in dt.Rows)
{
if (!products.Contains(row["product"].ToString()))
{
products.Add(row["product"].ToString());
}
}
Then
foreach (string product in products)
{
string seriesName = product;
chart1.Series.Add(seriesName);
DataTable dtprod = new DataTable();
dtprod = dt.Select("product= '" + product + "'").CopyToDataTable();
chart1.Series[seriesName].ChartType = SeriesChartType.Point;
chart1.Series[seriesName].YValueMembers = "VALUE";
chart1.Series[seriesName].XValueMember = "DATE";
chart1.Series[seriesName].Points.DataBindXY(dtprod.Rows,"DATE", dtprod.Rows, "VALUE");
chart1.Series[seriesName].XValueType = ChartValueType.DateTime;
chart1.Series[seriesName].MarkerSize = 10;
}
This produced a point chart with a unique marker for each product. Thanks for your answers!
Possibly a complex question - but here's hoping
I have a generic data grid on a single form (displays whatever table I want from a dataset) simply by swapping tables in the dataset.
I want to double-click on a given record and display a single-record view of the table data with the currently selected record displayed as default, but with the option to page through and edit/view/delete other records i.e.
I want to automatically create a details view form from a datagrid for a given table at runtime. The form should be dynamically created - displaying the dataset in details view with the option to page through single records using the binding source/binding source navigator.
My goal is to improve efficiency/maintainability of the application - rather than create and manage 10+ forms, I simply want to create and manage I generic details form in the same way as I manage I generic gridview form.
So far I have come up with:
public void CreateDetailsForm(BindingSource bs, int rowClicked)
{
Form detailsForm = new Form();
BindingSource newFormBS = new BindingSource();
//assign binding source for use on new detailsForm
newFormBS = bs;
//assign binding source to datatable
DataTable dt = (DataTable)bs.DataSource;
//create the form fields
CreateFormFields(dt); //not yet implemented
//assign form fields to form
//display form
}
Any help on the following appreciated
Generating and assigning the form fields to the form.
Thanks in advance.
it likes:
Form f=new Form();
TextBox t=new TextBox();//generate the controls u need
t.Text = "test";//set the actual value
t.Location=new Point(10,10);
f.Controls.Add(t);
DialogResult dr=f.ShowDialog();
So far I have got the col names generated on the form as follows
List colNames = GetColumnNames(dt);
int offset=25;
int xPos=50;
int yPos = 10;
foreach (string name in colNames)
{
Label l = new Label();
l.Name = name;
l.Width = 200;
l.Text = name;
TextBox t = new TextBox();
t.Name = name;
t.Width=200;
l.Location = new Point(xPos, yPos );
t.Location = new Point(xPos+250, yPos);
f.Controls.Add(l);
f.Controls.Add(t);
yPos = yPos + offset;
}
//TextBox t = new TextBox();//generate the controls u need
//t.Text = "test";//set the actual value
f.Width = 800;
f.Height = 600;
f.Show();
}
private List<string> GetColumnNames(DataTable table)
{
List<string> lstColNames=new List<string>();
if (table != null)
{
lstColNames=
(from DataColumn col in table.Columns
select col.ColumnName).ToList();
}
return lstColNames;
}
Now trying to work on getting the controls to bind to the binding source!
OK - got it working now - had to take a different approach
Created a single detailsView Form
Created a static class called PassBindingSource with a static property bst for passing binding source from gridview to details form
static class PassBindingSource
{
public static BindingSource bst { get; set; }
}
On the detailsView form added the following code
try{ bs.DataSource = PassBindingSource.bst;
DataTable dt = (DataTable)PassBindingSource.bst.DataSource;
List<string> colNames = GetColumnNames(dt);
int offset = 25;
int xPos = 50;
int yPos = 50;
foreach (string name in colNames)
{
Label l = new Label();
l.Name = name;
l.Width = 200;
l.Text = name;
TextBox t = new TextBox();
t.Name = name;
t.Width = 200;
// BindingOperations.SetBinding(t, t.TextProperty, bs);
//binding operation
t.DataBindings.Add(new Binding("Text", bs, t.Name, true));
l.Location = new Point(xPos, yPos);
t.Location = new Point(xPos + 250, yPos);
this.Controls.Add(l);
this.Controls.Add(t);
yPos = yPos + offset;
// dgDetailsView.DataSource = bs;
}
//move to correct record in binding source
bs.Position = PassBindingSource.currentRecord;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private List<string> GetColumnNames(DataTable table)
{
List<string> lstColNames=new List<string>();
if (table != null)
{
lstColNames=
(from DataColumn col in table.Columns
select col.ColumnName).ToList();
}
return lstColNames;
}
SUMMARY
Now it all works - the detailsView controls generated at run-time wired up correctly to the binding source and the datagrid can call this detailsView any time using any table from the dataset by wiring the double-click event of the gridview with the following code
PassBindingSource.bst= bs;
frmDetailsView nf = new frmDetailsView();
nf.Show();
Hope this helps others. Many thanks to User2354374 for the initial steer.
I have a database attached to a C# project, with 3 tables Company, Product, and Inventory. Inventory lists CompanyID, ProductID, and Quantity. Combobox1 lists all the companyID. When you select one, I want listview1 to display only the rows in Inventory with that CompanyID.
//binding DB to memorycopy
this.DBContext = new DBEntities();
listView1.ItemsSource = this.SupPartContext.SPs;
GridViewColumn companyIDColumn = new GridViewColumn();
sNumColumn.Width = 90;
sNumColumn.Header = "companyID";
sNumColumn.DisplayMemberBinding = new Binding("COMPANYID");
GridViewColumn ProductIDColumn = new GridViewColumn();
pNumColumn.Width = 90;
pNumColumn.Header = "ProductID";
pNumColumn.DisplayMemberBinding = new Binding("PRODUCTID");
GridViewColumn quantityColumn = new GridViewColumn();
qtyColumn.Width = 90;
qtyColumn.Header = "quantity";
qtyColumn.DisplayMemberBinding = new Binding("QUANTITY");
GridView newGridview = new GridView();
newGridview.Columns.Add(companyIDColumn);
newGridview.Columns.Add(productIDColumn);
newGridview.Columns.Add(quantityColumn);
listView1.View = newGridview;
Any help, even a point in the right direction would be appreciated. Thank you for your time.
If you are wanting the list view to change automatically without writing any code you're probably not going to be able to get that to happen. However, if you rebind the list when the combo box value changes with the following line it will filter the list as you expect.
listView1.ItemsSource = this.SupPartContext.SPs.Where(sp => sp.CompanyID = {get the select company from the row here})
I have a datagridview on my page, the datasource of which keeps changing based on records retrieved with pair of values from 2 combo-boxes,
I need to add a checkbox column to my datagrid, which has no databinding with any column from my database table, i am using this code
public void RefreshDataGrid(string query)
{
Buisness_logic bl = new Buisness_logic();
dataGridView1.DataSource = bl.GetDataTable(query);
SetUpDataGridView();
dataGridView1.ClearSelection();
}
public void SetUpDataGridView()
{
DataGridViewCellStyle style = dataGridView1.ColumnHeadersDefaultCellStyle;
style.BackColor = Color.White;
style.ForeColor = Color.Black;
dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dataGridView1.RowHeadersVisible = false;
dataGridView1.Columns[0].HeaderText = "Sr.No";
dataGridView1.Columns[0].Width = 50;
dataGridView1.Columns[1].HeaderText = "Rate";
dataGridView1.Columns[1].Width = 70;
dataGridView1.Columns[2].HeaderText = "Amount";
dataGridView1.Columns[2].Width = 100;
dataGridView1.Columns[3].HeaderText = "Mode";
dataGridView1.Columns[3].Width = 60;
dataGridView1.Columns[4].HeaderText = "Support";
dataGridView1.Columns[4].Width = 80;
dataGridView1.Columns[5].HeaderText = "Team1";
dataGridView1.Columns[5].Width = 100;
dataGridView1.Columns[6].HeaderText = "Team2";
dataGridView1.Columns[6].Width = 100;
dataGridView1.Columns[7].HeaderText = "Team3";
dataGridView1.Columns[7].Width = 100;
DataGridViewCheckBoxColumn column3 = new DataGridViewCheckBoxColumn();
column3.Name = "Column3";
column3.HeaderText = "IsCheck";
column3.ReadOnly = false;
dataGridView1.Columns.Add(column3);
}
It datagridview is good when tge form loads the first time, but when i change the value of the combo-boxes and the datasource changes, the columns get messed up, and a no. of checkbox columns get added and that ruins my form,
here is the code i used to retrieve the records from table
Combo_pair pr1 = combo_match_code.SelectedItem as Combo_pair;
int match_code_f1 = Convert.ToInt32(pr1.Text);
Combo_pair pair = combo_name.SelectedItem as Combo_pair;
int userid_f1 = Convert.ToInt32(pair.Value);
string query = "Select int_sr_no,double_rate,double_amount,txt_mode,txt_support,double_team1,double_team2,double_team3 from match_transaction where int_match_code='" + match_code_f1 + "' AND int_user_id='" + userid_f1 + "' AND is_deleted=0";
RefreshDataGrid(query);
this is the image when the form loads for the first time
and this is the image after i change the combo box values a few times
*(sorry, having trouble with images)
i really need some help with these, thanxx
Before the answer I'm just going to restate the problem in steps (so that my solution hopefully makes more sense):
You have a databound DataGridView where you want to change details of columns
When you want refresh the data in the grid (your search criteria change) your changes to the columns are overwritten
To fix this you update date grid datasource and remake all the changes
This has the side effect that an unbound checkbox column you add is being added multiple times
So the problem in a nutshell is how to keep the changes to columns while also only having the one column?
The trick here is the DataGridView's AutoGenerateColumns property.
For sake of argument let is say that you first setup your grid during the form load - if not then you might need a boolean field to store if you have previously setup the grid.
public Form1()
{
InitializeComponent();
// So this is the first time we call your refresh grid with some default string query
RefreshDataGrid(query);
// Now one time only we call SetUpDataGridView()
SetUpDataGridView();
// Now once we have done that we set AutoGenerateColumns to false
dataGridView1.AutoGenerateColumns = false;
}
public void RefreshDataGrid(string query)
{
Buisness_logic bl = new Buisness_logic();
dataGridView1.DataSource = bl.GetDataTable(query);
// We no longer need to call SetUpDataGridView()
// SetUpDataGridView();
dataGridView1.ClearSelection();
}
Your SetUpDataGridView() method is pretty much identical:
public void SetUpDataGridView()
{
DataGridViewCellStyle style = dataGridView1.ColumnHeadersDefaultCellStyle;
style.BackColor = Color.White;
style.ForeColor = Color.Black;
dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dataGridView1.RowHeadersVisible = false;
dataGridView1.Columns[0].HeaderText = "Sr.No";
dataGridView1.Columns[0].Width = 50;
// And so on for all the columns...
dataGridView1.Columns[7].Width = 100;
DataGridViewCheckBoxColumn column3 = new DataGridViewCheckBoxColumn();
column3.Name = "Column3";
column3.HeaderText = "IsCheck";
column3.ReadOnly = false;
dataGridView1.Columns.Add(column3);
}
So now when the combboxes containing the query information change you can call RefreshDataGrid() but it will only update the data, not change your custom settings.
One suggestion for the RefreshDataGrid() method is to add a line like so:
public void RefreshDataGrid(string query)
{
Buisness_logic bl = new Buisness_logic();
// This is the new line
dataGridView1.DataSource = typeof(List<>);
dataGridView1.DataSource = bl.GetDataTable(query);
// We no longer need to call SetUpDataGridView()
// SetUpDataGridView();
dataGridView1.ClearSelection();
}
This can reduce flicker as column widths change and also is often necessary to make changing the DataSource show at all.
You need to setup the gridview only once.
A good place to do this is after InitializeComponent().
Since this is a fixed column, you could also add it through the designer (Edit Columns).
That way the code would get add to InitializeComponent().
InitializeComponent() is usually called in the constructor of your form.
At present you are adding this line
dataGridView1.Columns.Add(column3);
Will cause the checkbox column to be added several times.