[12503] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Linq;
|
---|
| 4 | using System.Text;
|
---|
| 5 | using System.Windows.Controls;
|
---|
| 6 | using System.Windows.Shapes;
|
---|
| 7 | using System.Windows.Input;
|
---|
| 8 | using System.Windows;
|
---|
| 9 | using System.Windows.Media;
|
---|
| 10 | using System.Windows.Data;
|
---|
| 11 | using Microsoft.Research.DynamicDataDisplay.Common;
|
---|
| 12 |
|
---|
| 13 | namespace Microsoft.Research.DynamicDataDisplay.Charts.Navigation
|
---|
| 14 | {
|
---|
| 15 | /// <summary>
|
---|
| 16 | /// Adds to ChartPlotter two lines upon axes, showing current cursor position.
|
---|
| 17 | /// </summary>
|
---|
| 18 | public class AxisCursorGraph : DependencyObject, IPlotterElement
|
---|
| 19 | {
|
---|
| 20 | static AxisCursorGraph()
|
---|
| 21 | {
|
---|
| 22 | Line.StrokeProperty.AddOwner(typeof(AxisCursorGraph), new FrameworkPropertyMetadata(Brushes.Red));
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | /// <summary>
|
---|
| 26 | /// Initializes a new instance of the <see cref="AxisCursorGraph"/> class.
|
---|
| 27 | /// </summary>
|
---|
| 28 | public AxisCursorGraph() { }
|
---|
| 29 |
|
---|
| 30 | #region ShowVerticalLine property
|
---|
| 31 |
|
---|
| 32 | /// <summary>
|
---|
| 33 | /// Gets or sets a value indicating whether to show line upon vertical axis.
|
---|
| 34 | /// </summary>
|
---|
| 35 | /// <value><c>true</c> if line upon vertical axis is shown; otherwise, <c>false</c>.</value>
|
---|
| 36 | public bool ShowVerticalLine
|
---|
| 37 | {
|
---|
| 38 | get { return (bool)GetValue(ShowVerticalLineProperty); }
|
---|
| 39 | set { SetValue(ShowVerticalLineProperty, value); }
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 | /// <summary>
|
---|
| 43 | /// Identifies ShowVerticalLine dependency property.
|
---|
| 44 | /// </summary>
|
---|
| 45 | public static readonly DependencyProperty ShowVerticalLineProperty = DependencyProperty.Register(
|
---|
| 46 | "ShowVerticalLine",
|
---|
| 47 | typeof(bool),
|
---|
| 48 | typeof(AxisCursorGraph),
|
---|
| 49 | new FrameworkPropertyMetadata(true, OnShowLinePropertyChanged));
|
---|
| 50 |
|
---|
| 51 | private static void OnShowLinePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
---|
| 52 | {
|
---|
| 53 | AxisCursorGraph graph = (AxisCursorGraph)d;
|
---|
| 54 | graph.UpdateUIRepresentation();
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | #endregion
|
---|
| 58 |
|
---|
| 59 | #region ShowHorizontalLine property
|
---|
| 60 |
|
---|
| 61 | /// <summary>
|
---|
| 62 | /// Gets or sets a value indicating whether to show line upon horizontal axis.
|
---|
| 63 | /// </summary>
|
---|
| 64 | /// <value><c>true</c> if lien upon horizontal axis is shown; otherwise, <c>false</c>.</value>
|
---|
| 65 | public bool ShowHorizontalLine
|
---|
| 66 | {
|
---|
| 67 | get { return (bool)GetValue(ShowHorizontalLineProperty); }
|
---|
| 68 | set { SetValue(ShowHorizontalLineProperty, value); }
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | public static readonly DependencyProperty ShowHorizontalLineProperty = DependencyProperty.Register(
|
---|
| 72 | "ShowHorizontalLine",
|
---|
| 73 | typeof(bool),
|
---|
| 74 | typeof(AxisCursorGraph),
|
---|
| 75 | new FrameworkPropertyMetadata(true, OnShowLinePropertyChanged));
|
---|
| 76 |
|
---|
| 77 | #endregion
|
---|
| 78 |
|
---|
| 79 | #region IPlotterElement Members
|
---|
| 80 |
|
---|
| 81 | private Line leftLine;
|
---|
| 82 | private Line bottomLine;
|
---|
| 83 | private Canvas leftCanvas;
|
---|
| 84 | private Canvas bottomCanvas;
|
---|
| 85 |
|
---|
| 86 | private Plotter2D plotter;
|
---|
| 87 | void IPlotterElement.OnPlotterAttached(Plotter plotter)
|
---|
| 88 | {
|
---|
| 89 | this.plotter = (Plotter2D)plotter;
|
---|
| 90 |
|
---|
| 91 | this.plotter.Viewport.PropertyChanged += Viewport_PropertyChanged;
|
---|
| 92 |
|
---|
| 93 | var parent = plotter.MainGrid;
|
---|
| 94 | parent.MouseMove += parent_MouseMove;
|
---|
| 95 | parent.MouseEnter += parent_MouseEnter;
|
---|
| 96 | parent.MouseLeave += parent_MouseLeave;
|
---|
| 97 |
|
---|
| 98 | Style lineStyle = new Style(typeof(Line));
|
---|
| 99 | AddBindingSetter(lineStyle, Line.StrokeProperty);
|
---|
| 100 | AddBindingSetter(lineStyle, Line.StrokeThicknessProperty);
|
---|
| 101 |
|
---|
| 102 | leftCanvas = new Canvas();
|
---|
| 103 | Grid.SetRow(leftCanvas, 1);
|
---|
| 104 | Grid.SetColumn(leftCanvas, 0);
|
---|
| 105 | leftLine = new Line { Style = lineStyle, IsHitTestVisible = false };
|
---|
| 106 | leftCanvas.Children.Add(leftLine);
|
---|
| 107 | parent.Children.Add(leftCanvas);
|
---|
| 108 |
|
---|
| 109 | bottomCanvas = new Canvas();
|
---|
| 110 | Grid.SetRow(bottomCanvas, 2);
|
---|
| 111 | Grid.SetColumn(bottomCanvas, 1);
|
---|
| 112 | bottomLine = new Line { Style = lineStyle, IsHitTestVisible = false };
|
---|
| 113 | bottomCanvas.Children.Add(bottomLine);
|
---|
| 114 | parent.Children.Add(bottomCanvas);
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | private void AddBindingSetter(Style style, DependencyProperty property)
|
---|
| 118 | {
|
---|
| 119 | style.Setters.Add(new Setter(property,
|
---|
| 120 | new Binding
|
---|
| 121 | {
|
---|
| 122 | Path = new PropertyPath(property.Name),
|
---|
| 123 | Source = this
|
---|
| 124 | }));
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | void Viewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e)
|
---|
| 128 | {
|
---|
| 129 | UpdateUIRepresentation();
|
---|
| 130 | }
|
---|
| 131 |
|
---|
| 132 | private void UpdateUIRepresentation()
|
---|
| 133 | {
|
---|
| 134 | if (plotter == null) return;
|
---|
| 135 |
|
---|
| 136 | var transform = plotter.Viewport.Transform;
|
---|
| 137 | DataRect visible = plotter.Viewport.Visible;
|
---|
| 138 | Rect output = plotter.Viewport.Output;
|
---|
| 139 |
|
---|
| 140 | Point mousePos = Mouse.GetPosition(plotter.CentralGrid);
|
---|
| 141 |
|
---|
| 142 | if (ShowVerticalLine)
|
---|
| 143 | {
|
---|
| 144 | double y = mousePos.Y;
|
---|
| 145 | if (output.Top <= y && y <= output.Bottom)
|
---|
| 146 | {
|
---|
| 147 | leftLine.Visibility = Visibility.Visible;
|
---|
| 148 | leftLine.X1 = 0;
|
---|
| 149 | leftLine.X2 = plotter.LeftPanel.ActualWidth;
|
---|
| 150 |
|
---|
| 151 | leftLine.Y1 = leftLine.Y2 = y;
|
---|
| 152 | }
|
---|
| 153 | else
|
---|
| 154 | {
|
---|
| 155 | leftLine.Visibility = Visibility.Collapsed;
|
---|
| 156 | }
|
---|
| 157 | }
|
---|
| 158 | else
|
---|
| 159 | {
|
---|
| 160 | leftLine.Visibility = Visibility.Collapsed;
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | if (ShowHorizontalLine)
|
---|
| 164 | {
|
---|
| 165 | double x = mousePos.X;
|
---|
| 166 | if (output.Left <= x && x <= output.Right)
|
---|
| 167 | {
|
---|
| 168 | bottomLine.Visibility = Visibility.Visible;
|
---|
| 169 | bottomLine.Y1 = 0;
|
---|
| 170 | bottomLine.Y2 = plotter.BottomPanel.ActualHeight;
|
---|
| 171 |
|
---|
| 172 | bottomLine.X1 = bottomLine.X2 = x;
|
---|
| 173 | }
|
---|
| 174 | else
|
---|
| 175 | {
|
---|
| 176 | bottomLine.Visibility = Visibility.Collapsed;
|
---|
| 177 | }
|
---|
| 178 | }
|
---|
| 179 | else
|
---|
| 180 | {
|
---|
| 181 | bottomLine.Visibility = Visibility.Collapsed;
|
---|
| 182 | }
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | void parent_MouseLeave(object sender, MouseEventArgs e)
|
---|
| 186 | {
|
---|
| 187 | UpdateUIRepresentation();
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 | void parent_MouseEnter(object sender, MouseEventArgs e)
|
---|
| 191 | {
|
---|
| 192 | UpdateUIRepresentation();
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | void parent_MouseMove(object sender, MouseEventArgs e)
|
---|
| 196 | {
|
---|
| 197 | UpdateUIRepresentation();
|
---|
| 198 | }
|
---|
| 199 |
|
---|
| 200 | void IPlotterElement.OnPlotterDetaching(Plotter plotter)
|
---|
| 201 | {
|
---|
| 202 | this.plotter.Viewport.PropertyChanged -= Viewport_PropertyChanged;
|
---|
| 203 |
|
---|
| 204 | var parent = plotter.MainGrid;
|
---|
| 205 | parent.MouseMove -= parent_MouseMove;
|
---|
| 206 | parent.MouseEnter -= parent_MouseEnter;
|
---|
| 207 | parent.MouseLeave -= parent_MouseLeave;
|
---|
| 208 |
|
---|
| 209 | parent.Children.Remove(leftCanvas);
|
---|
| 210 | parent.Children.Remove(bottomCanvas);
|
---|
| 211 |
|
---|
| 212 | this.plotter = null;
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | Plotter IPlotterElement.Plotter
|
---|
| 216 | {
|
---|
| 217 | get { return plotter; }
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | #endregion
|
---|
| 221 | }
|
---|
| 222 | }
|
---|