如何用 WinRTXamlToolkit.Controls.DataVisualization 在值 X 处画一条直线?

How to draw a straight line at Value X with WinRTXamlToolkit.Controls.DataVisualization?

我已经通过以下代码创建了一个条形图,但是我想在某个 X 值处添加红线,如下图所示。这可能吗?如果是这样,我怎样才能做到这一点?

<charting:Chart x:Name="BarChart" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Visible" Width="280" Height="500" Margin="-5,-35,0,20" FontSize="10">
                <charting:Chart.LegendStyle>
                    <Style TargetType="datavis:Legend">
                        <Setter Property="Width" Value="0"/>
                    </Style>
                </charting:Chart.LegendStyle>
                <charting:BarSeries Visibility="Visible"/>
                <charting:Chart.Palette>
                    <charting:ResourceDictionaryCollection>
                        <ResourceDictionary>
                            <SolidColorBrush x:Key="Background" Color="#2574a9" />
                            <Style x:Key="DataPointStyle" TargetType="Control">
                                <Setter Property="Background" Value="{StaticResource Background}" />
                            </Style>
                            <Style x:Key="DataShapeStyle" TargetType="Shape">
                                <Setter Property="Stroke" Value="{StaticResource Background}" />
                                <Setter Property="StrokeThickness" Value="2" />
                                <Setter Property="StrokeMiterLimit" Value="1" />
                                <Setter Property="Fill" Value="{StaticResource Background}" />
                            </Style>
                        </ResourceDictionary>
                    </charting:ResourceDictionaryCollection>
                </charting:Chart.Palette>
            </charting:Chart>

我写了一个demo根据特殊的X值加一行。该功能是通过计算特殊X值的位置,并添加Line元素来实现的。它有效,您可以测试。 XAML代码

<Grid x:Name="rootgrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <charting:Chart
        x:Name="BarChart"
        Title="Bar Chart"
        Width="800"
        Height="400">
        <charting:BarSeries
            x:Name="bar"
            Title="Population"
            DependentValueBinding="{Binding Value}"
            IndependentValueBinding="{Binding Name}"
            IsSelectionEnabled="True" />
    </charting:Chart>
    <StackPanel x:Name="InsertLine" >
        <TextBox x:Name="txtnumber" Header="The location for insert a new line" />
        <Button
            x:Name="getaxi"
            Click="getaxi_Click"
            Content="Insert the new line" />
    </StackPanel>
</Grid>

代码隐藏

public sealed partial class BarChat : Page
{
    private Random _random = new Random();
    private LinearAxis linearaxis;
    private CategoryAxis categoryaxis;
    private double linearaximaximum;
    private double linearaximinimum;
    private Line newline;
    public BarChat()
    {
        this.InitializeComponent();
        Window.Current.SizeChanged += Current_SizeChanged; ;
        var items1 = new List<NameValueItem>();
        for (int i = 0; i < 3; i++)
        {
            items1.Add(new NameValueItem { Name = "Name" + i, Value = _random.Next(1, 100) });
        }
        this.RunIfSelected(this.BarChart, () => ((BarSeries)this.BarChart.Series[0]).ItemsSource = items1);

    }

    private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
    {
        if (rootgrid.Children.Contains(newline))
        {
            clearline();
            if (txtnumber.Text != null)
            {
                var insertvalue = Convert.ToDouble(txtnumber.Text);
                positionline(insertvalue);
            }
        }
    }

    public void barchartinihital()
    {
        var Actualaxes = BarChart.ActualAxes;
        linearaxis = Actualaxes[1] as LinearAxis;
        categoryaxis = Actualaxes[0] as CategoryAxis;
        linearaximaximum = Convert.ToDouble(linearaxis.ActualMaximum);
        linearaximinimum = Convert.ToDouble(linearaxis.ActualMinimum);
    }


    private void RunIfSelected(UIElement element, Action action)
    {
        action.Invoke();
    }

    private async void getaxi_Click(object sender, RoutedEventArgs e)
    {
        clearline();
        barchartinihital();          
        if (txtnumber.Text != null)
        {                
             double insertvalue = Convert.ToDouble(txtnumber.Text);  
            if (insertvalue > linearaximaximum || insertvalue < linearaximinimum)
            {
                await new Windows.UI.Popups.MessageDialog("Please input a value in chart arrange").ShowAsync();
            }
            else
            {
                positionline(insertvalue);
            }
        }
    }
    public void positionline(double insertvalue)
    {

        var interval = linearaxis.ActualInterval;
        double perinterval = Convert.ToDouble(linearaxis.ActualWidth / (linearaximaximum - linearaximinimum));

        var lineX = perinterval * (insertvalue - linearaximinimum);
        var lineheight = categoryaxis.ActualHeight;

        var ttv = bar.TransformToVisual(Window.Current.Content);
        Point screenCoords = ttv.TransformPoint(new Point(0, 0));

        var chartx = screenCoords.X;
        var charty = screenCoords.Y;

        newline = new Line();
        newline.X1 = Convert.ToDouble(lineX) + chartx;
        newline.X2 = Convert.ToDouble(lineX) + chartx;
        newline.Y1 = charty;
        newline.Y2 = charty + lineheight;
        newline.Stroke = new SolidColorBrush(Colors.Red);
        newline.StrokeThickness = 2;
        rootgrid.Children.Add(newline);

    }
    public void clearline()
    {
        if (rootgrid.Children.Contains(newline))
        {
            {
                rootgrid.Children.Remove(newline);
            }

        }
    }

}