Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/ChartPlotter.cs @ 13398

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

#2283 added GUI and charts; fixed MCTS

File size: 14.4 KB
Line 
1using System;
2using System.Linq;
3using System.ComponentModel;
4using System.Windows;
5using System.Windows.Controls;
6using Microsoft.Research.DynamicDataDisplay.Charts;
7using Microsoft.Research.DynamicDataDisplay.Charts.Navigation;
8using Microsoft.Research.DynamicDataDisplay.Navigation;
9using Microsoft.Research.DynamicDataDisplay.Common;
10using Microsoft.Research.DynamicDataDisplay.Charts.Axes;
11
12namespace Microsoft.Research.DynamicDataDisplay
13{
14  /// <summary>
15  /// Chart plotter is a plotter that renders axis and grid
16  /// </summary>
17  public class ChartPlotter : Plotter2D
18  {
19    private GeneralAxis horizontalAxis = new HorizontalAxis();
20    private GeneralAxis verticalAxis = new VerticalAxis();
21    private AxisGrid axisGrid = new AxisGrid();
22
23    private Legend legend = new Legend();
24
25    public ItemsPanelTemplate LegendPanelTemplate
26    {
27      get { return legend.ItemsPanel; }
28      set
29      {
30        if (legend == null)
31          throw new ArgumentNullException("LegendPanelTemplate");
32
33        legend.ItemsPanel = value;
34      }
35    }
36
37    public Style LegendStyle
38    {
39      get { return legend.Style; }
40      set { legend.Style = value; }
41    }
42
43    /// <summary>
44    /// Sets a value indicating whether to enable smooth axes panning for numeric axes.
45    /// </summary>
46    /// <value>
47    ///   <c>true</c> if enable smooth axes panning for numeric axes; otherwise, <c>false</c>.
48    /// </value>
49    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
50    public bool EnableSmoothPanningForNumericAxes
51    {
52      // todo improve returned value
53      get { return false; }// throw new NotImplementedException(); }
54      set
55      {
56        foreach (var axis in Children.OfType<NumericAxis>())
57        {
58          axis.UseSmoothPanning = value;
59        }
60      }
61    }
62
63    /// <summary>
64    /// Initializes a new instance of the <see cref="ChartPlotter"/> class.
65    /// </summary>
66    public ChartPlotter()
67      : base()
68    {
69      horizontalAxis.TicksChanged += OnHorizontalAxisTicksChanged;
70      verticalAxis.TicksChanged += OnVerticalAxisTicksChanged;
71
72      SetIsDefaultAxis(horizontalAxis as DependencyObject, true);
73      SetIsDefaultAxis(verticalAxis as DependencyObject, true);
74
75      mouseNavigation = new MouseNavigation();
76      keyboardNavigation = new KeyboardNavigation();
77      defaultContextMenu = new DefaultContextMenu();
78      horizontalAxisNavigation = new AxisNavigation { Placement = AxisPlacement.Bottom };
79      verticalAxisNavigation = new AxisNavigation { Placement = AxisPlacement.Left };
80
81      Children.AddMany(
82        horizontalAxis,
83        verticalAxis,
84        axisGrid,
85        mouseNavigation,
86        keyboardNavigation,
87        defaultContextMenu,
88        horizontalAxisNavigation,
89        verticalAxisNavigation,
90        new LongOperationsIndicator(),
91        legend
92        );
93
94#if DEBUG
95      Children.Add(new DebugMenu());
96#endif
97
98      SetAllChildrenAsDefault();
99    }
100
101    /// <summary>
102    /// Creates generic plotter from this ChartPlotter.
103    /// </summary>
104    /// <returns></returns>
105    public GenericChartPlotter<double, double> GetGenericPlotter()
106    {
107      return new GenericChartPlotter<double, double>(this);
108    }
109
110    /// <summary>
111    /// Creates generic plotter from this ChartPlotter.
112    /// Horizontal and Vertical types of GenericPlotter should correspond to ChartPlotter's actual main axes types.
113    /// </summary>
114    /// <typeparam name="THorizontal">The type of horizontal values.</typeparam>
115    /// <typeparam name="TVertical">The type of vertical values.</typeparam>
116    /// <returns>GenericChartPlotter, associated to this ChartPlotter.</returns>
117    public GenericChartPlotter<THorizontal, TVertical> GetGenericPlotter<THorizontal, TVertical>()
118    {
119      return new GenericChartPlotter<THorizontal, TVertical>(this);
120    }
121
122    /// <summary>
123    /// Creates generic plotter from this ChartPlotter.
124    /// </summary>
125    /// <typeparam name="THorizontal">The type of the horizontal axis.</typeparam>
126    /// <typeparam name="TVertical">The type of the vertical axis.</typeparam>
127    /// <param name="horizontalAxis">The horizontal axis to use as data conversion source.</param>
128    /// <param name="verticalAxis">The vertical axis to use as data conversion source.</param>
129    /// <returns>GenericChartPlotter, associated to this ChartPlotter</returns>
130    public GenericChartPlotter<THorizontal, TVertical> GetGenericPlotter<THorizontal, TVertical>(AxisBase<THorizontal> horizontalAxis, AxisBase<TVertical> verticalAxis)
131    {
132      return new GenericChartPlotter<THorizontal, TVertical>(this, horizontalAxis, verticalAxis);
133    }
134
135    protected ChartPlotter(PlotterLoadMode loadMode) : base(loadMode) { }
136
137    /// <summary>
138    /// Creates empty plotter without any axes, navigation, etc.
139    /// </summary>
140    /// <returns>Empty plotter without any axes, navigation, etc.</returns>
141    public static ChartPlotter CreateEmpty()
142    {
143      return new ChartPlotter(PlotterLoadMode.OnlyViewport);
144    }
145
146    public void BeginLongOperation()
147    {
148      LongOperationsIndicator.BeginLongOperation(this);
149    }
150
151    public void EndLongOperation()
152    {
153      LongOperationsIndicator.EndLongOperation(this);
154    }
155
156    #region Default charts
157
158    private MouseNavigation mouseNavigation;
159    /// <summary>
160    /// Gets the default mouse navigation of ChartPlotter.
161    /// </summary>
162    /// <value>The mouse navigation.</value>
163    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
164    public MouseNavigation MouseNavigation
165    {
166      get { return mouseNavigation; }
167    }
168
169    private KeyboardNavigation keyboardNavigation;
170    /// <summary>
171    /// Gets the default keyboard navigation of ChartPlotter.
172    /// </summary>
173    /// <value>The keyboard navigation.</value>
174    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
175    public KeyboardNavigation KeyboardNavigation
176    {
177      get { return keyboardNavigation; }
178    }
179
180    private DefaultContextMenu defaultContextMenu;
181    /// <summary>
182    /// Gets the default context menu of ChartPlotter.
183    /// </summary>
184    /// <value>The default context menu.</value>
185    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
186    public DefaultContextMenu DefaultContextMenu
187    {
188      get { return defaultContextMenu; }
189    }
190
191    private AxisNavigation horizontalAxisNavigation;
192    /// <summary>
193    /// Gets the default horizontal axis navigation of ChartPlotter.
194    /// </summary>
195    /// <value>The horizontal axis navigation.</value>
196    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
197    public AxisNavigation HorizontalAxisNavigation
198    {
199      get { return horizontalAxisNavigation; }
200    }
201
202    private AxisNavigation verticalAxisNavigation;
203    /// <summary>
204    /// Gets the default vertical axis navigation of ChartPlotter.
205    /// </summary>
206    /// <value>The vertical axis navigation.</value>
207    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
208    public AxisNavigation VerticalAxisNavigation
209    {
210      get { return verticalAxisNavigation; }
211    }
212
213    /// <summary>
214    /// Gets the default axis grid of ChartPlotter.
215    /// </summary>
216    /// <value>The axis grid.</value>
217    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
218    public AxisGrid AxisGrid
219    {
220      get { return axisGrid; }
221    }
222
223    #endregion
224
225    private void OnHorizontalAxisTicksChanged(object sender, EventArgs e)
226    {
227      GeneralAxis axis = (GeneralAxis)sender;
228      UpdateHorizontalTicks(axis);
229    }
230
231    private void UpdateHorizontalTicks(GeneralAxis axis)
232    {
233      axisGrid.BeginTicksUpdate();
234
235      if (axis != null)
236      {
237        axisGrid.HorizontalTicks = axis.ScreenTicks;
238        axisGrid.MinorHorizontalTicks = axis.MinorScreenTicks;
239      }
240      else
241      {
242        axisGrid.HorizontalTicks = null;
243        axisGrid.MinorHorizontalTicks = null;
244      }
245
246      axisGrid.EndTicksUpdate();
247    }
248
249    private void OnVerticalAxisTicksChanged(object sender, EventArgs e)
250    {
251      GeneralAxis axis = (GeneralAxis)sender;
252      UpdateVerticalTicks(axis);
253    }
254
255    private void UpdateVerticalTicks(GeneralAxis axis)
256    {
257      axisGrid.BeginTicksUpdate();
258
259      if (axis != null)
260      {
261        axisGrid.VerticalTicks = axis.ScreenTicks;
262        axisGrid.MinorVerticalTicks = axis.MinorScreenTicks;
263      }
264      else
265      {
266        axisGrid.VerticalTicks = null;
267        axisGrid.MinorVerticalTicks = null;
268      }
269
270      axisGrid.EndTicksUpdate();
271    }
272
273    bool keepOldAxis = false;
274    bool updatingAxis = false;
275
276    /// <summary>
277    /// Gets or sets the main vertical axis of ChartPlotter.
278    /// Main vertical axis of ChartPlotter is axis which ticks are used to draw horizontal lines on AxisGrid.
279    /// Value can be set to null to completely remove main vertical axis.
280    /// </summary>
281    /// <value>The main vertical axis.</value>
282    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
283    public GeneralAxis MainVerticalAxis
284    {
285      get { return verticalAxis; }
286      set
287      {
288        if (updatingAxis)
289          return;
290
291        if (value == null && verticalAxis != null)
292        {
293          if (!keepOldAxis)
294          {
295            Children.Remove(verticalAxis);
296          }
297          verticalAxis.TicksChanged -= OnVerticalAxisTicksChanged;
298          verticalAxis = null;
299
300          UpdateVerticalTicks(verticalAxis);
301
302          return;
303        }
304
305        VerifyAxisType(value.Placement, AxisType.Vertical);
306
307        if (value != verticalAxis)
308        {
309          ValidateVerticalAxis(value);
310
311          updatingAxis = true;
312
313          if (verticalAxis != null)
314          {
315            verticalAxis.TicksChanged -= OnVerticalAxisTicksChanged;
316            SetIsDefaultAxis(verticalAxis, false);
317            if (!keepOldAxis)
318            {
319              Children.Remove(verticalAxis);
320            }
321            value.Visibility = verticalAxis.Visibility;
322          }
323          SetIsDefaultAxis(value, true);
324
325          verticalAxis = value;
326          verticalAxis.TicksChanged += OnVerticalAxisTicksChanged;
327
328          if (!Children.Contains(value))
329          {
330            Children.Add(value);
331          }
332
333          UpdateVerticalTicks(value);
334          OnVerticalAxisChanged();
335
336          updatingAxis = false;
337        }
338      }
339    }
340
341    protected virtual void OnVerticalAxisChanged() { }
342    protected virtual void ValidateVerticalAxis(GeneralAxis axis) { }
343
344    /// <summary>
345    /// Gets or sets the main horizontal axis visibility.
346    /// </summary>
347    /// <value>The main horizontal axis visibility.</value>
348    public Visibility MainHorizontalAxisVisibility
349    {
350      get { return MainHorizontalAxis != null ? ((UIElement)MainHorizontalAxis).Visibility : Visibility.Hidden; }
351      set
352      {
353        if (MainHorizontalAxis != null)
354        {
355          ((UIElement)MainHorizontalAxis).Visibility = value;
356        }
357      }
358    }
359
360    /// <summary>
361    /// Gets or sets the main vertical axis visibility.
362    /// </summary>
363    /// <value>The main vertical axis visibility.</value>
364    public Visibility MainVerticalAxisVisibility
365    {
366      get { return MainVerticalAxis != null ? ((UIElement)MainVerticalAxis).Visibility : Visibility.Hidden; }
367      set
368      {
369        if (MainVerticalAxis != null)
370        {
371          ((UIElement)MainVerticalAxis).Visibility = value;
372        }
373      }
374    }
375
376    /// <summary>
377    /// Gets or sets the main horizontal axis of ChartPlotter.
378    /// Main horizontal axis of ChartPlotter is axis which ticks are used to draw vertical lines on AxisGrid.
379    /// Value can be set to null to completely remove main horizontal axis.
380    /// </summary>
381    /// <value>The main horizontal axis.</value>
382    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
383    public GeneralAxis MainHorizontalAxis
384    {
385      get { return horizontalAxis; }
386      set
387      {
388        if (updatingAxis)
389          return;
390
391        if (value == null && horizontalAxis != null)
392        {
393          Children.Remove(horizontalAxis);
394          horizontalAxis.TicksChanged -= OnHorizontalAxisTicksChanged;
395          horizontalAxis = null;
396
397          UpdateHorizontalTicks(horizontalAxis);
398
399          return;
400        }
401
402        VerifyAxisType(value.Placement, AxisType.Horizontal);
403
404        if (value != horizontalAxis)
405        {
406          ValidateHorizontalAxis(value);
407
408          updatingAxis = true;
409
410          if (horizontalAxis != null)
411          {
412            horizontalAxis.TicksChanged -= OnHorizontalAxisTicksChanged;
413            SetIsDefaultAxis(horizontalAxis, false);
414            if (!keepOldAxis)
415            {
416              Children.Remove(horizontalAxis);
417            }
418            value.Visibility = horizontalAxis.Visibility;
419          }
420          SetIsDefaultAxis(value, true);
421
422          horizontalAxis = value;
423          horizontalAxis.TicksChanged += OnHorizontalAxisTicksChanged;
424
425          if (!Children.Contains(value))
426          {
427            Children.Add(value);
428          }
429
430          UpdateHorizontalTicks(value);
431          OnHorizontalAxisChanged();
432
433          updatingAxis = false;
434        }
435      }
436    }
437
438    protected virtual void OnHorizontalAxisChanged() { }
439    protected virtual void ValidateHorizontalAxis(GeneralAxis axis) { }
440
441    private static void VerifyAxisType(AxisPlacement axisPlacement, AxisType axisType)
442    {
443      bool result = false;
444      switch (axisPlacement)
445      {
446        case AxisPlacement.Left:
447        case AxisPlacement.Right:
448          result = axisType == AxisType.Vertical;
449          break;
450        case AxisPlacement.Top:
451        case AxisPlacement.Bottom:
452          result = axisType == AxisType.Horizontal;
453          break;
454        default:
455          break;
456      }
457
458      if (!result)
459        throw new ArgumentException(Strings.Exceptions.InvalidAxisPlacement);
460    }
461
462    protected override void OnIsDefaultAxisChangedCore(DependencyObject d, DependencyPropertyChangedEventArgs e)
463    {
464      GeneralAxis axis = d as GeneralAxis;
465      if (axis != null)
466      {
467        bool value = (bool)e.NewValue;
468        bool oldKeepOldAxis = keepOldAxis;
469
470        bool horizontal = axis.Placement == AxisPlacement.Bottom || axis.Placement == AxisPlacement.Top;
471        keepOldAxis = true;
472
473        if (value && horizontal)
474        {
475          MainHorizontalAxis = axis;
476        }
477        else if (value && !horizontal)
478        {
479          MainVerticalAxis = axis;
480        }
481        else if (!value && horizontal)
482        {
483          MainHorizontalAxis = null;
484        }
485        else if (!value && !horizontal)
486        {
487          MainVerticalAxis = null;
488        }
489
490        keepOldAxis = oldKeepOldAxis;
491      }
492    }
493
494    /// <summary>
495    /// Gets the default legend of ChartPlotter.
496    /// </summary>
497    /// <value>The legend.</value>
498    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
499    public Legend Legend
500    {
501      get { return legend; }
502    }
503
504    /// <summary>
505    /// Gets or sets the visibility of legend.
506    /// </summary>
507    /// <value>The legend visibility.</value>
508    public Visibility LegendVisibility
509    {
510      get { return legend.Visibility; }
511      set { legend.Visibility = value; }
512    }
513
514    public bool LegendVisible
515    {
516      get { return legend.LegendVisible; }
517      set { legend.LegendVisible = value; }
518    }
519
520    private enum AxisType
521    {
522      Horizontal,
523      Vertical
524    }
525  }
526}
Note: See TracBrowser for help on using the repository browser.