How to group and name series chart in visual studio c# - c#

I have DataGridView which consist of these data
From these data i would like to make the first column, airport name to group the third column and sum to their corresponding ActLoadQuantityTo which is in the fifth column, the cargo type which landed on the airport. right now my chart is messed up as it look like this
for (int j = 0; j < dgv_3.Rows.Count; j++)
{
double Load_qty = 0;
double new_load_qty = 0;
DiscPort = dgv_3.Rows[j].Cells["ActDiscDischargingPort"].Value.ToString();
DestType = dgv_3.Rows[j].Cells["SchLoadDestination"].Value.ToString();
CargoType = dgv_3.Rows[j].Cells["SchLoadCargoType"].Value.ToString();
string CargoType2 = "Series-" + CargoType;
Load_qty = Convert.ToDouble(dgv_3.Rows[j].Cells["ActLoadQuantityTon"].Value);
if (chart3.Series.IndexOf(DiscPort) != -1)
{
chart3.Series["000 - Port"].Points.AddY(Load_qty);
}
else
{
chart3.Series["000 - Port"].Points.AddXY(DiscPort, Load_qty);
}
}
no grouping of series,etc. i've tried adding more series but it just doesn't make sense toward the DataGridView. and my expectation is that i would like the chart to look like this as I've described before
Any idea what set of code should it be?

I found my desired result by using this code
public void isichartdomestic(System.Data.DataTable initialDataSource)
{
chart3.Titles.Add("Your title");
chart3.Legends.Add("Your Legend");
for (int i = 1; i < initialDataSource.Columns.Count; i++)
{
System.Windows.Forms.DataVisualization.Charting.Series series = new System.Windows.Forms.DataVisualization.Charting.Series();
foreach (DataRow dr in initialDataSource.Rows)
{
double y = (double)dr[i];
series.Points.AddXY(dr["DiscPort"].ToString(), y);
TotalDomestic += y;
}
chart3.Series.Add(series);
string NamaSeries = series.ToString();
NamaSeries = NamaSeries.Replace("Series-","");
chart3.Series[NamaSeries].IsValueShownAsLabel = true;
chart3.Series[NamaSeries].IsVisibleInLegend = true;
if (NamaSeries == "Series1")
{
chart3.Series[NamaSeries].LegendText = "Bag";
}
else if (NamaSeries == "Series2")
{
chart3.Series[NamaSeries].LegendText = "Bulk";
}
else if (NamaSeries == "Series3")
{
chart3.Series[NamaSeries].LegendText = "Clinker";
}
else if (NamaSeries == "Series4")
{
chart3.Series[NamaSeries].LegendText = "Container";
}
}
lb_TotalDomestic.Text = Convert.ToString("Total Domestic: " + TotalDomestic);
TotalDomesticExport += TotalDomestic;
}

Related

How to change exact text value become consist or contains?

Is there a way to convert it, from exact value text become consist of? So I don't need to type Ballet instead of Bal.
Here's the code:
private void button6_Click_1(object sender, EventArgs e)
{
ColumnView View = gridControl1.MainView as ColumnView;
View.BeginUpdate();
try
{
int rowHandle = 0;
DevExpress.XtraGrid.Columns.GridColumn col = View.Columns["genre"];
while (true)
{
// // Locate the next row
rowHandle = View.LocateByValue(rowHandle, col, textBox6.Text);
// // Exit the loop if no row is found
if (rowHandle == DevExpress.XtraGrid.GridControl.InvalidRowHandle)
break;
//// Perform specific operations on the found row
gridView1.FocusedRowHandle = rowHandle;
rowHandle++;
}
}
finally { View.EndUpdate(); }
}
for (int i = 0; i < gridView1.VisibleRowCount; i++)
{
var row = gridView1.GetDataRow(i);
var genre = row["ColumnName"].ToString(); //ColumnName is your genre Column name
if(genre.StartsWith(textBox6.text)){
//here you can set row sellected
}
}
I dont have experience with devexpress but you can try it like this.
i dont if this what u seek, but it solved my own problem
for (int i = 0; i < gridView1.RowCount; i++)
{
var rosw = gridView1.GetDataRow(i);
var genre = rosw["genre"].ToString();
int tmpg = 0;
// //tmpg = genre.IndexOf(textBox8.Text, StringComparison.OrdinalIgnoreCase);
if (genre.IndexOf(textBox8.Text, StringComparison.OrdinalIgnoreCase) >= 0)
{
//if (tmpg >= 1)
// MessageBox.Show(genre);
gridView1.FocusedRowHandle = i;
break;
}
}

Excel Interop - Insert Rows & Repeat

OK so I have this function that works fine at inserting rows and then putting data within those rows.
public void inputRowData(string[] data, int rds)
{
int bestRow = getRowByRDS(rds);
string val = getValueOfCell(bestRow, 6);
if (val == null || val.Equals(""))
{
shiftRows(bestRow, data.Length-1);
string[] formatedData = formatOutput(bestRow, data);
// transform formated data into string[,]
string[][] splitedData = formatedData.Select(s => s.Split('\t')).ToArray();
var colCount = splitedData.Max(r => r.Length);
var excelData = new string[splitedData.Length, colCount];
for (int i = 0; i < splitedData.Length; i++)
{
for (int j = 0; j < splitedData[i].Length; j++)
{
excelData[i, j] = splitedData[i][j];
}
}
oSheet.get_Range("A" + bestRow.ToString()).Resize[splitedData.Length, colCount].Value = excelData;
}
else
{
Console.WriteLine("Line has some information already, skipping 1 more");
shiftRows(bestRow, data.Length + 1);
}
}
Now I if you take a look i find the "bestRow" which is determined by the last row in the excel with a int value at a particular column the code is show here:
private int getRowByRDS(int id)
{
int bestfit = -1;
Boolean foundOne = false;
Microsoft.Office.Interop.Excel.Range usedRange = oSheet.UsedRange;
for (int i = 2; i < usedRange.Rows.Count; i++)
{
string val = getValueOfCell(i, 3);
if (val == null)
continue;
int rds = int.Parse(val);
Console.WriteLine(val + " " +i);
if (rds == id)
{
bestfit = i;
foundOne = true;
}
else
if (foundOne)
return bestfit;
}
return bestfit;
}
What happens is that when it finishes on set of data in the inputRowData method it will move to another set with a different rds value. It will try to call getRowByRDS but it will throw an error.
On debug it looks like it didnt update the sheet... so lets say the first set of 10 strings was inserted at row 900, the and if the next set was suppose to start right after it bestRow will return 901 not 911.
The error is
A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in TTE Tool.exe
I found the problem. I disposed of the excel beforehand by mistake.

Collapsing the space between bars on a StackedBar100 in MSChart

Essentially I have to show rows of bars on a stacked bar chart. There will be one for each question. Optionally there will be an extra bar or two for each question if there's a National score or a Competitor score is available.
My issue is one of presentation. I wish to place the bars central relative to the label for the question or remove gaps if one of the national or competitor scores isn't present.
Perhaps a picture will help:
I put together an example quickly (that generated the above picture) into an MVC project. These are the files:
Index.cshtml
<h2>Attempt 2</h2>
<img src="/Home/StackedBar100" />
<h2>Attempt 1</h2>
<img src="/Home/StackedBar100_FirstAttempt" />
HomeController.cs
<!-- language: c# -->
public class HomeController : Controller
{
List<Color> colors = new List<Color>();
string[] rows = new string[] { "Q1", "Q2", "Q3", "Q4" };
string[] stackTypes = new string[] { "National", "Value", "Competitor" };
Color[] stackColors = new Color[] { Color.White, Color.Green, Color.Orange };
protected override void Initialize(RequestContext requestContext)
{
// Set up bands of colours for testing purposes.
int diff = (255 - 20) / 10;
for (int c = 10; c > 0; c--)
{
colors.Add(Color.FromArgb(0, (c * diff) + 10, 0));
}
base.Initialize(requestContext);
}
public ActionResult Index()
{
return View();
}
public ActionResult StackedBar100()
{
var chart = new Chart();
var chartArea = new ChartArea("Default");
chart.ChartAreas.Add(chartArea);
chart.Width = 640;
chart.Height = 480;
var r = new Random();
for (int s = 0; s < stackTypes.Count(); s++)
{
var stack = stackTypes[s];
var stackColor = stackColors[s];
{
for (int i = 1; i <= 10; i++)
{
var series = new Series(stack + i.ToString());
series.ChartType = SeriesChartType.StackedBar100;
series.Color = colors[i - 1];
series.BorderColor = stackColor;
series["StackedGroupName"] = stack;
series["DrawSideBySide"] = "true";
series.IsValueShownAsLabel = true;
series.LabelForeColor = Color.White;
chart.Series.Add(series);
}
}
}
var dt = CreateData();
foreach (DataRow row in dt.Rows)
{
var question = row["Question"];
var stack = row["Stack"];
var hidden = Convert.ToBoolean(row["Hidden"]);
var ks = "";
for (int k = 1; k <= 10; k++)
{
ks = k.ToString();
chart.Series[stack + ks].Points.AddXY(question, row[ks]);
if (hidden)
{
chart.Series[stack + ks].Points.Last().IsEmpty = true;
}
else if ((row[ks] as double?) < 3)
{
chart.Series[stack + ks].Points.Last().IsValueShownAsLabel = false;
}
}
}
return ReturnChartAsImage(chart);
}
private DataTable CreateData()
{
var r = new Random();
var dt = new DataTable("Chart Data");
dt.Columns.Add("Question", typeof(string));
dt.Columns.Add("Stack", typeof(string));
dt.Columns.Add("Hidden", typeof(string));
for (int i = 1; i <= 10; i++)
{
dt.Columns.Add(i.ToString(), typeof(double));
}
foreach (var row in rows.OrderByDescending(rw => rw))
{
foreach (var stack in stackTypes)
{
if (
(stack == "Value") && row != "Q4" ||
(stack == "National" && (row == "Q2" || row == "Q4")) ||
(stack == "Competitor" && (row == "Q3" || row == "Q4")))
{
var dr = dt.NewRow();
dr["Question"] = row;
dr["Hidden"] = false;
dr["Stack"] = stack;
for (int k = 1; k <= 10; k++)
{
dr[k.ToString()] = r.NextDouble() * 10;
}
dt.Rows.Add(dr);
}
else
{
var dr = dt.NewRow();
dr["Question"] = row;
dr["Stack"] = stack;
dr["Hidden"] = true;
dt.Rows.Add(dr);
}
}
}
dt.WriteXml(#"c:\Users\chris_000\Desktop\1.xml");
return dt;
}
public ActionResult StackedBar100_FirstAttempt()
{
var chart = new Chart();
var chartArea = new ChartArea("Default");
chart.ChartAreas.Add(chartArea);
chart.Width = 640;
chart.Height = 480;
for (int i = 1; i <= 30; i++)
{
var series = new Series("Series" + i.ToString());
series.ChartType = SeriesChartType.StackedBar100;
series.Color = colors[(i - 1) % 10];
if (i <= 10)
{
series["StackedGroupName"] = "Value";
}
else if (i > 10 && i <= 20)
{
series["StackedGroupName"] = "National";
series.BorderColor = Color.Green;
}
else
{
series["StackedGroupName"] = "Competitor";
series.BorderColor = Color.Orange;
}
chart.Series.Add(series);
}
var dt = CreateData_FirstAttempt();
foreach (DataRow row in dt.Rows)
{
var question = row["Question"];
var group = row["Stack"];
for (int k = 1; k <= 30; k++)
{
chart.Series["Series" + k.ToString()].Points.AddXY(question, row[k.ToString()]);
}
}
return ReturnChartAsImage(chart);
}
private DataTable CreateData_FirstAttempt()
{
var r = new Random();
var dt = new DataTable("Chart Data");
dt.Columns.Add("Question", typeof(string));
dt.Columns.Add("Stack", typeof(string)); // Value, National, Competitor
for (int i = 1; i <= 30; i++)
{
dt.Columns.Add(i.ToString(), typeof(double));
}
foreach (var row in rows.OrderByDescending(rw => rw))
{
var dr = dt.NewRow();
dr["Question"] = row;
dr["Stack"] = "Score";
for (int k = 1; k <= 30; k++)
{
if (k <= 10)
{
if (row != "Q4")
{
dr[k.ToString()] = r.NextDouble() * 100;
}
else
{
dr[k.ToString()] = DBNull.Value;
}
}
else if (k > 10 && k <= 20)
{
if (row == "Q2" || row == "Q4")
{
dr[k.ToString()] = r.NextDouble();
}
else
{
dr[k.ToString()] = DBNull.Value;
}
}
else
{
if (row == "Q3" || row == "Q4")
{
dr[k.ToString()] = r.NextDouble();
}
else
{
dr[k.ToString()] = DBNull.Value;
}
}
}
dt.Rows.Add(dr);
}
return dt;
}
private ActionResult ReturnChartAsImage(Chart chart)
{
MemoryStream ms = new MemoryStream();
chart.SaveImage(ms, ChartImageFormat.Png);
return File(ms.ToArray(), "image/png");
}
}
That's a long example, but shows two different attempts at building multiple bars on a stacked chart. One using 30 columns, but splitting every 10 for each group. The second (more sensible) naming the stacks after the Value, National or Competitor they're supposed to represent.
So, in short, can I collapse the space occupied but the missing series/bars? Is it the way I'm feeding the data in perhaps?
Thanks.

Extract Field Names and max lengths from a text file using C#

I have a file that is a SQL Server result set saved as a text file.
Here is a sample of what the file looks like:
RWS_DMP_ID RV1_DMP_NUM CUS_NAME
3192 3957 THE ACME COMPANY
3192 3957 THE ACME COMPANY
3192 3957 THE ACME COMPANY
I want to create a C# program that reads this file and creates the following table of data:
Field MaxSize
----- -------
RWS_DMP_ID 17
RV1_DMP_NUM 17
CUS_NAME 42
This is a list of the field names and their max length. The max length is the beginning of the field to the space right before the beginning of the next field.
By the way I don't care about code performance. This is seldom used file processing utility.
I solved this with the following code:
objFile = new StreamReader(strPath + strFileName);
strLine = objFile.ReadLine();
intLineCnt = 0;
while (strLine != null)
{
intLineCnt++;
if (intLineCnt <= 3)
{
if (intLineCnt == 1)
{
strWords = SplitWords(strLine);
intNumberOfFields = strWords.Length;
foreach (char c in strLine)
{
if (bolNewField == true)
{
bolFieldEnd = false;
bolNewField = false;
}
if (bolFieldEnd == false)
{
if (c == ' ')
{
bolFieldEnd = true;
}
}
else
{
if (c != ' ')
{
if (intFieldCnt < strWords.Length)
{
strProcessedData[intFieldCnt, 0] = strWords[intFieldCnt];
strProcessedData[intFieldCnt, 1] = (intCharCnt - 1).ToString();
}
intFieldCnt++;
intCharCnt = 1;
bolNewField = true;
}
}
if (bolNewField == false)
{
intCharCnt++;
}
}
strProcessedData[intFieldCnt, 0] = strWords[intFieldCnt];
strProcessedData[intFieldCnt, 1] = intCharCnt.ToString();
}
else if (intLineCnt == 3)
{
intLine2Cnt= 0;
intTotalLength = 0;
while(intLine2Cnt < intNumberOfFields)
{
intSize = Convert.ToInt32(strProcessedData[intLine2Cnt, 1]);
if (intSize + intTotalLength > strLine.Length)
{
intSize = strLine.Length - intTotalLength;
}
strField = strLine.Substring(intTotalLength, intSize);
strField = strField.Trim();
strProcessedData[intLine2Cnt, intLineCnt - 1] = strField;
intTotalLength = intTotalLength + intSize + 1;
intLine2Cnt++;
}
}
}
strLine = objFile.ReadLine();
}`enter code here`
I'm aware that this code is a complete hack job. I'm looking for a better way to solve this problem.
Is there a better way to solve this problem?
THanks
I'm not sure how memory efficient this is, but I think it's a bit cleaner (assuming your fields are tab-delimited):
var COL_DELIMITER = new[] { '\t' };
string[] lines = File.ReadAllLines(strPath + strFileName);
// read the field names from the first line
var fields = lines[0].Split(COL_DELIMITER, StringSplitOptions.RemoveEmptyEntries).ToList();
// get a 2-D array of the columns (excluding the header row)
string[][] columnsArray = lines.Skip(1).Select(l => l.Split(COL_DELIMITER)).ToArray();
// dictionary of columns with max length
var max = new Dictionary<string, int>();
// for each field, select all columns, and take the max string length
foreach (var field in fields)
{
max.Add(field, columnsArray.Select(row => row[fields.IndexOf(field)]).Max(col => col.Trim().Length));
}
// output per requirment
Console.WriteLine(string.Join(Environment.NewLine,
max.Keys.Select(field => field + " " + max[field])
));
void MaximumWidth(StreamReader reader)
{
string[] columns = null;
int[] maxWidth = null;
string line;
while ((line = reader.ReadLine()) != null)
{
string[] cols = line.Split('\t');
if (columns == null)
{
columns = cols;
maxWidth = new int[cols.Length];
}
else
{
for (int i = 0; i < columns.Length; i++)
{
int width = cols[i].Length;
if (maxWidth[i] < width)
{
maxWidth[i] = width;
}
}
}
}
// ...
}
Here is what I came up with. The big takeaway is to use the IndexOf string function.
class Program
{
static void Main(string[] args)
{
String strFilePath;
String strLine;
Int32 intMaxLineSize;
strFilePath = [File path and name];
StreamReader objFile= null;
objFile = new StreamReader(strFilePath);
intMaxLineSize = File.ReadAllLines(strFilePath).Max(line => line.Length);
//Get the first line
strLine = objFile.ReadLine();
GetFieldNameAndFieldLengh(strLine, intMaxLineSize);
Console.WriteLine("Press <enter> to continue.");
Console.ReadLine();
}
public static void GetFieldNameAndFieldLengh(String strLine, Int32 intMaxSize)
{
Int32 x;
string[] fields = null;
string[,] strFieldSizes = null;
Int32 intFieldSize;
fields = SplitWords(strLine);
strFieldSizes = new String[fields.Length, 2];
x = 0;
foreach (string strField in fields)
{
if (x < fields.Length - 1)
{
intFieldSize = strLine.IndexOf(fields[x + 1]) - strLine.IndexOf(fields[x]);
}
else
{
intFieldSize = intMaxSize - strLine.IndexOf(fields[x]);
}
strFieldSizes[x, 0] = fields[x];
strFieldSizes[x, 1] = intFieldSize.ToString();
x++;
}
Console.ReadLine();
}
static string[] SplitWords(string s)
{
return Regex.Split(s, #"\W+");
}
}

Merge cells using EPPlus?

I'm using the EPPlus library to read/write Excel files: http://epplus.codeplex.com/
I'm trying to simply merge some cells when writing a document:
using (ExcelPackage pck = new ExcelPackage())
{
//Create the worksheet
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Demo");
//Format the header for column 1-3
using (ExcelRange rng = ws.Cells["A1:C1"])
{
bool merge = rng.Merge;
}
}
There's a property named Merge that simply returns true or false. I thought maybe that would Merge the cells, but it doesn't.
Anyone know how to do this?
You have to use it like this:
ws.Cells["A1:C1"].Merge = true;
instead of:
using (ExcelRange rng = ws.Cells["A1:C1"])
{
bool merge = rng.Merge;
}
If you want to merge cells dynamically, you can also use:
worksheet.Cells[FromRow, FromColumn, ToRow, ToColumn].Merge = true;
All these variables are integers.
You can create a extension method:
public static void Merge(this ExcelRangeBase range)
{
ExcelCellAddress start = range.Start;
ExcelCellAddress end = range.End;
range.Worksheet.Cells[start.Row, start.Column, end.Row, end.Column].Merge = true;
}
You can use this as you would via interop:
range.Merge();
int inicio = CELDA_CUERPO;
bool values = true;
int COLUMNA_A = 0;
int finx_a = 0;
int finy_a = 0;
int COLUMNA_B = 1;
int finx_b = 0;
int finy_b = 0;
//Pintar cabecera:
for (int i = 0; i < ListaCabecera.Length; i++)
{
celda = $"{letras[i]}{CELDA_CABECERA}";
if (i == 0)
{
inicioRango = celda;
}
Sheet.Cells[celda].Value = ListaCabecera[i];
//System.Drawing.Color colFromHex = System.Drawing.ColorTranslator.FromHtml("#B7DEE8");
Sheet.Cells[celda].Style.Font.Color.SetColor(Color.FromArgb(0, 124, 183));
Sheet.Cells[celda].Style.Fill.PatternType = ExcelFillStyle.Solid;
Sheet.Cells[celda].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(232, 235, 249));
Sheet.Cells[celda].Style.Font.Bold = true;
Sheet.Cells[celda].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
}
//Pintar detalle:
for (int i = 0; i < Datos.GetLength(0); i++)
{
for (int j = 0; j < Datos.GetLength(1); j++)
{
celda = $"{letras[j]}{CELDA_CUERPO + i}";
finalizaRango = celda;
if (j < 3) if (Datos[i, j].valor != null && Datos[i, j + 1].valor == null)
{
Sheet.Cells[celda].Style.Font.Color.SetColor(Color.FromArgb(156, 0, 6));
Sheet.Cells[celda].Style.Fill.PatternType = ExcelFillStyle.Solid;
Sheet.Cells[celda].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(255, 199,206));
}
Sheet.Cells[celda].Value = Datos[i, j].valor;
}
//::::::::::::::::::: MERGE A ::::::::::::::::::::
if (i < Datos.GetLength(0) - 1)
{
// :::::::::::::::::::::: x :::::::::::::::::::::::::::::::::
if (values)
{
if (Datos[i, COLUMNA_A].valor == Datos[i, COLUMNA_A].valor)
{
values = false;
finx_a = inicio + i;
finx_b = inicio + i;
//list_x.Add(finx_b);
}
}
else
{
if (Datos[i - 1, COLUMNA_A].valor != Datos[i, COLUMNA_A].valor)
{
finx_a = inicio + i;
}
if (Datos[i - 1, COLUMNA_B].valor != Datos[i, COLUMNA_B].valor)
{
finx_b = inicio + i;
//list_x.Add(finx_b);
}
}
// :::::::::::::::::::::: y (A) :::::::::::::::::::::::::::::::::
if (Datos[i, COLUMNA_A].valor != Datos[i + 1, COLUMNA_A].valor)
{
finy_a = inicio + i;
//list_y.Add(finy);
Sheet.Cells[$"A{finx_a}:A{finy_a}"].Value = Datos[i, COLUMNA_A].valor;
Sheet.Cells[$"A{finx_a}:A{finy_a}"].Merge = true;
Sheet.Cells[$"A{finx_a}:A{finy_a}"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
}
// :::::::::::::::::::::: y (B) :::::::::::::::::::::::::::::::::
if (Datos[i, COLUMNA_B].valor != Datos[i + 1, COLUMNA_B].valor)
{
finy_b = inicio + i;
//list_y.Add(finy_b);
Sheet.Cells[$"B{finx_b}:B{finy_b}"].Value = Datos[i, COLUMNA_B].valor;
Sheet.Cells[$"B{finx_b}:B{finy_b}"].Merge = true;
Sheet.Cells[$"B{finx_b}:B{finy_b}"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
}
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
}

Categories