转帖|其它|编辑:郝浩|2011-11-22 13:58:55.000|阅读 2362 次
概述:简单的说Visifire是一组可视化数据控件集合,主要用在WPF、Sliverlight、WP7应用程序中,只需要编写简单的代码就能轻松实现比较绚丽的图表功能,包括3D效果。今天我们将借助该控件在WinForm中借助xaml来实现统计图表功能。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
简单的说Visifire是一组可视化数据控件集合,主要用在WPF、Sliverlight、WP7应用程序中,只需要编写简单的代码就能轻松实现比较绚丽的图表功能,包括3D效果。今天我们将借助该控件在WinForm中借助xaml来实现统计图表功能。
下面我们通过两个例子来看看如何在编写少量代码的前提下,实现统计图表中最常见的直方图、折线图功能。按照常规,还是先预览一下效果吧:
图一:单一数据统计2D效果
图二:单一数据统计3D效果
图三:折线图效果
图四:两组数据对比的3D效果
图一二三是一个页面实现的不同方式,图四用于对比统计。
下面看看图具体实现:
第一步:创建一个xmal (WPF用户控件)
需要给默认代码中的Grid加个x:Name属性,其实就是ID了,用户图表承载作用。
<UserControl x:Class="CHVM.Statistics.ACS"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid x:Name="canvas1">
</Grid>
</UserControl>
然后就是写其交换代码(后台代码xaml.cs)
/// <summary>
/// 数据源 共三列:XValue,YValue
/// </summary>
public DataTable DtChartData
{
get;
set;
}
/// <summary>
/// 创建图表
/// <param name="type">图表类型(Line:折线图 Column:直方图)</param>
/// </summary>
public void CreateChart(string type)
{
if (type=="Line")
{
LineChart();
}
else if(type=="Column")
{
ColumnChart();
}
else
{
MessageBox.Show("创建图表时,类型传值错误!");
}
}
/// <summary>
/// 折线图
/// </summary>
private void LineChart()
{
Chart chart = new Chart();
//chart.View3D = true;
Title title = new Title();
title.Text = "串并统计";
chart.Titles.Add(title);
DataSeries dataSeries = new DataSeries();
dataSeries.RenderAs = RenderAs.Line;//折线图
dataSeries.LabelEnabled = true;
dataSeries.LabelStyle = LabelStyles.OutSide;
DataPoint dataPoint;
for (int i = 0; i < DtChartData.Rows.Count; i++)
{
dataPoint = new DataPoint();
dataPoint.AxisXLabel = DtChartData.Rows[i]["XValue"].ToString();
dataPoint.YValue = Convert.ToDouble(DtChartData.Rows[i]["YValue"]);
dataSeries.DataPoints.Add(dataPoint);
}
chart.Series.Add(dataSeries);
canvas1.Children.Add(chart);
}
/// <summary>
/// 直方图
/// </summary>
private void ColumnChart()
{
Chart chart = new Chart();
chart.View3D = true;
Title title = new Title();
title.Text = "串并统计";
chart.Titles.Add(title);
DataSeries dataSeries = new DataSeries();
dataSeries.LabelEnabled = true;
dataSeries.LabelStyle = LabelStyles.OutSide;
dataSeries.RenderAs = RenderAs.Column;
DataPoint dataPoint;
for (int i = 0; i < DtChartData.Rows.Count; i++)
{
dataPoint = new DataPoint();
dataPoint.AxisXLabel = DtChartData.Rows[i]["XValue"].ToString();
dataPoint.YValue = Convert.ToDouble(DtChartData.Rows[i]["YValue"]);
dataSeries.DataPoints.Add(dataPoint);
}
chart.Series.Add(dataSeries);
canvas1.Children.Add(chart);
}
这里公开了数据源DtChartData(DataTable类型),和一个CreateChart()方法,参数为创建图表的类型。到这里xmal就算完成了。
第二步:创建一个Windows窗体,用于承载xaml,布局如下图所示
后台代码:
public partial class ACSStatistics : Form
{
ACS chart;
string ChartType = "Column"; //显示图像类别Line or Column
int XValueType = 1; //1:按月统计 2:按年统计
public ACSStatistics()
{
InitializeComponent();
dtEnd.Value = DateTime.Now;
dtBegin.Value = DateTime.Now.AddMonths(-6);
chart = new ACS();
ElementHost elHost = new ElementHost();
elHost.Dock = DockStyle.None;
elHost.Width = pnlChart.Width;
elHost.Height = pnlChart.Height;
elHost.Child = chart;
pnlChart.Controls.Add(elHost);
chart.DtChartData = GetData(1);
chart.CreateChart("Column");
if (chart.DtChartData.Rows.Count == 0)
{
MessageBox.Show("没有数据统计", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 查询数据
/// </summary>
/// <param name="type">1:按月统计 2:按年统计</param>
/// <returns></returns>
private DataTable GetData(int type)
{
string strWhere = string.Format(" where T.ACSTIME>='{0}' and T.ACSTIME<='{1}'", dtBegin.Value.ToString("yyyy-MM-dd HH:mm:ss"), dtEnd.Value.ToString("yyyy-MM-dd HH:mm:ss"));
DataTable dt;
if (type==1)
{
string strSql = string.Format(@" select concat(concat(A.InYear,'年'),concat(A.InMonth,'月')) as XValue, A.*,count(A.InMonth)as YValue from (
select SUBSTR(T.ACSTIME,1,4) as InYear,SUBSTR(T.ACSTIME,6,2) as InMonth from TACS T {0})A
group by InYear,InMonth ", strWhere);
dt = DataCon.Query(strSql).Tables[0];
return dt;
}
else if (type == 2)
{
string strSql = string.Format(@"select concat(A.InYear,'年') as XValue,count(A.InYear)as YValue from (
select SUBSTR(T.ACSTIME,1,4) as InYear from TACS T {0})A group by InYear ", strWhere);
dt = DataCon.Query(strSql).Tables[0];
return dt;
}
else
{
return new DataTable();
}
}
/// <summary>
/// 直方图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnColumnChart_Click(object sender, EventArgs e)
{
ChartType = "Column";
chart.DtChartData = GetData(XValueType);
chart.CreateChart(ChartType);
if (chart.DtChartData.Rows.Count == 0)
{
MessageBox.Show("没有数据统计", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 折线图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLineChart_Click(object sender, EventArgs e)
{
ChartType = "Line";
chart.DtChartData = GetData(XValueType);
chart.CreateChart(ChartType);
if (chart.DtChartData.Rows.Count == 0)
{
MessageBox.Show("没有数据统计", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void comboXValueType_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboXValueType.Text=="按月统计")
{
XValueType = 1;
}
else
{
XValueType = 2;
}
if (ChartType=="Column")
{
btnColumnChart_Click(btnColumnChart, e);
}
else if(ChartType=="Line")
{
btnLineChart_Click(btnLineChart, e);
}
}
}
简单说明:在构造函数中设置默认统计为六个月的数据,GetData()方法直接查询数据库(这里是简单实现演示效果,如果代码想分多层的话自己去处理,这个我在这就讲解了)得到DataTable格式的数据,PL-SQL直接查询Oracles数据库效果如下所示:
做统计的时候,重点就是会能用Group By语句了。里面根据统计的方式分为按年按月统计两种,下面是图一二三按年统计的效果:
只有2011年有数据。
例子二:图四的实现过程
其他的不讲了,大部分而例子一是一样的,这里提一下不相同的部分:
一是数据源: 变成三列的要求了,因为我们是对比,所以X值相同,Y值有两个
/// <summary>
/// 数据源 共三列:XValue,YValue1,YValue2
/// </summary>
public DataTable DtChartData
{
get;
set;
}
二是创建图表的方法多了一个循环,循环次数为2,因为我们对比的Y值只有两个,如果是多个,多次循环就行了
/// <summary>
/// 创建图表
/// </summary>
public void CreateChart()
{
Chart chart = new Chart();
chart.View3D = true;
Title title = new Title();
title.Text = "案件统计";
chart.Titles.Add(title);
//Axis axis = new Axis();
//axis.IntervalType = IntervalTypes.Months;
//axis.Interval = 20;
//chart.AxesX.Add(axis);
for( int j=0;j<2;j++)
{
DataSeries dataSeries = new DataSeries();
dataSeries.LabelEnabled = true;
dataSeries.LabelStyle = LabelStyles.OutSide;
if (j==0)
{
dataSeries.Name = "案件总数";
}
else
{
dataSeries.Name = "已破案件";
}
dataSeries.RenderAs = RenderAs.Column;
// dataSeries.XValueType = ChartValueTypes.Auto;
DataPoint dataPoint ;
for(int i=0;i<DtChartData.Rows.Count;i++)
{
dataPoint = new DataPoint();
dataPoint.AxisXLabel = DtChartData.Rows[i]["XValue"].ToString();
if (j==0)
{
dataPoint.YValue = Convert.ToDouble(DtChartData.Rows[i]["YValue1"]);
}
else
{
dataPoint.YValue = Convert.ToDouble(DtChartData.Rows[i]["YValue2"]);
}
dataSeries.DataPoints.Add(dataPoint);
}
chart.Series.Add(dataSeries);
}
canvas1.Children.Add(chart);
}
Winform的后台代码和例子一类似,其实就是获取数据源,不管使用什么方式都可以。
用Visifire实现统计图表效果是不是很简单,很方便呢?呵呵,至少我是这么觉得的!
如果认为直方图和折线图太平常了,希望创建其他图形如:饼状图、雷达图等等,自己去看API吧,也就是RenderAs的枚举值,方法和属性的适用范围不同而已!我们也Overview一下吧:
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:网络转载