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;
elseC1Chart.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)