using DevExpress.Utils;
using DevExpress.XtraCharts;
using OTSCommon.DBOperate.Model;
using OTSIncAReportApp;
using OTSIncAReportApp._1_UI.Control_DEVCharts;
using OTSIncAReportApp.DataOperation.DataAccess;
using OTSIncAReportApp.OTSRstMgrFunction;
using OTSIncAReportApp.OTSSampleReportInfo;
using OTSIncAReportApp.SysMgrTools;
using OTSIncAReportGraph.Class;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace OTSIncAReportGrids
{
///
/// 成分分布表 颗粒成份分布表
///
public partial class CompositionDistributionGrid : UserControl
{
#region settings / fields
// Internationalization
Language lan;
Hashtable table;
// measurement results
ResultFile result = null;
OTSIncAReportApp.OTSSampleReportInfo.ReportCondition source;
OTSIncAReportApp.frmReportApp m_ReportApp;
frmReportConditionChoose m_condition;
List list_gridheight = new List();
//List list_table_data = new List();
//List list_table_size = new List();
//List list_table_Point = new List();
//List list_fileName = new List();
List list_table_data = new List();
List list_table_size = new List();
List list_table_Point = new List();
List list_fileName = new List();
int DataNumber = 0; // current dataset index
List list_ComboBox = new List();
List list_ChartControl = new List();
int gridwidth = 0;
int gridhigh = 0;
int GridPosition = 0;
int chartposition = 0;
int indexGraphicType = 0;
string GraphicType = "柱状图";
// constants for column names used repeatedly
private static readonly string ColRowId = "rowid";
private static readonly string ColTypeName = "TypeName";
private static readonly string ColTypeColor = "TypeColor";
private static readonly string ColCount = "con";
private static readonly string ColAreaRadio = "AreaRadio";
private static readonly string ColAvg = "av";
private static readonly string ColMax = "max";
// list of possible chart types for combo boxes
private static readonly string[] ChartTypes = new string[]
{
"柱状图","折线图","饼图","圆环图","气泡图","簇状条形图","堆积条形图","瀑布图",
"3D柱状图","3D圆环图","3D饼图","3D折线图","3D百分比堆积条形图","3D漏斗图",
"3DManhattan 条形图","3D堆积条形图","3D阶梯线图"
};
#endregion
#region constructor / initialization
public CompositionDistributionGrid(OTSIncAReportApp.frmReportApp ReportApp)
{
m_ReportApp = ReportApp ?? throw new ArgumentNullException(nameof(ReportApp));
result = m_ReportApp.m_rstDataMgr.ResultFilesList[m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
source = m_ReportApp.m_conditionChoose.m_conditionData;
m_condition = ReportApp.m_conditionChoose;
InitializeComponent();
// internationalization
lan = new Language(this);
table = lan.GetNameTable(this.Name);
}
#endregion
#region grid/chart building
///
/// Primary method to bind one data source into a grid and optionally create chart controls.
/// Refactored for clarity and reuse.
///
public void BindDataGridView(string path, int num, string filename)
{
if (string.IsNullOrWhiteSpace(path)) return;
// load translation strings once
string str1 = table["str1"]?.ToString() ?? "No.";
string str2 = table["str2"]?.ToString() ?? string.Empty;
string str3 = table["str3"]?.ToString() ?? "Area";
string str4 = table["str4"]?.ToString() ?? "Avg";
string str5 = table["str5"]?.ToString() ?? string.Empty;
string str6 = table["str6"]?.ToString() ?? "Max";
string str7 = table["str7"]?.ToString() ?? "Max";
string str8 = table["str8"]?.ToString() ?? "Name";
string str9 = table["str9"]?.ToString() ?? "Color";
string str10 = table["str10"]?.ToString() ?? "Count";
string str11 = table["str11"]?.ToString() ?? string.Empty;
string str13 = table["str13"]?.ToString() ?? "Area%";
// prepare data access objects
var particledata = new ParticleData(path);
FieldData fielddata = new FieldData(path);
// Determine diameter column based on settings
string sizeMethod = m_ReportApp.m_conditionChoose.m_conditionData.GetPropItemDisplayValueByPropItemName(OTS_REPORT_PROP_GRID_ITEMS.SIZE_CAL_METHOD_TYPE).ToString();
string po;
switch (sizeMethod)
{
case "DMAX":
po = "DMAX";
break;
case "DMIN":
po = "DMIN";
break;
case "FERET":
po = "DFERET";
break;
case "ECD":
po = "Area";
break;
default:
po = "Area";
break;
}
// compute total area used in percentage calculation
double totalArea = ComputeTotalArea(result, fielddata);
// fetch data table
DataTable dt = particledata.GetParticleStatisticDataListByIncA(po) ?? new DataTable();
// create and set up grid
var gridView = new OTSGridView();
CreateGridColumns(gridView, str1, str8, str9, str10, str13, sizeMethod, str3, str4, str6, str7);
gridView.MergeColumnNames.Add(filename);
gridView.AddSpanHeader(1, gridView.Columns.Count - 1, filename);
// populate rows for TypeId >=100 (custom types) and for predefined types TypeId <=100
PopulateGridRows(gridView, dt, totalArea, sizeMethod, filename, true);
PopulateGridRows(gridView, dt, totalArea, sizeMethod, filename, false);
gridView.Name = "gridView" + num.ToString();
Point point = SetDataGridViewStyle(gridView);
list_table_Point.Add(point);
gridView.Location = new Point(point.X, point.Y + (DataNumber * 300));
AddSumRow(gridView);
panel1.Controls.Add(gridView);
list_table_data.Add(dt);
list_fileName.Add(filename);
}
private double ComputeTotalArea(ResultFile resultFile, FieldData fielddata)
{
try
{
if (resultFile == null || fielddata == null) return 0.0;
double scanFieldSize = resultFile.GetScanFieldSizeX();
double wide = resultFile.GetImageWidth();
double high = resultFile.GetImageHeight();
int filedCount = fielddata.GetFiledCount();
double pixelSize = scanFieldSize / wide;
// total scanned area = per-field width*height * number of fields (in OTS coordinates)
// in original code totalArea = high * pixelSize * wide * pixelSize * filedCount;
return high * pixelSize * wide * pixelSize * filedCount;
}
catch (Exception ex)
{
Debug.WriteLine("ComputeTotalArea failed: " + ex);
return 0.0;
}
}
private void CreateGridColumns(OTSGridView gridView, string headerRowId, string headerTypeName, string headerTypeColor, string headerCount, string headerAreaPct, string sizeMethod,
string headerArea, string headerAvg, string headerMaxAlt, string headerMax)
{
gridView.Columns.Clear();
gridView.Columns.Add(ColRowId, headerRowId);
gridView.Columns.Add(ColTypeName, headerTypeName);
gridView.Columns.Add(ColTypeColor, headerTypeColor);
gridView.Columns.Add(ColCount, headerCount);
gridView.Columns.Add(ColAreaRadio, headerAreaPct);
if (sizeMethod == "ECD")
{
gridView.Columns.Add(ColAvg, headerArea);
gridView.Columns.Add(ColMax, headerMaxAlt);
}
else
{
gridView.Columns.Add(ColAvg, headerAvg);
gridView.Columns.Add(ColMax, headerMax);
}
}
private void PopulateGridRows(OTSGridView gridView, DataTable dt, double totalArea, string sizeMethod, string filename, bool customTypesFirst)
{
if (dt == null || gridView == null) return;
// When customTypesFirst == true, process TypeId >= 100 (original code)
for (int i = 0; i < dt.Rows.Count; i++)
{
if (customTypesFirst)
{
if (Convert.ToInt32(dt.Rows[i]["TypeId"]) < 100) continue;
}
else
{
if (Convert.ToInt32(dt.Rows[i]["TypeId"]) >= 100) continue;
}
int addRowIndex = gridView.Rows.Add();
gridView.Rows[addRowIndex].Tag = "Statistics";
gridView.Rows[addRowIndex].Cells[0].Value = addRowIndex + 1;
for (int k = 1; k < gridView.ColumnCount; k++)
{
var colName = gridView.Columns[k].Name;
if (string.Equals(colName, ColTypeColor, StringComparison.OrdinalIgnoreCase) && dt.Rows[i]["TypeColor"] != DBNull.Value && dt.Rows[i]["TypeColor"].ToString() != "")
{
string color = dt.Rows[i]["TypeColor"].ToString();
if (!color.Contains("#")) color = "#" + color;
try
{
gridView.Rows[addRowIndex].Cells[k].Style.BackColor = DrawFunction.colorHx16toRGB(color);
}
catch
{
gridView.Rows[addRowIndex].Cells[k].Style.BackColor = Color.Black;
}
}
else if (string.Equals(colName, ColAvg, StringComparison.OrdinalIgnoreCase) || string.Equals(colName, ColMax, StringComparison.OrdinalIgnoreCase))
{
double value = 0;
double.TryParse(dt.Rows[i][gridView.Columns[k].Name].ToString(), out value);
if (sizeMethod == "ECD")
{
// value interpreted as area -> convert to diameter
double area = value;
gridView.Rows[addRowIndex].Cells[k].Value = Math.Round(Math.Sqrt(area / Math.PI) * 2, 2);
}
else
{
gridView.Rows[addRowIndex].Cells[k].Value = Math.Round(value , 2);
}
gridView.Rows[addRowIndex].Cells[k].Style.BackColor = Color.Azure;
}
else if (string.Equals(colName, ColAreaRadio, StringComparison.OrdinalIgnoreCase))
{
if (totalArea == 0)
{
gridView.Rows[addRowIndex].Cells[k].Value = 0;
}
else
{
double areaVal = 0;
double.TryParse(dt.Rows[i]["Area"].ToString(), out areaVal);
gridView.Rows[addRowIndex].Cells[k].Value = Math.Round(areaVal * 100 / totalArea, customTypesFirst ? 3 : 5);
}
gridView.Rows[addRowIndex].Cells[k].Style.BackColor = Color.Azure;
}
else
{
gridView.Rows[addRowIndex].Cells[k].Value = dt.Rows[i][gridView.Columns[k].Name];
gridView.Rows[addRowIndex].Cells[k].Style.BackColor = Color.Azure;
}
}
}
}
void AddSumRow(OTSGridView gridView)
{
if (gridView == null || gridView.Rows == null || gridView.Rows.Count == 0)
return;
int sumRowIndex = gridView.Rows.Add();
gridView.Rows[sumRowIndex].Tag = "Sum";
gridView.Rows[sumRowIndex].Cells[1].Value = "Sum";
gridView.Refresh();
long totalCount = 0;
double totalArea = 0.0;
for (int j = 0; j < gridView.Rows.Count - 1; j++)
{
if (gridView.Rows[j].Tag == null) continue;
try
{
var cntObj = gridView.Rows[j].Cells[3].Value;
if (cntObj != null && long.TryParse(cntObj.ToString(), out long cntVal))
totalCount += cntVal;
var areaObj = gridView.Rows[j].Cells[4].Value;
if (areaObj != null && double.TryParse(areaObj.ToString(), out double areaVal))
totalArea += areaVal;
}
catch { /* ignore malformed rows */ }
}
// assign sums
gridView.Rows[sumRowIndex].Cells[3].Value = totalCount;
gridView.Rows[sumRowIndex].Cells[4].Value = totalArea;
gridView.Rows[sumRowIndex].Height = gridView.Rows[Math.Max(0, sumRowIndex - 1)].Height;
for (int j = 1; j < gridView.Columns.Count; j++)
{
gridView.Rows[sumRowIndex].DefaultCellStyle.BackColor = Color.Azure;
}
//gridView.Rows[sumRowIndex].Height = 30;
gridView.Size = new System.Drawing.Size(gridView.ColumnCount * 100 + 60, gridView.RowCount * 30);
}
private Point SetDataGridViewStyle(OTSGridView gridView)
{
// user can't change header height
gridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
// user can't change row height
gridView.AllowUserToResizeRows = false;
gridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
var centeredStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter
};
gridView.DefaultCellStyle = centeredStyle;
gridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
gridView.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
gridView.Columns[0].Width = 40;
gridView.Columns[1].Width = 200;
gridView.Columns[0].Resizable = DataGridViewTriState.False;
gridView.AllowUserToAddRows = false;
gridView.AllowUserToDeleteRows = false;
gridView.AllowUserToResizeRows = false;
gridView.BackgroundColor = System.Drawing.SystemColors.ButtonHighlight;
gridView.RowHeadersVisible = false;
gridView.RowHeadersWidth = 40;
gridView.RowTemplate.Height = 30;
int gridViewHeight = 0;
for (int i = 0; i < gridView.Rows.Count; i++)
{
gridViewHeight= gridViewHeight+ gridView.Rows[i].Height;
}
gridView.Size = new System.Drawing.Size(gridView.ColumnCount * 100 + 60, gridViewHeight);
//gridView.Size = new System.Drawing.Size(gridView.ColumnCount * 100 + 60, gridView.RowCount * 30);
int gridheight = gridViewHeight + 7;
gridhigh = gridhigh + gridViewHeight+2;
//gridwidth = gridwidth + gridView.ColumnCount * 100 + 60;
chartposition = chartposition + gridView.ColumnCount * 100;
GridPosition = gridView.ColumnCount * 100 + 40;
list_gridheight.Add(gridheight);
gridView.TabIndex = 0;
gridView.ContextMenuStrip = this.contextMenuStrip1;
gridView.BorderStyle = 0;
gridView.ReadOnly = true;
gridView.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(this.Gview_ColumnHeaderMouseClick);
gridView.Sorted += new System.EventHandler(this.Gview_gz_Sorted);
// set header height a bit taller for aesthetics
gridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
gridView.ColumnHeadersHeight = 40;
list_table_size.Add(new Point(gridView.ColumnCount * 100 + 40, gridViewHeight+30 ));
//return new Point(gridwidth - (gridView.ColumnCount * 100 + 60), gridheight + 5);
return new Point(0, gridhigh- gridViewHeight-2);
}
#endregion
#region charts
public void SetGraphicType(ReportCondition sourceGridData)
{
if (sourceGridData == null) return;
string stdId_TYPE = "";
int stdIdIndex = 0;
var STDIdItm = sourceGridData.ConditionItemList.Find(s => s.iItemId == OTS_REPORT_PROP_GRID_ITEMS.GRAPHIC_TYPE);
if (STDIdItm != null)
{
stdId_TYPE = STDIdItm.itemDisplayVal.ToString();
stdIdIndex = STDIdItm.comboDownList.IndexOf(stdId_TYPE);
}
indexGraphicType = stdIdIndex;
GraphicType = stdId_TYPE;
int high = 0;
for (int i = 0; i < list_table_Point.Count; i++)
{
if (high < list_table_Point[i].Y)
{
high = list_table_Point[i].Y;
}
}
for (int i = 0; i < list_table_data.Count; i++)
{
DataNumber = i;
Graphics(list_table_data[i], list_fileName[i], stdId_TYPE, list_table_size[i], list_table_Point[i], high);
}
}
private void Graphics(DataTable data, string filename, string comboBox1Text, Point a_size, Point a_Location, int location_hig)
{
var chartControl1 = new ChartControl();
chartControl1.Series.Clear();
Series series = new Series(filename, ViewType.Bar);
if (data != null)
{
for (int a = 0; a < data.Rows.Count; a++)
{
string name = data.Rows[a]["TypeName"].ToString();
double cnt = 0;
double.TryParse(data.Rows[a]["con"].ToString(), out cnt);
series.Points.Add(new SeriesPoint(name, cnt));
}
}
series.LabelsVisibility = DefaultBoolean.True;
chartControl1.Series.Add(series);
chartControl1.Legend.AlignmentVertical = LegendAlignmentVertical.Top;
chartControl1.Legend.AlignmentHorizontal = LegendAlignmentHorizontal.RightOutside;
chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False;
chartControl1.Legend.Direction = LegendDirection.TopToBottom;
chartControl1.CrosshairEnabled = DefaultBoolean.True;
chartControl1.CrosshairOptions.ShowValueLine = true;
chartControl1.CrosshairOptions.ShowArgumentLabels = true;
DevFunctions.ChangeView2(chartControl1, comboBox1Text);
chartControl1.Location = new Point(a_Location.X+ a_size.X+20, a_Location.Y + 20 + (DataNumber * 300));
chartControl1.Size = new Size(a_size.X, a_size.Y);
var diagram = chartControl1.Diagram as XYDiagram;
if (diagram != null)
{
diagram.AxisX.Title.Text = "种类";
diagram.AxisX.Title.Visibility = DevExpress.Utils.DefaultBoolean.True;
diagram.AxisY.Title.Text = "数量";
diagram.AxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True;
}
// prepare combo box for chart type selection (re-use ChartTypes constant)
var comboBox = new ComboBox();
list_ChartControl.Add(chartControl1);
list_ComboBox.Add(comboBox);
comboBox.Items.AddRange(ChartTypes);
comboBox.Name = Convert.ToString(list_ComboBox.Count - 1);
comboBox.SelectedIndex = 0;
comboBox.Location = new Point(a_Location.X + a_size.X +20+ chartControl1.Size.Width - 100, a_Location.Y + (DataNumber * 300));
comboBox.Size = new Size(100, 25);
comboBox.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
panel1.Controls.Add(chartControl1);
panel1.Controls.Add(comboBox);
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox == null) return;
if (int.TryParse(comboBox.Name, out int idx) && idx >= 0 && idx < list_ChartControl.Count)
{
DevFunctions.ChangeView2(list_ChartControl[idx], comboBox.Text);
}
}
#endregion
#region events / UI actions
private void CompositionDistributionGrid_Load(object sender, EventArgs e)
{
list_table_data.Clear();
list_table_size.Clear();
list_table_Point.Clear();
list_fileName.Clear();
int ii = 0;
string sou = m_condition.m_CurrentConditions[OTS_REPORT_PROP_GRID_ITEMS.DATA_SOURCE].itemDisplayVal.ToString();
if (sou.Contains("+"))
{
foreach (var name in sou.Split('+'))
{
var resultFile = m_ReportApp.m_rstDataMgr.ResultFilesList.Find(s => s.anotherFileName == name);
if (resultFile != null)
{
DataNumber = ii;
BindDataGridView(resultFile.FilePath, list_fileName.Count, resultFile.anotherFileName);
ii++;
}
}
}
else
{
var match = m_ReportApp.m_rstDataMgr.ResultFilesList.FirstOrDefault(r => r.anotherFileName == sou);
if (match != null)
{
BindDataGridView(match.FilePath, 0, match.anotherFileName);
}
}
}
private void ToolStripMenuItem1_Click(object sender, EventArgs e)
{
OTSGridView otv = (OTSGridView)((ContextMenuStrip)(sender as ToolStripMenuItem).Owner).SourceControl;
CopyAll(otv);
}
private void ToolStripMenuItem2_Click(object sender, EventArgs e)
{
OTSGridView otv = (OTSGridView)((ContextMenuStrip)(sender as ToolStripMenuItem).Owner).SourceControl;
CopySelected(otv);
}
public void CopySelected(OTSGridView in_ogv)
{
if (in_ogv == null) return;
Clipboard.SetDataObject(in_ogv.GetClipboardContent());
}
public void CopySelected()
{
var dgv = panel1.Controls.OfType().FirstOrDefault();
if (dgv == null) return;
Clipboard.SetDataObject(dgv.GetClipboardContent());
}
public void CopyAll(OTSGridView in_ogv)
{
if (in_ogv == null) return;
in_ogv.SelectAll();
Clipboard.SetDataObject(in_ogv.GetClipboardContent());
}
public void CopyAll()
{
var dgv = panel1.Controls.OfType().FirstOrDefault();
if (dgv == null) return;
dgv.SelectAll();
Clipboard.SetDataObject(dgv.GetClipboardContent());
}
private void ToolStripMenuItem3_Click(object sender, EventArgs e)
{
// remove only OTSGridView controls
var toRemove = panel1.Controls.OfType().ToArray();
foreach (var g in toRemove) panel1.Controls.Remove(g);
list_table_data.Clear();
list_table_size.Clear();
list_table_Point.Clear();
list_fileName.Clear();
string sou = source.GetPropItemDisplayValueByPropItemName(OTS_REPORT_PROP_GRID_ITEMS.DATA_SOURCE).ToString();
if (sou.Contains("+"))
{
int ii = 0;
foreach (var name in sou.Split('+'))
{
var resultFile = m_ReportApp.m_rstDataMgr.ResultFilesList.Find(s => s.anotherFileName == name);
if (resultFile != null)
{
DataNumber = ii;
BindDataGridView(resultFile.FilePath, list_fileName.Count, resultFile.anotherFileName);
ii++;
}
}
}
else
{
var match = m_ReportApp.m_rstDataMgr.ResultFilesList[m_ReportApp.m_rstDataMgr.GetWorkingResultId()];
BindDataGridView(match.FilePath, 0, match.anotherFileName);
}
}
void Gview_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
var grid = sender as OTSGridView;
if (grid == null || grid.Rows == null || grid.Rows.Count == 0) return;
AddSumRow(grid);
}
private void Gview_gz_Sorted(object sender, EventArgs e)
{
var grid = sender as OTSGridView;
if (grid == null || grid.Rows == null || grid.Rows.Count == 0) return;
for (int i = 0; i < grid.Rows.Count; i++)
{
if (grid.Rows[i].Tag != null && grid.Rows[i].Tag.ToString() == "Sum")
{
grid.Rows.RemoveAt(i);
break;
}
}
grid.Refresh();
for (int i = 0; i < grid.Rows.Count; i++)
{
grid.Rows[i].Cells[0].Value = (i + 1).ToString();
}
}
#endregion
}
}