Search code examples
c#uwpwinrt-xamluwp-xamlwinrt-xaml-toolkit

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


I've created a bar chart via the below code however I'd like to add the red line at some X value as seen in the image below. Is this possible? And if so, how could I accomplish this?

<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>

enter image description here


Solution

  • I wrote a demo to add a line according to the special X value. This feature is implemented by calculating the position of the special X value, and add the Line element. It works and you can test. XAML Code

    <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>
    

    Code behind

    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);
                }
    
            }
        }
    
    }