每周源代码36 – PDC,BabySmash和Silverlight图表


[原文发表地址] The Weekly Source Code 36 - PDC, BabySmash and Silverlight Charting

[原文发表时间] 2008-11-05 21:33

首先我想说,我不断追求并奉信通过阅读源代码使自己成为一个更好的开发者,亲爱的读者,在这里,我给大家呈现第35篇“每周源代码”,当然之后还会有无尽的续篇。

PDC中的关于crazy babies演讲的末尾(一些关于我的准备工作的小贴士),我和Grant为了这个讲演创建了一个很棒的Demo并给出了Silverlight版BabySmash的URL。如果有兴趣,您可以在线观看整个演讲,或者快进到最后看最终的试样(整部片成60分钟左右)。基本上我们是通过ADO.NET Data Services(我会尽快把细节发布上来的)到SQL后端来开展我们的Silverlight BabySmash演讲的。我还有个MVC报表网站,大家都很关注,我在其中也不断更新添加图表。整个演讲过程中有9万多的关注。

clip_image001

大家的反响热烈,于是图表也不断更新。甚至在“A”群和“J”群间还爆发了Baby 对Baby 争论。Jeff Atwoodtweet上引发了这场唇枪舌战,他和Phil Haack在分会场提起呼吁。我想说那人很麻烦。

在谈判中,我从2003年旧版.NET 1.1图表着手,展示了其在ASP.NET3.5 SP1中一成不变的效用。这是个很好的提示,事物往往按照他们既定的方式来运行。然后我将它升级到全新的.NET 4.0 ASP.NET 图表,这个我在之后的博文中会详细介绍。然后我展示了最新的Silverlight图表。Tim Heuer写了篇很棒的博文,介绍如何将这些新图表进行数据绑定

Silverlight图表最酷的地方在于他们是Ms-PL微软公共许可)的,这个非常给力。他们是作为Silverlight工具包的一部分一起发布的,参见http://www.codeplex.com/Silverlight。那上面有很多的控件。这只是个预先版的公布,之后一定也会做些改变,希望会越做越好:

ž Preview Quality Band中的组件

n AutoCompleteBox

n NumericUpDown

n Viewbox

n Expander

n ImplicitStyleManager

n Charting

ž Stable Quality Band中的组件

n TreeView

n DockPanel

n WrapPanel

n Label

n HeaderedContentControl

n HeaderedItemsControl

你可以查看工具包图表样本,在这里亲自试运行。图表样本在Silverlight样本应用中包含源代码,这个相当不错。你可以浏览一打打的图表,然后转换tab,查看XAML和其代码。这些都存在Microsoft.Windows.Controls.DataVisualization里,也就是这些控件的命名空间里。

clip_image002

我的报表页面包括了一个Silverlight图表和Virtual Earth控件,显示了人们都是从哪里发来关注的。数据来源于阿斯陀利亚ADO.NET Data Service,通过JavaScript或者Silverlight都很容易能获取到。

你可以通过向程序集添加引用并为其分配命名空间的方式来把图表添加到你的Silverlight应用程序中:

xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.Charting;assembly=Microsoft.Windows.Controls.DataVisualization"
xmlns:datavis="clr-namespace:Microsoft.Windows.Controls.DataVisualization;assembly=Microsoft.Windows.Controls.DataVisualization"

它们,把它们排列出来。我这里做了两个图表,一个是柱状图,另一个是饼图。我还给背景添加了线性渐变等等。这些很简单。

   1: <charting:Chart Grid.Column="0" Height="300" StylePalette="{StaticResource PaletteColors}" Style="{StaticResource ChartStyle1}" >
   2: <charting:Chart.Background>
   3: <LinearGradientBrush EndPoint="1.332,1.361" StartPoint="-0.107,-0.129">
   4: <GradientStop Color="#FF6CA9D5"/>
   5: <GradientStop Color="#FFFFFFFF" Offset="1"/>
   6: </LinearGradientBrush>
   7: </charting:Chart.Background>
   8: <charting:Chart.Axes>
   9: <charting:Axis x:Name="colAxis" Orientation="Vertical" AxisType="Linear" Minimum="0" Maximum="1"></charting:Axis>
  10: </charting:Chart.Axes>
  11: <charting:Chart.Series>
  12: <charting:ColumnSeries x:Name="colSeries" ItemsSource="{StaticResource BasicValues}" DependentValueBinding="{Binding Count}" IndependentValueBinding="{Binding Character}" Title="Character">
  13: </charting:ColumnSeries>
  14: </charting:Chart.Series>
  15: </charting:Chart>
  16: <charting:Chart Style="{StaticResource ChartStyle1}" Grid.Column="1" Height="300" StylePalette="{StaticResource PaletteColors}" >
  17: <charting:Chart.Axes>
  18: <charting:Axis Orientation="Vertical" AxisType="Linear" Maximum="100000"></charting:Axis>
  19: </charting:Chart.Axes>
  20: <charting:Chart.Series>
  21: <charting:PieSeries x:Name="pieSeries" ItemsSource="{StaticResource BasicValues}" DependentValueBinding="{Binding Count}" IndependentValueBinding="{Binding Character}" Title="Character">
  22: </charting:PieSeries>
  23: </charting:Chart.Series>
  24: </charting:Chart>

我们有一个普通的"CharacterSmash"数据列表,就像<CharacterSmash>列表中的数据那样,我们会绑定到图表中去。

   1: private readonly List<CharacterSmash> characterData = new List<CharacterSmash>();

作为演讲的目的,我只是通过异步调用服务来获取数据,然后更新条状图和饼图:

   1: private void RequestSmashCountData()
   2: {
   3: var container = new SmashMetricsContainer(new Uri("/BabySmashPDC/SmashService.svc", UriKind.Relative));
   4: // Setup data query
   5: var query = container.SmashCount;
   6: // Start the async query
   7: query.BeginExecute((asyncResult =>
   8: {
   9: // Get the matching results from the service call
  10: var matches = query.EndExecute(asyncResult);
  11: UpdateCharacterData(matches);
  12: UpdateBarChart();
  13: UpdatePieChart();
  14: }), null);
  15: }

看到BeginExecute 是怎么把“返回时执行这个”作为一个lambda的了吗?这是个整洁的语法。

更新:Tim Heuer发邮件给我说,我们正在对结果进行重新的数据绑定,此外,他还明智地指出:

“当你为silverlight图表获取粉碎十进制数据时,在我看来你是在重绑数据吗?

比如你绑定了observablecollection,并且只改变了图表应随数据变化的东西,包括Y轴的增量。”

超赞的观点~Tim说得对。我用的方法可行,但是已经过时了。如果我只是更新一个ObservableCollection,那么图表会注意到这些变化并且自动更新。

更新十分清晰,只需将结果进行数据绑定:

   1: private void UpdateBarChart()
   2: {
   3: var axis = (Axis)FindName("colAxis");
   4: if (axis != null)
   5: axis.Maximum = GetMaximumCount() + 50;
   6: var colSeriesControl = (ColumnSeries)FindName("colSeries");
   7: if (colSeriesControl != null)
   8: colSeriesControl.ItemsSource = characterData;
   9: }

我们所要做的就是确定Y轴会随着数据增变。

我们要感谢这种图表控件,但要感谢谁呢?当然是David Anson。他是整个项目的主要开发者和唯一的测试人,你可以去看他的博客,获取Silverlight中图表部分更多的内部信息

更新:David在开发时,以下这些人提供了宝贵帮助:Jafar Husain, Jeremy Sheldon, Delian Tchoparinov, Alex Gorev,Sean Boon还有设计师Mehdi Slaoui Andaloussi

如果做一个复杂的图表似乎令人生畏,没关系,David有ChartBuilder,你现在就能用浏览器运行。它会生成并告诉你图表所需的XAML。

clip_image003

PDC上宣布了很多信息,我希望大家知晓这个重要的公布。而且,这些资源都是开放的,如果你不喜欢,那就换掉它。

Comments (0)

Skip to main content