in

C1 Community

ComponentOne Community is a free source for developers and help authors to collaborate and communicate.

Display XValue in Point Label (How To)

Last post 11-28-2008 3:03 AM by louispmarais. 2 replies.
Page 1 of 1 (3 items)
Sort Posts: Previous Next
  • 11-26-2008 2:07 AM

    Display XValue in Point Label (How To)

    Hi I was wondering if anyone could help me in my problem that I am experiencing. I have a chart that updates regularly and I want to display the XValue of the chart aswell as the YVlaue in the Label. Currently I have the YValue and Point Index but please can anyone help me getting the XValue also in there? I have attached my full XAML and C# code for you to have a look at. Please show me how to do it in XAML binding and in code if possible.......

     XAML:

    <UserControl xmlns:my1="clr-namespace:Liquid;assembly=Liquid" xmlns:my="clr-namespace:C1.Silverlight.Chart;assembly=C1.Silverlight.Chart" x:Class="Trending.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Loaded="UserControl_Loaded" Background="Transparent">

    <UserControl.Resources>

    <my:DataPointConverter x:Key="fc" />

    <DataTemplate x:Key="lbl">

    <Border Background="LightBlue" CornerRadius="2" BorderBrush="DarkGray"

    BorderThickness="1">

    <TextBlock FontSize="9" Margin="2" Foreground="DarkBlue"

    Text="{Binding

    Converter={StaticResource fc},

    ConverterParameter='Series:{#SeriesLabel}{#NewLine}Point:{#PointIndex}{#NewLine}Value:{#Value}'}" />

    </Border>

    </DataTemplate>

    <DataTemplate x:Key="legendlbl">

    <Border Background="LightBlue" CornerRadius="2" BorderBrush="DarkGray"

    BorderThickness="1">

    <TextBlock FontSize="9" Margin="2" Foreground="DarkBlue"

    Text="{Binding

    Converter={StaticResource fc},

    //What is the parameter for the XValue and how do I do this in code? 

    ConverterParameter='Series:{#SeriesLabel}{#NewLine}Point:{#PointIndex}{#NewLine}Value:{#Value}'}" />

    </Border>

    </DataTemplate>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Margin="0,0,0,0" Background="Transparent">

    <Grid.RowDefinitions>

    <RowDefinition Height="Auto"/>

    <RowDefinition />

    <RowDefinition Height="16"/>

    <RowDefinition Height="Auto"/>

    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>

    <ColumnDefinition Width="21"/>

    <ColumnDefinition />

    <ColumnDefinition Width="Auto"/>

    </Grid.ColumnDefinitions>

    <ScrollBar x:Name="sbY" Grid.Row="1" Minimum="0" Maximum="1" Orientation="Vertical"

    ValueChanged="ScrollBar_ValueChanged" Margin="5,10,0,0" />

    <my:C1Chart Grid.Row="1" Grid.Column="1" x:Name="C1Chart" ChartType="Line" Palette="Default" Theme="Office2003Blue"

    Foreground="White" BorderThickness="2" Margin="4,10,10,3" >

    <my:C1Chart.Actions>

    <my:ZoomAction Fill="#50ffffff" Stroke="DarkBlue" />

    <my:TranslateAction Modifiers="Shift" />

    <my:ScaleAction Modifiers="Control" />

    </my:C1Chart.Actions>

    </my:C1Chart>

    <ScrollBar x:Name="sbX" Grid.Row="2" Grid.Column="1" Minimum="0" Maximum="1"

    Orientation="Horizontal" ValueChanged="ScrollBar_ValueChanged" Margin="0,0,10,0" />

    <my:C1ChartLegend Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" x:Name="legend" Margin="4,10,0,0" CornerRadius="2" />

    <StackPanel Orientation="Horizontal" Grid.ColumnSpan="3" Grid.Row="0" HorizontalAlignment="Right" Margin="0,10,10,0">

    <RadioButton Foreground="Black" Background="Blue" OpacityMask="Blue" Opacity="70" Margin="4" x:Name="rbX" Content="ZoomX" Checked="rb_Checked" />

    <RadioButton Foreground="Black" Background="Blue" OpacityMask="Blue" Opacity="70" Margin="4" x:Name="rbY" Content="ZoomY" Checked="rb_Checked" />

    <RadioButton Foreground="Black" Background="Blue" OpacityMask="Blue" Opacity="70" Margin="4" x:Name="rbXY" Content="ZoomXY" Checked="rb_Checked" IsChecked="true"/>

    <Button OpacityMask="Blue" Opacity="70" Margin="2" Content="ZoomOut" Click="Button_Click" Foreground="Black"/>

    <Button OpacityMask="Blue" Opacity="70" Margin="2" Content="Refresh" Click="Button_Click_1" Foreground="Black"/>

    <Line OpacityMask="Blue" Opacity="70" Fill="Black" Height="18" Stroke="Black" Stretch="Fill" Margin="5,0,5,0" StrokeThickness="1" Y2="1" ></Line>

    <my1:TextBlockPlus Text="Tag: " Margin="2" UseLayoutRounding="True" Shadow="Slight"></my1:TextBlockPlus>

    <TextBox x:Name="txtTag" Width="120" Height="20" Margin="2" Text="sinusoid"></TextBox>

    <my1:TextBlockPlus Text="Start Time: " Margin="2" UseLayoutRounding="True" Shadow="Slight"></my1:TextBlockPlus>

    <TextBox x:Name="txtStartTime" Width="80" Height="20" Margin="2" Text="*-24h"></TextBox>

    <my1:TextBlockPlus Text="End Time: " Margin="2" UseLayoutRounding="True" Shadow="Slight"></my1:TextBlockPlus>

    <TextBox x:Name="txtEndTime" Width="80" Height="20" Margin="2" Text="*"></TextBox>

    </StackPanel>

    <StackPanel Grid.ColumnSpan="3" Orientation="Vertical" Grid.Row="3" Margin="4" Cursor="Hand">

     

    </StackPanel>

     

    </Grid>

    </UserControl>

    C#

    using System;

    using System.Linq;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Input;

    using System.Windows.Media;

    using C1.Silverlight.Chart;

    using Trending.DataS;

    namespace Trending

    {

    public partial class Page : UserControl

    {

    private bool loaded = false;

    private DataS.DataSClient proxyClient;

    private DataS.DataClass[] data;

    private System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();

    private Boolean IS_STARTED;public Page()

    {

    InitializeComponent();

    IS_STARTED =
    false;

    C1Chart.ActionEnter += new EventHandler(C1Chart_ActionEnter);

    C1Chart.ActionLeave += new EventHandler(C1Chart_ActionLeave);RotateTransform rt = new RotateTransform();

    rt.Angle = 180;

    sbY.RenderTransformOrigin =
    new Point(0.5, 0.5);

    sbY.RenderTransform = rt;

    UpdateScrollbars();

    loaded =
    true;

    }

    void C1Chart_ActionLeave(object sender, EventArgs e)

    {

    C1Chart.Cursor =
    Cursors.Arrow;

    UpdateScrollbars();

    }

    void C1Chart_ActionEnter(object sender, EventArgs e)

    {

    if (sender is ScaleAction)

    C1Chart.Cursor = Cursors.SizeNS;

    else if (sender is TranslateAction)

    C1Chart.Cursor = Cursors.Stylus;

    else

    C1Chart.Cursor = Cursors.Hand;

    UpdateScrollbars();

    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)

    {

    timer.Interval =
    new TimeSpan(0,0,0,30);timer.Tick += new EventHandler(timer_Tick);

    timer.Start();

    proxyClient = new DataSClient();

    proxyClient.StartCompleted += new EventHandler<StartCompletedEventArgs>(proxyClient_StartCompleted);

    proxyClient.GetDataValuesCompleted += new EventHandler<GetDataValuesCompletedEventArgs>(proxyClient_GetDataValuesCompleted);

    proxyClient.MySettingsCompleted += new EventHandler<MySettingsCompletedEventArgs>(proxyClient_MySettingsCompleted);

    proxyClient.StartAsync(txtTag.Text, txtStartTime.Text, txtEndTime.Text);

    }

    void proxyClient_MySettingsCompleted(object sender, MySettingsCompletedEventArgs e)

    {

    createChart(data, e.Result.TAGNAME, e.Result.STARTTIME, e.Result.ENDTIME);

    }

    void timer_Tick(object sender, EventArgs e)

    {

    if (IS_STARTED)

    {

    proxyClient.GetDataValuesAsync();

    }

    }

    void proxyClient_GetDataValuesCompleted(object sender, GetDataValuesCompletedEventArgs e)

    {

    data = e.Result;

    proxyClient.MySettingsAsync();

    }

    private void createChart(DataClass[] result, String Tagname, String Starttime, String Endtime)

    {

    txtStartTime.Text = Starttime;

    txtTag.Text = Tagname;

    txtEndTime.Text = Endtime;

    C1Chart.BeginUpdate();

    C1Chart.Data.Children.Clear();

    legend.Chart = C1Chart;

    XYDataSeries series = new XYDataSeries();

    int i = 0;

    Double[] values = new double[result.Count()];

    DateTime[] dates = new DateTime[result.Count()];

    foreach (DataS.DataClass val in result)

    {

    try

    {

    values[i] =
    Double.Parse(val.VALUE);dates[i] = DateTime.Parse(val.TIME_STAMP);

    i++;

    }

    catch {

    values[i] = Double.NaN;

    dates[i] = DateTime.Parse(val.TIME_STAMP);

    }

    }

    series.SymbolMarker =
    Marker.Dot;series.SymbolSize = new Size(7,7);

    series.XValuesSource = dates;

    series.ValuesSource = values;

    series.SymbolMarker = C1.Silverlight.Chart.
    Marker.Box;

    series.Label = Tagname;

    //How do I access the point directly so I can do this?

    DataTemplate tt = null;tt = (DataTemplate)Resources["lbl"];

    series.PointTooltipTemplate = tt;

    C1Chart.Data.Children.Add(series);

    TextBlock ty = new TextBlock();ty.Text = "Value";

    C1Chart.View.AxisY.Title = ty;

    C1Chart.View.AxisX.AnnoFormat =
    "hh:mm";

    C1Chart.View.AxisX.ItemsSource = dates;

    C1Chart.View.AxisX.IsTime = true;

    C1Chart.View.AxisX.AnnoPosition = AnnoPosition.Near;

    C1Chart.EndUpdate();

    }

    void proxyClient_StartCompleted(object sender, StartCompletedEventArgs e)

    {

    if (e.Result)

    {

    proxyClient.GetDataValuesAsync();

    }

    IS_STARTED = e.Result;

    }

    private void C1Chart_MouseLeave(object sender, MouseEventArgs e)

    {

    }

    private void Button_Click(object sender, RoutedEventArgs e)

    {

    C1Chart.BeginUpdate();

    C1Chart.View.AxisX.Scale = 1;

    C1Chart.View.AxisX.Value = 0.5;

    C1Chart.View.AxisY.Scale = 1;

    C1Chart.View.AxisY.Value = 0.5;

    UpdateScrollbars();

    C1Chart.EndUpdate();

    }

    private void rb_Checked(object sender, RoutedEventArgs e)

    {

    if (C1Chart == null)return;

    C1Chart.BeginUpdate();

    if (sender == rbX)

    {

    C1Chart.View.AxisY.MinScale = 1;

    C1Chart.View.AxisY.Scale = 1;

    C1Chart.View.AxisY.Value = 0.5;

    C1Chart.View.AxisX.MinScale = 0.001;

    }

    else if (sender == rbY)

    {

    C1Chart.View.AxisX.MinScale = 1;

    C1Chart.View.AxisX.Scale = 1;

    C1Chart.View.AxisX.Value = 0.5;

    C1Chart.View.AxisY.MinScale = 0.001;

    }

    else

    {

    C1Chart.View.AxisX.MinScale = 0.001;

    C1Chart.View.AxisY.MinScale = 0.001;

    }

    UpdateScrollbars();

    C1Chart.EndUpdate();

    }

    private void ScrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)

    {

    if (loaded)

    {

    if (sender == sbY)

    C1Chart.View.AxisY.Value = sbY.Value;

    else if (sender == sbX)

    C1Chart.View.AxisX.Value = sbX.Value;

    }

    }

    private void UpdateScrollbars()

    {

    sbX.Value = C1Chart.View.AxisX.Value;

    double sx = C1Chart.View.AxisX.Scale;if (sx >= 1)

    {

    sbX.ViewportSize = 10000;

    sbX.Visibility =
    Visibility.Collapsed;

    }

    else

    {

    sbX.ViewportSize = 1.0 / (1.0 - sx) - 1.0;

    sbX.Visibility =
    Visibility.Visible;

    }

    sbX.LargeChange = sbX.ViewportSize;

    sbX.SmallChange = 0.25 * sbX.ViewportSize;

    sbY.Value = C1Chart.View.AxisY.Value;

    double sy = C1Chart.View.AxisY.Scale;if (sy >= 1)

    {

    sbY.ViewportSize = 10000;

    sbY.Visibility =
    Visibility.Collapsed;

    }

    else

    {

    sbY.ViewportSize = 1.0 / (1.0 - sy) - 1.0;

    sbY.Visibility =
    Visibility.Visible;

    }

    sbY.LargeChange = sbY.ViewportSize;

    sbY.SmallChange = 0.25 * sbY.ViewportSize;

    }

    private void Button_Click_1(object sender, RoutedEventArgs e)

    {

    proxyClient.ResetSettingsAsync(txtTag.Text, txtStartTime.Text, txtEndTime.Text);

    }

    }

    }

    I know this is a long post but please, any assistance would be dearly appreciated.

    Thank you in advance.

     Louis Marais (Applications Developer)

     

  • 11-26-2008 10:36 AM In reply to

    Re: Display XValue in Point Label (How To)

    Louis,

    In XAML you can use #XValues and DataPointConverter.

    <c1chart:DataPointConverter x:Key="cnv" />
    ...
    <TextBlock Text="{Binding Converter={StaticResource cnv}, ConverterParameter='X={#XValues}'}" />
    ...

    In code the same can be done with indexer of DataPoint class. e.g. when creating own converter for label template

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      DataPoint dp = value as DataPoint;
      double x = (double)dp["XValues"];
    ...

    Perhaps plural is a bit odd here but it's generated automatically from the XYDataSeries.XValues property which is the source of this value.

    --
    Best regards,
    Alex

  • 11-28-2008 3:03 AM In reply to

    Re: Display XValue in Point Label (How To)

    Thank you very much Alex.

     I have got it working now in code and in XAML binding. Didn't know why I haven't though about it.

    Louis Marais

Page 1 of 1 (3 items)
Contact ComponentOne: 1.800.858.2739 ©1987-2009 ComponentOne LLC All Rights Reserved.