MSChart : How to add custom label in bar chart - c#

I want to add custom label something like that ( Category 1 and Category 2 ) but not getting idea whether I need to add new series or using custom label function.. Any help would be much appreciated.
Here is my Data Table,
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Section";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User1";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User2";
dt.Columns.Add(dc);
DataRow dr;
dr = dt.NewRow();
dr["Question"] = "A";
dr["Section"] = "Category 1";
dr["User1"] = "1";
dr["User2"] = "2";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "B";
dr["Section"] = "Category 1";
dr["User1"] = "4";
dr["User2"] = "5";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "C";
dr["Section"] = "Category 1";
dr["User1"] = "2";
dr["User2"] = "5";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "X";
dr["Section"] = "Category 2";
dr["User1"] = "3";
dr["User2"] = "5";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "Y";
dr["Section"] = "Category 2";
dr["User1"] = "5";
dr["User2"] = "1";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "Z";
dr["Section"] = "Category 2";
dr["User1"] = "6";
dr["User2"] = "5";
dt.Rows.Add(dr);
My Chart plotting code,
Series Series = new Series("Series1");
Chart4.Series.Add("Series1");
Chart4.Series.Add("Series2");
Chart4.ChartAreas.Add("ChartArea1");
// Set series chart type
Chart4.Series["Series1"].ChartType = SeriesChartType.Bar;
Chart4.Series["Series2"].ChartType = SeriesChartType.Bar;
// Draw as 3D Cylinder
Chart4.Series["Series1"]["DrawingStyle"] = "Cylinder";
Chart4.Series["Series2"]["DrawingStyle"] = "Cylinder";
Chart4.DataSource = dt.DefaultView;
Chart4.ChartAreas["ChartArea1"].AxisX.Interval = 1;
Chart4.Series["Series1"].XValueMember = "Question";
Chart4.Series["Series1"].YValueMembers = "User1";
Chart4.Series["Series2"].YValueMembers = "User2";
Chart4.DataBind();
Solution
DataTable dt = new DataTable();
DataColumn dc;
dt.Columns.Add("Id", typeof(int));
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Section";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User1";
dt.Columns.Add(dc);
DataRow dr;
dr = dt.NewRow();
dr["Question"] = "AA";
dr["Id"] = 1;
dr["Section"] = "Category1";
dr["User1"] = "6";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "BB";
dr["Id"] = 2;
dr["Section"] = "Category1";
dr["User1"] = "1";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "XX";
dr["Id"] = 3;
dr["Section"] = "Category2";
dr["User1"] = "3";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "YY";
dr["Id"] = 4;
dr["Section"] = "Category2";
dr["User1"] = "4";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Question"] = "ZZ";
dr["Id"] = 5;
dr["Section"] = "Category2";
dr["User1"] = "2";
dt.Rows.Add(dr);
Series Series = new Series("Series1");
Chart4.Series.Add("Series1");
Chart4.ChartAreas.Add("ChartArea1");
Chart4.Series["Series1"].ChartType = SeriesChartType.Bar;
Chart4.Series["Series1"]["BarLabelStyle"] = "Center";
Chart4.Series["Series1"]["DrawingStyle"] = "Cylinder";
Chart4.Series["Series1"].XValueMember = "Question";
Chart4.Series["Series1"].YValueMembers = "User1";
Chart4.DataSource = dt;
Chart4.DataBind();
foreach (var g in dt.AsEnumerable().GroupBy(x => x.Field<string>("Section")))
{
string section = g.Key;
var questions = g.Select(r => new { Id = r.Field<int>("Id"), Question = r.Field<string>("Question") });
int min = questions.Min(y => y.Id);
int max = questions.Max(y => y.Id);
var sectionlabel=new CustomLabel();
if (min == max)
{
sectionlabel = new CustomLabel(min - 0.5, max + 0.5, section, 1, LabelMarkStyle.LineSideMark);
}
else
{
sectionlabel = new CustomLabel(min, max, section, 1, LabelMarkStyle.LineSideMark);
}
Chart4.ChartAreas[0].AxisX.CustomLabels.Add(sectionlabel);
}
Chart4.ChartAreas["ChartArea1"].AxisX.Interval = 1;

Have you tried this? It will create a group label for items 1-3.
Chart4.ChartAreas["ChartArea1"].AxisX.CustomLabels.Add(1, 3, "Category 1", 1, LabelMarkStyle.LineSideMark);

The easiest way is to just add Annotations to your chart
TextAnnotation text = new TextAnnotation();
text.Text = 'Category 1';
text.X = 20;
text.Y = 20;
Chart4.Annotations.Add(text);
You can also draw the line using a LineAnnotation
http://msdn.microsoft.com/en-us/library/dd456725.aspx

Related

C# Adding rows to a DataTable inside a foreach loop

I'm trying to add variables from a text file into a datatable to be converted into a CSV file but I keep getting this error: "A column named 'Machine Number' already belongs to this DataTable" Im not sure what to do, any help would be appreciated, Thanks :)
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using System.Globalization;
using System.Text;
namespace Ispy
{
public partial class Form1 : Form
{
private DataGridView dexRead;
DataColumn column;
DataTable Data = new DataTable("ISpy");
DataSet dataSet = new DataSet();
DataRow row;
public Form1()
{
InitializeComponent();
ReadFiles();
}
private void ReadFiles()
{
DataTable dataTable;
//Location of Dex Files
DirectoryInfo DexFiles = new DirectoryInfo(Properties.Settings.Default.Dex_File_Path);
//List of file names in Dex File folder
List<string> DexNames = new List<string>();
//Location of Input File
string ExcelFile = Properties.Settings.Default.Excel_File_Path;
//Read Input File
string[] ExcelLines = File.ReadAllLines(ExcelFile);
//Add names of each file to a list
foreach (FileInfo DexFile in DexFiles.GetFiles("*.dex"))
{
DexNames.Add(DexFile.Name);
}
//Excel Input and Dex File Data Marriage
foreach (string Line in ExcelLines)
{
row = Data.NewRow();
dataTable = new DataTable();
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "Machine Number";
column.ReadOnly = false;
column.Unique = true;
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Customer";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "MEI Total Vend Count";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "DEX Total Vend Count";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "Stock Sold";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "Capacity";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.DateTime");
column.ColumnName = "Next Scheduled Visit Date";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Scheduled Visit In:";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Scheduled Visit Day";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Next Visit Stock Prediction";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Route Number";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Route Driver Name";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Current Stock %";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.DateTime");
column.ColumnName = "Date/Time of DEX";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Telemetry Provider";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Days since last refill";
column.AutoIncrement = false;
Data.Columns.Add(column);
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.String");
//column.ColumnName = "Machine #40% Stock in";
//column.AutoIncrement = false;
//Data.Columns.Add(column);
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.String");
//column.ColumnName = "Machine #30% Stock in";
//column.AutoIncrement = false;
//Data.Columns.Add(column);
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.String");
//column.ColumnName = "Optimal Fill Date";
//column.AutoIncrement = false;
//Data.Columns.Add(column);
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.String");
//column.ColumnName = "Optimal Fill Date In:";
//column.AutoIncrement = false;
//Data.Columns.Add(column);
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.String");
//column.ColumnName = "Optimal Fill Day";
//column.AutoIncrement = false;
//Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Sector";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Products";
column.AutoIncrement = false;
Data.Columns.Add(column);
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Machine Type";
column.AutoIncrement = false;
Data.Columns.Add(column);
string[] LineInfo = Line.Split(',');
//Input File Variables (.Trim('"') is to remove artifacts leftover from Input File)
string MachineNumber = LineInfo[0].Trim('"');
string MachineLocation = LineInfo[1].Trim('"');
string TelemetryProvider = LineInfo[7].Trim('"');
string Capacity = LineInfo[9].Trim('"');
string MEIVendCount = LineInfo[10].Trim('"');
string MEICashCount = LineInfo[11].Trim('"');
string LastVisitDate = LineInfo[12].Trim('"');
string MachinePHYSID = LineInfo[13].Trim('"');
string NextScheduledVisit = LineInfo[14].Trim('"');
string RouteName = LineInfo[16].Trim('"');
string DriverName = LineInfo[17].Trim('"');
string MachineModel = LineInfo[18].Trim('"');
string MachineType = LineInfo[19].Trim('"');
string MachineSector = LineInfo[20].Trim('"');
string DEXVendCount = "";
string DEXCashCount = "";
string Difference = "";
string NextScheduledVisitDays = "";
string NextScheduledVisitDay = "";
string NextVisitStockPrediction = "";
string MachineStockSold = "";
string DexNameDate = "";
string DaysSinceLastFill = "";
string MachineStockAt30In = "";
string OptimalFillDate = "";
string OptimalFillDay = "";
//Read each Dex File and retrieve data
foreach (string DexName in DexNames)
{
string[] DexNameData = DexName.Split('_', '.');
int DexPHYSID = Int32.Parse(DexNameData[0]);
string dexNameDate = DexNameData[1] + DexNameData[2];
try
{
//Marriage of Excel File Data and Dex File Data
if (Int32.Parse(MachinePHYSID) == DexPHYSID)
{
//Dex File Variable's
string MeterLine = "";
//Calculate location of each Dex File
string DexFilePath = DexFiles.ToString() + DexName;
//Read all of the Dex File's lines and add to an array
string[] DexLines = File.ReadAllLines(DexFilePath);
//Find Meter Read line and add to an array
foreach (string DexLine in DexLines)
{
MeterLine = Array.Find(DexLines,
element => element.StartsWith("VA1", StringComparison.Ordinal));
}
//Split data from Meter Read line
if (MeterLine != null)
{
string[] MeterReads = MeterLine.Split('*');
//Assign Dex values to Dex variables
DEXCashCount = MeterReads[1];
DEXVendCount = MeterReads[2];
}
DateTime creationDate = DateTime.ParseExact(dexNameDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
DateTime nextScheduledVisit = DateTime.ParseExact(NextScheduledVisit, "ddMMyy", CultureInfo.InvariantCulture);
TimeSpan scheduleDays = DateTime.Today - nextScheduledVisit;
TimeSpan LastVisitDays = DateTime.Today - DateTime.ParseExact(LastVisitDate, "ddMMyy", CultureInfo.InvariantCulture);
int Differential = Int32.Parse(DEXVendCount) - Int32.Parse(MEIVendCount);
int stockSold = Int32.Parse(Capacity) - Differential;
double percent = 0;
if (stockSold != 0)
{
percent = (double)(stockSold * 100) / Int32.Parse(Capacity);
}
else
{
percent = 0;
}
row["Machine Number"] = Int32.Parse(MachineNumber);
row["Customer"] = MachineLocation;
row["MEI Total Vend Count"] = Int32.Parse(MEIVendCount);
row["DEX Total Vend Count"] = Int32.Parse(DEXVendCount);
row["Stock Sold"] = Differential;
row["Capacity"] = Int32.Parse(Capacity);
row["Next Scheduled Visit Date"] = DateTime.ParseExact(NextScheduledVisit, "ddMMyy", CultureInfo.InvariantCulture);
row["Scheduled Visit In:"] = scheduleDays.Days.ToString() + " Days";
row["Scheduled Visit Day"] = nextScheduledVisit.DayOfWeek.ToString();
row["Next Visit Stock Prediction"] = "N/A";
row["Route Number"] = RouteName;
row["Route Driver Name"] = DriverName;
row["Current Stock %"] = percent.ToString() + " %";
row["Date/Time of DEX"] = creationDate;
row["Telemetry Provider"] = TelemetryProvider;
row["Days since last refill"] = LastVisitDays.Days.ToString() + " Days";
row["Sector"] = MachineSector;
row["Products"] = MachineModel;
row["Machine Type"] = MachineType;
dataTable.ImportRow(row);
}
}
catch(Exception e)
{
}
}
}
dataSet.Tables.Add(Data);
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = Data.Columns.Cast<DataColumn>().
Select(column1 => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row1 in Data.Rows)
{
IEnumerable<string> fields = row1.ItemArray.Select(field => field.ToString());
sb.AppendLine(string.Join(",", fields));
}
File.WriteAllText(#"\\DC01\Dev\Dexr\Excel Files\Output\test.csv", sb.ToString());
}
private void Load_Properties()
{
string configFile = "config.cfg";
string path = Path.Combine(Environment.CurrentDirectory, #"Data\", configFile);
}
}
}
You need to declare datatable and add data columns only once outside foreach loop.
//Prepare Datatable and Add All Columns Here
dataTable = new DataTable();
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "Machine Number";
column.ReadOnly = false;
column.Unique = true;
column.AutoIncrement = false;
//Excel Input and Dex File Data Marriage
foreach (string Line in ExcelLines)
{
//Add new row and assign values to columns, no need to add columns again and again in loop which will throw exception
row = dataTable.NewRow();
//Map all the values in the columns
row["ColumnName"]= value;
//At the end just add that row in datatable
dataTable.Rows.Add(row );
}
i see you add columns to DataTable Data every time in foreach loop
so try adding these column outside the loop
private void sBAdd_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("MonthlyActualPeriod1", typeof(System.Int32));
dt.Columns.Add("MonthlyActualPeriod2", typeof(System.Int32));
dt.Columns.Add("YearlyActualYear1", typeof(System.Int32));
dt.Columns.Add("YearlyActualYear2", typeof(System.Int32));
dt.Columns.Add("MonthlyBudgetPeriod1", typeof(System.Int32));
dt.Columns.Add("MonthlyBudgetPeriod2", typeof(System.Int32));
dt.Columns.Add("YearlyBudgetYear1", typeof(System.Int32));
dt.Columns.Add("YearlyBudgetYear2", typeof(System.Int32));
dt.Columns.Add("MonthlyActualCurrentPeriod", typeof(System.Int32));
dt.Columns.Add("YearlyActualCurrentyear", typeof(System.Int32));
dt.Columns.Add("YearlyActualPrioryear", typeof(System.Int32));
dt.Columns.Add("MonthlyBudgetCurrentPeriod", typeof(System.Int32));
dt.Columns.Add("YearlyBudgetCurrentyear", typeof(System.Int32));
dt.Columns.Add("YearlyBudgetPrioryear", typeof(System.Int32));
for (int i = 1; i < 61; i++)
{
dt.Columns.Add("MonthlyActualCurrentPeriod-" + i, typeof(System.Int32));
dt.Columns.Add("MonthlyBudgetCurrentPeriod-" + i, typeof(System.Int32));
}
int j = dt.Columns.Count;
DataRow row;
foreach (DataColumn cl in dt.Columns)
{
row = dt.NewRow();
for (int i = 0; i < j; i++)
{
row[i] = 1;
}
dt.Rows.Add(row);
}
this.gcCalcFields.DataSource = dt;
// Create an unbound column.
GridColumn unbColumn = gridView1.Columns.AddField("CalcFields");
unbColumn.VisibleIndex = gridView1.Columns.Count;
unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Object;
ColumnFilterMode prev = unbColumn.FilterMode;
unbColumn.FilterMode = ColumnFilterMode.Value;
gridView1.ShowUnboundExpressionEditor(unbColumn);
unbColumn.FilterMode = prev;
string Calculation = "";
Calculation = unbColumn.UnboundExpression;
LBCCalcFieldsActual.Items.Add(Calculation);
gridView1.Columns.Remove(gridView1.Columns["CalcFields"]);
}

MSChart: line chart UI does not look proper

I was trying to generate winform line chart from data table but UI does not look good.
see the UI
also see my full sample code. I believe I am missing something in code for which chart UI does not look good. I do not understand for what reason a white box is coming in chart?
please see my full code and tell me what I need to add or rectify in my code.
code
private void show()
{
DataRow dr = null;
DataTable dt = new DataTable();
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("data", typeof(Int32));
dt.Columns.Add("CountryCode", typeof(string));
dr = dt.NewRow();
dr[0] = DateTime.Parse("01/01/2017");
dr[1] = 03;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("02/01/2017");
dr[1] = 09;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("03/01/2017");
dr[1] = 15;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("04/01/2017");
dr[1] = 22;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("05/01/2017");
dr[1] = 13;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("06/01/2017");
dr[1] = 22;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("07/01/2017");
dr[1] = 07;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("08/01/2017");
dr[1] = 11;
dr[2] = "GB";
dt.Rows.Add(dr);
Chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;
//Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
Chart1.BorderlineColor = System.Drawing.Color.FromArgb(26, 59, 105);
Chart1.BorderlineWidth = 3;
Chart1.BackColor = Color.NavajoWhite;
Chart1.ChartAreas.Add("chtArea");
Chart1.ChartAreas[0].AxisX.Title = "Category Name";
Chart1.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Verdana", 11, System.Drawing.FontStyle.Bold);
Chart1.ChartAreas[0].AxisY.Title = "UnitPrice";
Chart1.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Verdana", 11, System.Drawing.FontStyle.Bold);
Chart1.ChartAreas[0].BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
Chart1.ChartAreas[0].BorderWidth = 2;
Chart1.Legends.Add("UnitPrice");
Chart1.Series.Add("UnitPrice");
//Chart1.Series[0].Palette = ChartColorPalette.Bright;
Chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
Chart1.Series[0].Points.DataBindXY(dt.DefaultView, "Date", dt.DefaultView, "Data");
//Chart1.Series[0].IsVisibleInLegend = true;
Chart1.Series[0].IsValueShownAsLabel = true;
Chart1.Series[0].ToolTip = "Data Point Y Value: #VALY{G}";
// Setting Line Width
Chart1.Series[0].BorderWidth = 3;
Chart1.Series[0].Color = Color.Red;
// Setting Line Shadow
//Chart1.Series[0].ShadowOffset = 5;
//Legend Properties
Chart1.Legends[0].LegendStyle = System.Windows.Forms.DataVisualization.Charting.LegendStyle.Table;
Chart1.Legends[0].TableStyle = System.Windows.Forms.DataVisualization.Charting.LegendTableStyle.Wide;
Chart1.Legends[0].Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Bottom;
Chart1.Width = 488;
Chart1.Height = 345;
}
Thanks
A Chart comes with a few default elements, like a ChartArea, a Series and a Legend.
If you want to create a ChartArea of your own, why not clear the default ChartArea first? Chart1.ChartAreas.Clear(); Then (and only then) your will actually access your newly created one with the Chart1.ChartAreas[0] references.
I also suggest to use short and nicely named references to Series, ChartAreas etc..:
ChartArea chtArea = Chart1.ChartAreas.Add("chtArea");
Series unitPrice = Chart1.Series.Add("UnitPrice");
This makes the code more compact and clearer..
issue solved. this line causing problem Chart1.ChartAreas.Add("chtArea"); so i removed this line.
my fresh code
private void show()
{
DataRow dr = null;
DataTable dt = new DataTable();
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("data", typeof(Int32));
dt.Columns.Add("CountryCode", typeof(string));
dr = dt.NewRow();
dr[0] = DateTime.Parse("01/01/2017");
dr[1] = 30;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("02/01/2017");
dr[1] = 09;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("03/01/2017");
dr[1] = 15;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("04/01/2017");
dr[1] = 22;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("05/01/2017");
dr[1] = 13;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("06/01/2017");
dr[1] = 22;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("07/01/2017");
dr[1] = 07;
dr[2] = "GB";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr[0] = DateTime.Parse("08/01/2017");
dr[1] = 11;
dr[2] = "GB";
dt.Rows.Add(dr);
//Chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;
////Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
//Chart1.BorderlineColor = System.Drawing.Color.FromArgb(26, 59, 105);
//Chart1.BorderlineWidth = 3;
//Chart1.BackColor = Color.NavajoWhite;
//Chart1.ChartAreas.Add("chtArea");
Chart1.ChartAreas[0].AxisX.Title = "NPS Dates";
Chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -60;
Chart1.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Verdana", 11, System.Drawing.FontStyle.Bold);
Chart1.ChartAreas[0].AxisY.Title = "NPS Values";
Chart1.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Verdana", 11, System.Drawing.FontStyle.Bold);
Chart1.ChartAreas[0].BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
Chart1.ChartAreas[0].BorderWidth = 2;
//Chart1.Legends.Add("UnitPrice");
//Chart1.Series.Add("UnitPricexxx");
//Chart1.Series[0].Palette = ChartColorPalette.Bright;
Chart1.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
Chart1.Series[0].Points.DataBindXY(dt.DefaultView, "Date", dt.DefaultView, "Data");
//Chart1.Series[0].IsVisibleInLegend = true;
Chart1.Series[0].IsValueShownAsLabel = true;
Chart1.Series[0].ToolTip = "Data Point Y Value: #VALY{G}";
// Setting Line Width
Chart1.Series[0].BorderWidth = 3;
Chart1.Series[0].Color = Color.Red;
// Setting Line Shadow
//Chart1.Series[0].ShadowOffset = 5;
//Legend Properties
Chart1.Legends[0].LegendStyle = System.Windows.Forms.DataVisualization.Charting.LegendStyle.Table;
Chart1.Legends[0].TableStyle = System.Windows.Forms.DataVisualization.Charting.LegendTableStyle.Wide;
Chart1.Legends[0].Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Bottom;
Chart1.Width = 488;
Chart1.Height = 345;
}

DataGridView Rows.Remove

I have this code to fill my datagridview from my database.
string query = "SELECT * From guestinfo";
using (con)
{
using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, con))
{
using (DataTable dt = new DataTable())
{
adapter.Fill(dt);
dataGridView1.AutoGenerateColumns = false;
dataGridView1.ColumnCount = 4;
dataGridView1.Columns[0].Name = "RoomNumber";
dataGridView1.Columns[0].HeaderText = "Room Number";
dataGridView1.Columns[0].DataPropertyName= "RoomNumber";
dataGridView1.Columns[1].Name = "GuestName";
dataGridView1.Columns[1].HeaderText = "Guest Name";
dataGridView1.Columns[1].DataPropertyName = "GuestName";
dataGridView1.Columns[2].Name = "RoomType";
dataGridView1.Columns[2].HeaderText = "Room Type";
dataGridView1.Columns[2].DataPropertyName = "RoomType";
dataGridView1.Columns[3].Name = "Status";
dataGridView1.Columns[3].HeaderText = "Status";
dataGridView1.Columns[3].DataPropertyName = "Status";
dataGridView1.DataSource = dt;
dataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders);}}}
And this code to remove the rows with empty value.
for (int i = dataGridView1.Rows.Count - 1; i >= 0; i--)
{
DataGridViewRow dataGridViewRow = dataGridView1.Rows[i];
foreach (DataGridViewCell cell in dataGridViewRow.Cells)
{
string val = cell.Value as string;
if (string.IsNullOrEmpty(val))
{
if (!dataGridViewRow.IsNewRow)
{
dataGridView1.Rows.Remove(dataGridViewRow);
break;
}
}
}
}
This Codes works but when I Add This code some runtime error happened.It Removes all my data. Even it is not empty.
dataGridView1.Columns[4].Name = "CheckDate";
dataGridView1.Columns[4].HeaderText = "Check Date";
dataGridView1.Columns[4].DataPropertyName = "CheckDate";
dataGridView1.Columns[5].Name = "OutDate";
dataGridView1.Columns[5].HeaderText = "Out Date";
dataGridView1.Columns[5].DataPropertyName = "OutDate";

How to arrange datatable using C#

I am building datatable dynamically and the format is like following,
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User1";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User2";
dt.Columns.Add(dc);
dr["Question"] = "2D";
dr["User1"] = "1";
dr["Question"] = "3D";
dr["User1"] = "4";
dr["Question"] = "2D";
dr["User2"] = "2";
dr["Question"] = "3D";
dr["User2"] = "5";
How can I arrange is it like following,
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User1";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "User2";
dt.Columns.Add(dc);
dr["Question"] = "2D";
dr["User1"] = "1";
dr["User2"] = "2";
dr["Question"] = "3D";
dr["User1"] = "4";
dr["User2"] = "5";
You can make linq cross join and filter it to list (you can bind list to your msChart)
var result = (from dr1 in dt.Select()
join dr2 in dt.Select() on dr1["Question"].ToString() equals dr2["Question"].ToString()
select new { q = dr1["question"], u1 = dr1["User1"], u2 = dr2["User2"] }
).Where(row => row.u1.ToString().Length > 0 && row.u2.ToString().Length > 0).ToList();
You could use code similar to this;
DataRow dr = dt.NewRow();
dr["Question"] = "2D";
dr["User1"] = "1";
dr["User2"] = "2";
dr = dt.NewRow();
dr["Question"] = "3D";
dr["User1"] = "4";
dr["User2"] = "5";
Supposing that dr is a variable of type DataRow obtained calling the DataTable method NewRow, then you can add the values to the row ItemArray property in just one line.
Of course you need to be absolutely sure of your columns order and type
DataRow dr = dt.NewRow();
dr.ItemArray = new object[] {"Q1", "1", "2"};
dt.Rows.Add(dr);
dr = dt.NewRow();
dr.ItemArray = new object[] {"Q2", "3", "4"};
dt.Rows.Add(dr);

Multi series bar chart in .NET Chart control

I'm trying multi series bar chart based on "Name" but it's throwing an error
The chart area contains incompatible chart types. For example, bar charts and column charts cannot exist in the same chart area.
Here is my code:
Chart1.Series["Series1"].ChartType = SeriesChartType.Bar;
Chart1.Series["Series1"]["DrawingStyle"] = "Emboss";
Chart1.ChartAreas["ChartArea1"].Area3DStyle.Enable3D = false;
Chart1.Series["Series1"].IsValueShownAsLabel = true;
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Name";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Marks";
dt.Columns.Add(dc);
DataRow dr;
dr = dt.NewRow();
dr["Name"] = "Fred";
dr["Question"] = "2D";
dr["Marks"] = "54";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Bill";
dr["Question"] = "3D";
dr["Marks"] = "66";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Rhona";
dr["Question"] = "4D";
dr["Marks"] = "32";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Peter";
dr["Question"] = "5D";
dr["Marks"] = "46";
dt.Rows.Add(dr);
var IEtable = (dt as System.ComponentModel.IListSource).GetList();
Chart1.DataBindTable(IEtable, "Name");
and Mark up is,
<asp:Chart ID="Chart1" runat="server" Width="850px" Height="500px" >
<Series>
<asp:series Name="Series1" ChartArea="ChartArea1"></asp:series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1">
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
I'm looking for an output like,
Where color bars represents "Names"
This is definitely possible and you'll be able to produce a chart that looks like this:
The following code will get what you need:
ASPX
<asp:Chart ID="Chart1" runat="server" Palette="SeaGreen" BackColor="LightGray" Width="654px">
<Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1" AlignmentOrientation="Horizontal">
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
C#
//Build Sample Data DataTable
DataTable dt = new DataTable();
DataColumn dc;
dc = new DataColumn();
dc.ColumnName = "Name";
dt.Columns.Add(dc);
dc = new DataColumn();
dc.ColumnName = "Question";
dt.Columns.Add(dc);
dt.Columns.Add("Marks", typeof(int));
string question = "2D";
DataRow dr;
dr = dt.NewRow();
dr["Name"] = "Fred";
dr["Question"] = question;
dr["Marks"] = 54;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Bill";
dr["Question"] = question;
dr["Marks"] = 66;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Rhona";
dr["Question"] = question;
dr["Marks"] = 32;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Peter";
dr["Question"] = question;
dr["Marks"] = 46;
dt.Rows.Add(dr);
question = "4D";
dr = dt.NewRow();
dr["Name"] = "Fred";
dr["Question"] = question;
dr["Marks"] = 89;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Bill";
dr["Question"] = question;
dr["Marks"] = 99;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Rhona";
dr["Question"] = question;
dr["Marks"] = 28;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Peter";
dr["Question"] = question;
dr["Marks"] = 44;
dt.Rows.Add(dr);
question = "3D";
dr = dt.NewRow();
dr["Name"] = "Fred";
dr["Question"] = question;
dr["Marks"] = 26;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Bill";
dr["Question"] = question;
dr["Marks"] = 89;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Rhona";
dr["Question"] = question;
dr["Marks"] = 73;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Peter";
dr["Question"] = question;
dr["Marks"] = 14;
dt.Rows.Add(dr);
//Sort the datatable
DataView dv = dt.DefaultView;
dv.Sort = "Question ASC, Name ASC";
dt = dv.ToTable();
DataTable table = new DataTable();
table.Columns.Add("Question", typeof(string));
foreach (DataRow dr2 in dt.Rows)
{
//Add user Names to DataTable table
if (!table.Columns.Contains(dr2["Name"].ToString())) {
table.Columns.Add(dr2["Name"].ToString(), typeof(int));
}
//Add empty Question rows to DataTable
if (table.AsEnumerable().Where(x => x.Field<string>("Question") == dr2["Question"].ToString()).Count() == 0)
{
table.Rows.Add(dr2["Question"].ToString());
}
}
// Loop through all columns and questions and then calculate the mark
for (int i = 1; i < table.Columns.Count;i++ )
{
for (int j = 0; j < table.Rows.Count; j++)
{
string questionName = table.Rows[j][0].ToString();
for (int k = 0; k < dt.Rows.Count; k++)
{
string userName = table.Columns[i].ColumnName;
table.Rows[j][i] = dt.AsEnumerable().Where(x => x.Field<string>("Name") == userName).Where(y=>y.Field<string>("Question") == questionName).Sum(r => r.Field<int>("Marks"));
}
}
}
Chart1.Series[seriesName].ChartType = SeriesChartType.Bar;
//convert datatable to a IEnumerable form
var IEtable = (table as System.ComponentModel.IListSource).GetList();
Chart1.DataBindTable(IEtable, "Question");

Categories