我一直在使用this示例绘制条形图。条形部分已完成,它代表交易中的数量/数量。它是一个介于20到30之间的关联价格。我现在想要绘制点以表示与数量相关的价格并将这些点连接起来。我在链接示例的EDIT部分中进行了两项更改(1)从TextBlock
的DataTemplate
中删除了ItemsControl
并添加了Ellipse
,并且(2)编辑画布以添加价格/体积轴标签。这是现在的样子:
如何在适当的位置添加Ellipse
并将其与Line
/ PolyLine
连接?
[xaml
中有此:
<Ellipse Width="5" Height="5" Fill="Red" VerticalAlignment="Bottom">
<Ellipse.RenderTransform>
<TranslateTransform Y="{Binding Price, Converter={StaticResource PConverter}}"/>
</Ellipse.RenderTransform>
</Ellipse>
以及IValueConverter
中的此:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var price = (double)value ;
var remainingHeight = 90;
var priceRange = 30 - 20.0;
return -45 - ((price - 20) * remainingHeight / priceRange);
}
我已经解决了定位部分。现在有了这些,看起来像这样:
我错过了恰好是30分的一些点(可能是由于四舍五入的滴答声),我想我可以自己解决这个问题。现在,我只需要连接Line
/ PolyLine
。怎么做?
以下示例使用垂直翻转的Canvas反转y轴顺序,使其向上移动。因此PConverter
应该返回正y值。
除了Rectangle和Ellipse元素外,它还通过值绑定中的Line
从先前的数据值到当前的数据值绘制了一个RelativeSource={RelativeSource PreviousData}
元素。它还在AlternationIndex
上使用DataTrigger隐藏第一行。
<ItemsControl ... AlternationCount="2147483647">
...
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas Width="20">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
<Rectangle Fill="LightGray" Margin="1" Width="18"
Height="{Binding Value1, Converter={StaticResource PConverter}}"/>
<Line Stroke="DarkGreen" StrokeThickness="3"
X1="-10" X2="10"
Y1="{Binding Price,
Converter={StaticResource PConverter},
RelativeSource={RelativeSource PreviousData}}"
Y2="{Binding Price,
Converter={StaticResource PConverter}}">
<Line.Style>
<Style TargetType="Line">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource
AncestorType=ContentPresenter}}"
Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Line.Style>
</Line>
<Ellipse Fill="Red" Width="6" Height="6" Margin="-3" Canvas.Left="10"
Canvas.Top="{Binding Price, Converter={StaticResource PConverter}}"/>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
由于现在还要求值转换器输入不存在的值(对于第一项的PreviousData
,因此必须确保它检查传递的值是否实际上是双精度值:
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is double)) return 0d;
...
}