摘要:
本文在上一篇的基础之上,介绍如何在图表中加入筛选功能,以及根据数据动态更改图表类型。
为图表增加筛选:
实现思路:在上一篇所示例的MDX语句的基础之上,请查看如下MDX语句:
select [Measures].[Reseller Order Count] on 0,
[Product].[Category].members on 1
from [Sales Targets]
where [Sales Territory].[Sales Territory Country].&[United States]
此处多了where部分,所以我们实现的思路就是通过where查询来对结果进行筛选。
顺便提一下,多个值的筛选如下:
select [Measures].[Reseller Order Count] on 0,
[Product].[Category].members on 1
from [Sales Targets]
where {[Sales Territory].[Sales Territory Country].&[United States],[Sales Territory].[Sales Territory Country].&[United Kingdom]}
这里我们只做简单的示例,所以筛选假设只有一个条件。
首先需要获取一个维度下的所有成员。虽然维度信息可以在AdomdConnection对象下获得,但是由于层次和等级下都有成员不大好确定,所以这里我用一个比较笨的方法,通过MDX语句来查。如下:
select [Measures].[Reseller Order Count] on 0,
[Sales Territory].[Sales Territory Country].[Sales Territory Country].members on 1
from [Sales Targets]
查询的结果:
如上图,列的起始位置和行的起始位置已经标出。根据这个结果,只需要在AdomdDatareader结果中通过循环把第0列的信息读取出来就可以了。(我承认,这个方法很笨)
打开上一节中建立的项目,找到web项目下的web服务文件,添加如下服务代码:
[WebMethod]
public List<string> GetCountryMember()
{
List<string> result = new List<string>();
AdomdConnection conn = new AdomdConnection();
conn.ConnectionString = "provider=msolap ;Integrated Security =SSPI ;Data Source= localhost ;Catalog = Adventure Works DW 2008 ;";
conn.Open();
AdomdCommand comm = new AdomdCommand();
comm.Connection = conn;
string strMDX = "select [Measures].[Reseller Order Count] on 0,[Sales Territory].[Sales Territory Country].[Sales Territory Country].members on 1 from [Sales Targets] ";
comm.CommandText = strMDX;
AdomdDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
result.Add(dr[0].ToString());
}
return result;
}
通过这个服务可以(间接地)获取Sales Territory Country等级下的成员。
然后再在服务中添加一个方法,这个服务和上一节提到的服务差不多,只不过其中有一个string类型的参数,通过它来构建 MDX查询中where后面的部分。代码如下:
[WebMethod]
public List<ChartItem> GetResultByCountry(string countryname)
{
List<ChartItem> result = new List<ChartItem>();
AdomdConnection conn = new AdomdConnection();
conn.ConnectionString = "provider=msolap ;Integrated Security =SSPI ;Data Source= localhost ;Catalog = Adventure Works DW 2008 ;";
conn.Open();
AdomdCommand comm = new AdomdCommand();
comm.Connection = conn;
string strMDX = "select [Measures].[Reseller Order Count] on 0,[Product].[Category].[Category].members on 1 from [Sales Targets] ";
strMDX += "where [Sales Territory].[Sales Territory Country].&["+countryname+"]";
comm.CommandText = strMDX;
AdomdDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
ChartItem ci = new ChartItem();
ci.Title = dr[0].ToString();
ci.Value = double.Parse(dr[1].ToString());
result.Add(ci);
}
return result;
}
至此,服务部分的代码构建完毕。
接下来,需要更新silverlight的服务引用:
如上图,在silverlight项目里展开Service References服务引用,找到上一节已经添加好的服务,右键单击它,选择Update Service Reference更新服务引用就可以了。Visual studio会根据web服务里的wsdl重新生成本地代理类。
服务更新完毕后,打开上一节创建的visifire图表界面,为界面添加一个ListBox作为国家列表的筛选。
这里的XAML文件如下:
<UserControl x:Class="SLVisifire.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="300" xmlns:Visifire_Charts="clr-namespace:Visifire.Charts;assembly=SLVisifire.Charts">
<Grid x:Name="LayoutRoot" Background="White">
<Visifire_Charts:Chart Margin="31,38,170,77" Name="chtTest"/>
<ListBox HorizontalAlignment="Right" Margin="0,38,33,103" Width="113" Name="lstCountry" />
</Grid>
</UserControl>
注:ListBox的添加是可以通过Blend来进行的,aspnetx承认在visual studio里硬敲是很痛苦的。这里直接给出结果xaml代码,具体在Blend如何添加ListBox可以参考TerryLee的相关silverlight教程。
最后打开与之对应的xaml.cs文件,此处需要对之前的代码进行比较大的改动,全部代码如下:
这里需要两次调用服务,第一次加载国家列表,然后每次列表选项更改之后就自动加载另外一个服务把选择的国家传递进去重新获得图表数据。
自此,为图表增加筛选功能的部分修改完毕,运行程序,界面如下:
以上演示的代码是通过一个维度作为筛选依据的示例,当然也可以其它或者更多的维度筛选,方法基本为重复如上的步骤,在此不做太多描述,如有有问题可以和aspnetx联系。
为图表增加动态选取:
也许到目前为止对如上实现功能还不够满足,那么就再加入一些比较眩目的功能。针对上一个图的效果,只能显示柱图,很枯燥,那么添加一个可以随便切换图表类型怎么样?
借助Visifire的功能这个我们可以轻易实现,不过aspnetx在这里建议,对于离散行的变量,适合用柱图,饼图,横条图等方式来展示,对于连续型变量,适合用线图来展示。所以这里我们选择图表可以在柱图,饼图和横条图之间来切换。
首先在界面再添加一个ListBox。
<ListBox Height="72" HorizontalAlignment="Right" Margin="0,0,33,21" VerticalAlignment="Bottom" Width="113" Name="lstChartType" SelectedIndex="0" >
<ListBoxItem Content="柱图"/>
<ListBoxItem Content="饼图"/>
<ListBoxItem Content="横条图"/>
</ListBox>
同样,这个操作建议在Blend操作生成。
然后,在页面(更确切的应该说是用户控件)构造函数,注册如下事件:
lstChartType.SelectionChanged += new SelectionChangedEventHandler(lstChartType_SelectionChanged);
然后加入如下响应代码:
void lstChartType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (((ListBoxItem)lstChartType.SelectedItem).Content.ToString())
{
case "柱图":
chtTest.Series[0].RenderAs = RenderAs.Column;
break;
case "饼图":
chtTest.Series[0].RenderAs = RenderAs.Pie;
break;
case "横条图":
chtTest.Series[0].RenderAs = RenderAs.Bar;
break;
}
}
至此,功能添加完毕,运行程序,就可以通过新加的ListBox来更改图表类型。先看看下面两个图吧:
看上去,是不是没有先前功能那么枯燥了?
总结:
本文在前一篇文章的基础上进行功能扩充,实现更眩更丰富的数据展现效果。通过这两篇文章相信您一定对silverlight以及多维数据集MDX有个更深刻的印象,并且理解使用Silverlight来展现BI数据的优势。
未来的一篇中aspnetx打算用自己做的一个控件来展示多维数据集中的数据。
ChowChow,this is especially for you,I love you