using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Microsoft.Research.DynamicDataDisplay.Common;
using System.Windows.Data;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Media;
using System.ComponentModel;
namespace Microsoft.Research.DynamicDataDisplay
{
///
/// Represents a nested plotter, which can control the way how its children are drawn in dependency of parent ChartPlotter Visible rect.
/// This plotter is designed to work inside of some other plotter.
///
/// There are 8 properties (ParentXMin, SelfXMin, etc) which can be used to tune the size and position of inner plotter
/// in dependence on parent Plotter's Visible rect.
/// For example, you can specify that when parent x coordinates are from 0.0 to 1.0, inner plotter's visible x coordinates are
/// from -1.0 to 2.0. This data will be used to calculate next positions of inner plotter's children charts.
///
///
[SkipPropertyCheck]
public class InjectedPlotter : InjectedPlotterBase, IPlotterElement
{
private double xScale = 1.0;
private double xShift = 0.0;
private double yScale = 1.0;
private double yShift = 0.0;
///
/// Initializes a new instance of the class.
///
public InjectedPlotter() : base() { }
protected override DataRect CoerceVisible(DataRect newVisible, DataRect baseVisible)
{
DataRect result = newVisible;
if (Plotter == null)
return baseVisible;
DataRect outerVisible = Plotter.Viewport.Visible;
double xMin = outerVisible.XMin * xScale + xShift;
double xMax = outerVisible.XMax * xScale + xShift;
double yMin = outerVisible.YMin * yScale + yShift;
double yMax = outerVisible.YMax * yScale + yShift;
outerVisible = DataRect.Create(xMin, yMin, xMax, yMax);
switch (ConjunctionMode)
{
case ViewportConjunctionMode.None:
result = baseVisible;
break;
case ViewportConjunctionMode.X:
result = new DataRect(outerVisible.XMin, baseVisible.YMin, outerVisible.Width, baseVisible.Height);
break;
case ViewportConjunctionMode.Y:
result = new DataRect(baseVisible.XMin, outerVisible.YMin, baseVisible.Width, outerVisible.Height);
break;
case ViewportConjunctionMode.XY:
result = outerVisible;
break;
default:
break;
}
return result;
}
private void UpdateTransform()
{
xScale = (SelfXMax - SelfXMin) / (ParentXMax - ParentXMin);
xShift = SelfXMin - ParentXMin;
yScale = (SelfYMax - SelfYMin) / (ParentYMax - ParentYMin);
yShift = SelfYMin - ParentYMin;
}
protected override void OnConjunctionModeChanged()
{
CoerceVisible();
}
#region Properties
#region Conversion properties
public double ParentXMin
{
get { return (double)GetValue(ParentXMinProperty); }
set { SetValue(ParentXMinProperty, value); }
}
public static readonly DependencyProperty ParentXMinProperty = DependencyProperty.Register(
"ParentXMin",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(0.0, OnTransformChanged));
public double ParentXMax
{
get { return (double)GetValue(ParentXMaxProperty); }
set { SetValue(ParentXMaxProperty, value); }
}
public static readonly DependencyProperty ParentXMaxProperty = DependencyProperty.Register(
"ParentXMax",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(1.0, OnTransformChanged));
public double SelfXMin
{
get { return (double)GetValue(SelfXMinProperty); }
set { SetValue(SelfXMinProperty, value); }
}
public static readonly DependencyProperty SelfXMinProperty = DependencyProperty.Register(
"SelfXMin",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(0.0, OnTransformChanged));
public double SelfXMax
{
get { return (double)GetValue(SelfXMaxProperty); }
set { SetValue(SelfXMaxProperty, value); }
}
public static readonly DependencyProperty SelfXMaxProperty = DependencyProperty.Register(
"SelfXMax",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(1.0, OnTransformChanged));
public double ParentYMin
{
get { return (double)GetValue(ParentYMinProperty); }
set { SetValue(ParentYMinProperty, value); }
}
public static readonly DependencyProperty ParentYMinProperty = DependencyProperty.Register(
"ParentYMin",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(0.0, OnTransformChanged));
public double ParentYMax
{
get { return (double)GetValue(ParentYMaxProperty); }
set { SetValue(ParentYMaxProperty, value); }
}
public static readonly DependencyProperty ParentYMaxProperty = DependencyProperty.Register(
"ParentYMax",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(1.0, OnTransformChanged));
public double SelfYMin
{
get { return (double)GetValue(SelfYMinProperty); }
set { SetValue(SelfYMinProperty, value); }
}
public static readonly DependencyProperty SelfYMinProperty = DependencyProperty.Register(
"SelfYMin",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(0.0, OnTransformChanged));
public double SelfYMax
{
get { return (double)GetValue(SelfYMaxProperty); }
set { SetValue(SelfYMaxProperty, value); }
}
public static readonly DependencyProperty SelfYMaxProperty = DependencyProperty.Register(
"SelfYMax",
typeof(double),
typeof(InjectedPlotter),
new FrameworkPropertyMetadata(1.0, OnTransformChanged));
private static void OnTransformChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
InjectedPlotter plotter = (InjectedPlotter)d;
plotter.UpdateTransform();
}
#endregion
#endregion
}
}