WinForm使用DecExpress控件中的ChartControl插件繪制圖表

最近因為公司項目需要用到WinForm的DecExpress控件,在這裡把一些使用方法總結一下。

 DevExpress中有一個專門用來繪制圖表的插件ChartControl,可以繪制折線圖、餅狀圖、柱狀圖等圖表。

1.繪制圖表基本步驟

準備數據並綁定

這裡從數據庫中取得數據,可以根據自己的需要修改。

DataTable dtData = BF<bll_ep_collection_data>.Instance.GetDataTable(sqlwhere, "data_time", parameters);
//建立新的datatable,用來存儲XY坐標
DataTable dtXY = new DataTable();
//橫坐標的值
dtXY.Columns.Add(new DataColumn("類型"));
var list = new List<object>();
//縱坐標的值
list.Add("數值");
//這裡是控制x軸顯示數據的數量,ArgumentScaleType類型設置為ScaleType.Qualitative時他不會自動控制x軸的數量
//如果得到數據小於X_COUNT,則x軸顯示全部得到的數據
if (X_COUNT < dtData.Rows.Count)
{
    for (int i = 0; i < X_COUNT; i++)
    {
        int index = (dtData.Rows.Count / X_COUNT) * i;
        DataRow item = dtData.Rows[index];
        dtXY.Columns.Add(new DataColumn(item["data_time"].ToString(), typeof(decimal)));
        list.Add(item["value"]);
    }
}
//如果得到數據大於X_COUNT,則x軸X_COUNT條數據
else
{
    for (int i = 0; i < dtData.Rows.Count; i++)
    {
        DataRow item = dtData.Rows[i];
        dtXY.Columns.Add(new DataColumn(item["data_time"].ToString(), typeof(decimal)));
        list.Add(item["value"]);
    }
}
var array = list.ToArray();
dtXY.Rows.Add(array);
this.chartControl1.DataSource = dtXY;

一個更直白的例子:

DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("類型"));
dt.Columns.Add(new DataColumn("2005-1月", typeof(decimal)));
dt.Columns.Add(new DataColumn("2005-2月", typeof(decimal)));
dt.Columns.Add(new DataColumn("2005-3月", typeof(decimal)));
dt.Columns.Add(new DataColumn("2005-4月", typeof(decimal)));
dt.Columns.Add(new DataColumn("2005-5月", typeof(decimal)));
dt.Columns.Add(new DataColumn("2005-6月", typeof(decimal)));

dt.Rows.Add(new object[] { "員工人數", 437, 437, 414, 397, 387, 378 });
dt.Rows.Add(new object[] { "人均月薪", 3964, 3961, 3979, 3974, 3967, 3972 });
dt.Rows.Add(new object[] { "成本TEU", 3104, 1339, 3595.8, 3154.5, 2499.8, 3026 });
dt.Rows.Add(new object[] { "人均生產率", 7.1, 3.06, 8.69, 7.95, 6.46, 8.01 });
dt.Rows.Add(new object[] { "占2005年3月人數比例", 1.06, 1.06, 1, 0.96, 0.93, 0.91 });

根據數據創建圖形展現

CreateSeries用於創建一個典型的圖形,這裡展示創建一條曲線。

/// <summary>
/// 根據數據創建一個圖形展現
/// </summary>
/// <param name="caption">圖形標題</param>
/// <param name="viewType">圖形類型</param>
/// <param name="dt">數據DataTable</param>
/// <param name="rowIndex">圖形數據的行序號</param>
/// <returns></returns>
private Series CreateSeries(string caption, ViewType viewType, DataTable dt, int rowIndex)
{
    Series series = new Series(caption, viewType);
    for (int i = 1; i < dt.Columns.Count; i++)
    {
        string argument = dt.Columns[i].ColumnName;//參數名稱
        decimal value = (decimal)dt.Rows[rowIndex][i];//參數值
        series.Points.Add(new SeriesPoint(argument, value));
    }
    //必須設置ArgumentScaleType的類型,否則顯示會轉換為日期格式,導致不是希望的格式顯示
    //也就是說,顯示字符串的參數,必須設置類型為ScaleType.Qualitative
    series.ArgumentScaleType = ScaleType.Qualitative;
    //series.ArgumentScaleType = ScaleType.DateTime;
    series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;//顯示標註標簽
    return series;
}

根據圖形對象創建一個圖表並綁定到CharControl中

/// <summary>
/// 根據圖形對象創建一個圖表
/// </summary>
/// <param name="chartControl">圖表綁定控件</param>
/// <param name="list">圖表中的圖形展現</param>
/// <returns></returns>
private void CreateChart(ChartControl chartControl, List<Series> list)
{
    chartControl.Series.AddRange(list.ToArray());
    chartControl.Legend.Visible = false;
    chartControl.SeriesTemplate.LabelsVisibility = DefaultBoolean.False;
    //XYDiagram diagram = (XYDiagram)chartControl1.Diagram;
    //diagram.AxisX.DateTimeMeasureUnit = DateTimeMeasurementUnit.Second;
    //diagram.AxisX.DateTimeOptions.Format = DateTimeFormat.Custom;
    //diagram.AxisX.DateTimeOptions.FormatString = "yyyy-MM-dd HH:mm:ss";
}

調用函數繪制圖表

//清空ChartControl控件
chartControl1.Series.Clear();
//創建圖形對象的列表
List<Series> list = new List<Series>();
foreach (DataRowView item in listBox.Items)
{
    string str = item["key"].ToString();
    //通過LoadData返回一個DataTable
    DataTable dtXY = LoadData(str);
    //創建一個圖形對象
    Series series = CreateSeries(caption, type, dtXY, 0);;
    list.Add(series);
}
//根據圖形對象列表創建一個圖表
CreateChart(chartControl1, list);

小結:在繪制折線圖的時候我遇到的一個很大的問題就是沒辦法控制數據的顯示數量,因為數據庫中存儲的數據量過大,在一定時間段內的數據都能達到上千條,所以不可能一次性全部顯示。我想到的解決辦法是固定顯示多少條數據,比如說20條,然後根據數據量每隔一段距離取一條數據顯示。  

2.柱狀圖

繪制柱狀圖其實和繪制折線圖沒有什麼區別,就是將new Series時的圖形類型改為ViewType.Bar即可,這裡我想總結一下一個困擾我很久的問題,如何繪制上圖所示的一個橫坐標對應兩個或者多個柱子。

準備數據

DataTable dtData = SqlHelper.GetDataSet(sql, parameters).Tables[0];
//建立新的datatable,用來存儲XY坐標
DataTable dtXY_max = new DataTable();
DataTable dtXY_min = new DataTable();
dtXY_max.Columns.Add(new DataColumn("類型"));
dtXY_min.Columns.Add(new DataColumn("類型"));
var list_max = new List<object>();
list_max.Add("數值");
var list_min = new List<object>();
list_min.Add("數值");
for (int i = 0; i < dtData.Rows.Count; i++)
{
    DataRow item = dtData.Rows[i];
    string value = item["max"].ToString() + "|" + item["min"].ToString();
    //dtXY.Columns.Add(new DataColumn(item["data_time"].ToString(), typeof(string)));
    //list.Add(value);
    dtXY_max.Columns.Add(new DataColumn(item["data_time"].ToString(), typeof(decimal)));
    list_max.Add(item["max"]);
    dtXY_min.Columns.Add(new DataColumn(item["data_time"].ToString(), typeof(decimal)));
    list_min.Add(item["min"]);
}
var array_max = list_max.ToArray();
dtXY_max.Rows.Add(array_max);
var array_min = list_min.ToArray();
dtXY_min.Rows.Add(array_min);

創建圖形展現對象方法

/// <summary>
/// 根據數據創建一個圖形展現
/// </summary>
/// <param name="caption">圖形標題</param>
/// <param name="viewType">圖形類型</param>
/// <param name="dt">數據DataTable</param>
/// <param name="rowIndex">圖形數據的行序號</param>
/// <returns></returns>
private Series CreateSeries(string caption, ViewType viewType, DataTable dt, int rowIndex)
{
    Series series = new Series(caption, viewType);
    for (int i = 1; i < dt.Columns.Count; i++)
    {
        string argument = dt.Columns[i].ColumnName;//參數名稱
        decimal value = (decimal) dt.Rows[rowIndex][i];
        series.Points.Add(new SeriesPoint(argument, value));
    }
    //柱狀圖柱子的寬度設置
    //BarSeriesView bsv = (BarSeriesView)series.View;
    //bsv.BarWidth = 0.1;
    //必須設置ArgumentScaleType的類型,否則顯示會轉換為日期格式,導致不是希望的格式顯示
    //也就是說,顯示字符串的參數,必須設置類型為ScaleType.Qualitative
    series.ArgumentScaleType = ScaleType.Qualitative;
    //series.ArgumentScaleType = ScaleType.DateTime;
    series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.True;//顯示標註標簽
    return series;
}

根據圖形對象創建圖表

/// <summary>
/// 根據圖形對象創建一個圖表
/// </summary>
/// <param name="chartControl">圖標綁定控件</param>
/// <param name="list">圖表中的圖形展現</param>
/// <returns></returns>
private void CreateChart(ChartControl chartControl, List<Series> series)
{
    chartControl.Series.AddRange(series.ToArray());
    //chartControl.Series.Add(series);
    chartControl.Legend.Visible = true;
    chartControl.SeriesTemplate.LabelsVisibility = DefaultBoolean.True;
    XYDiagram xydiagram = (XYDiagram)chartControl.Diagram;
    xydiagram.AxisX.MinorCount = 10;
}

3.餅狀圖

準備數據

private DataTable CreateChartData()
{
    DataTable dtData = SqlHelper.GetDataSet(sql, parameters).Tables[0];
    DataTable table = new DataTable("Table1");
    table.Columns.Add("Name", typeof(String));
    table.Columns.Add("Value", typeof(Double));
    foreach (DataRow item in dtData.Rows)
    {
        var array = new object[] { item["value_num"], item["count"] };
        table.Rows.Add(array);
    }
    return table;
}

創建一個餅狀圖

/// <summary>
/// 根據數據創建一個餅狀圖
/// </summary>
/// <returns></returns>
private void BuilderDevChart()
{
    Series _pieSeries = new Series("測試", ViewType.Pie);
    _pieSeries.ValueDataMembers[0] = "Value";
    _pieSeries.ArgumentDataMember = "Name";
    _pieSeries.DataSource = CreateChartData();
    chartControl1.Series.Add(_pieSeries);
    _pieSeries.SetPiePercentage();
    _pieSeries.LegendPointOptions.PointView = PointView.ArgumentAndValues;
}

設置餅狀圖顯示方式(數值/百分比)

public static class ExtensionClass
{
    /// <summary>
    /// 設置餅狀Series顯示方式(值/百分比)
    /// </summary>
    /// <param name="series">Series</param>
    public static void SetPiePercentage(this Series series)
    {
        if (series.View is PieSeriesView)
        {
            //設置為值
            //((PiePointOptions)series.PointOptions).PercentOptions.ValueAsPercent = false;
            //((PiePointOptions)series.PointOptions).ValueNumericOptions.Format = NumericFormat.Number;
            //((PiePointOptions)series.PointOptions).ValueNumericOptions.Precision = 0;
            //設置為百分比
            ((PiePointOptions)series.PointOptions).PercentOptions.ValueAsPercent = true;
            ((PiePointOptions)series.PointOptions).ValueNumericOptions.Format = NumericFormat.Percent;
            ((PiePointOptions)series.PointOptions).ValueNumericOptions.Precision = 0;
        }
    }
}

到此這篇關於WinForm使用DecExpress控件中的ChartControl插件繪制圖表的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: