ab56a9bcf7
SVN-Revision: r240
527 lines
21 KiB
C#
527 lines
21 KiB
C#
/******************************
|
|
* 说明:图表控件
|
|
* 创建人:龚宇超
|
|
* 创建日期: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;
|
|
|
|
namespace Lskj.Control
|
|
{
|
|
/// <summary>
|
|
/// 图表控件
|
|
/// </summary>
|
|
public partial class ChartControlEx : UserControl
|
|
{
|
|
private List<ChartModel> _models;
|
|
/// <summary>
|
|
/// 图表控件
|
|
/// </summary>
|
|
/// <value>The chart control object.</value>
|
|
public ChartControl ChartControlObj { get { return this.cmMain; } }
|
|
/// <summary>
|
|
/// 图表控件
|
|
/// </summary>
|
|
/// <value>The chart control object.</value>
|
|
public GridControlEx GridControlObj { get { return this.gridControlEx1; } }
|
|
/// <summary>
|
|
/// 图表控件
|
|
/// </summary>
|
|
/// <value>The chart control object.</value>
|
|
public DevExpress.XtraEditors.PanelControl PanelControlObj { get { return this.pl_buttom; } }
|
|
/// <summary>
|
|
/// 选中位置
|
|
/// </summary>
|
|
public SeriesPoint SeriesPoint;
|
|
/// <summary>
|
|
/// 是否为横向展示
|
|
/// </summary>
|
|
public bool transverseHistogram;
|
|
|
|
public ChartControlEx()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>说明:</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="chart">The chart.</param>
|
|
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<GridColumn> 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, series);
|
|
break;
|
|
case ChartType.BarChart:
|
|
if (chart.Chart3D == 1)
|
|
CreateSeriesBar3D(xValue, yValue, series);
|
|
else
|
|
CreateSeries(xValue, yValue, series);
|
|
break;
|
|
case ChartType.PieChart:
|
|
if (chart.Chart3D == 1)
|
|
CreateSeriesPie3D(xValue, yValue, series);
|
|
else
|
|
CreateSeriesPie(xValue, yValue, series);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:根据数据创建一个图形展现</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="colName">Name of the col.</param>
|
|
/// <param name="colValue">The col value.</param>
|
|
/// <param name="series">The series.</param>
|
|
/// <returns>Series.</returns>
|
|
private Series CreateSeries(string colName, string colValue, Series series)
|
|
{
|
|
|
|
series.Points.Add(new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, colValue + "" == "" ? "0" : colValue));
|
|
series.ArgumentScaleType = ScaleType.Qualitative;
|
|
|
|
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.True;//显示标注标签
|
|
return series;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:根据数据创建一个柱状图3D展现</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="colName">Name of the col.</param>
|
|
/// <param name="colValue">The col value.</param>
|
|
/// <param name="series">The series.</param>
|
|
/// <returns>Series.</returns>
|
|
private Series CreateSeriesBar3D(String colName, String colValue, Series series)
|
|
{
|
|
series.Points.Add(new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) }));
|
|
return series;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:根据数据创建一个饼图3D展现</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="colName">Name of the col.</param>
|
|
/// <param name="colValue">The col value.</param>
|
|
/// <param name="series">The series.</param>
|
|
/// <returns>Series.</returns>
|
|
private Series CreateSeriesPie3D(string colName, String colValue, Series series)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(colValue) && double.Parse(colValue) < 0) return series;
|
|
series.Points.Add(new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) }));
|
|
return series;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:根据数据创建一个饼图展现</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="colName">Name of the col.</param>
|
|
/// <param name="colValue">The col value.</param>
|
|
/// <param name="series">The series.</param>
|
|
/// <returns>Series.</returns>
|
|
private Series CreateSeriesPie(String colName, String colValue, Series series)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(colValue) && double.Parse(colValue) < 0) return series;
|
|
series.Points.Add(new SeriesPoint(colName + "" == "" ? "*指标为空*" : colName, new double[] { Convert.ToDouble(colValue + "" == "" ? "0" : colValue) }));
|
|
return series;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:创建图表的第二坐标系</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="series">The series.</param>
|
|
/// <param name="chartType">Type of the chart.</param>
|
|
/// <param name="chart3D">The chart3 d.</param>
|
|
/// <returns>SecondaryAxisY.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>说明:设置图表配置数据</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="table">The table.</param>
|
|
public void SetCharts(DataTable table)
|
|
{
|
|
this._models = new List<ChartModel>();
|
|
|
|
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;
|
|
this._models.Add(chart);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:创建图表</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="models">The models.</param>
|
|
/// <param name="fields">The fields.</param>
|
|
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;
|
|
|
|
|
|
|
|
switch (chart.ChartType)
|
|
{
|
|
case ChartType.LineChart:
|
|
default:
|
|
series = new Series(chart.YAxisTitle, chart.Chart3D == 1 ? ViewType.Line3D : ViewType.Line);
|
|
break;
|
|
case ChartType.BarChart:
|
|
series = new Series(chart.YAxisTitle, 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(chart.YAxisTitle, 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(chart.YAxisTitle, 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);
|
|
|
|
this.cmMain.Series.Add(series);
|
|
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.Legend.AlignmentVertical = LegendAlignmentVertical.Top;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <para>说明:双击图表</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="sender">The source of the event.</param>
|
|
/// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
|
|
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);
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:鼠标移动</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-29 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="sender">The source of the event.</param>
|
|
/// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
|
|
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 图表类型
|
|
/// </summary>
|
|
public enum ChartType
|
|
{
|
|
/// <summary>
|
|
/// 线型图表
|
|
/// </summary>
|
|
LineChart = 1,
|
|
/// <summary>
|
|
/// 柱状图表
|
|
/// </summary>
|
|
BarChart = 2,
|
|
/// <summary>
|
|
/// 圆饼图表
|
|
/// </summary>
|
|
PieChart = 3
|
|
}
|
|
|
|
/// <summary>
|
|
/// 图表对象
|
|
/// </summary>
|
|
public class ChartModel
|
|
{
|
|
/// <summary>
|
|
/// The chart3 d
|
|
/// </summary>
|
|
public int Chart3D;
|
|
/// <summary>
|
|
/// The y axis shared
|
|
/// </summary>
|
|
public int YAxisShared;
|
|
/// <summary>
|
|
/// The y axis title
|
|
/// </summary>
|
|
public string YAxisTitle;
|
|
/// <summary>
|
|
/// The x label field
|
|
/// </summary>
|
|
public string XLabelField;
|
|
/// <summary>
|
|
/// The y value field
|
|
/// </summary>
|
|
public string YValueField;
|
|
/// <summary>
|
|
/// The chart color
|
|
/// </summary>
|
|
public string ChartColor;
|
|
/// <summary>
|
|
/// The chart type
|
|
/// </summary>
|
|
public ChartType ChartType;
|
|
/// <summary>
|
|
/// 是否为百分比
|
|
/// </summary>
|
|
public string IsAbsolutely;
|
|
/// <summary>
|
|
/// Y轴最大刻度
|
|
/// </summary>
|
|
public double YScale;
|
|
|
|
}
|
|
}
|