diff --git a/AIMS/AIMS.csproj b/AIMS/AIMS.csproj index 6e8a9ec..c69d877 100644 --- a/AIMS/AIMS.csproj +++ b/AIMS/AIMS.csproj @@ -841,6 +841,12 @@ frmUserPurviewDetail.cs + + Form + + + frmTemplateSel.cs + Form @@ -1237,6 +1243,9 @@ frmUserPurviewDetail.cs + + frmTemplateSel.cs + MainFormManage.cs diff --git a/AIMS/PublicUI/frmTemplate.Designer.cs b/AIMS/PublicUI/frmTemplate.Designer.cs index edd102c..749ebe0 100644 --- a/AIMS/PublicUI/frmTemplate.Designer.cs +++ b/AIMS/PublicUI/frmTemplate.Designer.cs @@ -31,14 +31,6 @@ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.panel2 = new System.Windows.Forms.Panel(); this.dgv = new System.Windows.Forms.DataGridView(); - this.tsbExit = new System.Windows.Forms.ToolStripButton(); - this.tsbCreateTemplate = new System.Windows.Forms.ToolStripButton(); - this.panel1 = new System.Windows.Forms.Panel(); - this.toolStrip1 = new System.Windows.Forms.ToolStrip(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.TemplateNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.OperatorName = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.InputColumn = new System.Windows.Forms.DataGridViewButtonColumn(); @@ -47,6 +39,14 @@ this.IsPublic = new System.Windows.Forms.DataGridViewCheckBoxColumn(); this.OperatorNo = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.InRoomTime2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tsbExit = new System.Windows.Forms.ToolStripButton(); + this.tsbCreateTemplate = new System.Windows.Forms.ToolStripButton(); + this.panel1 = new System.Windows.Forms.Panel(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.panel2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit(); this.panel1.SuspendLayout(); @@ -90,6 +90,74 @@ this.dgv.TabIndex = 6; this.dgv.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgv_CellContentClick); // + // TemplateNameColumn + // + this.TemplateNameColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.TemplateNameColumn.DataPropertyName = "TemplateName"; + this.TemplateNameColumn.HeaderText = "模板名称"; + this.TemplateNameColumn.Name = "TemplateNameColumn"; + this.TemplateNameColumn.ReadOnly = true; + // + // OperatorName + // + this.OperatorName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.OperatorName.DataPropertyName = "OperatorName"; + this.OperatorName.HeaderText = "创建人"; + this.OperatorName.Name = "OperatorName"; + this.OperatorName.Width = 70; + // + // InputColumn + // + this.InputColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.InputColumn.HeaderText = ""; + this.InputColumn.Name = "InputColumn"; + this.InputColumn.Text = "导入"; + this.InputColumn.UseColumnTextForButtonValue = true; + this.InputColumn.Width = 60; + // + // EditColumn + // + this.EditColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.EditColumn.HeaderText = ""; + this.EditColumn.Name = "EditColumn"; + this.EditColumn.ReadOnly = true; + this.EditColumn.Text = "编辑"; + this.EditColumn.UseColumnTextForButtonValue = true; + this.EditColumn.Width = 60; + // + // DeleteColumn + // + this.DeleteColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; + this.DeleteColumn.HeaderText = ""; + this.DeleteColumn.Name = "DeleteColumn"; + this.DeleteColumn.ReadOnly = true; + this.DeleteColumn.Text = "删除"; + this.DeleteColumn.UseColumnTextForButtonValue = true; + this.DeleteColumn.Width = 60; + // + // IsPublic + // + this.IsPublic.DataPropertyName = "IsPublic"; + this.IsPublic.HeaderText = "公有"; + this.IsPublic.Name = "IsPublic"; + this.IsPublic.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.IsPublic.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.IsPublic.Visible = false; + // + // OperatorNo + // + this.OperatorNo.DataPropertyName = "OperatorNo"; + this.OperatorNo.HeaderText = "OperatorNo"; + this.OperatorNo.Name = "OperatorNo"; + this.OperatorNo.Visible = false; + // + // InRoomTime2 + // + this.InRoomTime2.DataPropertyName = "InRoomTime"; + this.InRoomTime2.HeaderText = "InRoomTime"; + this.InRoomTime2.Name = "InRoomTime2"; + this.InRoomTime2.Visible = false; + // // tsbExit // this.tsbExit.Font = new System.Drawing.Font("微软雅黑", 9F); @@ -167,74 +235,6 @@ this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; this.dataGridViewTextBoxColumn4.Visible = false; // - // TemplateNameColumn - // - this.TemplateNameColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.TemplateNameColumn.DataPropertyName = "TemplateName"; - this.TemplateNameColumn.HeaderText = "模板名称"; - this.TemplateNameColumn.Name = "TemplateNameColumn"; - this.TemplateNameColumn.ReadOnly = true; - // - // OperatorName - // - this.OperatorName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.OperatorName.DataPropertyName = "OperatorName"; - this.OperatorName.HeaderText = "创建人"; - this.OperatorName.Name = "OperatorName"; - this.OperatorName.Width = 70; - // - // InputColumn - // - this.InputColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.InputColumn.HeaderText = ""; - this.InputColumn.Name = "InputColumn"; - this.InputColumn.Text = "导入"; - this.InputColumn.UseColumnTextForButtonValue = true; - this.InputColumn.Width = 60; - // - // EditColumn - // - this.EditColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.EditColumn.HeaderText = ""; - this.EditColumn.Name = "EditColumn"; - this.EditColumn.ReadOnly = true; - this.EditColumn.Text = "编辑"; - this.EditColumn.UseColumnTextForButtonValue = true; - this.EditColumn.Width = 60; - // - // DeleteColumn - // - this.DeleteColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None; - this.DeleteColumn.HeaderText = ""; - this.DeleteColumn.Name = "DeleteColumn"; - this.DeleteColumn.ReadOnly = true; - this.DeleteColumn.Text = "删除"; - this.DeleteColumn.UseColumnTextForButtonValue = true; - this.DeleteColumn.Width = 60; - // - // IsPublic - // - this.IsPublic.DataPropertyName = "IsPublic"; - this.IsPublic.HeaderText = "公有"; - this.IsPublic.Name = "IsPublic"; - this.IsPublic.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.IsPublic.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - this.IsPublic.Visible = false; - // - // OperatorNo - // - this.OperatorNo.DataPropertyName = "OperatorNo"; - this.OperatorNo.HeaderText = "OperatorNo"; - this.OperatorNo.Name = "OperatorNo"; - this.OperatorNo.Visible = false; - // - // InRoomTime2 - // - this.InRoomTime2.DataPropertyName = "InRoomTime"; - this.InRoomTime2.HeaderText = "InRoomTime"; - this.InRoomTime2.Name = "InRoomTime2"; - this.InRoomTime2.Visible = false; - // // frmTemplate // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); diff --git a/AIMS/PublicUI/frmTemplate.cs b/AIMS/PublicUI/frmTemplate.cs index 0c2810d..49a01aa 100644 --- a/AIMS/PublicUI/frmTemplate.cs +++ b/AIMS/PublicUI/frmTemplate.cs @@ -61,12 +61,18 @@ namespace AIMS.PublicUI.UI { if (this.dgv.Columns[e.ColumnIndex].Name == "InputColumn") { - if (MessageBox.Show("确认要导入[" + dgv.CurrentRow.Cells["TemplateNameColumn"].Value.ToString() + "]模板吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + frmTemplateSel templateSel = new frmTemplateSel(); + templateSel.InRoomTime = InRoomTime; + if (templateSel.ShowDialog() == System.Windows.Forms.DialogResult.OK) { - //BOperationTemplate.ClearData(PatientId, TypeId); - BOperationTemplate.InputData(dgv.CurrentRow.Cells["TemplateNameColumn"].Value.ToString(), PatientId, InRoomTime, TypeId,_record); + BOperationTemplate.InputData(dgv.CurrentRow.Cells["TemplateNameColumn"].Value.ToString(), PatientId, templateSel.InRoomTime, TypeId, _record); this.DialogResult = System.Windows.Forms.DialogResult.OK; } + //if (MessageBox.Show("确认要导入[" + dgv.CurrentRow.Cells["TemplateNameColumn"].Value.ToString() + "]模板吗?\n模板开始时间:"+ InRoomTime, "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) + //{ + // //BOperationTemplate.ClearData(PatientId, TypeId); + // BOperationTemplate.InputData(dgv.CurrentRow.Cells["TemplateNameColumn"].Value.ToString(), PatientId, InRoomTime, TypeId,_record); + //} } else if (this.dgv.Columns[e.ColumnIndex].Name == "EditColumn") { diff --git a/AIMS/PublicUI/frmTemplateSel.Designer.cs b/AIMS/PublicUI/frmTemplateSel.Designer.cs new file mode 100644 index 0000000..fd0161b --- /dev/null +++ b/AIMS/PublicUI/frmTemplateSel.Designer.cs @@ -0,0 +1,96 @@ +namespace AIMS.PublicUI +{ + partial class frmTemplateSel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.dtpStartTempTime = new System.Windows.Forms.DateTimePicker(); + this.btnQuery = new DevComponents.DotNetBar.ButtonX(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.BackColor = System.Drawing.Color.Transparent; + this.label1.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.label1.Location = new System.Drawing.Point(15, 23); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 17); + this.label1.TabIndex = 12; + this.label1.Text = "开始时间"; + // + // dtpStartTempTime + // + this.dtpStartTempTime.CustomFormat = "yyyy-MM-dd HH:mm"; + this.dtpStartTempTime.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.dtpStartTempTime.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtpStartTempTime.Location = new System.Drawing.Point(74, 19); + this.dtpStartTempTime.Name = "dtpStartTempTime"; + this.dtpStartTempTime.Size = new System.Drawing.Size(145, 23); + this.dtpStartTempTime.TabIndex = 11; + // + // btnQuery + // + this.btnQuery.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; + this.btnQuery.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground; + this.btnQuery.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnQuery.Location = new System.Drawing.Point(225, 19); + this.btnQuery.Name = "btnQuery"; + this.btnQuery.Size = new System.Drawing.Size(80, 23); + this.btnQuery.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnQuery.TabIndex = 13; + this.btnQuery.Text = "确定"; + this.btnQuery.Click += new System.EventHandler(this.btnQuery_Click); + // + // frmTemplateSel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(308, 67); + this.Controls.Add(this.btnQuery); + this.Controls.Add(this.label1); + this.Controls.Add(this.dtpStartTempTime); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "frmTemplateSel"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "模板开始时间"; + this.Load += new System.EventHandler(this.frmTemplateSel_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.DateTimePicker dtpStartTempTime; + private DevComponents.DotNetBar.ButtonX btnQuery; + } +} \ No newline at end of file diff --git a/AIMS/PublicUI/frmTemplateSel.cs b/AIMS/PublicUI/frmTemplateSel.cs new file mode 100644 index 0000000..38305b9 --- /dev/null +++ b/AIMS/PublicUI/frmTemplateSel.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace AIMS.PublicUI +{ + public partial class frmTemplateSel : Form + { + public DateTime InRoomTime; + public frmTemplateSel() + { + InitializeComponent(); + } + + private void btnQuery_Click(object sender, EventArgs e) + { + InRoomTime = dtpStartTempTime.Value; + this.DialogResult = System.Windows.Forms.DialogResult.OK; + } + + private void frmTemplateSel_Load(object sender, EventArgs e) + { + dtpStartTempTime.Value = InRoomTime; + } + } +} diff --git a/AIMS/PublicUI/frmTemplateSel.resx b/AIMS/PublicUI/frmTemplateSel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/AIMS/PublicUI/frmTemplateSel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AIMSEntity/BLL/Extension/BOperationRecord.cs b/AIMSEntity/BLL/Extension/BOperationRecord.cs index ad31fcc..db19a39 100644 --- a/AIMSEntity/BLL/Extension/BOperationRecord.cs +++ b/AIMSEntity/BLL/Extension/BOperationRecord.cs @@ -59,6 +59,8 @@ namespace AIMSBLL _record.Age = OperationFrontdt.Rows[0]["Age"].ToString(); _record.Identity = OperationFrontdt.Rows[0]["IdentityCard"].ToString(); _record.FareType = OperationFrontdt.Rows[0]["PatientKind"].ToString(); + _record.BloodType = OperationFrontdt.Rows[0]["BloodType"].ToString(); + _record.RHBloodType = OperationFrontdt.Rows[0]["RHBloodType"].ToString(); ASALevel = OperationFrontdt.Rows[0]["ASA"].ToString(); if (OperationFrontdt.Rows[0]["Height"].ToString() != "") { @@ -136,7 +138,7 @@ namespace AIMSBLL } _record.OpeRecordInfo.InfoRemark = "-"; - _record.OpeRecordInfo.RuleNurse = "-"; + _record.OpeRecordInfo.NeedleDirection = "-"; _record.OpeRecordInfo.OperatorId = PublicMethod.OperatorName; _record.OpeRecordInfo.OperatorTime = DateTime.Now; diff --git a/DrawGraph/AreaManage/AnalgesiaDataBottonManage.cs b/DrawGraph/AreaManage/AnalgesiaDataBottonManage.cs index 7a87ad9..dcc2c69 100644 --- a/DrawGraph/AreaManage/AnalgesiaDataBottonManage.cs +++ b/DrawGraph/AreaManage/AnalgesiaDataBottonManage.cs @@ -270,11 +270,12 @@ namespace DrawGraph tokenEditor.Leave -= TokenEditor_Leave; tokenEditor.Leave += TokenEditor_Leave; - if (ableEdit.ControlTitleText == "手术" || ableEdit.ControlTitleText == "诊断") + if ((PublicMethod.RoleName.Contains("增加诊断") && ableEdit.ControlTitleText == "诊断") || (AIMSExtension.PublicMethod.RoleName.Contains("增加手术") && ableEdit.ControlTitleText == "手术")) { tokenEditor.ValidateToken -= new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); tokenEditor.ValidateToken += new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); } + } else if (ableEdit.ControlType == EControlType.CheckBox) { diff --git a/DrawGraph/AreaManage/AnalgesiaDataManage.cs b/DrawGraph/AreaManage/AnalgesiaDataManage.cs index 8edd5d3..5873162 100644 --- a/DrawGraph/AreaManage/AnalgesiaDataManage.cs +++ b/DrawGraph/AreaManage/AnalgesiaDataManage.cs @@ -272,11 +272,12 @@ namespace DrawGraph tokenEditor.Leave -= TokenEditor_Leave; tokenEditor.Leave += TokenEditor_Leave; - if (ableEdit.ControlTitleText == "手术" || ableEdit.ControlTitleText == "诊断") + if ((PublicMethod.RoleName.Contains("增加诊断") && ableEdit.ControlTitleText == "诊断") || (AIMSExtension.PublicMethod.RoleName.Contains("增加手术") && ableEdit.ControlTitleText == "手术")) { tokenEditor.ValidateToken -= new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); tokenEditor.ValidateToken += new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); } + } else if (ableEdit.ControlType == EControlType.CheckBox) { diff --git a/DrawGraph/AreaManage/BaseInfoBottomManage.cs b/DrawGraph/AreaManage/BaseInfoBottomManage.cs index dfda818..36a9f37 100644 --- a/DrawGraph/AreaManage/BaseInfoBottomManage.cs +++ b/DrawGraph/AreaManage/BaseInfoBottomManage.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using DevComponents.DotNetBar.Controls; +using Newtonsoft.Json.Linq; namespace DrawGraph { @@ -85,7 +86,19 @@ namespace DrawGraph break; case EControlType.Directorys: value = ableEdit.PackValue; - text = DBManage.GetDictionaryValuesById(ableEdit.PackValue, ableEdit.ControlTitleText); + + if (ableEdit.ClassDataSourceName == "OperationRecord.OperationDoctor" && myOpeRecord.OpeRecordInfo.Extend4 != null && myOpeRecord.OpeRecordInfo.Extend4 != "" && myOpeRecord.OpeRecordInfo.Extend4 != "|") + { + text = DBManage.GetDictionaryValuesById(ableEdit.PackValue, ableEdit.ControlTitleText, myOpeRecord.OpeRecordInfo.Extend4 ); + } + else if (ableEdit.ClassDataSourceName == "OperationRecord.AnesthesiaDoctor" && myOpeRecord.OpeRecordInfo.Extend5 != null && myOpeRecord.OpeRecordInfo.Extend5 != "" && myOpeRecord.OpeRecordInfo.Extend5 != "|") + { + text = DBManage.GetDictionaryValuesById(ableEdit.PackValue, ableEdit.ControlTitleText, myOpeRecord.OpeRecordInfo.Extend5 ); + } + else + { + text = DBManage.GetDictionaryValuesById(ableEdit.PackValue, ableEdit.ControlTitleText); + } //设置属性的值 template.SetObjValue(OpeRecord, ableEdit.ClassDataSourceName, text, value); break; @@ -518,11 +531,20 @@ namespace DrawGraph tokenEditor.Leave -= TokenEditor_Leave; tokenEditor.Leave += TokenEditor_Leave; - if (ableEdit.ControlTitleText == "手术" || ableEdit.ControlTitleText == "诊断") + if ((PublicMethod.RoleName.Contains("增加诊断") && ableEdit.ControlTitleText == "诊断") || (AIMSExtension.PublicMethod.RoleName.Contains("增加手术") && ableEdit.ControlTitleText == "手术")) { tokenEditor.ValidateToken -= new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); tokenEditor.ValidateToken += new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); } + if (ableEdit.ClassDataSourceName == "OperationRecord.OperationDoctor" || ableEdit.ClassDataSourceName == "OperationRecord.AnesthesiaDoctor") + { + tokenEditor.ValidateToken -= new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken1); + tokenEditor.ValidateToken += new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken1); + tokenEditor.Leave -= TokenEditor_Leave; + tokenEditor.Leave -= TokenEditor_Leave2; + tokenEditor.Leave += TokenEditor_Leave2; + } + EditTextBox_DoubleClick(tokenEditor.EditTextBox, null); tokenEditor.EditTextBox.Select(); } @@ -554,12 +576,39 @@ namespace DrawGraph } } + private void tokenEditor_ValidateToken1(object sender, DevComponents.DotNetBar.Controls.ValidateTokenEventArgs ea) + { + DevComponents.DotNetBar.Controls.TokenEditor tokenEditor = sender as DevComponents.DotNetBar.Controls.TokenEditor; + AbleEditPackObj aEdit = tokenEditor.Tag as AbleEditPackObj; + if (ea.IsNewToken) + { + if (tokenEditor.SelectedTokens.Count > 0) + { + tokenEditor.EditTextBox.TextChanged -= EditTextBox_TextChanged; + EditToken token = tokenEditor.SelectedTokens[tokenEditor.SelectedTokens.Count - 1]; + string Tokentxt = ea.Token.Value.Replace(":", ":"); + token.Text += Tokentxt; + ea.Token = null; + tokenEditor.EditTextBox.Text = ""; + tokenEditor.IsPopupOpen = false; + tokenEditor.EditTextBox.TextChanged += EditTextBox_TextChanged; + + } + } + } + private void TokenEditor_Leave(object sender, EventArgs e) { DevComponents.DotNetBar.Controls.TokenEditor tokenEditor = sender as DevComponents.DotNetBar.Controls.TokenEditor; AbleEditPackObj aEdit = tokenEditor.Tag as AbleEditPackObj; TokenEditorManage.SaveDictItem(template, OpeRecord as OperationRecord, tokenEditor, aEdit, true); } + private void TokenEditor_Leave2(object sender, EventArgs e) + { + DevComponents.DotNetBar.Controls.TokenEditor tokenEditor = sender as DevComponents.DotNetBar.Controls.TokenEditor; + AbleEditPackObj aEdit = tokenEditor.Tag as AbleEditPackObj; + TokenEditorManage.SaveDictItem2(template, OpeRecord as OperationRecord, tokenEditor, aEdit, true); + } } } diff --git a/DrawGraph/AreaManage/BaseInfoTopManage.cs b/DrawGraph/AreaManage/BaseInfoTopManage.cs index ea3ffa9..b2c98ba 100644 --- a/DrawGraph/AreaManage/BaseInfoTopManage.cs +++ b/DrawGraph/AreaManage/BaseInfoTopManage.cs @@ -394,7 +394,10 @@ namespace DrawGraph conl.DoubleClick += Conl_DoubleClick; break; case "OperationRecord.BloodType": //血型 - TYZD_Click(aEdit1, e); + TYZD_Click(aEdit1, e, true); + break; + case "OperationRecord.RHBloodType": //血型 + TYZD_Click(aEdit1, e, true); break; case "OperationRecord.Applydiagnose": //手术诊断 opeDisease_Click(aEdit1, e); @@ -435,20 +438,20 @@ namespace DrawGraph #region 可编辑区域响应事件 //通用字典分组窗体打开 private void TYZD_Click(AbleEditPackObj sender, EventArgs e, bool isRadio = false) - { + { try { AbleEditPackObj ableEdit = sender; if (ableEdit == null) return; if (myOpeRecord == null) return; - if (ableEdit.ControlType == EControlType.Directory) - { - SelDict(sender, e, ableEdit.ControlTitleText, isRadio); - } - else if (ableEdit.ControlType == EControlType.Directorys) + if (ableEdit.ControlType == EControlType.Directorys) { SetDirectorysMethod(ableEdit); } + else + { + SelDict(sender, e, ableEdit.ControlTitleText, isRadio); + } } catch (Exception ex) { @@ -598,13 +601,14 @@ namespace DrawGraph tokenEditor.Leave -= TokenEditor_Leave; tokenEditor.Leave += TokenEditor_Leave; - if (ableEdit.ControlTitleText == "手术" || ableEdit.ControlTitleText == "诊断") + if ((PublicMethod.RoleName.Contains("增加诊断") && ableEdit.ControlTitleText == "诊断") || (AIMSExtension.PublicMethod.RoleName.Contains("增加手术") && ableEdit.ControlTitleText == "手术")) { tokenEditor.ValidateToken -= new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); tokenEditor.ValidateToken += new DevComponents.DotNetBar.Controls.ValidateTokenEventHandler(this.tokenEditor_ValidateToken); } + EditTextBox_DoubleClick(tokenEditor.EditTextBox, null); - tokenEditor.EditTextBox.Select(); + tokenEditor.EditTextBox.Select(); } private void opeDisease_Click(AbleEditPackObj sender, EventArgs e) @@ -820,6 +824,5 @@ namespace DrawGraph AbleEditPackObj aEdit = tokenEditor.Tag as AbleEditPackObj; TokenEditorManage.SaveDictItem(template, OpeRecord as OperationRecord, tokenEditor, aEdit, true); } - } } diff --git a/DrawGraph/AreaManage/DBManage.cs b/DrawGraph/AreaManage/DBManage.cs index 4a76289..6c582df 100644 --- a/DrawGraph/AreaManage/DBManage.cs +++ b/DrawGraph/AreaManage/DBManage.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using System.Net; using System.Text; namespace DrawGraph @@ -76,14 +77,14 @@ namespace DrawGraph break; default: strSql = "SELECT top 30 p.Id,p.Name,p.Remark Code FROM BasicDictionary p WHERE p.IsValid=1 and ParentId in(select Id from BasicDictionary where Name='" + _title + "') AND (p.Name LIKE '%" + HelpCode + "%' OR p.HelpCode LIKE '%" + HelpCode + "%' )"; - if (SelPerson != "") strSql += " AND p.Id not in (" + SelPerson + ") "; + //if (SelPerson != "" && ) strSql += " AND p.Id not in (" + SelPerson + ") "; strSql += " order by p.[Order] asc"; break; } return HelperDB.DbHelperSQL.GetDataTable(strSql.ToString()); } - public static int SetOperationRecordValue(object operationRecord, string propertyName, string value) + public static int SetOperationRecordValue(object operationRecord, string propertyName, string value, string Text) { int i = 0; OperationRecord _operationRecord = operationRecord as OperationRecord; @@ -181,6 +182,10 @@ namespace DrawGraph { i += UpdatePatient(items[1] + "='" + value + "' where Id= " + _operationRecord.PatientId); } + else if (items[1] == "BloodType" || items[1] == "RHBloodType") + { + i += UpdatePatient(items[1] + "='" + Text + "' where Id= " + _operationRecord.PatientId); + } else if (items[1] == "OperationType") { i += UpdateApply(items[1] + "='" + value + "' where Id= " + _operationRecord.PatientId); @@ -399,7 +404,7 @@ namespace DrawGraph strSql.Append("" + DiagnoseId + ","); strSql.Append("'" + AIMSExtension.PublicMethod.OperatorNo + "',"); strSql.Append("'" + AIMSExtension.PublicMethod.OperatorName + "',"); - strSql.Append("'" + DateTime.Now + "'"); + strSql.Append("'" + DateTime.Now + "'"); strSql.Append(")"); i += HelperDB.DbHelperSQL.ExecNonQuery(strSql.ToString()); } @@ -706,5 +711,62 @@ namespace DrawGraph return Explain; } + public static string GetDictionaryValuesById(string Ids, string DictionaryName, string Tags) + { + if (Ids == null || Ids.Trim() == "") return ""; + string Explain = ""; + try + { + string sql = ""; + switch (DictionaryName) + { + case "手术": + sql = "select dbo.GetOperation('" + Ids + "') value"; + break; + case "CA人员": + sql = "select dbo.GetPersons('" + Ids + "') value"; + break; + case "人员": + sql = "select dbo.GetPersons('" + Ids + "') value"; + break; + case "诊断": + sql = "select dbo.GetDisease('" + Ids + "') value"; + break; + case "麻醉方式": + sql = "select dbo.GetAnaesthesiaMethod('" + Ids + "') value"; + break; + case "手术体位": + sql = "select dbo.GetOperationBodyPosition('" + Ids + "') value"; + break; + case "手术部位": + sql = "select dbo.GetOperationPosition('" + Ids + "') value"; + break; + default: + sql = "select dbo.funBasicDictionary('" + Ids + "') value"; + break; + } + if (sql != "") + { + object dt = DBHelper.ExecuteScalar(sql); + if (dt != null) + { + string namestr = dt.ToString(); + List list = namestr.Split(',').ToList(); + List tags = Tags.Split('|').ToList(); + for (int i = 0; i < list.Count; i++) + { + list[i] = list[i] + tags[i]; + } + Explain = string.Join(",", list); + } + } + } + catch (Exception ex) + { + PublicMethod.WriteLog(ex); + Explain = ""; + } + return Explain; + } } } diff --git a/DrawGraph/AreaManage/PhysioDataManage.cs b/DrawGraph/AreaManage/PhysioDataManage.cs index f8a93c6..694ab83 100644 --- a/DrawGraph/AreaManage/PhysioDataManage.cs +++ b/DrawGraph/AreaManage/PhysioDataManage.cs @@ -648,12 +648,14 @@ namespace DrawGraph pp.ConfigType = "事件"; pp.ConveColor = System.Drawing.Color.White; - pp.IsValid = true; - pp.ClearTagstr(ZedControl); - pp.phListPack = phListPack; - pp.setAnasArr(ZedControl, chartPack.RealX, chartPack.RealEndX, myOpeRecord.PageBegin, - myOpeRecord.PageBegin.AddMinutes(EVERY_PAGE_TIME_SPAN)); - pp.initCurve(); + if (pp.IsDefalultShow == true) + { + pp.IsValid = true; + pp.phListPack = phListPack; + pp.setAnasArr(ZedControl, chartPack.RealX, chartPack.RealEndX, myOpeRecord.PageBegin, + myOpeRecord.PageBegin.AddMinutes(EVERY_PAGE_TIME_SPAN)); + pp.initCurve(); + } } } catch (Exception ex) @@ -744,6 +746,21 @@ namespace DrawGraph } } } + //加载事件图标 + //IList dtevent = PhysioDataConfig.GetEventList(); + //for (int i = 0; i < dtevent.Count; i++) + //{ + // PhysioDataConfig pp = dtevent[i]; + // pp.ConfigType = "事件"; + // pp.ConveColor = System.Drawing.Color.White; + + // pp.IsValid = true; + // pp.ClearTagstr(ZedControl); + // pp.phListPack = phListPack; + // pp.setAnasArr(ZedControl, chartPack.RealX, chartPack.RealEndX, myOpeRecord.PageBegin, + // myOpeRecord.PageBegin.AddMinutes(EVERY_PAGE_TIME_SPAN)); + // pp.initCurve(); + //} if (phListPack != null) { diff --git a/DrawGraph/AreaManage/TemplateManage.cs b/DrawGraph/AreaManage/TemplateManage.cs index c65a59c..088b51a 100644 --- a/DrawGraph/AreaManage/TemplateManage.cs +++ b/DrawGraph/AreaManage/TemplateManage.cs @@ -37,7 +37,7 @@ namespace DrawGraph //private XmlUtil xmlOpe = new XmlUtil(System.Windows.Forms.Application.StartupPath + "\\AIMS.xml"); private TypesettingEnum typesetting = TypesettingEnum.Vertical; private PageTypeEnum pageType = PageTypeEnum.A4; - + public int LocationY { set @@ -103,7 +103,7 @@ namespace DrawGraph if (isUpdate && t != null) { //为真时更新数据库 - i = DBManage.SetOperationRecordValue(t, propertyName, newValue); + i = DBManage.SetOperationRecordValue(t, propertyName, newValue, newText); } if (isUpdate && i <= 0) return i; diff --git a/DrawGraph/AreaManage/TokenEditorManage.cs b/DrawGraph/AreaManage/TokenEditorManage.cs index 600e123..e74a3f8 100644 --- a/DrawGraph/AreaManage/TokenEditorManage.cs +++ b/DrawGraph/AreaManage/TokenEditorManage.cs @@ -27,7 +27,7 @@ namespace DrawGraph PersonType = "0"; break; case "OperationRecord.InstrumentNurse": - tokenEditor.DropDownHeight = 120; + tokenEditor.DropDownHeight = 250; PersonType = "3"; break; case "OperationRecord.Assistant1": @@ -35,7 +35,7 @@ namespace DrawGraph PersonType = "0"; break; case "OperationRecord.TourNurse": - tokenEditor.DropDownHeight = 120; + tokenEditor.DropDownHeight = 250; PersonType = "3"; break; case "OperationRecord.OrtherDoctorId": @@ -94,6 +94,18 @@ namespace DrawGraph } return Id; } + public static string GetWorkerTags(string text, string value) + { + string result = ""; + string sql = string.Format("select Name from Person where Id = '{0}'", value); + object dt = DBHelper.ExecuteScalar(sql); + if (dt != null) + { + string name = dt.ToString(); + result = text.Replace(name, ""); + } + return result; + } public static void SaveDictItem(TemplateManage _template, OperationRecord OpeRecord, TokenEditor tokenEditor, AbleEditPackObj aEdit, bool IsVisible = false) { string SplitChar = ","; @@ -126,6 +138,7 @@ namespace DrawGraph if (aEdit.PackValue != Value) //设置属性的值 _template.SetObjValue(OpeRecord, aEdit.ClassDataSourceName, Value, Key, true); + } public static void SaveDictItemText(TemplateManage _template, OperationRecord OpeRecord, TokenEditor tokenEditor, AbleEditPackObj aEdit, bool IsVisible = false) { @@ -155,5 +168,52 @@ namespace DrawGraph //设置属性的值 _template.SetObjValue(OpeRecord, aEdit.ClassDataSourceName, Value, Value, true); } + public static void SaveDictItem2(TemplateManage _template, OperationRecord OpeRecord, TokenEditor tokenEditor, AbleEditPackObj aEdit, bool IsVisible = false) + { + string SplitChar = ","; + if (aEdit.ClassDataSourceName == "OperationRecord.AnaesthesiaMethodName") + { + SplitChar = "+"; + } + string Value = ""; + string Key = ""; + string Tag = ""; + List namevalue = new List(); + List idvalue = new List(); + List tagvalue = new List(); + + foreach (var item in tokenEditor.SelectedTokens) + { + namevalue.Add(item.Text); + idvalue.Add(item.Value); + tagvalue.Add(GetWorkerTags(item.Text,item.Value)); + } + if (idvalue.Count > 0) + { + Value = string.Join(SplitChar, namevalue); + Key = string.Join(SplitChar, idvalue); + Tag = string.Join("|", tagvalue); + } + else + { + Value = ""; + Key = ""; + Tag = ""; + } + if (IsVisible == true) + aEdit.IsVisible = !aEdit.IsVisible; + if (aEdit.PackValue != Value) + //设置属性的值 + _template.SetObjValue(OpeRecord, aEdit.ClassDataSourceName, Value, Key, true); + + if (aEdit.ClassDataSourceName == "OperationRecord.OperationDoctor") + { + _template.SetObjValue(OpeRecord, "OperationRecord.OpeRecordInfo.Extend4", Tag, Tag, true); + } + else if (aEdit.ClassDataSourceName == "OperationRecord.AnesthesiaDoctor") + { + _template.SetObjValue(OpeRecord, "OperationRecord.OpeRecordInfo.Extend5", Tag, Tag, true); + } + } } } diff --git a/DrawGraph/Graph/Legend.cs b/DrawGraph/Graph/Legend.cs index 77b1da1..a705312 100644 --- a/DrawGraph/Graph/Legend.cs +++ b/DrawGraph/Graph/Legend.cs @@ -24,958 +24,960 @@ using System.Security.Permissions; namespace DrawGraph { - /// - /// This class encapsulates the chart that is displayed - /// in the - /// - /// - /// John Champion - /// $Revision: 3.38 $ $Date: 2007/03/11 02:08:16 $ - [Serializable] - public class Legend : ICloneable, ISerializable - { - #region private Fields - - /// Private field to hold the bounding rectangle around the legend. - /// This bounding rectangle varies with the number of legend entries, font sizes, - /// etc., and is re-calculated by at each redraw. - /// Use the public readonly property to access this - /// rectangle. - /// - private RectangleF _rect; - /// Private field to hold the legend location setting. This field - /// contains the enum type to specify the area of - /// the graph where the legend will be positioned. Use the public property - /// to access this value. - /// - /// - private LegendPos _position; - /// - /// Private field to enable/disable horizontal stacking of the legend entries. - /// If this value is false, then the legend entries will always be a single column. - /// Use the public property to access this value. - /// - /// - private bool _isHStack; - /// - /// Private field to enable/disable drawing of the entire legend. - /// If this value is false, then the legend will not be drawn. - /// Use the public property to access this value. - /// - private bool _isVisible; - /// - /// Private field that stores the data for this - /// . Use the public property to - /// access this value. - /// - private Fill _fill; - /// - /// Private field that stores the data for this - /// . Use the public property to - /// access this value. - /// - private Border _border; - /// - /// Private field to maintain the class that - /// maintains font attributes for the entries in this legend. Use - /// the property to access this class. - /// - private FontSpec _fontSpec; - /// - /// Private field to maintain the location. This object - /// is only applicable if the property is set to - /// . - /// - private Location _location; - - /// - /// Private temporary field to maintain the number of columns (horizontal stacking) to be used - /// for drawing the . This value is only valid during a draw operation. - /// - private int _hStack; - /// - /// Private temporary field to maintain the width of each column in the - /// . This value is only valid during a draw operation. - /// - private float _legendItemWidth; - /// - /// Private temporary field to maintain the height of each row in the - /// . This value is only valid during a draw operation. - /// - private float _legendItemHeight; - - /// - /// Private field to store the gap between the legend and the chart rectangle. - /// - private float _gap; - - // CJBL - /// - /// Private field to select output order of legend entries. - /// - private bool _isReverse; - - /// - /// Private temporary field to maintain the characteristic "gap" for the legend. - /// This is normal the height of the largest font in the legend. - /// This value is only valid during a draw operation. - /// - private float _tmpSize; - - #endregion - - #region Defaults - /// - /// A simple struct that defines the - /// default property values for the class. - /// - public struct Default - { - // Default Legend properties - /// - /// The default pen width for the border border. - /// ( property). Units are in pixels. - /// - public static float BorderWidth = 1; - /// - /// The default color for the border border. - /// ( property). - /// - public static Color BorderColor = Color.Black; - /// - /// The default color for the background. - /// ( property). Use of this - /// color depends on the status of the - /// property. - /// - public static Color FillColor = Color.White; - /// - /// The default custom brush for filling in this . - /// - public static Brush FillBrush = null; - /// - /// The default fill mode for the background. - /// - public static FillType FillType = FillType.Brush; - /// - /// The default location for the on the graph - /// ( property). This property is - /// defined as a enumeration. - /// - public static LegendPos Position = LegendPos.Top; - /// - /// The default border mode for the . - /// ( property). true - /// to draw a border around the , - /// false otherwise. - /// - public static bool IsBorderVisible = true; - /// - /// The default display mode for the . - /// ( property). true - /// to show the legend, - /// false to hide it. - /// - public static bool IsVisible = true; - /// - /// The default fill mode for the background - /// ( property). - /// true to fill-in the background with color, - /// false to leave the background transparent. - /// - public static bool IsFilled = true; - /// - /// The default horizontal stacking mode for the - /// ( property). - /// true to allow horizontal legend item stacking, false to allow - /// only vertical legend orientation. - /// - public static bool IsHStack = true; - - /// - /// The default font family for the entries - /// ( property). - /// - public static string FontFamily = "Arial"; - /// - /// The default font size for the entries - /// ( property). Units are - /// in points (1/72 inch). - /// - public static float FontSize = 12; - /// - /// The default font color for the entries - /// ( property). - /// - public static Color FontColor = Color.Black; - /// - /// The default font bold mode for the entries - /// ( property). true - /// for a bold typeface, false otherwise. - /// - public static bool FontBold = false; - /// - /// The default font italic mode for the entries - /// ( property). true - /// for an italic typeface, false otherwise. - /// - public static bool FontItalic = false; - /// - /// The default font underline mode for the entries - /// ( property). true - /// for an underlined typeface, false otherwise. - /// - public static bool FontUnderline = false; - /// - /// The default color for filling in the scale text background - /// (see property). - /// - public static Color FontFillColor = Color.White; - /// - /// The default custom brush for filling in the scale text background - /// (see property). - /// - public static Brush FontFillBrush = null; - /// - /// The default fill mode for filling in the scale text background - /// (see property). - /// - public static FillType FontFillType = FillType.None; - - /// - /// The default gap size between the legend and the . - /// This is the default value of . - /// - public static float Gap = 0.5f; - - /// - /// Default value for the property. - /// - public static bool IsReverse = false; - } - #endregion - - #region Properties - /// - /// Get the bounding rectangle for the in screen coordinates - /// - /// A screen rectangle in pixel units - public RectangleF Rect - { - get { return _rect; } - } - /// - /// Access to the class used to render - /// the entries - /// - /// A reference to a object - /// - /// - /// - /// - /// - /// - public FontSpec FontSpec - { - get { return _fontSpec; } - set - { - if ( value == null ) - throw new ArgumentNullException( "Uninitialized FontSpec in Legend" ); - _fontSpec = value; - } - } - /// - /// Gets or sets a property that shows or hides the entirely - /// - /// true to show the , false to hide it - /// - public bool IsVisible - { - get { return _isVisible; } - set { _isVisible = value; } - } - /// - /// The class used to draw the border border around this . - /// - public Border Border - { - get { return _border; } - set { _border = value; } - } - /// - /// Gets or sets the data for this - /// background. - /// - public Fill Fill - { - get { return _fill; } - set { _fill = value; } - } - - /// - /// Sets or gets a property that allows the items to - /// stack horizontally in addition to the vertical stacking - /// - /// true to allow horizontal stacking, false otherwise - /// - /// - public bool IsHStack - { - get { return _isHStack; } - set { _isHStack = value; } - } - /// - /// Sets or gets the location of the on the - /// using the enum type - /// - /// - public LegendPos Position - { - get { return _position; } - set { _position = value; } - } - /// - /// Gets or sets the data for the . - /// This property is only applicable if is set - /// to . - /// - public Location Location - { - get { return _location; } - set { _location = value; } - } - - /// - /// Gets or sets the gap size between the legend and the . - /// - /// - /// This is expressed as a fraction of the largest scaled character height for any - /// of the fonts used in the legend. Each in the legend can - /// optionally have its own specification. - /// - public float Gap - { - get { return _gap; } - set { _gap = value; } - } - - /// - /// Gets or sets a value that determines if the legend entries are displayed in normal order - /// (matching the order in the , or in reverse order. - /// - public bool IsReverse - { - get { return _isReverse; } - set { _isReverse = value; } - } - - #endregion - - #region Constructors - /// - /// Default constructor that sets all properties to default - /// values as defined in the class. - /// - public Legend() - { - _position = Default.Position; - _isHStack = Default.IsHStack; - _isVisible = Default.IsVisible; - this.Location = new Location( 0, 0, CoordType.PaneFraction ); - - _fontSpec = new FontSpec( Default.FontFamily, Default.FontSize, - Default.FontColor, Default.FontBold, - Default.FontItalic, Default.FontUnderline, - Default.FontFillColor, Default.FontFillBrush, - Default.FontFillType ); - _fontSpec.Border.IsVisible = false; - - _border = new Border( Default.IsBorderVisible, Default.BorderColor, Default.BorderWidth ); - _fill = new Fill( Default.FillColor, Default.FillBrush, Default.FillType ); - - _gap = Default.Gap; - - _isReverse = Default.IsReverse; - } - - /// - /// The Copy Constructor - /// - /// The XAxis object from which to copy - public Legend( Legend rhs ) - { - _rect = rhs.Rect; - _position = rhs.Position; - _isHStack = rhs.IsHStack; - _isVisible = rhs.IsVisible; - - _location = rhs.Location; - _border = rhs.Border.Clone(); - _fill = rhs.Fill.Clone(); - - _fontSpec = rhs.FontSpec.Clone(); - - _gap = rhs._gap; - - _isReverse = rhs._isReverse; - } - - /// - /// Implement the interface in a typesafe manner by just - /// calling the typed version of - /// - /// A deep copy of this object - object ICloneable.Clone() - { - return this.Clone(); - } - - /// - /// Typesafe, deep-copy clone method. - /// - /// A new, independent copy of this class - public Legend Clone() - { - return new Legend( this ); - } - - #endregion - - #region Serialization - /// - /// Current schema value that defines the version of the serialized file - /// - public const int schema = 11; - - /// - /// Constructor for deserializing objects - /// - /// A instance that defines the serialized data - /// - /// A instance that contains the serialized data - /// - protected Legend( SerializationInfo info, StreamingContext context ) - { - // The schema value is just a file version parameter. You can use it to make future versions - // backwards compatible as new member variables are added to classes - int sch = info.GetInt32( "schema" ); - - _position = (LegendPos) info.GetValue( "position", typeof(LegendPos) ); - _isHStack = info.GetBoolean( "isHStack" ); - _isVisible = info.GetBoolean( "isVisible" ); - _fill = (Fill) info.GetValue( "fill", typeof(Fill) ); - _border = (Border) info.GetValue( "border", typeof(Border) ); - _fontSpec = (FontSpec) info.GetValue( "fontSpec", typeof(FontSpec) ); - _location = (Location) info.GetValue( "location", typeof(Location) ); - - _gap = info.GetSingle( "gap" ); - - if ( schema >= 11 ) - _isReverse = info.GetBoolean( "isReverse" ); - } - /// - /// Populates a instance with the data needed to serialize the target object - /// - /// A instance that defines the serialized data - /// A instance that contains the serialized data - [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)] - public virtual void GetObjectData( SerializationInfo info, StreamingContext context ) - { - info.AddValue( "schema", schema ); - info.AddValue( "position", _position ); - info.AddValue( "isHStack", _isHStack ); - info.AddValue( "isVisible", _isVisible ); - info.AddValue( "fill", _fill ); - info.AddValue( "border", _border ); - info.AddValue( "fontSpec", _fontSpec ); - info.AddValue( "location", _location ); - - info.AddValue( "gap", _gap ); - info.AddValue( "isReverse", _isReverse ); - } - #endregion - - #region Rendering Methods - - /// - /// Render the to the specified device. - /// - /// - /// This method is normally only called by the Draw method - /// of the parent object. - /// - /// - /// A graphic device object to be drawn into. This is normally e.Graphics from the - /// PaintEventArgs argument to the Paint() method. - /// - /// - /// A reference to the object that is the parent or - /// owner of this object. - /// - /// - /// The scaling factor to be used for rendering objects. This is calculated and - /// passed down by the parent object using the - /// method, and is used to proportionally adjust - /// font sizes, etc. according to the actual size of the graph. - /// - public void Draw( Graphics g, PaneBase pane, float scaleFactor ) - { - // if the legend is not visible, do nothing - if ( ! _isVisible ) - return; - - // Fill the background with the specified color if required - _fill.Draw( g, _rect ); - - PaneList paneList = GetPaneList( pane ); - - float halfGap = _tmpSize / 2.0F; - - // Check for bad data values - if ( _hStack <= 0 ) - _hStack = 1; - if ( _legendItemWidth <= 0 ) - _legendItemWidth = 100; - if ( _legendItemHeight <= 0 ) - _legendItemHeight = _tmpSize; - - //float gap = pane.ScaledGap( scaleFactor ); - - int iEntry = 0; - float x, y; - - // Get a brush for the legend label text - using ( SolidBrush brushB = new SolidBrush( Color.Black ) ) - { - foreach ( GraphPane tmpPane in paneList ) - { - // Loop for each curve in the CurveList collection - //foreach ( CurveItem curve in tmpPane.CurveList ) - int count = tmpPane.CurveList.Count; - for ( int i = 0; i < count; i++ ) - { - CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; - - if ( curve._label._text != "" && curve._label._isVisible ) - { - // Calculate the x,y (TopLeft) location of the current - // curve legend label - // assuming: - // charHeight/2 for the left margin, plus legendWidth for each - // horizontal column - // legendHeight is the line spacing, with no extra margin above - - x = _rect.Left + halfGap / 2.0F + - ( iEntry % _hStack ) * _legendItemWidth; - y = _rect.Top + (int)( iEntry / _hStack ) * _legendItemHeight; - - // Draw the legend label for the current curve - FontSpec tmpFont = ( curve._label._fontSpec != null ) ? - curve._label._fontSpec : this.FontSpec; - - // This is required because, for long labels, the centering can affect the - // position in GDI+. - tmpFont.StringAlignment = StringAlignment.Near; - - tmpFont.Draw( g, pane, curve._label._text, - x + 2.5F * _tmpSize, y + _legendItemHeight / 2.0F, - AlignH.Left, AlignV.Center, scaleFactor ); - - RectangleF rect = new RectangleF( x, y + _legendItemHeight / 4.0F, - 2 * _tmpSize, _legendItemHeight / 2.0F ); - curve.DrawLegendKey( g, tmpPane, rect, scaleFactor ); - - // maintain a curve count for positioning - iEntry++; - } - } - if ( pane is MasterPane && ( (MasterPane)pane ).IsUniformLegendEntries ) - break; - } - - // Draw a border around the legend if required - if ( iEntry > 0 ) - this.Border.Draw( g, pane, scaleFactor, _rect ); - } - } - - private float GetMaxHeight( PaneList paneList, Graphics g, float scaleFactor ) - { - // Set up some scaled dimensions for calculating sizes and locations - float defaultCharHeight = this.FontSpec.GetHeight( scaleFactor ); - float maxCharHeight = defaultCharHeight; - - // Find the largest charHeight, just in case the curves have individual fonts defined - foreach ( GraphPane tmpPane in paneList ) - { - foreach ( CurveItem curve in tmpPane.CurveList ) - { - if ( curve._label._text != string.Empty && curve._label._isVisible ) - { - float tmpHeight = defaultCharHeight; - if ( curve._label._fontSpec != null ) - tmpHeight = curve._label._fontSpec.GetHeight( scaleFactor ); - - // Account for multiline legend entries - tmpHeight *= curve._label._text.Split( '\n' ).Length; - - if ( tmpHeight > maxCharHeight ) - maxCharHeight = tmpHeight; - } - } - } - - return maxCharHeight; - } - - /// - /// Determine if a mouse point is within the legend, and if so, which legend - /// entry () is nearest. - /// - /// The screen point, in pixel coordinates. - /// - /// A reference to the object that is the parent or - /// owner of this object. - /// - /// - /// The scaling factor to be used for rendering objects. This is calculated and - /// passed down by the parent object using the - /// method, and is used to proportionally adjust - /// font sizes, etc. according to the actual size of the graph. - /// - /// The index number of the legend - /// entry that is under the mouse point. The object is - /// accessible via CurveList[index]. - /// - /// true if the mouse point is within the bounding - /// box, false otherwise. - /// - public bool FindPoint( PointF mousePt, PaneBase pane, float scaleFactor, out int index ) - { - index = -1; - - if ( _rect.Contains( mousePt ) ) - { - int j = (int) ( ( mousePt.Y - _rect.Top ) / _legendItemHeight ); - int i = (int) ( ( mousePt.X - _rect.Left - _tmpSize / 2.0f ) / _legendItemWidth ); - if ( i < 0 ) - i = 0; - if ( i >= _hStack ) - i = _hStack - 1; - - int pos = i + j * _hStack; - index = 0; - - PaneList paneList = GetPaneList( pane ); - - foreach ( GraphPane tmpPane in paneList ) - { - foreach ( CurveItem curve in tmpPane.CurveList ) - { - if ( curve._label._isVisible && curve._label._text != string.Empty ) - { - if ( pos == 0 ) - return true; - pos--; - } - index++; - } - } - - return true; - } - else - return false; - } - - private PaneList GetPaneList( PaneBase pane ) - { - // For a single GraphPane, create a PaneList to contain it - // Otherwise, just use the paneList from the MasterPane - PaneList paneList; - - if ( pane is GraphPane ) - { - paneList = new PaneList(); - paneList.Add( (GraphPane) pane ); - } - else - paneList = ((MasterPane)pane).PaneList; - - return paneList; - } - - /// - /// Calculate the rectangle (), - /// taking into account the number of required legend - /// entries, and the legend drawing preferences. - /// - /// Adjust the size of the - /// for the parent to accomodate the - /// space required by the legend. - /// - /// - /// A graphic device object to be drawn into. This is normally e.Graphics from the - /// PaintEventArgs argument to the Paint() method. - /// - /// - /// A reference to the object that is the parent or - /// owner of this object. - /// - /// - /// The scaling factor to be used for rendering objects. This is calculated and - /// passed down by the parent object using the - /// method, and is used to proportionally adjust - /// font sizes, etc. according to the actual size of the graph. - /// - /// - /// The rectangle that contains the area bounded by the axes, in pixel units. - /// - /// - public void CalcRect( Graphics g, PaneBase pane, float scaleFactor, - ref RectangleF tChartRect ) - { - // Start with an empty rectangle - _rect = Rectangle.Empty; - _hStack = 1; - _legendItemWidth = 1; - _legendItemHeight = 0; - - RectangleF clientRect = pane.CalcClientRect( g, scaleFactor ); - - // If the legend is invisible, don't do anything - if ( !_isVisible ) - return; - - int nCurve = 0; - - PaneList paneList = GetPaneList( pane ); - _tmpSize = GetMaxHeight( paneList, g, scaleFactor ); - - float halfGap = _tmpSize / 2.0F, - maxWidth = 0, - tmpWidth, - gapPix = _gap * _tmpSize; - - foreach ( GraphPane tmpPane in paneList ) - { - // Loop through each curve in the curve list - // Find the maximum width of the legend labels - //foreach ( CurveItem curve in tmpPane.CurveList ) - //foreach ( CurveItem curve in GetIterator( tmpPane.CurveList, _isReverse ) ) - int count = tmpPane.CurveList.Count; - for ( int i = 0; i < count; i++ ) - { - CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; - if ( curve._label._text != string.Empty && curve._label._isVisible ) - { - // Calculate the width of the label save the max width - FontSpec tmpFont = ( curve._label._fontSpec != null ) ? - curve._label._fontSpec : this.FontSpec; - - tmpWidth = tmpFont.GetWidth( g, curve._label._text, scaleFactor ); - - if ( tmpWidth > maxWidth ) - maxWidth = tmpWidth; - - // Save the maximum symbol height for line-type curves - if ( curve is LineItem && ( (LineItem) curve ).Symbol.Size > _legendItemHeight ) - _legendItemHeight = ( (LineItem) curve ).Symbol.Size; - - nCurve++; - } - } - - if ( pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries ) - break ; - } - - float widthAvail; - - // Is this legend horizontally stacked? - - if ( _isHStack ) - { - // Determine the available space for horizontal stacking - switch( _position ) - { - // Never stack if the legend is to the right or left - case LegendPos.Right: - case LegendPos.Left: - widthAvail = 0; - break; - - // for the top & bottom, the axis border width is available - case LegendPos.Top: - case LegendPos.TopCenter: - case LegendPos.Bottom: - case LegendPos.BottomCenter : - widthAvail = tChartRect.Width; - break; - - // for the top & bottom flush left, the panerect less margins is available - case LegendPos.TopFlushLeft: - case LegendPos.BottomFlushLeft: - widthAvail = clientRect.Width; - break; - - // for inside the axis area or Float, use 1/2 of the axis border width - case LegendPos.InsideTopRight: - case LegendPos.InsideTopLeft: - case LegendPos.InsideBotRight: - case LegendPos.InsideBotLeft: - case LegendPos.Float: - widthAvail = tChartRect.Width / 2; - break; - - // shouldn't ever happen - default: - widthAvail = 0; - break; - } - - // width of one legend entry - _legendItemWidth = 3 * _tmpSize + maxWidth; - - // Calculate the number of columns in the legend - // Normally, the legend is: - // available width / ( max width of any entry + space for line&symbol ) - if ( maxWidth > 0 ) - _hStack = (int) ( (widthAvail - halfGap) / _legendItemWidth ); - - // You can never have more columns than legend entries - if ( _hStack > nCurve ) - _hStack = nCurve; - - // a saftey check - if ( _hStack == 0 ) - _hStack = 1; - } - else - _legendItemWidth = 3.5F * _tmpSize + maxWidth; - - // legend is: - // item: space line space text space - // width: wid 4*wid wid maxWid wid - // The symbol is centered on the line - // - // legend begins 3 * wid to the right of the plot rect - // - // The height of the legend is the actual height of the lines of text - // (nCurve * hite) plus wid on top and wid on the bottom - - // total legend width - float totLegWidth = _hStack * _legendItemWidth; - - // The total legend height - _legendItemHeight = _legendItemHeight * (float) scaleFactor + halfGap; - if ( _tmpSize > _legendItemHeight ) - _legendItemHeight = _tmpSize; - float totLegHeight = (float) Math.Ceiling( (double) nCurve / (double) _hStack ) - * _legendItemHeight; - - RectangleF newRect = new RectangleF(); - - // Now calculate the legend rect based on the above determined parameters - // Also, adjust the ChartRect to reflect the space for the legend - if ( nCurve > 0 ) - { - newRect = new RectangleF( 0, 0, totLegWidth, totLegHeight ); - - // The switch statement assigns the left and top edges, and adjusts the ChartRect - // as required. The right and bottom edges are calculated at the bottom of the switch. - switch( _position ) - { - case LegendPos.Right: - newRect.X = clientRect.Right - totLegWidth; - newRect.Y = tChartRect.Top; - - tChartRect.Width -= totLegWidth + gapPix; - break; - case LegendPos.Top: - newRect.X = tChartRect.Left; - newRect.Y = clientRect.Top; - - tChartRect.Y += totLegHeight + gapPix; - tChartRect.Height -= totLegHeight + gapPix; - break; - case LegendPos.TopFlushLeft: - newRect.X = clientRect.Left; - newRect.Y = clientRect.Top; - - tChartRect.Y += totLegHeight + gapPix * 1.5f; - tChartRect.Height -= totLegHeight + gapPix * 1.5f; - break; - case LegendPos.TopCenter: - newRect.X = tChartRect.Left + ( tChartRect.Width - totLegWidth ) / 2; - newRect.Y = tChartRect.Top; - - tChartRect.Y += totLegHeight + gapPix; - tChartRect.Height -= totLegHeight + gapPix; - break; - case LegendPos.Bottom: - newRect.X = tChartRect.Left; - newRect.Y = clientRect.Bottom - totLegHeight; - - tChartRect.Height -= totLegHeight + gapPix; - break; - case LegendPos.BottomFlushLeft: - newRect.X = clientRect.Left; - newRect.Y = clientRect.Bottom - totLegHeight; - - tChartRect.Height -= totLegHeight + gapPix; - break; - case LegendPos.BottomCenter: - newRect.X = tChartRect.Left + ( tChartRect.Width - totLegWidth ) / 2; - newRect.Y = clientRect.Bottom - totLegHeight; - - tChartRect.Height -= totLegHeight + gapPix; - break; - case LegendPos.Left: - newRect.X = clientRect.Left; - newRect.Y = tChartRect.Top; - - tChartRect.X += totLegWidth + halfGap; - tChartRect.Width -= totLegWidth + gapPix; - break; - case LegendPos.InsideTopRight: - newRect.X = tChartRect.Right - totLegWidth; - newRect.Y = tChartRect.Top; - break; - case LegendPos.InsideTopLeft: - newRect.X = tChartRect.Left; - newRect.Y = tChartRect.Top; - break; - case LegendPos.InsideBotRight: - newRect.X = tChartRect.Right - totLegWidth; - newRect.Y = tChartRect.Bottom - totLegHeight; - break; - case LegendPos.InsideBotLeft: - newRect.X = tChartRect.Left; - newRect.Y = tChartRect.Bottom - totLegHeight; - break; - case LegendPos.Float: - newRect.Location = this.Location.TransformTopLeft( pane, totLegWidth, totLegHeight ); - break; - } - } - - _rect = newRect; - } - -// /// -// /// Private method to the render region that gives the iterator depending on the attribute -// /// -// /// -// /// -// /// -// private IEnumerable GetIterator(CurveList c, bool forward) -// { -// return forward ? c.Forward : c.Backward; -// } - - #endregion - } + /// + /// This class encapsulates the chart that is displayed + /// in the + /// + /// + /// John Champion + /// $Revision: 3.38 $ $Date: 2007/03/11 02:08:16 $ + [Serializable] + public class Legend : ICloneable, ISerializable + { + #region private Fields + + /// Private field to hold the bounding rectangle around the legend. + /// This bounding rectangle varies with the number of legend entries, font sizes, + /// etc., and is re-calculated by at each redraw. + /// Use the public readonly property to access this + /// rectangle. + /// + private RectangleF _rect; + /// Private field to hold the legend location setting. This field + /// contains the enum type to specify the area of + /// the graph where the legend will be positioned. Use the public property + /// to access this value. + /// + /// + private LegendPos _position; + /// + /// Private field to enable/disable horizontal stacking of the legend entries. + /// If this value is false, then the legend entries will always be a single column. + /// Use the public property to access this value. + /// + /// + private bool _isHStack; + /// + /// Private field to enable/disable drawing of the entire legend. + /// If this value is false, then the legend will not be drawn. + /// Use the public property to access this value. + /// + private bool _isVisible; + /// + /// Private field that stores the data for this + /// . Use the public property to + /// access this value. + /// + private Fill _fill; + /// + /// Private field that stores the data for this + /// . Use the public property to + /// access this value. + /// + private Border _border; + /// + /// Private field to maintain the class that + /// maintains font attributes for the entries in this legend. Use + /// the property to access this class. + /// + private FontSpec _fontSpec; + /// + /// Private field to maintain the location. This object + /// is only applicable if the property is set to + /// . + /// + private Location _location; + + /// + /// Private temporary field to maintain the number of columns (horizontal stacking) to be used + /// for drawing the . This value is only valid during a draw operation. + /// + private int _hStack; + /// + /// Private temporary field to maintain the width of each column in the + /// . This value is only valid during a draw operation. + /// + private float _legendItemWidth; + /// + /// Private temporary field to maintain the height of each row in the + /// . This value is only valid during a draw operation. + /// + private float _legendItemHeight; + + /// + /// Private field to store the gap between the legend and the chart rectangle. + /// + private float _gap; + + // CJBL + /// + /// Private field to select output order of legend entries. + /// + private bool _isReverse; + + /// + /// Private temporary field to maintain the characteristic "gap" for the legend. + /// This is normal the height of the largest font in the legend. + /// This value is only valid during a draw operation. + /// + private float _tmpSize; + + #endregion + + #region Defaults + /// + /// A simple struct that defines the + /// default property values for the class. + /// + public struct Default + { + // Default Legend properties + /// + /// The default pen width for the border border. + /// ( property). Units are in pixels. + /// + public static float BorderWidth = 1; + /// + /// The default color for the border border. + /// ( property). + /// + public static Color BorderColor = Color.Black; + /// + /// The default color for the background. + /// ( property). Use of this + /// color depends on the status of the + /// property. + /// + public static Color FillColor = Color.White; + /// + /// The default custom brush for filling in this . + /// + public static Brush FillBrush = null; + /// + /// The default fill mode for the background. + /// + public static FillType FillType = FillType.Brush; + /// + /// The default location for the on the graph + /// ( property). This property is + /// defined as a enumeration. + /// + public static LegendPos Position = LegendPos.Top; + /// + /// The default border mode for the . + /// ( property). true + /// to draw a border around the , + /// false otherwise. + /// + public static bool IsBorderVisible = true; + /// + /// The default display mode for the . + /// ( property). true + /// to show the legend, + /// false to hide it. + /// + public static bool IsVisible = true; + /// + /// The default fill mode for the background + /// ( property). + /// true to fill-in the background with color, + /// false to leave the background transparent. + /// + public static bool IsFilled = true; + /// + /// The default horizontal stacking mode for the + /// ( property). + /// true to allow horizontal legend item stacking, false to allow + /// only vertical legend orientation. + /// + public static bool IsHStack = true; + + /// + /// The default font family for the entries + /// ( property). + /// + public static string FontFamily = "Arial"; + /// + /// The default font size for the entries + /// ( property). Units are + /// in points (1/72 inch). + /// + public static float FontSize = 12; + /// + /// The default font color for the entries + /// ( property). + /// + public static Color FontColor = Color.Black; + /// + /// The default font bold mode for the entries + /// ( property). true + /// for a bold typeface, false otherwise. + /// + public static bool FontBold = false; + /// + /// The default font italic mode for the entries + /// ( property). true + /// for an italic typeface, false otherwise. + /// + public static bool FontItalic = false; + /// + /// The default font underline mode for the entries + /// ( property). true + /// for an underlined typeface, false otherwise. + /// + public static bool FontUnderline = false; + /// + /// The default color for filling in the scale text background + /// (see property). + /// + public static Color FontFillColor = Color.White; + /// + /// The default custom brush for filling in the scale text background + /// (see property). + /// + public static Brush FontFillBrush = null; + /// + /// The default fill mode for filling in the scale text background + /// (see property). + /// + public static FillType FontFillType = FillType.None; + + /// + /// The default gap size between the legend and the . + /// This is the default value of . + /// + public static float Gap = 0.5f; + + /// + /// Default value for the property. + /// + public static bool IsReverse = false; + } + #endregion + + #region Properties + /// + /// Get the bounding rectangle for the in screen coordinates + /// + /// A screen rectangle in pixel units + public RectangleF Rect + { + get { return _rect; } + } + /// + /// Access to the class used to render + /// the entries + /// + /// A reference to a object + /// + /// + /// + /// + /// + /// + public FontSpec FontSpec + { + get { return _fontSpec; } + set + { + if (value == null) + throw new ArgumentNullException("Uninitialized FontSpec in Legend"); + _fontSpec = value; + } + } + /// + /// Gets or sets a property that shows or hides the entirely + /// + /// true to show the , false to hide it + /// + public bool IsVisible + { + get { return _isVisible; } + set { _isVisible = value; } + } + /// + /// The class used to draw the border border around this . + /// + public Border Border + { + get { return _border; } + set { _border = value; } + } + /// + /// Gets or sets the data for this + /// background. + /// + public Fill Fill + { + get { return _fill; } + set { _fill = value; } + } + + /// + /// Sets or gets a property that allows the items to + /// stack horizontally in addition to the vertical stacking + /// + /// true to allow horizontal stacking, false otherwise + /// + /// + public bool IsHStack + { + get { return _isHStack; } + set { _isHStack = value; } + } + /// + /// Sets or gets the location of the on the + /// using the enum type + /// + /// + public LegendPos Position + { + get { return _position; } + set { _position = value; } + } + /// + /// Gets or sets the data for the . + /// This property is only applicable if is set + /// to . + /// + public Location Location + { + get { return _location; } + set { _location = value; } + } + + /// + /// Gets or sets the gap size between the legend and the . + /// + /// + /// This is expressed as a fraction of the largest scaled character height for any + /// of the fonts used in the legend. Each in the legend can + /// optionally have its own specification. + /// + public float Gap + { + get { return _gap; } + set { _gap = value; } + } + + /// + /// Gets or sets a value that determines if the legend entries are displayed in normal order + /// (matching the order in the , or in reverse order. + /// + public bool IsReverse + { + get { return _isReverse; } + set { _isReverse = value; } + } + + #endregion + + #region Constructors + /// + /// Default constructor that sets all properties to default + /// values as defined in the class. + /// + public Legend() + { + _position = Default.Position; + _isHStack = Default.IsHStack; + _isVisible = Default.IsVisible; + this.Location = new Location(0, 0, CoordType.PaneFraction); + + _fontSpec = new FontSpec(Default.FontFamily, Default.FontSize, + Default.FontColor, Default.FontBold, + Default.FontItalic, Default.FontUnderline, + Default.FontFillColor, Default.FontFillBrush, + Default.FontFillType); + _fontSpec.Border.IsVisible = false; + + _border = new Border(Default.IsBorderVisible, Default.BorderColor, Default.BorderWidth); + _fill = new Fill(Default.FillColor, Default.FillBrush, Default.FillType); + + _gap = Default.Gap; + + _isReverse = Default.IsReverse; + } + + /// + /// The Copy Constructor + /// + /// The XAxis object from which to copy + public Legend(Legend rhs) + { + _rect = rhs.Rect; + _position = rhs.Position; + _isHStack = rhs.IsHStack; + _isVisible = rhs.IsVisible; + + _location = rhs.Location; + _border = rhs.Border.Clone(); + _fill = rhs.Fill.Clone(); + + _fontSpec = rhs.FontSpec.Clone(); + + _gap = rhs._gap; + + _isReverse = rhs._isReverse; + } + + /// + /// Implement the interface in a typesafe manner by just + /// calling the typed version of + /// + /// A deep copy of this object + object ICloneable.Clone() + { + return this.Clone(); + } + + /// + /// Typesafe, deep-copy clone method. + /// + /// A new, independent copy of this class + public Legend Clone() + { + return new Legend(this); + } + + #endregion + + #region Serialization + /// + /// Current schema value that defines the version of the serialized file + /// + public const int schema = 11; + + /// + /// Constructor for deserializing objects + /// + /// A instance that defines the serialized data + /// + /// A instance that contains the serialized data + /// + protected Legend(SerializationInfo info, StreamingContext context) + { + // The schema value is just a file version parameter. You can use it to make future versions + // backwards compatible as new member variables are added to classes + int sch = info.GetInt32("schema"); + + _position = (LegendPos)info.GetValue("position", typeof(LegendPos)); + _isHStack = info.GetBoolean("isHStack"); + _isVisible = info.GetBoolean("isVisible"); + _fill = (Fill)info.GetValue("fill", typeof(Fill)); + _border = (Border)info.GetValue("border", typeof(Border)); + _fontSpec = (FontSpec)info.GetValue("fontSpec", typeof(FontSpec)); + _location = (Location)info.GetValue("location", typeof(Location)); + + _gap = info.GetSingle("gap"); + + if (schema >= 11) + _isReverse = info.GetBoolean("isReverse"); + } + /// + /// Populates a instance with the data needed to serialize the target object + /// + /// A instance that defines the serialized data + /// A instance that contains the serialized data + [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("schema", schema); + info.AddValue("position", _position); + info.AddValue("isHStack", _isHStack); + info.AddValue("isVisible", _isVisible); + info.AddValue("fill", _fill); + info.AddValue("border", _border); + info.AddValue("fontSpec", _fontSpec); + info.AddValue("location", _location); + + info.AddValue("gap", _gap); + info.AddValue("isReverse", _isReverse); + } + #endregion + + #region Rendering Methods + + /// + /// Render the to the specified device. + /// + /// + /// This method is normally only called by the Draw method + /// of the parent object. + /// + /// + /// A graphic device object to be drawn into. This is normally e.Graphics from the + /// PaintEventArgs argument to the Paint() method. + /// + /// + /// A reference to the object that is the parent or + /// owner of this object. + /// + /// + /// The scaling factor to be used for rendering objects. This is calculated and + /// passed down by the parent object using the + /// method, and is used to proportionally adjust + /// font sizes, etc. according to the actual size of the graph. + /// + public void Draw(Graphics g, PaneBase pane, float scaleFactor) + { + // if the legend is not visible, do nothing + if (!_isVisible) + return; + + // Fill the background with the specified color if required + _fill.Draw(g, _rect); + + PaneList paneList = GetPaneList(pane); + + float halfGap = _tmpSize / 2.0F; + + // Check for bad data values + if (_hStack <= 0) + _hStack = 1; + if (_legendItemWidth <= 0) + _legendItemWidth = 100; + if (_legendItemHeight <= 0) + _legendItemHeight = _tmpSize; + + //float gap = pane.ScaledGap( scaleFactor ); + + int iEntry = 0; + float x, y; + + // Get a brush for the legend label text + using (SolidBrush brushB = new SolidBrush(Color.Black)) + { + foreach (GraphPane tmpPane in paneList) + { + // Loop for each curve in the CurveList collection + //foreach ( CurveItem curve in tmpPane.CurveList ) + int count = tmpPane.CurveList.Count; + for (int i = 0; i < count; i++) + { + CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; + + if (curve._label._text != "" && curve._label._isVisible) + { + // Calculate the x,y (TopLeft) location of the current + // curve legend label + // assuming: + // charHeight/2 for the left margin, plus legendWidth for each + // horizontal column + // legendHeight is the line spacing, with no extra margin above + + x = _rect.Left + halfGap / 2.0F + + (iEntry % _hStack) * _legendItemWidth; + y = _rect.Top + (int)(iEntry / _hStack) * _legendItemHeight; + + // Draw the legend label for the current curve + FontSpec tmpFont = (curve._label._fontSpec != null) ? + curve._label._fontSpec : this.FontSpec; + + // This is required because, for long labels, the centering can affect the + // position in GDI+. + tmpFont.StringAlignment = StringAlignment.Near; + + tmpFont.Draw(g, pane, curve._label._text, + x + 2.5F * _tmpSize, y + _legendItemHeight / 2.0F, + AlignH.Left, AlignV.Center, scaleFactor); + + RectangleF rect = new RectangleF(x, y + _legendItemHeight / 4.0F, + 2 * _tmpSize, _legendItemHeight / 2.0F); + curve.DrawLegendKey(g, tmpPane, rect, scaleFactor); + + // maintain a curve count for positioning + iEntry++; + } + } + if (pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries) + break; + } + + // Draw a border around the legend if required + if (iEntry > 0) + this.Border.Draw(g, pane, scaleFactor, _rect); + } + } + + private float GetMaxHeight(PaneList paneList, Graphics g, float scaleFactor) + { + // Set up some scaled dimensions for calculating sizes and locations + float defaultCharHeight = this.FontSpec.GetHeight(scaleFactor); + float maxCharHeight = defaultCharHeight; + + // Find the largest charHeight, just in case the curves have individual fonts defined + foreach (GraphPane tmpPane in paneList) + { + foreach (CurveItem curve in tmpPane.CurveList) + { + if (curve._label._text != string.Empty && curve._label._isVisible) + { + float tmpHeight = defaultCharHeight; + if (curve._label._fontSpec != null) + tmpHeight = curve._label._fontSpec.GetHeight(scaleFactor); + + // Account for multiline legend entries + tmpHeight *= curve._label._text.Split('\n').Length; + + if (tmpHeight > maxCharHeight) + maxCharHeight = tmpHeight; + } + } + } + + return maxCharHeight; + } + + /// + /// Determine if a mouse point is within the legend, and if so, which legend + /// entry () is nearest. + /// + /// The screen point, in pixel coordinates. + /// + /// A reference to the object that is the parent or + /// owner of this object. + /// + /// + /// The scaling factor to be used for rendering objects. This is calculated and + /// passed down by the parent object using the + /// method, and is used to proportionally adjust + /// font sizes, etc. according to the actual size of the graph. + /// + /// The index number of the legend + /// entry that is under the mouse point. The object is + /// accessible via CurveList[index]. + /// + /// true if the mouse point is within the bounding + /// box, false otherwise. + /// + public bool FindPoint(PointF mousePt, PaneBase pane, float scaleFactor, out int index) + { + index = -1; + + if (_rect.Contains(mousePt)) + { + int j = (int)((mousePt.Y - _rect.Top) / _legendItemHeight); + int i = (int)((mousePt.X - _rect.Left - _tmpSize / 2.0f) / _legendItemWidth); + if (i < 0) + i = 0; + if (i >= _hStack) + i = _hStack - 1; + + int pos = i + j * _hStack; + index = 0; + + PaneList paneList = GetPaneList(pane); + + foreach (GraphPane tmpPane in paneList) + { + foreach (CurveItem curve in tmpPane.CurveList) + { + if (curve._label._isVisible && curve._label._text != string.Empty) + { + if (pos == 0) + return true; + pos--; + } + index++; + } + } + + return true; + } + else + return false; + } + + private PaneList GetPaneList(PaneBase pane) + { + // For a single GraphPane, create a PaneList to contain it + // Otherwise, just use the paneList from the MasterPane + PaneList paneList; + + if (pane is GraphPane) + { + paneList = new PaneList(); + paneList.Add((GraphPane)pane); + } + else + paneList = ((MasterPane)pane).PaneList; + + return paneList; + } + + /// + /// Calculate the rectangle (), + /// taking into account the number of required legend + /// entries, and the legend drawing preferences. + /// + /// Adjust the size of the + /// for the parent to accomodate the + /// space required by the legend. + /// + /// + /// A graphic device object to be drawn into. This is normally e.Graphics from the + /// PaintEventArgs argument to the Paint() method. + /// + /// + /// A reference to the object that is the parent or + /// owner of this object. + /// + /// + /// The scaling factor to be used for rendering objects. This is calculated and + /// passed down by the parent object using the + /// method, and is used to proportionally adjust + /// font sizes, etc. according to the actual size of the graph. + /// + /// + /// The rectangle that contains the area bounded by the axes, in pixel units. + /// + /// + public void CalcRect(Graphics g, PaneBase pane, float scaleFactor, + ref RectangleF tChartRect) + { + // Start with an empty rectangle + _rect = Rectangle.Empty; + _hStack = 1; + _legendItemWidth = 1; + _legendItemHeight = 0; + + RectangleF clientRect = pane.CalcClientRect(g, scaleFactor); + + // If the legend is invisible, don't do anything + if (!_isVisible) + return; + + int nCurve = 0; + + PaneList paneList = GetPaneList(pane); + _tmpSize = GetMaxHeight(paneList, g, scaleFactor); + + float halfGap = _tmpSize / 2.0F, + maxWidth = 0, + tmpWidth, + gapPix = _gap * _tmpSize; + + foreach (GraphPane tmpPane in paneList) + { + // Loop through each curve in the curve list + // Find the maximum width of the legend labels + //foreach ( CurveItem curve in tmpPane.CurveList ) + //foreach ( CurveItem curve in GetIterator( tmpPane.CurveList, _isReverse ) ) + int count = tmpPane.CurveList.Count; + for (int i = 0; i < count; i++) + { + CurveItem curve = tmpPane.CurveList[_isReverse ? count - i - 1 : i]; + if (curve._label._text != string.Empty && curve._label._isVisible) + { + // Calculate the width of the label save the max width + FontSpec tmpFont = (curve._label._fontSpec != null) ? + curve._label._fontSpec : this.FontSpec; + + tmpWidth = tmpFont.GetWidth(g, curve._label._text, scaleFactor); + + if (tmpWidth > maxWidth) + maxWidth = tmpWidth; + + // Save the maximum symbol height for line-type curves + if (curve is LineItem && ((LineItem)curve).Symbol.Size > _legendItemHeight) + _legendItemHeight = ((LineItem)curve).Symbol.Size; + + if (curve.Label.Text.Contains("") || curve.Label.Text.Contains("") || curve.Label.Text.Contains("") || curve.Label.Text.Contains("")) + curve.Color = Color.White; + nCurve++; + } + } + + if (pane is MasterPane && ((MasterPane)pane).IsUniformLegendEntries) + break; + } + + float widthAvail; + + // Is this legend horizontally stacked? + + if (_isHStack) + { + // Determine the available space for horizontal stacking + switch (_position) + { + // Never stack if the legend is to the right or left + case LegendPos.Right: + case LegendPos.Left: + widthAvail = 0; + break; + + // for the top & bottom, the axis border width is available + case LegendPos.Top: + case LegendPos.TopCenter: + case LegendPos.Bottom: + case LegendPos.BottomCenter: + widthAvail = tChartRect.Width; + break; + + // for the top & bottom flush left, the panerect less margins is available + case LegendPos.TopFlushLeft: + case LegendPos.BottomFlushLeft: + widthAvail = clientRect.Width; + break; + + // for inside the axis area or Float, use 1/2 of the axis border width + case LegendPos.InsideTopRight: + case LegendPos.InsideTopLeft: + case LegendPos.InsideBotRight: + case LegendPos.InsideBotLeft: + case LegendPos.Float: + widthAvail = tChartRect.Width / 2; + break; + + // shouldn't ever happen + default: + widthAvail = 0; + break; + } + + // width of one legend entry + _legendItemWidth = 3 * _tmpSize + maxWidth; + + // Calculate the number of columns in the legend + // Normally, the legend is: + // available width / ( max width of any entry + space for line&symbol ) + if (maxWidth > 0) + _hStack = (int)((widthAvail - halfGap) / _legendItemWidth); + + // You can never have more columns than legend entries + if (_hStack > nCurve) + _hStack = nCurve; + + // a saftey check + if (_hStack == 0) + _hStack = 1; + } + else + _legendItemWidth = 3.5F * _tmpSize + maxWidth; + + // legend is: + // item: space line space text space + // width: wid 4*wid wid maxWid wid + // The symbol is centered on the line + // + // legend begins 3 * wid to the right of the plot rect + // + // The height of the legend is the actual height of the lines of text + // (nCurve * hite) plus wid on top and wid on the bottom + + // total legend width + float totLegWidth = _hStack * _legendItemWidth; + + // The total legend height + _legendItemHeight = _legendItemHeight * (float)scaleFactor + halfGap; + if (_tmpSize > _legendItemHeight) + _legendItemHeight = _tmpSize; + float totLegHeight = (float)Math.Ceiling((double)nCurve / (double)_hStack) + * _legendItemHeight; + + RectangleF newRect = new RectangleF(); + + // Now calculate the legend rect based on the above determined parameters + // Also, adjust the ChartRect to reflect the space for the legend + if (nCurve > 0) + { + newRect = new RectangleF(0, 0, totLegWidth, totLegHeight); + + // The switch statement assigns the left and top edges, and adjusts the ChartRect + // as required. The right and bottom edges are calculated at the bottom of the switch. + switch (_position) + { + case LegendPos.Right: + newRect.X = clientRect.Right - totLegWidth; + newRect.Y = tChartRect.Top; + + tChartRect.Width -= totLegWidth + gapPix; + break; + case LegendPos.Top: + newRect.X = tChartRect.Left; + newRect.Y = clientRect.Top; + + tChartRect.Y += totLegHeight + gapPix; + tChartRect.Height -= totLegHeight + gapPix; + break; + case LegendPos.TopFlushLeft: + newRect.X = clientRect.Left; + newRect.Y = clientRect.Top; + + tChartRect.Y += totLegHeight + gapPix * 1.5f; + tChartRect.Height -= totLegHeight + gapPix * 1.5f; + break; + case LegendPos.TopCenter: + newRect.X = tChartRect.Left + (tChartRect.Width - totLegWidth) / 2; + newRect.Y = tChartRect.Top; + + tChartRect.Y += totLegHeight + gapPix; + tChartRect.Height -= totLegHeight + gapPix; + break; + case LegendPos.Bottom: + newRect.X = tChartRect.Left; + newRect.Y = clientRect.Bottom - totLegHeight; + + tChartRect.Height -= totLegHeight + gapPix; + break; + case LegendPos.BottomFlushLeft: + newRect.X = clientRect.Left; + newRect.Y = clientRect.Bottom - totLegHeight; + + tChartRect.Height -= totLegHeight + gapPix; + break; + case LegendPos.BottomCenter: + newRect.X = tChartRect.Left + (tChartRect.Width - totLegWidth) / 2; + newRect.Y = clientRect.Bottom - totLegHeight; + + tChartRect.Height -= totLegHeight + gapPix; + break; + case LegendPos.Left: + newRect.X = clientRect.Left; + newRect.Y = tChartRect.Top; + + tChartRect.X += totLegWidth + halfGap; + tChartRect.Width -= totLegWidth + gapPix; + break; + case LegendPos.InsideTopRight: + newRect.X = tChartRect.Right - totLegWidth; + newRect.Y = tChartRect.Top; + break; + case LegendPos.InsideTopLeft: + newRect.X = tChartRect.Left; + newRect.Y = tChartRect.Top; + break; + case LegendPos.InsideBotRight: + newRect.X = tChartRect.Right - totLegWidth; + newRect.Y = tChartRect.Bottom - totLegHeight; + break; + case LegendPos.InsideBotLeft: + newRect.X = tChartRect.Left; + newRect.Y = tChartRect.Bottom - totLegHeight; + break; + case LegendPos.Float: + newRect.Location = this.Location.TransformTopLeft(pane, totLegWidth, totLegHeight); + break; + } + } + + _rect = newRect; + } + + // /// + // /// Private method to the render region that gives the iterator depending on the attribute + // /// + // /// + // /// + // /// + // private IEnumerable GetIterator(CurveList c, bool forward) + // { + // return forward ? c.Forward : c.Backward; + // } + + #endregion + } } diff --git a/DrawGraph/Graph/MasterPane.cs b/DrawGraph/Graph/MasterPane.cs index a62f0e9..5497735 100644 --- a/DrawGraph/Graph/MasterPane.cs +++ b/DrawGraph/Graph/MasterPane.cs @@ -573,9 +573,8 @@ namespace DrawGraph // Recalculate the legend rect, just in case it has not yet been done // innerRect is the area for the GraphPane's - RectangleF innerRect = CalcClientRect( g, scaleFactor ); - _legend.CalcRect( g, this, scaleFactor, ref innerRect ); - //this.legend.SetLocation( this, + RectangleF innerRect = CalcClientRect( g, scaleFactor ); + _legend.CalcRect( g, this, scaleFactor, ref innerRect ); _legend.Draw( g, this, scaleFactor );