using DevExpress.XtraCharts; using DevExpress.XtraSplashScreen; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Runtime; using System.Windows.Forms; namespace IStation.WinFrmUI.Monitor { public partial class TimeValueSwiftPlotChartView : DevExpress.XtraEditors.XtraUserControl { public TimeValueSwiftPlotChartView() { InitializeComponent(); InitialDiagarm(); InitialDefaultAxis(); InitialBoxSelHelper(); } #region Initial /// /// 初始化图表 /// private void InitialDiagarm() { //this.moniotrChartControl.Series.Clear(); //this.moniotrChartControl.Titles.Add(new ChartTitle()); //this.moniotrChartControl.Titles[0].Text = "A Point Chart"; //this.moniotrChartControl.Legend.AlignmentHorizontal = LegendAlignmentHorizontal.RightOutside; //获取或设置图表控件中的图例的水平对齐方式。 //this.moniotrChartControl.Legend.AlignmentVertical = LegendAlignmentVertical.Top;//获取或设置图表控件中的图例的竖直对齐方式。 //this.moniotrChartControl.Legend.Direction = LegendDirection.BottomToTop;//获取或设置在该图例中显示系列名称的方向。 //this.moniotrChartControl.Legend.Visibility = DevExpress.Utils.DefaultBoolean.True;//是否在图表上显示图例 this.moniotrChartControl.Legend.Visibility = DevExpress.Utils.DefaultBoolean.True;//是否在图表上显示图例 this.moniotrChartControl.Legend.AlignmentHorizontal = LegendAlignmentHorizontal.RightOutside; this.moniotrChartControl.Legend.AlignmentVertical = LegendAlignmentVertical.Top; this.moniotrChartControl.Legend.TextVisible = true; this.moniotrChartControl.Legend.MarkerMode= LegendMarkerMode.CheckBoxAndMarker; // Access the diagram's properties.把 Diagram 对象转换为所需的图象类型 _diagram = (SwiftPlotDiagram)this.moniotrChartControl.Diagram; //_diagram.Rotated = false;//图像是否旋转 _diagram.EnableAxisXScrolling = true;//X轴是否允许滚动 _diagram.EnableAxisXZooming = true;//X轴是否允许缩放 _diagram.EnableAxisYScrolling = true;//Y轴是否允许滚动 _diagram.EnableAxisYZooming = true;//Y轴是否允许缩放 _diagram.PaneLayout.Direction = PaneLayoutDirection.Vertical;//窗格的对齐方式 // Customize the appearance of the X-axis title.调整 X-轴 _defaultAxisX = _diagram.AxisX;//获取X轴 _defaultAxisX.Alignment = AxisAlignment.Near;//指定轴相对于另一主轴的位置。属性 AxisAlignment.Zero 设置仅对主轴可用 _defaultAxisX.Title.Text = "X轴";//设置轴标题 _defaultAxisX.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; //是否显示轴标题 _defaultAxisX.Label.TextPattern = ""; ////防止过长的轴标签产生重叠 //_defaultAxisX.Label.Angle = 0;//设置轴标签文本旋转的角度 //_defaultAxisX.Label.EnableAntialiasing = DevExpress.Utils.DefaultBoolean.Default;//获取或设置是否对轴标签的文本应用反走样(平滑) //_defaultAxisX.Label.Staggered = false;//轴标签是否是交错排列的 ////_defaultAxisX.DateTimeScaleOptions.ScaleMode = ScaleMode.Continuous; //_defaultAxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Hour; //轴取值的范围是自动确定的(当启用了 xAxis.WholeRange.Auto 属性时),也可以人工指定两个轴取值来限定轴的范围 //xAxis.WholeRange.Auto = false; //xAxis.WholeRange.MaxValue = 70; //xAxis.WholeRange.MinValue = -70; //通过 AxisBase.Logarithmic 和 AxisBase.LogarithmicBase 属性,以对数来呈现轴的取值。 //xAxis.Logarithmic = true; //xAxis.LogarithmicBase = 10; // Create a constant line. 设置常数线 //ConstantLine constantLine1 = new ConstantLine("Constant Line 1"); //_defaultAxisX.ConstantLines.Add(constantLine1); // Create a strip with its maximum and minimum axis value defined.数值带 //_defaultAxisX.Strips.Add(new Strip("Strip 1", 2, 9)); _defaultAxisY = _diagram.AxisY; // Enable automatic scale breaks creation, and define their maximum number.启用自动刻度分隔线 // _defaultAxisY.AutoScaleBreaks.Enabled = true; //_axisY.AutoScaleBreaks.MaxCount = 559; // // Add scale breaks to the Y-axis collection, with their Edge1 and Edge2 properties defined in the constructor.人工把刻度分隔线插入到轴中 //_axisY.ScaleBreaks.Add(new ScaleBreak("Scale Break 1", 110, 100)); //_axisY.ScaleBreaks.Add(new ScaleBreak("Scale Break 2", 110, 2000)); // Customize the appearance of the axes' grid lines.网格显示和设置 _defaultAxisY.GridLines.Visible = true; _defaultAxisY.GridLines.MinorVisible = false; _defaultAxisX.GridLines.Visible = false; _defaultAxisX.GridLines.MinorVisible = false; // Customize the appearance of the axes' tickmarks.刻度线显示和设置 _defaultAxisY.Tickmarks.Visible = false; _defaultAxisY.Tickmarks.MinorVisible = false; /* //定制窗格的滚动条的外观 ScrollBarOptions scrollBarOptions = _defaultDiagramPane.ScrollBarOptions; scrollBarOptions.BackColor = Color.White; scrollBarOptions.BarColor = Color.LightSlateGray; scrollBarOptions.BorderColor = Color.DarkGray; scrollBarOptions.BarThickness = 15; scrollBarOptions.XAxisScrollBarAlignment = ScrollBarAlignment.Far; scrollBarOptions.XAxisScrollBarVisible = true;*/ } /// /// 初始化默认轴线 /// private void InitialDefaultAxis() { //x轴为时间轴 /* _defaultAxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Millisecond; _defaultAxisX.DateTimeScaleOptions.ScaleMode = ScaleMode.Continuous; _defaultAxisX.Label.TextPattern = "{A:yyyy-MM-dd}"; //_defaultAxisX.Title.Font = new System.Drawing.Font("Tahoma", 9F);*/ _defaultAxisX.Title.Text = "时间"; _defaultAxisX.Title.Visibility = 0; //_defaultAxisX.VisibleInPanesSerializable = "-1";//??? //_defaultAxisX.WholeRange.Auto = false; ////_defaultAxisX.WholeRange.SideMarginsValue = 1; //_defaultAxisX.Interlaced = false;//X轴交叉允许 _diagram.AxisY.WholeRange.AlwaysShowZeroLevel = false;//始终显示0水平线 //_diagram.AxisY.Title.Font = new System.Drawing.Font("Tahoma", 9F); _diagram.AxisY.Title.Text = "未知"; _diagram.AxisY.Title.Visibility = 0; //_diagram.AxisY.VisibleInPanesSerializable = "-1";//???? } /// /// 初始化框选辅助类 /// private void InitialBoxSelHelper() { _boxSelHelper = new ChartBoxSelHelper(this.moniotrChartControl); _boxSelHelper.BoxSelCompletedEvent += _boxSelHelper_BoxSelCompletedEvent; } #endregion public void InitialDefaultAxisX() { _defaultAxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Millisecond; _defaultAxisX.DateTimeScaleOptions.ScaleMode = ScaleMode.Manual; } #region BoxSelHelper private string _boxSelTag;//框选标签 //开始框选 public void StartBoxSel(string tag) { _boxSelTag = tag; _diagram.EnableAxisXScrolling = false; _diagram.EnableAxisXZooming = false; _boxSelHelper.StartBoxSel(); } //结束框选 public void CloseBoxSel() { this._boxSelHelper.CloseBoxSel(); } //框选辅助类 private void _boxSelHelper_BoxSelCompletedEvent(MouseEventArgs obj) { _diagram.EnableAxisXScrolling = true; _diagram.EnableAxisXZooming = true; if (_boxSelHelper == null) return; var boxSelSeriesPointList = _boxSelHelper.CalcuDataTimeSelSeriesPoints(new List() { _defaultSeries }); if (boxSelSeriesPointList == null || boxSelSeriesPointList.Count < 1) { _boxSelHelper.CloseBoxSel(); return; } if (this.BoxSelCompleteEvent != null) { var list = boxSelSeriesPointList.Select(x => x.Tag as TimeValue).ToList(); this.BoxSelCompleteEvent.Invoke(_boxSelTag, list); } } #endregion private SwiftPlotDiagram _diagram;//图表 private SwiftPlotDiagramAxisX _defaultAxisX; //默认X轴 private SwiftPlotDiagramAxisY _defaultAxisY; //默认Y轴 private Series _defaultSeries; //默认系列 private ChartBoxSelHelper _boxSelHelper = null;//框选辅助类 public event Action> BoxSelCompleteEvent = null;//框选完成事件 /// /// 初始化默认系列 /// /// 系列的Name(唯一) /// 系列的数据源 public void InitialDefaultSeries(string seriesName, IEnumerable timeValues) { _defaultSeries = this.moniotrChartControl.Series[0]; _defaultSeries.Tag = "default"; _defaultSeries.Name = seriesName; if (timeValues == null || timeValues.Count() < 1) { _defaultSeries.BindToData(timeValues, null); } else { _defaultSeries.BindToData(timeValues, "Time", "Value"); } GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(2, GCCollectionMode.Forced); GC.WaitForFullGCComplete(); } public void SetAxisXTitle(string title) { _defaultAxisX.Title.Text = title; } public void SetAxisYTitle(string title) { _diagram.AxisY.Title.Text = title; } public void SetTimeAxisX(DateTimeMeasureUnit unit) { _defaultAxisX.DateTimeScaleOptions.MeasureUnit = unit; } /// /// 添加 SwiftPlot系列 /// public void AddSwiftPlotSeries(string id, Color color, string caption, string axisYTitle, List timeValues) { //IOverlaySplashScreenHandle lays = null; if (this.moniotrChartControl.Series.Count < 1) { _defaultAxisY.Title.Text = axisYTitle; } { //lays = this.moniotrChartControl.ShowOverlay(); } var swiftPlotSeriesView = new SwiftPlotSeriesView(); swiftPlotSeriesView.Color = color; Series series = new Series(id, ViewType.SwiftPlot); series.Name = id; series.Tag = id; series.CrosshairEnabled = DevExpress.Utils.DefaultBoolean.True; //获取或设置一个值,该值指定此系列是否启用十字准线游标。 series.CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True;//指定是否在特定的2D DEVExt.xCARTARTSs系列的图表上显示十字准线标签。 series.CrosshairLabelPattern = caption + ":({A},{V})";//获取或设置一个字符串表示指定要在当前系列的瞄准线标签中显示的文本的模式 series.CrosshairHighlightPoints = DevExpress.Utils.DefaultBoolean.Default;//获取或设置一个值,该值指定当十字准线光标悬停时,系列点是否突出显示。 //series.ArgumentScaleType = ScaleType.DateTime; //指定系列的参数刻度类型。默认为(ScaleType.Auto)X轴 // series.ValueScaleType = ScaleType.Numerical; //指定系列的取值刻度类型 Y轴 series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.True; //是否显示系列点标签 series.LegendText = caption;//设置标志系列的图例文本 series.DateTimeSummaryOptions.MeasureUnit = DateTimeMeasureUnit.Second; series.View = swiftPlotSeriesView; if (axisYTitle == _defaultAxisY.Title.Text) { swiftPlotSeriesView.AxisY = _diagram.AxisY; } else { var exist = _diagram.SecondaryAxesY.GetAxisByName(axisYTitle); if (exist == null) { AddAxisY(series, axisYTitle); } else { swiftPlotSeriesView.AxisY = exist; } } if (timeValues != null && timeValues.Any()) { series.BindToData(timeValues, "Time", "Value"); } this.moniotrChartControl.Series.Add(series); } /// /// 添加图表的坐标系 /// public void AddAxisY(Series series, string title = "Y轴") { var axisY = new SwiftPlotDiagramSecondaryAxisY(series.Name); ((SwiftPlotSeriesView)series.View).AxisY = axisY;//为当前系列指定Y轴 axisY.Name = title; axisY.Title.Text = title; axisY.Title.Alignment = StringAlignment.Far; //顶部对齐 axisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; //axisY.Title.Font = new Font("宋体", 9.0f); Color color = series.View.Color;//设置坐标的颜色和图表线条颜色一致 axisY.Title.TextColor = color; axisY.Label.TextColor = color; axisY.Color = color; _diagram.SecondaryAxesY.Add(axisY); } /// /// 清空系列 /// public void RemoveSeries(string id) { var lays = this.moniotrChartControl.ShowOverlay(); var seriesCount = this.moniotrChartControl.Series.Count; if (seriesCount > 0) { this.moniotrChartControl.BeginInit(); for (int i = 0; i < seriesCount; i++) { var series = this.moniotrChartControl.Series[i]; if (series.Name == id) { this.moniotrChartControl.Series.RemoveAt(i); break; } } for (int i = 0; i < _diagram.SecondaryAxesY.Count; i++) { var axesY = _diagram.SecondaryAxesY[i]; if (axesY.Name == id) { _diagram.SecondaryAxesY.RemoveAt(i); break; } } this.moniotrChartControl.EndInit(); } lays.Close(); } /// /// 清空系列 /// public void ClearSeries() { this.moniotrChartControl.BeginInit(); this.moniotrChartControl.Series.Clear(); this.moniotrChartControl.EndInit(); } } }