hi ,
i am newer to xamdatachart so i want sample code for developing for crosshair for interpolated data in xamdatachart ,
if anybodies having idea about xamdatachart plz give me some sample
whether crosshair is possible to do in xamdatachart if possible means give me some example ,if not means how can i achieve crosshair
in chart ,plz anybodies give me reply it's very urgent for me
thanks in advance
Hi, do you just mean turning on the crosshairs? Or do you mean displaying the axis values at the exact point of the crosshair?
Turning on the crosshairs is done through the CrosshairVisibility property on the XamDataChart.
If you want access to the closest item to the crosshair then you should look at the SeriesCursorMouseMove event on the chart.
If you want to get the exact axis values at each move of the crosshair, then you should look at these samples: http://community.infragistics.com/forums/p/41666/237218.aspx#237218
The chart does not natively expose that information to you yet.
Hope this helps!
-Graham
hi Graham ,
i don't want display the axis values at the exact point of the crosshair but i need all the values of axis where ever touches the crosshair in chart
plz help me it's very urgent
Madhusudan
I've made some adjustments to get the floating tooltip working for your sample. Is this what you are trying for or something else?
<UserControl.Resources> <LinearGradientBrush x:Key="rscGradientBackground" StartPoint="0.0, 0.0" EndPoint="1.0, 1.0"> <GradientStop Color="#FFFFFFFF" Offset="0" /> <GradientStop Color="#c0c2c8" Offset="0.4" /> <GradientStop Color="#e0e2e8" Offset="1" /> </LinearGradientBrush> <Style x:Key="rscXamDataChartStyle" TargetType="igChart:XamDataChart"> <Setter Property="PlotAreaBackground" Value="Transparent" /> </Style> <!--<Style x:Key="LegendStyle" TargetType="{x:Type igChart:Legend}"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="White" Offset="0" /> <GradientStop Color="White" Offset="0.5" /> <GradientStop Color="White" Offset="0.5" /> <GradientStop Color="#FFE8E8EF" Offset="1" /> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" Value="{StaticResource rscGradientBorder}"/> <Setter Property="BorderThickness" Value="0.75" /> <Setter Property="Orientation" Value="Vertical" /> <Setter Property="Padding" Value="4" /> <Setter Property="Margin" Value="2" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igChart:Legend}"> <Grid Margin="{TemplateBinding Margin}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="3" Background="Transparent" CornerRadius="4"> <Grid Margin="{TemplateBinding Padding}"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ContentPresenter Content="{TemplateBinding Content}" Margin="0" Grid.Row="1" /> <ScrollViewer BorderThickness="0" HorizontalScrollBarVisibility="Auto" Grid.Row="2" VerticalScrollBarVisibility="Auto" Margin="3,0,0,0"> <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Grid.Row="1" /> </ScrollViewer> </Grid> </Border> <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" IsHitTestVisible="False"> <Border.Background> <LinearGradientBrush EndPoint="0,1" Opacity="0" StartPoint="0,0"> <GradientStop Color="Transparent" Offset="0" /> <GradientStop Color="#10FFFFFF" Offset="0.499" /> <GradientStop Color="Transparent" Offset="0.501" /> </LinearGradientBrush> </Border.Background> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>--> <LinearGradientBrush x:Key="rscGradientBorder" StartPoint="0.0, 0.0" EndPoint="0.0, 1.0"> <GradientStop Color="#FFFFFFFF" Offset="0" /> <GradientStop Color="#c0c2c8" Offset="0.75" /> <GradientStop Color="#e0e2e8" Offset="1" /> </LinearGradientBrush> </UserControl.Resources> <Border CornerRadius="5" Margin="5" Background="{StaticResource rscGradientBackground}"> <igChart:XamDataChart Grid.Row="1" Name="wpfWebDataChart1" Style="{StaticResource rscXamDataChartStyle}" Legend="{Binding ElementName=Legend}" CrosshairVisibility="Visible" > <!--<igChart:Legend igCtrl:XamDock.Edge="OutsideRight" x:Name="Legend" Style="{DynamicResource LegendStyle}" igCtrl:XamDock.VerticalAlignment="Center" Content="Prices" />--> <local:ChartBehaviors.CursorTooltip> <local:CursorTooltipBehavior TooltipTemplate="{StaticResource tooltipTemplate}" /> </local:ChartBehaviors.CursorTooltip> <igChart:XamDataChart.Axes> <igChart:CategoryXAxis x:Name="XAxis" VerticalAlignment="Top" ItemsSource="{Binding}" /> <igChart:NumericYAxis x:Name="YAxis" /> </igChart:XamDataChart.Axes> <igChart:XamDataChart.Series> <igChart:LineSeries Title="High" Legend="{Binding ElementName=Legend}" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" MarkerType="None" ItemsSource="{Binding}" ValueMemberPath="Column2" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column2:C}" /> <igChart:LineSeries Title="Low" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" Legend="{Binding ElementName=Legend}" ItemsSource="{Binding}" ValueMemberPath="Column3" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column3:C}" /> <igChart:LineSeries Title="Close" Legend="{Binding ElementName=Legend}" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" ItemsSource="{Binding}" ValueMemberPath="Column4" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column4:C}" /> </igChart:XamDataChart.Series> </igChart:XamDataChart> </Border>
<DataTemplate x:Key="tooltipTemplate"> <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Background="White" IsHitTestVisible="False" Padding="5"> <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Series.LegendItemBadgeTemplate}" /> <TextBlock Text="Series: " /> <TextBlock Text="{Binding Series.Title}" /> <TextBlock Text=" " /> <TextBlock Text="Value: " /> <TextBlock Text="{Binding Value}" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Border> </DataTemplate>
And the code behind:
public partial class XamDataChartHostControl : UserControl { private CursorTooltipBehavior curt; public XamDataChartHostControl() { InitializeComponent(); } public XamDataChart XamDataChart { get { return wpfWebDataChart1; } } private void wpfWebDataChart1_SeriesCursorMouseMove(object sender, ChartCursorEventArgs e) { //CursorTooltipBehavior temp = new CursorTooltipBehavior(); //temp.Chart_SeriesCursorMouseMove(sender, e); //if (e.Series != null && e.Item != null) //{ // curt.Chart_SeriesCursorMouseMove(sender , e ); //} } } public class ChartBehaviors : DependencyObject { public static readonly DependencyProperty CursorTooltipProperty = DependencyProperty.RegisterAttached("CursorTooltip", typeof(CursorTooltipBehavior), typeof(ChartBehaviors), new PropertyMetadata(null, (o, e) => CursorTooltipChanged(o as XamDataChart, e.OldValue as CursorTooltipBehavior, e.NewValue as CursorTooltipBehavior))); public static CursorTooltipBehavior GetCursorTooltip(DependencyObject target) { return target.GetValue(CursorTooltipProperty) as CursorTooltipBehavior; } public static void SetCursorTooltip(DependencyObject target, CursorTooltipBehavior behavior) { target.SetValue(CursorTooltipProperty, behavior); } private static void CursorTooltipChanged(XamDataChart chart, CursorTooltipBehavior oldValue, CursorTooltipBehavior newValue) { if (chart == null) { return; } if (oldValue != null) { oldValue.OnDetach(chart); } if (newValue != null) { newValue.OnAttach(chart); } } } public class SeriesItemInfo : INotifyPropertyChanged { private Series _series; public Series Series { get { return _series; } set { _series = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Series")); PropertyChanged(this, new PropertyChangedEventArgs("Value")); } } } private object _item; public object Item { get { return _item; } set { _item = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Item")); PropertyChanged(this, new PropertyChangedEventArgs("Value")); } } } private double _value; private FastReflectionHelper _helper = new FastReflectionHelper(); public double Value { get { if (Series == null || Item == null) { return 0.0; } if (Series is AnchoredCategorySeries) { _helper.PropertyName = ((AnchoredCategorySeries)Series) .ValueMemberPath; return Convert.ToDouble(_helper.GetPropertyValue(Item)); } return 0.0; } } public event PropertyChangedEventHandler PropertyChanged; } public class SeriesItemInfoCollection : ObservableCollection<SeriesItemInfo> { public void UpdateSeriesItem(Series series, object item) { bool found = false; var indexes = from curr in this where curr.Series == series select this.IndexOf(curr); foreach (int index in indexes) { found = true; this[index].Item = item; } if (!found) { this.Add(new SeriesItemInfo() { Series = series, Item = item, }); } } } public class CursorTooltipBehavior { private bool _isOverChart = false; private Popup _popup = new Popup(); private ContentControl _content = new ContentControl(); private Panel _container; private XamDataChart _owner = null; private DataTemplate _tooltipTemplate; private SeriesItemInfoCollection _items = new SeriesItemInfoCollection(); public DataTemplate TooltipTemplate { get { return _tooltipTemplate; } set { _tooltipTemplate = value; _content.ContentTemplate = _tooltipTemplate; } } protected bool IsOverChart { get { return _isOverChart; } set { bool last = _isOverChart; _isOverChart = value; if (_isOverChart && !last) { ShowPopup(); } if (!_isOverChart && last) { HidePopup(); } } } private void HidePopup() { _popup.IsOpen = false; } private void ShowPopup() { _popup.IsOpen = true; } public void OnAttach(XamDataChart chart) { if (_owner != null) { OnDetach(_owner); } chart.MouseLeave += Chart_MouseLeave; chart.MouseMove += Chart_MouseMove; chart.SeriesCursorMouseMove += Chart_SeriesCursorMouseMove; _popup.IsOpen = false; _popup.Child = _content; _content.ContentTemplate = TooltipTemplate; _content.Content = _items; if (chart.Parent != null && chart.Parent is Panel) { _container = chart.Parent as Panel; _container.Children.Add(_popup); } } public void OnDetach(XamDataChart chart) { if (_owner != chart) { return; } chart.MouseLeave -= Chart_MouseLeave; chart.MouseMove -= Chart_MouseMove; chart.SeriesCursorMouseMove -= Chart_SeriesCursorMouseMove; IsOverChart = false; _items.Clear(); _owner = null; } void Chart_MouseMove(object sender, MouseEventArgs e) { SetPopupOffsets(e.GetPosition(_owner)); IsOverChart = true; } private void SetPopupOffsets(Point point) { _popup.VerticalOffset = point.Y; _popup.HorizontalOffset = point.X + 10; } public void Chart_SeriesCursorMouseMove(object sender, ChartCursorEventArgs e) { if (e.Series != null && e.Item != null) { _items.UpdateSeriesItem(e.Series, e.Item); } } public void Chart_MouseLeave(object sender, MouseEventArgs e) { IsOverChart = false; } }
Hope that helps!
This specific example is always showing the closest actual data points values for all the series in the tooltip. You need to take a different approach if you want to show the actual value of the line at the precise x location that you are at. Which approach are you interested in?
hi Graham,
what you gave the code for me in that below line
private FastReflectionHelper _helper = new FastReflectionHelper();
i am getting this error
" The type or namespace name 'FastReflectionHelper' could not be found (are you missing a using directive or an assembly reference?) "
the above error i added some code like below
public class FastReflectionHelper { public string PropertyName { get; set; }
public object GetPropertyValue(object item) { return item ; } }
whether it's right or wrong realy i don't know and its working but i didn't get the values and here i attached screenshot ,
plz see my screenshot whereever i marked in chart , there we hv to display the data points value of the line at the precise x and y both the location.
add:
using Infragistics;
to the top of your file. Let me know if that helps!
thanks for ur reply Graham ,
it's working and one more problem , here i attached one screenshot plz see this
here i getting only y-axis values and also i want to show the actual value of the line at the precise x location ( i put question mark in chart ) because i want both x & y location
thanks a lot Graham, it's working once again thank you so much...
--Madhusudan
Make sure you didn't miss merging any changes into your project, there were a lot of updates. I've attached my working project so that you can compare it to your project.
your code is Running without any error but i didn't get any values of intersect vertical and horizontal crosshair for your reference i attached my screenshot
Hi, I didn't share with you the code that does all the intersections because it isn't useful graphically. But in case you want to use the list of intersections in a listbox or something, here it is:
Tooltip template:
<DataTemplate x:Key="tooltipTemplate"> <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Background="White" IsHitTestVisible="False" Padding="5"> <!--<ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate>--> <StackPanel Orientation="Horizontal"> <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Series.LegendItemBadgeTemplate}" /> <TextBlock Text="Series: " /> <TextBlock Text="{Binding Series.Title}" /> <TextBlock Text=" " /> <TextBlock Text="Value: " /> <TextBlock Text="{Binding Value}" /> </StackPanel> <!--</DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>--> </Border> </DataTemplate>
Control:
<UserControl x:Class="SilverlightApplication86.XamDataChartHostControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:igChart="clr-namespace:Infragistics.Controls.Charts;assembly=InfragisticsSL4.Controls.Charts.XamDataChart.v10.2" xmlns:igCtrl="clr-namespace:Infragistics.Controls;assembly=InfragisticsSL4.DataVisualization.v10.2" xmlns:local="clr-namespace:SilverlightApplication86" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <UserControl.Resources> <LinearGradientBrush x:Key="rscGradientBackground" StartPoint="0.0, 0.0" EndPoint="1.0, 1.0"> <GradientStop Color="#FFFFFFFF" Offset="0" /> <GradientStop Color="#c0c2c8" Offset="0.4" /> <GradientStop Color="#e0e2e8" Offset="1" /> </LinearGradientBrush> <Style x:Key="rscXamDataChartStyle" TargetType="igChart:XamDataChart"> <Setter Property="PlotAreaBackground" Value="Transparent" /> </Style> <!--<Style x:Key="LegendStyle" TargetType="{x:Type igChart:Legend}"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="White" Offset="0" /> <GradientStop Color="White" Offset="0.5" /> <GradientStop Color="White" Offset="0.5" /> <GradientStop Color="#FFE8E8EF" Offset="1" /> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" Value="{StaticResource rscGradientBorder}"/> <Setter Property="BorderThickness" Value="0.75" /> <Setter Property="Orientation" Value="Vertical" /> <Setter Property="Padding" Value="4" /> <Setter Property="Margin" Value="2" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igChart:Legend}"> <Grid Margin="{TemplateBinding Margin}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="3" Background="Transparent" CornerRadius="4"> <Grid Margin="{TemplateBinding Padding}"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ContentPresenter Content="{TemplateBinding Content}" Margin="0" Grid.Row="1" /> <ScrollViewer BorderThickness="0" HorizontalScrollBarVisibility="Auto" Grid.Row="2" VerticalScrollBarVisibility="Auto" Margin="3,0,0,0"> <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Grid.Row="1" /> </ScrollViewer> </Grid> </Border> <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" IsHitTestVisible="False"> <Border.Background> <LinearGradientBrush EndPoint="0,1" Opacity="0" StartPoint="0,0"> <GradientStop Color="Transparent" Offset="0" /> <GradientStop Color="#10FFFFFF" Offset="0.499" /> <GradientStop Color="Transparent" Offset="0.501" /> </LinearGradientBrush> </Border.Background> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>--> <LinearGradientBrush x:Key="rscGradientBorder" StartPoint="0.0, 0.0" EndPoint="0.0, 1.0"> <GradientStop Color="#FFFFFFFF" Offset="0" /> <GradientStop Color="#c0c2c8" Offset="0.75" /> <GradientStop Color="#e0e2e8" Offset="1" /> </LinearGradientBrush> </UserControl.Resources> <Border CornerRadius="5" Margin="5" Background="{StaticResource rscGradientBackground}"> <igChart:XamDataChart Grid.Row="1" Name="wpfWebDataChart1" Style="{StaticResource rscXamDataChartStyle}" Legend="{Binding ElementName=Legend}" CrosshairVisibility="Visible" > <!--<igChart:Legend igCtrl:XamDock.Edge="OutsideRight" x:Name="Legend" Style="{DynamicResource LegendStyle}" igCtrl:XamDock.VerticalAlignment="Center" Content="Prices" />--> <local:ChartBehaviors.CursorTooltip> <local:CursorTooltipBehavior TooltipTemplate="{StaticResource tooltipTemplate}" > <local:CursorTooltipBehavior.IntersectionFinder> <local:IntersectionFinder /> </local:CursorTooltipBehavior.IntersectionFinder> </local:CursorTooltipBehavior> </local:ChartBehaviors.CursorTooltip> <igChart:XamDataChart.Axes> <igChart:CategoryXAxis x:Name="XAxis" VerticalAlignment="Top" ItemsSource="{Binding}" /> <igChart:NumericYAxis x:Name="YAxis" /> </igChart:XamDataChart.Axes> <igChart:XamDataChart.Series> <igChart:LineSeries Title="High" Legend="{Binding ElementName=Legend}" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" MarkerType="None" ItemsSource="{Binding}" ValueMemberPath="Column2" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column2:C}" /> <igChart:LineSeries Title="Low" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" Legend="{Binding ElementName=Legend}" ItemsSource="{Binding}" ValueMemberPath="Column3" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column3:C}" /> <igChart:LineSeries Title="Close" Legend="{Binding ElementName=Legend}" XAxis="{Binding ElementName=XAxis}" YAxis="{Binding ElementName=YAxis}" ItemsSource="{Binding}" ValueMemberPath="Column4" ToolTip="{}{Series.Title} {Item.Column0:D}: {Item.Column4:C}" /> </igChart:XamDataChart.Series> </igChart:XamDataChart> </Border> </UserControl>
Control code behind:
public partial class XamDataChartHostControl : UserControl { private CursorTooltipBehavior curt; public XamDataChartHostControl() { InitializeComponent(); } public XamDataChart XamDataChart { get { return wpfWebDataChart1; } } private void wpfWebDataChart1_SeriesCursorMouseMove(object sender, ChartCursorEventArgs e) { //CursorTooltipBehavior temp = new CursorTooltipBehavior(); //temp.Chart_SeriesCursorMouseMove(sender, e); //if (e.Series != null && e.Item != null) //{ // curt.Chart_SeriesCursorMouseMove(sender , e ); //} } } public class ChartBehaviors : DependencyObject { public static readonly DependencyProperty CursorTooltipProperty = DependencyProperty.RegisterAttached("CursorTooltip", typeof(CursorTooltipBehavior), typeof(ChartBehaviors), new PropertyMetadata(null, (o, e) => CursorTooltipChanged(o as XamDataChart, e.OldValue as CursorTooltipBehavior, e.NewValue as CursorTooltipBehavior))); public static CursorTooltipBehavior GetCursorTooltip(DependencyObject target) { return target.GetValue(CursorTooltipProperty) as CursorTooltipBehavior; } public static void SetCursorTooltip(DependencyObject target, CursorTooltipBehavior behavior) { target.SetValue(CursorTooltipProperty, behavior); } private static void CursorTooltipChanged(XamDataChart chart, CursorTooltipBehavior oldValue, CursorTooltipBehavior newValue) { if (chart == null) { return; } if (oldValue != null) { oldValue.OnDetach(chart); } if (newValue != null) { newValue.OnAttach(chart); } } } public class SeriesItemInfo : INotifyPropertyChanged { private Series _series; public Series Series { get { return _series; } set { _series = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Series")); PropertyChanged(this, new PropertyChangedEventArgs("Value")); } } } private object _item; public object Item { get { return _item; } set { _item = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Item")); PropertyChanged(this, new PropertyChangedEventArgs("Value")); } } } private Point _position; public Point Position { get { return _position; } set { _position = value; if (PropertyChanged != null) { PropertyChanged( this, new PropertyChangedEventArgs("Position")); } } } private double _value; private FastReflectionHelper _helper = new FastReflectionHelper(); public double Value { get { if (Series == null || Item == null) { return 0.0; } if (Series is AnchoredCategorySeries) { _helper.PropertyName = ((AnchoredCategorySeries)Series) .ValueMemberPath; return Convert.ToDouble(_helper.GetPropertyValue(Item)); } return 0.0; } } public event PropertyChangedEventHandler PropertyChanged; } public class SeriesItemInfoCollection : ObservableCollection<SeriesItemInfo> { internal void UpdateSeriesItems(Series series, IList<Tuple<object, Point>> intersectedAxisItems) { bool found = false; var old = (from curr in this where curr.Series == series select curr).ToList(); foreach (var item in old) { Remove(item); } foreach (var item in intersectedAxisItems) { Add(new SeriesItemInfo() { Series = series, Item = item.Item1, Position = item.Item2 }); } } } public class PopupCollection { private XamDataChart _owner = null; private List<Popup> _popups = new List<Popup>(); public PopupCollection(XamDataChart owner) { _owner = owner; } public void RefreshPopups( IList<SeriesItemInfo> infos, DataTemplate tooltipTemplate, Rect viewportRect) { int index = 0; foreach (var popup in _popups) { if (index >= infos.Count) { break; } ContentControl control = popup.Child as ContentControl; control.ContentTemplate = tooltipTemplate; control.Content = infos[index]; UpdatePopupPosition(popup, infos[index], viewportRect); popup.IsOpen = true; index++; } for (int i = index; i < infos.Count; i++) { Popup popup = new Popup(); popup.Child = new ContentControl(); ContentControl control = popup.Child as ContentControl; control.ContentTemplate = tooltipTemplate; control.Content = infos[i]; UpdatePopupPosition(popup, infos[i], viewportRect); popup.IsOpen = true; Panel container; if (_owner.Parent != null && _owner.Parent is Panel) { container = _owner.Parent as Panel; container.Children.Add(popup); } _popups.Add(popup); index++; } for (int i = index; i < _popups.Count; i++) { _popups[i].IsOpen = false; } } private void UpdatePopupPosition( Popup popup, SeriesItemInfo info, Rect viewportRect) { double xPosition = ((AnchoredCategorySeries)info.Series).XAxis .GetScaledValue( info.Position.X, info.Series.Chart.WindowRect, viewportRect); double yPosition = ((AnchoredCategorySeries)info.Series).YAxis .GetScaledValue( info.Position.Y, info.Series.Chart.WindowRect, viewportRect); popup.HorizontalOffset = xPosition; popup.VerticalOffset = yPosition; } } public class CursorTooltipBehavior { private bool _isOverChart = false; private PopupCollection _popups = null; private ContentControl _content = new ContentControl(); private Panel _container; private XamDataChart _owner = null; private DataTemplate _tooltipTemplate; private SeriesItemInfoCollection _items = new SeriesItemInfoCollection(); public DataTemplate TooltipTemplate { get { return _tooltipTemplate; } set { _tooltipTemplate = value; _content.ContentTemplate = _tooltipTemplate; } } //protected bool IsOverChart //{ // get { return _isOverChart; } // set // { // bool last = _isOverChart; // _isOverChart = value; // if (_isOverChart && !last) // { // ShowPopup(); // } // if (!_isOverChart && last) // { // HidePopup(); // } // } //} public void OnAttach(XamDataChart chart) { if (_owner != null) { OnDetach(_owner); } _owner = chart; chart.MouseLeave += Chart_MouseLeave; chart.MouseMove += Chart_MouseMove; //chart.SeriesCursorMouseMove += Chart_SeriesCursorMouseMove; chart.PropertyUpdated += Chart_PropertyUpdated; _popups = new PopupCollection(_owner); } void Chart_PropertyUpdated(object sender, PropertyUpdatedEventArgs e) { if (e.PropertyName == "CrosshairPoint") { if (e.NewValue != null && e.NewValue is Point && _owner != null) { //get the relevant axes. CategoryXAxis x = _owner.Axes.First((a) => a is CategoryXAxis) as CategoryXAxis; NumericYAxis y = _owner.Axes.First((a) => a is NumericYAxis) as NumericYAxis; //determine the series viewport. Rect viewportRect = GetViewportRect( _owner.Series[0], x, y); Point p = (Point)e.NewValue; double left; double right; double top; double bottom; GetInViewAxisBounds(x, y, viewportRect, out left, out right, out top, out bottom); //get crosshair window values. double windowX = (p.X - _owner.WindowRect.Left) / _owner.WindowRect.Width; double windowY = (p.Y - _owner.WindowRect.Top) / _owner.WindowRect.Height; //interpolate axis values. double xAxisValue = left + (windowX * (right - left)); double yAxisValue = top + (windowY * (bottom - top)); if (!double.IsNaN(xAxisValue) && !double.IsNaN(yAxisValue) && IntersectionFinder != null) { foreach (var series in _owner.Series) { IList<Tuple<object, Point>> intersectedAxisItems = IntersectionFinder.GetIntersectedItemAxisItems( series, new Point(xAxisValue, yAxisValue)); _items.UpdateSeriesItems(series, intersectedAxisItems); } } } } } public IIntersectionFinder IntersectionFinder { get; set; } private void GetInViewAxisBounds( CategoryXAxis x, NumericYAxis y, Rect viewportRect, out double left, out double right, out double top, out double bottom) { left = x.GetUnscaledValue( viewportRect.Left, _owner.WindowRect, viewportRect); right = x.GetUnscaledValue( viewportRect.Right, _owner.WindowRect, viewportRect); top = y.GetUnscaledValue( viewportRect.Top, _owner.WindowRect, viewportRect); bottom = y.GetUnscaledValue( viewportRect.Bottom, _owner.WindowRect, viewportRect); } private Rect GetViewportRect( Series target, CategoryXAxis x, NumericYAxis y) { double top = 0; double left = 0; double bottom = y.ActualHeight; double right = x.ActualWidth; double width = right - left; double height = bottom - top; if (width > 0.0 && height > 0.0) { return new Rect(left, top, width, height); } return Rect.Empty; } public void OnDetach(XamDataChart chart) { if (_owner != chart) { return; } chart.MouseLeave -= Chart_MouseLeave; chart.MouseMove -= Chart_MouseMove; //chart.SeriesCursorMouseMove -= Chart_SeriesCursorMouseMove; chart.PropertyUpdated -= Chart_PropertyUpdated; //IsOverChart = false; _items.Clear(); _owner = null; } void Chart_MouseMove(object sender, MouseEventArgs e) { CategoryXAxis x = _owner.Axes.First((a) => a is CategoryXAxis) as CategoryXAxis; NumericYAxis y = _owner.Axes.First((a) => a is NumericYAxis) as NumericYAxis; //determine the series viewport. Rect viewportRect = GetViewportRect( _owner.Series[0], x, y); _popups.RefreshPopups(_items, _tooltipTemplate, viewportRect); //IsOverChart = true; } //public void Chart_SeriesCursorMouseMove(object sender, ChartCursorEventArgs e) //{ // if (e.Series != null && e.Item != null) // { // _items.UpdateSeriesItem(e.Series, e.Item); // } //} public void Chart_MouseLeave(object sender, MouseEventArgs e) { //IsOverChart = false; } } public interface IIntersectionFinder { IList<Tuple<object, Point>> GetIntersectedItemAxisItems( Series series, Point crosshairAxisPosition); }
Test Data:
public class TestData : ObservableCollection<TestDataItem> { private static Random _rand = new Random(); public TestData() { double curr = 10.0; for (int i = 0; i < 100; i++) { if (_rand.NextDouble() < .5) { curr += _rand.NextDouble() * 3.0; } else { curr -= _rand.NextDouble() * 3.0; } Add(new TestDataItem() { Column0 = i, Column1 = curr + _rand.NextDouble() * 3.0, Column2 = curr + _rand.NextDouble() * 3.0, Column3 = curr - _rand.NextDouble() * 3.0, Column4 = curr - _rand.NextDouble() * 3.0 }); } } } public class TestDataItem { public double Column0 { get; set; } public double Column1 { get; set; } public double Column2 { get; set; } public double Column3 { get; set; } public double Column4 { get; set; } } public class IntersectionFinder : IIntersectionFinder { FastReflectionHelper _helper = new FastReflectionHelper(); public IList<Tuple<object, System.Windows.Point>> GetIntersectedItemAxisItems( Series series, System.Windows.Point crosshairAxisPosition ) { var intersections = new List<Tuple<object, Point>>(); int index = 0; _helper.PropertyName = ((AnchoredCategorySeries)series).ValueMemberPath; double prevX = double.NaN; double prevY = double.NaN; foreach (var item in series.ItemsSource.OfType<TestDataItem>()) { double xVal = index; double yVal = Convert.ToDouble(_helper.GetPropertyValue(item)); if (!double.IsNaN(xVal) && !double.IsNaN(yVal)) { if ((prevY < crosshairAxisPosition.Y && yVal >= crosshairAxisPosition.Y) || (prevY > crosshairAxisPosition.Y && yVal <= crosshairAxisPosition.Y)) { intersections.Add(new Tuple<object,Point>( item, new Point(xVal,yVal))); } } index++; prevX = xVal; prevY = yVal; } return intersections; } }
Hope that helps.
i added the sample code through which one you gave me the link , but i didn't get the all intersect values of Horizontal crosshair like which one you attached one screenshot in my thread
here i attached my code and xaml code plz see this , i think i did some mistake ,where i did i unable to findout plz help me this
4705.xaml.txt
6378.Code.txt