223 lines
5.7 KiB
C#
223 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Shapes;
|
|
using System.Windows.Input;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using System.Windows.Data;
|
|
using Microsoft.Research.DynamicDataDisplay.Common;
|
|
|
|
namespace Microsoft.Research.DynamicDataDisplay.Charts.Navigation
|
|
{
|
|
/// <summary>
|
|
/// Adds to ChartPlotter two lines upon axes, showing current cursor position.
|
|
/// </summary>
|
|
public class AxisCursorGraph : DependencyObject, IPlotterElement
|
|
{
|
|
static AxisCursorGraph()
|
|
{
|
|
Line.StrokeProperty.AddOwner(typeof(AxisCursorGraph), new FrameworkPropertyMetadata(Brushes.Red));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="AxisCursorGraph"/> class.
|
|
/// </summary>
|
|
public AxisCursorGraph() { }
|
|
|
|
#region ShowVerticalLine property
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether to show line upon vertical axis.
|
|
/// </summary>
|
|
/// <value><c>true</c> if line upon vertical axis is shown; otherwise, <c>false</c>.</value>
|
|
public bool ShowVerticalLine
|
|
{
|
|
get { return (bool)GetValue(ShowVerticalLineProperty); }
|
|
set { SetValue(ShowVerticalLineProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Identifies ShowVerticalLine dependency property.
|
|
/// </summary>
|
|
public static readonly DependencyProperty ShowVerticalLineProperty = DependencyProperty.Register(
|
|
"ShowVerticalLine",
|
|
typeof(bool),
|
|
typeof(AxisCursorGraph),
|
|
new FrameworkPropertyMetadata(true, OnShowLinePropertyChanged));
|
|
|
|
private static void OnShowLinePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
AxisCursorGraph graph = (AxisCursorGraph)d;
|
|
graph.UpdateUIRepresentation();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ShowHorizontalLine property
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether to show line upon horizontal axis.
|
|
/// </summary>
|
|
/// <value><c>true</c> if lien upon horizontal axis is shown; otherwise, <c>false</c>.</value>
|
|
public bool ShowHorizontalLine
|
|
{
|
|
get { return (bool)GetValue(ShowHorizontalLineProperty); }
|
|
set { SetValue(ShowHorizontalLineProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty ShowHorizontalLineProperty = DependencyProperty.Register(
|
|
"ShowHorizontalLine",
|
|
typeof(bool),
|
|
typeof(AxisCursorGraph),
|
|
new FrameworkPropertyMetadata(true, OnShowLinePropertyChanged));
|
|
|
|
#endregion
|
|
|
|
#region IPlotterElement Members
|
|
|
|
private Line leftLine;
|
|
private Line bottomLine;
|
|
private Canvas leftCanvas;
|
|
private Canvas bottomCanvas;
|
|
|
|
private Plotter2D plotter;
|
|
void IPlotterElement.OnPlotterAttached(Plotter plotter)
|
|
{
|
|
this.plotter = (Plotter2D)plotter;
|
|
|
|
this.plotter.Viewport.PropertyChanged += Viewport_PropertyChanged;
|
|
|
|
var parent = plotter.MainGrid;
|
|
parent.MouseMove += parent_MouseMove;
|
|
parent.MouseEnter += parent_MouseEnter;
|
|
parent.MouseLeave += parent_MouseLeave;
|
|
|
|
Style lineStyle = new Style(typeof(Line));
|
|
AddBindingSetter(lineStyle, Line.StrokeProperty);
|
|
AddBindingSetter(lineStyle, Line.StrokeThicknessProperty);
|
|
|
|
leftCanvas = new Canvas();
|
|
Grid.SetRow(leftCanvas, 1);
|
|
Grid.SetColumn(leftCanvas, 0);
|
|
leftLine = new Line { Style = lineStyle, IsHitTestVisible = false };
|
|
leftCanvas.Children.Add(leftLine);
|
|
parent.Children.Add(leftCanvas);
|
|
|
|
bottomCanvas = new Canvas();
|
|
Grid.SetRow(bottomCanvas, 2);
|
|
Grid.SetColumn(bottomCanvas, 1);
|
|
bottomLine = new Line { Style = lineStyle, IsHitTestVisible = false };
|
|
bottomCanvas.Children.Add(bottomLine);
|
|
parent.Children.Add(bottomCanvas);
|
|
}
|
|
|
|
private void AddBindingSetter(Style style, DependencyProperty property)
|
|
{
|
|
style.Setters.Add(new Setter(property,
|
|
new Binding
|
|
{
|
|
Path = new PropertyPath(property.Name),
|
|
Source = this
|
|
}));
|
|
}
|
|
|
|
void Viewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e)
|
|
{
|
|
UpdateUIRepresentation();
|
|
}
|
|
|
|
private void UpdateUIRepresentation()
|
|
{
|
|
if (plotter == null) return;
|
|
|
|
var transform = plotter.Viewport.Transform;
|
|
DataRect visible = plotter.Viewport.Visible;
|
|
Rect output = plotter.Viewport.Output;
|
|
|
|
Point mousePos = Mouse.GetPosition(plotter.CentralGrid);
|
|
|
|
if (ShowVerticalLine)
|
|
{
|
|
double y = mousePos.Y;
|
|
if (output.Top <= y && y <= output.Bottom)
|
|
{
|
|
leftLine.Visibility = Visibility.Visible;
|
|
leftLine.X1 = 0;
|
|
leftLine.X2 = plotter.LeftPanel.ActualWidth;
|
|
|
|
leftLine.Y1 = leftLine.Y2 = y;
|
|
}
|
|
else
|
|
{
|
|
leftLine.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
leftLine.Visibility = Visibility.Collapsed;
|
|
}
|
|
|
|
if (ShowHorizontalLine)
|
|
{
|
|
double x = mousePos.X;
|
|
if (output.Left <= x && x <= output.Right)
|
|
{
|
|
bottomLine.Visibility = Visibility.Visible;
|
|
bottomLine.Y1 = 0;
|
|
bottomLine.Y2 = plotter.BottomPanel.ActualHeight;
|
|
|
|
bottomLine.X1 = bottomLine.X2 = x;
|
|
}
|
|
else
|
|
{
|
|
bottomLine.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bottomLine.Visibility = Visibility.Collapsed;
|
|
}
|
|
}
|
|
|
|
void parent_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
UpdateUIRepresentation();
|
|
}
|
|
|
|
void parent_MouseEnter(object sender, MouseEventArgs e)
|
|
{
|
|
UpdateUIRepresentation();
|
|
}
|
|
|
|
void parent_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
UpdateUIRepresentation();
|
|
}
|
|
|
|
void IPlotterElement.OnPlotterDetaching(Plotter plotter)
|
|
{
|
|
this.plotter.Viewport.PropertyChanged -= Viewport_PropertyChanged;
|
|
|
|
var parent = plotter.MainGrid;
|
|
parent.MouseMove -= parent_MouseMove;
|
|
parent.MouseEnter -= parent_MouseEnter;
|
|
parent.MouseLeave -= parent_MouseLeave;
|
|
|
|
parent.Children.Remove(leftCanvas);
|
|
parent.Children.Remove(bottomCanvas);
|
|
|
|
this.plotter = null;
|
|
}
|
|
|
|
Plotter IPlotterElement.Plotter
|
|
{
|
|
get { return plotter; }
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|