Initial Commit

This commit is contained in:
2024-02-23 00:46:06 -05:00
commit 2bbedc0178
470 changed files with 46035 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
public class OldBarChart : MarkerChart
{
/// <summary>
/// Initializes a new instance of the <see cref="BarChart"/> class.
/// </summary>
public OldBarChart() { }
protected override void OnDataSourceChanged()
{
}
BarFromValueConverter converter = new BarFromValueConverter();
List<double> xValues = new List<double>();
protected override void OnMarkerBind(BindMarkerEventArgs e)
{
var marker = e.Marker;
//marker.SetBinding(ViewportRectPanel.ViewportVerticalAlignmentProperty, new Binding { Path = new PropertyPath("Value"), Converter = converter });
xValues.Add(ViewportPanel.GetX(marker));
}
protected override void RebuildMarkers(bool shouldReleaseMarkers)
{
xValues.Clear();
base.RebuildMarkers(shouldReleaseMarkers);
double width = 0;
for (int i = 0; i < xValues.Count - 1; i++)
{
double currX = xValues[i];
double nextX = xValues[i + 1];
width = (nextX - currX);
ViewportPanel.SetViewportWidth(ItemsPanel.Children[i], width);
}
if (ItemsPanel.Children.Count > 0)
{
ViewportPanel.SetViewportWidth(ItemsPanel.Children[ItemsPanel.Children.Count - 1], width);
}
}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
public class BarFromValueConverter : IValueConverter
{
/// <summary>
/// Initializes a new instance of the <see cref="BarFromValueConverter"/> class.
/// </summary>
public BarFromValueConverter() { }
public Brush PositiveBrush { get; set; }
public Brush NegativeBrush { get; set; }
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is double))
return DependencyProperty.UnsetValue;
double height = (double)value;
if (targetType == typeof(Brush))
{
if (height > 0)
return PositiveBrush;
else
return NegativeBrush;
}
else if (targetType == typeof(double))
{
return Math.Abs(height);
}
else if (targetType == typeof(VerticalAlignment))
{
return height > 0 ? VerticalAlignment.Bottom : VerticalAlignment.Top;
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
public sealed class BindMarkerEventArgs
{
internal BindMarkerEventArgs() { }
public FrameworkElement Marker { get; internal set; }
public object Data { get; internal set; }
}
}

View File

@@ -0,0 +1,286 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Research.DynamicDataDisplay.Common;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
public class MarkerChart : PlotterElement
{
/// <summary>
/// Initializes a new instance of the <see cref="MarkerChart"/> class.
/// </summary>
public MarkerChart()
{
Viewport2D.SetIsContentBoundsHost(this, true);
}
#region DataSource
private IEnumerable dataSource;
/// <summary>
/// Gets or sets the data source.
/// Value can be null.
/// </summary>
/// <value>The data source.</value>
public IEnumerable DataSource
{
get { return dataSource; }
set
{
DetachDataSource();
dataSource = value;
AttachDataSource();
OnDataSourceChanged();
RebuildMarkers(true);
}
}
protected virtual void OnDataSourceChanged() { }
protected virtual void RebuildMarkers(bool shouldReleaseMarkers)
{
if (markerGenerator == null)
return;
if (shouldReleaseMarkers)
{
foreach (FrameworkElement item in itemsPanel.Children)
{
var enumerator = item.GetLocalValueEnumerator();
while (enumerator.MoveNext())
{
item.ClearValue(enumerator.Current.Property);
}
descriptor.RemoveValueChanged(item, OnMarkerViewportBoundsChanged);
markerGenerator.ReleaseMarker(item);
}
}
itemsPanel.Children.Clear();
if (dataSource == null)
return;
IndividualArrangePanel specialPanel = itemsPanel as IndividualArrangePanel;
if (specialPanel != null)
specialPanel.BeginBatchAdd();
foreach (object item in dataSource)
{
var marker = CreateMarker(item);
itemsPanel.Children.Add(marker);
}
if (specialPanel != null)
specialPanel.EndBatchAdd();
RecalculateViewportBounds();
}
private FrameworkElement CreateMarker(object item)
{
var marker = markerGenerator.CreateMarker(item);
if (marker != null)
{
marker.DataContext = item;
AttachViewportChangedListener(marker);
BindMarkerEventArgs bindArgs = new BindMarkerEventArgs { Data = item, Marker = marker };
OnMarkerBind(bindArgs);
if (markerBindCallback != null)
{
markerBindCallback(bindArgs);
}
}
return marker;
}
protected virtual void OnMarkerBind(BindMarkerEventArgs e) { }
private Action<BindMarkerEventArgs> markerBindCallback = null;
public Action<BindMarkerEventArgs> MarkerBindCallback
{
get { return markerBindCallback; }
set
{
if (markerBindCallback != value)
{
markerBindCallback = value;
RebuildMarkers(false);
}
}
}
private void AttachDataSource()
{
INotifyCollectionChanged notifyingCollection = dataSource as INotifyCollectionChanged;
if (notifyingCollection != null)
{
notifyingCollection.CollectionChanged += OnDataSourceCollectionChanged;
}
}
private void OnDataSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
int index = e.OldStartingIndex;
foreach (object item in e.OldItems)
{
var oldMarker = itemsPanel.Children[index];
if (markerGenerator != null)
{
FrameworkElement element = (FrameworkElement)oldMarker;
// todo call cleanup callback here
markerGenerator.ReleaseMarker(element);
descriptor.RemoveValueChanged(element, OnMarkerViewportBoundsChanged);
}
itemsPanel.Children.RemoveAt(index);
}
}
if (e.NewItems != null)
{
int index = e.NewStartingIndex;
foreach (object item in e.NewItems)
{
var marker = CreateMarker(item);
itemsPanel.Children.Insert(index, marker);
index++;
}
}
RecalculateViewportBounds();
}
DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(ViewportPanel.ActualViewportBoundsProperty, typeof(FrameworkElement));
private void AttachViewportChangedListener(FrameworkElement element)
{
// todo or use this, or remove this
//descriptor.RemoveValueChanged(element, OnMarkerViewportBoundsChanged);
//descriptor.AddValueChanged(element, OnMarkerViewportBoundsChanged);
}
private Rect viewportBounds = Rect.Empty;
private void OnMarkerViewportBoundsChanged(object sender, EventArgs e)
{
RecalculateViewportBounds();
FrameworkElement element = (FrameworkElement)sender;
DataRect elementBounds = ViewportPanel.GetActualViewportBounds(element);
DataRect prevElementBounds = ViewportPanel.GetPrevActualViewportBounds(element);
}
private void RecalculateViewportBounds()
{
DataRect bounds = DataRect.Empty;
foreach (UIElement item in itemsPanel.Children)
{
DataRect elementBounds = ViewportPanel.GetActualViewportBounds(item);
bounds.Union(elementBounds);
}
Viewport2D.SetContentBounds(this, bounds);
}
private void DetachDataSource()
{
INotifyCollectionChanged notifyingCollection = dataSource as INotifyCollectionChanged;
if (notifyingCollection != null)
{
notifyingCollection.CollectionChanged -= OnDataSourceCollectionChanged;
}
}
#endregion
#region Marker
private OldMarkerGenerator markerGenerator;
public OldMarkerGenerator MarkerGenerator
{
get { return markerGenerator; }
set
{
if (value == null)
throw new ArgumentNullException("value");
if (markerGenerator != value)
{
DetachMarkerGenerator();
markerGenerator = value;
AttachMarkerGenerator();
RebuildMarkers(false);
}
}
}
private void AttachMarkerGenerator()
{
markerGenerator.Changed += OnMarkerChanged;
}
private void OnMarkerChanged(object sender, EventArgs e)
{
RebuildMarkers(false);
}
private void DetachMarkerGenerator()
{
if (markerGenerator != null)
{
markerGenerator.Changed -= OnMarkerChanged;
}
}
#endregion
#region Plotter attaching
private ViewportPanel itemsPanel = new ViewportPanel();
protected Panel ItemsPanel
{
get { return itemsPanel; }
}
private Plotter2D plotter;
protected override void OnPlotterAttached(Plotter plotter)
{
base.OnPlotterAttached(plotter);
this.plotter = (Plotter2D)plotter;
((IPlotterElement)itemsPanel).OnPlotterAttached(plotter);
}
protected override void OnPlotterDetaching(Plotter plotter)
{
((IPlotterElement)itemsPanel).OnPlotterDetaching(plotter);
this.plotter = null;
base.OnPlotterDetaching(plotter);
}
#endregion
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
public abstract class OldMarkerGenerator : DependencyObject
{
public FrameworkElement CreateMarker(object dataItem)
{
return CreateMarkerCore(dataItem);
}
protected abstract FrameworkElement CreateMarkerCore(object dataItem);
protected void RaiseChanged()
{
Changed.Raise(this);
}
public event EventHandler Changed;
public virtual void ReleaseMarker(FrameworkElement element) { }
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Research.DynamicDataDisplay.Common;
using System.Windows.Markup;
using System.Windows.Controls;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Markers
{
[ContentProperty("Template")]
public class TemplateMarkerGenerator2 : OldMarkerGenerator
{
private DataTemplate template;
[NotNull]
public DataTemplate Template
{
get { return template; }
set
{
if (value == null)
throw new ArgumentNullException("value");
if (template != value)
{
template = value;
pool.Clear();
RaiseChanged();
}
}
}
private readonly ResourcePool<FrameworkElement> pool = new ResourcePool<FrameworkElement>();
protected override FrameworkElement CreateMarkerCore(object dataItem)
{
if (template == null)
throw new InvalidOperationException(Strings.Exceptions.TemplateShouldNotBeNull);
FrameworkElement marker = pool.Get();
if (marker == null)
{
marker = (FrameworkElement)template.LoadContent();
}
return marker;
}
public override void ReleaseMarker(FrameworkElement element)
{
pool.Put(element);
}
}
}