/*
Copyright (C) 2008 Webyog Softworks Private Limited
This file is a part of Visifire Charts.
Visifire is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with Visifire Charts. If not, see .
If GPL is not suitable for your products or company, Webyog provides Visifire
under a flexible commercial license designed to meet your specific usage and
distribution requirements. If you have already obtained a commercial license
from Webyog, you can use this file under those license terms.
*/
#if WPF
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Markup;
using System.IO;
using System.Xml;
#else
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Browser;
#endif
using Visifire.Charts;
namespace Visifire.Commons
{
///
/// Visifire.Commons.Marker class
///
public class Marker : IComparable
{
#region Public Methods
///
/// Initializes a new instance of the Visifire.Commons.Marker class
///
public Marker(MarkerTypes markerType, Double scaleFactor, Size markerSize, Boolean markerBevel, Brush markerColor, String markerLabelText)
{
MarkerType = markerType;
MarkerFillColor = markerColor;
Text = markerLabelText;
TextOrientation = Orientation.Horizontal;
TextAlignmentX = AlignmentX.Right;
TextAlignmentY = AlignmentY.Center;
ScaleFactor = scaleFactor;
MarkerSize = markerSize;
BorderThickness = 1;
TextBackground = new SolidColorBrush(Colors.Transparent);
Bevel = markerBevel;
Opacity = 1;
LabelAngle = Double.NaN;
}
///
/// Initializes a new instance of the Visifire.Commons.Marker class
///
public Marker()
{
}
///
/// Compare two Markers
///
/// Object
/// int
public int CompareTo(Object o)
{
Marker dataPoint = (Marker)o;
return this.Position.X.CompareTo(dataPoint.Position.X);
}
///
/// Add elements to parent panel
///
/// ParentCanvas
/// x position value
/// y position value
/// AnchorPoint
public void AddToParent(Canvas parentCanvas, Double xPosition, Double yPosition, Point anchorPoint)
{
Position = new Point(xPosition, yPosition);
parentCanvas.Children.Add(Visual);
Double visualHeight;
Double visualWidth;
#if WPF
Visual.Measure(new Size(Double.MaxValue, Double.MaxValue));
visualHeight = Visual.DesiredSize.Height;
visualWidth = Visual.DesiredSize.Width;
#else
visualHeight = Visual.ActualHeight;
visualWidth = Visual.ActualWidth;
#endif
if (anchorPoint.X == 0.5)
xPosition -= (MarkerShape.Width / 2 + ((TextAlignmentX == AlignmentX.Left) ? _markerShapePosition.X : 0));
else if (anchorPoint.X == 1)
xPosition -= (MarkerShape.Width + ((TextAlignmentX == AlignmentX.Left) ? _markerShapePosition.X : 0));
if (anchorPoint.Y == 0.5)
yPosition -= (MarkerShape.Height / 2 + ((TextAlignmentY == AlignmentY.Top) ? _markerShapePosition.Y : 0));
else if (anchorPoint.Y == 1)
yPosition -= (MarkerShape.Height + ((TextAlignmentY == AlignmentY.Top) ? _markerShapePosition.Y : 0));
if (Double.IsNaN(LabelAngle))
{
if (TextAlignmentX == AlignmentX.Center)
if (TextBlockSize.Width > MarkerShape.Width)
xPosition -= (TextBlockSize.Width - MarkerShape.Width) / 2;
if (TextAlignmentY == AlignmentY.Center)
if (TextBlockSize.Height > MarkerShape.Height)
yPosition -= (TextBlockSize.Height - MarkerShape.Height) / 2;
}
Visual.SetValue(Canvas.TopProperty, yPosition);
Visual.SetValue(Canvas.LeftProperty, xPosition);
}
///
/// Add elements to parent panel
///
/// Panel
public void AddToParent(Panel parent)
{
parent.Children.Add(Visual);
}
///
/// Create visual for Marker
///
public void CreateVisual()
{
// Create Visual as Grid
Visual = new Grid();
// Create Shape for Marker
MarkerShape = GetShape();
if (MarkerShape != null)
MarkerShape.Tag = Tag;
MarkerShape.SetValue(Grid.RowProperty, 1);
MarkerShape.SetValue(Grid.ColumnProperty, 1);
if (ShadowEnabled)
{
MarkerShadow = GetShape();
if (MarkerShadow != null)
MarkerShadow.Tag = Tag;
// Set shadow properties
MarkerShadow.Fill = GetMarkerShadowColor();
TranslateTransform tt = new TranslateTransform() { X = 1, Y = 1 };
MarkerShadow.RenderTransform = tt;
// display or hide the shadow
//MarkerShadow.Visibility = (ShadowEnabled ? Visibility.Visible : Visibility.Collapsed);
// Set properties
MarkerShadow.SetValue(Grid.RowProperty, 1);
MarkerShadow.SetValue(Grid.ColumnProperty, 1);
// Add Shape for Marker into Visual
Visual.Children.Add(MarkerShadow);
}
Visual.Children.Add(MarkerShape);
UpdateMarker();
if (!String.IsNullOrEmpty(Text))
{
// Define row and columns
Visual.RowDefinitions.Add(new RowDefinition());
Visual.RowDefinitions.Add(new RowDefinition());
Visual.RowDefinitions.Add(new RowDefinition());
Visual.ColumnDefinitions.Add(new ColumnDefinition());
Visual.ColumnDefinitions.Add(new ColumnDefinition());
Visual.ColumnDefinitions.Add(new ColumnDefinition());
// Create TextBlock for Label of the Marker
TextBlock = new TextBlock() { Tag = this.Tag };
// Apply TextBlock Properties
ApplyTextBlockProperties();
if (!Double.IsNaN(LabelAngle))
{
// Create Canvas for TextBlock
LabelCanvas = new Canvas();
TextBackgroundCanvas = new Canvas();
TextBackgroundCanvas.Background = TextBackground;
TextBackgroundCanvas.Children.Add(TextBlock);
// Add TextBackgroundCanvas to LabelCanvas
LabelCanvas.Children.Add(TextBackgroundCanvas);
// Set Alignment
SetAlignment4Label();
if (TextAlignmentX == AlignmentX.Left)
{
LabelCanvas.SetValue(Grid.ColumnProperty, 0);
}
else if (TextAlignmentX == AlignmentX.Right)
{
LabelCanvas.SetValue(Grid.ColumnProperty, 2);
}
else
{
LabelCanvas.SetValue(Grid.ColumnProperty, 1);
LabelCanvas.HorizontalAlignment = HorizontalAlignment.Center;
}
if (TextAlignmentY == AlignmentY.Top)
{
LabelCanvas.SetValue(Grid.RowProperty, 0);
LabelCanvas.VerticalAlignment = VerticalAlignment.Top;
}
else if (TextAlignmentY == AlignmentY.Bottom)
{
LabelCanvas.SetValue(Grid.RowProperty, 2);
LabelCanvas.VerticalAlignment = VerticalAlignment.Top;
}
else
{
LabelCanvas.SetValue(Grid.RowProperty, 1);
LabelCanvas.VerticalAlignment = VerticalAlignment.Top;
}
// Add LabelCanvas into Visual
Visual.Children.Add(LabelCanvas);
}
else
{
if (TextBackground != null)
{
TextBackgroundCanvas = new Canvas();
TextBackgroundCanvas.Background = TextBackground;
Visual.Children.Add(TextBackgroundCanvas);
}
// Set Alignment
SetAlignment4Label();
Visual.Children.Add(TextBlock);
}
TextBlock.Margin = new Thickness(LabelMargin, 0, 0, 0);
Visual.Margin = new Thickness(Margin, Margin, Margin, Margin);
}
MarkerShape.Opacity = Opacity;
MarkerActualSize = Graphics.CalculateVisualSize(Visual);
}
///
/// Update Marker with new properties
///
public void UpdateMarker()
{
if (BevelLayer != null)
Visual.Children.Remove(BevelLayer);
if (Bevel)
{
BevelLayer = GetBevelLayer();
BevelLayer.IsHitTestVisible = false;
BevelLayer.SetValue(Grid.RowProperty, 1);
BevelLayer.SetValue(Grid.ColumnProperty, 1);
BevelLayer.SetValue(Grid.RowProperty, 1);
BevelLayer.SetValue(Grid.ColumnProperty, 1);
Visual.Children.Add(BevelLayer);
}
ApplyMarkerShapeProperties();
}
#endregion
#region Public Properties
///
/// Tag property
///
public Object Tag
{
get;
set;
}
///
/// Get or set the Marker Visual
///
public Grid Visual
{
get;
set;
}
///
/// Whether the Bevel effect is applied on Marker
///
public Boolean Bevel
{
get;
set;
}
///
/// Get or set scale factor of Marker symbol
///
public Double ScaleFactor
{
get
{
return _scaleFactor;
}
set
{
// System.Diagnostics.Debug.Assert(value < 1, "ScaleFactor can not be less than 1..");
if (value >= 1)
_scaleFactor = value;
}
}
///
/// Get or set padding for label of a Marker
///
public Double LabelPadding
{
get;
set;
}
///
/// Get or set Position of the Marker
///
public Point Position
{
get;
set;
}
///
/// Get or set the Actual Size of Marker
///
public Size MarkerSize
{
get;
set;
}
///
/// Get or set the Text orientation of Marker label
///
public Orientation TextOrientation
{
get;
set;
}
///
/// Get or set the HorizontalAlignment of Marker label
///
public AlignmentX TextAlignmentX
{
get
{
return _textAlignmentX;
}
set
{
_textAlignmentX = value;
}
}
///
/// Get or set the VerticalAlignment of Marker label
///
public AlignmentY TextAlignmentY
{
get
{
return _textAlignmentY;
}
set
{
_textAlignmentY = value;
}
}
///
/// Get or set the Shape type of a Marker
///
public MarkerTypes MarkerType
{
get;
set;
}
public Double Opacity
{
get;
set;
}
///
/// Get or set the Margin of Marker
///
public Double Margin
{
get;
set;
}
///
/// Get or set the LabelMargin of the label of Marker
///
public Double LabelMargin
{
get;
set;
}
#region Font Properties
///
/// Get or set the marker label FontFamily
///
public FontFamily FontFamily
{
get
{
if (_fontFamily == null)
return new FontFamily("Arial");
else
return _fontFamily;
}
set
{
_fontFamily = value;
}
}
///
/// Get or set the marker label FontSize
///
public Double FontSize
{
get
{
if (_fontSize == 0)
_fontSize = 10;
return _fontSize;
}
set
{
_fontSize = value;
}
}
///
/// Get or set the marker label FontColor
///
public Brush FontColor
{
get
{
return (_fontColor == null) ? (new SolidColorBrush(Colors.Black)) : _fontColor;
}
set
{
_fontColor = value;
}
}
///
/// Get or set the marker label FontStyle
///
public FontStyle FontStyle
{
get
{
return _fontStyle;
}
set
{
_fontStyle = value;
}
}
///
/// Get or set the marker label FontWeight
///
public FontWeight FontWeight
{
get
{
return _fontWeight;
}
set
{
_fontWeight = value;
}
}
///
/// Get or set the marker label Text
///
public String Text
{
get
{
return (_text == null) ? "" : _text;
}
set
{
_text = value;
}
}
///
/// Get or set the background of marker label text
///
public Brush TextBackground
{
get;
set;
}
#endregion
#region Border Properties
///
/// Get or set the BorderColor
///
public Brush BorderColor
{
get
{
if (_borderColor == null)
_borderColor = MarkerFillColor;
return _borderColor;
}
set
{
_borderColor = value;
}
}
///
/// Get or set the BorderThickness
///
public Double BorderThickness
{
get
{
return _borderThickness;
}
set
{
_borderThickness = value;
}
}
///
/// Get or set the Marker fill color
///
public Brush MarkerFillColor
{
get;
set;
}
#endregion
#endregion
#region Public Events And Delegates
#endregion
#region Protected Methods
#endregion
#region Internal Properties
///
/// Marker shape reference
///
internal Shape MarkerShape
{
get;
set;
}
///
/// BevelLayer of the Marker shape
///
internal FrameworkElement BevelLayer
{
get;
set;
}
internal Point MarkerPosition
{
get;
set;
}
///
/// MarkerShadow of the Marker shape
///
internal Shape MarkerShadow
{
get;
set;
}
///
/// Control reference
///
internal VisifireControl Control
{
get;
set;
}
///
/// TextBlock for Marker
///
internal TextBlock TextBlock
{
get;
set;
}
internal Canvas LabelCanvas
{
get;
set;
}
///
/// Angle for Marker labels
///
internal Double LabelAngle
{
get;
set;
}
internal LabelStyles LabelStyle
{
get;
set;
}
///
/// Actual Size of Marker
///
internal Size MarkerActualSize
{
get;
private set;
}
///
/// Size of the TextBlock
///
internal Size TextBlockSize
{
get;
set;
}
///
/// Background of the label of the Marker
///
internal Canvas TextBackgroundCanvas
{
get;
set;
}
///
/// This property applies only for Bubble and Point charts
///
internal bool ShadowEnabled
{
get;
set;
}
///
/// DataSeries used in Legend for line chart
///
internal DataSeries DataSeriesOfLegendMarker
{
get;
set;
}
#endregion
#region Private Properties
#endregion
#region Private Delegates
#endregion
#region Private Methods
///
/// Apply all style properties of the Marker text
///
private void ApplyMarkerShapeProperties()
{
// Set Border Properties
if (MarkerShape != null)
{
MarkerShape.Stroke = BorderColor;
MarkerShape.Fill = MarkerFillColor;
MarkerShape.StrokeThickness = BorderThickness;
MarkerShape.Height = MarkerSize.Height * ScaleFactor;
MarkerShape.Width = MarkerSize.Width * ScaleFactor;
if (MarkerShadow != null)
{
MarkerShadow.Height = MarkerSize.Height * ScaleFactor;
MarkerShadow.Width = MarkerSize.Width * ScaleFactor;
MarkerShadow.Stroke = null;
}
}
if (BevelLayer != null)
{
BevelLayer.Height = MarkerSize.Height * ScaleFactor;
BevelLayer.Width = MarkerSize.Width * ScaleFactor;
if ((BevelLayer as Shape) != null)
(BevelLayer as Shape).StrokeThickness = BorderThickness;
}
}
///
/// Apply all style properties of the Marker text
///
private void ApplyTextBlockProperties()
{
if (TextBlock != null)
{
// Set TextElement properties
#if WPF
TextBlock.FlowDirection = FlowDirection.LeftToRight;
#endif
TextBlock.FontFamily = FontFamily;
TextBlock.FontSize = FontSize;
TextBlock.FontStyle = FontStyle;
TextBlock.FontWeight = FontWeight;
TextBlock.Text = Text;
TextBlock.Foreground = FontColor;
TextBlock.VerticalAlignment = VerticalAlignment.Top;
}
}
///
/// Create shape for Marker
///
/// Shape
private Shape GetShape()
{
String xaml = null;
switch (MarkerType)
{
case MarkerTypes.Circle:
//Ellipse ellipse = new Ellipse() { Height = 6, Width = 6 };
//GradientStopCollection gsc = new GradientStopCollection();
//gsc.Add(new GradientStop() { Offset = 0, Color = Colors.White });
//gsc.Add(new GradientStop() { Offset = 1, Color = Colors.Gray });
//ellipse.Fill = new LinearGradientBrush() { GradientStops = gsc, StartPoint = new Point(0.5, 1), EndPoint = new Point(0.5, 0) };
//return ellipse;
return new Ellipse() { Height = 6, Width = 6, Stroke = new SolidColorBrush(Colors.Transparent) };
case MarkerTypes.Cross:
xaml = String.Format(@"");
break;
case MarkerTypes.Diamond:
xaml = String.Format(@"");
break;
case MarkerTypes.Square:
xaml = String.Format(@"");
break;
case MarkerTypes.Triangle:
xaml = String.Format(@"");
break;
case MarkerTypes.Line:
xaml = String.Format(@"");
break;
}
#if WPF
return (Shape)XamlReader.Load(new XmlTextReader(new StringReader(xaml)));
#else
return System.Windows.Markup.XamlReader.Load(xaml) as Shape;
#endif
}
///
/// Create shape for Marker
///
/// FrameworkElement
private FrameworkElement GetBevelLayer()
{
String xaml = null;
Brush topBrush = Graphics.GetBevelTopBrush(MarkerFillColor);
String color;
switch (MarkerType)
{
case MarkerTypes.Circle:
Ellipse ellipse = new Ellipse() { Height = 6, Width = 6 };
GradientStopCollection gsc = new GradientStopCollection();
gsc.Add(new GradientStop() { Offset = 0, Color = Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[1].Color, .8) });
gsc.Add(new GradientStop() { Offset = 0.6, Color = Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[1].Color, .8) });
gsc.Add(new GradientStop() { Offset = 0.8, Color = (topBrush as LinearGradientBrush).GradientStops[1].Color });
gsc.Add(new GradientStop() { Offset = 1, Color = (topBrush as LinearGradientBrush).GradientStops[1].Color });
ellipse.Fill = new LinearGradientBrush() { GradientStops = gsc, StartPoint = new Point(0.5, 1), EndPoint = new Point(0.5, 0) };
return ellipse;
case MarkerTypes.Cross:
topBrush = Graphics.GetBevelTopBrush(BorderColor);
color = (topBrush as LinearGradientBrush).GradientStops[2].Color.ToString();
xaml = String.Format(@"
", Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[2].Color, .8).ToString(), color);
break;
case MarkerTypes.Diamond:
color = (topBrush as LinearGradientBrush).GradientStops[2].Color.ToString();
xaml = String.Format(@"
", Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[2].Color, .8).ToString(), color);
break;
case MarkerTypes.Square:
Double height = MarkerSize.Height * ScaleFactor;
Double width = MarkerSize.Width * ScaleFactor;
Canvas bevelCanvas = Visifire.Charts.ExtendedGraphics.Get2DRectangleBevel(this.Tag as FrameworkElement, width, height,
3, 3,
topBrush,
Graphics.GetBevelSideBrush(0, MarkerFillColor),
Graphics.GetBevelSideBrush(120, MarkerFillColor),
Graphics.GetBevelSideBrush(100, MarkerFillColor)
);
return bevelCanvas;
case MarkerTypes.Triangle:
color = (topBrush as LinearGradientBrush).GradientStops[1].Color.ToString();
xaml = String.Format(@"
", Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[1].Color, .8).ToString(), color);
break;
case MarkerTypes.Line:
color = (topBrush as LinearGradientBrush).GradientStops[1].Color.ToString();
xaml = String.Format(@"
", Graphics.GetDarkerColor((topBrush as LinearGradientBrush).GradientStops[1].Color, .8).ToString(), color);
break;
}
#if WPF
return (Shape)XamlReader.Load(new XmlTextReader(new StringReader(xaml)));
#else
return System.Windows.Markup.XamlReader.Load(xaml) as Shape;
#endif
}
///
/// Sets values for rotate transform
///
/// Ref RotateTransform
/// CenterX
/// CenterY
/// Angle
private void SetRotateTransformValues(ref RotateTransform rotateTransform, Double centerX, Double centerY, Double angle)
{
rotateTransform.CenterX = centerX;
rotateTransform.CenterY = centerY;
rotateTransform.Angle = angle;
}
private void SetRotation(Double radius, Double angle, Double angleInRadian, Point centerOfRotation)
{
Double left = centerOfRotation.X + radius * Math.Cos(angleInRadian);
Double top = centerOfRotation.Y + radius * Math.Sin(angleInRadian);
top -= TextBlockSize.Height / 2;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Canvas.LeftProperty, left);
TextBackgroundCanvas.SetValue(Canvas.TopProperty, top);
TextBackgroundCanvas.Width = TextBlockSize.Width;
TextBackgroundCanvas.Height = TextBlockSize.Height;
TextBlock.SetValue(Canvas.TopProperty, -(Double)2);
TextBackgroundCanvas.RenderTransformOrigin = new Point(0, 0.5);
TextBackgroundCanvas.RenderTransform = new RotateTransform()
{
CenterX = 0,
CenterY = 0,
Angle = angle
};
}
}
///
/// Set alignment for the Marker label
///
private void SetAlignment4Label()
{
if (TextBlock != null)
{
#if WPF
TextBlockSize = Graphics.CalculateVisualSize(TextBlock);
#else
TextBlockSize = new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);
#endif
if (TextOrientation == Orientation.Vertical)
{
TransformGroup tg = new TransformGroup();
RotateTransform rt = new RotateTransform();
TranslateTransform tt = new TranslateTransform();
tg.Children.Add(rt);
tg.Children.Add(tt);
switch (TextAlignmentY)
{
case AlignmentY.Top:
switch (TextAlignmentX)
{
case AlignmentX.Left:
TextBlock.RenderTransformOrigin = new Point(0, 1);
SetRotateTransformValues(ref rt, 0, 0, -90);
tt.X = TextBlockSize.Width;
break;
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, TextBlockSize.Width / 2, TextBlockSize.Height / 2, -90);
tt.Y = -TextBlockSize.Width / 2 + TextBlockSize.Height / 2 - 5;
tt.X = -1;
}
else
{
Point centerOfRotation = new Point(Position.X, Position.Y);
Double radius = MarkerSize.Height / 2 * ScaleFactor;
Double angle = 0;
Double angleInRadian = 0;
if (LabelStyle == LabelStyles.OutSide)
{
if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
else
{
centerOfRotation = new Point(Position.X, Position.Y + MarkerSize.Height / 2);
if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = 180 + LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle > 0 && LabelAngle <= 90)
{
radius += 3;
angle = LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
}
break;
case AlignmentX.Right:
TextBlock.RenderTransformOrigin = new Point(0, 1);
SetRotateTransformValues(ref rt, 0, 0, -90);
tt.X = TextBlockSize.Height;
break;
}
break;
case AlignmentY.Center:
switch (TextAlignmentX)
{
case AlignmentX.Left:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, TextBlockSize.Width, TextBlockSize.Height / 2, 90);
tt.Y = TextBlockSize.Width / 2;
tt.X = -TextBlockSize.Height / 2;
}
else
{
Point centerOfRotation = new Point(Position.X + MarkerSize.Width / 2, Position.Y + MarkerSize.Height / 2);
Double radius = MarkerSize.Width / 2 * ScaleFactor;
Double angle = 0;
Double angleInRadian = 0;
if (LabelStyle == LabelStyles.OutSide)
{
if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
else
{
if (LabelAngle <= 90 && LabelAngle >= -90)
{
angle = LabelAngle;
radius += 3;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
}
break;
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
TextBlock.RenderTransformOrigin = new Point(0.5, 0.5);
rt.Angle = 90;
}
else
{
Point centerOfRotation = new Point(Position.X, Position.Y + MarkerShape.Height / 2);
Double radius = 4;
Double angle = 0;
Double angleInRadian = 0;
if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
break;
case AlignmentX.Right:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, TextBlockSize.Height / 2, -90);
tt.Y = TextBlockSize.Width / 2;
tt.X = TextBlockSize.Height / 2;
}
else
{
Point centerOfRotation = new Point(Position.X - MarkerSize.Width / 2, Position.Y + MarkerSize.Height / 2);
Double radius = MarkerSize.Width / 2 * ScaleFactor;
Double angle = 0;
Double angleInRadian = 0;
if (LabelStyle == LabelStyles.OutSide)
{
if (LabelAngle <= 90 && LabelAngle >= -90)
{
angle = LabelAngle;
radius += 3;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
else
{
if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
}
break;
}
break;
case AlignmentY.Bottom:
switch (TextAlignmentX)
{
case AlignmentX.Left:
SetRotateTransformValues(ref rt, TextBlockSize.Width / 2, TextBlockSize.Height / 2, -90);
tt.Y = TextBlockSize.Width / 2 - TextBlockSize.Height / 2;
tt.X = TextBlockSize.Width / 2 - TextBlockSize.Height / 2;
break;
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, TextBlockSize.Width / 2, TextBlockSize.Height / 2, -90);
//tt.Y = TextBlockSize.Height + MarkerSize.Height * ScaleFactor;
tt.Y = TextBlockSize.Width / 2;
tt.X = -1;
}
else
{
Point centerOfRotation = new Point();
Double radius = MarkerSize.Height / 2 * ScaleFactor;
Double angle = 0;
Double angleInRadian = 0;
if (LabelStyle == LabelStyles.OutSide)
{
centerOfRotation = new Point(Position.X, Position.Y);
if (LabelAngle >= -90 && LabelAngle < 0)
{
angle = 180 + LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
else
{
centerOfRotation = new Point(Position.X, Position.Y - MarkerSize.Height / 2);
if (LabelAngle > 0 && LabelAngle <= 90)
{
angle = LabelAngle - 180;
angleInRadian = (Math.PI / 180) * angle;
radius += TextBlockSize.Width + 3;
angle = (angleInRadian - Math.PI) * (180 / Math.PI);
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
else if (LabelAngle >= -90 && LabelAngle < 0)
{
radius += 3;
angle = LabelAngle;
angleInRadian = (Math.PI / 180) * angle;
SetRotation(radius, angle, angleInRadian, centerOfRotation);
}
}
}
break;
case AlignmentX.Right:
SetRotateTransformValues(ref rt, 0, 0, -90);
tt.Y = TextBlockSize.Width;
break;
}
break;
}
if (Double.IsNaN(LabelAngle))
{
TextBlock.RenderTransform = tg;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.RenderTransformOrigin = TextBlock.RenderTransformOrigin;
TextBackgroundCanvas.RenderTransform = tg;
TextBackgroundCanvas.Height = TextBlockSize.Height;
TextBackgroundCanvas.Width = TextBlockSize.Width;
}
}
}
else
{
if (DataSeriesOfLegendMarker == null)
{
TransformGroup tg = new TransformGroup();
RotateTransform rt = new RotateTransform();
TranslateTransform tt = new TranslateTransform();
tg.Children.Add(rt);
tg.Children.Add(tt);
switch (TextAlignmentY)
{
case AlignmentY.Top:
switch (TextAlignmentX)
{
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, 0, 0);
tt.Y = -3;
}
break;
}
break;
case AlignmentY.Bottom:
switch (TextAlignmentX)
{
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, 0, 0);
tt.Y = 1;
}
break;
}
break;
case AlignmentY.Center:
switch (TextAlignmentX)
{
case AlignmentX.Left:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, 0, 0);
tt.X = -5;
tt.Y = -1;
}
break;
case AlignmentX.Center:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, 0, 0);
tt.Y = -1;
}
break;
case AlignmentX.Right:
if (Double.IsNaN(LabelAngle))
{
SetRotateTransformValues(ref rt, 0, 0, 0);
tt.X = 4;
tt.Y = -1;
}
break;
}
break;
}
if (Double.IsNaN(LabelAngle))
{
TextBlock.RenderTransform = tg;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.RenderTransformOrigin = TextBlock.RenderTransformOrigin;
TextBackgroundCanvas.RenderTransform = tg;
TextBackgroundCanvas.Height = TextBlockSize.Height;
TextBackgroundCanvas.Width = TextBlockSize.Width;
}
}
}
}
SetLabelBackgroundAndSymbolPosition();
}
}
///
/// Set background of label and position of symbol
///
private void SetLabelBackgroundAndSymbolPosition()
{
if (Double.IsNaN(LabelAngle))
{
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.Height = TextBlockSize.Height;
TextBackgroundCanvas.Width = TextBlockSize.Width;
}
if (TextAlignmentX == AlignmentX.Left)
{
TextBlock.SetValue(Grid.ColumnProperty, 0);
_markerShapePosition.X = TextBlockSize.Width;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.ColumnProperty, 0);
}
}
else if (TextAlignmentX == AlignmentX.Right)
{
TextBlock.SetValue(Grid.ColumnProperty, 2);
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.ColumnProperty, 2);
}
}
else
{
TextBlock.SetValue(Grid.ColumnProperty, 1);
TextBlock.HorizontalAlignment = HorizontalAlignment.Center;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.ColumnProperty, 1);
TextBackgroundCanvas.HorizontalAlignment = HorizontalAlignment.Center;
}
}
if (TextAlignmentY == AlignmentY.Top)
{
TextBlock.SetValue(Grid.RowProperty, 0);
_markerShapePosition.Y = TextBlockSize.Height;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.RowProperty, 0);
}
}
else if (TextAlignmentY == AlignmentY.Bottom)
{
TextBlock.SetValue(Grid.RowProperty, 2);
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.RowProperty, 2);
}
}
else
{
TextBlock.SetValue(Grid.RowProperty, 1);
TextBlock.VerticalAlignment = VerticalAlignment.Center;
if (TextBackgroundCanvas != null)
{
TextBackgroundCanvas.SetValue(Grid.RowProperty, 1);
TextBackgroundCanvas.VerticalAlignment = VerticalAlignment.Center;
}
}
}
if (TextAlignmentX == AlignmentX.Center)
_markerShapePosition.X += Math.Abs((TextBlockSize.Width - MarkerShape.Width) / 2);
if (TextAlignmentY == AlignmentY.Center)
_markerShapePosition.Y += Math.Abs((TextBlockSize.Height - MarkerShape.Height) / 2);
}
///
/// Get shadow color of the Marker shape
///
///
private Brush GetMarkerShadowColor()
{
// String xaml = String.Format(@"
//
//
// ");
LinearGradientBrush brush = new LinearGradientBrush();
brush.StartPoint = new Point(0.497000008821487, 1.00100004673004);
brush.EndPoint = new Point(0.503000020980835, -0.00100000004749745);
brush.GradientStops.Add(new GradientStop() { Color = Color.FromArgb(180, 108, 108, 108), Offset = 1 });
brush.GradientStops.Add(new GradientStop() { Color = Color.FromArgb(00, 255, 255, 255), Offset = 1 });
return brush;
#if WPF
//return (Brush)XamlReader.Load(new XmlTextReader(new StringReader(xaml)));
#else
//return System.Windows.Markup.XamlReader.Load(xaml) as Brush;
#endif
}
#endregion
#region Internal Methods
#endregion
#region Internal Events And Delegates
#endregion
#region Data
///
/// The identifier for property FontSize
///
private Double _fontSize;
///
/// The identifier for property FontFamily
///
private FontFamily _fontFamily;
///
/// The identifier for property FontStyle
///
private FontStyle _fontStyle;
///
/// The identifier for property FontWeight
///
private FontWeight _fontWeight;
///
/// The identifier for property FontColor
///
private Brush _fontColor;
///
/// The identifier for property BorderThickness
///
private Double _borderThickness;
///
/// The identifier for property BorderColor
///
private Brush _borderColor;
///
/// HorizontalAlignment of Marker label
///
private AlignmentX _textAlignmentX;
///
/// VerticalAlignment of Marker label
///
private AlignmentY _textAlignmentY;
///
/// The identifier for property Text
///
private String _text;
///
/// The identifier for ScaleFactor property
///
private Double _scaleFactor = 1;
///
/// Actual position of the Marker shape inside Marker grid
///
private Point _markerShapePosition;
#endregion
}
}