123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- using DevExpress.Charts.Native;
- using DevExpress.Utils.Extensions;
- using DevExpress.XtraCharts;
- using DevExpress.XtraEditors;
- using DevExpress.XtraLayout;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ExtensionsDev
- {
- public static class ChartExtension
- {
- private enum EnumTimeType
- {
- Year,
- Month,
- Day,
- Hour,
- Minute,
- Second,
- Millisecond
- }
- private class ChartOptions
- {
- public int XLableCount { get; set; } = 5;
- public EnumTimeType TimeType { get; set; } = EnumTimeType.Second;
- public bool ShowMarker { get; set; }
- public int MarkerSize { get; set; } = 4;
- }
- /// <summary>
- /// 快速构建一个Spline类型的ChartControl Series,X轴绑定时间类型的数据(目前还不支持多个series)
- /// </summary>
- /// <param name="ctrl"></param>
- /// <param name="chartTitle">Chart顶部的标题</param>
- /// <param name="unitY">Y轴单位,默认无单位</param>
- /// <param name="yPrecision">Y轴数字保留的精度,默认3(只对double float类型的数据有效)</param>
- /// <param name="xFormat">时间格式字符</param>
- /// <param name="xLableCount">X轴时间显示的标签个数</param>
- /// <param name="showMarker">是否在Spline中显示点(如果绑定的数据点数少于3个,则始终会显示)</param>
- /// <param name="series">该参数会使ChartControl创建多个Series,不含元素时也会创建一个</param>
- /// <returns></returns>
- public static ChartControl UseSplineWithTimeData(this ChartControl ctrl, string chartTitle = "ChartTitle", string unitY = "", int yPrecision = 3, string xFormat = "yyyy-MM-dd HH:mm:ss", int xLableCount = 5, bool showMarker = false,string[] series=null)
- {
- ctrl.Titles.Clear();
- ctrl.Titles.Add(new ChartTitle() { Text = chartTitle });
- ctrl.Series.Clear();
- if (series == null || !series.Any())
- {
- series = new string[1];
- }
- var options = new ChartOptions()
- {
- XLableCount = xLableCount,
- ShowMarker = showMarker,
- };
- foreach (var item in series)
- {
- Series s = new Series();
- s.CrosshairLabelPattern = "{A:" + xFormat + "}\r\n {V:f" + yPrecision + "}" + unitY;
- s.Name = item;
- s.ArgumentScaleType = ScaleType.DateTime;
- SplineSeriesView splineSeriesView1 = new SplineSeriesView();
- s.View = splineSeriesView1;
- s.Tag = options;
- ctrl.Series.Add(s);
- }
- var dt = new DateTime(2000, 2, 2, 1, 1, 1, 1);
- var dtStr = dt.ToString(xFormat);
- var dtNew = DateTime.ParseExact(dtStr, xFormat, null);
- XYDiagram diagram = (XYDiagram)ctrl.Diagram;//坐标系设定
- diagram.AxisX.Tickmarks.MinorVisible = false;
- diagram.AxisY.Tickmarks.MinorVisible = false;
- diagram.AxisX.Label.TextPattern = "{A:" + xFormat + "}";
- diagram.AxisY.Label.TextPattern = "{V}" + unitY;
-
- if (dtNew.Millisecond == 1)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Millisecond;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Millisecond;
- options.TimeType = EnumTimeType.Millisecond;
- }
- else if (dtNew.Second == 1)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Second;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Second;
- options.TimeType = EnumTimeType.Second;
- }
- else if (dtNew.Minute == 1)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Minute;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Minute;
- options.TimeType = EnumTimeType.Minute;
- }
- else if (dtNew.Hour == 1)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Hour;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Hour;
- options.TimeType = EnumTimeType.Hour;
- }
- else if (dtNew.Day == 2)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Day;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Day;
- options.TimeType = EnumTimeType.Day;
- }
- else if (dtNew.Month == 2)
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Month;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Month;
- options.TimeType = EnumTimeType.Month;
- }
- else
- {
- diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Year;
- diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Year;
- options.TimeType = EnumTimeType.Year;
- }
- return ctrl;
- }
- /// <summary>
- /// 设置数据源
- /// </summary>
- /// <typeparam name="T">泛型只支持基本数值类型</typeparam>
- /// <param name="ctrl"></param>
- /// <param name="data"></param>
- /// <param name="series">要设置的series,默认会设置第一个series</param>
- /// <returns></returns>
- public static ChartControl SetData<T>(this ChartControl ctrl, IEnumerable<(DateTime x, T y)> data,string series=null)
- {
- var s = ctrl.Series.Where(p=>p.Name==series).FirstOrDefault() as Series;
- if (s == null)
- s = ctrl.Series.FirstOrDefault() as Series;
- ChartOptions options = s.Tag as ChartOptions;
- (s.View as SplineSeriesView).LineMarkerOptions.Size = options.MarkerSize;
- if (data.Count() < 3)
- (s.View as SplineSeriesView).MarkerVisibility = DevExpress.Utils.DefaultBoolean.True;
- else
- {
- if (options.ShowMarker)
- (s.View as SplineSeriesView).MarkerVisibility = DevExpress.Utils.DefaultBoolean.True;
- else
- (s.View as SplineSeriesView).MarkerVisibility = DevExpress.Utils.DefaultBoolean.False;
- }
- var yMin = data.Select(p => p.y).Min();
- var yMax = data.Select(p => p.y).Max();
- var xMin = data.Select(p => p.x).Min();
- var xMax = data.Select(p => p.x).Max();
- XYDiagram diagram = (XYDiagram)ctrl.Diagram;//坐标系设定
- diagram.AxisY.WholeRange.SetMinMaxValues(yMin, yMax);
- double gridSpacing = 0;
- if (options.TimeType == EnumTimeType.Millisecond)
- {
- gridSpacing = (xMax - xMin).TotalMilliseconds / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Second)
- {
- gridSpacing = (xMax - xMin).TotalSeconds / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Minute)
- {
- gridSpacing = (xMax - xMin).TotalMinutes / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Hour)
- {
- gridSpacing = (xMax - xMin).TotalHours / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Day)
- {
- gridSpacing = (xMax - xMin).TotalDays / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Month)
- {
- gridSpacing = (xMax - xMin).TotalDays / 30d / (options.XLableCount - 1);
- }
- else if (options.TimeType == EnumTimeType.Year)
- {
- gridSpacing = (xMax - xMin).TotalDays / 365d / (options.XLableCount - 1);
- }
- if (gridSpacing > 0)
- diagram.AxisX.DateTimeScaleOptions.GridSpacing = gridSpacing;
- s.Points.AddRange(data.Select(p => new SeriesPoint(p.x, p.y)).ToArray());
- return ctrl;
- }
- }
- }
|