Adding legend to winforms point chart - c#

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!

Related

graph line (X,Y,Z) control

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..

How to show dates in a chart in Report Viewer?

I asked a question
How to show dates in a chart in Excel?
I solved that in Excel, But I have the same problem in Report Viewer. It shifts data (related to the previous year) to the right side of the chart.
My date data is in string format.
List<Report> tempList = new List<Report>();
foreach (DataRow row in DT.Rows)
{
Report temp = new Report();//class
temp.Row = Convert.ToInt16(row["Row"].ToString());
temp.Date = row["Date"].ToString();
temp.Value= Convert.ToDouble(row["Value"].ToString());
tempList.Add(temp);
}
Microsoft.Reporting.WinForms.ReportDataSource reportDataSource1 = new Microsoft.Reporting.WinForms.ReportDataSource();
string reportEmbeddedResource = "ETc.Report1.rdlc";
reportDataSource1.Name = "DataSet1";
reportDataSource1.Value = this.ReportBindingSource;
this.reportViewer.LocalReport.DataSources.Add(reportDataSource1);
this.reportViewer.LocalReport.ReportEmbeddedResource = reportEmbeddedResource;
this.ReportBindingSource.DataSource = tempList;
this.reportViewer.RefreshReport();
OK.
In 'Category Group Properties...' --> in 'Sorting' section, change sort type (if you have a uniqe value for each row) or delete it.

MsChart Add Multiple Series from Database

I want to add different line chart one at the time to my chart. So i have a textbox with a button . i input a code and load the series from my database. The problem is that the new line series override the old line series. so i decided to keep tract of the added series into a gridview, i loop through it and fill the chart; same result.
This is my code
void AddSerie(string stockName)
{
try
{
Legend legend = new Legend(stockName);
Chart1.Legends.Add(legend);
Series series = new Series(stockName);
Chart1.Series.Add(series);
string[] _data = new string[3];
_data[0] = stockName;
_data[1] = "2010-01-01";
_data[2] = "2015-03-15";
DataSet ds = DBSelect(_data, "web_price_series");
Chart1.DataSource = ds;
Chart1.Series[stockName].XValueMember = "tdate";
Chart1.Series[stockName].YValueMembers = "value";
Chart1.Series[stockName].ChartType = SeriesChartType.Line;
Chart1.DataBind();
}
catch (Exception)
{
throw;
}
}
this is how i call the method
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
AddSerie(row.Cells[0].Text);
}
}
and i have the legend showing two series but the chart displays only one line.
i added this picture to show the second output of the chart for two companies using MarkerStyle.
This is an example of what i want to achieve .
This is the structure of the table
any help?
Instead of using the databind i used another method:
Chart1.Series[0].Points.AddXY(XValues, Yalues);
void AddSerie(string stockName)
{
try
{
Legend legend = new Legend(stockName);
Chart1.Legends.Add(legend);
Series series = new Series(stockName);
Chart1.Series.Add(series);
string[] _data = new string[3];
_data[0] = stockName;
_data[1] = "2010-01-01";
_data[2] = "2015-03-15";
DataSet ds = DBSelect(_data, "web_price_series");
Chart1.DataSource = ds;
Chart1.Series[stockName].XValueMember = "tdate";
Chart1.Series[stockName].YValueMembers = "value";
Chart1.Series[stockName].ChartType = SeriesChartType.Line;
foreach (DataRow row in ds.Tables[0].Rows)
{
Chart1.Series[stockName].Points.AddXY(row[0], row[1]);
}
// Chart1.DataBind();
}
catch (Exception)
{
throw;
}
}

Ajax Pie Chart C# modify properties

Here is an image of my pie chart now
Here is the c# code for it..
string query = string.Format("select TestName,Count (TestName) AS Counts from VExecutionGlobalHistory where Tester <> 'dit2988' AND TestTypeID = 1 group by TestName", ddlTests.SelectedItem.Value);
DataTable dt = GetData(query);
foreach (DataRow row in dt.Rows)
{
SpecificTestsWeb6.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
{
Category = row["TestName"].ToString(),
Data = Convert.ToDecimal(row["Counts"]),
}
);
}
SpecificTestsWeb6.ChartTitle = "Specific Tests Run";
I need to align the bottom values to the left so i can see them all. I would also like to be able to manually asign colors so there are no repeats. Thanks.
var random = new Random();
foreach (DataRow row in dt.Rows)
{
var color = String.Format("#{0:X6}", random.Next(0x1000000));
SpecificTestsRapp.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
{
Category = row["TestName"].ToString(),
Data = Convert.ToDecimal(row["Counts"]),
PieChartValueColor = color
});
}
SpecificTestsRapp.ChartTitle = "Specific Tests Run";

zed graph: how to make my graph start at 0,0

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);

Categories

Resources