Silverlight Chart 综合运用(样式、多轴、数据绑定、点状图、线形图、DataGrid、Chart导出综合运用)
前面的文章,我们已经介绍过样式、数据绑定、点状图、线形图在Silverlight中的基本运用方法。这一章,我们将之前的内容融合起来,并进行一定的扩展。
在下面,我们将实现下图功能:
该图呈现的是一个典型的SQC图(Statistical Quality Control) 图中包含以下内容:
1、Chart、Legend、点、线、的样式设置。
2、多Y轴。图中设置了两个Y轴,第一轴(左) 与数据标准线绑定,显示标准值区间。第二轴(右)与采样点绑定,显示采样数值区间。取样数据。
3、Chart中的Series_SelectionChanged事件,与DataGrid联动。
4、数据标准线。本图中有四条,分别为Warning Limit Up/Warning Limit Low 和 Control Limit Up/Control Limit Low。
5、图中显示了被选择的8个采样点,他们的值分别分布在被数据标准线划分的几个区间内。
6、Chart的导出。(导出功能的实现请看这里)
第一步:在页面上加载需要的控件
我们在页面上放置一个Chart控件,一个DataGrid,一对Button,然后对Chart的每个列进行数据绑定设置。
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
x:Class="MySilverlightTest.Control_ChartMultipleAxis"
Title=""
d:DesignWidth="1024" d:DesignHeight="768"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:toolkitChart="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="493*"/>
</Grid.RowDefinitions>
<toolkitChart:Chart Height="620" HorizontalAlignment="Left" Margin="12,16,0,0" Name="chart" VerticalAlignment="Top" Width="987" BorderThickness="0"></toolkitChart:Chart>
<sdk:DataGrid IsReadOnly="True" ItemsSource="{Binding}" AutoGenerateColumns="False" HorizontalAlignment="Left" Name="dataGrid1" Width="851" Margin="39,623,0,0" CanUserReorderColumns="False" CanUserResizeColumns="True" CanUserSortColumns="False" ColumnWidth="100" Height="59" VerticalAlignment="Top">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Local}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Time" Width="120"/>
<sdk:DataGridTextColumn Binding="{Binding AnalyzerComponent}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Analyzer & Component" Width="150"/>
<sdk:DataGridTextColumn Binding="{Binding Description}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Description" Width="150"/>
<sdk:DataGridTextColumn Binding="{Binding Value}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Value" Width="50"/>
<sdk:DataGridTextColumn Binding="{Binding Quality}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Quality" Width="70"/>
<sdk:DataGridTextColumn Binding="{Binding Unit}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Unit" Width="80"/>
<sdk:DataGridTextColumn Binding="{Binding EngineeringLow}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Engineering Low" Width="Auto"/>
<sdk:DataGridTextColumn Binding="{Binding EngineeringHigh}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Engineering High" Width="Auto"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<Button Content="Export" Height="22" HorizontalAlignment="Left" Margin="373,700,0,0" Name="btnExport" VerticalAlignment="Top" Width="65" Click="btnExport_Click"/>
<Button Content="Close" Height="22" HorizontalAlignment="Left" Margin="554,700,0,0" Name="btnClose" VerticalAlignment="Top" Width="65"/>
</Grid>
</navigation:Page>
然后就需要在后台对数据以及Chart中的各各对象进行设置了。
为点、线、Chart、第二Y轴、Legend定义样式 (关于样式的基本使用方法请看这里和这里)
2 Style ChartAreaStyle =new System.Windows.Style();
3 ChartAreaStyle.TargetType =typeof(System.Windows.Controls.Grid);
4
5 //分别对四条线(两种类型)设置样式
6 Style controlLimitStyle =new System.Windows.Style();
7 controlLimitStyle.TargetType =typeof(System.Windows.Controls.Control);
8
9 Style warningLimitStyle =new System.Windows.Style();
10 warningLimitStyle.TargetType =typeof(System.Windows.Controls.Control);
11
12 //设置线形图中点的样式
13 Style dataPointStyle =new System.Windows.Style();
14 dataPointStyle.TargetType =typeof(System.Windows.Controls.Control);
15
16 Style hideStyle =new System.Windows.Style();
17 hideStyle.TargetType =typeof(System.Windows.Controls.Control);
18
19 //设置时间的显示格式
20 Style timeStyle =new System.Windows.Style();
21 timeStyle.TargetType =typeof(System.Windows.Controls.Control);
22
23 //为Style设置Setter
24 Setter controlLimitsetterTemplate =new Setter(System.Windows.Controls.Control.TemplateProperty, null);
25 Setter warningLimitsetterTemplate =new Setter(System.Windows.Controls.Control.TemplateProperty, null);
26 Setter setterBlue =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Colors.Blue));
27 Setter setterGreen =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 0, 255, 0)));
28 Setter setterRed =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Colors.Red));
29 Setter setterHide =new Setter(System.Windows.Controls.Control.VisibilityProperty, Visibility.Collapsed);
30 Setter setterArea =new Setter(Grid.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 255, 255, 180)));
31 Setter setterTime =new Setter(AxisLabel.StringFormatProperty, "{0:HH:mm}");
32
33 dataPointStyle.Setters.Add(setterBlue);
34 warningLimitStyle.Setters.Add(warningLimitsetterTemplate);
35 controlLimitStyle.Setters.Add(controlLimitsetterTemplate);
36 warningLimitStyle.Setters.Add(setterGreen);
37 controlLimitStyle.Setters.Add(setterRed);
38 hideStyle.Setters.Add(setterHide);
39 ChartAreaStyle.Setters.Add(setterArea);
40 timeStyle.Setters.Add(setterTime);
定义X轴,Y轴和第二Y轴。
2 IAxis dateAxis =new DateTimeAxis { Orientation = AxisOrientation.X, Title ="时间", IntervalType = DateTimeIntervalType.Minutes, Interval =30, AxisLabelStyle = timeStyle };
3 //定义Y轴
4 IAxis valueAxis =new LinearAxis { Orientation = AxisOrientation.Y, Location = AxisLocation.Left, Title ="Lines", Minimum =-10, Maximum =10, ShowGridLines =true };
5 //定义需要绑定的轴
6 IRangeAxis rangeAxis =new LinearAxis
7 {
8 Orientation=AxisOrientation.Y,//指定为Y轴
9 Location=AxisLocation.Right,//呈现在右侧
10 Title ="Range Axis",
11 FontSize =14,
12
13 //设置轴的区间
14 Minimum =-20,
15 Maximum =20,
16
17 //这里使用了两种方法设置颜色
18 Background =new SolidColorBrush(Color.FromArgb(255, 255, 255, 100)),
19 Foreground=new SolidColorBrush(Colors.Blue),
20 };
模拟数据
2
3 _dynamicDateItemsSource =new List<DateTimeValue>();
4
5 //准备数据
6 for (int i =0; i <9; i++)
7 {
8 DateTimeValue lv =new DateTimeValue();
9 lv.Datetime =new DateTime(2008, 10, 1, 13, 22, 5).AddHours(i);
10 double rad = random.NextDouble();
11 if (i%2==0)
12 rad =-1* rad;
13 double num = Math.Round(20* rad, 2);
14 lv.Value = num;
15 lv.Data =new List<PVData> {
16 new PVData {
17 Local ="Root.AREA5.PV"+ i,
18 AnalyzerComponent ="52QA007 D-90",
19 Description ="DISTLL'N 90% BP",
20 Value =num,
21 Quality ="GOOD",
22 Unit ="degC",
23 EngineeringLow = i*4+ i,
24 EngineeringHigh = (i+1) *3-i,
25 }
26 };
27 _dynamicDateItemsSource.Add(lv);
28 }
lines 4条线分别为 warnLimitUp/Low 和 controlLimitUp/Low
2 new LineSeries
3 {
4 ItemsSource = warningLimitUpDate,
5 IndependentValueBinding =new Binding("Datetime"),
6 DependentValueBinding =new Binding("Value"),
7 Title ="Warning Limit",
8 DataPointStyle = warningLimitStyle,
9 LegendItemStyle = hideStyle,//隐藏不需要显示在Legend上的对象
10 };
11
12 LineSeries warnLimitLow =
13 new LineSeries
14 {
15 ItemsSource = warningLimitLowDate,
16 IndependentValueBinding =new Binding("Datetime"),
17 DependentValueBinding =new Binding("Value"),
18 Title ="Warning Limit",
19 DataPointStyle = warningLimitStyle
20 };
21
22 LineSeries controlLimitUp =
23 new LineSeries
24 {
25 ItemsSource = controlLimitUpDate,
26 IndependentValueBinding =new Binding("Datetime"),
27 DependentValueBinding =new Binding("Value"),
28 Title ="Contrl Limit",
29 DataPointStyle = controlLimitStyle,
30 LegendItemStyle = hideStyle
31 };
32
33 LineSeries controlLimitLow =
34 new LineSeries
35 {
36 ItemsSource = controlLimitLowDate,
37 IndependentValueBinding =new Binding("Datetime"),
38 DependentValueBinding =new Binding("Value"),
39 Title ="Contrl Limit",
40 DataPointStyle = controlLimitStyle
41 };
对采样点设置样式,以及绑定到第二Y轴
2 {
3 ItemsSource = _dynamicDateItemsSource,
4 Title ="Validation Value",
5 DataPointStyle = dataPointStyle,
6 IsSelectionEnabled =true,
7 IndependentValueBinding =new Binding("Datetime"),
8 DependentValueBinding =new Binding("Value"),
9 DependentRangeAxis = rangeAxis,//绑定的RangeAxis会自动显示在Chart中
10 };
12 scatterSeries.SelectionChanged +=new SelectionChangedEventHandler(scatterSeries_SelectionChanged);
绑定数据到DataGrid
2 {
3 DateTimeValue dtv = e.AddedItems[0] as DateTimeValue;
4 dataGrid1.DataContext = dtv.Data;
5 }
下面附上完整代码:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Controls.DataVisualization.Charting;
using System.Windows.Data;
namespace MySilverlightTest
{
publicpartialclass Control_ChartMultipleAxis : Page
{
publicclass PVData
{
publicstring Local
{ get; set; }
publicstring AnalyzerComponent
{ get; set; }
publicstring Description
{ get; set; }
publicdouble Value
{ get; set; }
publicstring Quality
{ get; set; }
publicstring Unit
{ get; set; }
publicint EngineeringLow
{ get; set; }
publicint EngineeringHigh
{ get; set; }
}
publicclass DateTimeValue
{
public DateTime Datetime
{
get;
set;
}
publicdouble Value
{
get;
set;
}
public List<PVData> Data
{ get; set; }
}
publicclass LineValue
{
public DateTime Datetime
{ get; set; }
publicdouble Value
{ get; set; }
}
private List<DateTimeValue> _dynamicDateItemsSource =new List<DateTimeValue>();
private List<LineValue> warningLimitUpDate =new List<LineValue>
{
new LineValue{ Datetime=new DateTime(2008, 10, 1,13,22,5),Value=4.0,},
new LineValue{ Datetime=new DateTime(2008, 10, 1,22,22,5),Value=4.0},
};
private List<LineValue> warningLimitLowDate =new List<LineValue>
{
new LineValue{ Datetime=new DateTime(2008, 10, 1,13,22,5),Value=-4.0},
new LineValue{ Datetime=new DateTime(2008, 10, 1,22,22,5),Value=-4.0},
};
private List<LineValue> controlLimitUpDate =new List<LineValue>
{
new LineValue{ Datetime=new DateTime(2008, 10, 1,13,22,5),Value=6},
new LineValue{ Datetime=new DateTime(2008, 10, 1,22,22,5),Value=6},
};
private List<LineValue> controlLimitLowDate =new List<LineValue>
{
new LineValue{ Datetime=new DateTime(2008, 10, 1,13,22,5),Value=-6},
new LineValue{ Datetime=new DateTime(2008, 10, 1,22,22,5),Value=-6},
};
public Control_ChartMultipleAxis()
{
InitializeComponent();
Loaded +=new RoutedEventHandler(Control_ChartMultipleAxis_Loaded);
}
void Control_ChartMultipleAxis_Loaded(object sender, RoutedEventArgs e)
{
#region Styles
//Chart样式
Style ChartAreaStyle =new System.Windows.Style();
ChartAreaStyle.TargetType =typeof(System.Windows.Controls.Grid);
//分别对四条线(两种类型)设置样式
Style controlLimitStyle =new System.Windows.Style();
controlLimitStyle.TargetType =typeof(System.Windows.Controls.Control);
Style warningLimitStyle =new System.Windows.Style();
warningLimitStyle.TargetType =typeof(System.Windows.Controls.Control);
//设置线形图中点的样式
Style dataPointStyle =new System.Windows.Style();
dataPointStyle.TargetType =typeof(System.Windows.Controls.Control);
Style hideStyle =new System.Windows.Style();
hideStyle.TargetType =typeof(System.Windows.Controls.Control);
//设置时间的显示格式
Style timeStyle =new System.Windows.Style();
timeStyle.TargetType =typeof(System.Windows.Controls.Control);
//为Style设置Setter
Setter controlLimitsetterTemplate =new Setter(System.Windows.Controls.Control.TemplateProperty, null);
Setter warningLimitsetterTemplate =new Setter(System.Windows.Controls.Control.TemplateProperty, null);
Setter setterBlue =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Colors.Blue));
Setter setterGreen =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 0, 255, 0)));
Setter setterRed =new Setter(System.Windows.Controls.Control.BackgroundProperty, new SolidColorBrush(Colors.Red));
Setter setterHide =new Setter(System.Windows.Controls.Control.VisibilityProperty, Visibility.Collapsed);
Setter setterArea =new Setter(Grid.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 255, 255, 180)));
Setter setterTime =new Setter(AxisLabel.StringFormatProperty, "{0:HH:mm}");
dataPointStyle.Setters.Add(setterBlue);
warningLimitStyle.Setters.Add(warningLimitsetterTemplate);
controlLimitStyle.Setters.Add(controlLimitsetterTemplate);
warningLimitStyle.Setters.Add(setterGreen);
controlLimitStyle.Setters.Add(setterRed);
hideStyle.Setters.Add(setterHide);
ChartAreaStyle.Setters.Add(setterArea);
timeStyle.Setters.Add(setterTime);
#endregion
//定义X轴
IAxis dateAxis =new DateTimeAxis { Orientation = AxisOrientation.X, Title ="时间", IntervalType = DateTimeIntervalType.Minutes, Interval =30, AxisLabelStyle = timeStyle };
//定义Y轴
IAxis valueAxis =new LinearAxis { Orientation = AxisOrientation.Y, Location = AxisLocation.Left, Title ="Lines", Minimum =-10, Maximum =10, ShowGridLines =true };
//定义需要绑定的轴
IRangeAxis rangeAxis =new LinearAxis
{
Orientation=AxisOrientation.Y,//指定为Y轴
Location=AxisLocation.Right,//呈现在右侧
Title ="Range Axis",
FontSize =14,
//设置轴的区间
Minimum =-20,
Maximum =20,
//这里使用了两种方法设置颜色
Background =new SolidColorBrush(Color.FromArgb(255, 255, 255, 100)),
Foreground=new SolidColorBrush(Colors.Blue),
};
Random random =new Random();
_dynamicDateItemsSource =new List<DateTimeValue>();
//准备数据
for (int i =0; i <9; i++)
{
DateTimeValue lv =new DateTimeValue();
lv.Datetime =new DateTime(2008, 10, 1, 13, 22, 5).AddHours(i);
double rad = random.NextDouble();
if (i%2==0)
rad =-1* rad;
double num = Math.Round(20* rad, 2);
lv.Value = num;
lv.Data =new List<PVData> {
new PVData {
Local ="Root.AREA5.PV"+ i,
AnalyzerComponent ="52QA007 D-90",
Description ="DISTLL'N 90% BP",
Value =num,
Quality ="GOOD",
Unit ="degC",
EngineeringLow = i*4+ i,
EngineeringHigh = (i+1) *3-i,
}
};
_dynamicDateItemsSource.Add(lv);
}
#region lines 4条线分别为 warnLimitUp/Low 和 controlLimitUp/Low
LineSeries warnLimitUp =
new LineSeries
{
ItemsSource = warningLimitUpDate,
IndependentValueBinding =new Binding("Datetime"),
DependentValueBinding =new Binding("Value"),
Title ="Warning Limit",
DataPointStyle = warningLimitStyle,
LegendItemStyle = hideStyle,//隐藏不需要显示在Legend上的对象
};
LineSeries warnLimitLow =
new LineSeries
{
ItemsSource = warningLimitLowDate,
IndependentValueBinding =new Binding("Datetime"),
DependentValueBinding =new Binding("Value"),
Title ="Warning Limit",
DataPointStyle = warningLimitStyle
};
LineSeries controlLimitUp =
new LineSeries
{
ItemsSource = controlLimitUpDate,
IndependentValueBinding =new Binding("Datetime"),
DependentValueBinding =new Binding("Value"),
Title ="Contrl Limit",
DataPointStyle = controlLimitStyle,
LegendItemStyle = hideStyle
};
LineSeries controlLimitLow =
new LineSeries
{
ItemsSource = controlLimitLowDate,
IndependentValueBinding =new Binding("Datetime"),
DependentValueBinding =new Binding("Value"),
Title ="Contrl Limit",
DataPointStyle = controlLimitStyle
};
#endregion
ScatterSeries scatterSeries =new ScatterSeries()
{
ItemsSource = _dynamicDateItemsSource,
Title ="Validation Value",
DataPointStyle = dataPointStyle,
IsSelectionEnabled =true,
IndependentValueBinding =new Binding("Datetime"),
DependentValueBinding =new Binding("Value"),
DependentRangeAxis = rangeAxis,//绑定的RangeAxis会自动显示在Chart中
};
scatterSeries.SelectionChanged +=new SelectionChangedEventHandler(scatterSeries_SelectionChanged);
chart.Title =null;
chart.Series.Add(warnLimitUp);
chart.Series.Add(warnLimitLow);
chart.Series.Add(controlLimitUp);
chart.Series.Add(controlLimitLow);
chart.Series.Add(scatterSeries);
chart.PlotAreaStyle = ChartAreaStyle;
chart.Axes.Add(dateAxis);
chart.Axes.Add(valueAxis);
}
void scatterSeries_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DateTimeValue dtv = e.AddedItems[0] as DateTimeValue;
dataGrid1.DataContext = dtv.Data;
}
privatevoid btnExport_Click(object sender, RoutedEventArgs e)
{
ElementToPNG eTP =new ElementToPNG();
eTP.ShowSaveDialog(chart);
}
// Executes when the user navigates to this page.
protectedoverridevoid OnNavigatedTo(NavigationEventArgs e)
{
}
}
}