Silverlight 4 Toolkit 中图表控件的样式






4.85/5 (13投票s)
通过设置 Silverlight Toolkit 中的图表控件样式,创造新的外观和感觉。
引言
我注意到许多人,包括我自己,在 styling Silverlight 4 Toolkit 中附带的 Chart
控件时遇到了一些困难。要深入到控件的视觉树以在 Expression Blend 的 Design 视图中 styling 该控件,以获得良好的外观和感觉,相对来说是比较困难的。我在网上搜索了一下,关于如何进行此过程的信息很少,于是我决定自己来解决。我成功地重新 styling 了图表控件,并且大部分工作都是在 XAML 中完成的。我认为本文将缓解其他开发者/设计师在面临同样问题时的挑战。
Silverlight 4 Toolkit 中包含一系列 Chart
控件,其中一些列在下面
BarSeries
ColumnSeries
StackedColumnSeries
BubbleSeries
LineSeries
PieSeries
ScatterSeries
我将讨论其中的两个系列
ColumnSeries
StackedColumnSeries
注意:您可以在 Expression Blend 4 和 Visual Studio 2010 中遵循本文中的步骤,但我将在本文中使用 Expression Blend 4。如果您没有该工具包,可以在 Silverlight Toolkit - CodePlex 下载。
ColumnSeries
在创建了一个新的 Silverlight 应用程序后,我添加了一个 Chart
控件并编辑了 Template
。在本文中,我决定从 Template 中删除 Legend 和 Chart Title,因为我不需要它们。Chart Title 仍然可以使用,所以您可以保留您的,但 Legend 没有用,因为我们将为每个柱子使用不同的颜色。图表控件现在看起来像这样
接下来,编辑 XAML 以将 Chart
控件的 DependentValueBinding
和 IndependentValueBinding
属性绑定到一个控制每个柱子的类。DataPointStyle
属性也绑定到一个用于控制柱子外观的样式。XAML 如下
<toolkit:Chart x:Name="GasChart" Style="{StaticResource GasChartStyle}"
BorderBrush="{x:Null}" Margin="4,141,0,60">
<toolkit:ColumnSeries
DependentValueBinding="{Binding GasValue}"
IndependentValueBinding="{Binding GasName}"
DataPointStyle="{StaticResource ColorByGradeColumn}"
AnimationSequence="FirstToLast"/>
</toolkit:Chart>
DataPointStyle
设置为 StaticResource
,它为 ColumnDataPoint
设置了 ControlTemplate
。此时,我们正在改变柱子的外观。这种外观是一个类似光泽的柱子,与默认的难看外观相比。仔细查看下面的 XAML 代码,您会注意到 ControlTemplate
中 Border
的 Background
属性绑定到了一个类的一个属性 (GasColor
)。这使得可以动态更改柱子的颜色
<Style x:Key="ColorByGradeColumn" TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background" Value="DarkGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="{Binding GasColor}"
BorderBrush="{Binding GasColor}"
BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<!--Provides the tooltip for each column -->
<StackPanel>
<ContentControl
Content ="{ TemplateBinding IndependentValue }"/>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content ="ppm"/>
</StackPanel>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<!--This gradiesnt provides
the gloss-like feature for each-->
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="{Binding GasColor}"
Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
现在,属性绑定到 Chart
控件的类是
public class GasNameValue
{
public double GasValue { get; set; }
public string GasName { get; set; }
public Brush GasColor { get; set; }
}
下面的方法在一个 List
中创建上面类的新对象,其中设置了每个柱子的值。创建的对象数量将决定您的 Chart
将包含多少个柱子;大多数情况下,您的数据来自数据库或云,这个过程将是动态的而不是手动的。最后一行代码将 Chart
控件的 ItemsSource
设置为 List
对象。
private void SetData()
{
List<GasNameValue> gasList = new List<GasNameValue>
{
new GasNameValue
{
GasName = "CO2",
GasValue = 850.0,
GasColor = new SolidColorBrush(Colors.Red)
},
new GasNameValue
{
GasName = "SO2",
GasValue = 700.0,
GasColor = new SolidColorBrush(Colors.Blue)
},
new GasNameValue
{
GasName = "CH4",
GasValue = 820.0,
GasColor = new SolidColorBrush(Colors.Green)
},
new GasNameValue
{
GasName = "NO2",
GasValue = 600.0,
GasColor = new SolidColorBrush(Colors.Yellow)
},
new GasName_Value
{
GasName = "F11",
GasValue = 910.o,
GasColor = new SolidColorBrush(Colors.Purple)
},
new GasNameValue
{
GasName = "F12",
GasValue = 760.0,
GasColor = new SolidColorBrush(Colors.Orange)
},
};
((ColumnSeries)GasChart.Series[0]).ItemsSource = gasList;
}
最终的 ColumnSeries
看起来像这样
StackedColumnSeries
默认的 StackedColumnSeries
看起来像这样(在我看来很难看)
现在,在处理 StackedColumnSeries
时,在添加 Chart
控件并相应地编辑 Template
后,您需要为每个Stacked Column 添加 SeriesDefinition
。您添加的 SeriesDefinition
的数量决定了每个 Stacked Column 上您最终拥有的分区数量。下面的 XAML 在每个 Stacked Column 上包含六 (6) 个分区,并且属性绑定到一个类
<toolkit:StackedColumnSeries>
<toolkit:SeriesDefinition
Title="CO2"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue1}"
IndependentValueBinding="{Binding Year}"/>
<toolkit:SeriesDefinition
Title="SO2"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue2}"
IndependentValueBinding="{Binding Year}"/>
<toolkit:SeriesDefinition
Title="NO2"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue3}"
IndependentValueBinding="{Binding Year}"/>
<toolkit:SeriesDefinition
Title="CH4"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue4}"
IndependentValueBinding="{Binding Year}"/>
<toolkit:SeriesDefinition
Title="F11"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue5}"
IndependentValueBinding="{Binding Year}"/>
<toolkit:SeriesDefinition
Title="F12"
ItemsSource="{Binding}"
DependentValueBinding="{Binding GasValue6}"
IndependentValueBinding="{Binding Year}"/>
</toolkit:StackedColumnSeries>
这一次,为了创建每个分区的新颜色,必须将 ResourceDictionaryCollection
添加到图表调色板中;这个 ResourceDictionaryCollection
包含六 (6) 个 ResourceDictionary
。每个 ResourceDictionary
为堆栈上的每个分区提供颜色。XAML 如下
<toolkit:Chart.Palette>
<toolkit:ResourceDictionaryCollection>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Red" BorderBrush="Red" BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Red" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Blue"
BorderBrush="Blue" BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Blue" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Green"
BorderBrush="Green" BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Green" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary><ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Yellow"
BorderBrush="Yellow" BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Yellow" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="Purple"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Purple"
BorderBrush="Purple" BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Purple" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="Control">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ColumnDataPoint">
<Border Background="Orange"
BorderBrush="Orange"
BorderThickness="0.5">
<Grid Background="{x:Null}">
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl
Content ="{ TemplateBinding
FormattedDependentValue }"/>
<ContentControl Content =" ppm"/>
</StackPanel>
</ToolTipService.ToolTip>
<Border BorderBrush="{x:Null}">
<Border.Background>
<LinearGradientBrush EndPoint="1.344,0.5"
StartPoint="-0.344,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Orange" Offset="0.5"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</toolkit:ResourceDictionaryCollection>
</toolkit:Chart.Palette>
请注意,从上面的代码可以看出,Chart
绑定到一个类,但这次颜色是固定的,尽管仍然可以通过数据绑定 ControlTemplate
中的 Background
属性来动态更改颜色。
图表绑定的类是
public class GasName_Value
{
public string Year { get; set; }
public double GasValue1 { get; set; }
public double GasValue2 { get; set; }
public double GasValue3 { get; set; }
public double GasValue4 { get; set; }
public double GasValue5 { get; set; }
public double GasValue6 { get; set; }
}
最终的 StackedColumnSeries
看起来像这样
这些技术也可以应用于其他 StackedColumn Series,如 Stacked100ColumnSeries
、StakedBarSeries
和 Stacked100BarSeries
,只需很少的修改。样式设置愉快!