如何使用 Silverlight 工具包创建股票图表






4.70/5 (14投票s)
一篇关于如何使用Silverlight Toolkit创建蜡烛图的文章。
引言
Silverlight Toolkit是一组Silverlight控件、组件和实用程序,在正常的Silverlight发布周期之外提供。它为设计人员和开发人员快速添加新功能,并通过为社区提供贡献想法和错误报告的有效方式来帮助塑造产品开发。它包括12个新控件的完整源代码、单元测试、示例和文档,涵盖图表、样式、布局和用户输入。
Silverlight Toolkit 为我们提供了Silverlight一个非常强大的图表控件!使用此工具包仍然相对难以创建的一种图表类型是股票图表(OHLC 或 蜡烛图)。
它结合了折线图和柱状图,其中每个柱代表给定时间间隔内的价格变动范围。它最常用于股票和货币价格模式的技术分析。它们表面上类似于误差线,但两者无关。
幸运的是,Silverlight Toolkit也具有很强的可定制性。本文将展示一种扩展 Silverlight Toolkit的方法,以允许创建股票图表。
基础知识
每个图表可以包含多个系列。Silverlight Toolkit有一些常见的系列
柱状图系列 (BarSeries)
气泡图系列 (BubbleSeries)
柱状图系列 (ColumnSeries)
折线图系列 (LineSeries)
饼图系列 (PieSeries)
散点图系列 (ScatterSeries)
我们将通过从 DataPointSingleSeriesWithAxes
派生来创建我们自己的 CandlestickSeries
public sealed partial class CandlestickSeries : DataPointSingleSeriesWithAxes
{
// ...
}
DataPointSingleSeriesWithAxes
是一个带有轴的动态系列,并且所有数据点只有一个图例项和样式。
每个系列包含多个数据点
public sealed partial classCandlestickDataPoint : DataPoint
{
// ...
}
DataPoint
代表一个显示数据点的控件。
现在我们有了基础知识(一个图表有一个系列,每个系列都有数据点),让我们深入研究一下它是如何工作的…
CandlestickDataPoint
CandlestickDataPoint
将负责呈现蜡烛图。每个蜡烛图都有一个阴影和一个实体。这是 CandlestickDataPoint
的默认控件模板
<ControlTemplate TargetType="charting:CandlestickDataPoint">
<Border x:Name="Root" Opacity="0"
BorderBrush="{x:Null}" BorderThickness="0"
RenderTransformOrigin="0.5,0.5">
<!-- Removed the VSM stuff for brevity -->
<Grid>
<Grid x:Name="PART_Shadow">
<Rectangle Fill="Black" Width="1" />
</Grid>
<Grid x:Name="PART_Body"
Background="{TemplateBinding Background}"
Margin="0,5,0,5">
<Rectangle Fill="{TemplateBinding Background}" />
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#64686868" />
<GradientStop Color="#FF4D4C4C" Offset="0.996" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle RenderTransformOrigin="0.5,0.5"
Margin="19,19,17,17" Opacity="0.245">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF919191" />
<GradientStop Color="#FFFFFFFF" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform X="0.5" Y="0.5" />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="MouseOverHighlight" Opacity="0"
Fill="#FF9B1C1C" Stroke="#FF000000" />
<Rectangle x:Name="SelectionHighlight"
Opacity="0" Fill="#3EF0F0F0" />
</Grid>
</Grid>
</Border>
</ControlTemplate>
每个 CandlestickDataPoint
也有以下 DPs(这些是计算实体大小所必需的)
打开
Close
高
低功耗
关于 CandlestickDataPoint
唯一“棘手”的事情是它如何调整实体的尺寸。CandlestickDataPoint
有一个名为 UpdateBody()
的方法,它将调整实体的大小。
CandlestickSeries
为了使 CandlestickSeries
“工作”,我们需要重写 CreateDataPoint
、PrepareDataPoint
和 UpdateDataPoint
。
protected override DataPoint CreateDataPoint()
{
return new CandlestickDataPoint();
}
CreateDataPoint
通过为系列主机创建一个相应的数据点来添加一个对象。
protected override void PrepareDataPoint(DataPoint dataPoint, object dataContext)
{
base.PrepareDataPoint(dataPoint, dataContext);
CandlestickDataPoint candlestickDataPoint = (CandlestickDataPoint)dataPoint;
candlestickDataPoint.SetBinding(CandlestickDataPoint.OpenProperty, OpenValueBinding);
candlestickDataPoint.SetBinding(CandlestickDataPoint.CloseProperty, CloseValueBinding);
candlestickDataPoint.SetBinding(CandlestickDataPoint.HighProperty, HighValueBinding);
candlestickDataPoint.SetBinding(CandlestickDataPoint.LowProperty, LowValueBinding);
}
PrepareDataPoint
通过提取数据点并将其绑定到数据上下文对象来准备数据点。
protected override void UpdateDataPoint(DataPoint dataPoint)
{
CandlestickDataPoint candlestickDataPoint = (CandlestickDataPoint)dataPoint;
double PlotAreaHeight =
ActualDependentRangeAxis.GetPlotAreaCoordinate(
ActualDependentRangeAxis.Range.Maximum);
double dataPointX =
ActualIndependentRangeAxis.GetPlotAreaCoordinate(
ValueHelper.ToComparable(dataPoint.ActualIndependentValue));
double highPointY =
ActualDependentRangeAxis.GetPlotAreaCoordinate(
ValueHelper.ToDouble(candlestickDataPoint.High));
double lowPointY =
ActualDependentRangeAxis.GetPlotAreaCoordinate(
ValueHelper.ToDouble(candlestickDataPoint.Low));
double openPointY =
ActualDependentRangeAxis.GetPlotAreaCoordinate(
ValueHelper.ToDouble(candlestickDataPoint.Open));
double closePointY =
ActualDependentRangeAxis.GetPlotAreaCoordinate(
ValueHelper.ToDouble(candlestickDataPoint.Close));
candlestickDataPoint.UpdateBody(ActualDependentRangeAxis);
if (ValueHelper.CanGraph(dataPointX))
{
dataPoint.Height = Math.Abs(highPointY - lowPointY);
dataPoint.Width = 5.0;
if (dataPoint.ActualWidth == 0.0 || dataPoint.ActualHeight == 0.0)
dataPoint.UpdateLayout();
Canvas.SetLeft(dataPoint,
Math.Round(dataPointX - (dataPoint.ActualWidth / 2)));
Canvas.SetTop(dataPoint,
Math.Round(PlotAreaHeight - highPointY));
}
}
UpdateDataPoint
更新绘图区域中单个数据点的视觉表示。
就这样…
<charting:Chart Title="Typical Use">
<charting:Chart.Series>
<charting:CandlestickSeries
Title="MSFT"
ItemsSource="{Binding Microsoft, Source={StaticResource FinancialData}}"
IndependentValueBinding="{Binding Date}"
DependentValueBinding="{Binding High}"
OpenValueBinding="{Binding Open}"
CloseValueBinding="{Binding Close}"
LowValueBinding="{Binding Low}"
HighValueBinding="{Binding High}"/>
</charting:Chart.Series>
</charting:Chart>
请访问 我的博客 以获取更多信息...