/******************************
* 说明:图表控件
* 创建人:龚宇超
* 创建日期:2018-01-29
* 修改人:
* 修改日期:
* 修改备注:
* 版本:1.0.0.0
******************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lskj.Model;
using DevExpress.XtraCharts;
using DevExpress.Utils;
using Lskj.Control.Model;
using DevExpress.XtraEditors;
using Lskj.Business.Impl;
using DevExpress.XtraGrid.Columns;
using System.Collections;
using Lskj.Util;
namespace Lskj.Control
{
///
/// 图表控件
///
public partial class ChartControlEx : UserControl
{
private List _models;
///
/// 图表控件
///
/// The chart control object.
public ChartControl ChartControlObj { get { return this.cmMain; } }
///
/// 图表控件
///
/// The chart control object.
public GridControlEx GridControlObj { get { return this.gridControlEx1; } }
///
/// 图表控件
///
/// The chart control object.
public DevExpress.XtraEditors.PanelControl PanelControlObj { get { return this.pl_buttom; } }
///
/// 选中位置
///
public SeriesPoint SeriesPoint;
///
/// 是否为横向展示
///
public bool transverseHistogram;
///
/// 分割条
///
/// The chart control object.
public DevExpress.XtraEditors.SplitContainerControl SplitMain { get { return this.splitMain; } }
public ChartControlEx()
{
InitializeComponent();
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel1;//初始化时默认隐藏下方
}
///
/// 说明:
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The chart.
private void CreateSeriesChart(ChartModel chart, Series series, DataTable chartData, DevExpress.XtraGrid.Views.Grid.GridView view = null)
{
foreach (DataRow item in chartData.Rows)
{
//string formatStr = string.Empty;
//if (view != null)
//{
// IEnumerable columns = view.Columns.Where(n => n.FieldName.Equals(chart.YValueField));
// GridColumn column = columns.Count() > 0 ? columns.First() : null;
// if (view != null && column != null) formatStr = (column.Tag is GridColumnModel) ? (column.Tag as GridColumnModel).DataFormat : string.Empty;
//}
string xValue = item[chart.XLabelField] + "";
string yValue = item[chart.YValueField] + "";
//if (formatStr == "0%") series.Label.TextPattern = "{V:0%}";
if (chart.IsAbsolutely != null && chart.IsAbsolutely.Equals("1"))
{
series.Label.TextPattern = "{V:0.00%}";
}
switch (chart.ChartType)
{
default:
case ChartType.LineChart:
CreateSeries(xValue, yValue, item, series);
break;
case ChartType.BarChart:
if (chart.Chart3D == 1)
CreateSeriesBar3D(xValue, yValue, item, series);
else
CreateSeries(xValue, yValue, item, series);
break;
case ChartType.PieChart:
if (chart.Chart3D == 1)
CreateSeriesPie3D(xValue, yValue, item, series);
else
CreateSeriesPie(xValue, yValue, item, series);
break;
}
}
}
///
/// 说明:根据数据创建一个图形展现
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// Name of the col.
/// The col value.
/// The series.
/// Series.
private Series CreateSeries(string colName, string colValue, DataRow dataRow, Series series)
{
SeriesPoint seriesPoint = new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, colValue + "" == "" ? "0" : colValue);
seriesPoint.Tag = dataRow;//缓存数据源
series.Points.Add(seriesPoint);
series.ArgumentScaleType = ScaleType.Qualitative;
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.True;//显示标注标签
return series;
}
///
/// 说明:根据数据创建一个柱状图3D展现
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// Name of the col.
/// The col value.
/// The series.
/// Series.
private Series CreateSeriesBar3D(string colName, string colValue, DataRow dataRow, Series series)
{
SeriesPoint seriesPoint = new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) });
seriesPoint.Tag = dataRow;
series.Points.Add(seriesPoint);
return series;
}
///
/// 说明:根据数据创建一个饼图3D展现
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// Name of the col.
/// The col value.
/// The series.
/// Series.
private Series CreateSeriesPie3D(string colName, string colValue, DataRow dataRow, Series series)
{
if (!string.IsNullOrWhiteSpace(colValue) && double.Parse(colValue) < 0) return series;
SeriesPoint seriesPoint = new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) });
seriesPoint.Tag = dataRow;
series.Points.Add(seriesPoint);
return series;
}
///
/// 说明:根据数据创建一个饼图展现
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// Name of the col.
/// The col value.
/// The series.
/// Series.
private Series CreateSeriesPie(string colName, string colValue, DataRow dataRow, Series series)
{
if (!string.IsNullOrWhiteSpace(colValue) && double.Parse(colValue) < 0) return series;
SeriesPoint seriesPoint = new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) });
seriesPoint.Tag = dataRow;
series.Points.Add(seriesPoint);
return series;
}
///
/// 说明:创建图表的第二坐标系
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The series.
/// Type of the chart.
/// The chart3 d.
/// SecondaryAxisY.
private SecondaryAxisY CreateAxisY(Series series, ChartType chartType, int chart3D)
{
SecondaryAxisY myAxis = new SecondaryAxisY(series.Name);
try
{
((XYDiagram)((Diagram)cmMain.Diagram)).SecondaryAxesY.Add(myAxis);
}
catch (Exception)
{
}
if (chartType == ChartType.LineChart)
((LineSeriesView)series.View).AxisY = myAxis;
if (chartType == ChartType.BarChart)
((BarSeriesView)series.View).AxisY = myAxis;
myAxis.Title.Text = series.Name;
myAxis.Title.Alignment = StringAlignment.Far; //顶部对齐
myAxis.Title.Visibility = DefaultBoolean.True; //显示标题
myAxis.Title.Font = new Font("宋体", 9.0f);
Color color = series.View.Color;//设置坐标的颜色和图表线条颜色一致
myAxis.Title.TextColor = color;
myAxis.Label.TextColor = color;
myAxis.Color = color;
return myAxis;
}
///
/// 说明:设置图表配置数据
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The table.
public void SetCharts(DataTable table)
{
this._models = new List();
DataRow[] drs = table.Select("", "orderId");
foreach (DataRow item in drs)
{
ChartModel chart = new ChartModel();
chart.Chart3D = Convert.ToInt32(item["chart3D"]);
chart.ChartType = (ChartType)Convert.ToInt32(item["chartType"]);
chart.YAxisShared = Convert.ToInt32(item["YAxisShared"]);
chart.YAxisTitle = item["YAxisTitle"] + "";
chart.XLabelField = item["XLabelField"] + "";
chart.YValueField = item["YValueField"] + "";
chart.IsAbsolutely = item.Table.Columns.Contains("IsAbsolutely") ? item["IsAbsolutely"] + "" : null;
chart.YScale = item.Table.Columns.Contains("YScale") && !string.IsNullOrWhiteSpace(item["YScale"].ToString()) ? double.Parse(item["YScale"].ToString()) : 0;
chart.ChartColor= item.Table.Columns.Contains("ChartColor") ? item["ChartColor"] + "" : "";
chart.ValueVisible = item.Table.Columns.Contains("valueVisible") ? "1".Equals(item["valueVisible"] + "") : false;
chart.ChartTitle = item.Table.Columns.Contains("ChartTitle") ? item["ChartTitle"] + "" : "";
this._models.Add(chart);
}
}
///
/// 说明:创建图表
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The models.
/// The fields.
public void CreateChart(DataTable chartData, DevExpress.XtraGrid.Views.Grid.GridView gridView = null)
{
if (cmMain.Diagram is XYDiagram)
(cmMain.Diagram as XYDiagram).SecondaryAxesY.Clear();
cmMain.Series.Clear();
foreach (ChartModel chart in this._models)
{
Series series = null;
string Title = !string.IsNullOrWhiteSpace(chart.ChartTitle) ? chart.ChartTitle : chart.YAxisTitle;
switch (chart.ChartType)
{
case ChartType.LineChart:
default:
series = new Series(Title, chart.Chart3D == 1 ? ViewType.Line3D : ViewType.Line);
break;
case ChartType.BarChart:
series = new Series(Title, chart.Chart3D == 1 ? ViewType.Bar3D : ViewType.Bar);
//柱状图显示值出现在顶端
BarSeriesLabel label = (BarSeriesLabel)series.Label;
label.Position = BarSeriesLabelPosition.Top;
break;
case ChartType.PieChart:
{
if (chart.Chart3D == 1)
{
series = new Series(Title, ViewType.Doughnut3D);
PiePointOptions options = series.Label.PointOptions as PiePointOptions;
((PiePointOptions)series.LegendPointOptions).PointView = PointView.ArgumentAndValues;
Doughnut3DSeriesView view = series.View as Doughnut3DSeriesView;
view.ExplodeMode = PieExplodeMode.All;
series.LegendPointOptions.ValueNumericOptions.Format = NumericFormat.Percent;
series.LabelsVisibility = DefaultBoolean.True;
if (options != null)
{
options.PercentOptions.ValueAsPercent = true;
options.PointView = PointView.ArgumentAndValues;
}
}
else
{
series = new Series(Title, ViewType.Pie);
PiePointOptions options = series.Label.PointOptions as PiePointOptions;
series.LegendPointOptions.ValueNumericOptions.Format = NumericFormat.Percent;
((PiePointOptions)series.LegendPointOptions).PointView = PointView.ArgumentAndValues;
PieSeriesView view = series.View as PieSeriesView;
view.ExplodeMode = PieExplodeMode.All;
view.Rotation = 50;
view.RuntimeExploding = true;
series.LabelsVisibility = DefaultBoolean.True;
if (options != null)
{
options.PercentOptions.ValueAsPercent = true;
options.PointView = PointView.ArgumentAndValues;
}
}
series.LegendTextPattern = "{A}: {VP:P2},{V} ";
break;
}
}
if (series != null)
{
this.CreateSeriesChart(chart, series, chartData, gridView);
series.View.Color = System.Drawing.ColorTranslator.FromHtml(chart.ChartColor);
if(chart.ValueVisible) series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
this.cmMain.Series.Add(series);
//if (chart.ChartType == ChartType.LineChart)
//{
// if (series.Points.Count > 0)
// {
// // 创建文本注解
// TextAnnotation textAnnotation = new TextAnnotation
// {
// Text = chart.YAxisTitle
// };
// SeriesPoint seriesPoint = series.Points[0];
// textAnnotation.AnchorPoint = new SeriesPointAnchorPoint(seriesPoint);
// RelativePosition relativePosition = new RelativePosition();
// relativePosition.Angle = 135;
// relativePosition.ConnectorLength = 100;
// textAnnotation.ShapePosition = relativePosition;
// cmMain.AnnotationRepository.Add(textAnnotation);
// }
//}
if (chart.YScale > 0)
{
(cmMain.Diagram as XYDiagram).AxisY.WholeRange.SetMinMaxValues(0, chart.YScale);
}
if (chart.YAxisShared == 0)
CreateAxisY(series, chart.ChartType, chart.Chart3D);
}
}
if (transverseHistogram && cmMain.Diagram != null) ((XYDiagram)cmMain.Diagram).Rotated = true;
this.cmMain.Legend.Visibility = DefaultBoolean.True;
this.cmMain.SeriesTemplate.LabelsVisibility = DefaultBoolean.True;
this.cmMain.CrosshairEnabled = DefaultBoolean.True;
this.cmMain.ToolTipEnabled = DefaultBoolean.True;
this.cmMain.CustomDrawCrosshair += OnCmMainCustomDrawCrosshair;
this.cmMain.CustomDrawSeriesPoint += OnCmMainCustomDrawSeriesPoint;
// this.cmMain.Legend.AlignmentVertical = LegendAlignmentVertical.Top;
this.cmMain.CrosshairOptions.ShowOnlyInFocusedPane = false;
}
///
/// 说明:双击图表
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The source of the event.
/// The instance containing the event data.
private void cmMain_MouseDoubleClick(object sender, MouseEventArgs e)
{
try
{
ChartHitInfo hitInfo = this.cmMain.CalcHitInfo(e.Location);
if (hitInfo.SeriesPoint != null)
{
if (this.cmMain.ContextMenuStrip != null)
{
foreach (ToolStripMenuItem item in this.cmMain.ContextMenuStrip.Items)
{
if (item.Tag == null && !(item.Tag is GridRightMenuModel))
continue;
GridRightMenuModel model = item.Tag as GridRightMenuModel;
if (model.DbClick)
{
item.PerformClick();
}
}
}
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
///
/// 说明:鼠标移动
/// 创建人:龚宇超
/// 创建日期:2018-01-29
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The source of the event.
/// The instance containing the event data.
private void cmMain_MouseMove(object sender, MouseEventArgs e)
{
try
{
this.SeriesPoint = null;
ChartHitInfo hitInfo = this.cmMain.CalcHitInfo(e.Location);
StringBuilder builder = new StringBuilder();
if (hitInfo.InDiagram)
builder.AppendLine("In Diagram");
if (hitInfo.InNonDefaultPane)
builder.AppendLine("In non-default pane: " + hitInfo.NonDefaultPane.Name);
if (hitInfo.InAxis)
{
builder.AppendLine("In axis: " + hitInfo.Axis.Name);
if (hitInfo.AxisLabelItem != null)
builder.AppendLine(" Label item: " + hitInfo.AxisLabelItem.Text);
if (hitInfo.AxisTitle != null)
builder.AppendLine(" Axis title: " + hitInfo.AxisTitle.Text);
}
if (hitInfo.InChartTitle)
builder.AppendLine("In chart title: " + hitInfo.ChartTitle.Text);
if (hitInfo.InLegend)
builder.AppendLine("In legend");
if (hitInfo.InSeries)
builder.AppendLine("In series: " + ((Series)hitInfo.Series).Name);
if (hitInfo.InSeriesLabel)
{
builder.AppendLine("In series label");
builder.AppendLine(" Series: " + ((Series)hitInfo.Series).Name);
}
if (hitInfo.SeriesPoint != null)
{
SeriesPoint = hitInfo.SeriesPoint;
builder.AppendLine(" Argument: " + hitInfo.SeriesPoint.Argument);
if (!hitInfo.SeriesPoint.IsEmpty)
builder.AppendLine(" Value: " + hitInfo.SeriesPoint.Values[0]);
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
///
/// 自定义悬浮框信息
///
///
///
private void OnCmMainCustomDrawCrosshair(object sender, CustomDrawCrosshairEventArgs e)
{
foreach (CrosshairElementGroup group in e.CrosshairElementGroups)
{
CrosshairGroupHeaderElement groupHeaderElement = group.HeaderElement;
SeriesPoint seriesPoint = groupHeaderElement.SeriesPoints.FirstOrDefault();
if (seriesPoint != null && seriesPoint.Tag != null && seriesPoint.Tag is DataRow dataRow)
{
if (dataRow.Table.Columns.Contains("customHeaderTips"))
{
string customHeaderTips = dataRow["customHeaderTips"] + "";
if (!string.IsNullOrEmpty(customHeaderTips))
{
groupHeaderElement.Text = ReplaceHelper.ReplaceRowParam(dataRow, customHeaderTips);
}
}
}
}
}
///
/// 自定义点样式
///
///
///
private void OnCmMainCustomDrawSeriesPoint(object sender, CustomDrawSeriesPointEventArgs e)
{
int index = e.Series.Points.IndexOf(e.SeriesPoint);
if (e.Series.View is LineSeriesView && index == 0 && e.SeriesPoint != null && e.SeriesPoint.Length > 0)//第一个点显示名称
{
e.LabelText = $"{e.Series.Name}:{e.SeriesPoint[0]}";
}
}
///
/// 设置图标标题
///
///
///
public void SetTitle(string text,string color)
{
// 清空标题
cmMain.Titles.Clear();
// 创建标题
ChartTitle chartTitle = new ChartTitle();
chartTitle.Text = text; // 替换为你的实际标题内容
chartTitle.Font = new Font("微软雅黑", 12, FontStyle.Bold); // 字体样式
if(!string.IsNullOrWhiteSpace(color))chartTitle.TextColor = System.Drawing.ColorTranslator.FromHtml(color);
chartTitle.Dock = ChartTitleDockStyle.Bottom; // 固定在顶部
// 添加到图表
cmMain.Titles.Add(chartTitle);
}
}
///
/// 图表类型
///
public enum ChartType
{
///
/// 线型图表
///
LineChart = 1,
///
/// 柱状图表
///
BarChart = 2,
///
/// 圆饼图表
///
PieChart = 3
}
///
/// 图表对象
///
public class ChartModel
{
///
/// The chart3 d
///
public int Chart3D;
///
/// The y axis shared
///
public int YAxisShared;
///
/// The y axis title
///
public string YAxisTitle;
///
/// The x label field
///
public string XLabelField;
///
/// The y value field
///
public string YValueField;
///
/// The chart color
///
public string ChartColor;
///
/// The chart type
///
public ChartType ChartType;
///
/// 是否为百分比
///
public string IsAbsolutely;
///
/// Y轴最大刻度
///
public double YScale;
///
/// 禁显数字
///
public bool ValueVisible;
///
/// 图表标题
///
public string ChartTitle;
}
}