Hi Telerik,
I'm currently trying to achieve functionality similar to the trackball behavior, but I actually need to display a horizontal line, that crosses the given ScatterLineSeries and starts at the corresponding vertical axis. I have to draw a slider on that axis, so I will be able to move this line by moving the slider along the axis (I've attached an image to explain what I mean).
The problem is I can't determine the position of the vertical axis during runtime to place the slider on the correct location.
I can draw the horizontal line and intersection points using another ScatterLineSeries (as was done to create an attached image), but the series cannot be drawn outside the ChartArea, so I have to extend the line to an axis programmatically.
So, is it possible to get the Y-axis coordinates inside the ChartView, or is there another way to implement the described scenario?
Thanks in advance.

public class AppointmentExt : Appointment{ public planning_slot Slot { get; set; } public string SpecialTooltip { get; set; }}ObservableCollection<AppointmentExt> appointments = new ObservableCollection<AppointmentExt>();<DataTemplate x:Key="ScheduleTooltip"> <StackPanel Orientation="Horizontal"> <TextBlock MaxWidth="200" TextWrapping="Wrap" Text="{Binding SpecialTooltip}"/> </StackPanel></DataTemplate>CustomItems="{Binding Markers}"
CustomItemTemplate="{StaticResource CustomItemTemplate}"
but we cannot make it work.<telerik:RadHorizontalLinearGauge Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" x:Name="TimeGauge" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Margin="0" OuterBackground="#00000000" OuterBorderThickness="0" Background="#00000000" BorderBrush="#00000000"> <telerik:LinearScale x:Name="TimeScale" Min="{Binding Min}" Max="{Binding Max}" IsInteractive="True" RelativeX="0.04" RelativeWidth="0.92" RelativeY="0.6" FontSize="10" Fill="#4D0000F9" CustomItems="{Binding Markers}" CustomItemTemplate="{StaticResource CustomItemTemplate}"> <telerik:LinearScale.Indicators> <telerik:BarIndicator x:Name="TrackBar" Value="{Binding CurrentFrameNumber, Mode=TwoWay}" IsAnimated="False" Background="#FF00C500" /> <telerik:Marker x:Name="CurrentFrameMarker" Value="{Binding CurrentFrameNumber, Mode=TwoWay}" telerik:ScaleObject.Offset="0.10" telerik:LinearScale.RotateForVertical="True" telerik:ScaleObject.RelativeWidth="0.04" telerik:ScaleObject.RelativeHeight="0.30" telerik:ScaleObject.Location="Outside"> <telerik:Marker.Template> <ControlTemplate TargetType="{x:Type telerik:Marker}"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Polygon Points="0,0 0,0.7 0.5,1 1,0.7 1,0" Stretch="Fill" Fill="Yellow" Stroke="Green" StrokeThickness="2" /> </Grid> </ControlTemplate> </telerik:Marker.Template> </telerik:Marker> </telerik:LinearScale.Indicators> </telerik:LinearScale> </telerik:RadHorizontalLinearGauge>
public class Task { public Task() { this.TotalHoursByResource = new List<ResourceHour>(); } public int ID {get;set;} public string Name { get; set; } public decimal TotalHours { get; set; } public List<ResourceHour> TotalHoursByResource { get; set; }}public class ResourceHour { public string Resource { get; set; } public string WorkingHourType { get; set; } public double Hours { get; set; } }public class HoursAggregate : EnumerableSelectorAggregateFunction { protected override string AggregateMethodName { get { return "GetAggregateHours"; } } protected override Type ExtensionMethodsType { get { return typeof(HoursAggregateType); } }}public static class HoursAggregateType { public static string GetAggregateHours<T>(IEnumerable<Task> source, Func<Task, List<ResourceHour>> selector) where T : Task { return "Some string from TotalHoursByResource"; }}<UserControl x:Class="CarSystem.CustomControls.TimeSpanSpinner" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:cs="clr-namespace:CarSystem.CustomControls" mc:Ignorable="d" Focusable="True" Loaded="UserControl_Loaded"> <UserControl.Resources> <cs:TimeSpanToDateTimeConverter x:Key="TimeSpanConverter" /> </UserControl.Resources> <Grid Background="{Binding Path=GridBackground, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Width="{Binding Path=Width, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <telerik:RadMaskedDateTimeInput BorderBrush="{Binding Path=BorderBrush, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FlowDirection="{Binding Path=FlowDirection, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Focusable="True" FontFamily="{Binding Path=FontFamily, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontSize="{Binding Path=FontSize, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontStretch="{Binding Path=FontStretch, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontStyle="{Binding Path=FontStyle, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontWeight="{Binding Path=FontWeight, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" GotFocus="ValueBox_GotFocus" Grid.Column="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Right" InputBehavior="Insert" IsClearButtonVisible="False" LostFocus="ValueBox_LostFocus" Margin="5" Mask="{Binding Path=Mask, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Name="ValueBox" SelectionOnFocus="CaretToEnd" SpinMode="PositionAndValue" TabIndex="{Binding Path=TabIndex, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" TextMode="MaskedText" UpdateValueEvent="PropertyChanged" Value="{Binding Path=Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}, Converter={StaticResource TimeSpanConverter}}" VerticalAlignment="Center" /> <RepeatButton Background="{DynamicResource ButtonBackground}" Click="IncrementButton_Click" Focusable="False" Foreground="{DynamicResource ButtonForeground}" Grid.Column="1" IsTabStop="False" Name="IncrementButton"> <Image> <Image.Style> <Style TargetType="{x:Type Image}"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpDay.png" /> <Style.Triggers> <DataTrigger Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpNight.png" /> </DataTrigger> </Style.Triggers> </Style> </Image.Style> </Image> </RepeatButton> <RepeatButton Background="{DynamicResource ButtonBackground}" Click="DecrementButton_Click" Focusable="False" Foreground="{DynamicResource ButtonForeground}" Grid.Column="2" IsTabStop="False" Name="DecrementButton"> <Image> <Image.Style> <Style TargetType="{x:Type Image}"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnDay.png" /> <Style.Triggers> <DataTrigger Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnNight.png" /> </DataTrigger> </Style.Triggers> </Style> </Image.Style> </Image> </RepeatButton> </Grid> </UserControl> public partial class TimeSpanSpinner : UserControl { public static readonly DependencyProperty FocusedBackgroundProperty = DependencyProperty.Register( "FocusedBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty FocusedForegroundProperty = DependencyProperty.Register( "FocusedForeground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static DependencyProperty GridBackgroundProperty = DependencyProperty.Register( "GridBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( Brushes.Transparent ) ); public static readonly DependencyProperty MaskProperty = DependencyProperty.Register( "Mask", typeof( string ), typeof( TimeSpanSpinner ), new PropertyMetadata( "HH:mm:ss.fff" ) ); public static readonly DependencyProperty TimeOfDayModeProperty = DependencyProperty.Register( "TimeOfDayMode", typeof( TimesOfDay ), typeof( TimeSpanSpinner ), new FrameworkPropertyMetadata( TimesOfDay.DayTime, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback( OnTimeOfDayInvalidated ) ) ); public static readonly DependencyProperty UnfocusedBackgroundProperty = DependencyProperty.Register( "UnfocusedBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty UnfocusedForegroundProperty = DependencyProperty.Register( "UnfocusedForeground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( TimeSpan ), typeof( TimeSpanSpinner ), new PropertyMetadata( TimeSpan.Zero ) ); public Brush FocusedBackground { get { return (Brush) GetValue( FocusedBackgroundProperty ); } set { SetValue( FocusedBackgroundProperty, value ); } } public Brush FocusedForeground { get { return (Brush) GetValue( FocusedForegroundProperty ); } set { SetValue( FocusedForegroundProperty, value ); } } public Brush GridBackground { get { return (Brush) GetValue( GridBackgroundProperty ); } set { SetValue( GridBackgroundProperty, value ); } } public string Mask { get { return (string) GetValue( MaskProperty ); } set { SetValue( MaskProperty, value ); } } public TimesOfDay TimeOfDayMode { get { return (TimesOfDay) GetValue( TimeOfDayModeProperty ); } set { SetValue( TimeOfDayModeProperty, value ); } } public Brush UnfocusedBackground { get { return (Brush) GetValue( UnfocusedBackgroundProperty ); } set { SetValue( UnfocusedBackgroundProperty, value ); } } public Brush UnfocusedForeground { get { return (Brush) GetValue( UnfocusedForegroundProperty ); } set { SetValue( UnfocusedForegroundProperty, value ); } } public TimeSpan Value { get { return (TimeSpan) GetValue( ValueProperty ); } set { SetValue( ValueProperty, value ); } } public TimeSpanSpinner() { InitializeComponent(); } private void DecrementButton_Click( object sender, RoutedEventArgs e ) { // Decrement the Value in the ValueBox ValueBox.CallSpin( false ); } private void IncrementButton_Click( object sender, RoutedEventArgs e ) { ValueBox.CallSpin( true ); } private void OnTimeOfDayModeChanged( TimesOfDay newTimeofDayMode ) { if ( FocusedBackground != null && UnfocusedBackground != null ) { ValueBox.Background = ValueBox.IsFocused ? FocusedBackground : UnfocusedBackground; } if ( FocusedForeground != null && UnfocusedForeground != null ) { ValueBox.Foreground = ValueBox.IsFocused ? FocusedForeground : UnfocusedForeground; } } private static void OnTimeOfDayInvalidated( DependencyObject d, DependencyPropertyChangedEventArgs e ) { TimeSpanSpinner spinner = (TimeSpanSpinner) d; spinner.OnTimeOfDayModeChanged( (TimesOfDay) e.NewValue ); } private void UserControl_Loaded( object sender, RoutedEventArgs e ) { if ( FocusedBackground == null && UnfocusedBackground == null ) { ValueBox.Background = Background; } if ( FocusedForeground == null && UnfocusedForeground == null ) { ValueBox.Foreground = Foreground; } } private void ValueBox_GotFocus( object sender, RoutedEventArgs e ) { if ( FocusedBackground != null ) { ValueBox.Background = FocusedBackground; } if ( FocusedForeground != null ) { ValueBox.Foreground = FocusedForeground; } } private void ValueBox_LostFocus( object sender, RoutedEventArgs e ) { if ( UnfocusedBackground != null ) { ValueBox.Background = UnfocusedBackground; } if ( UnfocusedForeground != null ) { ValueBox.Foreground = UnfocusedForeground; } } } }