This commit is contained in:
2024-02-23 09:29:44 -05:00
parent 2bbedc0178
commit 0038248f33
398 changed files with 39074 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
using System.Threading;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Renders specified text near the point</summary>
public class CenteredTextMarker : PointMarker
{
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(CenteredTextMarker),
new FrameworkPropertyMetadata(""));
public override void Render(DrawingContext dc, Point screenPoint)
{
FormattedText textToDraw = new FormattedText(Text, Thread.CurrentThread.CurrentCulture,
FlowDirection.LeftToRight, new Typeface("Arial"), 12, Brushes.Black);
double width = textToDraw.Width;
double height = textToDraw.Height;
const double verticalShift = -20; // px
Rect bounds = RectExtensions.FromCenterSize(new Point(screenPoint.X, screenPoint.Y + verticalShift - height / 2),
new Size(width, height));
Point loc = bounds.Location;
bounds = CoordinateUtilities.RectZoom(bounds, 1.05, 1.15);
dc.DrawLine(new Pen(Brushes.Black, 1), Point.Add(screenPoint, new Vector(0, verticalShift)), screenPoint);
dc.DrawRectangle(Brushes.White, new Pen(Brushes.Black, 1), bounds);
dc.DrawText(textToDraw, loc);
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Adds Circle element at every point of graph</summary>
public class CircleElementPointMarker : ShapeElementPointMarker {
public override UIElement CreateMarker()
{
Ellipse result = new Ellipse();
result.Width = Size;
result.Height = Size;
result.Stroke = Brush;
result.Fill = Fill;
if (!String.IsNullOrEmpty(ToolTipText))
{
ToolTip tt = new ToolTip();
tt.Content = ToolTipText;
result.ToolTip = tt;
}
return result;
}
public override void SetMarkerProperties(UIElement marker)
{
Ellipse ellipse = (Ellipse)marker;
ellipse.Width = Size;
ellipse.Height = Size;
ellipse.Stroke = Brush;
ellipse.Fill = Fill;
if (!String.IsNullOrEmpty(ToolTipText))
{
ToolTip tt = new ToolTip();
tt.Content = ToolTipText;
ellipse.ToolTip = tt;
}
}
public override void SetPosition(UIElement marker, Point screenPoint)
{
Canvas.SetLeft(marker, screenPoint.X - Size / 2);
Canvas.SetTop(marker, screenPoint.Y - Size / 2);
}
}
}

View File

@@ -0,0 +1,14 @@
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Renders circle around each point of graph</summary>
public class CirclePointMarker : ShapePointMarker {
public override void Render(DrawingContext dc, Point screenPoint) {
dc.DrawEllipse(Fill, Pen, screenPoint, Size / 2, Size / 2);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Composite point markers renders a specified set of markers
/// at every point of graph</summary>
public sealed class CompositePointMarker : PointMarker {
public CompositePointMarker() { }
public CompositePointMarker(params PointMarker[] markers) {
if (markers == null)
throw new ArgumentNullException("markers");
foreach (PointMarker m in markers)
this.markers.Add(m);
}
public CompositePointMarker(IEnumerable<PointMarker> markers) {
if (markers == null)
throw new ArgumentNullException("markers");
foreach (PointMarker m in markers)
this.markers.Add(m);
}
private readonly Collection<PointMarker> markers = new Collection<PointMarker>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<PointMarker> Markers {
get { return markers; }
}
public override void Render(DrawingContext dc, Point screenPoint) {
LocalValueEnumerator enumerator = GetLocalValueEnumerator();
foreach (var marker in markers) {
enumerator.Reset();
while (enumerator.MoveNext()) {
marker.SetValue(enumerator.Current.Property, enumerator.Current.Value);
}
marker.Render(dc, screenPoint);
}
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Invokes specified delegate for rendering custon marker
/// at every point of graph</summary>
public sealed class DelegatePointMarker : PointMarker {
public MarkerRenderHandler RenderCallback { get; set; }
public DelegatePointMarker() { }
public DelegatePointMarker(MarkerRenderHandler renderCallback) {
if (renderCallback == null)
throw new ArgumentNullException("renderCallback");
RenderCallback = renderCallback;
}
public override void Render(DrawingContext dc, Point screenPoint) {
RenderCallback(dc, screenPoint);
}
}
}

View File

@@ -0,0 +1,19 @@
using System.Windows;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Provides elements that represent markers along the graph</summary>
public abstract class ElementPointMarker : DependencyObject {
/// <summary>Creates marker element at specified point</summary>
/// <returns>UIElement representing marker</returns>
public abstract UIElement CreateMarker();
public abstract void SetMarkerProperties(UIElement marker);
/// <summary>Moves specified marker so its center is located at specified screen point</summary>
/// <param name="marker">UIElement created using CreateMarker</param>
/// <param name="screenPoint">Point to center element around</param>
public abstract void SetPosition(UIElement marker, Point screenPoint);
}
}

View File

@@ -0,0 +1,26 @@
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
public delegate void MarkerRenderHandler(DrawingContext dc, Point screenPoint);
/// <summary>Renders markers along graph</summary>
public abstract class PointMarker : DependencyObject {
/// <summary>Renders marker on screen</summary>
/// <param name="dc">Drawing context to render marker on</param>
/// <param name="dataPoint">Point from data source</param>
/// <param name="screenPoint">Marker center coordinates on drawing context</param>
public abstract void Render(DrawingContext dc, Point screenPoint);
public static implicit operator PointMarker(MarkerRenderHandler renderer) {
return FromRenderer(renderer);
}
public static PointMarker FromRenderer(MarkerRenderHandler renderer)
{
return new DelegatePointMarker(renderer);
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Adds Circle element at every point of graph</summary>
public class RectElementPointMarker : ShapeElementPointMarker {
public override UIElement CreateMarker()
{
Rectangle result = new Rectangle();
result.Width = Size;
result.Height = Size;
result.Stroke = Brush;
result.Fill = Fill;
if (!String.IsNullOrEmpty(ToolTipText))
{
ToolTip tt = new ToolTip();
tt.Content = ToolTipText;
result.ToolTip = tt;
}
return result;
}
public override void SetMarkerProperties(UIElement marker)
{
Rectangle rect = (Rectangle)marker;
rect.Width = Size;
rect.Height = Size;
rect.Stroke = Brush;
rect.Fill = Fill;
if (!String.IsNullOrEmpty(ToolTipText))
{
ToolTip tt = new ToolTip();
tt.Content = ToolTipText;
rect.ToolTip = tt;
}
}
public override void SetPosition(UIElement marker, Point screenPoint)
{
Canvas.SetLeft(marker, screenPoint.X - Size / 2);
Canvas.SetTop(marker, screenPoint.Y - Size / 2);
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Abstract class that extends ElementPointMarker and contains
/// marker property as Pen, Brush and Size</summary>
public abstract class ShapeElementPointMarker : ElementPointMarker {
/// <summary>Size of marker in points</summary>
public double Size {
get { return (double)GetValue(SizeProperty); }
set { SetValue(SizeProperty, value); }
}
public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register(
"Size",
typeof(double),
typeof(ShapeElementPointMarker),
new FrameworkPropertyMetadata(5.0));
/// <summary>Tooltip to show when cursor on over</summary>
public string ToolTipText
{
get { return (string)GetValue(ToolTipTextProperty); }
set { SetValue(ToolTipTextProperty, value); }
}
public static readonly DependencyProperty ToolTipTextProperty =
DependencyProperty.Register(
"ToolTipText",
typeof(string),
typeof(ShapeElementPointMarker),
new FrameworkPropertyMetadata(String.Empty));
/// <summary>Pen to outline marker</summary>
public Pen Pen {
get { return (Pen)GetValue(PenProperty); }
set { SetValue(PenProperty, value); }
}
public static readonly DependencyProperty PenProperty =
DependencyProperty.Register(
"Pen",
typeof(Pen),
typeof(ShapeElementPointMarker),
new FrameworkPropertyMetadata(null));
public Brush Brush {
get { return (Brush)GetValue(BrushProperty); }
set { SetValue(BrushProperty, value); }
}
public static readonly DependencyProperty BrushProperty =
DependencyProperty.Register(
"Brush",
typeof(Brush),
typeof(ShapeElementPointMarker),
new FrameworkPropertyMetadata(Brushes.Red));
public Brush Fill
{
get { return (Brush)GetValue(FillProperty); }
set { SetValue(FillProperty, value); }
}
public static readonly DependencyProperty FillProperty =
DependencyProperty.Register(
"Fill",
typeof(Brush),
typeof(ShapeElementPointMarker),
new FrameworkPropertyMetadata(Brushes.Red));
}
}

View File

@@ -0,0 +1,49 @@
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Abstract class that extends PointMarker and contains
/// marker property as Pen, Brush and Size</summary>
public abstract class ShapePointMarker : PointMarker {
/// <summary>Size of marker in points</summary>
public double Size {
get { return (double)GetValue(SizeProperty); }
set { SetValue(SizeProperty, value); }
}
public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register(
"Size",
typeof(double),
typeof(ShapePointMarker),
new FrameworkPropertyMetadata(5.0));
/// <summary>Pen to outline marker</summary>
public Pen Pen {
get { return (Pen)GetValue(PenProperty); }
set { SetValue(PenProperty, value); }
}
public static readonly DependencyProperty PenProperty =
DependencyProperty.Register(
"Pen",
typeof(Pen),
typeof(ShapePointMarker),
new FrameworkPropertyMetadata(null));
public Brush Fill {
get { return (Brush)GetValue(FillProperty); }
set { SetValue(FillProperty, value); }
}
public static readonly DependencyProperty FillProperty =
DependencyProperty.Register(
"Fill",
typeof(Brush),
typeof(ShapePointMarker),
new FrameworkPropertyMetadata(Brushes.Red));
}
}

View File

@@ -0,0 +1,22 @@
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.PointMarkers
{
/// <summary>Class that renders triangular marker at every point of graph</summary>
public class TrianglePointMarker : ShapePointMarker {
public override void Render(DrawingContext dc, Point screenPoint) {
Point pt0 = Point.Add(screenPoint, new Vector(-Size / 2, -Size / 2));
Point pt1 = Point.Add(screenPoint, new Vector(0, Size / 2));
Point pt2 = Point.Add(screenPoint, new Vector(Size / 2, -Size / 2));
StreamGeometry streamGeom = new StreamGeometry();
using (var context = streamGeom.Open()) {
context.BeginFigure(pt0, true, true);
context.LineTo(pt1, true, true);
context.LineTo(pt2, true, true);
}
dc.DrawGeometry(Fill, Pen, streamGeom);
}
}
}