Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/Isolines/IsolineTrackingGraph.xaml.cs @ 12503

Last change on this file since 12503 was 12503, checked in by aballeit, 9 years ago

#2283 added GUI and charts; fixed MCTS

File size: 6.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows;
6using System.Windows.Controls;
7using System.Windows.Data;
8using System.Windows.Documents;
9using System.Windows.Input;
10using System.Windows.Media;
11using System.Windows.Media.Imaging;
12using System.Windows.Navigation;
13using System.Windows.Shapes;
14using Microsoft.Research.DynamicDataDisplay.Charts.Isolines;
15using Microsoft.Research.DynamicDataDisplay;
16using Microsoft.Research.DynamicDataDisplay.Common;
17
18namespace Microsoft.Research.DynamicDataDisplay.Charts
19{
20  /// <summary>
21  /// Draws one isoline line through mouse position.
22  /// </summary>
23  public partial class IsolineTrackingGraph : IsolineGraphBase
24  {
25    /// <summary>
26    /// Initializes a new instance of the <see cref="IsolineTrackingGraph"/> class.
27    /// </summary>
28    public IsolineTrackingGraph()
29    {
30      InitializeComponent();
31    }
32
33    private Style pathStyle = null;
34    /// <summary>
35    /// Gets or sets style, applied to line path.
36    /// </summary>
37    /// <value>The path style.</value>
38    public Style PathStyle
39    {
40      get { return pathStyle; }
41      set
42      {
43        pathStyle = value;
44        foreach (var path in addedPaths)
45        {
46          path.Style = pathStyle;
47        }
48      }
49    }
50
51    Point prevMousePos;
52
53    protected override void OnPlotterAttached()
54    {
55      UIElement parent = (UIElement)Parent;
56      parent.MouseMove += parent_MouseMove;
57
58      UpdateUIRepresentation();
59    }
60
61    protected override void OnPlotterDetaching()
62    {
63      UIElement parent = (UIElement)Parent;
64      parent.MouseMove -= parent_MouseMove;
65    }
66
67    private void parent_MouseMove(object sender, MouseEventArgs e)
68    {
69      Point mousePos = e.GetPosition(this);
70      if (mousePos != prevMousePos)
71      {
72        prevMousePos = mousePos;
73
74        UpdateUIRepresentation();
75      }
76    }
77
78    protected override void UpdateDataSource()
79    {
80      IsolineBuilder.DataSource = DataSource;
81
82      UpdateUIRepresentation();
83    }
84
85    protected override void OnViewportPropertyChanged(ExtendedPropertyChangedEventArgs e)
86    {
87      UpdateUIRepresentation();
88    }
89
90    private readonly List<Path> addedPaths = new List<Path>();
91    private Vector labelShift = new Vector(3, 3);
92    private void UpdateUIRepresentation()
93    {
94      if (Plotter2D == null)
95        return;
96
97      foreach (var path in addedPaths)
98      {
99        content.Children.Remove(path);
100      }
101      addedPaths.Clear();
102
103      if (DataSource == null)
104      {
105        labelGrid.Visibility = Visibility.Hidden;
106        return;
107      }
108
109      Rect output = Plotter2D.Viewport.Output;
110
111      Point mousePos = Mouse.GetPosition(this);
112      if (!output.Contains(mousePos)) return;
113
114      var transform = Plotter2D.Viewport.Transform;
115      Point visiblePoint = mousePos.ScreenToData(transform);
116      DataRect visible = Plotter2D.Viewport.Visible;
117
118      double isolineLevel;
119      if (Search(visiblePoint, out isolineLevel))
120      {
121        var collection = IsolineBuilder.BuildIsoline(isolineLevel);
122
123        string format = "G3";
124        if (Math.Abs(isolineLevel) < 1000)
125          format = "F";
126
127        textBlock.Text = isolineLevel.ToString(format);
128
129        double x = mousePos.X + labelShift.X;
130        if (x + labelGrid.ActualWidth > output.Right)
131          x = mousePos.X - labelShift.X - labelGrid.ActualWidth;
132        double y = mousePos.Y - labelShift.Y - labelGrid.ActualHeight;
133        if (y < output.Top)
134          y = mousePos.Y + labelShift.Y;
135
136        Canvas.SetLeft(labelGrid, x);
137        Canvas.SetTop(labelGrid, y);
138
139        foreach (LevelLine segment in collection.Lines)
140        {
141          StreamGeometry streamGeom = new StreamGeometry();
142          using (StreamGeometryContext context = streamGeom.Open())
143          {
144            Point startPoint = segment.StartPoint.DataToScreen(transform);
145            var otherPoints = segment.OtherPoints.DataToScreenAsList(transform);
146            context.BeginFigure(startPoint, false, false);
147            context.PolyLineTo(otherPoints, true, true);
148          }
149
150          Path path = new Path
151          {
152            Stroke = new SolidColorBrush(Palette.GetColor(segment.Value01)),
153            Data = streamGeom,
154            Style = pathStyle
155          };
156          content.Children.Add(path);
157          addedPaths.Add(path);
158
159          labelGrid.Visibility = Visibility.Visible;
160
161          Binding pathBinding = new Binding { Path = new PropertyPath("StrokeThickness"), Source = this };
162          path.SetBinding(Path.StrokeThicknessProperty, pathBinding);
163        }
164      }
165      else
166      {
167        labelGrid.Visibility = Visibility.Hidden;
168      }
169    }
170
171    int foundI = 0;
172    int foundJ = 0;
173    Quad foundQuad = null;
174    private bool Search(Point pt, out double foundVal)
175    {
176      var grid = DataSource.Grid;
177
178      foundVal = 0;
179
180      int width = DataSource.Width;
181      int height = DataSource.Height;
182      bool found = false;
183      int i = 0, j = 0;
184      for (i = 0; i < width - 1; i++)
185      {
186        for (j = 0; j < height - 1; j++)
187        {
188          Quad quad = new Quad(
189          grid[i, j],
190          grid[i, j + 1],
191          grid[i + 1, j + 1],
192          grid[i + 1, j]);
193          if (quad.Contains(pt))
194          {
195            found = true;
196            foundQuad = quad;
197            foundI = i;
198            foundJ = j;
199
200            break;
201          }
202        }
203        if (found) break;
204      }
205      if (!found)
206      {
207        foundQuad = null;
208        return false;
209      }
210
211      var data = DataSource.Data;
212
213      double x = pt.X;
214      double y = pt.Y;
215      Vector A = grid[i, j + 1].ToVector();         // @TODO: in common case add a sorting of points:
216      Vector B = grid[i + 1, j + 1].ToVector();       //   maxA ___K___ B
217      Vector C = grid[i + 1, j].ToVector();         //      |         |
218      Vector D = grid[i, j].ToVector();           //      M    P    N
219      double a = data[i, j + 1];            //    |         |
220      double b = data[i + 1, j + 1];          //    В ___L____Сmin
221      double c = data[i + 1, j];
222      double d = data[i, j];
223
224      Vector K, L;
225      double k, l;
226      if (x >= A.X)
227        k = Interpolate(A, B, a, b, K = new Vector(x, GetY(A, B, x)));
228      else
229        k = Interpolate(D, A, d, a, K = new Vector(x, GetY(D, A, x)));
230
231      if (x >= C.X)
232        l = Interpolate(C, B, c, b, L = new Vector(x, GetY(C, B, x)));
233      else
234        l = Interpolate(D, C, d, c, L = new Vector(x, GetY(D, C, x)));
235
236      foundVal = Interpolate(L, K, l, k, new Vector(x, y));
237      return !Double.IsNaN(foundVal);
238    }
239
240    private double Interpolate(Vector v0, Vector v1, double u0, double u1, Vector a)
241    {
242      Vector l1 = a - v0;
243      Vector l = v1 - v0;
244
245      double res = (u1 - u0) / l.Length * l1.Length + u0;
246      return res;
247    }
248
249    private double GetY(Vector v0, Vector v1, double x)
250    {
251      double res = v0.Y + (v1.Y - v0.Y) / (v1.X - v0.X) * (x - v0.X);
252      return res;
253    }
254  }
255}
Note: See TracBrowser for help on using the repository browser.