# HG changeset patch
# User moel.mich
# Date 1370710402 0
# Node ID 5be8f27732373b285e7a9452b6bb5f08e44f65df
# Parent 88d699a65cc2c1e571d455ea20b0dcc1ecc86b06
Added the source code of OxyPlot as of commit d190d7748a73 (6.5.2013).
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/GlobalAssemblyInfo.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/GlobalAssemblyInfo.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//-----------------------------------------------------------------------
+
+using System.Reflection;
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("OxyPlot")]
+[assembly: AssemblyCompany("OxyPlot")]
+[assembly: AssemblyCopyright("Copyright (C) OxyPlot 2012.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: AssemblyVersion("2013.1.1.1")]
+[assembly: AssemblyFileVersion("2013.1.1.1")]
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/GraphicsRenderContext.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/GraphicsRenderContext.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,558 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The graphics render context.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.WindowsForms
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Drawing;
+ using System.Drawing.Drawing2D;
+ using System.Drawing.Imaging;
+ using System.IO;
+ using System.Linq;
+
+ using OxyPlot;
+
+ ///
+ /// The graphics render context.
+ ///
+ internal class GraphicsRenderContext : RenderContextBase
+ {
+ ///
+ /// The font size factor.
+ ///
+ private const float FontsizeFactor = 0.8f;
+
+ ///
+ /// The GDI+ drawing surface.
+ ///
+ private Graphics g;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GraphicsRenderContext()
+ {
+ }
+
+ ///
+ /// Sets the graphics target.
+ ///
+ /// The graphics surface.
+ public void SetGraphicsTarget(Graphics graphics)
+ {
+ this.g = graphics;
+ }
+
+ ///
+ /// Draws the ellipse.
+ ///
+ /// The rect.
+ /// The fill.
+ /// The stroke.
+ /// The thickness.
+ public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
+ {
+ if (fill != null)
+ {
+ this.g.FillEllipse(
+ this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
+ }
+
+ if (stroke == null || thickness <= 0)
+ {
+ return;
+ }
+
+ using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
+ {
+ this.g.SmoothingMode = SmoothingMode.HighQuality;
+ this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
+ }
+ }
+
+ ///
+ /// Draws the line.
+ ///
+ /// The points.
+ /// The stroke.
+ /// The thickness.
+ /// The dash array.
+ /// The line join.
+ /// if set to true [aliased].
+ public override void DrawLine(
+ IList points,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased)
+ {
+ if (stroke == null || thickness <= 0 || points.Count < 2)
+ {
+ return;
+ }
+
+ this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
+ using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
+ {
+
+ if (dashArray != null)
+ {
+ pen.DashPattern = this.ToFloatArray(dashArray);
+ }
+
+ switch (lineJoin)
+ {
+ case OxyPenLineJoin.Round:
+ pen.LineJoin = LineJoin.Round;
+ break;
+ case OxyPenLineJoin.Bevel:
+ pen.LineJoin = LineJoin.Bevel;
+ break;
+
+ // The default LineJoin is Miter
+ }
+
+ this.g.DrawLines(pen, this.ToPoints(points));
+ }
+ }
+
+ ///
+ /// Draws the polygon.
+ ///
+ /// The points.
+ /// The fill.
+ /// The stroke.
+ /// The thickness.
+ /// The dash array.
+ /// The line join.
+ /// if set to true [aliased].
+ public override void DrawPolygon(
+ IList points,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased)
+ {
+ if (points.Count < 2)
+ {
+ return;
+ }
+
+ this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
+
+ PointF[] pts = this.ToPoints(points);
+ if (fill != null)
+ {
+ this.g.FillPolygon(this.ToBrush(fill), pts);
+ }
+
+ if (stroke != null && thickness > 0)
+ {
+ using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
+ {
+
+ if (dashArray != null)
+ {
+ pen.DashPattern = this.ToFloatArray(dashArray);
+ }
+
+ switch (lineJoin)
+ {
+ case OxyPenLineJoin.Round:
+ pen.LineJoin = LineJoin.Round;
+ break;
+ case OxyPenLineJoin.Bevel:
+ pen.LineJoin = LineJoin.Bevel;
+ break;
+
+ // The default LineJoin is Miter
+ }
+
+ this.g.DrawPolygon(pen, pts);
+ }
+ }
+ }
+
+ ///
+ /// The draw rectangle.
+ ///
+ ///
+ /// The rect.
+ ///
+ ///
+ /// The fill.
+ ///
+ ///
+ /// The stroke.
+ ///
+ ///
+ /// The thickness.
+ ///
+ public override void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
+ {
+ if (fill != null)
+ {
+ this.g.FillRectangle(
+ this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
+ }
+
+ if (stroke == null || thickness <= 0)
+ {
+ return;
+ }
+
+ using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
+ {
+ this.g.DrawRectangle(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
+ }
+ }
+
+ ///
+ /// The draw text.
+ ///
+ ///
+ /// The p.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The fill.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// The font size.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The rotate.
+ ///
+ ///
+ /// The halign.
+ ///
+ ///
+ /// The valign.
+ ///
+ ///
+ /// The maximum size of the text.
+ ///
+ public override void DrawText(
+ ScreenPoint p,
+ string text,
+ OxyColor fill,
+ string fontFamily,
+ double fontSize,
+ double fontWeight,
+ double rotate,
+ HorizontalAlignment halign,
+ VerticalAlignment valign,
+ OxySize? maxSize)
+ {
+ var fs = FontStyle.Regular;
+ if (fontWeight >= 700)
+ {
+ fs = FontStyle.Bold;
+ }
+
+ using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
+ {
+ using (var sf = new StringFormat { Alignment = StringAlignment.Near })
+ {
+ var size = this.g.MeasureString(text, font);
+ if (maxSize != null)
+ {
+ if (size.Width > maxSize.Value.Width)
+ {
+ size.Width = (float)maxSize.Value.Width;
+ }
+
+ if (size.Height > maxSize.Value.Height)
+ {
+ size.Height = (float)maxSize.Value.Height;
+ }
+ }
+
+ float dx = 0;
+ if (halign == HorizontalAlignment.Center)
+ {
+ dx = -size.Width / 2;
+ }
+
+ if (halign == HorizontalAlignment.Right)
+ {
+ dx = -size.Width;
+ }
+
+ float dy = 0;
+ sf.LineAlignment = StringAlignment.Near;
+ if (valign == VerticalAlignment.Middle)
+ {
+ dy = -size.Height / 2;
+ }
+
+ if (valign == VerticalAlignment.Bottom)
+ {
+ dy = -size.Height;
+ }
+
+ this.g.TranslateTransform((float)p.X, (float)p.Y);
+ if (Math.Abs(rotate) > double.Epsilon)
+ {
+ this.g.RotateTransform((float)rotate);
+ }
+
+ this.g.TranslateTransform(dx, dy);
+
+ var layoutRectangle = new RectangleF(0, 0, size.Width, size.Height);
+ this.g.DrawString(text, font, this.ToBrush(fill), layoutRectangle, sf);
+
+ this.g.ResetTransform();
+ }
+ }
+ }
+
+ ///
+ /// The measure text.
+ ///
+ /// The text.
+ /// The font family.
+ /// The font size.
+ /// The font weight.
+ /// The size of the text.
+ public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight)
+ {
+ if (text == null)
+ {
+ return OxySize.Empty;
+ }
+
+ var fs = FontStyle.Regular;
+ if (fontWeight >= 700)
+ {
+ fs = FontStyle.Bold;
+ }
+
+ using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
+ {
+ var size = this.g.MeasureString(text, font);
+ return new OxySize(size.Width, size.Height);
+ }
+ }
+
+ ///
+ /// Converts a fill color to a System.Drawing.Brush.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The brush.
+ ///
+ private Brush ToBrush(OxyColor fill)
+ {
+ if (fill != null)
+ {
+ return new SolidBrush(this.ToColor(fill));
+ }
+
+ return null;
+ }
+
+ ///
+ /// Converts a color to a System.Drawing.Color.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// The System.Drawing.Color.
+ ///
+ private Color ToColor(OxyColor c)
+ {
+ return Color.FromArgb(c.A, c.R, c.G, c.B);
+ }
+
+ ///
+ /// Converts a double array to a float array.
+ ///
+ ///
+ /// The a.
+ ///
+ ///
+ /// The float array.
+ ///
+ private float[] ToFloatArray(double[] a)
+ {
+ if (a == null)
+ {
+ return null;
+ }
+
+ var r = new float[a.Length];
+ for (int i = 0; i < a.Length; i++)
+ {
+ r[i] = (float)a[i];
+ }
+
+ return r;
+ }
+
+ ///
+ /// Converts a list of point to an array of PointF.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// An array of points.
+ ///
+ private PointF[] ToPoints(IList points)
+ {
+ if (points == null)
+ {
+ return null;
+ }
+
+ var r = new PointF[points.Count()];
+ int i = 0;
+ foreach (ScreenPoint p in points)
+ {
+ r[i++] = new PointF((float)p.X, (float)p.Y);
+ }
+
+ return r;
+ }
+
+ public override void CleanUp()
+ {
+ var imagesToRelease = imageCache.Keys.Where(i => !imagesInUse.Contains(i));
+ foreach (var i in imagesToRelease)
+ {
+ var image = this.GetImage(i);
+ image.Dispose();
+ imageCache.Remove(i);
+ }
+
+ imagesInUse.Clear();
+ }
+
+ public override OxyImageInfo GetImageInfo(OxyImage source)
+ {
+ var image = this.GetImage(source);
+ return image == null ? null : new OxyImageInfo { Width = (uint)image.Width, Height = (uint)image.Height, DpiX = image.HorizontalResolution, DpiY = image.VerticalResolution };
+ }
+
+ public override void DrawImage(OxyImage source, uint srcX, uint srcY, uint srcWidth, uint srcHeight, double x, double y, double w, double h, double opacity, bool interpolate)
+ {
+ var image = this.GetImage(source);
+ if (image != null)
+ {
+ ImageAttributes ia = null;
+ if (opacity < 1)
+ {
+ var cm = new ColorMatrix
+ {
+ Matrix00 = 1f,
+ Matrix11 = 1f,
+ Matrix22 = 1f,
+ Matrix33 = 1f,
+ Matrix44 = (float)opacity
+ };
+
+ ia = new ImageAttributes();
+ ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
+ }
+
+ g.InterpolationMode = interpolate ? InterpolationMode.HighQualityBicubic : InterpolationMode.NearestNeighbor;
+ int sx = (int)Math.Round(x);
+ int sy = (int)Math.Round(y);
+ int sw = (int)Math.Round(x + w) - sx;
+ int sh = (int)Math.Round(y + h) - sy;
+ g.DrawImage(image, new Rectangle(sx, sy, sw, sh), srcX, srcY, srcWidth, srcHeight, GraphicsUnit.Pixel, ia);
+ }
+ }
+
+ private HashSet imagesInUse = new HashSet();
+
+ private Dictionary imageCache = new Dictionary();
+
+
+ private Image GetImage(OxyImage source)
+ {
+ if (source == null)
+ {
+ return null;
+ }
+
+ if (!this.imagesInUse.Contains(source))
+ {
+ this.imagesInUse.Add(source);
+ }
+
+ Image src;
+ if (this.imageCache.TryGetValue(source, out src))
+ {
+ return src;
+ }
+
+ if (source != null)
+ {
+ Image btm;
+ using (var ms = new MemoryStream(source.GetData()))
+ {
+ btm = Image.FromStream(ms);
+ }
+
+ this.imageCache.Add(source, btm);
+ return btm;
+ }
+
+ return null;
+ }
+
+ public override bool SetClip(OxyRect rect)
+ {
+ this.g.SetClip(rect.ToRect(false));
+ return true;
+ }
+
+ public override void ResetClip()
+ {
+ this.g.ResetClip();
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/Helpers/ConverterExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/Helpers/ConverterExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,251 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Extension method used to convert to/from Windows/Windows.Media classes.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.WindowsForms
+{
+ using System;
+ using System.Drawing;
+ using System.Windows.Forms;
+
+ ///
+ /// Extension method used to convert to/from Windows/Windows.Media classes.
+ ///
+ public static class ConverterExtensions
+ {
+ ///
+ /// Calculate the distance between two points.
+ ///
+ ///
+ /// The first point.
+ ///
+ ///
+ /// The second point.
+ ///
+ ///
+ /// The distance.
+ ///
+ public static double DistanceTo(this Point p1, Point p2)
+ {
+ double dx = p1.X - p2.X;
+ double dy = p1.Y - p2.Y;
+ return Math.Sqrt((dx * dx) + (dy * dy));
+ }
+
+ ///
+ /// Converts a color to a Brush.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// A SolidColorBrush.
+ ///
+ public static Brush ToBrush(this OxyColor c)
+ {
+ return new SolidBrush(c.ToColor());
+ }
+
+ ///
+ /// Converts an OxyColor to a Color.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// A Color.
+ ///
+ public static Color ToColor(this OxyColor c)
+ {
+ return Color.FromArgb(c.A, c.R, c.G, c.B);
+ }
+
+ ///
+ /// Converts a HorizontalAlignment to a HorizontalTextAlign.
+ ///
+ ///
+ /// The alignment.
+ ///
+ ///
+ /// A HorizontalTextAlign.
+ ///
+ public static OxyPlot.HorizontalAlignment ToHorizontalTextAlign(this HorizontalAlignment alignment)
+ {
+ switch (alignment)
+ {
+ case HorizontalAlignment.Center:
+ return OxyPlot.HorizontalAlignment.Center;
+ case HorizontalAlignment.Right:
+ return OxyPlot.HorizontalAlignment.Right;
+ default:
+ return OxyPlot.HorizontalAlignment.Left;
+ }
+ }
+
+ ///
+ /// Converts a Color to an OxyColor.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// An OxyColor.
+ ///
+ public static OxyColor ToOxyColor(this Color color)
+ {
+ return OxyColor.FromArgb(color.A, color.R, color.G, color.B);
+ }
+
+ ///
+ /// Converts a nullable Color to an OxyColor.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// An OxyColor.
+ ///
+ public static OxyColor ToOxyColor(this Color? color)
+ {
+ return color.HasValue ? color.Value.ToOxyColor() : null;
+ }
+
+ ///
+ /// Converts a Brush to an OxyColor.
+ ///
+ ///
+ /// The brush.
+ ///
+ ///
+ /// An oxycolor.
+ ///
+ public static OxyColor ToOxyColor(this Brush brush)
+ {
+ var scb = brush as SolidBrush;
+ return scb != null ? scb.Color.ToOxyColor() : null;
+ }
+
+ ///
+ /// Converts a Thickness to an OxyThickness.
+ ///
+ ///
+ /// An OxyPlot thickness.
+ ///
+ ///
+ /// Converts a ScreenPoint to a Point.
+ ///
+ ///
+ /// The screen point.
+ ///
+ ///
+ /// use pixel alignment conversion if set to true.
+ ///
+ ///
+ /// A point.
+ ///
+ public static Point ToPoint(this ScreenPoint pt, bool aliased)
+ {
+ // adding 0.5 to get pixel boundary alignment, seems to work
+ // http://weblogs.asp.net/mschwarz/archive/2008/01/04/silverlight-rectangles-paths-and-line-comparison.aspx
+ // http://www.wynapse.com/Silverlight/Tutor/Silverlight_Rectangles_Paths_And_Lines_Comparison.aspx
+ if (aliased)
+ {
+ return new Point((int)pt.X, (int)pt.Y);
+ }
+
+ return new Point((int)Math.Round(pt.X), (int)Math.Round(pt.Y));
+ }
+
+ ///
+ /// Converts an OxyRect to a Rect.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// use pixel alignment if set to true.
+ ///
+ ///
+ /// A rect.
+ ///
+ public static Rectangle ToRect(this OxyRect r, bool aliased)
+ {
+ if (aliased)
+ {
+ var x = (int)r.Left;
+ var y = (int)r.Top;
+ var ri = (int)r.Right;
+ var bo = (int)r.Bottom;
+ return new Rectangle(x, y, ri - x, bo - y);
+ }
+
+ return new Rectangle(
+ (int)Math.Round(r.Left), (int)Math.Round(r.Top), (int)Math.Round(r.Width), (int)Math.Round(r.Height));
+ }
+
+ ///
+ /// Converts a point to a ScreenPoint.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// A screen point.
+ ///
+ public static ScreenPoint ToScreenPoint(this Point pt)
+ {
+ return new ScreenPoint(pt.X, pt.Y);
+ }
+
+ ///
+ /// Converts a Point array to a ScreenPoint array.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// A ScreenPoint array.
+ ///
+ public static ScreenPoint[] ToScreenPointArray(this Point[] points)
+ {
+ if (points == null)
+ {
+ return null;
+ }
+
+ var pts = new ScreenPoint[points.Length];
+ for (int i = 0; i < points.Length; i++)
+ {
+ pts[i] = points[i].ToScreenPoint();
+ }
+
+ return pts;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/NamespaceDoc.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/NamespaceDoc.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,37 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot.WindowsForms
+{
+ ///
+ /// The OxyPlot.WindowsForms namespace contains controls for Windows Forms and a bitmap exporter.
+ ///
+ [System.Runtime.CompilerServices.CompilerGenerated]
+ internal class NamespaceDoc
+ {
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,79 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {D4554296-094E-4CAC-8EAE-44EB250666C6}
+ Library
+ Properties
+ OxyPlot.WindowsForms
+ OxyPlot.WindowsForms
+ v4.0
+ Client
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\NET40\
+ obj\Debug\NET40\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\Output\NET40\
+ obj\Release\NET40\
+ TRACE
+ prompt
+ 4
+ ..\..\Output\NET40\OxyPlot.WindowsForms.XML
+
+
+ true
+
+
+ OxyPlot.WindowsForms.snk
+
+
+
+
+
+
+
+
+
+ Properties\GlobalAssemblyInfo.cs
+
+
+
+
+
+ Component
+
+
+
+
+
+
+
+
+
+
+ {7a0b35c0-dd17-4964-8e9a-44d6cecdc692}
+ OxyPlot
+
+
+
+
+
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk
Binary file External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk has changed
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/Plot.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/Plot.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,897 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a control that displays a plot.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.WindowsForms
+{
+ using System;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Drawing;
+ using System.Runtime.InteropServices;
+ using System.Windows.Forms;
+
+ using OxyPlot.Axes;
+ using OxyPlot.Series;
+
+ ///
+ /// Represents a control that displays a plot.
+ ///
+ [Serializable]
+ public class Plot : Control, IPlotControl
+ {
+ ///
+ /// The category for the properties of this control.
+ ///
+ private const string OxyPlotCategory = "OxyPlot";
+
+ ///
+ /// The invalidate lock.
+ ///
+ private readonly object invalidateLock = new object();
+
+ ///
+ /// The model lock.
+ ///
+ private readonly object modelLock = new object();
+
+ ///
+ /// The rendering lock.
+ ///
+ private readonly object renderingLock = new object();
+
+ ///
+ /// The current model (holding a reference to this plot control).
+ ///
+ [NonSerialized]
+ private PlotModel currentModel;
+
+ ///
+ /// The is model invalidated.
+ ///
+ private bool isModelInvalidated;
+
+ ///
+ /// The model.
+ ///
+ private PlotModel model;
+
+ ///
+ /// The mouse manipulator.
+ ///
+ [NonSerialized]
+ private ManipulatorBase mouseManipulator;
+
+ ///
+ /// The update data flag.
+ ///
+ private bool updateDataFlag = true;
+
+ ///
+ /// The zoom rectangle.
+ ///
+ private Rectangle zoomRectangle;
+
+ ///
+ /// The render context.
+ ///
+ private GraphicsRenderContext renderContext;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Plot()
+ {
+ this.renderContext = new GraphicsRenderContext();
+
+ // ReSharper disable DoNotCallOverridableMethodsInConstructor
+ this.DoubleBuffered = true;
+ // ReSharper restore DoNotCallOverridableMethodsInConstructor
+ this.KeyboardPanHorizontalStep = 0.1;
+ this.KeyboardPanVerticalStep = 0.1;
+ this.PanCursor = Cursors.Hand;
+ this.ZoomRectangleCursor = Cursors.SizeNWSE;
+ this.ZoomHorizontalCursor = Cursors.SizeWE;
+ this.ZoomVerticalCursor = Cursors.SizeNS;
+ }
+
+ ///
+ /// Gets the actual model.
+ ///
+ /// The actual model.
+ public PlotModel ActualModel
+ {
+ get
+ {
+ return this.Model;
+ }
+ }
+
+ ///
+ /// Gets or sets the keyboard pan horizontal step.
+ ///
+ /// The keyboard pan horizontal step.
+ [Category(OxyPlotCategory)]
+ public double KeyboardPanHorizontalStep { get; set; }
+
+ ///
+ /// Gets or sets the keyboard pan vertical step.
+ ///
+ /// The keyboard pan vertical step.
+ [Category(OxyPlotCategory)]
+ public double KeyboardPanVerticalStep { get; set; }
+
+ ///
+ /// Gets or sets the model.
+ ///
+ [Browsable(false)]
+ [DefaultValue(null)]
+ [Category(OxyPlotCategory)]
+ public PlotModel Model
+ {
+ get
+ {
+ return this.model;
+ }
+
+ set
+ {
+ if (this.model != value)
+ {
+ this.model = value;
+ this.OnModelChanged();
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the pan cursor.
+ ///
+ [Category(OxyPlotCategory)]
+ public Cursor PanCursor { get; set; }
+
+ ///
+ /// Gets or sets the horizontal zoom cursor.
+ ///
+ [Category(OxyPlotCategory)]
+ public Cursor ZoomHorizontalCursor { get; set; }
+
+ ///
+ /// Gets or sets the rectangle zoom cursor.
+ ///
+ [Category(OxyPlotCategory)]
+ public Cursor ZoomRectangleCursor { get; set; }
+
+ ///
+ /// Gets or sets vertical zoom cursor.
+ ///
+ [Category(OxyPlotCategory)]
+ public Cursor ZoomVerticalCursor { get; set; }
+
+ ///
+ /// Get the axes from a point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The x axis.
+ ///
+ ///
+ /// The y axis.
+ ///
+ public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
+ {
+ if (this.Model == null)
+ {
+ xaxis = null;
+ yaxis = null;
+ return;
+ }
+
+ this.Model.GetAxesFromPoint(pt, out xaxis, out yaxis);
+ }
+
+ ///
+ /// Get the series from a point.
+ ///
+ ///
+ /// The point (screen coordinates).
+ ///
+ ///
+ /// The limit.
+ ///
+ ///
+ /// The series.
+ ///
+ public Series GetSeriesFromPoint(ScreenPoint pt, double limit)
+ {
+ if (this.Model == null)
+ {
+ return null;
+ }
+
+ return this.Model.GetSeriesFromPoint(pt, limit);
+ }
+
+ ///
+ /// The hide tracker.
+ ///
+ public void HideTracker()
+ {
+ }
+
+ ///
+ /// The hide zoom rectangle.
+ ///
+ public void HideZoomRectangle()
+ {
+ this.zoomRectangle = Rectangle.Empty;
+ this.Invalidate();
+ }
+
+ ///
+ /// The invalidate plot.
+ ///
+ ///
+ /// The update data.
+ ///
+ public void InvalidatePlot(bool updateData)
+ {
+ lock (this.invalidateLock)
+ {
+ this.isModelInvalidated = true;
+ this.updateDataFlag = this.updateDataFlag || updateData;
+ }
+
+ this.Invalidate();
+ }
+
+ ///
+ /// Called when the Model property has been changed.
+ ///
+ public void OnModelChanged()
+ {
+ lock (this.modelLock)
+ {
+ if (this.currentModel != null)
+ {
+ this.currentModel.AttachPlotControl(null);
+ }
+
+ if (this.Model != null)
+ {
+ if (this.Model.PlotControl != null)
+ {
+ throw new InvalidOperationException(
+ "This PlotModel is already in use by some other plot control.");
+ }
+
+ this.Model.AttachPlotControl(this);
+ this.currentModel = this.Model;
+ }
+ }
+
+ this.InvalidatePlot(true);
+ }
+
+ ///
+ /// The pan.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The x 0.
+ ///
+ ///
+ /// The x 1.
+ ///
+ public void Pan(Axis axis, ScreenPoint x0, ScreenPoint x1)
+ {
+ axis.Pan(x0, x1);
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// Pans all axes.
+ ///
+ ///
+ /// The horizontal delta.
+ ///
+ ///
+ /// The vertical delta.
+ ///
+ public void PanAll(double deltax, double deltay)
+ {
+ foreach (var a in this.ActualModel.Axes)
+ {
+ a.Pan(a.IsHorizontal() ? deltax : deltay);
+ }
+
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// The refresh plot.
+ ///
+ ///
+ /// The update data.
+ ///
+ public void RefreshPlot(bool updateData)
+ {
+ lock (this.invalidateLock)
+ {
+ this.isModelInvalidated = true;
+ this.updateDataFlag = this.updateDataFlag || updateData;
+ }
+
+ this.Refresh();
+ }
+
+ ///
+ /// The reset.
+ ///
+ ///
+ /// The axis.
+ ///
+ public void Reset(Axis axis)
+ {
+ axis.Reset();
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// Sets the cursor type.
+ ///
+ ///
+ /// The cursor type.
+ ///
+ public void SetCursorType(CursorType cursorType)
+ {
+ switch (cursorType)
+ {
+ case CursorType.Pan:
+ this.Cursor = this.PanCursor;
+ break;
+ case CursorType.ZoomRectangle:
+ this.Cursor = this.ZoomRectangleCursor;
+ break;
+ case CursorType.ZoomHorizontal:
+ this.Cursor = this.ZoomHorizontalCursor;
+ break;
+ case CursorType.ZoomVertical:
+ this.Cursor = this.ZoomVerticalCursor;
+ break;
+ default:
+ this.Cursor = Cursors.Arrow;
+ break;
+ }
+ }
+
+ ///
+ /// The show tracker.
+ ///
+ ///
+ /// The data.
+ ///
+ public void ShowTracker(TrackerHitResult data)
+ {
+ // not implemented for WindowsForms
+ }
+
+ ///
+ /// The show zoom rectangle.
+ ///
+ ///
+ /// The r.
+ ///
+ public void ShowZoomRectangle(OxyRect r)
+ {
+ this.zoomRectangle = new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height);
+ this.Invalidate();
+ }
+
+ ///
+ /// The zoom.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The p 1.
+ ///
+ ///
+ /// The p 2.
+ ///
+ public void Zoom(Axis axis, double p1, double p2)
+ {
+ axis.Zoom(p1, p2);
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// The zoom all.
+ ///
+ public void ZoomAll()
+ {
+ foreach (var a in this.Model.Axes)
+ {
+ a.Reset();
+ }
+
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// Zooms all axes.
+ ///
+ ///
+ /// The delta.
+ ///
+ public void ZoomAllAxes(double delta)
+ {
+ foreach (var a in this.ActualModel.Axes)
+ {
+ this.ZoomAt(a, delta);
+ }
+
+ this.RefreshPlot(false);
+ }
+
+ ///
+ /// The zoom at.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The factor.
+ ///
+ ///
+ /// The x.
+ ///
+ public void ZoomAt(Axis axis, double factor, double x = double.NaN)
+ {
+ if (double.IsNaN(x))
+ {
+ double sx = (axis.Transform(axis.ActualMaximum) + axis.Transform(axis.ActualMinimum)) * 0.5;
+ x = axis.InverseTransform(sx);
+ }
+
+ axis.ZoomAt(factor, x);
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// The on mouse down.
+ ///
+ ///
+ /// The e.
+ ///
+ protected override void OnMouseDown(MouseEventArgs e)
+ {
+ base.OnMouseDown(e);
+
+ if (this.mouseManipulator != null)
+ {
+ return;
+ }
+
+ this.Focus();
+ this.Capture = true;
+
+ if (this.ActualModel != null)
+ {
+ var args = this.CreateMouseEventArgs(e);
+ this.ActualModel.HandleMouseDown(this, args);
+ if (args.Handled)
+ {
+ return;
+ }
+ }
+
+ this.mouseManipulator = this.GetManipulator(e);
+
+ if (this.mouseManipulator != null)
+ {
+ this.mouseManipulator.Started(this.CreateManipulationEventArgs(e));
+ }
+ }
+
+ ///
+ /// The on mouse move.
+ ///
+ ///
+ /// The e.
+ ///
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ base.OnMouseMove(e);
+
+ if (this.ActualModel != null)
+ {
+ var args = this.CreateMouseEventArgs(e);
+ this.ActualModel.HandleMouseMove(this, args);
+ if (args.Handled)
+ {
+ return;
+ }
+ }
+
+ if (this.mouseManipulator != null)
+ {
+ this.mouseManipulator.Delta(this.CreateManipulationEventArgs(e));
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// A that contains the event data.
+ ///
+ protected override void OnMouseUp(MouseEventArgs e)
+ {
+ base.OnMouseUp(e);
+ this.Capture = false;
+
+ if (this.ActualModel != null)
+ {
+ var args = this.CreateMouseEventArgs(e);
+ this.ActualModel.HandleMouseUp(this, args);
+ if (args.Handled)
+ {
+ return;
+ }
+ }
+
+ if (this.mouseManipulator != null)
+ {
+ this.mouseManipulator.Completed(this.CreateManipulationEventArgs(e));
+ }
+
+ this.mouseManipulator = null;
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// A that contains the event data.
+ ///
+ protected override void OnMouseWheel(MouseEventArgs e)
+ {
+ base.OnMouseWheel(e);
+ bool isControlDown = ModifierKeys == Keys.Control;
+ var m = new ZoomStepManipulator(this, e.Delta * 0.001, isControlDown);
+ m.Started(new ManipulationEventArgs(e.Location.ToScreenPoint()));
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// A that contains the event data.
+ ///
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ base.OnPaint(e);
+ try
+ {
+ lock (this.invalidateLock)
+ {
+ if (this.isModelInvalidated)
+ {
+ if (this.model != null)
+ {
+ this.model.Update(this.updateDataFlag);
+ this.updateDataFlag = false;
+ }
+
+ this.isModelInvalidated = false;
+ }
+ }
+
+ lock (this.renderingLock)
+ {
+ this.renderContext.SetGraphicsTarget(e.Graphics);
+ if (this.model != null)
+ {
+ this.model.Render(this.renderContext, this.Width, this.Height);
+ }
+
+ if (this.zoomRectangle != Rectangle.Empty)
+ {
+ using (var zoomBrush = new SolidBrush(Color.FromArgb(0x40, 0xFF, 0xFF, 0x00)))
+ using (var zoomPen = new Pen(Color.Black))
+ {
+ zoomPen.DashPattern = new float[] { 3, 1 };
+ e.Graphics.FillRectangle(zoomBrush, this.zoomRectangle);
+ e.Graphics.DrawRectangle(zoomPen, this.zoomRectangle);
+ }
+ }
+ }
+ }
+ catch (Exception paintException)
+ {
+ var trace = new StackTrace(paintException);
+ Debug.WriteLine(paintException);
+ Debug.WriteLine(trace);
+ using (var font = new Font("Arial", 10))
+ {
+ e.Graphics.DrawString(
+ "OxyPlot paint exception: " + paintException.Message, font, Brushes.Red, 10, 10);
+ }
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// A that contains the event data.
+ ///
+ protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
+ {
+ base.OnPreviewKeyDown(e);
+ if (e.KeyCode == Keys.A)
+ {
+ this.ZoomAll();
+ }
+
+ bool control = (e.Modifiers & Keys.Control) == Keys.Control;
+ bool alt = (e.Modifiers & Keys.Alt) == Keys.Alt;
+
+ double deltax = 0;
+ double deltay = 0;
+ double zoom = 0;
+ switch (e.KeyCode)
+ {
+ case Keys.Up:
+ deltay = -1;
+ break;
+ case Keys.Down:
+ deltay = 1;
+ break;
+ case Keys.Left:
+ deltax = -1;
+ break;
+ case Keys.Right:
+ deltax = 1;
+ break;
+ case Keys.Add:
+ case Keys.Oemplus:
+ case Keys.PageUp:
+ zoom = 1;
+ break;
+ case Keys.Subtract:
+ case Keys.OemMinus:
+ case Keys.PageDown:
+ zoom = -1;
+ break;
+ }
+
+ if ((deltax * deltax) + (deltay * deltay) > 0)
+ {
+ deltax = deltax * this.ActualModel.PlotArea.Width * this.KeyboardPanHorizontalStep;
+ deltay = deltay * this.ActualModel.PlotArea.Height * this.KeyboardPanVerticalStep;
+
+ // small steps if the user is pressing control
+ if (control)
+ {
+ deltax *= 0.2;
+ deltay *= 0.2;
+ }
+
+ this.PanAll(deltax, deltay);
+
+ // e.Handled = true;
+ }
+
+ if (Math.Abs(zoom) > 1e-8)
+ {
+ if (control)
+ {
+ zoom *= 0.2;
+ }
+
+ this.ZoomAllAxes(1 + (zoom * 0.12));
+
+ // e.Handled = true;
+ }
+
+ if (control && alt && this.ActualModel != null)
+ {
+ switch (e.KeyCode)
+ {
+ case Keys.R:
+ this.SetClipboardText(this.ActualModel.CreateTextReport());
+ break;
+ case Keys.C:
+ this.SetClipboardText(this.ActualModel.ToCode());
+ break;
+ case Keys.X:
+
+ // this.SetClipboardText(this.ActualModel.ToXml());
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// An that contains the event data.
+ ///
+ protected override void OnResize(EventArgs e)
+ {
+ base.OnResize(e);
+ this.InvalidatePlot(false);
+ }
+
+ ///
+ /// Converts the changed button.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ ///
+ /// The mouse button.
+ ///
+ private static OxyMouseButton ConvertChangedButton(MouseEventArgs e)
+ {
+ switch (e.Button)
+ {
+ case MouseButtons.Left:
+ return OxyMouseButton.Left;
+ case MouseButtons.Middle:
+ return OxyMouseButton.Middle;
+ case MouseButtons.Right:
+ return OxyMouseButton.Right;
+ case MouseButtons.XButton1:
+ return OxyMouseButton.XButton1;
+ case MouseButtons.XButton2:
+ return OxyMouseButton.XButton2;
+ }
+
+ return OxyMouseButton.Left;
+ }
+
+ ///
+ /// Creates the mouse event arguments.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ ///
+ /// Mouse event arguments.
+ ///
+ private OxyMouseEventArgs CreateMouseEventArgs(MouseEventArgs e)
+ {
+ return new OxyMouseEventArgs
+ {
+ ChangedButton = ConvertChangedButton(e),
+ Position = new ScreenPoint(e.Location.X, e.Location.Y),
+ IsShiftDown = (ModifierKeys & Keys.Shift) == Keys.Shift,
+ IsControlDown = (ModifierKeys & Keys.Control) == Keys.Control,
+ IsAltDown = (ModifierKeys & Keys.Alt) == Keys.Alt,
+ };
+ }
+
+ ///
+ /// Creates the manipulation event args.
+ ///
+ ///
+ /// The MouseEventArgs instance containing the event data.
+ ///
+ ///
+ /// A manipulation event args object.
+ ///
+ private ManipulationEventArgs CreateManipulationEventArgs(MouseEventArgs e)
+ {
+ return new ManipulationEventArgs(e.Location.ToScreenPoint());
+ }
+
+ ///
+ /// Gets the manipulator for the current mouse button and modifier keys.
+ ///
+ ///
+ /// The event args.
+ ///
+ ///
+ /// A manipulator or null if no gesture was recognized.
+ ///
+ private ManipulatorBase GetManipulator(MouseEventArgs e)
+ {
+ bool control = (ModifierKeys & Keys.Control) == Keys.Control;
+ bool shift = (ModifierKeys & Keys.Shift) == Keys.Shift;
+ bool alt = (ModifierKeys & Keys.Alt) == Keys.Alt;
+
+ bool lmb = e.Button == MouseButtons.Left;
+ bool rmb = e.Button == MouseButtons.Right;
+ bool mmb = e.Button == MouseButtons.Middle;
+ bool xb1 = e.Button == MouseButtons.XButton1;
+ bool xb2 = e.Button == MouseButtons.XButton2;
+
+ // MMB / control RMB / control+alt LMB
+ if (mmb || (control && rmb) || (control && alt && lmb))
+ {
+ if (e.Clicks == 2)
+ {
+ return new ResetManipulator(this);
+ }
+
+ return new ZoomRectangleManipulator(this);
+ }
+
+ // Right mouse button / alt+left mouse button
+ if (rmb || (lmb && alt))
+ {
+ return new PanManipulator(this);
+ }
+
+ // Left mouse button
+ if (lmb)
+ {
+ return new TrackerManipulator(this) { Snap = !control, PointsOnly = shift };
+ }
+
+ // XButtons are zoom-stepping
+ if (xb1 || xb2)
+ {
+ double d = xb1 ? 0.05 : -0.05;
+ return new ZoomStepManipulator(this, d, control);
+ }
+
+ return null;
+ }
+
+ ///
+ /// The set clipboard text.
+ ///
+ ///
+ /// The text.
+ ///
+ private void SetClipboardText(string text)
+ {
+ try
+ {
+ // todo: can't get the following solution to work
+ // http://stackoverflow.com/questions/5707990/requested-clipboard-operation-did-not-succeed
+ Clipboard.SetText(text);
+ }
+ catch (ExternalException ee)
+ {
+ // Requested Clipboard operation did not succeed.
+ MessageBox.Show(this, ee.Message, "OxyPlot");
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/PlotControl.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/PlotControl.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,237 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using OxyPlot;
+
+namespace Oxyplot.WindowsForms
+{
+ public class PlotControl : Control, IPlotControl
+ {
+ public List MouseActions { get; private set; }
+
+ private readonly PanAction panAction;
+ private readonly SliderAction sliderAction;
+ private readonly ZoomAction zoomAction;
+ private Rectangle zoomRectangle;
+
+ public PlotControl()
+ {
+ // InitializeComponent();
+ DoubleBuffered = true;
+ Model = new PlotModel();
+
+ panAction = new PanAction(this);
+ zoomAction = new ZoomAction(this);
+ sliderAction = new SliderAction(this);
+
+ MouseActions = new List();
+ MouseActions.Add(panAction);
+ MouseActions.Add(zoomAction);
+ MouseActions.Add(sliderAction);
+ }
+
+ private PlotModel model;
+
+ [Browsable(false), DefaultValue(null)]
+ public PlotModel Model
+ {
+ get { return model; }
+ set
+ {
+ model = value;
+ Refresh();
+ }
+ }
+
+ public override void Refresh()
+ {
+ if (model != null)
+ model.UpdateData();
+ base.Refresh();
+ }
+
+ protected override void OnResize(EventArgs e)
+ {
+ base.OnResize(e);
+ Invalidate();
+ }
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ base.OnPaint(e);
+
+ var rc = new GraphicsRenderContext(this, e.Graphics, e.ClipRectangle);
+ if (model != null)
+ model.Render(rc);
+ if (zoomRectangle != Rectangle.Empty)
+ {
+ using (var zoomBrush = new SolidBrush(Color.FromArgb(0x40, 0xFF, 0xFF, 0x00)))
+ using (var zoomPen = new Pen(Color.Black))
+ {
+ zoomPen.DashPattern = new float[] { 3, 1 };
+ e.Graphics.FillRectangle(zoomBrush, zoomRectangle);
+ e.Graphics.DrawRectangle(zoomPen, zoomRectangle);
+ }
+ }
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+ if (e.KeyCode == Keys.A)
+ {
+ ZoomAll();
+ }
+ }
+
+ public void ZoomAll()
+ {
+ foreach (var a in Model.Axes)
+ a.Reset();
+ Refresh();
+ }
+
+ protected override void OnMouseDown(MouseEventArgs e)
+ {
+ base.OnMouseDown(e);
+
+ Focus();
+ Capture = true;
+
+ bool control = Control.ModifierKeys == Keys.Control;
+ bool shift = Control.ModifierKeys == Keys.Shift;
+
+ var button = OxyMouseButton.Left;
+ if (e.Button == MouseButtons.Middle)
+ button = OxyMouseButton.Middle;
+ if (e.Button == MouseButtons.Right)
+ button = OxyMouseButton.Right;
+ if (e.Button == MouseButtons.XButton1)
+ button = OxyMouseButton.XButton1;
+ if (e.Button == MouseButtons.XButton2)
+ button = OxyMouseButton.XButton2;
+
+ var p = new ScreenPoint(e.X, e.Y);
+ foreach (var a in MouseActions)
+ a.OnMouseDown(p, button, e.Clicks, control, shift);
+ }
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ base.OnMouseMove(e);
+ bool control = Control.ModifierKeys == Keys.Control;
+ bool shift = Control.ModifierKeys == Keys.Shift;
+ var p = new ScreenPoint(e.X, e.Y);
+ foreach (var a in MouseActions)
+ a.OnMouseMove(p, control, shift);
+ }
+
+ protected override void OnMouseUp(MouseEventArgs e)
+ {
+ base.OnMouseUp(e);
+ foreach (var a in MouseActions)
+ a.OnMouseUp();
+ Capture = false;
+ }
+
+ protected override void OnMouseWheel(MouseEventArgs e)
+ {
+ base.OnMouseWheel(e);
+ bool control = Control.ModifierKeys == Keys.Control;
+ bool shift = Control.ModifierKeys == Keys.Shift;
+ var p = new ScreenPoint(e.X, e.Y);
+ foreach (var a in MouseActions)
+ a.OnMouseWheel(p, e.Delta, control, shift);
+ }
+
+ public void GetAxesFromPoint(ScreenPoint pt, out AxisBase xaxis, out AxisBase yaxis)
+ {
+ Model.GetAxesFromPoint(pt, out xaxis, out yaxis);
+ }
+
+ public DataSeries GetSeriesFromPoint(ScreenPoint pt, double limit)
+ {
+ return Model.GetSeriesFromPoint(pt, limit);
+ }
+
+ public void Refresh(bool refreshData)
+ {
+ if (refreshData)
+ Model.UpdateData();
+ Invalidate();
+ }
+
+ public void Pan(AxisBase axis, double dx)
+ {
+ axis.Pan(dx);
+ }
+
+ public void Reset(AxisBase axis)
+ {
+ axis.Reset();
+ }
+
+ public void Zoom(AxisBase axis, double p1, double p2)
+ {
+ axis.Zoom(p1, p2);
+ }
+
+ public void ZoomAt(AxisBase axis, double factor, double x)
+ {
+ axis.ZoomAt(factor, x);
+ }
+
+ public OxyRect GetPlotArea()
+ {
+ return Model.PlotArea;
+ }
+
+ public void ShowSlider(DataSeries s, DataPoint dp)
+ {
+ }
+
+ public void HideSlider()
+ {
+ }
+
+ public void ShowZoomRectangle(OxyRect r)
+ {
+ zoomRectangle = new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height);
+ Invalidate();
+ }
+
+ public void HideZoomRectangle()
+ {
+ zoomRectangle = Rectangle.Empty;
+ Invalidate();
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/PngExporter.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/PngExporter.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,81 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The png exporter.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.WindowsForms
+{
+ using System.Drawing;
+ using System.Drawing.Imaging;
+
+ using OxyPlot.WindowsForms;
+
+ ///
+ /// The png exporter.
+ ///
+ public static class PngExporter
+ {
+ ///
+ /// The export.
+ ///
+ ///
+ /// The model.
+ ///
+ ///
+ /// The file name.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The background.
+ ///
+ public static void Export(PlotModel model, string fileName, int width, int height, Brush background = null)
+ {
+ using (var bm = new Bitmap(width, height))
+ {
+ using (Graphics g = Graphics.FromImage(bm))
+ {
+ if (background != null)
+ {
+ g.FillRectangle(background, 0, 0, width, height);
+ }
+
+ var rc = new GraphicsRenderContext { RendersToScreen = false };
+ rc.SetGraphicsTarget(g);
+ model.Update();
+ model.Render(rc, width, height);
+ bm.Save(fileName, ImageFormat.Png);
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.WindowsForms/Properties/AssemblyInfo.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.WindowsForms/Properties/AssemblyInfo.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,10 @@
+//-----------------------------------------------------------------------
+//
+// http://oxyplot.codeplex.com, license: MIT
+//
+//-----------------------------------------------------------------------
+
+using System.Reflection;
+
+[assembly: AssemblyTitle("OxyPlot for Windows Forms")]
+[assembly: AssemblyDescription("OxyPlot controls for Windows Forms.")]
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot.sln
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot.sln Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot", "OxyPlot\OxyPlot.csproj", "{BCC43E58-E473-403E-A84D-63FEDC723040}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot.WindowsForms", "OxyPlot.WindowsForms\OxyPlot.WindowsForms.csproj", "{D4554296-094E-4CAC-8EAE-44EB250666C6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BCC43E58-E473-403E-A84D-63FEDC723040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCC43E58-E473-403E-A84D-63FEDC723040}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCC43E58-E473-403E-A84D-63FEDC723040}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCC43E58-E473-403E-A84D-63FEDC723040}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4554296-094E-4CAC-8EAE-44EB250666C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D4554296-094E-4CAC-8EAE-44EB250666C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4554296-094E-4CAC-8EAE-44EB250666C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D4554296-094E-4CAC-8EAE-44EB250666C6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/Annotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/Annotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,181 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Annotation base class.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ using System;
+ using System.Globalization;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Provides an abstract base class for annotations.
+ ///
+ public abstract class Annotation : UIPlotElement
+ {
+ ///
+ /// Gets the actual culture.
+ ///
+ ///
+ /// The culture is defined in the parent PlotModel.
+ ///
+ public CultureInfo ActualCulture
+ {
+ get
+ {
+ return this.PlotModel != null ? this.PlotModel.ActualCulture : CultureInfo.CurrentCulture;
+ }
+ }
+
+ ///
+ /// Gets or sets the layer.
+ ///
+ public AnnotationLayer Layer { get; set; }
+
+ ///
+ /// Gets or sets the X axis.
+ ///
+ /// The X axis.
+ public Axis XAxis { get; set; }
+
+ ///
+ /// Gets or sets the X axis key.
+ ///
+ /// The X axis key.
+ public string XAxisKey { get; set; }
+
+ ///
+ /// Gets or sets the Y axis.
+ ///
+ /// The Y axis.
+ public Axis YAxis { get; set; }
+
+ ///
+ /// Gets or sets the Y axis key.
+ ///
+ /// The Y axis key.
+ public string YAxisKey { get; set; }
+
+ ///
+ /// Ensures that the annotation axes are set.
+ ///
+ public void EnsureAxes()
+ {
+ this.XAxis = this.PlotModel.GetAxisOrDefault(this.XAxisKey, this.PlotModel.DefaultXAxis);
+ this.YAxis = this.PlotModel.GetAxisOrDefault(this.YAxisKey, this.PlotModel.DefaultYAxis);
+ }
+
+ ///
+ /// Renders the annotation on the specified context.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The model.
+ ///
+ public virtual void Render(IRenderContext rc, PlotModel model)
+ {
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ /// The point.
+ /// The tolerance.
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ return null;
+ }
+
+ ///
+ /// Transforms the specified coordinates to a screen point.
+ ///
+ ///
+ /// The x coordinate.
+ ///
+ ///
+ /// The y coordinate.
+ ///
+ ///
+ /// A screen point.
+ ///
+ public ScreenPoint Transform(double x, double y)
+ {
+ return this.XAxis.Transform(x, y, this.YAxis);
+ }
+
+ ///
+ /// Transforms the specified data point to a screen point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// A screen point.
+ ///
+ public ScreenPoint Transform(IDataPoint p)
+ {
+ return this.XAxis.Transform(p.X, p.Y, this.YAxis);
+ }
+
+ ///
+ /// Transforms the specified screen position to a data point.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// A data point
+ ///
+ public DataPoint InverseTransform(ScreenPoint position)
+ {
+ return Axis.InverseTransform(position, this.XAxis, this.YAxis);
+ }
+
+ ///
+ /// Gets the clipping rectangle.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ protected OxyRect GetClippingRect()
+ {
+ double minX = Math.Min(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
+ double minY = Math.Min(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
+ double maxX = Math.Max(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
+ double maxY = Math.Max(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
+
+ return new OxyRect(minX, minY, maxX - minX, maxY - minY);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/AnnotationLayer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/AnnotationLayer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,52 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The annotation layer.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Specifies the layer for an .
+ ///
+ public enum AnnotationLayer
+ {
+ ///
+ /// Render the annotation below the gridlines of the axes.
+ ///
+ BelowAxes,
+
+ ///
+ /// Render the annotation below the series.
+ ///
+ BelowSeries,
+
+ ///
+ /// Render the annotation above the series.
+ ///
+ AboveSeries
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/ArrowAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/ArrowAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,228 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an arrow annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Represents an arrow annotation.
+ ///
+ public class ArrowAnnotation : TextualAnnotation
+ {
+ ///
+ /// The end point in screen coordinates.
+ ///
+ private ScreenPoint screenEndPoint;
+
+ ///
+ /// The start point in screen coordinates.
+ ///
+ private ScreenPoint screenStartPoint;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ArrowAnnotation()
+ {
+ this.HeadLength = 10;
+ this.HeadWidth = 3;
+ this.Color = OxyColors.Blue;
+ this.StrokeThickness = 2;
+ this.LineStyle = LineStyle.Solid;
+ this.LineJoin = OxyPenLineJoin.Miter;
+ }
+
+ ///
+ /// Gets or sets the arrow direction.
+ ///
+ ///
+ /// Setting this property overrides the StartPoint property.
+ ///
+ public ScreenVector ArrowDirection { get; set; }
+
+ ///
+ /// Gets or sets the color of the arrow.
+ ///
+ public OxyColor Color { get; set; }
+
+ ///
+ /// Gets or sets the end point.
+ ///
+ public DataPoint EndPoint { get; set; }
+
+ ///
+ /// Gets or sets the length of the head (relative to the stroke thickness) (the default value is 10).
+ ///
+ /// The length of the head.
+ public double HeadLength { get; set; }
+
+ ///
+ /// Gets or sets the width of the head (relative to the stroke thickness) (the default value is 3).
+ ///
+ /// The width of the head.
+ public double HeadWidth { get; set; }
+
+ ///
+ /// Gets or sets the line join type.
+ ///
+ /// The line join type.
+ public OxyPenLineJoin LineJoin { get; set; }
+
+ ///
+ /// Gets or sets the line style.
+ ///
+ /// The line style.
+ public LineStyle LineStyle { get; set; }
+
+ ///
+ /// Gets or sets the start point.
+ ///
+ ///
+ /// This property is overridden by the ArrowDirection property, if set.
+ ///
+ public DataPoint StartPoint { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness (the default value is 2).
+ ///
+ /// The stroke thickness.
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Gets or sets the 'veeness' of the arrow head (relative to thickness) (the default value is 0).
+ ///
+ /// The 'veeness'.
+ public double Veeness { get; set; }
+
+ ///
+ /// Renders the arrow annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ this.screenEndPoint = this.Transform(this.EndPoint);
+
+ if (!this.ArrowDirection.x.IsZero() || !this.ArrowDirection.y.IsZero())
+ {
+ this.screenStartPoint = this.screenEndPoint - this.ArrowDirection;
+ }
+ else
+ {
+ this.screenStartPoint = this.Transform(this.StartPoint);
+ }
+
+ var d = this.screenEndPoint - this.screenStartPoint;
+ d.Normalize();
+ var n = new ScreenVector(d.Y, -d.X);
+
+ var p1 = this.screenEndPoint - (d * this.HeadLength * this.StrokeThickness);
+ var p2 = p1 + (n * this.HeadWidth * this.StrokeThickness);
+ var p3 = p1 - (n * this.HeadWidth * this.StrokeThickness);
+ var p4 = p1 + (d * this.Veeness * this.StrokeThickness);
+
+ OxyRect clippingRect = this.GetClippingRect();
+ const double MinimumSegmentLength = 4;
+
+ rc.DrawClippedLine(
+ new[] { this.screenStartPoint, p4 },
+ clippingRect,
+ MinimumSegmentLength * MinimumSegmentLength,
+ this.GetSelectableColor(this.Color),
+ this.StrokeThickness,
+ this.LineStyle,
+ this.LineJoin,
+ false);
+
+ rc.DrawClippedPolygon(
+ new[] { p3, this.screenEndPoint, p2, p4 },
+ clippingRect,
+ MinimumSegmentLength * MinimumSegmentLength,
+ this.GetSelectableColor(this.Color),
+ null);
+
+ if (!string.IsNullOrEmpty(this.Text))
+ {
+ var ha = d.X < 0 ? HorizontalAlignment.Left : HorizontalAlignment.Right;
+ var va = d.Y < 0 ? VerticalAlignment.Top : VerticalAlignment.Bottom;
+
+ var textPoint = this.screenStartPoint;
+ rc.DrawClippedText(
+ clippingRect,
+ textPoint,
+ this.Text,
+ this.ActualTextColor,
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ 0,
+ ha,
+ va);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ if ((point - this.screenStartPoint).Length < tolerance)
+ {
+ return new HitTestResult(this.screenStartPoint, null, 1);
+ }
+
+ if ((point - this.screenEndPoint).Length < tolerance)
+ {
+ return new HitTestResult(this.screenEndPoint, null, 2);
+ }
+
+ var p = ScreenPointHelper.FindPointOnLine(point, this.screenStartPoint, this.screenEndPoint);
+ if ((p - point).Length < tolerance)
+ {
+ return new HitTestResult(p);
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/EllipseAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/EllipseAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,152 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a rectangle annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Represents an ellipse annotation.
+ ///
+ public class EllipseAnnotation : TextualAnnotation
+ {
+ ///
+ /// The rectangle transformed to screen coordinates.
+ ///
+ private OxyRect screenRectangle;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EllipseAnnotation()
+ {
+ this.Stroke = OxyColors.Black;
+ this.Fill = OxyColors.LightBlue;
+ }
+
+ ///
+ /// Gets or sets the fill color.
+ ///
+ /// The fill.
+ public OxyColor Fill { get; set; }
+
+ ///
+ /// Gets or sets the stroke color.
+ ///
+ public OxyColor Stroke { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness.
+ ///
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Gets or sets the x-coordinate of the center.
+ ///
+ public double X { get; set; }
+
+ ///
+ /// Gets or sets the y-coordinate of the center.
+ ///
+ public double Y { get; set; }
+
+ ///
+ /// Gets or sets the width of the ellipse.
+ ///
+ public double Width { get; set; }
+
+ ///
+ /// Gets or sets the height of the ellipse.
+ ///
+ public double Height { get; set; }
+
+ ///
+ /// Gets or sets the text rotation (degrees).
+ ///
+ /// The text rotation in degrees.
+ public double TextRotation { get; set; }
+
+ ///
+ /// Renders the polygon annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ this.screenRectangle = OxyRect.Create(this.Transform(this.X - (Width / 2), Y - (Height / 2)), this.Transform(X + (Width / 2), Y + (Height / 2)));
+
+ // clip to the area defined by the axes
+ var clipping = this.GetClippingRect();
+
+ rc.DrawClippedEllipse(clipping, this.screenRectangle, this.Fill, this.Stroke, this.StrokeThickness);
+
+ if (!string.IsNullOrEmpty(this.Text))
+ {
+ var textPosition = this.screenRectangle.Center;
+ rc.DrawClippedText(
+ clipping,
+ textPosition,
+ this.Text,
+ this.ActualTextColor,
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ this.TextRotation,
+ HorizontalAlignment.Center,
+ VerticalAlignment.Middle);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ if (this.screenRectangle.Contains(point))
+ {
+ return new HitTestResult(point);
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/ImageAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/ImageAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,451 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a text object annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Represents a text annotation.
+ ///
+ public class ImageAnnotation : Annotation
+ {
+ ///
+ /// The actual bounds of the rendered image.
+ ///
+ private OxyRect actualBounds;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ImageAnnotation()
+ {
+ this.X = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea);
+ this.Y = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea);
+ this.OffsetX = new PlotLength(0, PlotLengthUnit.ScreenUnits);
+ this.OffsetY = new PlotLength(0, PlotLengthUnit.ScreenUnits);
+ this.Width = new PlotLength(double.NaN, PlotLengthUnit.ScreenUnits);
+ this.Height = new PlotLength(double.NaN, PlotLengthUnit.ScreenUnits);
+ this.Opacity = 1.0;
+ this.Interpolate = true;
+ this.HorizontalAlignment = OxyPlot.HorizontalAlignment.Center;
+ this.VerticalAlignment = OxyPlot.VerticalAlignment.Middle;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The image.
+ ///
+ ///
+ /// The position in screen coordinates.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ public ImageAnnotation(
+ OxyImage image,
+ ScreenPoint position,
+ HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center,
+ VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
+ : this()
+ {
+ this.ImageSource = image;
+ this.X = new PlotLength(position.X, PlotLengthUnit.ScreenUnits);
+ this.Y = new PlotLength(position.Y, PlotLengthUnit.ScreenUnits);
+ this.HorizontalAlignment = horizontalAlignment;
+ this.VerticalAlignment = verticalAlignment;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The image.
+ ///
+ ///
+ /// The position in data coordinates.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ public ImageAnnotation(
+ OxyImage image,
+ IDataPoint position,
+ HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center,
+ VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
+ : this()
+ {
+ this.ImageSource = image;
+ this.X = new PlotLength(position.X, PlotLengthUnit.Data);
+ this.Y = new PlotLength(position.Y, PlotLengthUnit.Data);
+ this.HorizontalAlignment = horizontalAlignment;
+ this.VerticalAlignment = verticalAlignment;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The image.
+ ///
+ ///
+ /// The x-coordinate relative to the plot area (0-1).
+ ///
+ ///
+ /// The y-coordinate relative to the plot area (0-1).
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ public ImageAnnotation(
+ OxyImage image,
+ double relativeX,
+ double relativeY,
+ HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center,
+ VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
+ : this()
+ {
+ this.ImageSource = image;
+ this.X = new PlotLength(relativeX, PlotLengthUnit.RelativeToPlotArea);
+ this.Y = new PlotLength(relativeY, PlotLengthUnit.RelativeToPlotArea);
+ this.HorizontalAlignment = horizontalAlignment;
+ this.VerticalAlignment = verticalAlignment;
+ }
+
+ ///
+ /// Gets or sets the image source.
+ ///
+ ///
+ /// The image source.
+ ///
+ public OxyImage ImageSource { get; set; }
+
+ ///
+ /// Gets or sets the horizontal alignment.
+ ///
+ /// The horizontal alignment.
+ public HorizontalAlignment HorizontalAlignment { get; set; }
+
+ ///
+ /// Gets or sets the X position of the image.
+ ///
+ ///
+ /// The X.
+ ///
+ public PlotLength X { get; set; }
+
+ ///
+ /// Gets or sets the Y position of the image.
+ ///
+ ///
+ /// The Y.
+ ///
+ public PlotLength Y { get; set; }
+
+ ///
+ /// Gets or sets the X offset.
+ ///
+ ///
+ /// The offset X.
+ ///
+ public PlotLength OffsetX { get; set; }
+
+ ///
+ /// Gets or sets the Y offset.
+ ///
+ ///
+ /// The offset Y.
+ ///
+ public PlotLength OffsetY { get; set; }
+
+ ///
+ /// Gets or sets the width.
+ ///
+ ///
+ /// The width.
+ ///
+ public PlotLength Width { get; set; }
+
+ ///
+ /// Gets or sets the height.
+ ///
+ ///
+ /// The height.
+ ///
+ public PlotLength Height { get; set; }
+
+ ///
+ /// Gets or sets the opacity (0-1).
+ ///
+ ///
+ /// The opacity value.
+ ///
+ public double Opacity { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to apply smooth interpolation to the image.
+ ///
+ ///
+ /// true if the image should be interpolated (using a high-quality bi-cubic interpolation); false if the nearest neighbor should be used.
+ ///
+ public bool Interpolate { get; set; }
+
+ ///
+ /// Gets or sets the vertical alignment.
+ ///
+ /// The vertical alignment.
+ public VerticalAlignment VerticalAlignment { get; set; }
+
+ ///
+ /// Renders the image annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ var p = this.GetPoint(this.X, this.Y, rc, model);
+ var o = this.GetVector(this.OffsetX, this.OffsetY, rc, model);
+ var position = p + o;
+
+ var clippingRect = this.GetClippingRect();
+
+ var imageInfo = rc.GetImageInfo(this.ImageSource);
+ if (imageInfo == null)
+ {
+ return;
+ }
+
+ var s = this.GetVector(this.Width, this.Height, rc, model);
+
+ var width = s.X;
+ var height = s.Y;
+
+ if (double.IsNaN(width) && double.IsNaN(height))
+ {
+ width = imageInfo.Width;
+ height = imageInfo.Height;
+ }
+
+ if (double.IsNaN(width))
+ {
+ width = height / imageInfo.Height * imageInfo.Width;
+ }
+
+ if (double.IsNaN(height))
+ {
+ height = width / imageInfo.Width * imageInfo.Height;
+ }
+
+ double x = position.X;
+ double y = position.Y;
+
+ if (this.HorizontalAlignment == HorizontalAlignment.Center)
+ {
+ x -= width * 0.5;
+ }
+
+ if (this.HorizontalAlignment == HorizontalAlignment.Right)
+ {
+ x -= width;
+ }
+
+ if (this.VerticalAlignment == VerticalAlignment.Middle)
+ {
+ y -= height * 0.5;
+ }
+
+ if (this.VerticalAlignment == VerticalAlignment.Bottom)
+ {
+ y -= height;
+ }
+
+ this.actualBounds = new OxyRect(x, y, width, height);
+
+ if (this.X.Unit == PlotLengthUnit.Data || this.Y.Unit == PlotLengthUnit.Data)
+ {
+ rc.DrawClippedImage(clippingRect, this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
+ }
+ else
+ {
+ rc.DrawImage(this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ if (this.actualBounds.Contains(point))
+ {
+ return new HitTestResult(point);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the point.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The y.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The model.
+ ///
+ ///
+ /// The point in screen coordinates.
+ ///
+ protected ScreenPoint GetPoint(PlotLength x, PlotLength y, IRenderContext rc, PlotModel model)
+ {
+ if (x.Unit == PlotLengthUnit.Data || y.Unit == PlotLengthUnit.Data)
+ {
+ return this.XAxis.Transform(x.Value, y.Value, this.YAxis);
+ }
+
+ double sx;
+ double sy;
+ switch (x.Unit)
+ {
+ case PlotLengthUnit.RelativeToPlotArea:
+ sx = model.PlotArea.Left + (model.PlotArea.Width * x.Value);
+ break;
+ case PlotLengthUnit.RelativeToViewport:
+ sx = model.Width * x.Value;
+ break;
+ default:
+ sx = x.Value;
+ break;
+ }
+
+ switch (y.Unit)
+ {
+ case PlotLengthUnit.RelativeToPlotArea:
+ sy = model.PlotArea.Top + (model.PlotArea.Height * y.Value);
+ break;
+ case PlotLengthUnit.RelativeToViewport:
+ sy = model.Height * y.Value;
+ break;
+ default:
+ sy = y.Value;
+ break;
+ }
+
+ return new ScreenPoint(sx, sy);
+ }
+
+ ///
+ /// Gets the vector.
+ ///
+ ///
+ /// The x component.
+ ///
+ ///
+ /// The y component.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The model.
+ ///
+ ///
+ /// The vector in screen coordinates.
+ ///
+ protected ScreenVector GetVector(PlotLength x, PlotLength y, IRenderContext rc, PlotModel model)
+ {
+ double sx;
+ double sy;
+
+ switch (x.Unit)
+ {
+ case PlotLengthUnit.Data:
+ sx = this.XAxis.Transform(x.Value) - this.XAxis.Transform(0);
+ break;
+ case PlotLengthUnit.RelativeToPlotArea:
+ sx = model.PlotArea.Width * x.Value;
+ break;
+ case PlotLengthUnit.RelativeToViewport:
+ sx = model.Width * x.Value;
+ break;
+ default:
+ sx = x.Value;
+ break;
+ }
+
+ switch (y.Unit)
+ {
+ case PlotLengthUnit.Data:
+ sy = this.YAxis.Transform(y.Value) - this.YAxis.Transform(0);
+ break;
+ case PlotLengthUnit.RelativeToPlotArea:
+ sy = model.PlotArea.Height * y.Value;
+ break;
+ case PlotLengthUnit.RelativeToViewport:
+ sy = model.Height * y.Value;
+ break;
+ default:
+ sy = y.Value;
+ break;
+ }
+
+ return new ScreenVector(sx, sy);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/LineAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/LineAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,528 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Specify the orientation of the annotation text
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Specifes the orientation of the annotation text
+ ///
+ public enum AnnotationTextOrientation
+ {
+ ///
+ /// Horizontal text.
+ ///
+ Horizontal,
+
+ ///
+ /// Vertical text.
+ ///
+ Vertical,
+
+ ///
+ /// Oriented along the line.
+ ///
+ AlongLine
+ }
+
+ ///
+ /// Represents a line annotation.
+ ///
+ public class LineAnnotation : TextualAnnotation
+ {
+ ///
+ /// The points of the line, transformed to screen coordinates.
+ ///
+ private IList screenPoints;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LineAnnotation()
+ {
+ this.Type = LineAnnotationType.LinearEquation;
+ this.MinimumX = double.MinValue;
+ this.MaximumX = double.MaxValue;
+ this.MinimumY = double.MinValue;
+ this.MaximumY = double.MaxValue;
+ this.Color = OxyColors.Blue;
+ this.StrokeThickness = 1;
+ this.LineStyle = LineStyle.Dash;
+ this.LineJoin = OxyPenLineJoin.Miter;
+ this.ClipByXAxis = true;
+ this.ClipByYAxis = true;
+
+ this.TextPosition = 1;
+ this.TextOrientation = AnnotationTextOrientation.AlongLine;
+ this.TextMargin = 12;
+ this.TextHorizontalAlignment = HorizontalAlignment.Right;
+ this.TextVerticalAlignment = VerticalAlignment.Top;
+ }
+
+ ///
+ /// Gets or sets the color of the line.
+ ///
+ public OxyColor Color { get; set; }
+
+ ///
+ /// Gets or sets the y=f(x) equation when Type is Equation.
+ ///
+ public Func Equation { get; set; }
+
+ ///
+ /// Gets or sets the y-intercept when Type is LinearEquation.
+ ///
+ /// The intercept value.
+ ///
+ /// Linear equation y-intercept (the b in y=mx+b).
+ /// http://en.wikipedia.org/wiki/Linear_equation
+ ///
+ public double Intercept { get; set; }
+
+ ///
+ /// Gets or sets the line join.
+ ///
+ /// The line join.
+ public OxyPenLineJoin LineJoin { get; set; }
+
+ ///
+ /// Gets or sets the line style.
+ ///
+ /// The line style.
+ public LineStyle LineStyle { get; set; }
+
+ ///
+ /// Gets or sets the maximum X coordinate for the line.
+ ///
+ public double MaximumX { get; set; }
+
+ ///
+ /// Gets or sets the maximum Y coordinate for the line.
+ ///
+ public double MaximumY { get; set; }
+
+ ///
+ /// Gets or sets the minimum X coordinate for the line.
+ ///
+ public double MinimumX { get; set; }
+
+ ///
+ /// Gets or sets the minimum Y coordinate for the line.
+ ///
+ public double MinimumY { get; set; }
+
+ ///
+ /// Gets or sets the slope when Type is LinearEquation.
+ ///
+ /// The slope value.
+ ///
+ /// Linear equation slope (the m in y=mx+b)
+ /// http://en.wikipedia.org/wiki/Linear_equation
+ ///
+ public double Slope { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness.
+ ///
+ /// The stroke thickness.
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Gets or sets the text horizontal alignment.
+ ///
+ /// The text horizontal alignment.
+ public HorizontalAlignment TextHorizontalAlignment { get; set; }
+
+ ///
+ /// Gets or sets the text margin (along the line).
+ ///
+ /// The text margin.
+ public double TextMargin { get; set; }
+
+ ///
+ /// Gets or sets the text padding (in the direction of the text).
+ ///
+ /// The text padding.
+ public double TextPadding { get; set; }
+
+ ///
+ /// Gets or sets the text orientation.
+ ///
+ /// The text orientation.
+ public AnnotationTextOrientation TextOrientation { get; set; }
+
+ ///
+ /// Gets or sets the text position fraction.
+ ///
+ /// The text position in the interval [0,1].
+ ///
+ /// Positions smaller than 0.25 are left aligned at the start of the line
+ /// Positions larger than 0.75 are right aligned at the end of the line
+ /// Other positions are center aligned at the specified position
+ ///
+ public double TextPosition { get; set; }
+
+ ///
+ /// Gets or sets the vertical alignment of text (above or below the line).
+ ///
+ public VerticalAlignment TextVerticalAlignment { get; set; }
+
+ ///
+ /// Gets or sets the type of line equation.
+ ///
+ public LineAnnotationType Type { get; set; }
+
+ ///
+ /// Gets or sets the X position for vertical lines (only for Type==Vertical).
+ ///
+ public double X { get; set; }
+
+ ///
+ /// Gets or sets the Y position for horizontal lines (only for Type==Horizontal)
+ ///
+ public double Y { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to clip the annotation line by the X axis range.
+ ///
+ /// true if clipping by the X axis is enabled; otherwise, false.
+ public bool ClipByXAxis { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to clip the annotation line by the Y axis range.
+ ///
+ /// true if clipping by the Y axis is enabled; otherwise, false.
+ public bool ClipByYAxis { get; set; }
+
+ ///
+ /// Renders the line annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ bool aliased = false;
+
+ double actualMinimumX = Math.Max(this.MinimumX, this.XAxis.ActualMinimum);
+ double actualMaximumX = Math.Min(this.MaximumX, this.XAxis.ActualMaximum);
+ double actualMinimumY = Math.Max(this.MinimumY, this.YAxis.ActualMinimum);
+ double actualMaximumY = Math.Min(this.MaximumY, this.YAxis.ActualMaximum);
+
+ if (!this.ClipByXAxis)
+ {
+ double right = XAxis.InverseTransform(PlotModel.PlotArea.Right);
+ double left = XAxis.InverseTransform(PlotModel.PlotArea.Left);
+ actualMaximumX = Math.Max(left, right);
+ actualMinimumX = Math.Min(left, right);
+ }
+
+ if (!this.ClipByYAxis)
+ {
+ double bottom = YAxis.InverseTransform(PlotModel.PlotArea.Bottom);
+ double top = YAxis.InverseTransform(PlotModel.PlotArea.Top);
+ actualMaximumY = Math.Max(top, bottom);
+ actualMinimumY = Math.Min(top, bottom);
+ }
+
+ // y=f(x)
+ Func fx = null;
+
+ // x=f(y)
+ Func fy = null;
+
+ switch (this.Type)
+ {
+ case LineAnnotationType.Horizontal:
+ fx = x => this.Y;
+ break;
+ case LineAnnotationType.Vertical:
+ fy = y => this.X;
+ break;
+ case LineAnnotationType.EquationY:
+ fx = this.Equation;
+ break;
+ case LineAnnotationType.EquationX:
+ fy = this.Equation;
+ break;
+ default:
+ fx = x => (this.Slope * x) + this.Intercept;
+ break;
+ }
+
+ var points = new List();
+
+ bool isCurvedLine = !(this.XAxis is LinearAxis) || !(this.YAxis is LinearAxis) || this.Type == LineAnnotationType.EquationY;
+
+ if (!isCurvedLine)
+ {
+ // we only need to calculate two points if it is a straight line
+ if (fx != null)
+ {
+ points.Add(new DataPoint(actualMinimumX, fx(actualMinimumX)));
+ points.Add(new DataPoint(actualMaximumX, fx(actualMaximumX)));
+ }
+ else if (fy != null)
+ {
+ points.Add(new DataPoint(fy(actualMinimumY), actualMinimumY));
+ points.Add(new DataPoint(fy(actualMaximumY), actualMaximumY));
+ }
+
+ if (this.Type == LineAnnotationType.Horizontal || this.Type == LineAnnotationType.Vertical)
+ {
+ // use aliased line drawing for horizontal and vertical lines
+ aliased = true;
+ }
+ }
+ else
+ {
+ if (fx != null)
+ {
+ double x = actualMinimumX;
+
+ // todo: the step size should be adaptive
+ double dx = (actualMaximumX - actualMinimumX) / 100;
+ while (true)
+ {
+ points.Add(new DataPoint(x, fx(x)));
+ if (x > actualMaximumX)
+ {
+ break;
+ }
+
+ x += dx;
+ }
+ }
+ else if (fy != null)
+ {
+ double y = actualMinimumY;
+
+ // todo: the step size should be adaptive
+ double dy = (actualMaximumY - actualMinimumY) / 100;
+ while (true)
+ {
+ points.Add(new DataPoint(fy(y), y));
+ if (y > actualMaximumY)
+ {
+ break;
+ }
+
+ y += dy;
+ }
+ }
+ }
+
+ // transform to screen coordinates
+ this.screenPoints = points.Select(p => this.Transform(p)).ToList();
+
+ // clip to the area defined by the axes
+ var clippingRectangle = OxyRect.Create(
+ this.ClipByXAxis ? this.XAxis.ScreenMin.X : PlotModel.PlotArea.Left,
+ this.ClipByYAxis ? this.YAxis.ScreenMin.Y : PlotModel.PlotArea.Top,
+ this.ClipByXAxis ? this.XAxis.ScreenMax.X : PlotModel.PlotArea.Right,
+ this.ClipByYAxis ? this.YAxis.ScreenMax.Y : PlotModel.PlotArea.Bottom);
+
+ const double MinimumSegmentLength = 4;
+
+ IList clippedPoints = null;
+
+ rc.DrawClippedLine(
+ this.screenPoints,
+ clippingRectangle,
+ MinimumSegmentLength * MinimumSegmentLength,
+ this.GetSelectableColor(this.Color),
+ this.StrokeThickness,
+ this.LineStyle,
+ this.LineJoin,
+ aliased,
+ pts => clippedPoints = pts);
+
+ ScreenPoint position;
+ double angle;
+ double margin = this.TextMargin;
+
+ if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
+ {
+ margin = 0;
+ }
+ else
+ {
+ margin *= this.TextPosition < 0.5 ? 1 : -1;
+ }
+
+ if (clippedPoints != null && GetPointAtRelativeDistance(clippedPoints, this.TextPosition, margin, out position, out angle))
+ {
+ if (angle < -90)
+ {
+ angle += 180;
+ }
+
+ if (angle > 90)
+ {
+ angle -= 180;
+ }
+
+ switch (this.TextOrientation)
+ {
+ case AnnotationTextOrientation.Horizontal:
+ angle = 0;
+ break;
+ case AnnotationTextOrientation.Vertical:
+ angle = -90;
+ break;
+ }
+
+ // Apply 'padding' to the position
+ var angleInRadians = angle / 180 * Math.PI;
+ var f = 1;
+
+ if (this.TextHorizontalAlignment == HorizontalAlignment.Right)
+ {
+ f = -1;
+ }
+
+ if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
+ {
+ f = 0;
+ }
+
+ position.X += f * this.TextPadding * Math.Cos(angleInRadians);
+ position.Y += f * this.TextPadding * Math.Sin(angleInRadians);
+
+ var cs = new CohenSutherlandClipping(clippingRectangle);
+ if (!string.IsNullOrEmpty(this.Text) && cs.IsInside(position))
+ {
+ rc.DrawClippedText(
+ clippingRectangle,
+ position,
+ this.Text,
+ this.ActualTextColor,
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ angle,
+ this.TextHorizontalAlignment,
+ this.TextVerticalAlignment);
+ }
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ /// The point.
+ /// The tolerance.
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ var nearestPoint = ScreenPointHelper.FindNearestPointOnPolyline(point, this.screenPoints);
+ double dist = (point - nearestPoint).Length;
+ if (dist < tolerance)
+ {
+ return new HitTestResult(nearestPoint);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the point on a curve at the specified relative distance along the curve.
+ ///
+ ///
+ /// The curve points.
+ ///
+ ///
+ /// The relative distance along the curve.
+ ///
+ ///
+ /// The margins.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The angle.
+ ///
+ ///
+ /// True if a position was found.
+ ///
+ private static bool GetPointAtRelativeDistance(
+ IList pts, double p, double margin, out ScreenPoint position, out double angle)
+ {
+ if (pts == null || pts.Count == 0)
+ {
+ position = new ScreenPoint();
+ angle = 0;
+ return false;
+ }
+
+ double length = 0;
+ for (int i = 1; i < pts.Count; i++)
+ {
+ length += (pts[i] - pts[i - 1]).Length;
+ }
+
+ double l = (length * p) + margin;
+ length = 0;
+ for (int i = 1; i < pts.Count; i++)
+ {
+ double dl = (pts[i] - pts[i - 1]).Length;
+ if (l >= length && l <= length + dl)
+ {
+ double f = (l - length) / dl;
+ double x = (pts[i].X * f) + (pts[i - 1].X * (1 - f));
+ double y = (pts[i].Y * f) + (pts[i - 1].Y * (1 - f));
+ position = new ScreenPoint(x, y);
+ double dx = pts[i].X - pts[i - 1].X;
+ double dy = pts[i].Y - pts[i - 1].Y;
+ angle = Math.Atan2(dy, dx) / Math.PI * 180;
+ return true;
+ }
+
+ length += dl;
+ }
+
+ position = pts[0];
+ angle = 0;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/LineAnnotationType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/LineAnnotationType.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,62 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The line annotation type.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Specifies the definition of the line in a .
+ ///
+ public enum LineAnnotationType
+ {
+ ///
+ /// Horizontal line given by the Y property
+ ///
+ Horizontal,
+
+ ///
+ /// Vertical line given by the X property
+ ///
+ Vertical,
+
+ ///
+ /// Linear equation y=mx+b given by the Slope and Intercept properties
+ ///
+ LinearEquation,
+
+ ///
+ /// Curve equation x=f(y) given by the Equation property
+ ///
+ EquationX,
+
+ ///
+ /// Curve equation y=f(x) given by the Equation property
+ ///
+ EquationY
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/PolygonAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/PolygonAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,166 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a polygon annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Represents a polygon annotation.
+ ///
+ public class PolygonAnnotation : TextualAnnotation
+ {
+ ///
+ /// The polygon points transformed to screen coordinates.
+ ///
+ private IList screenPoints;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PolygonAnnotation()
+ {
+ this.Color = OxyColors.Blue;
+ this.Fill = OxyColors.LightBlue;
+ this.StrokeThickness = 1;
+ this.LineStyle = LineStyle.Solid;
+ this.LineJoin = OxyPenLineJoin.Miter;
+ }
+
+ ///
+ /// Gets or sets the color of the line.
+ ///
+ public OxyColor Color { get; set; }
+
+ ///
+ /// Gets or sets the fill color.
+ ///
+ /// The fill.
+ public OxyColor Fill { get; set; }
+
+ ///
+ /// Gets or sets the line join.
+ ///
+ /// The line join.
+ public OxyPenLineJoin LineJoin { get; set; }
+
+ ///
+ /// Gets or sets the line style.
+ ///
+ /// The line style.
+ public LineStyle LineStyle { get; set; }
+
+ ///
+ /// Gets or sets the points.
+ ///
+ /// The points.
+ public IList Points { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness.
+ ///
+ /// The stroke thickness.
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Renders the polygon annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+ if (this.Points == null)
+ {
+ return;
+ }
+
+ // transform to screen coordinates
+ this.screenPoints = this.Points.Select(p => this.Transform(p)).ToList();
+ if (this.screenPoints.Count == 0)
+ {
+ return;
+ }
+
+ // clip to the area defined by the axes
+ var clipping = this.GetClippingRect();
+
+ const double MinimumSegmentLength = 4;
+
+ rc.DrawClippedPolygon(
+ this.screenPoints,
+ clipping,
+ MinimumSegmentLength * MinimumSegmentLength,
+ this.GetSelectableFillColor(this.Fill),
+ this.GetSelectableColor(this.Color),
+ this.StrokeThickness,
+ this.LineStyle,
+ this.LineJoin);
+
+ if (!string.IsNullOrEmpty(this.Text))
+ {
+ var textPosition = ScreenPointHelper.GetCentroid(this.screenPoints);
+
+ rc.DrawClippedText(
+ clipping,
+ textPosition,
+ this.Text,
+ this.ActualTextColor,
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ 0,
+ HorizontalAlignment.Center,
+ VerticalAlignment.Middle);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ return ScreenPointHelper.IsPointInPolygon(point, this.screenPoints) ? new HitTestResult(point) : null;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/RectangleAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/RectangleAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,174 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a rectangle annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Represents a rectangle annotation.
+ ///
+ public class RectangleAnnotation : TextualAnnotation
+ {
+ ///
+ /// The rectangle transformed to screen coordinates.
+ ///
+ private OxyRect screenRectangle;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public RectangleAnnotation()
+ {
+ this.Stroke = OxyColors.Black;
+ this.Fill = OxyColors.LightBlue;
+ this.MinimumX = double.MinValue;
+ this.MaximumX = double.MaxValue;
+ this.MinimumY = double.MinValue;
+ this.MaximumY = double.MaxValue;
+ this.TextRotation = 0;
+ }
+
+ ///
+ /// Gets or sets the fill color.
+ ///
+ /// The fill.
+ public OxyColor Fill { get; set; }
+
+ ///
+ /// Gets or sets the stroke color.
+ ///
+ public OxyColor Stroke { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness.
+ ///
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum X.
+ ///
+ /// The minimum X.
+ public double MinimumX { get; set; }
+
+ ///
+ /// Gets or sets the maximum X.
+ ///
+ /// The maximum X.
+ public double MaximumX { get; set; }
+
+ ///
+ /// Gets or sets the minimum Y.
+ ///
+ /// The minimum Y.
+ public double MinimumY { get; set; }
+
+ ///
+ /// Gets or sets the maximum Y.
+ ///
+ /// The maximum Y.
+ public double MaximumY { get; set; }
+
+ ///
+ /// Gets or sets the text rotation (degrees).
+ ///
+ /// The text rotation in degrees.
+ public double TextRotation { get; set; }
+
+ ///
+ /// Renders the polygon annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ double x0 = double.IsNaN(this.MinimumX) || this.MinimumX.Equals(double.MinValue)
+ ? this.XAxis.ActualMinimum
+ : this.MinimumX;
+ double x1 = double.IsNaN(this.MaximumX) || this.MaximumX.Equals(double.MaxValue)
+ ? this.XAxis.ActualMaximum
+ : this.MaximumX;
+ double y0 = double.IsNaN(this.MinimumY) || this.MinimumY.Equals(double.MinValue)
+ ? this.YAxis.ActualMinimum
+ : this.MinimumY;
+ double y1 = double.IsNaN(this.MaximumY) || this.MaximumY.Equals(double.MaxValue)
+ ? this.YAxis.ActualMaximum
+ : this.MaximumY;
+
+ this.screenRectangle = OxyRect.Create(this.Transform(x0, y0), this.Transform(x1, y1));
+
+ // clip to the area defined by the axes
+ var clipping = this.GetClippingRect();
+
+ rc.DrawClippedRectangle(this.screenRectangle, clipping, this.Fill, this.Stroke, this.StrokeThickness);
+
+ if (!string.IsNullOrEmpty(this.Text))
+ {
+ var textPosition = this.screenRectangle.Center;
+ rc.DrawClippedText(
+ clipping,
+ textPosition,
+ this.Text,
+ this.ActualTextColor,
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ this.TextRotation,
+ HorizontalAlignment.Center,
+ VerticalAlignment.Middle);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ if (this.screenRectangle.Contains(point))
+ {
+ return new HitTestResult(point);
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/TextAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/TextAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,254 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a text object annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Annotations
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Represents a text annotation.
+ ///
+ public class TextAnnotation : TextualAnnotation
+ {
+ ///
+ /// The actual bounds of the text.
+ ///
+ private IList actualBounds;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TextAnnotation()
+ {
+ this.TextColor = OxyColors.Blue;
+ this.Stroke = OxyColors.Black;
+ this.Background = null;
+ this.StrokeThickness = 1;
+ this.Rotation = 0;
+ this.HorizontalAlignment = OxyPlot.HorizontalAlignment.Center;
+ this.VerticalAlignment = OxyPlot.VerticalAlignment.Bottom;
+ this.Padding = new OxyThickness(4);
+ }
+
+ ///
+ /// Gets or sets the fill color of the background rectangle.
+ ///
+ /// The background.
+ public OxyColor Background { get; set; }
+
+ ///
+ /// Gets or sets the horizontal alignment.
+ ///
+ /// The horizontal alignment.
+ public HorizontalAlignment HorizontalAlignment { get; set; }
+
+ ///
+ /// Gets or sets the position offset (screen coordinates).
+ ///
+ /// The offset.
+ public ScreenVector Offset { get; set; }
+
+ ///
+ /// Gets or sets the padding of the background rectangle.
+ ///
+ /// The padding.
+ public OxyThickness Padding { get; set; }
+
+ ///
+ /// Gets or sets the position of the text.
+ ///
+ public DataPoint Position { get; set; }
+
+ ///
+ /// Gets or sets the rotation angle (degrees).
+ ///
+ /// The rotation.
+ public double Rotation { get; set; }
+
+ ///
+ /// Gets or sets the stroke color of the background rectangle.
+ ///
+ /// The stroke color.
+ public OxyColor Stroke { get; set; }
+
+ ///
+ /// Gets or sets the stroke thickness of the background rectangle.
+ ///
+ /// The stroke thickness.
+ public double StrokeThickness { get; set; }
+
+ ///
+ /// Gets or sets the vertical alignment.
+ ///
+ /// The vertical alignment.
+ public VerticalAlignment VerticalAlignment { get; set; }
+
+ ///
+ /// Renders the text annotation.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+
+ var position = this.Transform(this.Position);
+ position.X += this.Offset.X;
+ position.Y += this.Offset.Y;
+
+ var clippingRect = this.GetClippingRect();
+
+ var textSize = rc.MeasureText(this.Text, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
+
+ const double MinDistSquared = 4;
+
+ this.actualBounds = GetTextBounds(
+ position, textSize, this.Padding, this.Rotation, this.HorizontalAlignment, this.VerticalAlignment);
+ rc.DrawClippedPolygon(
+ this.actualBounds, clippingRect, MinDistSquared, this.Background, this.Stroke, this.StrokeThickness);
+
+ rc.DrawClippedText(
+ clippingRect,
+ position,
+ this.Text,
+ this.GetSelectableFillColor(this.ActualTextColor),
+ this.ActualFont,
+ this.ActualFontSize,
+ this.ActualFontWeight,
+ this.Rotation,
+ this.HorizontalAlignment,
+ this.VerticalAlignment);
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ if (this.actualBounds == null)
+ {
+ return null;
+ }
+
+ // Todo: see if performance can be improved by checking rectangle (with rotation and alignment), not polygon
+ return ScreenPointHelper.IsPointInPolygon(point, this.actualBounds) ? new HitTestResult(point) : null;
+ }
+
+ ///
+ /// Gets the coordinates of the (rotated) background rectangle.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The size.
+ ///
+ ///
+ /// The padding.
+ ///
+ ///
+ /// The rotation.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ ///
+ /// The background rectangle coordinates.
+ ///
+ private static IList GetTextBounds(
+ ScreenPoint position,
+ OxySize size,
+ OxyThickness padding,
+ double rotation,
+ HorizontalAlignment horizontalAlignment,
+ VerticalAlignment verticalAlignment)
+ {
+ double left, right, top, bottom;
+ switch (horizontalAlignment)
+ {
+ case HorizontalAlignment.Center:
+ left = -size.Width * 0.5;
+ right = -left;
+ break;
+ case HorizontalAlignment.Right:
+ left = -size.Width;
+ right = 0;
+ break;
+ default:
+ left = 0;
+ right = size.Width;
+ break;
+ }
+
+ switch (verticalAlignment)
+ {
+ case VerticalAlignment.Middle:
+ top = -size.Height * 0.5;
+ bottom = -top;
+ break;
+ case VerticalAlignment.Bottom:
+ top = -size.Height;
+ bottom = 0;
+ break;
+ default:
+ top = 0;
+ bottom = size.Height;
+ break;
+ }
+
+ double cost = Math.Cos(rotation / 180 * Math.PI);
+ double sint = Math.Sin(rotation / 180 * Math.PI);
+ var u = new ScreenVector(cost, sint);
+ var v = new ScreenVector(-sint, cost);
+ var polygon = new ScreenPoint[4];
+ polygon[0] = position + (u * (left - padding.Left)) + (v * (top - padding.Top));
+ polygon[1] = position + (u * (right + padding.Right)) + (v * (top - padding.Top));
+ polygon[2] = position + (u * (right + padding.Right)) + (v * (bottom + padding.Bottom));
+ polygon[3] = position + (u * (left - padding.Left)) + (v * (bottom + padding.Bottom));
+ return polygon;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/TextualAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/TextualAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,46 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides an abstract base class for annotations that contains text.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot.Annotations
+{
+ ///
+ /// Provides an abstract base class for annotations that contains text.
+ ///
+ public abstract class TextualAnnotation : Annotation
+ {
+ ///
+ /// Gets or sets the annotation text.
+ ///
+ ///
+ /// The text.
+ ///
+ public string Text { get; set; }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Annotations/TileMapAnnotation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Annotations/TileMapAnnotation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,457 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides a tile map annotation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot.Annotations
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.IO;
+ using System.Net;
+ using System.Threading;
+
+ ///
+ /// Provides a tile map annotation.
+ ///
+ ///
+ /// The longitude and latitude range of the map is defined by the range of the x and y axis, respectively.
+ ///
+ public class TileMapAnnotation : Annotation
+ {
+ ///
+ /// The image cache.
+ ///
+ private readonly Dictionary images = new Dictionary();
+
+ ///
+ /// The download queue.
+ ///
+ private readonly Queue queue = new Queue();
+
+ ///
+ /// The current number of downloads
+ ///
+ private int numberOfDownloads;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TileMapAnnotation()
+ {
+ this.TileSize = 256;
+ this.MinZoomLevel = 0;
+ this.MaxZoomLevel = 20;
+ this.Opacity = 1.0;
+ this.MaxNumberOfDownloads = 8;
+ }
+
+ ///
+ /// Gets or sets the max number of simultaneous downloads.
+ ///
+ ///
+ /// The max number of downloads.
+ ///
+ public int MaxNumberOfDownloads { get; set; }
+
+ ///
+ /// Gets or sets the URL.
+ ///
+ ///
+ /// The URL.
+ ///
+ public string Url { get; set; }
+
+ ///
+ /// Gets or sets the copyright notice.
+ ///
+ ///
+ /// The copyright notice.
+ ///
+ public string CopyrightNotice { get; set; }
+
+ ///
+ /// Gets or sets the size of the tiles.
+ ///
+ ///
+ /// The size of the tiles.
+ ///
+ public int TileSize { get; set; }
+
+ ///
+ /// Gets or sets the min zoom level.
+ ///
+ ///
+ /// The min zoom level.
+ ///
+ public int MinZoomLevel { get; set; }
+
+ ///
+ /// Gets or sets the max zoom level.
+ ///
+ ///
+ /// The max zoom level.
+ ///
+ public int MaxZoomLevel { get; set; }
+
+ ///
+ /// Gets or sets the opacity.
+ ///
+ ///
+ /// The opacity.
+ ///
+ public double Opacity { get; set; }
+
+ ///
+ /// Renders the annotation on the specified context.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The model.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model)
+ {
+ base.Render(rc, model);
+ var clippingRect = this.GetClippingRect();
+ var lon0 = this.XAxis.ActualMinimum;
+ var lon1 = this.XAxis.ActualMaximum;
+ var lat0 = this.YAxis.ActualMinimum;
+ var lat1 = this.YAxis.ActualMaximum;
+
+ // the desired number of tiles horizontally
+ double tilesx = model.Width / this.TileSize;
+
+ // calculate the desired zoom level
+ var n = tilesx / (((lon1 + 180) / 360) - ((lon0 + 180) / 360));
+ var zoom = (int)Math.Round(Math.Log(n) / Math.Log(2));
+ if (zoom < this.MinZoomLevel)
+ {
+ zoom = this.MinZoomLevel;
+ }
+
+ if (zoom > this.MaxZoomLevel)
+ {
+ zoom = this.MaxZoomLevel;
+ }
+
+ // find tile coordinates for the corners
+ double x0, y0;
+ LatLonToTile(lat0, lon0, zoom, out x0, out y0);
+ double x1, y1;
+ LatLonToTile(lat1, lon1, zoom, out x1, out y1);
+
+ double xmax = Math.Max(x0, x1);
+ double xmin = Math.Min(x0, x1);
+ double ymax = Math.Max(y0, y1);
+ double ymin = Math.Min(y0, y1);
+
+ // Add the tiles
+ for (var x = (int)xmin; x < xmax; x++)
+ {
+ for (var y = (int)ymin; y < ymax; y++)
+ {
+ string uri = this.GetTileUri(x, y, zoom);
+ var img = this.GetImage(uri, rc.RendersToScreen);
+
+ if (img == null)
+ {
+ continue;
+ }
+
+ // transform from tile coordinates to lat/lon
+ double latitude0, latitude1, longitude0, longitude1;
+ TileToLatLon(x, y, zoom, out latitude0, out longitude0);
+ TileToLatLon(x + 1, y + 1, zoom, out latitude1, out longitude1);
+
+ // transform from lat/lon to screen coordinates
+ var s00 = this.Transform(longitude0, latitude0);
+ var s11 = this.Transform(longitude1, latitude1);
+
+ var r = OxyRect.Create(s00.X, s00.Y, s11.X, s11.Y);
+
+ // draw the image
+ rc.DrawClippedImage(clippingRect, img, r.Left, r.Top, r.Width, r.Height, this.Opacity, true);
+ }
+ }
+
+ // draw the copyright notice
+ var p = new ScreenPoint(clippingRect.Right - 5, clippingRect.Bottom - 5);
+ var textSize = rc.MeasureText(this.CopyrightNotice, null, 12);
+ rc.DrawRectangle(new OxyRect(p.X - textSize.Width - 2, p.Y - textSize.Height - 2, textSize.Width + 4, textSize.Height + 4), OxyColors.White.ChangeAlpha(200), null);
+
+ rc.DrawText(
+ p,
+ this.CopyrightNotice,
+ OxyColors.Black,
+ null,
+ 12,
+ 500,
+ 0,
+ HorizontalAlignment.Right,
+ VerticalAlignment.Bottom);
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A hit test result.
+ ///
+ protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
+ {
+ return null;
+ }
+
+ ///
+ /// Transforms a position to a tile coordinate.
+ ///
+ /// The latitude.
+ /// The longitude.
+ /// The zoom.
+ /// The x.
+ /// The y.
+ private static void LatLonToTile(double latitude, double longitude, int zoom, out double x, out double y)
+ {
+ // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+ int n = 1 << zoom;
+ double lat = latitude / 180 * Math.PI;
+ x = (longitude + 180.0) / 360.0 * n;
+ y = (1.0 - Math.Log(Math.Tan(lat) + 1.0 / Math.Cos(lat)) / Math.PI) / 2.0 * n;
+ }
+
+ ///
+ /// Transforms a tile coordinate (x,y) to a position.
+ ///
+ /// The x.
+ /// The y.
+ /// The zoom.
+ /// The latitude.
+ /// The longitude.
+ private static void TileToLatLon(double x, double y, int zoom, out double latitude, out double longitude)
+ {
+ int n = 1 << zoom;
+ longitude = (x / n * 360.0) - 180.0;
+ double lat = Math.Atan(Math.Sinh(Math.PI * (1 - (2 * y / n))));
+ latitude = lat * 180.0 / Math.PI;
+ }
+
+ ///
+ /// Gets the image from the specified uri.
+ ///
+ /// The URI.
+ /// Get the image asynchronously if set to true. The plot model will be invalidated when the image has been downloaded.
+ ///
+ /// The image.
+ ///
+ ///
+ /// This method gets the image from cache, or starts an async download.
+ ///
+ private OxyImage GetImage(string uri, bool async)
+ {
+ OxyImage img;
+ if (this.images.TryGetValue(uri, out img))
+ {
+ return img;
+ }
+
+ if (!async)
+ {
+ return this.Download(uri);
+ }
+
+ lock (this.queue)
+ {
+ // 'reserve' an image (otherwise multiple downloads of the same uri may happen)
+ this.images[uri] = null;
+ this.queue.Enqueue(uri);
+ }
+
+ this.BeginDownload();
+ return null;
+ }
+
+ ///
+ /// Downloads the image from the specified URI.
+ ///
+ /// The URI.
+ /// The image
+ private OxyImage Download(string uri)
+ {
+ OxyImage img = null;
+ var mre = new ManualResetEvent(false);
+ var request = (HttpWebRequest)WebRequest.Create(uri);
+ request.Method = "GET";
+ request.BeginGetResponse(
+ r =>
+ {
+ try
+ {
+ if (request.HaveResponse)
+ {
+ var response = request.EndGetResponse(r);
+ var stream = response.GetResponseStream();
+
+ var ms = new MemoryStream();
+ stream.CopyTo(ms);
+ var buffer = ms.ToArray();
+
+ img = new OxyImage(buffer);
+ this.images[uri] = img;
+ }
+
+ }
+ catch (Exception e)
+ {
+ var ie = e;
+ while (ie != null)
+ {
+ System.Diagnostics.Debug.WriteLine(ie.Message);
+ ie = ie.InnerException;
+ }
+ }
+ finally
+ {
+ mre.Set();
+ }
+ },
+ request);
+
+ mre.WaitOne();
+ return img;
+ }
+
+ ///
+ /// Starts the next download in the queue.
+ ///
+ private void BeginDownload()
+ {
+ if (this.numberOfDownloads >= this.MaxNumberOfDownloads)
+ {
+ return;
+ }
+
+ string uri = this.queue.Dequeue();
+ var request = (HttpWebRequest)WebRequest.Create(uri);
+ request.Method = "GET";
+ Interlocked.Increment(ref this.numberOfDownloads);
+ request.BeginGetResponse(
+ r =>
+ {
+ Interlocked.Decrement(ref this.numberOfDownloads);
+ try
+ {
+ if (request.HaveResponse)
+ {
+ var response = request.EndGetResponse(r);
+ var stream = response.GetResponseStream();
+ this.DownloadCompleted(uri, stream);
+ }
+ }
+ catch (Exception e)
+ {
+ var ie = e;
+ while (ie != null)
+ {
+ System.Diagnostics.Debug.WriteLine(ie.Message);
+ ie = ie.InnerException;
+ }
+ }
+ },
+ request);
+ }
+
+ ///
+ /// The download completed, set the image.
+ ///
+ /// The URI.
+ /// The result.
+ private void DownloadCompleted(string uri, Stream result)
+ {
+ if (result == null)
+ {
+ return;
+ }
+
+ var ms = new MemoryStream();
+ result.CopyTo(ms);
+ var buffer = ms.ToArray();
+
+ var img = new OxyImage(buffer);
+ this.images[uri] = img;
+
+ lock (this.queue)
+ {
+ // Clear old items in the queue, new ones will be added when the plot is refreshed
+ foreach (var queuedUri in this.queue)
+ {
+ // Remove the 'reserved' image
+ this.images.Remove(queuedUri);
+ }
+
+ this.queue.Clear();
+ }
+
+ this.PlotModel.InvalidatePlot(false);
+ if (this.queue.Count > 0)
+ {
+ this.BeginDownload();
+ }
+ }
+
+ ///
+ /// Gets the tile URI.
+ ///
+ ///
+ /// The tile x.
+ ///
+ ///
+ /// The tile y.
+ ///
+ ///
+ /// The zoom.
+ ///
+ ///
+ /// The uri.
+ ///
+ private string GetTileUri(int x, int y, int zoom)
+ {
+ string url = this.Url.Replace("{X}", x.ToString(CultureInfo.InvariantCulture));
+ url = url.Replace("{Y}", y.ToString(CultureInfo.InvariantCulture));
+ return url.Replace("{Z}", zoom.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/AngleAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/AngleAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,184 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an angular axis for polar plots.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+
+ ///
+ /// Represents an angular axis for polar plots.
+ ///
+ public class AngleAxis : LinearAxis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AngleAxis()
+ {
+ this.IsPanEnabled = false;
+ this.IsZoomEnabled = false;
+ this.MajorGridlineStyle = LineStyle.Solid;
+ this.MinorGridlineStyle = LineStyle.Solid;
+ this.StartAngle = 0;
+ this.EndAngle = 360;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The minimum.
+ ///
+ ///
+ /// The maximum.
+ ///
+ ///
+ /// The major step.
+ ///
+ ///
+ /// The minor step.
+ ///
+ ///
+ /// The title.
+ ///
+ public AngleAxis(
+ double minimum = double.NaN,
+ double maximum = double.NaN,
+ double majorStep = double.NaN,
+ double minorStep = double.NaN,
+ string title = null)
+ : this()
+ {
+ this.Minimum = minimum;
+ this.Maximum = maximum;
+ this.MajorStep = majorStep;
+ this.MinorStep = minorStep;
+ this.Title = title;
+ this.StartAngle = 0;
+ this.EndAngle = 360;
+ }
+
+ ///
+ /// Gets or sets the start angle (degrees).
+ ///
+ public double StartAngle { get; set; }
+
+ ///
+ /// Gets or sets the end angle (degrees).
+ ///
+ public double EndAngle { get; set; }
+
+ ///
+ /// Inverse transform the specified screen point.
+ ///
+ /// The x coordinate.
+ /// The y coordinate.
+ /// The y-axis.
+ ///
+ /// The data point.
+ ///
+ public override DataPoint InverseTransform(double x, double y, Axis yaxis)
+ {
+ throw new InvalidOperationException("Angle axis should always be the y-axis.");
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public override bool IsXyAxis()
+ {
+ return false;
+ }
+
+ ///
+ /// Renders the axis on the specified render context.
+ ///
+ /// The render context.
+ /// The model.
+ /// The rendering order.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
+ {
+ if (this.Layer != axisLayer)
+ {
+ return;
+ }
+
+ var r = new AngleAxisRenderer(rc, model);
+ r.Render(this, pass);
+ }
+
+ ///
+ /// Transforms the specified point to screen coordinates.
+ ///
+ ///
+ /// The x value (for the current axis).
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// The y axis.
+ ///
+ ///
+ /// The transformed point.
+ ///
+ public override ScreenPoint Transform(double x, double y, Axis yaxis)
+ {
+ throw new InvalidOperationException("Angle axis should always be the y-axis.");
+ }
+
+ ///
+ /// The update transform.
+ ///
+ ///
+ /// The bounds.
+ ///
+ internal override void UpdateTransform(OxyRect bounds)
+ {
+ double x0 = bounds.Left;
+ double x1 = bounds.Right;
+ double y0 = bounds.Bottom;
+ double y1 = bounds.Top;
+
+ this.ScreenMin = new ScreenPoint(x0, y1);
+ this.ScreenMax = new ScreenPoint(x1, y0);
+
+ double startAngle = this.StartAngle / 180 * Math.PI;
+ double endAngle = this.EndAngle / 180 * Math.PI;
+
+ this.Scale = (endAngle - startAngle) / (this.ActualMaximum - this.ActualMinimum);
+ this.Offset = this.ActualMinimum - (startAngle / this.Scale);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/Axis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/Axis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,1753 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Abstract base class for axes.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Globalization;
+
+ using OxyPlot.Series;
+
+ ///
+ /// Provides an abstract base class for axes.
+ ///
+ public abstract class Axis : PlotElement
+ {
+ ///
+ /// Exponent function.
+ ///
+ protected static readonly Func Exponent = x => Math.Round(Math.Log(Math.Abs(x), 10));
+
+ ///
+ /// Mantissa function. http://en.wikipedia.org/wiki/Mantissa
+ ///
+ protected static readonly Func Mantissa = x => x / Math.Pow(10, Exponent(x));
+
+ ///
+ /// The offset.
+ ///
+ [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate",
+ Justification = "Reviewed. Suppression is OK here.")]
+ protected double offset;
+
+ ///
+ /// The scale.
+ ///
+ [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate",
+ Justification = "Reviewed. Suppression is OK here.")]
+ protected double scale;
+
+ ///
+ /// The position.
+ ///
+ private AxisPosition position;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected Axis()
+ {
+ this.Position = AxisPosition.Left;
+ this.PositionTier = 0;
+ this.IsAxisVisible = true;
+ this.Layer = AxisLayer.BelowSeries;
+
+ this.ViewMaximum = double.NaN;
+ this.ViewMinimum = double.NaN;
+
+ this.AbsoluteMaximum = double.MaxValue;
+ this.AbsoluteMinimum = double.MinValue;
+
+ this.Minimum = double.NaN;
+ this.Maximum = double.NaN;
+ this.MinorStep = double.NaN;
+ this.MajorStep = double.NaN;
+
+ this.MinimumPadding = 0.01;
+ this.MaximumPadding = 0.01;
+ this.MinimumRange = 0;
+
+ this.TickStyle = TickStyle.Outside;
+ this.TicklineColor = OxyColors.Black;
+
+ this.AxislineStyle = LineStyle.None;
+ this.AxislineColor = OxyColors.Black;
+ this.AxislineThickness = 1.0;
+
+ this.MajorGridlineStyle = LineStyle.None;
+ this.MajorGridlineColor = OxyColor.FromArgb(0x40, 0, 0, 0);
+ this.MajorGridlineThickness = 1;
+
+ this.MinorGridlineStyle = LineStyle.None;
+ this.MinorGridlineColor = OxyColor.FromArgb(0x20, 0, 0, 0x00);
+ this.MinorGridlineThickness = 1;
+
+ this.ExtraGridlineStyle = LineStyle.Solid;
+ this.ExtraGridlineColor = OxyColors.Black;
+ this.ExtraGridlineThickness = 1;
+
+ this.ShowMinorTicks = true;
+
+ this.MinorTickSize = 4;
+ this.MajorTickSize = 7;
+
+ this.StartPosition = 0;
+ this.EndPosition = 1;
+
+ this.TitlePosition = 0.5;
+ this.TitleFormatString = "{0} [{1}]";
+ this.TitleClippingLength = 0.9;
+ this.TitleColor = null;
+ this.TitleFontSize = double.NaN;
+ this.TitleFontWeight = FontWeights.Normal;
+ this.ClipTitle = true;
+
+ this.Angle = 0;
+
+ this.IsZoomEnabled = true;
+ this.IsPanEnabled = true;
+
+ this.FilterMinValue = double.MinValue;
+ this.FilterMaxValue = double.MaxValue;
+ this.FilterFunction = null;
+
+ this.IntervalLength = 60;
+
+ this.AxisTitleDistance = 4;
+ this.AxisTickToLabelDistance = 4;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position of the axis.
+ ///
+ ///
+ /// The minimum value.
+ ///
+ ///
+ /// The maximum value.
+ ///
+ ///
+ /// The axis title.
+ ///
+ protected Axis(AxisPosition pos, double minimum, double maximum, string title = null)
+ : this()
+ {
+ this.Position = pos;
+ this.Minimum = minimum;
+ this.Maximum = maximum;
+
+ this.AbsoluteMaximum = double.NaN;
+ this.AbsoluteMinimum = double.NaN;
+
+ this.Title = title;
+ }
+
+ ///
+ /// Occurs when the axis has been changed (by zooming, panning or resetting).
+ ///
+ public event EventHandler AxisChanged;
+
+ ///
+ /// Gets or sets the absolute maximum. This is only used for the UI control. It will not be possible to zoom/pan beyond this limit.
+ ///
+ /// The absolute maximum.
+ public double AbsoluteMaximum { get; set; }
+
+ ///
+ /// Gets or sets the absolute minimum. This is only used for the UI control. It will not be possible to zoom/pan beyond this limit.
+ ///
+ /// The absolute minimum.
+ public double AbsoluteMinimum { get; set; }
+
+ ///
+ /// Gets the actual culture.
+ ///
+ ///
+ /// The culture is defined in the parent PlotModel.
+ ///
+ public CultureInfo ActualCulture
+ {
+ get
+ {
+ return this.PlotModel != null ? this.PlotModel.ActualCulture : CultureInfo.CurrentCulture;
+ }
+ }
+
+ ///
+ /// Gets or sets the actual major step.
+ ///
+ public double ActualMajorStep { get; protected set; }
+
+ ///
+ /// Gets or sets the actual maximum value of the axis.
+ ///
+ ///
+ /// If ViewMaximum is not NaN, this value will be defined by ViewMaximum.
+ /// Otherwise, if Maximum is not NaN, this value will be defined by Maximum.
+ /// Otherwise, this value will be defined by the maximum (+padding) of the data.
+ ///
+ public double ActualMaximum { get; protected set; }
+
+ ///
+ /// Gets or sets the actual minimum value of the axis.
+ ///
+ ///
+ /// If ViewMinimum is not NaN, this value will be defined by ViewMinimum.
+ /// Otherwise, if Minimum is not NaN, this value will be defined by Minimum.
+ /// Otherwise this value will be defined by the minimum (+padding) of the data.
+ ///
+ public double ActualMinimum { get; protected set; }
+
+ ///
+ /// Gets or sets the maximum value of the data displayed on this axis.
+ ///
+ /// The data maximum.
+ public double DataMaximum { get; protected set; }
+
+ ///
+ /// Gets or sets the minimum value of the data displayed on this axis.
+ ///
+ /// The data minimum.
+ public double DataMinimum { get; protected set; }
+
+ ///
+ /// Gets or sets the actual minor step.
+ ///
+ public double ActualMinorStep { get; protected set; }
+
+ ///
+ /// Gets or sets the actual string format being used.
+ ///
+ public string ActualStringFormat { get; protected set; }
+
+ ///
+ /// Gets the actual title (including Unit if Unit is set).
+ ///
+ /// The actual title.
+ public string ActualTitle
+ {
+ get
+ {
+ if (this.Unit != null)
+ {
+ return string.Format(this.TitleFormatString, this.Title, this.Unit);
+ }
+
+ return this.Title;
+ }
+ }
+
+ ///
+ /// Gets or sets the angle for the axis values.
+ ///
+ public double Angle { get; set; }
+
+ ///
+ /// Gets or sets the distance from axis tick to number label.
+ ///
+ /// The axis tick to label distance.
+ public double AxisTickToLabelDistance { get; set; }
+
+ ///
+ /// Gets or sets the distance from axis number to axis title.
+ ///
+ /// The axis title distance.
+ public double AxisTitleDistance { get; set; }
+
+ ///
+ /// Gets or sets the color of the axis line.
+ ///
+ public OxyColor AxislineColor { get; set; }
+
+ ///
+ /// Gets or sets the axis line.
+ ///
+ public LineStyle AxislineStyle { get; set; }
+
+ ///
+ /// Gets or sets the axis line.
+ ///
+ public double AxislineThickness { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to clip the axis title.
+ ///
+ ///
+ /// The default value is true.
+ ///
+ public bool ClipTitle { get; set; }
+
+ ///
+ /// Gets or sets the end position of the axis on the plot area. This is a fraction from 0(bottom/left) to 1(top/right).
+ ///
+ public double EndPosition { get; set; }
+
+ ///
+ /// Gets or sets the color of the extra gridlines.
+ ///
+ public OxyColor ExtraGridlineColor { get; set; }
+
+ ///
+ /// Gets or sets the extra gridlines line style.
+ ///
+ public LineStyle ExtraGridlineStyle { get; set; }
+
+ ///
+ /// Gets or sets the extra gridline thickness.
+ ///
+ public double ExtraGridlineThickness { get; set; }
+
+ ///
+ /// Gets or sets the values for extra gridlines.
+ ///
+ public double[] ExtraGridlines { get; set; }
+
+ ///
+ /// Gets or sets the filter function.
+ ///
+ /// The filter function.
+ public Func FilterFunction { get; set; }
+
+ ///
+ /// Gets or sets the maximum value that can be shown using this axis. Values greater or equal to this value will not be shown.
+ ///
+ /// The filter max value.
+ public double FilterMaxValue { get; set; }
+
+ ///
+ /// Gets or sets the minimum value that can be shown using this axis. Values smaller or equal to this value will not be shown.
+ ///
+ /// The filter min value.
+ public double FilterMinValue { get; set; }
+
+ ///
+ /// Gets or sets the length of the interval (screen length). The available length of the axis will be divided by this length to get the approximate number of major intervals on the axis. The default value is 60.
+ ///
+ public double IntervalLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this axis is visible.
+ ///
+ public bool IsAxisVisible { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether pan is enabled.
+ ///
+ public bool IsPanEnabled { get; set; }
+
+ ///
+ /// Gets a value indicating whether this axis is reversed. It is reversed if StartPosition>EndPosition.
+ ///
+ public bool IsReversed
+ {
+ get
+ {
+ return this.StartPosition > this.EndPosition;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether zoom is enabled.
+ ///
+ public bool IsZoomEnabled { get; set; }
+
+ ///
+ /// Gets or sets the key of the axis. This can be used to find an axis if you have defined multiple axes in a plot.
+ ///
+ public string Key { get; set; }
+
+ ///
+ /// Gets or sets the layer.
+ ///
+ /// The layer.
+ public AxisLayer Layer { get; set; }
+
+ ///
+ /// Gets or sets the color of the major gridline.
+ ///
+ public OxyColor MajorGridlineColor { get; set; }
+
+ ///
+ /// Gets or sets the major gridline style.
+ ///
+ public LineStyle MajorGridlineStyle { get; set; }
+
+ ///
+ /// Gets or sets the major gridline thickness.
+ ///
+ public double MajorGridlineThickness { get; set; }
+
+ ///
+ /// Gets or sets the major step. (the interval between large ticks with numbers).
+ ///
+ public double MajorStep { get; set; }
+
+ ///
+ /// Gets or sets the size of the major tick.
+ ///
+ public double MajorTickSize { get; set; }
+
+ ///
+ /// Gets or sets the maximum value of the axis.
+ ///
+ public double Maximum { get; set; }
+
+ ///
+ /// Gets or sets the 'padding' fraction of the maximum value. A value of 0.01 gives 1% more space on the maximum end of the axis. This property is not used if the Maximum property is set.
+ ///
+ public double MaximumPadding { get; set; }
+
+ ///
+ /// Gets or sets the minimum value of the axis.
+ ///
+ public double Minimum { get; set; }
+
+ ///
+ /// Gets or sets the 'padding' fraction of the minimum value. A value of 0.01 gives 1% more space on the minimum end of the axis. This property is not used if the Minimum property is set.
+ ///
+ public double MinimumPadding { get; set; }
+
+ ///
+ /// Gets or sets the minimum range of the axis. Setting this property ensures that ActualMaximum-ActualMinimum > MinimumRange.
+ ///
+ public double MinimumRange { get; set; }
+
+ ///
+ /// Gets or sets the color of the minor gridline.
+ ///
+ public OxyColor MinorGridlineColor { get; set; }
+
+ ///
+ /// Gets or sets the minor gridline style.
+ ///
+ public LineStyle MinorGridlineStyle { get; set; }
+
+ ///
+ /// Gets or sets the minor gridline thickness.
+ ///
+ public double MinorGridlineThickness { get; set; }
+
+ ///
+ /// Gets or sets the minor step (the interval between small ticks without number).
+ ///
+ public double MinorStep { get; set; }
+
+ ///
+ /// Gets or sets the size of the minor tick.
+ ///
+ public double MinorTickSize { get; set; }
+
+ ///
+ /// Gets or sets the offset. This is used to transform between data and screen coordinates.
+ ///
+ public double Offset
+ {
+ get
+ {
+ return this.offset;
+ }
+
+ protected set
+ {
+ this.offset = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the position of the axis.
+ ///
+ public AxisPosition Position
+ {
+ get
+ {
+ return this.position;
+ }
+
+ set
+ {
+ this.position = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the axis should be positioned on the zero-crossing of the related axis.
+ ///
+ public bool PositionAtZeroCrossing { get; set; }
+
+ ///
+ /// Gets or sets the position tier which defines in which tier the axis is displayed.
+ ///
+ ///
+ /// The bigger the value the the further afar is the axis from the graph.
+ ///
+ public int PositionTier { get; set; }
+
+ ///
+ /// Gets or sets the related axis. This is used for polar coordinate systems where the angle and magnitude axes are related.
+ ///
+ public Axis RelatedAxis { get; set; }
+
+ ///
+ /// Gets or sets the scaling factor of the axis. This is used to transform between data and screen coordinates.
+ ///
+ public double Scale
+ {
+ get
+ {
+ return this.scale;
+ }
+
+ protected set
+ {
+ this.scale = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the screen coordinate of the Maximum point on the axis.
+ ///
+ public ScreenPoint ScreenMax { get; protected set; }
+
+ ///
+ /// Gets or sets the screen coordinate of the Minimum point on the axis.
+ ///
+ public ScreenPoint ScreenMin { get; protected set; }
+
+ ///
+ /// Gets or sets a value indicating whether minor ticks should be shown.
+ ///
+ public bool ShowMinorTicks { get; set; }
+
+ ///
+ /// Gets or sets the start position of the axis on the plot area. This is a fraction from 0(bottom/left) to 1(top/right).
+ ///
+ public double StartPosition { get; set; }
+
+ ///
+ /// Gets or sets the string format used for formatting the axis values.
+ ///
+ public string StringFormat { get; set; }
+
+ ///
+ /// Gets or sets the tick style (both for major and minor ticks).
+ ///
+ public TickStyle TickStyle { get; set; }
+
+ ///
+ /// Gets or sets the color of the ticks (both major and minor ticks).
+ ///
+ public OxyColor TicklineColor { get; set; }
+
+ ///
+ /// Gets or sets the title of the axis.
+ ///
+ public string Title { get; set; }
+
+ ///
+ /// Gets or sets the length of the title clipping rectangle (fraction of the available length of the axis).
+ ///
+ ///
+ /// The default value is 0.9
+ ///
+ public double TitleClippingLength { get; set; }
+
+ ///
+ /// Gets or sets the color of the title.
+ ///
+ /// The color of the title.
+ ///
+ /// If TitleColor is null, the parent PlotModel's TextColor will be used.
+ ///
+ public OxyColor TitleColor { get; set; }
+
+ ///
+ /// Gets or sets the title font.
+ ///
+ /// The title font.
+ public string TitleFont { get; set; }
+
+ ///
+ /// Gets or sets the size of the title font.
+ ///
+ /// The size of the title font.
+ public double TitleFontSize { get; set; }
+
+ ///
+ /// Gets or sets the title font weight.
+ ///
+ /// The title font weight.
+ public double TitleFontWeight { get; set; }
+
+ ///
+ /// Gets or sets the format string used for formatting the title and unit when unit is defined. If unit is null, only Title is used. The default value is "{0} [{1}]", where {0} uses the Title and {1} uses the Unit.
+ ///
+ public string TitleFormatString { get; set; }
+
+ ///
+ /// Gets or sets the position of the title (0.5 is in the middle).
+ ///
+ public double TitlePosition { get; set; }
+
+ ///
+ /// Gets or sets the tool tip.
+ ///
+ /// The tool tip.
+ public string ToolTip { get; set; }
+
+ ///
+ /// Gets or sets the unit of the axis.
+ ///
+ public string Unit { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to use superscript exponential format. This format will convert 1.5E+03 to 1.5·10^{3} and render the superscript properly If StringFormat is null, 1.0E+03 will be converted to 10^{3}
+ ///
+ public bool UseSuperExponentialFormat { get; set; }
+
+ ///
+ /// Gets or sets the position tier max shift.
+ ///
+ /// The position tier max shift.
+ internal double PositionTierMaxShift { get; set; }
+
+ ///
+ /// Gets or sets the position tier min shift.
+ ///
+ /// The position tier min shift.
+ internal double PositionTierMinShift { get; set; }
+
+ ///
+ /// Gets or sets the size of the position tier.
+ ///
+ /// The size of the position tier.
+ internal double PositionTierSize { get; set; }
+
+ ///
+ /// Gets the actual color of the title.
+ ///
+ /// The actual color of the title.
+ protected internal OxyColor ActualTitleColor
+ {
+ get
+ {
+ return this.TitleColor ?? this.PlotModel.TextColor;
+ }
+ }
+
+ ///
+ /// Gets the actual title font.
+ ///
+ protected internal string ActualTitleFont
+ {
+ get
+ {
+ return this.TitleFont ?? this.PlotModel.DefaultFont;
+ }
+ }
+
+ ///
+ /// Gets the actual size of the title font.
+ ///
+ /// The actual size of the title font.
+ protected internal double ActualTitleFontSize
+ {
+ get
+ {
+ return !double.IsNaN(this.TitleFontSize) ? this.TitleFontSize : this.ActualFontSize;
+ }
+ }
+
+ ///
+ /// Gets the actual title font weight.
+ ///
+ protected internal double ActualTitleFontWeight
+ {
+ get
+ {
+ return !double.IsNaN(this.TitleFontWeight) ? this.TitleFontWeight : this.ActualFontWeight;
+ }
+ }
+
+ ///
+ /// Gets or sets the current view's maximum. This value is used when the user zooms or pans.
+ ///
+ /// The view maximum.
+ protected double ViewMaximum { get; set; }
+
+ ///
+ /// Gets or sets the current view's minimum. This value is used when the user zooms or pans.
+ ///
+ /// The view minimum.
+ protected double ViewMinimum { get; set; }
+
+ ///
+ /// Transforms the specified point to screen coordinates.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The x axis.
+ ///
+ ///
+ /// The y axis.
+ ///
+ ///
+ /// The transformed point.
+ ///
+ public static ScreenPoint Transform(DataPoint p, Axis xaxis, Axis yaxis)
+ {
+ return xaxis.Transform(p.x, p.y, yaxis);
+ }
+
+ ///
+ /// Transform the specified screen point to data coordinates.
+ ///
+ /// The point.
+ /// The x axis.
+ /// The y axis.
+ /// The data point.
+ public static DataPoint InverseTransform(ScreenPoint p, Axis xaxis, Axis yaxis)
+ {
+ return xaxis.InverseTransform(p.x, p.y, yaxis);
+ }
+
+ ///
+ /// Transforms the specified point to screen coordinates.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The x axis.
+ ///
+ ///
+ /// The y axis.
+ ///
+ ///
+ /// The transformed point.
+ ///
+ public static ScreenPoint Transform(IDataPoint p, Axis xaxis, Axis yaxis)
+ {
+ return xaxis.Transform(p.X, p.Y, yaxis);
+ }
+
+ ///
+ /// Coerces the actual maximum and minimum values.
+ ///
+ public virtual void CoerceActualMaxMin()
+ {
+ // Coerce actual minimum
+ if (double.IsNaN(this.ActualMinimum) || double.IsInfinity(this.ActualMinimum))
+ {
+ this.ActualMinimum = 0;
+ }
+
+ // Coerce actual maximum
+ if (double.IsNaN(this.ActualMaximum) || double.IsInfinity(this.ActualMaximum))
+ {
+ this.ActualMaximum = 100;
+ }
+
+ if (this.ActualMaximum <= this.ActualMinimum)
+ {
+ this.ActualMaximum = this.ActualMinimum + 100;
+ }
+
+ // Coerce the minimum range
+ double range = this.ActualMaximum - this.ActualMinimum;
+ if (range < this.MinimumRange)
+ {
+ double avg = (this.ActualMaximum + this.ActualMinimum) * 0.5;
+ this.ActualMinimum = avg - (this.MinimumRange * 0.5);
+ this.ActualMaximum = avg + (this.MinimumRange * 0.5);
+ }
+
+ if (this.AbsoluteMaximum <= this.AbsoluteMinimum)
+ {
+ throw new InvalidOperationException("AbsoluteMaximum should be larger than AbsoluteMinimum.");
+ }
+ }
+
+ ///
+ /// Formats the value to be used on the axis.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The formatted value.
+ ///
+ public virtual string FormatValue(double x)
+ {
+ // The "SuperExponentialFormat" renders the number with superscript exponents. E.g. 10^2
+ if (this.UseSuperExponentialFormat)
+ {
+ // if (x == 1 || x == 10 || x == -1 || x == -10)
+ // return x.ToString();
+ double exp = Exponent(x);
+ double mantissa = Mantissa(x);
+ string fmt;
+ if (this.StringFormat == null)
+ {
+ fmt = Math.Abs(mantissa - 1.0) < 1e-6 ? "10^{{{1:0}}}" : "{0}·10^{{{1:0}}}";
+ }
+ else
+ {
+ fmt = "{0:" + this.StringFormat + "}·10^{{{1:0}}}";
+ }
+
+ return string.Format(this.ActualCulture, fmt, mantissa, exp);
+ }
+
+ string format = this.ActualStringFormat ?? this.StringFormat ?? string.Empty;
+ return x.ToString(format, this.ActualCulture);
+ }
+
+ ///
+ /// Formats the value to be used by the tracker.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The formatted value.
+ ///
+ public virtual string FormatValueForTracker(double x)
+ {
+ return x.ToString(this.ActualCulture);
+ }
+
+ ///
+ /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
+ ///
+ ///
+ /// The major label values.
+ ///
+ ///
+ /// The major tick values.
+ ///
+ ///
+ /// The minor tick values.
+ ///
+ public virtual void GetTickValues(
+ out IList majorLabelValues, out IList majorTickValues, out IList minorTickValues)
+ {
+ minorTickValues = CreateTickValues(this.ActualMinimum, this.ActualMaximum, this.ActualMinorStep);
+ majorTickValues = CreateTickValues(this.ActualMinimum, this.ActualMaximum, this.ActualMajorStep);
+ majorLabelValues = majorTickValues;
+ }
+
+ ///
+ /// Gets the value from an axis coordinate, converts from double to the correct data type if necessary. e.g. DateTimeAxis returns the DateTime and CategoryAxis returns category strings.
+ ///
+ ///
+ /// The coordinate.
+ ///
+ ///
+ /// The value.
+ ///
+ public virtual object GetValue(double x)
+ {
+ return x;
+ }
+
+ ///
+ /// Inverse transform the specified screen point.
+ ///
+ ///
+ /// The x coordinate.
+ ///
+ ///
+ /// The y coordinate.
+ ///
+ ///
+ /// The y-axis.
+ ///
+ ///
+ /// The data point.
+ ///
+ public virtual DataPoint InverseTransform(double x, double y, Axis yaxis)
+ {
+ return new DataPoint(this.InverseTransform(x), yaxis != null ? yaxis.InverseTransform(y) : 0);
+ }
+
+ ///
+ /// Inverse transform the specified screen coordinate. This method can only be used with non-polar coordinate systems.
+ ///
+ ///
+ /// The screen coordinate.
+ ///
+ ///
+ /// The value.
+ ///
+ public virtual double InverseTransform(double sx)
+ {
+ return this.PostInverseTransform((sx / this.scale) + this.offset);
+ }
+
+ ///
+ /// Determines whether this axis is horizontal.
+ ///
+ ///
+ /// true if this axis is horizontal; otherwise, false .
+ ///
+ public bool IsHorizontal()
+ {
+ return this.position == AxisPosition.Top || this.position == AxisPosition.Bottom;
+ }
+
+ ///
+ /// Determines whether the specified value is valid.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// true if the specified value is valid; otherwise, false .
+ ///
+ public virtual bool IsValidValue(double value)
+ {
+ return !double.IsNaN(value) && !double.IsInfinity(value) && value < this.FilterMaxValue
+ && value > this.FilterMinValue && (this.FilterFunction == null || this.FilterFunction(value));
+ }
+
+ ///
+ /// Determines whether this axis is vertical.
+ ///
+ ///
+ /// true if this axis is vertical; otherwise, false .
+ ///
+ public bool IsVertical()
+ {
+ return this.position == AxisPosition.Left || this.position == AxisPosition.Right;
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public abstract bool IsXyAxis();
+
+ ///
+ /// Measures the size of the axis (maximum axis label width/height).
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The size of the axis.
+ ///
+ public virtual OxySize Measure(IRenderContext rc)
+ {
+ IList majorTickValues;
+ IList minorTickValues;
+ IList majorLabelValues;
+
+ this.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
+
+ var maximumTextSize = new OxySize();
+ foreach (double v in majorLabelValues)
+ {
+ string s = this.FormatValue(v);
+ var size = rc.MeasureText(s, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
+ if (size.Width > maximumTextSize.Width)
+ {
+ maximumTextSize.Width = size.Width;
+ }
+
+ if (size.Height > maximumTextSize.Height)
+ {
+ maximumTextSize.Height = size.Height;
+ }
+ }
+
+ var labelTextSize = rc.MeasureText(
+ this.ActualTitle, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
+
+ double width = 0;
+ double height = 0;
+
+ if (this.IsHorizontal())
+ {
+ switch (this.TickStyle)
+ {
+ case TickStyle.Outside:
+ height += this.MajorTickSize;
+ break;
+ case TickStyle.Crossing:
+ height += this.MajorTickSize * 0.75;
+ break;
+ }
+
+ height += this.AxisTickToLabelDistance;
+ height += maximumTextSize.Height;
+ if (labelTextSize.Height > 0)
+ {
+ height += this.AxisTitleDistance;
+ height += labelTextSize.Height;
+ }
+ }
+ else
+ {
+ switch (this.TickStyle)
+ {
+ case TickStyle.Outside:
+ width += this.MajorTickSize;
+ break;
+ case TickStyle.Crossing:
+ width += this.MajorTickSize * 0.75;
+ break;
+ }
+
+ width += this.AxisTickToLabelDistance;
+ width += maximumTextSize.Width;
+ if (labelTextSize.Height > 0)
+ {
+ width += this.AxisTitleDistance;
+ width += labelTextSize.Height;
+ }
+ }
+
+ return new OxySize(width, height);
+ }
+
+ ///
+ /// Pans the specified axis.
+ ///
+ ///
+ /// The previous point (screen coordinates).
+ ///
+ ///
+ /// The current point (screen coordinates).
+ ///
+ public virtual void Pan(ScreenPoint ppt, ScreenPoint cpt)
+ {
+ if (!this.IsPanEnabled)
+ {
+ return;
+ }
+
+ bool isHorizontal = this.IsHorizontal();
+
+ double dsx = isHorizontal ? cpt.X - ppt.X : cpt.Y - ppt.Y;
+ this.Pan(dsx);
+ }
+
+ ///
+ /// Pans the specified axis.
+ ///
+ ///
+ /// The delta.
+ ///
+ public virtual void Pan(double delta)
+ {
+ if (!this.IsPanEnabled)
+ {
+ return;
+ }
+
+ double dx = delta / this.Scale;
+
+ double newMinimum = this.ActualMinimum - dx;
+ double newMaximum = this.ActualMaximum - dx;
+ if (newMinimum < this.AbsoluteMinimum)
+ {
+ newMinimum = this.AbsoluteMinimum;
+ newMaximum = newMinimum + this.ActualMaximum - this.ActualMinimum;
+ }
+
+ if (newMaximum > this.AbsoluteMaximum)
+ {
+ newMaximum = this.AbsoluteMaximum;
+ newMinimum = newMaximum - (this.ActualMaximum - this.ActualMinimum);
+ }
+
+ this.ViewMinimum = newMinimum;
+ this.ViewMaximum = newMaximum;
+ this.UpdateActualMaxMin();
+
+ this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Pan));
+ }
+
+ ///
+ /// Renders the axis on the specified render context.
+ ///
+ /// The render context.
+ /// The model.
+ /// The rendering order.
+ /// The pass.
+ public virtual void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
+ {
+ var r = new HorizontalAndVerticalAxisRenderer(rc, model);
+ r.Render(this, pass);
+ }
+
+ ///
+ /// Resets the user's modification (zooming/panning) to minimum and maximum of this axis.
+ ///
+ public virtual void Reset()
+ {
+ this.ViewMinimum = double.NaN;
+ this.ViewMaximum = double.NaN;
+ this.UpdateActualMaxMin();
+ this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Reset));
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0}({1}, {2}, {3}, {4})",
+ this.GetType().Name,
+ this.Position,
+ this.ActualMinimum,
+ this.ActualMaximum,
+ this.ActualMajorStep);
+ }
+
+ ///
+ /// Transforms the specified point to screen coordinates.
+ ///
+ ///
+ /// The x value (for the current axis).
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// The y axis.
+ ///
+ ///
+ /// The transformed point.
+ ///
+ public virtual ScreenPoint Transform(double x, double y, Axis yaxis)
+ {
+ if (yaxis == null)
+ {
+ throw new NullReferenceException("Y axis should not be null when transforming.");
+ }
+
+ return new ScreenPoint(this.Transform(x), yaxis.Transform(y));
+ }
+
+ ///
+ /// Transforms the specified coordinate to screen coordinates. This method can only be used with non-polar coordinate systems.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The transformed value (screen coordinate).
+ ///
+ public virtual double Transform(double x)
+ {
+ return (x - this.offset) * this.scale;
+
+ // return (this.PreTransform(x) - this.Offset) * this.Scale;
+ }
+
+ ///
+ /// Zoom to the specified scale.
+ ///
+ ///
+ /// The new scale.
+ ///
+ public virtual void Zoom(double newScale)
+ {
+ double sx1 = this.Transform(this.ActualMaximum);
+ double sx0 = this.Transform(this.ActualMinimum);
+
+ double sgn = Math.Sign(this.scale);
+ double mid = (this.ActualMaximum + this.ActualMinimum) / 2;
+
+ double dx = (this.offset - mid) * this.scale;
+ this.scale = sgn * newScale;
+ this.offset = (dx / this.scale) + mid;
+
+ double newMaximum = this.InverseTransform(sx1);
+ double newMinimum = this.InverseTransform(sx0);
+
+ if (newMinimum < this.AbsoluteMinimum && newMaximum > this.AbsoluteMaximum)
+ {
+ newMinimum = this.AbsoluteMinimum;
+ newMaximum = this.AbsoluteMaximum;
+ }
+ else
+ {
+ if (newMinimum < this.AbsoluteMinimum)
+ {
+ double d = newMaximum - newMinimum;
+ newMinimum = this.AbsoluteMinimum;
+ newMaximum = this.AbsoluteMinimum + d;
+ if (newMaximum > this.AbsoluteMaximum)
+ {
+ newMaximum = this.AbsoluteMaximum;
+ }
+ }
+ else if (newMaximum > this.AbsoluteMaximum)
+ {
+ double d = newMaximum - newMinimum;
+ newMaximum = this.AbsoluteMaximum;
+ newMinimum = this.AbsoluteMaximum - d;
+ if (newMinimum < this.AbsoluteMinimum)
+ {
+ newMinimum = this.AbsoluteMinimum;
+ }
+ }
+ }
+
+ this.ViewMaximum = newMaximum;
+ this.ViewMinimum = newMinimum;
+ this.UpdateActualMaxMin();
+ }
+
+ ///
+ /// Zooms the axis to the range [x0,x1].
+ ///
+ ///
+ /// The new minimum.
+ ///
+ ///
+ /// The new maximum.
+ ///
+ public virtual void Zoom(double x0, double x1)
+ {
+ if (!this.IsZoomEnabled)
+ {
+ return;
+ }
+
+ double newMinimum = Math.Max(Math.Min(x0, x1), this.AbsoluteMinimum);
+ double newMaximum = Math.Min(Math.Max(x0, x1), this.AbsoluteMaximum);
+
+ this.ViewMinimum = newMinimum;
+ this.ViewMaximum = newMaximum;
+ this.UpdateActualMaxMin();
+
+ this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Zoom));
+ }
+
+ ///
+ /// Zooms the axis at the specified coordinate.
+ ///
+ ///
+ /// The zoom factor.
+ ///
+ ///
+ /// The coordinate to zoom at.
+ ///
+ public virtual void ZoomAt(double factor, double x)
+ {
+ if (!this.IsZoomEnabled)
+ {
+ return;
+ }
+
+ double dx0 = (this.ActualMinimum - x) * this.scale;
+ double dx1 = (this.ActualMaximum - x) * this.scale;
+ this.scale *= factor;
+
+ double newMinimum = Math.Max((dx0 / this.scale) + x, this.AbsoluteMinimum);
+ double newMaximum = Math.Min((dx1 / this.scale) + x, this.AbsoluteMaximum);
+
+ this.ViewMinimum = newMinimum;
+ this.ViewMaximum = newMaximum;
+ this.UpdateActualMaxMin();
+
+ this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Zoom));
+ }
+
+ ///
+ /// Modifies the data range of the axis [DataMinimum,DataMaximum] to includes the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ public virtual void Include(double value)
+ {
+ if (!this.IsValidValue(value))
+ {
+ return;
+ }
+
+ this.DataMinimum = double.IsNaN(this.DataMinimum) ? value : Math.Min(this.DataMinimum, value);
+ this.DataMaximum = double.IsNaN(this.DataMaximum) ? value : Math.Max(this.DataMaximum, value);
+ }
+
+ ///
+ /// Applies a transformation after the inverse transform of the value. This is used in logarithmic axis.
+ ///
+ ///
+ /// The value to transform.
+ ///
+ ///
+ /// The transformed value.
+ ///
+ internal virtual double PostInverseTransform(double x)
+ {
+ return x;
+ }
+
+ ///
+ /// Applies a transformation before the transform the value. This is used in logarithmic axis.
+ ///
+ ///
+ /// The value to transform.
+ ///
+ ///
+ /// The transformed value.
+ ///
+ internal virtual double PreTransform(double x)
+ {
+ return x;
+ }
+
+ ///
+ /// Resets the data maximum and minimum.
+ ///
+ internal virtual void ResetDataMaxMin()
+ {
+ this.DataMaximum = this.DataMinimum = double.NaN;
+ }
+
+ ///
+ /// Updates the actual maximum and minimum values. If the user has zoomed/panned the axis, the internal ViewMaximum/ViewMinimum values will be used. If Maximum or Minimum have been set, these values will be used. Otherwise the maximum and minimum values of the series will be used, including the 'padding'.
+ ///
+ internal virtual void UpdateActualMaxMin()
+ {
+ // Use the minimum/maximum of the data as default
+ this.ActualMaximum = this.DataMaximum;
+ this.ActualMinimum = this.DataMinimum;
+
+ double range = this.ActualMaximum - this.ActualMinimum;
+ double zeroRange = this.ActualMaximum > 0 ? this.ActualMaximum : 1;
+
+ if (!double.IsNaN(this.ViewMaximum))
+ {
+ // Override the ActualMaximum by the ViewMaximum value (from zoom/pan)
+ this.ActualMaximum = this.ViewMaximum;
+ }
+ else if (!double.IsNaN(this.Maximum))
+ {
+ // Override the ActualMaximum by the Maximum value
+ this.ActualMaximum = this.Maximum;
+ }
+ else
+ {
+ if (range < double.Epsilon)
+ {
+ this.ActualMaximum += zeroRange * 0.5;
+ }
+
+ if (!double.IsNaN(this.ActualMinimum) && !double.IsNaN(this.ActualMaximum))
+ {
+ double x1 = this.PreTransform(this.ActualMaximum);
+ double x0 = this.PreTransform(this.ActualMinimum);
+ double dx = this.MaximumPadding * (x1 - x0);
+ this.ActualMaximum = this.PostInverseTransform(x1 + dx);
+ }
+ }
+
+ if (!double.IsNaN(this.ViewMinimum))
+ {
+ this.ActualMinimum = this.ViewMinimum;
+ }
+ else if (!double.IsNaN(this.Minimum))
+ {
+ this.ActualMinimum = this.Minimum;
+ }
+ else
+ {
+ if (range < double.Epsilon)
+ {
+ this.ActualMinimum -= zeroRange * 0.5;
+ }
+
+ if (!double.IsNaN(this.ActualMaximum) && !double.IsNaN(this.ActualMaximum))
+ {
+ double x1 = this.PreTransform(this.ActualMaximum);
+ double x0 = this.PreTransform(this.ActualMinimum);
+ double dx = this.MinimumPadding * (x1 - x0);
+ this.ActualMinimum = this.PostInverseTransform(x0 - dx);
+ }
+ }
+
+ this.CoerceActualMaxMin();
+ }
+
+ ///
+ /// Updates the axis with information from the plot series.
+ ///
+ ///
+ /// The series collection.
+ ///
+ ///
+ /// This is used by the category axis that need to know the number of series using the axis.
+ ///
+ internal virtual void UpdateFromSeries(IEnumerable series)
+ {
+ }
+
+ ///
+ /// Updates the actual minor and major step intervals.
+ ///
+ ///
+ /// The plot area rectangle.
+ ///
+ internal virtual void UpdateIntervals(OxyRect plotArea)
+ {
+ double labelSize = this.IntervalLength;
+ double length = this.IsHorizontal() ? plotArea.Width : plotArea.Height;
+ length *= Math.Abs(this.EndPosition - this.StartPosition);
+
+ this.ActualMajorStep = !double.IsNaN(this.MajorStep)
+ ? this.MajorStep
+ : this.CalculateActualInterval(length, labelSize);
+
+ this.ActualMinorStep = !double.IsNaN(this.MinorStep)
+ ? this.MinorStep
+ : this.CalculateMinorInterval(this.ActualMajorStep);
+
+ if (double.IsNaN(this.ActualMinorStep))
+ {
+ this.ActualMinorStep = 2;
+ }
+
+ if (double.IsNaN(this.ActualMajorStep))
+ {
+ this.ActualMajorStep = 10;
+ }
+
+ this.ActualStringFormat = this.StringFormat;
+
+ // if (ActualStringFormat==null)
+ // {
+ // if (ActualMaximum > 1e6 || ActualMinimum < 1e-6)
+ // ActualStringFormat = "#.#e-0";
+ // }
+ }
+
+ ///
+ /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
+ ///
+ ///
+ /// The bounds.
+ ///
+ internal virtual void UpdateTransform(OxyRect bounds)
+ {
+ double x0 = bounds.Left;
+ double x1 = bounds.Right;
+ double y0 = bounds.Bottom;
+ double y1 = bounds.Top;
+
+ this.ScreenMin = new ScreenPoint(x0, y1);
+ this.ScreenMax = new ScreenPoint(x1, y0);
+
+ // this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);
+
+ // if (this.Position == AxisPosition.Angle)
+ // {
+ // this.scale = 2 * Math.PI / (this.ActualMaximum - this.ActualMinimum);
+ // this.Offset = this.ActualMinimum;
+ // return;
+ // }
+
+ // if (this.Position == AxisPosition.Magnitude)
+ // {
+ // this.ActualMinimum = 0;
+ // double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
+ // this.scale = 0.5 * r / (this.ActualMaximum - this.ActualMinimum);
+ // this.Offset = this.ActualMinimum;
+ // return;
+ // }
+ double a0 = this.IsHorizontal() ? x0 : y0;
+ double a1 = this.IsHorizontal() ? x1 : y1;
+
+ double dx = a1 - a0;
+ a1 = a0 + (this.EndPosition * dx);
+ a0 = a0 + (this.StartPosition * dx);
+ this.ScreenMin = new ScreenPoint(a0, a1);
+ this.ScreenMax = new ScreenPoint(a1, a0);
+
+ if (this.ActualMaximum - this.ActualMinimum < double.Epsilon)
+ {
+ this.ActualMaximum = this.ActualMinimum + 1;
+ }
+
+ double max = this.PreTransform(this.ActualMaximum);
+ double min = this.PreTransform(this.ActualMinimum);
+
+ double da = a0 - a1;
+ if (Math.Abs(da) > double.Epsilon)
+ {
+ this.offset = (a0 / da * max) - (a1 / da * min);
+ }
+ else
+ {
+ this.offset = 0;
+ }
+
+ double range = max - min;
+ if (Math.Abs(range) > double.Epsilon)
+ {
+ this.scale = (a1 - a0) / range;
+ }
+ else
+ {
+ this.scale = 1;
+ }
+ }
+
+ ///
+ /// Creates tick values at the specified interval.
+ ///
+ ///
+ /// The minimum coordinate.
+ ///
+ ///
+ /// The maximum coordinate.
+ ///
+ ///
+ /// The interval.
+ ///
+ ///
+ /// A list of tick values.
+ ///
+ protected static IList CreateTickValues(double min, double max, double step)
+ {
+ if (max <= min)
+ {
+ throw new ArgumentException("Axis: Maximum should be larger than minimum.", "max");
+ }
+
+ if (step <= 0)
+ {
+ throw new ArgumentException("Axis: Step cannot be zero or negative.", "step");
+ }
+
+ double x0 = Math.Round(min / step) * step;
+ int n = Math.Max((int)((max - min) / step), 1);
+ var values = new List(n);
+
+ // Limit the maximum number of iterations (in case something is wrong with the step size)
+ int i = 0;
+ const int MaxIterations = 1000;
+ double x = x0;
+ double eps = step * 1e-3;
+
+ while (x <= max + eps && i < MaxIterations)
+ {
+ x = x0 + (i * step);
+ i++;
+ if (x >= min - eps && x <= max + eps)
+ {
+ x = x.RemoveNoise();
+ values.Add(x);
+ }
+ }
+
+ return values;
+ }
+
+ ///
+ /// Calculates the actual interval.
+ ///
+ ///
+ /// Size of the available area.
+ ///
+ ///
+ /// Maximum length of the intervals.
+ ///
+ ///
+ /// The calculate actual interval.
+ ///
+ protected virtual double CalculateActualInterval(double availableSize, double maxIntervalSize)
+ {
+ return this.CalculateActualInterval(availableSize, maxIntervalSize, this.ActualMaximum - this.ActualMinimum);
+ }
+
+ // alternative algorithm not in use
+ /* private double CalculateActualIntervalOldAlgorithm(double availableSize, double maxIntervalSize)
+ {
+ const int minimumTags = 5;
+ const int maximumTags = 20;
+ var numberOfTags = (int) (availableSize/maxIntervalSize);
+ double range = ActualMaximum - ActualMinimum;
+ double interval = range/numberOfTags;
+ const int k1 = 10;
+ interval = Math.Log10(interval/k1);
+ interval = Math.Ceiling(interval);
+ interval = Math.Pow(10, interval)*k1;
+
+ if (range/interval > maximumTags) interval *= 5;
+ if (range/interval < minimumTags) interval *= 0.5;
+
+ if (interval <= 0) interval = 1;
+ return interval;
+ }*/
+
+ // ===
+ // the following algorithm is from
+ // System.Windows.Controls.DataVisualization.Charting.LinearAxis.cs
+
+ // (c) Copyright Microsoft Corporation.
+ // This source is subject to the Microsoft Public License (MIT).
+ // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
+ // All other rights reserved.
+
+ ///
+ /// Returns the actual interval to use to determine which values are displayed in the axis.
+ ///
+ ///
+ /// The available size.
+ ///
+ ///
+ /// The maximum interval size.
+ ///
+ ///
+ /// The range.
+ ///
+ ///
+ /// Actual interval to use to determine which values are displayed in the axis.
+ ///
+ protected double CalculateActualInterval(double availableSize, double maxIntervalSize, double range)
+ {
+ if (availableSize <= 0)
+ {
+ return maxIntervalSize;
+ }
+
+ Func exponent = x => Math.Ceiling(Math.Log(x, 10));
+ Func mantissa = x => x / Math.Pow(10, exponent(x) - 1);
+
+ // reduce intervals for horizontal axis.
+ // double maxIntervals = Orientation == AxisOrientation.x ? MaximumAxisIntervalsPer200Pixels * 0.8 : MaximumAxisIntervalsPer200Pixels;
+ // real maximum interval count
+ double maxIntervalCount = availableSize / maxIntervalSize;
+
+ range = Math.Abs(range);
+ double interval = Math.Pow(10, exponent(range));
+ double tempInterval = interval;
+
+ // decrease interval until interval count becomes less than maxIntervalCount
+ while (true)
+ {
+ var m = (int)mantissa(tempInterval);
+ if (m == 5)
+ {
+ // reduce 5 to 2
+ tempInterval = (tempInterval / 2.5).RemoveNoiseFromDoubleMath();
+ }
+ else if (m == 2 || m == 1 || m == 10)
+ {
+ // reduce 2 to 1, 10 to 5, 1 to 0.5
+ tempInterval = (tempInterval / 2.0).RemoveNoiseFromDoubleMath();
+ }
+ else
+ {
+ tempInterval = (tempInterval / 2.0).RemoveNoiseFromDoubleMath();
+ }
+
+ if (range / tempInterval > maxIntervalCount)
+ {
+ break;
+ }
+
+ if (double.IsNaN(tempInterval) || double.IsInfinity(tempInterval))
+ {
+ break;
+ }
+
+ interval = tempInterval;
+ }
+
+ return interval;
+ }
+
+ ///
+ /// The calculate minor interval.
+ ///
+ ///
+ /// The major interval.
+ ///
+ ///
+ /// The minor interval.
+ ///
+ protected double CalculateMinorInterval(double majorInterval)
+ {
+ // if major interval is 100, the minor interval will be 20.
+ return majorInterval / 5;
+
+ // The following obsolete code divided major intervals into 4 minor intervals, unless the major interval's mantissa was 5.
+ // e.g. Major interval 100 => minor interval 25.
+
+ // Func exponent = x => Math.Ceiling(Math.Log(x, 10));
+ // Func mantissa = x => x / Math.Pow(10, exponent(x) - 1);
+ // var m = (int)mantissa(majorInterval);
+ // switch (m)
+ // {
+ // case 5:
+ // return majorInterval / 5;
+ // default:
+ // return majorInterval / 4;
+ // }
+ }
+
+ ///
+ /// Raises the AxisChanged event.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected virtual void OnAxisChanged(AxisChangedEventArgs args)
+ {
+ this.UpdateActualMaxMin();
+
+ var handler = this.AxisChanged;
+ if (handler != null)
+ {
+ handler(this, args);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/AxisChangeTypes.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/AxisChangeTypes.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,52 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Change types of the Axis.AxisChanged event.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Specifies change types for the event.
+ ///
+ public enum AxisChangeTypes
+ {
+ ///
+ /// The axis was zoomed by the user.
+ ///
+ Zoom,
+
+ ///
+ /// The axis was panned by the user.
+ ///
+ Pan,
+
+ ///
+ /// The axis zoom/pan was reset by the user.
+ ///
+ Reset
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/AxisChangedEventArgs.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/AxisChangedEventArgs.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,57 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// EventArgs for the Axis.AxisChanged event.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+
+ ///
+ /// Provides additional data for the event.
+ ///
+ public class AxisChangedEventArgs : EventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Type of the change.
+ ///
+ public AxisChangedEventArgs(AxisChangeTypes changeType)
+ {
+ this.ChangeType = changeType;
+ }
+
+ ///
+ /// Gets or sets the type of the change.
+ ///
+ /// The type of the change.
+ public AxisChangeTypes ChangeType { get; set; }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/AxisLayer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/AxisLayer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,47 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Axis layer position.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Specifies the layer position of an .
+ ///
+ public enum AxisLayer
+ {
+ ///
+ /// Below all series.
+ ///
+ BelowSeries,
+
+ ///
+ /// Above all series.
+ ///
+ AboveSeries
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/AxisPosition.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/AxisPosition.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,62 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Axis positions.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Specifies the position of an .
+ ///
+ public enum AxisPosition
+ {
+ ///
+ /// No position.
+ ///
+ None,
+
+ ///
+ /// Left of the plot area.
+ ///
+ Left,
+
+ ///
+ /// Right of the plot area.
+ ///
+ Right,
+
+ ///
+ /// Top of the plot area.
+ ///
+ Top,
+
+ ///
+ /// Bottom of the plot area.
+ ///
+ Bottom
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/CategoryAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/CategoryAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,501 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a category axes.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+
+ using OxyPlot.Series;
+
+ ///
+ /// Represents a category axis.
+ ///
+ ///
+ /// The category axis is using the label collection indices as the coordinate. If you have 5 categories in the Labels collection, the categories will be placed at coordinates 0 to 4. The range of the axis will be from -0.5 to 4.5 (excl. padding).
+ ///
+ public class CategoryAxis : LinearAxis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CategoryAxis()
+ {
+ this.Labels = new List();
+ this.TickStyle = TickStyle.Outside;
+ this.Position = AxisPosition.Bottom;
+ this.MinimumPadding = 0;
+ this.MaximumPadding = 0;
+ this.MajorStep = 1;
+ this.GapWidth = 1;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The position.
+ /// The title.
+ /// The categories.
+ public CategoryAxis(AxisPosition position, string title = null, params string[] categories)
+ : this(title, categories)
+ {
+ this.Position = position;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The title.
+ ///
+ ///
+ /// The categories.
+ ///
+ public CategoryAxis(string title, params string[] categories)
+ : this()
+ {
+ this.Title = title;
+ if (categories != null)
+ {
+ foreach (var c in categories)
+ {
+ this.Labels.Add(c);
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the gap width.
+ ///
+ ///
+ /// The default value is 1.0 (100%). The gap width is given as a fraction of the total width/height of the items in a category.
+ ///
+ public double GapWidth { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the ticks are centered. If this is false, ticks will be drawn between each category. If this is true, ticks will be drawn in the middle of each category.
+ ///
+ public bool IsTickCentered { get; set; }
+
+ ///
+ /// Gets or sets the items source (used to update the Labels collection).
+ ///
+ ///
+ /// The items source.
+ ///
+ public IEnumerable ItemsSource { get; set; }
+
+ ///
+ /// Gets or sets the data field for the labels.
+ ///
+ public string LabelField { get; set; }
+
+ ///
+ /// Gets or sets the labels collection.
+ ///
+ public IList Labels { get; set; }
+
+ ///
+ /// Gets or sets the current offset of the bars (not used for stacked bar series).
+ ///
+ internal double[] BarOffset { get; set; }
+
+ ///
+ /// Gets or sets the max value per StackIndex and Label (only used for stacked bar series).
+ ///
+ internal double[,] MaxValue { get; set; }
+
+ ///
+ /// Gets or sets the maximal width of all labels
+ ///
+ internal double MaxWidth { get; set; }
+
+ ///
+ /// Gets or sets the min value per StackIndex and Label (only used for stacked bar series).
+ ///
+ internal double[,] MinValue { get; set; }
+
+ ///
+ /// Gets or sets per StackIndex and Label the base value for negative values of stacked bar series.
+ ///
+ internal double[,] NegativeBaseValues { get; set; }
+
+ ///
+ /// Gets or sets per StackIndex and Label the base value for positive values of stacked bar series.
+ ///
+ internal double[,] PositiveBaseValues { get; set; }
+
+ ///
+ /// Gets or sets the StackIndexMapping. The mapping indicates to which rank a specific stack index belongs.
+ ///
+ internal Dictionary StackIndexMapping { get; set; }
+
+ ///
+ /// Gets or sets the offset of the bars per StackIndex and Label (only used for stacked bar series).
+ ///
+ internal double[,] StackedBarOffset { get; set; }
+
+ ///
+ /// Gets or sets sum of the widths of the single bars per label. This is used to find the bar width of BarSeries
+ ///
+ internal double[] TotalWidthPerCategory { get; set; }
+
+ ///
+ /// Fills the specified array.
+ ///
+ ///
+ /// The array.
+ ///
+ ///
+ /// The value.
+ ///
+ public static void Fill(double[] array, double value)
+ {
+ for (var i = 0; i < array.Length; i++)
+ {
+ array[i] = value;
+ }
+ }
+
+ ///
+ /// Fills the specified array.
+ ///
+ ///
+ /// The array.
+ ///
+ ///
+ /// The value.
+ ///
+ public static void Fill(double[,] array, double value)
+ {
+ for (var i = 0; i < array.GetLength(0); i++)
+ {
+ for (var j = 0; j < array.GetLength(1); j++)
+ {
+ array[i, j] = value;
+ }
+ }
+ }
+
+ ///
+ /// Formats the value to be used on the axis.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The formatted value.
+ ///
+ public override string FormatValue(double x)
+ {
+ var index = (int)x;
+ if (this.Labels != null && index >= 0 && index < this.Labels.Count)
+ {
+ return this.Labels[index];
+ }
+
+ return null;
+ }
+
+ ///
+ /// Formats the value to be used by the tracker.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The formatted value.
+ ///
+ public override string FormatValueForTracker(double x)
+ {
+ return this.FormatValue(x);
+ }
+
+ ///
+ /// Gets the category value.
+ ///
+ ///
+ /// Index of the category.
+ ///
+ ///
+ /// Index of the stack.
+ ///
+ ///
+ /// Actual width of the bar.
+ ///
+ ///
+ /// The get category value.
+ ///
+ public double GetCategoryValue(int categoryIndex, int stackIndex, double actualBarWidth)
+ {
+ var offsetBegin = this.StackedBarOffset[stackIndex, categoryIndex];
+ var offsetEnd = this.StackedBarOffset[stackIndex + 1, categoryIndex];
+ return categoryIndex - 0.5 + ((offsetEnd + offsetBegin - actualBarWidth) * 0.5);
+ }
+
+ ///
+ /// Gets the category value.
+ ///
+ ///
+ /// Index of the category.
+ ///
+ ///
+ /// The get category value.
+ ///
+ public double GetCategoryValue(int categoryIndex)
+ {
+ return categoryIndex - 0.5 + this.BarOffset[categoryIndex];
+ }
+
+ ///
+ /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
+ ///
+ ///
+ /// The major label values.
+ ///
+ ///
+ /// The major tick values.
+ ///
+ ///
+ /// The minor tick values.
+ ///
+ public override void GetTickValues(
+ out IList majorLabelValues, out IList majorTickValues, out IList minorTickValues)
+ {
+ base.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
+ minorTickValues.Clear();
+
+ if (!this.IsTickCentered)
+ {
+ // Subtract 0.5 from the label values to get the tick values.
+ // Add one extra tick at the end.
+ var mv = new List(majorLabelValues.Count);
+ mv.AddRange(majorLabelValues.Select(v => v - 0.5));
+ if (mv.Count > 0)
+ {
+ mv.Add(mv[mv.Count - 1] + 1);
+ }
+
+ majorTickValues = mv;
+ }
+ }
+
+ ///
+ /// Gets the value from an axis coordinate, converts from double to the correct data type if necessary. e.g. DateTimeAxis returns the DateTime and CategoryAxis returns category strings.
+ ///
+ ///
+ /// The coordinate.
+ ///
+ ///
+ /// The value.
+ ///
+ public override object GetValue(double x)
+ {
+ return this.FormatValue(x);
+ }
+
+ ///
+ /// Updates the actual maximum and minimum values. If the user has zoomed/panned the axis, the internal ViewMaximum/ViewMinimum values will be used. If Maximum or Minimum have been set, these values will be used. Otherwise the maximum and minimum values of the series will be used, including the 'padding'.
+ ///
+ internal override void UpdateActualMaxMin()
+ {
+ // Update the DataMinimum/DataMaximum from the number of categories
+ this.Include(-0.5);
+
+ if (this.Labels != null && this.Labels.Count > 0)
+ {
+ this.Include((this.Labels.Count - 1) + 0.5);
+ }
+ else
+ {
+ this.Include(0.5);
+ }
+
+ base.UpdateActualMaxMin();
+
+ this.MinorStep = 1;
+ }
+
+ ///
+ /// Updates the axis with information from the plot series.
+ ///
+ ///
+ /// The series collection.
+ ///
+ ///
+ /// This is used by the category axis that need to know the number of series using the axis.
+ ///
+ internal override void UpdateFromSeries(IEnumerable series)
+ {
+ if (this.Labels.Count == 0)
+ {
+ this.TotalWidthPerCategory = null;
+ this.MaxWidth = double.NaN;
+ this.BarOffset = null;
+ this.StackedBarOffset = null;
+ this.StackIndexMapping = null;
+ this.PositiveBaseValues = null;
+ this.NegativeBaseValues = null;
+ this.MaxValue = null;
+ this.MinValue = null;
+
+ return;
+ }
+
+ this.TotalWidthPerCategory = new double[this.Labels.Count];
+
+ var usedSeries = series.Where(s => s.IsUsing(this)).ToList();
+
+ // Add width of stacked series
+ var categorizedSeries = usedSeries.OfType().ToList();
+ var stackedSeries = categorizedSeries.OfType().Where(s => s.IsStacked).ToList();
+ var stackIndices = stackedSeries.Select(s => s.StackGroup).Distinct().ToList();
+ var stackRankBarWidth = new Dictionary();
+ for (var j = 0; j < stackIndices.Count; j++)
+ {
+ var maxBarWidth =
+ stackedSeries.Where(s => s.StackGroup == stackIndices[j]).Select(
+ s => ((CategorizedSeries)s).GetBarWidth()).Concat(new[] { 0.0 }).Max();
+ for (var i = 0; i < this.Labels.Count; i++)
+ {
+ int k = 0;
+ if (
+ stackedSeries.SelectMany(s => ((CategorizedSeries)s).GetItems()).Any(
+ item => item.GetCategoryIndex(k++) == i))
+ {
+ this.TotalWidthPerCategory[i] += maxBarWidth;
+ }
+ }
+
+ stackRankBarWidth[j] = maxBarWidth;
+ }
+
+ // Add width of unstacked series
+ var unstackedBarSeries =
+ categorizedSeries.Where(s => !(s is IStackableSeries) || !((IStackableSeries)s).IsStacked).ToList();
+ foreach (var s in unstackedBarSeries)
+ {
+ for (var i = 0; i < this.Labels.Count; i++)
+ {
+ int j = 0;
+ var numberOfItems = s.GetItems().Count(item => item.GetCategoryIndex(j++) == i);
+ this.TotalWidthPerCategory[i] += s.GetBarWidth() * numberOfItems;
+ }
+ }
+
+ this.MaxWidth = this.TotalWidthPerCategory.Max();
+
+ // Calculate BarOffset and StackedBarOffset
+ this.BarOffset = new double[this.Labels.Count];
+ this.StackedBarOffset = new double[stackIndices.Count + 1, this.Labels.Count];
+
+ var factor = 0.5 / (1 + this.GapWidth) / this.MaxWidth;
+ for (var i = 0; i < this.Labels.Count; i++)
+ {
+ this.BarOffset[i] = 0.5 - (this.TotalWidthPerCategory[i] * factor);
+ }
+
+ for (var j = 0; j <= stackIndices.Count; j++)
+ {
+ for (var i = 0; i < this.Labels.Count; i++)
+ {
+ int k = 0;
+ if (
+ stackedSeries.SelectMany(s => ((CategorizedSeries)s).GetItems()).All(
+ item => item.GetCategoryIndex(k++) != i))
+ {
+ continue;
+ }
+
+ this.StackedBarOffset[j, i] = this.BarOffset[i];
+ if (j < stackIndices.Count)
+ {
+ this.BarOffset[i] += stackRankBarWidth[j] / (1 + this.GapWidth) / this.MaxWidth;
+ }
+ }
+ }
+
+ stackIndices.Sort();
+ this.StackIndexMapping = new Dictionary();
+ for (var i = 0; i < stackIndices.Count; i++)
+ {
+ this.StackIndexMapping.Add(stackIndices[i], i);
+ }
+
+ this.PositiveBaseValues = new double[stackIndices.Count, this.Labels.Count];
+ Fill(this.PositiveBaseValues, double.NaN);
+ this.NegativeBaseValues = new double[stackIndices.Count, this.Labels.Count];
+ Fill(this.NegativeBaseValues, double.NaN);
+
+ this.MaxValue = new double[stackIndices.Count, this.Labels.Count];
+ Fill(this.MaxValue, double.NaN);
+ this.MinValue = new double[stackIndices.Count, this.Labels.Count];
+ Fill(this.MinValue, double.NaN);
+ }
+
+ ///
+ /// Creates Labels list if no labels were set
+ ///
+ ///
+ /// The list of series which are rendered
+ ///
+ internal void UpdateLabels(IEnumerable series)
+ {
+ if (this.ItemsSource != null)
+ {
+ this.Labels.Clear();
+ ReflectionHelper.FillList(this.ItemsSource, this.LabelField, this.Labels);
+ }
+
+ if (this.Labels.Count == 0)
+ {
+ foreach (var s in series)
+ {
+ if (!s.IsUsing(this))
+ {
+ continue;
+ }
+
+ var bsb = s as CategorizedSeries;
+ if (bsb != null)
+ {
+ int max = bsb.GetItems().Count;
+ while (this.Labels.Count < max)
+ {
+ this.Labels.Add((this.Labels.Count + 1).ToString(CultureInfo.InvariantCulture));
+ }
+ }
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/ColorAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/ColorAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,283 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The color axis.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Represents a color axis.
+ ///
+ public class ColorAxis : Axis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ColorAxis()
+ {
+ this.Position = AxisPosition.None;
+ this.IsPanEnabled = false;
+ this.IsZoomEnabled = false;
+ }
+
+ ///
+ /// Gets or sets the color of values above the maximum value.
+ ///
+ /// The color of the high values.
+ public OxyColor HighColor { get; set; }
+
+ ///
+ /// Gets or sets the color of values below the minimum value.
+ ///
+ /// The color of the low values.
+ public OxyColor LowColor { get; set; }
+
+ ///
+ /// Gets or sets the palette.
+ ///
+ /// The palette.
+ public OxyPalette Palette { get; set; }
+
+ ///
+ /// Gets the color.
+ ///
+ ///
+ /// The color map index (less than NumberOfEntries).
+ ///
+ ///
+ /// The color.
+ ///
+ public OxyColor GetColor(int paletteIndex)
+ {
+ if (paletteIndex == 0)
+ {
+ return this.LowColor;
+ }
+
+ if (paletteIndex == this.Palette.Colors.Count + 1)
+ {
+ return this.HighColor;
+ }
+
+ return this.Palette.Colors[paletteIndex - 1];
+ }
+
+ ///
+ /// Gets the color for the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The color.
+ ///
+ public OxyColor GetColor(double value)
+ {
+ return this.GetColor(this.GetPaletteIndex(value));
+ }
+
+ ///
+ /// Gets the colors.
+ ///
+ /// The colors.
+ public IEnumerable GetColors()
+ {
+ yield return this.LowColor;
+ foreach (var color in this.Palette.Colors)
+ {
+ yield return color;
+ }
+
+ yield return this.HighColor;
+ }
+
+ ///
+ /// Gets the palette index of the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The palette index.
+ ///
+ ///
+ /// If the value is less than minimum, 0 is returned. If the value is greater than maximum, Palette.Colors.Count+1 is returned.
+ ///
+ public int GetPaletteIndex(double value)
+ {
+ if (this.LowColor != null && value < this.Minimum)
+ {
+ return 0;
+ }
+
+ if (this.HighColor != null && value > this.Maximum)
+ {
+ return this.Palette.Colors.Count + 1;
+ }
+
+ int index = 1 + (int)((value - this.ActualMinimum) / (this.ActualMaximum - this.ActualMinimum) * this.Palette.Colors.Count);
+
+ if (index < 1)
+ {
+ index = 1;
+ }
+
+ if (index > this.Palette.Colors.Count)
+ {
+ index = this.Palette.Colors.Count;
+ }
+
+ return index;
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public override bool IsXyAxis()
+ {
+ return false;
+ }
+
+ ///
+ /// Renders the axis on the specified render context.
+ ///
+ /// The render context.
+ /// The model.
+ /// The rendering order.
+ /// The render pass.
+ public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
+ {
+ if (this.Position == AxisPosition.None)
+ {
+ return;
+ }
+
+ if (pass == 0)
+ {
+ double left = model.PlotArea.Left;
+ double top = model.PlotArea.Top;
+ double width = this.MajorTickSize - 2;
+ double height = this.MajorTickSize - 2;
+
+ switch (this.Position)
+ {
+ case AxisPosition.Left:
+ left = model.PlotArea.Left - this.PositionTierMinShift - width;
+ top = model.PlotArea.Top;
+ break;
+ case AxisPosition.Right:
+ left = model.PlotArea.Right + this.PositionTierMinShift;
+ top = model.PlotArea.Top;
+ break;
+ case AxisPosition.Top:
+ left = model.PlotArea.Left;
+ top = model.PlotArea.Top - this.PositionTierMinShift - height;
+ break;
+ case AxisPosition.Bottom:
+ left = model.PlotArea.Left;
+ top = model.PlotArea.Bottom + this.PositionTierMinShift;
+ break;
+ }
+
+ Action drawColorRect = (ylow, yhigh, color) =>
+ {
+ double ymin = Math.Min(ylow, yhigh);
+ double ymax = Math.Max(ylow, yhigh);
+ rc.DrawRectangle(
+ this.IsHorizontal()
+ ? new OxyRect(ymin, top, ymax - ymin, height)
+ : new OxyRect(left, ymin, width, ymax - ymin),
+ color,
+ null);
+ };
+
+ int n = this.Palette.Colors.Count;
+ for (int i = 0; i < n; i++)
+ {
+ double ylow = this.Transform(this.GetLowValue(i));
+ double yhigh = this.Transform(this.GetHighValue(i));
+ drawColorRect(ylow, yhigh, this.Palette.Colors[i]);
+ }
+
+ double highLowLength = 10;
+ if (this.IsHorizontal())
+ {
+ highLowLength *= -1;
+ }
+
+ if (this.LowColor != null)
+ {
+ double ylow = this.Transform(this.ActualMinimum);
+ drawColorRect(ylow, ylow + highLowLength, this.LowColor);
+ }
+
+ if (this.HighColor != null)
+ {
+ double yhigh = this.Transform(this.ActualMaximum);
+ drawColorRect(yhigh, yhigh - highLowLength, this.HighColor);
+ }
+ }
+
+ base.Render(rc, model, axisLayer, pass);
+ }
+
+ ///
+ /// Gets the high value of the specified palette index.
+ ///
+ ///
+ /// Index of the palette.
+ ///
+ ///
+ /// The value.
+ ///
+ protected double GetHighValue(int paletteIndex)
+ {
+ return this.GetLowValue(paletteIndex + 1);
+ }
+
+ ///
+ /// Gets the low value of the specified palette index.
+ ///
+ ///
+ /// Index of the palette.
+ ///
+ ///
+ /// The value.
+ ///
+ protected double GetLowValue(int paletteIndex)
+ {
+ return ((double)paletteIndex / this.Palette.Colors.Count * (this.ActualMaximum - this.ActualMinimum))
+ + this.ActualMinimum;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,679 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a DateTime axis.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot.Axes
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Globalization;
+ using System.Linq;
+
+ ///
+ /// Represents a axis presenting values.
+ ///
+ ///
+ /// The actual numeric values on the axis are days since 1900/01/01.
+ /// Use the static ToDouble and ToDateTime to convert numeric values to DateTimes.
+ /// The StringFormat value can be used to force formatting of the axis values
+ /// "yyyy-MM-dd" shows date
+ /// "w" or "ww" shows week number
+ /// "h:mm" shows hours and minutes
+ ///
+ public class DateTimeAxis : LinearAxis
+ {
+ ///
+ /// The time origin.
+ ///
+ ///
+ /// Same date values as Excel
+ ///
+ private static DateTime timeOrigin = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ ///
+ /// The actual interval type.
+ ///
+ private DateTimeIntervalType actualIntervalType;
+
+ ///
+ /// The actual minor interval type.
+ ///
+ private DateTimeIntervalType actualMinorIntervalType;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DateTimeAxis()
+ {
+ this.Position = AxisPosition.Bottom;
+ this.IntervalType = DateTimeIntervalType.Auto;
+ this.FirstDayOfWeek = DayOfWeek.Monday;
+ this.CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The axis title.
+ ///
+ ///
+ /// The string format for the axis values.
+ ///
+ ///
+ /// The interval type.
+ ///
+ public DateTimeAxis(
+ AxisPosition pos = AxisPosition.Bottom,
+ string title = null,
+ string format = null,
+ DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
+ : base(pos, title)
+ {
+ this.FirstDayOfWeek = DayOfWeek.Monday;
+ this.CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek;
+
+ this.StringFormat = format;
+ this.IntervalType = intervalType;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The first date/time on the axis.
+ ///
+ ///
+ /// The last date/time on the axis.
+ ///
+ ///
+ /// The position of the axis.
+ ///
+ ///
+ /// The axis title.
+ ///
+ ///
+ /// The string format for the axis values.
+ ///
+ ///
+ /// The interval type.
+ ///
+ [Obsolete]
+ public DateTimeAxis(
+ DateTime firstDateTime,
+ DateTime lastDateTime,
+ AxisPosition pos = AxisPosition.Bottom,
+ string title = null,
+ string format = null,
+ DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
+ : this(pos, title, format, intervalType)
+ {
+ this.Minimum = ToDouble(firstDateTime);
+ this.Maximum = ToDouble(lastDateTime);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The position of the axis.
+ /// The first date/time on the axis.
+ /// The last date/time on the axis.
+ /// The axis title.
+ /// The string format for the axis values.
+ /// The interval type.
+ public DateTimeAxis(
+ AxisPosition pos,
+ DateTime firstDateTime,
+ DateTime lastDateTime,
+ string title = null,
+ string format = null,
+ DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
+ : this(pos, title, format, intervalType)
+ {
+ this.Minimum = ToDouble(firstDateTime);
+ this.Maximum = ToDouble(lastDateTime);
+ }
+
+ ///
+ /// Gets or sets CalendarWeekRule.
+ ///
+ public CalendarWeekRule CalendarWeekRule { get; set; }
+
+ ///
+ /// Gets or sets FirstDayOfWeek.
+ ///
+ public DayOfWeek FirstDayOfWeek { get; set; }
+
+ ///
+ /// Gets or sets IntervalType.
+ ///
+ public DateTimeIntervalType IntervalType { get; set; }
+
+ ///
+ /// Gets or sets MinorIntervalType.
+ ///
+ public DateTimeIntervalType MinorIntervalType { get; set; }
+
+ ///
+ /// Gets or sets the time zone (used when formatting date/time values).
+ ///
+ ///
+ /// No date/time conversion will be performed if this property is null.
+ ///
+ ///
+ /// The time zone info.
+ ///
+ public TimeZoneInfo TimeZone { get; set; }
+
+ ///
+ /// Creates a data point.
+ ///
+ ///
+ /// The x value.
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// A data point.
+ ///
+ public static DataPoint CreateDataPoint(DateTime x, double y)
+ {
+ return new DataPoint(ToDouble(x), y);
+ }
+
+ ///
+ /// Creates a data point.
+ ///
+ ///
+ /// The x value.
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// A data point.
+ ///
+ public static DataPoint CreateDataPoint(DateTime x, DateTime y)
+ {
+ return new DataPoint(ToDouble(x), ToDouble(y));
+ }
+
+ ///
+ /// Creates a data point.
+ ///
+ ///
+ /// The x value.
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// A data point.
+ ///
+ public static DataPoint CreateDataPoint(double x, DateTime y)
+ {
+ return new DataPoint(x, ToDouble(y));
+ }
+
+ ///
+ /// Converts a numeric representation of the date (number of days after the time origin) to a DateTime structure.
+ ///
+ ///
+ /// The number of days after the time origin.
+ ///
+ ///
+ /// A date/time structure.
+ ///
+ public static DateTime ToDateTime(double value)
+ {
+ if (double.IsNaN(value))
+ {
+ return new DateTime();
+ }
+
+ return timeOrigin.AddDays(value - 1);
+ }
+
+ ///
+ /// Converts a DateTime to days after the time origin.
+ ///
+ ///
+ /// The date/time structure.
+ ///
+ ///
+ /// The number of days after the time origin.
+ ///
+ public static double ToDouble(DateTime value)
+ {
+ var span = value - timeOrigin;
+ return span.TotalDays + 1;
+ }
+
+ ///
+ /// Formats the specified value by the axis' ActualStringFormat.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The formatted DateTime value
+ ///
+ public override string FormatValue(double x)
+ {
+ // convert the double value to a DateTime
+ var time = ToDateTime(x);
+
+ // If a time zone is specified, convert the time
+ if (this.TimeZone != null)
+ {
+ time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
+ }
+
+ string fmt = this.ActualStringFormat;
+ if (fmt == null)
+ {
+ return time.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern);
+ }
+
+ int week = this.GetWeek(time);
+ fmt = fmt.Replace("ww", week.ToString("00"));
+ fmt = fmt.Replace("w", week.ToString(CultureInfo.InvariantCulture));
+ return time.ToString(fmt, this.ActualCulture);
+ }
+
+ ///
+ /// Gets the tick values.
+ ///
+ ///
+ /// The major label values.
+ ///
+ ///
+ /// The major tick values.
+ ///
+ ///
+ /// The minor tick values.
+ ///
+ public override void GetTickValues(
+ out IList majorLabelValues, out IList majorTickValues, out IList minorTickValues)
+ {
+ minorTickValues = this.CreateDateTimeTickValues(
+ this.ActualMinimum, this.ActualMaximum, this.ActualMinorStep, this.actualMinorIntervalType);
+ majorTickValues = this.CreateDateTimeTickValues(
+ this.ActualMinimum, this.ActualMaximum, this.ActualMajorStep, this.actualIntervalType);
+ majorLabelValues = majorTickValues;
+ }
+
+ ///
+ /// Gets the value from an axis coordinate, converts from double to the correct data type if necessary.
+ /// e.g. DateTimeAxis returns the DateTime and CategoryAxis returns category strings.
+ ///
+ ///
+ /// The coordinate.
+ ///
+ ///
+ /// The value.
+ ///
+ public override object GetValue(double x)
+ {
+ var time = ToDateTime(x);
+
+ if (this.TimeZone != null)
+ {
+ time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
+ }
+
+ return time;
+ }
+
+ ///
+ /// Updates the intervals.
+ ///
+ ///
+ /// The plot area.
+ ///
+ internal override void UpdateIntervals(OxyRect plotArea)
+ {
+ base.UpdateIntervals(plotArea);
+ switch (this.actualIntervalType)
+ {
+ case DateTimeIntervalType.Years:
+ this.ActualMinorStep = 31;
+ this.actualMinorIntervalType = DateTimeIntervalType.Years;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "yyyy";
+ }
+
+ break;
+ case DateTimeIntervalType.Months:
+ this.actualMinorIntervalType = DateTimeIntervalType.Months;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "yyyy-MM-dd";
+ }
+
+ break;
+ case DateTimeIntervalType.Weeks:
+ this.actualMinorIntervalType = DateTimeIntervalType.Days;
+ this.ActualMajorStep = 7;
+ this.ActualMinorStep = 1;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "yyyy/ww";
+ }
+
+ break;
+ case DateTimeIntervalType.Days:
+ this.ActualMinorStep = this.ActualMajorStep;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "yyyy-MM-dd";
+ }
+
+ break;
+ case DateTimeIntervalType.Hours:
+ this.ActualMinorStep = this.ActualMajorStep;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "HH:mm";
+ }
+
+ break;
+ case DateTimeIntervalType.Minutes:
+ this.ActualMinorStep = this.ActualMajorStep;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "HH:mm";
+ }
+
+ break;
+ case DateTimeIntervalType.Seconds:
+ this.ActualMinorStep = this.ActualMajorStep;
+ if (this.ActualStringFormat == null)
+ {
+ this.ActualStringFormat = "HH:mm:ss";
+ }
+
+ break;
+ case DateTimeIntervalType.Manual:
+ break;
+ case DateTimeIntervalType.Auto:
+ break;
+ }
+ }
+
+ ///
+ /// Calculates the actual interval.
+ ///
+ ///
+ /// Size of the available area.
+ ///
+ ///
+ /// Maximum length of the intervals.
+ ///
+ ///
+ /// The calculate actual interval.
+ ///
+ protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
+ {
+ const double Year = 365.25;
+ const double Month = 30.5;
+ const double Week = 7;
+ const double Day = 1.0;
+ const double Hour = Day / 24;
+ const double Minute = Hour / 60;
+ const double Second = Minute / 60;
+
+ double range = Math.Abs(this.ActualMinimum - this.ActualMaximum);
+
+ var goodIntervals = new[]
+ {
+ Second, 2 * Second, 5 * Second, 10 * Second, 30 * Second, Minute, 2 * Minute,
+ 5 * Minute, 10 * Minute, 30 * Minute, Hour, 4 * Hour, 8 * Hour, 12 * Hour, Day,
+ 2 * Day, 5 * Day, Week, 2 * Week, Month, 2 * Month, 3 * Month, 4 * Month,
+ 6 * Month, Year
+ };
+
+ double interval = goodIntervals[0];
+
+ int maxNumberOfIntervals = Math.Max((int)(availableSize / maxIntervalSize), 2);
+
+ while (true)
+ {
+ if (range / interval < maxNumberOfIntervals)
+ {
+ break;
+ }
+
+ double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
+ if (Math.Abs(nextInterval) < double.Epsilon)
+ {
+ nextInterval = interval * 2;
+ }
+
+ interval = nextInterval;
+ }
+
+ this.actualIntervalType = this.IntervalType;
+ this.actualMinorIntervalType = this.MinorIntervalType;
+
+ if (this.IntervalType == DateTimeIntervalType.Auto)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Seconds;
+ if (interval >= 1.0 / 24 / 60)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Minutes;
+ }
+
+ if (interval >= 1.0 / 24)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Hours;
+ }
+
+ if (interval >= 1)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Days;
+ }
+
+ if (interval >= 30)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Months;
+ }
+
+ if (range >= 365.25)
+ {
+ this.actualIntervalType = DateTimeIntervalType.Years;
+ }
+ }
+
+ if (this.actualIntervalType == DateTimeIntervalType.Months)
+ {
+ double monthsRange = range / 30.5;
+ interval = this.CalculateActualInterval(availableSize, maxIntervalSize, monthsRange);
+ }
+
+ if (this.actualIntervalType == DateTimeIntervalType.Years)
+ {
+ double yearsRange = range / 365.25;
+ interval = this.CalculateActualInterval(availableSize, maxIntervalSize, yearsRange);
+ }
+
+ if (this.actualMinorIntervalType == DateTimeIntervalType.Auto)
+ {
+ switch (this.actualIntervalType)
+ {
+ case DateTimeIntervalType.Years:
+ this.actualMinorIntervalType = DateTimeIntervalType.Months;
+ break;
+ case DateTimeIntervalType.Months:
+ this.actualMinorIntervalType = DateTimeIntervalType.Days;
+ break;
+ case DateTimeIntervalType.Weeks:
+ this.actualMinorIntervalType = DateTimeIntervalType.Days;
+ break;
+ case DateTimeIntervalType.Days:
+ this.actualMinorIntervalType = DateTimeIntervalType.Hours;
+ break;
+ case DateTimeIntervalType.Hours:
+ this.actualMinorIntervalType = DateTimeIntervalType.Minutes;
+ break;
+ default:
+ this.actualMinorIntervalType = DateTimeIntervalType.Days;
+ break;
+ }
+ }
+
+ return interval;
+ }
+
+ ///
+ /// Creates the date tick values.
+ ///
+ ///
+ /// The min.
+ ///
+ ///
+ /// The max.
+ ///
+ ///
+ /// The step.
+ ///
+ ///
+ /// Type of the interval.
+ ///
+ ///
+ /// Date tick values.
+ ///
+ private IList CreateDateTickValues(
+ double min, double max, double step, DateTimeIntervalType intervalType)
+ {
+ DateTime start = ToDateTime(min);
+ switch (intervalType)
+ {
+ case DateTimeIntervalType.Weeks:
+
+ // make sure the first tick is at the 1st day of a week
+ start = start.AddDays(-(int)start.DayOfWeek + (int)this.FirstDayOfWeek);
+ break;
+ case DateTimeIntervalType.Months:
+
+ // make sure the first tick is at the 1st of a month
+ start = new DateTime(start.Year, start.Month, 1);
+ break;
+ case DateTimeIntervalType.Years:
+
+ // make sure the first tick is at Jan 1st
+ start = new DateTime(start.Year, 1, 1);
+ break;
+ }
+
+ // Adds a tick to the end time to make sure the end DateTime is included.
+ DateTime end = ToDateTime(max).AddTicks(1);
+
+ DateTime current = start;
+ var values = new Collection();
+ double eps = step * 1e-3;
+ DateTime minDateTime = ToDateTime(min - eps);
+ DateTime maxDateTime = ToDateTime(max + eps);
+ while (current < end)
+ {
+ if (current > minDateTime && current < maxDateTime)
+ {
+ values.Add(ToDouble(current));
+ }
+
+ switch (intervalType)
+ {
+ case DateTimeIntervalType.Months:
+ current = current.AddMonths((int)Math.Ceiling(step));
+ break;
+ case DateTimeIntervalType.Years:
+ current = current.AddYears((int)Math.Ceiling(step));
+ break;
+ default:
+ current = current.AddDays(step);
+ break;
+ }
+ }
+
+ return values;
+ }
+
+ ///
+ /// Creates date/time tick values.
+ ///
+ ///
+ /// The min.
+ ///
+ ///
+ /// The max.
+ ///
+ ///
+ /// The interval.
+ ///
+ ///
+ /// The interval type.
+ ///
+ /// DateTime tick values.
+ ///
+ /// DateTime tick values.
+ ///
+ private IList CreateDateTimeTickValues(
+ double min, double max, double interval, DateTimeIntervalType intervalType)
+ {
+ // If the step size is more than 7 days (e.g. months or years) we use a specialized tick generation method that adds tick values with uneven spacing...
+ if (intervalType > DateTimeIntervalType.Days)
+ {
+ return this.CreateDateTickValues(min, max, interval, intervalType);
+ }
+
+ // For shorter step sizes we use the method from Axis
+ return CreateTickValues(min, max, interval);
+ }
+
+ ///
+ /// Gets the week number for the specified date.
+ ///
+ ///
+ /// The date.
+ ///
+ ///
+ /// The week number for the current culture.
+ ///
+ private int GetWeek(DateTime date)
+ {
+ return this.ActualCulture.Calendar.GetWeekOfYear(date, this.CalendarWeekRule, this.FirstDayOfWeek);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/DateTimeIntervalType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/DateTimeIntervalType.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,87 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Defines the date time interval for DateTimeAxis.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Specifies the date time interval for .
+ ///
+ public enum DateTimeIntervalType
+ {
+ ///
+ /// Automatically determine interval.
+ ///
+ Auto = 0,
+
+ ///
+ /// Manual definition of intervals.
+ ///
+ Manual = 1,
+
+ ///
+ /// Interval type is milliseconds.
+ ///
+ Milliseconds = 2,
+
+ ///
+ /// Interval type is seconds.
+ ///
+ Seconds = 3,
+
+ ///
+ /// Interval type is minutes.
+ ///
+ Minutes = 4,
+
+ ///
+ /// Interval type is hours.
+ ///
+ Hours = 5,
+
+ ///
+ /// Interval type is days.
+ ///
+ Days = 6,
+
+ ///
+ /// Interval type is weeks.
+ ///
+ Weeks = 7,
+
+ ///
+ /// Interval type is months.
+ ///
+ Months = 8,
+
+ ///
+ /// Interval type is years.
+ ///
+ Years = 9,
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/LinearAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/LinearAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,164 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an axis with linear scale.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Represents an axis with linear scale.
+ ///
+ public class LinearAxis : Axis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LinearAxis()
+ {
+ this.FractionUnit = 1.0;
+ this.FractionUnitSymbol = null;
+ this.FormatAsFractions = false;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The pos.
+ ///
+ ///
+ /// The title.
+ ///
+ public LinearAxis(AxisPosition pos, string title)
+ : this()
+ {
+ this.Position = pos;
+ this.Title = title;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The pos.
+ ///
+ ///
+ /// The minimum.
+ ///
+ ///
+ /// The maximum.
+ ///
+ ///
+ /// The title.
+ ///
+ public LinearAxis(
+ AxisPosition pos, double minimum = double.NaN, double maximum = double.NaN, string title = null)
+ : this(pos, minimum, maximum, double.NaN, double.NaN, title)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The pos.
+ ///
+ ///
+ /// The minimum.
+ ///
+ ///
+ /// The maximum.
+ ///
+ ///
+ /// The major step.
+ ///
+ ///
+ /// The minor step.
+ ///
+ ///
+ /// The title.
+ ///
+ public LinearAxis(
+ AxisPosition pos, double minimum, double maximum, double majorStep, double minorStep, string title = null)
+ : this(pos, title)
+ {
+ this.Minimum = minimum;
+ this.Maximum = maximum;
+ this.MajorStep = majorStep;
+ this.MinorStep = minorStep;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether to format numbers as fractions.
+ ///
+ public bool FormatAsFractions { get; set; }
+
+ ///
+ /// Gets or sets the fraction unit. Remember to set FormatAsFractions to true.
+ ///
+ /// The fraction unit.
+ public double FractionUnit { get; set; }
+
+ ///
+ /// Gets or sets the fraction unit symbol. Use FractionUnit = Math.PI and FractionUnitSymbol = "π" if you want the axis to show "π/2,π,3π/2,2π" etc. Use FractionUnit = 1 and FractionUnitSymbol = "L" if you want the axis to show "0,L/2,L" etc. Remember to set FormatAsFractions to true.
+ ///
+ /// The fraction unit symbol.
+ public string FractionUnitSymbol { get; set; }
+
+ ///
+ /// Formats the value to be used on the axis.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The formatted value.
+ ///
+ public override string FormatValue(double x)
+ {
+ if (this.FormatAsFractions)
+ {
+ return FractionHelper.ConvertToFractionString(
+ x, this.FractionUnit, this.FractionUnitSymbol, 1e-6, this.ActualCulture);
+ }
+
+ return base.FormatValue(x);
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public override bool IsXyAxis()
+ {
+ return true;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/LogarithmicAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/LogarithmicAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,406 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an axis with logarithmic scale.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+
+ ///
+ /// Represents an axis with logarithmic scale.
+ ///
+ ///
+ /// See http://en.wikipedia.org/wiki/Logarithmic_scale.
+ ///
+ public class LogarithmicAxis : Axis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LogarithmicAxis()
+ {
+ this.PowerPadding = true;
+ this.Base = 10;
+ this.FilterMinValue = 0;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The title.
+ ///
+ public LogarithmicAxis(AxisPosition pos, string title)
+ : this()
+ {
+ this.Position = pos;
+ this.Title = title;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The minimum.
+ ///
+ ///
+ /// The maximum.
+ ///
+ ///
+ /// The title.
+ ///
+ public LogarithmicAxis(
+ AxisPosition position, double minimum = double.NaN, double maximum = double.NaN, string title = null)
+ : this()
+ {
+ this.Position = position;
+ this.Title = title;
+ this.Minimum = minimum;
+ this.Maximum = maximum;
+ }
+
+ ///
+ /// Gets or sets the logarithmic base (normally 10).
+ ///
+ ///
+ /// See http://en.wikipedia.org/wiki/Logarithm.
+ ///
+ /// The logarithmic base.
+ public double Base { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the ActualMaximum and ActualMinimum values should be padded to the nearest power of the Base.
+ ///
+ public bool PowerPadding { get; set; }
+
+ ///
+ /// Coerces the actual maximum and minimum values.
+ ///
+ public override void CoerceActualMaxMin()
+ {
+ if (double.IsNaN(this.ActualMinimum) || double.IsInfinity(this.ActualMinimum))
+ {
+ this.ActualMinimum = 1;
+ }
+
+ if (this.ActualMinimum <= 0)
+ {
+ this.ActualMinimum = 1;
+ }
+
+ if (this.ActualMaximum <= this.ActualMinimum)
+ {
+ this.ActualMaximum = this.ActualMinimum * 100;
+ }
+
+ base.CoerceActualMaxMin();
+ }
+
+ ///
+ /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
+ ///
+ ///
+ /// The major label values.
+ ///
+ ///
+ /// The major tick values.
+ ///
+ ///
+ /// The minor tick values.
+ ///
+ public override void GetTickValues(
+ out IList majorLabelValues, out IList majorTickValues, out IList minorTickValues)
+ {
+ if (this.ActualMinimum <= 0)
+ {
+ this.ActualMinimum = 0.1;
+ }
+
+ double logBase = Math.Log(this.Base);
+ var e0 = (int)Math.Floor(Math.Log(this.ActualMinimum) / logBase);
+ var e1 = (int)Math.Ceiling(Math.Log(this.ActualMaximum) / logBase);
+
+ // find the min & max values for the specified base
+ // round to max 10 digits
+ double p0 = Math.Pow(this.Base, e0);
+ double p1 = Math.Pow(this.Base, e1);
+ double d0 = Math.Round(p0, 10);
+ double d1 = Math.Round(p1, 10);
+ if (d0 <= 0)
+ {
+ d0 = p0;
+ }
+
+ double d = d0;
+ majorTickValues = new List();
+ minorTickValues = new List();
+
+ double epsMin = this.ActualMinimum * 1e-6;
+ double epsMax = this.ActualMaximum * 1e-6;
+
+ while (d <= d1 + epsMax)
+ {
+ // d = RemoveNoiseFromDoubleMath(d);
+ if (d >= this.ActualMinimum - epsMin && d <= this.ActualMaximum + epsMax)
+ {
+ majorTickValues.Add(d);
+ }
+
+ for (int i = 1; i < this.Base; i++)
+ {
+ double d2 = d * (i + 1);
+ if (d2 > d1 + double.Epsilon)
+ {
+ break;
+ }
+
+ if (d2 > this.ActualMaximum)
+ {
+ break;
+ }
+
+ if (d2 >= this.ActualMinimum && d2 <= this.ActualMaximum)
+ {
+ minorTickValues.Add(d2);
+ }
+ }
+
+ d *= this.Base;
+ if (double.IsInfinity(d))
+ {
+ break;
+ }
+
+ if (d < double.Epsilon)
+ {
+ break;
+ }
+
+ if (double.IsNaN(d))
+ {
+ break;
+ }
+ }
+
+ if (majorTickValues.Count < 2)
+ {
+ base.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
+ }
+ else
+ {
+ majorLabelValues = majorTickValues;
+ }
+ }
+
+ ///
+ /// Determines whether the specified value is valid.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// true if the specified value is valid; otherwise, false.
+ ///
+ public override bool IsValidValue(double value)
+ {
+ return value > 0 && base.IsValidValue(value);
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public override bool IsXyAxis()
+ {
+ return true;
+ }
+
+ ///
+ /// Pans the specified axis.
+ ///
+ ///
+ /// The previous point (screen coordinates).
+ ///
+ ///
+ /// The current point (screen coordinates).
+ ///
+ public override void Pan(ScreenPoint ppt, ScreenPoint cpt)
+ {
+ if (!this.IsPanEnabled)
+ {
+ return;
+ }
+
+ bool isHorizontal = this.IsHorizontal();
+
+ double x0 = this.InverseTransform(isHorizontal ? ppt.X : ppt.Y);
+ double x1 = this.InverseTransform(isHorizontal ? cpt.X : cpt.Y);
+
+ if (Math.Abs(x1) < double.Epsilon)
+ {
+ return;
+ }
+
+ double dx = x0 / x1;
+
+ double newMinimum = this.ActualMinimum * dx;
+ double newMaximum = this.ActualMaximum * dx;
+ if (newMinimum < this.AbsoluteMinimum)
+ {
+ newMinimum = this.AbsoluteMinimum;
+ newMaximum = newMinimum * this.ActualMaximum / this.ActualMinimum;
+ }
+
+ if (newMaximum > this.AbsoluteMaximum)
+ {
+ newMaximum = this.AbsoluteMaximum;
+ newMinimum = newMaximum * this.ActualMaximum / this.ActualMinimum;
+ }
+
+ this.ViewMinimum = newMinimum;
+ this.ViewMaximum = newMaximum;
+
+ this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Pan));
+ }
+
+ ///
+ /// Transforms the specified coordinate to screen coordinates.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The transformed value (screen coordinate).
+ ///
+ public override double Transform(double x)
+ {
+ Debug.Assert(x > 0, "Value should be positive.");
+ if (x <= 0)
+ {
+ return -1;
+ }
+
+ return (Math.Log(x) - this.offset) * this.scale;
+ }
+
+ ///
+ /// Zooms the axis at the specified coordinate.
+ ///
+ ///
+ /// The zoom factor.
+ ///
+ ///
+ /// The coordinate to zoom at.
+ ///
+ public override void ZoomAt(double factor, double x)
+ {
+ if (!this.IsZoomEnabled)
+ {
+ return;
+ }
+
+ double px = this.PreTransform(x);
+ double dx0 = this.PreTransform(this.ActualMinimum) - px;
+ double dx1 = this.PreTransform(this.ActualMaximum) - px;
+ double newViewMinimum = this.PostInverseTransform((dx0 / factor) + px);
+ double newViewMaximum = this.PostInverseTransform((dx1 / factor) + px);
+
+ this.ViewMinimum = Math.Max(newViewMinimum, this.AbsoluteMinimum);
+ this.ViewMaximum = Math.Min(newViewMaximum, this.AbsoluteMaximum);
+ }
+
+ ///
+ /// Applies a transformation after the inverse transform of the value. This is used in logarithmic axis.
+ ///
+ /// The value to transform.
+ ///
+ /// The transformed value.
+ ///
+ internal override double PostInverseTransform(double x)
+ {
+ return Math.Exp(x);
+ }
+
+ ///
+ /// Applies a transformation before the transform the value. This is used in logarithmic axis.
+ ///
+ /// The value to transform.
+ ///
+ /// The transformed value.
+ ///
+ internal override double PreTransform(double x)
+ {
+ Debug.Assert(x > 0, "Value should be positive.");
+
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ return Math.Log(x);
+ }
+
+ ///
+ /// Updates the actual maximum and minimum values.
+ /// If the user has zoomed/panned the axis, the internal ViewMaximum/ViewMinimum values will be used.
+ /// If Maximum or Minimum have been set, these values will be used.
+ /// Otherwise the maximum and minimum values of the series will be used, including the 'padding'.
+ ///
+ internal override void UpdateActualMaxMin()
+ {
+ if (this.PowerPadding)
+ {
+ double logBase = Math.Log(this.Base);
+ var e0 = (int)Math.Floor(Math.Log(this.ActualMinimum) / logBase);
+ var e1 = (int)Math.Ceiling(Math.Log(this.ActualMaximum) / logBase);
+ if (!double.IsNaN(this.ActualMinimum))
+ {
+ this.ActualMinimum = Math.Exp(e0 * logBase).RemoveNoiseFromDoubleMath();
+ }
+
+ if (!double.IsNaN(this.ActualMaximum))
+ {
+ this.ActualMaximum = Math.Exp(e1 * logBase).RemoveNoiseFromDoubleMath();
+ }
+ }
+
+ base.UpdateActualMaxMin();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/MagnitudeAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/MagnitudeAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,205 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a magnitude axis for polar plots.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+
+ ///
+ /// Represents a magnitude axis for polar plots.
+ ///
+ public class MagnitudeAxis : LinearAxis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MagnitudeAxis()
+ {
+ this.Position = AxisPosition.Bottom;
+ this.IsPanEnabled = false;
+ this.IsZoomEnabled = false;
+
+ this.MajorGridlineStyle = LineStyle.Solid;
+ this.MinorGridlineStyle = LineStyle.Solid;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The minimum.
+ ///
+ ///
+ /// The maximum.
+ ///
+ ///
+ /// The major step.
+ ///
+ ///
+ /// The minor step.
+ ///
+ ///
+ /// The title.
+ ///
+ public MagnitudeAxis(
+ double minimum = double.NaN,
+ double maximum = double.NaN,
+ double majorStep = double.NaN,
+ double minorStep = double.NaN,
+ string title = null)
+ : this()
+ {
+ this.Minimum = minimum;
+ this.Maximum = maximum;
+ this.MajorStep = majorStep;
+ this.MinorStep = minorStep;
+ this.Title = title;
+ }
+
+ ///
+ /// Gets or sets the midpoint (screen coordinates) of the plot area. This is used by polar coordinate systems.
+ ///
+ internal ScreenPoint MidPoint { get; set; }
+
+ ///
+ /// Inverse transform the specified screen point.
+ ///
+ ///
+ /// The x coordinate.
+ ///
+ ///
+ /// The y coordinate.
+ ///
+ ///
+ /// The y-axis.
+ ///
+ ///
+ /// The data point.
+ ///
+ public override DataPoint InverseTransform(double x, double y, Axis yaxis)
+ {
+ var angleAxis = yaxis as AngleAxis;
+ if (angleAxis == null)
+ {
+ throw new InvalidOperationException("Polar angle axis not defined!");
+ }
+
+ x -= this.MidPoint.x;
+ y -= this.MidPoint.y;
+ double th = Math.Atan2(y, x);
+ double r = Math.Sqrt((x * x) + (y * y));
+ x = (r / this.scale) + this.offset;
+ y = (th / angleAxis.Scale) + angleAxis.Offset;
+ return new DataPoint(x, y);
+ }
+
+ ///
+ /// Determines whether the axis is used for X/Y values.
+ ///
+ ///
+ /// true if it is an XY axis; otherwise, false .
+ ///
+ public override bool IsXyAxis()
+ {
+ return false;
+ }
+
+ ///
+ /// Renders the axis on the specified render context.
+ ///
+ /// The render context.
+ /// The model.
+ /// The rendering order.
+ ///
+ public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
+ {
+ if (this.Layer != axisLayer)
+ {
+ return;
+ }
+
+ var r = new MagnitudeAxisRenderer(rc, model);
+ r.Render(this, pass);
+ }
+
+ ///
+ /// Transforms the specified point to screen coordinates.
+ ///
+ ///
+ /// The x value (for the current axis).
+ ///
+ ///
+ /// The y value.
+ ///
+ ///
+ /// The y axis.
+ ///
+ ///
+ /// The transformed point.
+ ///
+ public override ScreenPoint Transform(double x, double y, Axis yaxis)
+ {
+ var angleAxis = yaxis as AngleAxis;
+ if (angleAxis == null)
+ {
+ throw new InvalidOperationException("Polar angle axis not defined!");
+ }
+
+ double r = (x - this.Offset) * this.scale;
+ double theta = (y - angleAxis.Offset) * angleAxis.Scale;
+
+ return new ScreenPoint(this.MidPoint.x + (r * Math.Cos(theta)), this.MidPoint.y - (r * Math.Sin(theta)));
+ }
+
+ ///
+ /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
+ ///
+ ///
+ /// The bounds.
+ ///
+ internal override void UpdateTransform(OxyRect bounds)
+ {
+ double x0 = bounds.Left;
+ double x1 = bounds.Right;
+ double y0 = bounds.Bottom;
+ double y1 = bounds.Top;
+
+ this.ScreenMin = new ScreenPoint(x0, y1);
+ this.ScreenMax = new ScreenPoint(x1, y0);
+
+ this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);
+
+ this.ActualMinimum = 0;
+ double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
+ this.scale = 0.5 * r / (this.ActualMaximum - this.ActualMinimum);
+ this.Offset = this.ActualMinimum;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/RangeAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/RangeAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,469 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Updates the minor/major step intervals if they are undefined.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace OxyPlot
+{
+ public class Axis : IAxis
+ {
+ public Axis()
+ {
+ Position = AxisPosition.Left;
+ IsVisible = true;
+
+ Minimum = double.NaN;
+ Maximum = double.NaN;
+ MinorStep = double.NaN;
+ MajorStep = double.NaN;
+
+ MinimumPadding = 0.01;
+ MaximumPadding = 0.01;
+
+ TickStyle = TickStyle.Inside;
+ MajorGridlineStyle = LineStyle.None;
+ MinorGridlineStyle = LineStyle.None;
+ TicklineColor = Colors.Black;
+ MajorGridlineColor = Color.FromARGB(0x40, 0, 0, 0);
+ TicklineColor = Colors.Black;
+ MinorGridlineColor = Color.FromARGB(0x20, 0, 0, 0x00);
+ MajorGridlineThickness = 1;
+ MinorGridlineThickness = 1;
+
+ ExtraGridlineStyle = LineStyle.Solid;
+ ExtraGridlineColor = Colors.Black;
+ ExtraGridlineThickness = 1;
+
+ ShowMinorTicks = true;
+
+ FontFamily = "Segoe UI";
+ FontSize = 12;
+
+ MinorTickSize = 4;
+ MajorTickSize = 7;
+
+ StartPosition = 0;
+ EndPosition = 1;
+
+ Angle = 0;
+ }
+
+ public Axis(AxisPosition pos, double minimum, double maximum)
+ : this()
+ {
+ Position = pos;
+ Minimum = minimum;
+ Maximum = maximum;
+ }
+ public string Key { get; set; }
+
+ public AxisPosition Position { get; set; }
+ public bool PositionAtZeroCrossing { get; set; }
+ public bool IsHorizontal { get { return Position == AxisPosition.Top || Position == AxisPosition.Bottom; } }
+ public bool IsVertical { get { return Position == AxisPosition.Left || Position == AxisPosition.Right; } }
+ public bool IsPolar { get { return Position == AxisPosition.Magnitude || Position == AxisPosition.Angle; } }
+
+ public bool IsVisible { get; set; }
+
+ public double ActualMinimum { get; set; }
+ public double ActualMaximum { get; set; }
+ internal double ActualMinorStep { get; set; }
+ internal double ActualMajorStep { get; set; }
+
+ public double Minimum { get; set; }
+ public double Maximum { get; set; }
+ public double MinorStep { get; set; }
+ public double MajorStep { get; set; }
+
+ public double MinimumPadding { get; set; }
+ public double MaximumPadding { get; set; }
+
+ public TickStyle TickStyle { get; set; }
+ public double MinorTickSize { get; set; }
+ public double MajorTickSize { get; set; }
+ public Color TicklineColor { get; set; }
+ public bool ShowMinorTicks { get; set; }
+
+ public LineStyle MajorGridlineStyle { get; set; }
+ public LineStyle MinorGridlineStyle { get; set; }
+ public Color MajorGridlineColor { get; set; }
+ public Color MinorGridlineColor { get; set; }
+ public double MajorGridlineThickness { get; set; }
+ public double MinorGridlineThickness { get; set; }
+
+ public double[] ExtraGridlines { get; set; }
+ public LineStyle ExtraGridlineStyle { get; set; }
+ public Color ExtraGridlineColor { get; set; }
+ public double ExtraGridlineThickness { get; set; }
+
+ public double Angle { get; set; }
+ public string StringFormat { get; set; }
+ internal string ActualStringFormat { get; set; }
+ public string Title { get; set; }
+ public string Unit { get; set; }
+
+ public string FontFamily { get; set; }
+ public double FontSize { get; set; }
+ public double FontWeight { get; set; }
+
+ public double StartPosition { get; set; }
+ public double EndPosition { get; set; }
+
+ public Axis RelatedAxis { get; set; }
+
+ public bool IsReversed { get { return StartPosition > EndPosition; } }
+
+ internal double Offset;
+ internal double Scale;
+ internal Point MidPoint;
+ internal Point ScreenMin;
+ internal Point ScreenMax;
+
+ public override string ToString()
+ {
+ return String.Format(CultureInfo.InvariantCulture, "{0}({1}, {2}, {3}, {4})", GetType().Name, Position, ActualMinimum, ActualMaximum, ActualMajorStep);
+ }
+
+ public virtual void GetTickValues(out ICollection majorValues, out ICollection minorValues)
+ {
+ minorValues = CreateTickValues(ActualMinimum, ActualMaximum, ActualMinorStep);
+ majorValues = CreateTickValues(ActualMinimum, ActualMaximum, ActualMajorStep);
+ }
+
+ public virtual string FormatValue(double x)
+ {
+ return x.ToString(ActualStringFormat, CultureInfo.InvariantCulture);
+ }
+
+ private static ICollection CreateTickValues(double min, double max, double step)
+ {
+ if (max <= min)
+ throw new InvalidOperationException("Axis: Maximum should be larger than minimum.");
+ if (step <= 0)
+ throw new InvalidOperationException("Axis: Step cannot be negative.");
+
+ double x = (int)Math.Round(min / step) * step;
+
+ var values = new Collection();
+ // Maximum number of iterations (in case of very small step size)
+ int it = 0;
+ const int maxit = 1000;
+ double epsilon = Math.Abs(max - min) * 1e-6;
+ while (x <= max + epsilon && it++ < maxit)
+ {
+ if (x >= min - epsilon && x <= max + epsilon)
+ {
+ x = RemoveNoiseFromDoubleMath(x);
+ values.Add(x);
+ }
+ x += step;
+ }
+ return values;
+ }
+
+ protected virtual double PreTransform(double x)
+ {
+ return x;
+ }
+
+ protected virtual double PostInverseTransform(double x)
+ {
+ return x;
+ }
+
+ public virtual Point Transform(double x, double y, Axis yAxis)
+ {
+ Debug.Assert(yAxis != null);
+ if (IsPolar)
+ {
+ double r = (x - Offset) * Scale;
+ double th = yAxis != null ? (y - yAxis.Offset) * yAxis.Scale : double.NaN;
+ return new Point(MidPoint.X + r * Math.Cos(th), MidPoint.Y + r * Math.Sin(th));
+ }
+ if (yAxis == null)
+ return new Point();
+ return new Point(TransformX(x), yAxis != null ? yAxis.TransformX(y) : double.NaN);
+ }
+
+ public double TransformX(double x)
+ {
+ return (PreTransform(x) - Offset) * Scale;
+ }
+
+ public virtual Point InverseTransform(double x, double y, Axis yAxis)
+ {
+ Debug.Assert(yAxis != null);
+ if (IsPolar)
+ {
+ x -= MidPoint.X;
+ y -= MidPoint.Y;
+ double th = Math.Atan2(y, x);
+ double r = Math.Sqrt(x * x + y * y);
+ x = r / Scale + Offset;
+ y = yAxis != null ? th / yAxis.Scale + yAxis.Offset : double.NaN;
+ return new Point(x, y);
+ }
+
+ return new Point(InverseTransformX(x), yAxis.InverseTransformX(y));
+ }
+
+ public double InverseTransformX(double x)
+ {
+ return PostInverseTransform(x / Scale + Offset);
+ }
+
+ public double UpdateTransform(double x0, double x1, double y0, double y1)
+ {
+ ScreenMin = new Point(x0, y1);
+ ScreenMax = new Point(x1, y0);
+
+ if (Position == AxisPosition.Angle)
+ {
+ MidPoint = new Point((x0 + x1) / 2, (y0 + y1) / 2);
+ Scale = 2 * Math.PI / (ActualMaximum - ActualMinimum);
+ Offset = ActualMinimum;
+ return Scale;
+ }
+ if (Position == AxisPosition.Magnitude)
+ {
+ ActualMinimum = 0;
+ MidPoint = new Point((x0 + x1) / 2, (y0 + y1) / 2);
+ double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
+ Scale = 0.5 * r / (ActualMaximum - ActualMinimum);
+ Offset = ActualMinimum;
+ return Scale;
+ }
+ double a0 = IsHorizontal ? x0 : y0;
+ double a1 = IsHorizontal ? x1 : y1;
+
+ double dx = a1 - a0;
+ a1 = a0 + EndPosition * dx;
+ a0 = a0 + StartPosition * dx;
+
+ if (ActualMaximum - ActualMinimum < double.Epsilon)
+ ActualMaximum = ActualMinimum + 1;
+
+ double max = PreTransform(ActualMaximum);
+ double min = PreTransform(ActualMinimum);
+
+ const double eps = 1e-6;
+ if (max - min < eps) max = min + 1;
+
+ if (Math.Abs(a0 - a1) != 0)
+ Offset = (a0 * max - min * a1) / (a0 - a1);
+ else
+ Offset = 0;
+
+ Scale = (a1 - a0) / (max - min);
+
+ return Scale;
+ }
+
+ public void SetScale(double scale)
+ {
+ double sgn = Math.Sign(Scale);
+ double mid = (ActualMaximum + ActualMinimum) / 2;
+ double dx = (Offset - mid) * Scale;
+ Scale = sgn * scale;
+ Offset = dx / Scale + mid;
+ }
+
+ public virtual void Pan(double dx)
+ {
+ Minimum = ActualMinimum + dx;
+ Maximum = ActualMaximum + dx;
+ }
+
+ public virtual void ScaleAt(double factor, double x)
+ {
+ double dx0 = (ActualMinimum - x) * Scale;
+ double dx1 = (ActualMaximum - x) * Scale;
+ Scale *= factor;
+ Minimum = dx0 / Scale + x;
+ Maximum = dx1 / Scale + x;
+ }
+
+ public virtual void Zoom(double x0, double x1)
+ {
+ Minimum = Math.Min(x0, x1);
+ Maximum = Math.Max(x0, x1);
+ }
+
+ public virtual void Reset()
+ {
+ Minimum = double.NaN;
+ Maximum = double.NaN;
+ }
+
+ ///
+ /// Updates the minor/major step intervals if they are undefined.
+ ///
+ public void UpdateIntervals(double dx, double dy)
+ {
+ double labelSize = GetLabelSize();
+ double length = IsHorizontal ? dx : dy;
+
+ if (!double.IsNaN(MajorStep))
+ ActualMajorStep = MajorStep;
+ else
+ ActualMajorStep = CalculateActualInterval(length, labelSize);
+
+ if (!double.IsNaN(MinorStep))
+ ActualMinorStep = MinorStep;
+ else
+ ActualMinorStep = ActualMajorStep / 5;
+
+ if (double.IsNaN(ActualMinorStep))
+ ActualMinorStep = 2;
+ if (double.IsNaN(ActualMajorStep))
+ ActualMajorStep = 10;
+
+ ActualStringFormat = StringFormat;
+ }
+
+ private double GetLabelSize()
+ {
+ if (IsHorizontal)
+ return 100;
+ if (IsVertical)
+ return 30;
+ if (Position == AxisPosition.Angle)
+ return 50;
+ if (Position == AxisPosition.Magnitude)
+ return 100;
+ return 50;
+ }
+
+ protected virtual double CalculateActualInterval(double availableSize, double maxIntervalSize)
+ {
+ return CalculateActualInterval2(availableSize, maxIntervalSize);
+ }
+
+ private double CalculateActualInterval1(double availableSize, double maxIntervalSize)
+ {
+ int minTags = 5;
+ int maxTags = 20;
+ int numberOfTags = (int)(availableSize / maxIntervalSize);
+ double range = ActualMaximum - ActualMinimum;
+ double interval = range / numberOfTags;
+ const int k1 = 10;
+ interval = Math.Log10(interval / k1);
+ interval = Math.Ceiling(interval);
+ interval = Math.Pow(10, interval) * k1;
+
+ if (range / interval > maxTags) interval *= 5;
+ if (range / interval < minTags) interval *= 0.5;
+
+ if (interval <= 0) interval = 1;
+ return interval;
+ }
+
+ ///
+ /// Returns the actual interval to use to determine which values are
+ /// displayed in the axis.
+ ///
+ /// The available size.
+ /// Actual interval to use to determine which values are
+ /// displayed in the axis.
+ ///
+ private double CalculateActualInterval2(double availableSize, double maxIntervalSize)
+ {
+ Func Exponent = x => Math.Ceiling(Math.Log(x, 10));
+ Func Mantissa = x => x / Math.Pow(10, Exponent(x) - 1);
+
+ // reduce intervals for horizontal axis.
+ // double maxIntervals = Orientation == AxisOrientation.X ? MaximumAxisIntervalsPer200Pixels * 0.8 : MaximumAxisIntervalsPer200Pixels;
+ // real maximum interval count
+ double maxIntervalCount = availableSize / maxIntervalSize;
+
+ double range = Math.Abs(ActualMinimum - ActualMaximum);
+ double interval = Math.Pow(10, Exponent(range));
+ double tempInterval = interval;
+
+ // decrease interval until interval count becomes less than maxIntervalCount
+ while (true)
+ {
+ int mantissa = (int)Mantissa(tempInterval);
+ if (mantissa == 5)
+ {
+ // reduce 5 to 2
+ tempInterval = RemoveNoiseFromDoubleMath(tempInterval / 2.5);
+ }
+ else if (mantissa == 2 || mantissa == 1 || mantissa == 10)
+ {
+ // reduce 2 to 1,10 to 5,1 to 0.5
+ tempInterval = RemoveNoiseFromDoubleMath(tempInterval / 2.0);
+ }
+
+ if (range / tempInterval > maxIntervalCount)
+ {
+ break;
+ }
+
+ interval = tempInterval;
+ }
+ return interval;
+ }
+
+ ///
+ /// Removes the noise from double math.
+ ///
+ /// The value.
+ /// A double without a noise.
+ internal static double RemoveNoiseFromDoubleMath(double value)
+ {
+ if (value == 0.0 || Math.Abs((Math.Log10(Math.Abs(value)))) < 27)
+ {
+ return (double)((decimal)value);
+ }
+ return Double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
+ }
+
+ public void Include(double p)
+ {
+ if (double.IsNaN(p) || double.IsInfinity(p))
+ return;
+
+ if (double.IsNaN(ActualMinimum))
+ ActualMinimum = p;
+ else
+ ActualMinimum = Math.Min(ActualMinimum, p);
+
+ if (double.IsNaN(ActualMaximum))
+ ActualMaximum = p;
+ else
+ ActualMaximum = Math.Max(ActualMaximum, p);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/TickStyle.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/TickStyle.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,57 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Tick styles.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ ///
+ /// Specifies the style of axis ticks.
+ ///
+ public enum TickStyle
+ {
+ ///
+ /// The ticks are rendered crossing the axis line.
+ ///
+ Crossing,
+
+ ///
+ /// The ticks are rendered inside of the plot area.
+ ///
+ Inside,
+
+ ///
+ /// The ticks are rendered Outside the plot area.
+ ///
+ Outside,
+
+ ///
+ /// The ticks are not rendered.
+ ///
+ None
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/TimeAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/TimeAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,120 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Time Axis
+// The values should be in seconds.
+// The StringFormat value can be used to force formatting of the axis values
+// "h:mm" shows hours and minutes
+// "m:ss" shows minutes and seconds
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+using System.Linq;
+
+namespace OxyPlot
+{
+ ///
+ /// Time Axis
+ /// The values should be in seconds.
+ /// The StringFormat value can be used to force formatting of the axis values
+ /// "h:mm" shows hours and minutes
+ /// "m:ss" shows minutes and seconds
+ ///
+ public class TimeAxis : LinearAxis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The position.
+ /// The axis title.
+ /// The string format for the axis values.
+ public TimeAxis(AxisPosition pos, string title = null, string format = "m:ss")
+ : base(pos, title)
+ {
+ StringFormat = format;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The position.
+ /// The min.
+ /// The max.
+ /// The axis title.
+ /// The string format for the axis values.
+ public TimeAxis(AxisPosition pos = AxisPosition.Bottom, double min = double.NaN, double max = double.NaN,
+ string title = null, string format = "m:ss")
+ : base(pos, min, max, title)
+ {
+ StringFormat = format;
+ }
+
+ ///
+ /// Formats the value.
+ ///
+ /// The x.
+ ///
+ public override string FormatValue(double x)
+ {
+ var span = TimeSpan.FromSeconds(x);
+ string s = ActualStringFormat ?? "h:mm:ss";
+
+ s = s.Replace("mm", span.Minutes.ToString("00"));
+ s = s.Replace("ss", span.Seconds.ToString("00"));
+ s = s.Replace("hh", span.Hours.ToString("00"));
+ s = s.Replace("msec", span.Milliseconds.ToString("000"));
+ s = s.Replace("m", ((int)span.TotalMinutes).ToString("0"));
+ s = s.Replace("s", ((int)span.TotalSeconds).ToString("0"));
+ s = s.Replace("h", ((int)span.TotalHours).ToString("0"));
+ return s;
+ }
+
+ protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
+ {
+ double range = Math.Abs(ActualMinimum - ActualMaximum);
+ double interval = 1;
+ var goodIntervals = new[] { 1.0, 5, 10, 30, 60, 120, 300, 600, 900, 1200, 1800, 3600 };
+
+ const int maxSteps = 20;
+
+ while (true)
+ {
+ if (range / interval < maxSteps)
+ {
+ return interval;
+ }
+
+ double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
+ if (nextInterval == 0)
+ {
+ nextInterval = interval * 2;
+ }
+
+ interval = nextInterval;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Axes/TimeSpanAxis.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Axes/TimeSpanAxis.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,197 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Time axis.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Axes
+{
+ using System;
+ using System.Linq;
+
+ ///
+ /// Represents an axis presenting values.
+ ///
+ ///
+ /// The values should be in seconds.
+ /// The StringFormat value can be used to force formatting of the axis values
+ /// "h:mm" shows hours and minutes
+ /// "m:ss" shows minutes and seconds
+ ///
+ public class TimeSpanAxis : LinearAxis
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TimeSpanAxis()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The axis title.
+ ///
+ ///
+ /// The string format for the axis values.
+ ///
+ public TimeSpanAxis(AxisPosition pos, string title = null, string format = "m:ss")
+ : base(pos, title)
+ {
+ this.StringFormat = format;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The min.
+ ///
+ ///
+ /// The max.
+ ///
+ ///
+ /// The axis title.
+ ///
+ ///
+ /// The string format for the axis values.
+ ///
+ public TimeSpanAxis(
+ AxisPosition pos = AxisPosition.Bottom,
+ double min = double.NaN,
+ double max = double.NaN,
+ string title = null,
+ string format = "m:ss")
+ : base(pos, min, max, title)
+ {
+ this.StringFormat = format;
+ }
+
+ ///
+ /// Converts a time span to a double.
+ ///
+ ///
+ /// The time span.
+ ///
+ ///
+ /// A double value.
+ ///
+ public static double ToDouble(TimeSpan s)
+ {
+ return s.TotalSeconds;
+ }
+
+ ///
+ /// Converts a double to a time span.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// A time span.
+ ///
+ public static TimeSpan ToTimeSpan(double value)
+ {
+ return TimeSpan.FromSeconds(value);
+ }
+
+ ///
+ /// Formats the value.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The format value.
+ ///
+ public override string FormatValue(double x)
+ {
+ TimeSpan span = TimeSpan.FromSeconds(x);
+ string s = this.ActualStringFormat ?? "h:mm:ss";
+
+ s = s.Replace("mm", span.Minutes.ToString("00"));
+ s = s.Replace("ss", span.Seconds.ToString("00"));
+ s = s.Replace("hh", span.Hours.ToString("00"));
+ s = s.Replace("msec", span.Milliseconds.ToString("000"));
+ s = s.Replace("m", ((int)span.TotalMinutes).ToString("0"));
+ s = s.Replace("s", ((int)span.TotalSeconds).ToString("0"));
+ s = s.Replace("h", ((int)span.TotalHours).ToString("0"));
+ return s;
+ }
+
+ ///
+ /// Gets the value from an axis coordinate, converts from double to the correct data type if necessary. e.g. DateTimeAxis returns the DateTime and CategoryAxis returns category strings.
+ ///
+ /// The coordinate.
+ ///
+ /// The value.
+ ///
+ public override object GetValue(double x)
+ {
+ return TimeSpan.FromSeconds(x);
+ }
+
+ ///
+ /// Calculates the actual interval.
+ ///
+ /// Size of the available area.
+ /// Maximum length of the intervals.
+ ///
+ /// The calculate actual interval.
+ ///
+ protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
+ {
+ double range = Math.Abs(this.ActualMinimum - this.ActualMaximum);
+ double interval = 1;
+ var goodIntervals = new[] { 1.0, 5, 10, 30, 60, 120, 300, 600, 900, 1200, 1800, 3600 };
+
+ int maxNumberOfIntervals = Math.Max((int)(availableSize / maxIntervalSize), 2);
+
+ while (true)
+ {
+ if (range / interval < maxNumberOfIntervals)
+ {
+ return interval;
+ }
+
+ double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
+ if (Math.Abs(nextInterval) < double.Epsilon)
+ {
+ nextInterval = interval * 2;
+ }
+
+ interval = nextInterval;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/ClassDiagrams/PlotModel.cd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/ClassDiagrams/PlotModel.cd Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,276 @@
+
+
+
+
+
+
+
+
+ EBZwcA2UaBI/BUK9ZBHDJRgBY1uVERMI45sgpP2SPzE=
+ PlotModel\PlotModel.cs
+
+
+
+
+
+ AAQCAAEIAiAAAGCAABBAAAAhRCAMEAAAADAAggACIgA=
+ Series\LineSeries.cs
+
+
+
+
+
+ IAAAAAyAEAABgAAAACACAAAABAAEAAAAAAAAAgAAAAA=
+ Series\DataPointSeries.cs
+
+
+
+
+
+ AgAAAAEAEAAAAIAAAAAACAAAAAAECAAAABMAAgIAAAA=
+ Series\AreaSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Series\FunctionSeries.cs
+
+
+
+
+
+ AAQAAAAAAQAAACAAAAAAAAAAAAAAAAAAAAEAAAAAQAA=
+ Axes\LinearAxis.cs
+
+
+
+
+
+ AAAAAAAAAQAAEgAAAIAAABQAAAAAQAAAAAAAABQAQAA=
+ Axes\LogarithmicAxis.cs
+
+
+
+
+
+ AAAAAAAAIAAAAAEAAAAAAAAAAAEAAAAAABEAAAAAAAA=
+ Axes\TimeSpanAxis.cs
+
+
+
+
+
+ AIAAEAABMAAEEAgAIBAAAFAAAAAEnAAAAAEgAJAAABE=
+ Axes\CategoryAxis.cs
+
+
+
+
+
+ gAIAAAAAIAAkGAEBAAAAIAAAggAAAAAAABEAAAAVAAA=
+ Axes\DateTimeAxis.cs
+
+
+
+
+
+ gAAQAAAFAAAAAAAAAEAAQAQAAAAAAAAEABAADAACAAA=
+ Annotations\Annotation.cs
+
+
+
+
+
+ BAAQEAAAACBwAIAAABgAgAAAEAAAAAAACTAAkgAgYGA=
+ Annotations\LineAnnotation.cs
+
+
+
+
+
+ CAAAAAgAIAQAAAAAAAAAAAAAAIAAAABAAAAAEAAAAAA=
+ Series\BarSeries\BarSeries.cs
+
+
+
+
+
+ sAAQAAE1WAAAAAAAAEAAQAQAAAAEAAAAABAUACACEAA=
+ Series\XYAxisSeries.cs
+
+
+
+
+
+ AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAABAA=
+ Series\CandleStickSeries.cs
+
+
+
+
+
+ AAAAAAkBECABCAAAABgAAAQABAQEAAABAHAAggACAAA=
+ Series\HighLowSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAIIAAAA=
+ Series\ItemsSeries.cs
+
+
+
+
+
+ AQAQAAEAWGAYACAIAAAAAAAgAAgEICJAgpQFAoCCAAI=
+ Series\PieSeries.cs
+
+
+
+
+
+ AARQAAEIEAAAAEgQAAAIAAAgACBEAAAEABAwAgQDAgA=
+ Series\ScatterSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAAAA=
+ Series\StairStepSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAQAA=
+ Series\StemSeries.cs
+
+
+
+
+
+ AAAAAAAAAQAAAAAAAAAAQAQAAAAEAAAAABAAAAAAAAA=
+ Axes\AngleAxis.cs
+
+
+
+
+
+ AAAAAAAAAQAAAAAAAAAAQAQAAAAEAIAAABAAAAAAAAA=
+ Axes\MagnitudeAxis.cs
+
+
+
+
+
+ AAAQAAEAWABAEEAAAAAAAAAAAAAEAAAAABAkBgISAAA=
+ Series\Series.cs
+
+
+
+
+
+
+ gEeXCAGRedQgH2V09tJAe5wCkhCEgABEG1cgxZQB4CU=
+ Axes\Axis.cs
+
+
+
+
+
+ AAQACAAAACBAQAAAQFAAAAAAABAAAAAAgDAAgAAAAAg=
+ Annotations\ArrowAnnotation.cs
+
+
+
+
+
+ AAAAAAAAACBggAAAABAAAAAAAAAACAAAADAAgAAAAAA=
+ Annotations\PolygonAnnotation.cs
+
+
+
+
+
+ AAAAAAAgACBAAIAggAAAAAAAAAgAAAIAABIggAAAgAA=
+ Annotations\TextAnnotation.cs
+
+
+
+
+
+ BYQAAIEAKCSAACCQAAAAAAABAAgEIBBAAhAUAgoCAAE=
+ Series\BarSeries\BarSeriesBase.cs
+
+
+
+
+
+
+ AAAAAAgAIAQAAAAAAEAAAAAAAIAAAABAAAAAEAAAAAA=
+ Series\BarSeries\ColumnSeries.cs
+
+
+
+
+
+ DQQAAAkBGCSACECAAAAAAAABAIgEIgAAABAUEgoCAAE=
+ Series\BarSeries\IntervalBarSeries.cs
+
+
+
+
+
+
+ AAAAAAEAECCACACAAAAAAAAAAAgEAAAAABAQAggCAAE=
+ Series\BarSeries\RectangleBarSeries.cs
+
+
+
+
+
+ DYQAAAsBGCUACEAAAQAgAAABAKgEAoAAABAUEgICAAE=
+ Series\BarSeries\TornadoBarSeries.cs
+
+
+
+
+
+ AAAAABAAAQAAAAAAAQIAACAAAAAAAAiAABAAAQAAAAA=
+ Axes\ColorAxis.cs
+
+
+
+
+
+ AAAAAAAAEAAACEAAAAAAAAAAAAAAAgAAAAAAAAAAAAA=
+ Series\BarSeries\BarSeriesBase{T}.cs
+
+
+
+
+
+ AAAAAAgAAAAAAAAAAAAAAAAAAIAAAgAAAAAAEAAAAAA=
+ Series\BarSeries\CategorizedSeries.cs
+
+
+
+
+
+ AAAIAAAAAEAAAAAAAAAAAAAAAAAEABAAAAAAAAAAAAA=
+ Series\BarSeries\ErrorColumnSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAQAAA=
+ Series\ITrackableSeries.cs
+
+
+
+
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/ClassDiagrams/Reporting.cd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/ClassDiagrams/Reporting.cd Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ AAQAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAABgQAA=
+ Reporting\Report\TableOfContents.cs
+
+
+
+
+
+ AAAAAAAAAgAAAAAAAAAAAEAAAAgAAAAAAAAAAAAAAAA=
+ Reporting\Report\DrawingFigure.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAAAAgAAAAAAAAAAAEAAAAAAAAAACAAAAAAAAAA=
+ Reporting\Report\Equation.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAEgAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Reporting\Report\Figure.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAEAAAAAEAAAAAAAAABAgAACAAAAAA=
+ Reporting\Report\Header.cs
+
+
+
+
+
+ AAAAAAAAAgAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA=
+ Reporting\Report\Image.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAACAAAAAA=
+ Reporting\Report\Paragraph.cs
+
+
+
+
+
+ AAAAAAAABAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAQAA=
+ Reporting\Report\PlotFigure.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Reporting\Report\PropertyTable.cs
+
+
+
+
+
+ AAAAAAAAAAAAAEAAgAAAAEAAAAAAAAAAAAAAAAEAAAA=
+ Reporting\Report\Report.cs
+
+
+
+
+
+ AAcGAAAAAACCAAAAAAAEAEAAAAAAAAAAAAAAAAELCAA=
+ Reporting\Report\ReportItem.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Reporting\Report\ReportSection.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ AAQAAAAgAAAAAEAgAAAAAEBAAAAAAAEACAAAAAgAAAA=
+ Reporting\Report\Table.cs
+
+
+
+
+
+ ACAAgAAAAAAgAIQAAAAQAAAAAAoUAABAIEIkAAigAAA=
+ Reporting\ReportWriters\HtmlReportWriter.cs
+
+
+
+
+
+
+ ACABgAAAACAsAAQABAAAAAQAAAAAIAAAAEAkAAAiAAA=
+ Reporting\ReportWriters\LatexReportWriter.cs
+
+
+
+
+
+
+ ICAAgABAAAAgAAQIAAAACIAEAAAAAAAAAEAkAAAgAAA=
+ Reporting\ReportWriters\TextReportWriter.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAAAgAAIAAACAAAACgIAEAAAAAAAAAAAAAAAAhAgAA=
+ Reporting\Report\ItemsTable.cs
+
+
+
+
+
+ ICAAkABAAAAgAAQIAAAACIAEAAAAAACEAEAkAAAgAAA=
+ Reporting\ReportWriters\WikiReportWriter.cs
+
+
+
+
+
+
+ ACAAgAAAAAAgAAQAAAAAAAAAAAAAAAAAAEAkAAAgAAA=
+ Reporting\ReportWriters\IReportWriter.cs
+
+
+
+
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/ClassDiagrams/Series.cd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/ClassDiagrams/Series.cd Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,161 @@
+
+
+
+
+
+ AAQCAAEIAiAAAGCAABBAAAAhRCAMEAAAADAAggAKIgA=
+ Series\LineSeries.cs
+
+
+
+
+
+ IAAAAAyAEAABgAAAACACAAAABAAEAAAAAAAAAgAAAAA=
+ Series\DataPointSeries.cs
+
+
+
+
+
+ AgAAAAEAEAAAAIAAAAAACAAAAAAECAAAABMAAgIAAAA=
+ Series\AreaSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Series\FunctionSeries.cs
+
+
+
+
+
+ CAAAAAgAIAQAAAAAAAAAAAAAAIAAAABAAAAAEAAAAAA=
+ Series\BarSeries\BarSeries.cs
+
+
+
+
+
+ sAAQAAE1WAAAAAAAAEAAQAQAAAAEAAAAABAUACACEAA=
+ Series\XYAxisSeries.cs
+
+
+
+
+
+ AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAABAA=
+ Series\CandleStickSeries.cs
+
+
+
+
+
+ AAAAAAkBECABCAAAABgAAAQABAQEAAABAHAAggAKAAA=
+ Series\HighLowSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAIIAAAA=
+ Series\ItemsSeries.cs
+
+
+
+
+
+ AQAQAAEAWGAYACAIAAAAAAAgAAgEICJAgpQFAoCCAAI=
+ Series\PieSeries.cs
+
+
+
+
+
+ AARQAAEIEAAAAEgQAAAIAAAgACBEQAIEABAwAgQDAgA=
+ Series\ScatterSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAAAA=
+ Series\StairStepSeries.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAQAA=
+ Series\StemSeries.cs
+
+
+
+
+
+ AAAQAAEAWABAEEAAAAAAAAAAAAAEAAAAABAkBgISAAA=
+ Series\Series.cs
+
+
+
+
+
+
+ BYQAgIEAKCSAACCQAAAAAAABAAgEIBBAAhAUEgoCAAE=
+ Series\BarSeries\BarSeriesBase.cs
+
+
+
+
+
+
+ AAAAAAgAIAQAAAAAAEAAAAAAAIAAAABAAAAAEAAAAAA=
+ Series\BarSeries\ColumnSeries.cs
+
+
+
+
+
+ DQQAgAkBGCSACECAAAAAAAABAIgEIgAAABAUEgoCAAE=
+ Series\BarSeries\IntervalBarSeries.cs
+
+
+
+
+
+
+ AAAAgAEAECCACACAAAAAAAAAAAgEAAAAABAQEggCAAE=
+ Series\BarSeries\RectangleBarSeries.cs
+
+
+
+
+
+ DYQAAAsBGCUICEAABQAgAAAFAKgEAoAAABA0EgICAAE=
+ Series\BarSeries\TornadoBarSeries.cs
+
+
+
+
+
+ AAAAAAAAEAAACEAAAAAAAAAAAAAAAgAAAAAAAAAAAAA=
+ Series\BarSeries\BarSeriesBase{T}.cs
+
+
+
+
+
+ AAAAAAgAAAAAAAAAAAAAAAAAAIAAAgAAAAAAEAAAAAA=
+ Series\BarSeries\CategorizedSeries.cs
+
+
+
+
+
+ AAAIAAAAAEAAAAAAAAAAAAAAAAAEABAAAAAAAAAAAAA=
+ Series\BarSeries\ErrorColumnSeries.cs
+
+
+
+
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ArrayHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ArrayHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,124 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Array helper methods.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides utility methods for vector generation.
+ ///
+ public static class ArrayHelper
+ {
+ ///
+ /// Creates a vector.
+ ///
+ ///
+ /// The first value.
+ ///
+ ///
+ /// The last value.
+ ///
+ ///
+ /// The number of steps.
+ ///
+ ///
+ /// A vector.
+ ///
+ public static double[] CreateVector(double x0, double x1, int n)
+ {
+ var result = new double[n];
+ for (int i = 0; i < n; i++)
+ {
+ result[i] = (x0 + ((x1 - x0) * i / (n - 1))).RemoveNoise();
+ }
+
+ return result;
+ }
+
+ ///
+ /// Creates a vector.
+ ///
+ ///
+ /// The first value.
+ ///
+ ///
+ /// The last value.
+ ///
+ ///
+ /// The step size.
+ ///
+ ///
+ /// A vector.
+ ///
+ public static double[] CreateVector(double x0, double x1, double dx)
+ {
+ var n = (int)Math.Round((x1 - x0) / dx);
+ var result = new double[n + 1];
+ for (int i = 0; i <= n; i++)
+ {
+ result[i] = (x0 + (i * dx)).RemoveNoise();
+ }
+
+ return result;
+ }
+
+ ///
+ /// Evaluates the specified function.
+ ///
+ ///
+ /// The function.
+ ///
+ ///
+ /// The x values.
+ ///
+ ///
+ /// The y values.
+ ///
+ ///
+ /// Array of evaluations. The value of f(x_i,y_j) will be placed at index [i, j].
+ ///
+ public static double[,] Evaluate(Func f, double[] x, double[] y)
+ {
+ int m = x.Length;
+ int n = y.Length;
+ var result = new double[m, n];
+ for (int i = 0; i < m; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ result[i, j] = f(x[i], y[j]);
+ }
+ }
+
+ return result;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CanonicalSplineHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CanonicalSplineHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,252 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Interpolates a list of points using a canonical spline.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Provides functionality to interpolate a list of points by a canonical spline.
+ ///
+ internal static class CanonicalSplineHelper
+ {
+ // CanonicalSplineHelper.cs (c) 2009 by Charles Petzold (WPF and Silverlight)
+ // www.charlespetzold.com/blog/2009/01/Canonical-Splines-in-WPF-and-Silverlight.html
+ ///
+ /// Creates a spline of data points.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The tension.
+ ///
+ ///
+ /// The tensions.
+ ///
+ ///
+ /// True if the spline is closed.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A list of data points.
+ ///
+ internal static List CreateSpline(
+ IList points, double tension, IList tensions, bool isClosed, double tolerance)
+ {
+ var screenPoints = points.Select(p => new ScreenPoint(p.X, p.Y)).ToList();
+ var interpolatedScreenPoints = CreateSpline(screenPoints, tension, tensions, isClosed, tolerance);
+ var interpolatedDataPoints = new List(interpolatedScreenPoints.Count);
+
+ foreach (var s in interpolatedScreenPoints)
+ {
+ interpolatedDataPoints.Add(new DataPoint(s.X, s.Y));
+ }
+
+ return interpolatedDataPoints;
+ }
+
+ ///
+ /// Creates a spline of screen points.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The tension.
+ ///
+ ///
+ /// The tensions.
+ ///
+ ///
+ /// True if the spline is closed.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// A list of screen points.
+ ///
+ internal static List CreateSpline(
+ IList points, double tension, IList tensions, bool isClosed, double tolerance)
+ {
+ var result = new List();
+ if (points == null)
+ {
+ return result;
+ }
+
+ int n = points.Count;
+ if (n < 1)
+ {
+ return result;
+ }
+
+ if (n < 2)
+ {
+ result.AddRange(points);
+ return result;
+ }
+
+ if (n == 2)
+ {
+ if (!isClosed)
+ {
+ Segment(result, points[0], points[0], points[1], points[1], tension, tension, tolerance);
+ }
+ else
+ {
+ Segment(result, points[1], points[0], points[1], points[0], tension, tension, tolerance);
+ Segment(result, points[0], points[1], points[0], points[1], tension, tension, tolerance);
+ }
+ }
+ else
+ {
+ bool useTensionCollection = tensions != null && tensions.Count > 0;
+
+ for (int i = 0; i < n; i++)
+ {
+ double t1 = useTensionCollection ? tensions[i % tensions.Count] : tension;
+ double t2 = useTensionCollection ? tensions[(i + 1) % tensions.Count] : tension;
+
+ if (i == 0)
+ {
+ Segment(
+ result,
+ isClosed ? points[n - 1] : points[0],
+ points[0],
+ points[1],
+ points[2],
+ t1,
+ t2,
+ tolerance);
+ }
+ else if (i == n - 2)
+ {
+ Segment(
+ result,
+ points[i - 1],
+ points[i],
+ points[i + 1],
+ isClosed ? points[0] : points[i + 1],
+ t1,
+ t2,
+ tolerance);
+ }
+ else if (i == n - 1)
+ {
+ if (isClosed)
+ {
+ Segment(result, points[i - 1], points[i], points[0], points[1], t1, t2, tolerance);
+ }
+ }
+ else
+ {
+ Segment(result, points[i - 1], points[i], points[i + 1], points[i + 2], t1, t2, tolerance);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// The segment.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The pt 0.
+ ///
+ ///
+ /// The pt 1.
+ ///
+ ///
+ /// The pt 2.
+ ///
+ ///
+ /// The pt 3.
+ ///
+ ///
+ /// The t 1.
+ ///
+ ///
+ /// The t 2.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ private static void Segment(
+ IList points,
+ ScreenPoint pt0,
+ ScreenPoint pt1,
+ ScreenPoint pt2,
+ ScreenPoint pt3,
+ double t1,
+ double t2,
+ double tolerance)
+ {
+ // See Petzold, "Programming Microsoft Windows with C#", pages 645-646 or
+ // Petzold, "Programming Microsoft Windows with Microsoft Visual Basic .NET", pages 638-639
+ // for derivation of the following formulas:
+ double sx1 = t1 * (pt2.X - pt0.X);
+ double sy1 = t1 * (pt2.Y - pt0.Y);
+ double sx2 = t2 * (pt3.X - pt1.X);
+ double sy2 = t2 * (pt3.Y - pt1.Y);
+
+ double ax = sx1 + sx2 + 2 * pt1.X - 2 * pt2.X;
+ double ay = sy1 + sy2 + 2 * pt1.Y - 2 * pt2.Y;
+ double bx = -2 * sx1 - sx2 - 3 * pt1.X + 3 * pt2.X;
+ double by = -2 * sy1 - sy2 - 3 * pt1.Y + 3 * pt2.Y;
+
+ double cx = sx1;
+ double cy = sy1;
+ double dx = pt1.X;
+ double dy = pt1.Y;
+
+ var num = (int)((Math.Abs(pt1.X - pt2.X) + Math.Abs(pt1.Y - pt2.Y)) / tolerance);
+
+ // Notice begins at 1 so excludes the first point (which is just pt1)
+ for (int i = 1; i < num; i++)
+ {
+ double t = (double)i / (num - 1);
+ var pt = new ScreenPoint(
+ ax * t * t * t + bx * t * t + cx * t + dx,
+ ay * t * t * t + by * t * t + cy * t + dy);
+ points.Add(pt);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerationAttribute.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerationAttribute.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,57 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Attribute that controls if code should be generated for the property.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Specifies whether code should be generated for the property.
+ ///
+ [AttributeUsage(AttributeTargets.Property)]
+ public class CodeGenerationAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The generate code.
+ ///
+ public CodeGenerationAttribute(bool generateCode)
+ {
+ this.GenerateCode = generateCode;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether GenerateCode.
+ ///
+ public bool GenerateCode { get; set; }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,448 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Generates c# code for the specified PlotModel.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Reflection;
+ using System.Text;
+ using System.Text.RegularExpressions;
+
+ ///
+ /// Provides functionality to generate C# code for the specified .
+ ///
+ ///
+ /// This is useful for creating examples or unit tests. Press Ctrl+Alt+C in a plot to copy code to the clipboard.
+ /// Usage:
+ /// var cg = new CodeGenerator(myPlotModel);
+ /// Clipboard.SetText(cg.ToCode());
+ ///
+ public class CodeGenerator
+ {
+ ///
+ /// The sb.
+ ///
+ private readonly StringBuilder sb;
+
+ ///
+ /// The variables.
+ ///
+ private readonly Dictionary variables;
+
+ ///
+ /// The indent string.
+ ///
+ private string indentString;
+
+ ///
+ /// The indents.
+ ///
+ private int indents;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The model.
+ ///
+ public CodeGenerator(PlotModel model)
+ {
+ this.variables = new Dictionary();
+ this.sb = new StringBuilder();
+ this.Indents = 8;
+ var title = model.Title ?? "Untitled";
+ this.AppendLine("[Example({0})]", title.ToCode());
+ string methodName = this.MakeValidVariableName(title);
+ this.AppendLine("public static PlotModel {0}()", methodName);
+ this.AppendLine("{");
+ this.Indents += 4;
+ string modelName = this.Add(model);
+ this.AddChildren(modelName, "Axes", model.Axes);
+ this.AddChildren(modelName, "Series", model.Series);
+ this.AddChildren(modelName, "Annotations", model.Annotations);
+ this.AppendLine("return {0};", modelName);
+ this.Indents -= 4;
+ this.AppendLine("}");
+ }
+
+ ///
+ /// Gets or sets Indents.
+ ///
+ private int Indents
+ {
+ get
+ {
+ return this.indents;
+ }
+
+ set
+ {
+ this.indents = value;
+ this.indentString = new string(' ', value);
+ }
+ }
+
+ ///
+ /// Formats the code.
+ ///
+ ///
+ /// The format.
+ ///
+ ///
+ /// The values.
+ ///
+ ///
+ /// The format code.
+ ///
+ public static string FormatCode(string format, params object[] values)
+ {
+ var encodedValues = new object[values.Length];
+ for (int i = 0; i < values.Length; i++)
+ {
+ encodedValues[i] = values[i].ToCode();
+ }
+
+ return string.Format(format, encodedValues);
+ }
+
+ ///
+ /// Formats a constructor.
+ ///
+ ///
+ /// The type.
+ ///
+ ///
+ /// The format of the constructor arguments.
+ ///
+ ///
+ /// The argument values.
+ ///
+ ///
+ /// The format constructor.
+ ///
+ public static string FormatConstructor(Type type, string format, params object[] values)
+ {
+ return string.Format("new {0}({1})", type.Name, FormatCode(format, values));
+ }
+
+ ///
+ /// Returns the c# code for this model.
+ ///
+ ///
+ /// C# code.
+ ///
+ public string ToCode()
+ {
+ return this.sb.ToString();
+ }
+
+ ///
+ /// Adds the specified object to the generated code.
+ ///
+ ///
+ /// The object.
+ ///
+ ///
+ /// The variable name.
+ ///
+ private string Add(object obj)
+ {
+ Type type = obj.GetType();
+ object defaultInstance = Activator.CreateInstance(type);
+ string varName = this.GetNewVariableName(type);
+ this.variables.Add(varName, true);
+ this.AppendLine("var {0} = new {1}();", varName, type.Name);
+ this.SetProperties(obj, varName, defaultInstance);
+ return varName;
+ }
+
+ ///
+ /// Adds the children.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// Name of the collection.
+ ///
+ ///
+ /// The children.
+ ///
+ private void AddChildren(string name, string collectionName, IEnumerable children)
+ {
+ foreach (var child in children)
+ {
+ string childName = this.Add(child);
+ this.AppendLine("{0}.{1}.Add({2});", name, collectionName, childName);
+ }
+ }
+
+ ///
+ /// Adds the items.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// The list.
+ ///
+ private void AddItems(string name, IList list)
+ {
+ foreach (var item in list)
+ {
+ var code = item.ToCode();
+ if (code == null)
+ {
+ continue;
+ }
+
+ this.AppendLine("{0}.Add({1});", name, code);
+ }
+ }
+
+ ///
+ /// Appends the line.
+ ///
+ ///
+ /// The format string.
+ ///
+ ///
+ /// The args.
+ ///
+ private void AppendLine(string format, params object[] args)
+ {
+ if (args.Length > 0)
+ {
+ this.sb.AppendLine(this.indentString + string.Format(CultureInfo.InvariantCulture, format, args));
+ }
+ else
+ {
+ this.sb.AppendLine(this.indentString + format);
+ }
+ }
+
+ ///
+ /// Determines if the two specifed lists are equal.
+ ///
+ ///
+ /// The first list.
+ ///
+ ///
+ /// The second list.
+ ///
+ ///
+ /// True if all items are equal.
+ ///
+ private bool AreListsEqual(IList list1, IList list2)
+ {
+ if (list1 == null || list2 == null)
+ {
+ return false;
+ }
+
+ if (list1.Count != list2.Count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < list1.Count; i++)
+ {
+ if (!list1[i].Equals(list2[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// Get the first attribute of the specified type.
+ ///
+ ///
+ /// The property info.
+ ///
+ ///
+ /// The type.
+ ///
+ ///
+ /// The attribute, or null if no attribute was found.
+ ///
+ private T GetFirstAttribute(PropertyInfo pi) where T : Attribute
+ {
+ foreach (T a in pi.GetCustomAttributes(typeof(CodeGenerationAttribute), true))
+ {
+ return a;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets a new variable name of the specified type.
+ ///
+ ///
+ /// The type.
+ ///
+ ///
+ /// The variable name.
+ ///
+ private string GetNewVariableName(Type type)
+ {
+ string prefix = type.Name;
+ prefix = char.ToLower(prefix[0]) + prefix.Substring(1);
+ int i = 1;
+ while (this.variables.ContainsKey(prefix + i))
+ {
+ i++;
+ }
+
+ return prefix + i;
+ }
+
+ ///
+ /// Makes a valid variable name of a string. Invalid characters will simply be removed.
+ ///
+ ///
+ /// The title.
+ ///
+ ///
+ /// A valid variable name.
+ ///
+ private string MakeValidVariableName(string title)
+ {
+ if (title == null)
+ {
+ return null;
+ }
+
+ var regex = new Regex("[a-zA-Z_][a-zA-Z0-9_]*");
+ var result = new StringBuilder();
+ foreach (var c in title)
+ {
+ string s = c.ToString();
+ if (regex.Match(s).Success)
+ {
+ result.Append(s);
+ }
+ }
+
+ return result.ToString();
+ }
+
+ ///
+ /// The set properties.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// The var name.
+ ///
+ ///
+ /// The default values.
+ ///
+ private void SetProperties(object instance, string varName, object defaultValues)
+ {
+ var instanceType = instance.GetType();
+ var listsToAdd = new Dictionary();
+ foreach (var pi in instanceType.GetProperties())
+ {
+ // check the [CodeGeneration] attribute
+ var cga = this.GetFirstAttribute(pi);
+ if (cga != null && !cga.GenerateCode)
+ {
+ continue;
+ }
+
+ string name = varName + "." + pi.Name;
+ object value = pi.GetValue(instance, null);
+ object defaultValue = pi.GetValue(defaultValues, null);
+
+ // check if lists are equal
+ if (this.AreListsEqual(value as IList, defaultValue as IList))
+ {
+ continue;
+ }
+
+ // add items of lists
+ var list = value as IList;
+ if (list != null)
+ {
+ listsToAdd.Add(name, list);
+ continue;
+ }
+
+ // only properties with public setters are used
+ var setter = pi.GetSetMethod();
+ if (setter == null || !setter.IsPublic)
+ {
+ continue;
+ }
+
+ // skip default values
+ if ((value != null && value.Equals(defaultValue)) || value == defaultValue)
+ {
+ continue;
+ }
+
+ this.SetProperty(name, value);
+ }
+
+ // Add the items of the lists
+ foreach (var kvp in listsToAdd)
+ {
+ var name = kvp.Key;
+ var list = kvp.Value;
+ this.AddItems(name, list);
+ }
+ }
+
+ ///
+ /// Sets the property.
+ ///
+ ///
+ /// The property name.
+ ///
+ ///
+ /// The value.
+ ///
+ private void SetProperty(string name, object value)
+ {
+ string code = value.ToCode();
+ if (code != null)
+ {
+ this.AppendLine("{0} = {1};", name, code);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGeneratorStringExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGeneratorStringExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,188 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The code generator string extensions.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Globalization;
+
+ ///
+ /// Provides extension methods for code generation.
+ ///
+ public static class CodeGeneratorStringExtensions
+ {
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this string value)
+ {
+ value = value.Replace("\"", "\\\"");
+ value = value.Replace("\r\n", "\\n");
+ value = value.Replace("\n", "\\n");
+ value = value.Replace("\t", "\\t");
+ return "\"" + value + "\"";
+ }
+
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this bool value)
+ {
+ return value.ToString().ToLower();
+ }
+
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this int value)
+ {
+ return value.ToString(CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this Enum value)
+ {
+ return string.Format("{0}.{1}", value.GetType().Name, value);
+ }
+
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this double value)
+ {
+ if (double.IsNaN(value))
+ {
+ return "double.NaN";
+ }
+
+ if (double.IsPositiveInfinity(value))
+ {
+ return "double.PositiveInfinity";
+ }
+
+ if (double.IsNegativeInfinity(value))
+ {
+ return "double.NegativeInfinity";
+ }
+
+ if (value.Equals(double.MinValue))
+ {
+ return "double.MinValue";
+ }
+
+ if (value.Equals(double.MaxValue))
+ {
+ return "double.MaxValue";
+ }
+
+ return value.ToString(CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Converts the value of this instance to c# code.
+ ///
+ ///
+ /// The instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ public static string ToCode(this object value)
+ {
+ if (value == null)
+ {
+ return "null";
+ }
+
+ if (value is int)
+ {
+ return ((int)value).ToCode();
+ }
+
+ if (value is double)
+ {
+ return ((double)value).ToCode();
+ }
+
+ if (value is string)
+ {
+ return ((string)value).ToCode();
+ }
+
+ if (value is bool)
+ {
+ return ((bool)value).ToCode();
+ }
+
+ if (value is Enum)
+ {
+ return ((Enum)value).ToCode();
+ }
+
+ if (value is ICodeGenerating)
+ {
+ return ((ICodeGenerating)value).ToCode();
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CodeGenerator/ICodeGenerating.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/ICodeGenerating.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,45 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides functionality to generate c# code of an object.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides functionality to generate C# code of an object.
+ ///
+ public interface ICodeGenerating
+ {
+ ///
+ /// Returns c# code that generates this instance.
+ ///
+ ///
+ /// C# code.
+ ///
+ string ToCode();
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/CohenSutherlandClipping.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/CohenSutherlandClipping.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,298 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Line clipping algorithm.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a line clipping algorithm.
+ ///
+ ///
+ /// See http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland
+ ///
+ public class CohenSutherlandClipping
+ {
+ ///
+ /// The bottom code.
+ ///
+ private const int Bottom = 4; // 0100
+
+ ///
+ /// The inside code.
+ ///
+ private const int Inside = 0; // 0000
+
+ ///
+ /// The left code.
+ ///
+ private const int Left = 1; // 0001
+
+ ///
+ /// The right code.
+ ///
+ private const int Right = 2; // 0010
+
+ ///
+ /// The top code.
+ ///
+ private const int Top = 8; // 1000
+
+ ///
+ /// The x maximum.
+ ///
+ private readonly double xmax;
+
+ ///
+ /// The x minimum.
+ ///
+ private readonly double xmin;
+
+ ///
+ /// The y maximum.
+ ///
+ private readonly double ymax;
+
+ ///
+ /// The y minimum.
+ ///
+ private readonly double ymin;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ public CohenSutherlandClipping(OxyRect rect)
+ {
+ this.xmin = rect.Left;
+ this.xmax = rect.Right;
+ this.ymin = rect.Top;
+ this.ymax = rect.Bottom;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The xmin.
+ ///
+ ///
+ /// The xmax.
+ ///
+ ///
+ /// The ymin.
+ ///
+ ///
+ /// The ymax.
+ ///
+ public CohenSutherlandClipping(double xmin, double xmax, double ymin, double ymax)
+ {
+ this.xmin = xmin;
+ this.ymin = ymin;
+ this.xmax = xmax;
+ this.ymax = ymax;
+ }
+
+ ///
+ /// Cohen–Sutherland clipping algorithm clips a line from
+ /// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
+ /// diagonal from (xmin, ymin) to (xmax, ymax).
+ ///
+ /// X coordinate of the first point.
+ /// Y coordinate of the first point.
+ /// X coordinate of the second point.
+ /// Y coordinate of the second point.
+ ///
+ /// true if the line is inside.
+ ///
+ public bool ClipLine(ref double x0, ref double y0, ref double x1, ref double y1)
+ {
+ // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
+ int outcode0 = this.ComputeOutCode(x0, y0);
+ int outcode1 = this.ComputeOutCode(x1, y1);
+ bool accept = false;
+
+ while (true)
+ {
+ if ((outcode0 | outcode1) == 0)
+ {
+ // logical or is 0. Trivially accept and get out of loop
+ accept = true;
+ break;
+ }
+
+ if ((outcode0 & outcode1) != 0)
+ {
+ // logical and is not 0. Trivially reject and get out of loop
+ break;
+ }
+
+ // failed both tests, so calculate the line segment to clip
+ // from an outside point to an intersection with clip edge
+ double x = 0, y = 0;
+
+ // At least one endpoint is outside the clip rectangle; pick it.
+ int outcodeOut = outcode0 != 0 ? outcode0 : outcode1;
+
+ // Now find the intersection point;
+ // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
+ if ((outcodeOut & Top) != 0)
+ {
+ // point is above the clip rectangle
+ x = x0 + ((x1 - x0) * (this.ymax - y0) / (y1 - y0));
+ y = this.ymax;
+ }
+ else if ((outcodeOut & Bottom) != 0)
+ {
+ // point is below the clip rectangle
+ x = x0 + ((x1 - x0) * (this.ymin - y0) / (y1 - y0));
+ y = this.ymin;
+ }
+ else if ((outcodeOut & Right) != 0)
+ {
+ // point is to the right of clip rectangle
+ y = y0 + ((y1 - y0) * (this.xmax - x0) / (x1 - x0));
+ x = this.xmax;
+ }
+ else if ((outcodeOut & Left) != 0)
+ {
+ // point is to the left of clip rectangle
+ y = y0 + ((y1 - y0) * (this.xmin - x0) / (x1 - x0));
+ x = this.xmin;
+ }
+
+ // Now we move outside point to intersection point to clip
+ // and get ready for next pass.
+ if (outcodeOut == outcode0)
+ {
+ x0 = x;
+ y0 = y;
+ outcode0 = this.ComputeOutCode(x0, y0);
+ }
+ else
+ {
+ x1 = x;
+ y1 = y;
+ outcode1 = this.ComputeOutCode(x1, y1);
+ }
+ }
+
+ return accept;
+ }
+
+ ///
+ /// Cohen–Sutherland clipping algorithm clips a line from
+ /// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
+ /// diagonal from (xmin, ymin) to (xmax, ymax).
+ ///
+ ///
+ /// The s 0.
+ ///
+ ///
+ /// The s 1.
+ ///
+ ///
+ /// true if the line is inside
+ ///
+ public bool ClipLine(ref ScreenPoint s0, ref ScreenPoint s1)
+ {
+ return this.ClipLine(ref s0.x, ref s0.y, ref s1.x, ref s1.y);
+ }
+
+ ///
+ /// Determines whether the specified point is inside the rectangle.
+ ///
+ /// The x coordinate.
+ /// The y coordinate.
+ ///
+ /// true if the specified point is inside; otherwise, false.
+ ///
+ public bool IsInside(double x, double y)
+ {
+ return this.ComputeOutCode(x, y) == Inside;
+ }
+
+ ///
+ /// Determines whether the specified point is inside the rectangle.
+ ///
+ /// The point.
+ ///
+ /// true if the specified point is inside; otherwise, false.
+ ///
+ public bool IsInside(ScreenPoint s)
+ {
+ return this.ComputeOutCode(s.X, s.Y) == Inside;
+ }
+
+ ///
+ /// Computes the out code.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The y.
+ ///
+ ///
+ /// The out code.
+ ///
+ ///
+ /// Compute the bit code for a point (x, y) using the clip rectangle
+ /// bounded diagonally by (xmin, ymin), and (xmax, ymax)
+ ///
+ private int ComputeOutCode(double x, double y)
+ {
+ int code = Inside; // initialized as being inside of clip window
+
+ if (x < this.xmin)
+ {
+ // to the left of clip window
+ code |= Left;
+ }
+ else if (x > this.xmax)
+ {
+ // to the right of clip window
+ code |= Right;
+ }
+
+ if (y < this.ymin)
+ {
+ // below the clip window
+ code |= Bottom;
+ }
+ else if (y > this.ymax)
+ {
+ // above the clip window
+ code |= Top;
+ }
+
+ return code;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Color.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Color.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,55 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public class Color
+ {
+ public byte A { get; set; }
+ public byte R { get; set; }
+ public byte G { get; set; }
+ public byte B { get; set; }
+
+ public static Color FromARGB(byte a, byte r, byte g, byte b)
+ {
+ return new Color { A = a, R = r, G = g, B = b };
+ }
+
+ public static Color FromRGB(byte r, byte g, byte b)
+ {
+ return new Color { A = 255, R = r, G = g, B = b };
+ }
+
+ public static Color FromAColor(byte a, Color color)
+ {
+ return new Color { A = a, R = color.R, G = color.G, B = color.B };
+ }
+ public override string ToString()
+ {
+ return string.Format("#{0:x2}{1:x2}{2:x2}{3:x2}", A, R, G, B);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Colors.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Colors.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,45 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public static class Colors
+ {
+ public static readonly Color Transparent = Color.FromARGB(0, 0, 0, 0);
+ public static readonly Color Black = Color.FromRGB(0, 0, 0);
+ public static readonly Color White = Color.FromRGB(0xFF, 0xFF, 0xFF);
+ public static readonly Color DarkGray = Color.FromRGB(0xA9, 0xA9, 0xA9);
+ public static readonly Color Gray = Color.FromRGB(0x80, 0x80, 0x80);
+ public static readonly Color LightGray = Color.FromRGB(0xD3, 0xD3, 0xD3);
+ public static readonly Color Red = Color.FromRGB(0xFF, 0, 0);
+ public static readonly Color Green = Color.FromRGB(0, 0xFF, 0);
+ public static readonly Color Blue = Color.FromRGB(0, 0, 0xFF);
+ public static readonly Color Orange = Color.FromRGB(0xFF, 0xA5, 0x00);
+ public static readonly Color Indigo = Color.FromRGB(0x4B, 0x00, 0x82);
+ public static readonly Color Violet = Color.FromRGB(0xEE, 0x82, 0xEE);
+ public static readonly Color Yellow = Color.FromRGB(0xFF, 0xFF, 0x00);
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Conrec.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Conrec.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,294 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Creates contours from a triangular mesh.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides functionality to create contours from a triangular mesh.
+ ///
+ ///
+ ///
+ /// Ported from C / Fortran code by Paul Bourke.
+ /// See Conrec for
+ /// full description of code and the original source.
+ ///
+ ///
+ /// Contouring aids in visualizing three dimensional surfaces on a two dimensional
+ /// medium (on paper or in this case a computer graphics screen). Two most common
+ /// applications are displaying topological features of an area on a map or the air
+ /// pressure on a weather map. In all cases some parameter is plotted as a function
+ /// of two variables, the longitude and latitude or x and y axis. One problem with
+ /// computer contouring is the process is usually CPU intensive and the algorithms
+ /// often use advanced mathematical techniques making them susceptible to error.
+ ///
+ ///
+ public static class Conrec
+ {
+ ///
+ /// Renderer delegate
+ ///
+ ///
+ /// Start point x-coordinate
+ ///
+ ///
+ /// Start point y-coordinate
+ ///
+ ///
+ /// End point x-coordinate
+ ///
+ ///
+ /// End point y-coordinate
+ ///
+ ///
+ /// Contour level
+ ///
+ public delegate void RendererDelegate(double x1, double y1, double x2, double y2, double z);
+
+ ///
+ /// Contour is a contouring subroutine for rectangularily spaced data
+ /// It emits calls to a line drawing subroutine supplied by the user
+ /// which draws a contour map corresponding to data on a randomly
+ /// spaced rectangular grid. The coordinates emitted are in the same
+ /// units given in the x() and y() arrays.
+ /// Any number of contour levels may be specified but they must be
+ /// in order of increasing value.
+ ///
+ ///
+ /// Matrix of data to contour.
+ ///
+ ///
+ /// Data matrix column coordinates.
+ ///
+ ///
+ /// Data matrix row coordinates.
+ ///
+ ///
+ /// Contour levels in increasing order.
+ ///
+ ///
+ /// The renderer.
+ ///
+ public static void Contour(double[,] d, double[] x, double[] y, double[] z, RendererDelegate renderer)
+ {
+ double x1 = 0.0;
+ double x2 = 0.0;
+ double y1 = 0.0;
+ double y2 = 0.0;
+
+ var h = new double[5];
+ var sh = new int[5];
+ var xh = new double[5];
+ var yh = new double[5];
+
+ int ilb = d.GetLowerBound(0);
+ int iub = d.GetUpperBound(0);
+ int jlb = d.GetLowerBound(1);
+ int jub = d.GetUpperBound(1);
+ int nc = z.Length;
+
+ // The indexing of im and jm should be noted as it has to start from zero
+ // unlike the fortran counter part
+ int[] im = { 0, 1, 1, 0 };
+ int[] jm = { 0, 0, 1, 1 };
+
+ // Note that castab is arranged differently from the FORTRAN code because
+ // Fortran and C/C++ arrays are transposed of each other, in this case
+ // it is more tricky as castab is in 3 dimension
+ int[,,] castab =
+ {
+ { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } }, { { 0, 3, 4 }, { 1, 3, 1 }, { 4, 3, 0 } },
+ { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } }
+ };
+
+ Func xsect = (p1, p2) => ((h[p2] * xh[p1]) - (h[p1] * xh[p2])) / (h[p2] - h[p1]);
+ Func ysect = (p1, p2) => ((h[p2] * yh[p1]) - (h[p1] * yh[p2])) / (h[p2] - h[p1]);
+
+ for (int j = jub - 1; j >= jlb; j--)
+ {
+ int i;
+ for (i = ilb; i <= iub - 1; i++)
+ {
+ double temp1 = Math.Min(d[i, j], d[i, j + 1]);
+ double temp2 = Math.Min(d[i + 1, j], d[i + 1, j + 1]);
+ double dmin = Math.Min(temp1, temp2);
+ temp1 = Math.Max(d[i, j], d[i, j + 1]);
+ temp2 = Math.Max(d[i + 1, j], d[i + 1, j + 1]);
+ double dmax = Math.Max(temp1, temp2);
+
+ if (dmax >= z[0] && dmin <= z[nc - 1])
+ {
+ int k;
+ for (k = 0; k < nc; k++)
+ {
+ if (z[k] >= dmin && z[k] <= dmax)
+ {
+ int m;
+ for (m = 4; m >= 0; m--)
+ {
+ if (m > 0)
+ {
+ // The indexing of im and jm should be noted as it has to
+ // start from zero
+ h[m] = d[i + im[m - 1], j + jm[m - 1]] - z[k];
+ xh[m] = x[i + im[m - 1]];
+ yh[m] = y[j + jm[m - 1]];
+ }
+ else
+ {
+ h[0] = 0.25 * (h[1] + h[2] + h[3] + h[4]);
+ xh[0] = 0.5 * (x[i] + x[i + 1]);
+ yh[0] = 0.5 * (y[j] + y[j + 1]);
+ }
+
+ if (h[m] > 0.0)
+ {
+ sh[m] = 1;
+ }
+ else if (h[m] < 0.0)
+ {
+ sh[m] = -1;
+ }
+ else
+ {
+ sh[m] = 0;
+ }
+ }
+
+ //// Note: at this stage the relative heights of the corners and the
+ //// centre are in the h array, and the corresponding coordinates are
+ //// in the xh and yh arrays. The centre of the box is indexed by 0
+ //// and the 4 corners by 1 to 4 as shown below.
+ //// Each triangle is then indexed by the parameter m, and the 3
+ //// vertices of each triangle are indexed by parameters m1,m2,and
+ //// m3.
+ //// It is assumed that the centre of the box is always vertex 2
+ //// though this isimportant only when all 3 vertices lie exactly on
+ //// the same contour level, in which case only the side of the box
+ //// is drawn.
+ //// vertex 4 +-------------------+ vertex 3
+ //// | \ / |
+ //// | \ m-3 / |
+ //// | \ / |
+ //// | \ / |
+ //// | m=2 X m=2 | the centre is vertex 0
+ //// | / \ |
+ //// | / \ |
+ //// | / m=1 \ |
+ //// | / \ |
+ //// vertex 1 +-------------------+ vertex 2
+
+ // Scan each triangle in the box
+ for (m = 1; m <= 4; m++)
+ {
+ int m1 = m;
+ int m2 = 0;
+ int m3;
+ if (m != 4)
+ {
+ m3 = m + 1;
+ }
+ else
+ {
+ m3 = 1;
+ }
+
+ int caseValue = castab[sh[m1] + 1, sh[m2] + 1, sh[m3] + 1];
+ if (caseValue != 0)
+ {
+ switch (caseValue)
+ {
+ case 1: // Line between vertices 1 and 2
+ x1 = xh[m1];
+ y1 = yh[m1];
+ x2 = xh[m2];
+ y2 = yh[m2];
+ break;
+ case 2: // Line between vertices 2 and 3
+ x1 = xh[m2];
+ y1 = yh[m2];
+ x2 = xh[m3];
+ y2 = yh[m3];
+ break;
+ case 3: // Line between vertices 3 and 1
+ x1 = xh[m3];
+ y1 = yh[m3];
+ x2 = xh[m1];
+ y2 = yh[m1];
+ break;
+ case 4: // Line between vertex 1 and side 2-3
+ x1 = xh[m1];
+ y1 = yh[m1];
+ x2 = xsect(m2, m3);
+ y2 = ysect(m2, m3);
+ break;
+ case 5: // Line between vertex 2 and side 3-1
+ x1 = xh[m2];
+ y1 = yh[m2];
+ x2 = xsect(m3, m1);
+ y2 = ysect(m3, m1);
+ break;
+ case 6: // Line between vertex 3 and side 1-2
+ x1 = xh[m3];
+ y1 = yh[m3];
+ x2 = xsect(m1, m2);
+ y2 = ysect(m1, m2);
+ break;
+ case 7: // Line between sides 1-2 and 2-3
+ x1 = xsect(m1, m2);
+ y1 = ysect(m1, m2);
+ x2 = xsect(m2, m3);
+ y2 = ysect(m2, m3);
+ break;
+ case 8: // Line between sides 2-3 and 3-1
+ x1 = xsect(m2, m3);
+ y1 = ysect(m2, m3);
+ x2 = xsect(m3, m1);
+ y2 = ysect(m3, m1);
+ break;
+ case 9: // Line between sides 3-1 and 1-2
+ x1 = xsect(m3, m1);
+ y1 = ysect(m3, m1);
+ x2 = xsect(m1, m2);
+ y2 = ysect(m1, m2);
+ break;
+ }
+
+ renderer(x1, y1, x2, y2, z[k]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/DataPoint.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/DataPoint.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,136 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// DataPoint value type.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Diagnostics.CodeAnalysis;
+
+ ///
+ /// Represents a point in the data coordinate system.
+ ///
+ ///
+ /// s are transformed to s.
+ ///
+ public struct DataPoint : IDataPoint, ICodeGenerating
+ {
+ ///
+ /// The undefined.
+ ///
+ public static readonly DataPoint Undefined = new DataPoint(double.NaN, double.NaN);
+
+ ///
+ /// The x-coordinate.
+ ///
+ [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
+ Justification = "Reviewed. Suppression is OK here.")]
+ internal double x;
+
+ ///
+ /// The y-coordinate.
+ ///
+ [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
+ Justification = "Reviewed. Suppression is OK here.")]
+ internal double y;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The y.
+ ///
+ public DataPoint(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ ///
+ /// Gets or sets the X.
+ ///
+ ///
+ /// The X.
+ ///
+ public double X
+ {
+ get
+ {
+ return this.x;
+ }
+
+ set
+ {
+ this.x = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the Y.
+ ///
+ ///
+ /// The Y.
+ ///
+ public double Y
+ {
+ get
+ {
+ return this.y;
+ }
+
+ set
+ {
+ this.y = value;
+ }
+ }
+
+ ///
+ /// Returns C# code that generates this instance.
+ ///
+ ///
+ /// The to code.
+ ///
+ public string ToCode()
+ {
+ return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.x, this.y);
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return this.x + " " + this.y;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/DataPointConverter.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/DataPointConverter.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,82 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The DataPoint converter.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.ComponentModel;
+ using System.Globalization;
+
+ ///
+ /// Converts a object from one data type to another.
+ ///
+ public class DataPointConverter : TypeConverter
+ {
+ ///
+ /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
+ ///
+ /// An that provides a format context.
+ /// A that represents the type you want to convert from.
+ ///
+ /// true if this converter can perform the conversion; otherwise, false.
+ ///
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ {
+ return true;
+ }
+
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ ///
+ /// Converts the given object to the type of this converter, using the specified context and culture information.
+ ///
+ /// An that provides a format context.
+ /// The to use as the current culture.
+ /// The to convert.
+ ///
+ /// An that represents the converted value.
+ ///
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value is string)
+ {
+ var input = (string)value;
+ var xy = input.Split(',');
+ double x = double.Parse(xy[0], CultureInfo.InvariantCulture);
+ double y = double.Parse(xy[1], CultureInfo.InvariantCulture);
+ return new DataPoint(x, y);
+ }
+
+ return base.ConvertFrom(context, culture, value);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/DoubleExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/DoubleExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,236 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Extension methods for double values.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Globalization;
+
+ ///
+ /// Provides extension methods for the type.
+ ///
+ public static class DoubleExtensions
+ {
+ ///
+ /// Squares the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// Squared value.
+ ///
+ public static double Squared(this double x)
+ {
+ return x * x;
+ }
+
+ ///
+ /// Exponent function.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The exponent.
+ ///
+ public static double GetExponent(this double x)
+ {
+ return Math.Round(Math.Log(Math.Abs(x), 10));
+ }
+
+ ///
+ /// Mantissa function.
+ /// http://en.wikipedia.org/wiki/Mantissa
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The mantissa.
+ ///
+ public static double GetMantissa(this double x)
+ {
+ return x / Math.Pow(10, x.GetExponent());
+ }
+
+ ///
+ /// Removes the floating point noise.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// A double without noise.
+ ///
+ public static double RemoveNoise2(this double value)
+ {
+ return (double)((decimal)value);
+ }
+
+ ///
+ /// Removes the floating point noise.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The maximum number of digits.
+ ///
+ ///
+ /// A double without noise.
+ ///
+ public static double RemoveNoise(this double value, int maxDigits = 8)
+ {
+ return double.Parse(value.ToString("e" + maxDigits));
+ }
+
+ ///
+ /// Removes the noise from double math.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// A double without noise.
+ ///
+ public static double RemoveNoiseFromDoubleMath(this double value)
+ {
+ if (value.IsZero() || Math.Abs(Math.Log10(Math.Abs(value))) < 27)
+ {
+ return (double)((decimal)value);
+ }
+
+ return double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Determines whether the specified value is zero.
+ ///
+ /// The value.
+ ///
+ /// true if the specified value is zero; otherwise, false.
+ ///
+ public static bool IsZero(this double value)
+ {
+ return Math.Abs(value) < double.Epsilon;
+ }
+
+ ///
+ /// Calculates the nearest larger multiple of the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The multiplier.
+ ///
+ ///
+ /// The multiple value.
+ ///
+ public static double ToUpperMultiple(this double value, double step)
+ {
+ var i = (int)Math.Ceiling(value / step);
+ return (step * i).RemoveNoise();
+ }
+
+ ///
+ /// Calculates the nearest smaller multiple of the specified value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The multiplier.
+ ///
+ ///
+ /// The multiple value.
+ ///
+ public static double ToLowerMultiple(this double value, double step)
+ {
+ var i = (int)Math.Floor(value / step);
+ return (step * i).RemoveNoise();
+ }
+
+#if THISISNOTINUSE
+
+ //
+ // Gets the mantissa and exponent.
+ //
+ ///
+ /// From
+ ///
+ /// The d.
+ /// if set to true [negative].
+ /// The mantissa.
+ /// The exponent.
+ public static void GetMantissaAndExponent(this double d, out bool negative, out long mantissa, out int exponent)
+ {
+ // Translate the double into sign, exponent and mantissa.
+ long bits = BitConverter.DoubleToInt64Bits(d);
+
+// Note that the shift is sign-extended, hence the test against -1 not 1
+ negative = (bits < 0);
+ exponent = (int)((bits >> 52) & 0x7ffL);
+ mantissa = bits & 0xfffffffffffffL;
+
+ // Subnormal numbers; exponent is effectively one higher,
+ // but there's no extra normalisation bit in the mantissa
+ if (exponent == 0)
+ {
+ exponent++;
+ }
+
+// Normal numbers; leave exponent as it is but add extra
+ // bit to the front of the mantissa
+ else
+ {
+ mantissa = mantissa | (1L << 52);
+ }
+
+ // Bias the exponent. It's actually biased by 1023, but we're
+ // treating the mantissa as m.0 rather than 0.m, so we need
+ // to subtract another 52 from it.
+ exponent -= 1075;
+
+ if (mantissa == 0)
+ {
+ return;
+ }
+
+ /* Normalize */
+ while ((mantissa & 1) == 0)
+ { /* i.e., Mantissa is even */
+ mantissa >>= 1;
+ exponent++;
+ }
+ }
+#endif
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/FontWeights.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/FontWeights.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,48 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Static font weights.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a set of static predefined font weight values.
+ ///
+ public static class FontWeights
+ {
+ ///
+ /// Specifies a bold font weight.
+ ///
+ public const double Bold = 700;
+
+ ///
+ /// Specifies a normal font weight.
+ ///
+ public const double Normal = 400;
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/FractionHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/FractionHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,155 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Generates fraction strings from double values.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Globalization;
+
+ ///
+ /// Provides functionality to generate fraction strings from double values.
+ ///
+ ///
+ /// Examples: "3/4", "PI/2"
+ ///
+ public static class FractionHelper
+ {
+ ///
+ /// Converts a double to a fraction string.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The unit.
+ ///
+ ///
+ /// The unit symbol.
+ ///
+ ///
+ /// The tolerance.
+ ///
+ ///
+ /// The format Provider.
+ ///
+ ///
+ /// The convert to fraction string.
+ ///
+ public static string ConvertToFractionString(
+ double value,
+ double unit = 1,
+ string unitSymbol = null,
+ double eps = 1e-6,
+ IFormatProvider formatProvider = null)
+ {
+ if (Math.Abs(value) < eps)
+ {
+ return "0";
+ }
+
+ // ½, ⅝, ¾
+ value /= unit;
+
+ // int whole = (int)(value - (int) value);
+ // int N = 10000;
+ // int frac = (int) ((value - whole)*N);
+ // var d = GCF(N,frac);
+ for (int d = 1; d <= 64; d++)
+ {
+ double n = value * d;
+ var ni = (int)Math.Round(n);
+ if (Math.Abs(n - ni) < eps)
+ {
+ string nis = unitSymbol == null || ni != 1 ? ni.ToString(CultureInfo.InvariantCulture) : string.Empty;
+ if (d == 1)
+ {
+ return string.Format("{0}{1}", nis, unitSymbol);
+ }
+
+ return string.Format("{0}{1}/{2}", nis, unitSymbol, d);
+ }
+ }
+
+ return string.Format(formatProvider ?? CultureInfo.CurrentCulture, "{0}{1}", value, unitSymbol);
+ }
+
+ ///
+ /// Finds the greates common divisor.
+ ///
+ ///
+ /// The a.
+ ///
+ ///
+ /// The b.
+ ///
+ ///
+ /// The gcd.
+ ///
+ public static int gcd(int a, int b)
+ {
+ if (b == 0)
+ {
+ return a;
+ }
+
+ return gcd(b, a % b);
+ }
+
+ ///
+ /// Finds the greatest common factor.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The y.
+ ///
+ ///
+ /// The gcf.
+ ///
+ private static int GCF(int x, int y)
+ {
+ x = Math.Abs(x);
+ y = Math.Abs(y);
+ int z;
+ do
+ {
+ z = x % y;
+ if (z == 0)
+ {
+ return y;
+ }
+
+ x = y;
+ y = z;
+ }
+ while (true);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/HorizontalAlignment.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/HorizontalAlignment.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,52 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Horizontal text alignment.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies the horizontal alignment.
+ ///
+ public enum HorizontalAlignment
+ {
+ ///
+ /// Aligned to the left.
+ ///
+ Left = -1,
+
+ ///
+ /// Aligned in the center.
+ ///
+ Center = 0,
+
+ ///
+ /// Aligned to the right.
+ ///
+ Right = 1
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/IDataPoint.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/IDataPoint.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,49 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// DataPoint interface.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Defines a point.
+ ///
+ public interface IDataPoint
+ {
+ ///
+ /// Gets or sets the x-coordinate.
+ ///
+ /// The x-coordinate.
+ double X { get; set; }
+
+ ///
+ /// Gets or sets the y-coordinate.
+ ///
+ /// The y-coordinate.
+ double Y { get; set; }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/IDataPointProvider.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/IDataPointProvider.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,45 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides functionality to create data points for items in an .
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides functionality to create data points.
+ ///
+ public interface IDataPointProvider
+ {
+ ///
+ /// Gets the data point.
+ ///
+ ///
+ /// The data point.
+ ///
+ DataPoint GetDataPoint();
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/LineStyle.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/LineStyle.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,97 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Enumeration of line styles.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies the style of a line.
+ ///
+ public enum LineStyle
+ {
+ ///
+ /// The solid line style.
+ ///
+ Solid,
+
+ ///
+ /// The dash line style.
+ ///
+ Dash,
+
+ ///
+ /// The dot line style.
+ ///
+ Dot,
+
+ ///
+ /// The dash dot line style.
+ ///
+ DashDot,
+
+ ///
+ /// The dash dash dot line style.
+ ///
+ DashDashDot,
+
+ ///
+ /// The dash dot dot line style.
+ ///
+ DashDotDot,
+
+ ///
+ /// The dash dash dot dot line style.
+ ///
+ DashDashDotDot,
+
+ ///
+ /// The long dash line style.
+ ///
+ LongDash,
+
+ ///
+ /// The long dash dot line style.
+ ///
+ LongDashDot,
+
+ ///
+ /// The long dash dot dot line style.
+ ///
+ LongDashDotDot,
+
+ ///
+ /// The hidden line style.
+ ///
+ None,
+
+ ///
+ /// The undefined line style.
+ ///
+ Undefined
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/LineStyleHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/LineStyleHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,76 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Converts from LineStyle to stroke dash array.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides functionality to convert from LineStyle to a stroke dash array.
+ ///
+ public static class LineStyleHelper
+ {
+ ///
+ /// Gets the stroke dash array for a given .
+ ///
+ ///
+ /// The line style.
+ ///
+ ///
+ /// A dash array.
+ ///
+ public static double[] GetDashArray(this LineStyle style)
+ {
+ switch (style)
+ {
+ case LineStyle.Solid:
+ return null;
+ case LineStyle.Dash:
+ return new double[] { 4, 1 };
+ case LineStyle.Dot:
+ return new double[] { 1, 1 };
+ case LineStyle.DashDot:
+ return new double[] { 4, 1, 1, 1 };
+ case LineStyle.DashDashDot:
+ return new double[] { 4, 1, 4, 1, 1, 1 };
+ case LineStyle.DashDotDot:
+ return new double[] { 4, 1, 1, 1, 1, 1 };
+ case LineStyle.DashDashDotDot:
+ return new double[] { 4, 1, 4, 1, 1, 1, 1, 1 };
+ case LineStyle.LongDash:
+ return new double[] { 10, 1 };
+ case LineStyle.LongDashDot:
+ return new double[] { 10, 1, 1, 1 };
+ case LineStyle.LongDashDotDot:
+ return new double[] { 10, 1, 1, 1, 1, 1 };
+ default:
+ return null;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ListFiller.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ListFiller.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,145 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Reflection;
+
+ ///
+ /// Provides functionality to fill a list by specified properties of another list.
+ ///
+ ///
+ /// This class uses reflection.
+ ///
+ ///
+ /// The target list item type.
+ ///
+ public class ListFiller
+ where T : class, new()
+ {
+ ///
+ /// The properties.
+ ///
+ private readonly Dictionary> properties;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ListFiller()
+ {
+ this.properties = new Dictionary>();
+ }
+
+ ///
+ /// Adds a setter for the specified property.
+ ///
+ ///
+ /// Name of the property.
+ ///
+ ///
+ /// The setter.
+ ///
+ public void Add(string propertyName, Action setter)
+ {
+ if (string.IsNullOrEmpty(propertyName))
+ {
+ return;
+ }
+
+ this.properties.Add(propertyName, setter);
+ }
+
+ ///
+ /// Fills the specified target list.
+ ///
+ /// The target.
+ /// The source.
+ public void FillT(IList target, IEnumerable source)
+ {
+ this.Fill((IList)target, source);
+ }
+
+ ///
+ /// Fills the specified target list.
+ ///
+ ///
+ /// The target.
+ ///
+ ///
+ /// The source list.
+ ///
+ public void Fill(IList target, IEnumerable source)
+ {
+ PropertyInfo[] pi = null;
+ Type t = null;
+ foreach (var sourceItem in source)
+ {
+ if (pi == null || sourceItem.GetType() != t)
+ {
+ t = sourceItem.GetType();
+ pi = new PropertyInfo[this.properties.Count];
+ int i = 0;
+ foreach (var p in this.properties)
+ {
+ if (string.IsNullOrEmpty(p.Key))
+ {
+ i++;
+ continue;
+ }
+
+ pi[i] = t.GetProperty(p.Key);
+ if (pi[i] == null)
+ {
+ throw new InvalidOperationException(
+ string.Format("Could not find field {0} on type {1}", p.Key, t));
+ }
+
+ i++;
+ }
+ }
+
+ var item = new T();
+
+ int j = 0;
+ foreach (var p in this.properties)
+ {
+ if (pi[j] != null)
+ {
+ var value = pi[j].GetValue(sourceItem, null);
+ p.Value(item, value);
+ }
+
+ j++;
+ }
+
+ target.Add(item);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/MarkerType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/MarkerType.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,91 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Enumeration of marker types.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies the marker type.
+ ///
+ public enum MarkerType
+ {
+ ///
+ /// Do not render markers.
+ ///
+ None,
+
+ ///
+ /// Render markers as circles.
+ ///
+ Circle,
+
+ ///
+ /// Render markers as squares.
+ ///
+ Square,
+
+ ///
+ /// Render markers as diamonds.
+ ///
+ Diamond,
+
+ ///
+ /// Render markers as triangles.
+ ///
+ Triangle,
+
+ ///
+ /// Render markers as crosses (note: this marker type requires the stroke color to be set).
+ ///
+ ///
+ /// This marker type requires the stroke color to be set.
+ ///
+ Cross,
+
+ ///
+ /// Renders markers as plus signs (note: this marker type requires the stroke color to be set).
+ ///
+ ///
+ /// This marker type requires the stroke color to be set.
+ ///
+ Plus,
+
+ ///
+ /// Renders markers as stars (note: this marker type requires the stroke color to be set).
+ ///
+ ///
+ /// This marker type requires the stroke color to be set.
+ ///
+ Star,
+
+ ///
+ /// Render markers by a custom shape (defined by outline).
+ ///
+ Custom
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyColor.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyColor.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,626 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes a color in terms of alpha, red, green, and blue channels.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.ComponentModel;
+ using System.Globalization;
+ using System.Linq;
+ using System.Reflection;
+
+ ///
+ /// Describes a color in terms of alpha, red, green, and blue channels.
+ ///
+ public class OxyColor : ICodeGenerating
+ {
+ ///
+ /// Gets or sets the alpha value.
+ ///
+ /// The alpha value.
+ public byte A { get; set; }
+
+ ///
+ /// Gets or sets the blue value.
+ ///
+ /// The blue value.
+ public byte B { get; set; }
+
+ ///
+ /// Gets or sets the green value.
+ ///
+ /// The green value.
+ public byte G { get; set; }
+
+ ///
+ /// Gets or sets the red value.
+ ///
+ /// The red value.
+ public byte R { get; set; }
+
+ ///
+ /// Parse a string.
+ ///
+ ///
+ /// The string in the format "#FFFFFF00" or "255,200,180,50".
+ ///
+ ///
+ /// The OxyColor.
+ ///
+ ///
+ /// Invalid format.
+ ///
+ public static OxyColor Parse(string value)
+ {
+ value = value.Trim();
+ if (value.StartsWith("#"))
+ {
+ value = value.Trim('#');
+ var u = uint.Parse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+ if (value.Length < 8)
+ {
+ // alpha value was not specified
+ u += 0xFF000000;
+ }
+
+ return FromUInt32(u);
+ }
+
+ var values = value.Split(',');
+ if (values.Length < 3 || values.Length > 4)
+ {
+ throw new FormatException("Invalid format.");
+ }
+
+ var i = 0;
+
+ byte alpha = 255;
+ if (values.Length > 3)
+ {
+ alpha = byte.Parse(values[i++], CultureInfo.InvariantCulture);
+ }
+
+ var red = byte.Parse(values[i++], CultureInfo.InvariantCulture);
+ var green = byte.Parse(values[i++], CultureInfo.InvariantCulture);
+ var blue = byte.Parse(values[i], CultureInfo.InvariantCulture);
+ return FromArgb(alpha, red, green, blue);
+ }
+
+ ///
+ /// Calculates the difference between two s
+ ///
+ ///
+ /// The first color.
+ ///
+ ///
+ /// The second color.
+ ///
+ ///
+ /// L2-norm in RGBA space
+ ///
+ public static double ColorDifference(OxyColor c1, OxyColor c2)
+ {
+ // http://en.wikipedia.org/wiki/OxyColor_difference
+ // http://mathworld.wolfram.com/L2-Norm.html
+ double dr = (c1.R - c2.R) / 255.0;
+ double dg = (c1.G - c2.G) / 255.0;
+ double db = (c1.B - c2.B) / 255.0;
+ double da = (c1.A - c2.A) / 255.0;
+ double e = (dr * dr) + (dg * dg) + (db * db) + (da * da);
+ return Math.Sqrt(e);
+ }
+
+ ///
+ /// Convert an to a .
+ ///
+ ///
+ /// The unsigned integer color value.
+ ///
+ ///
+ /// The .
+ ///
+ public static OxyColor FromUInt32(uint color)
+ {
+ var a = (byte)(color >> 24);
+ var r = (byte)(color >> 16);
+ var g = (byte)(color >> 8);
+ var b = (byte)(color >> 0);
+ return FromArgb(a, r, g, b);
+ }
+
+ ///
+ /// Creates a OxyColor from the specified HSV array.
+ ///
+ ///
+ /// The HSV value array.
+ ///
+ ///
+ /// A OxyColor.
+ ///
+ public static OxyColor FromHsv(double[] hsv)
+ {
+ if (hsv.Length != 3)
+ {
+ throw new InvalidOperationException("Wrong length of hsv array.");
+ }
+
+ return FromHsv(hsv[0], hsv[1], hsv[2]);
+ }
+
+ ///
+ /// Convert from HSV to
+ /// http://en.wikipedia.org/wiki/HSL_Color_space
+ ///
+ ///
+ /// The hue value [0,1]
+ ///
+ ///
+ /// The saturation value [0,1]
+ ///
+ ///
+ /// The intensity value [0,1]
+ ///
+ ///
+ /// The .
+ ///
+ public static OxyColor FromHsv(double hue, double sat, double val)
+ {
+ double g, b;
+ double r = g = b = 0;
+
+ if (sat.Equals(0))
+ {
+ // Gray scale
+ r = g = b = val;
+ }
+ else
+ {
+ if (hue.Equals(1))
+ {
+ hue = 0;
+ }
+
+ hue *= 6.0;
+ int i = (int)Math.Floor(hue);
+ double f = hue - i;
+ double aa = val * (1 - sat);
+ double bb = val * (1 - (sat * f));
+ double cc = val * (1 - (sat * (1 - f)));
+ switch (i)
+ {
+ case 0:
+ r = val;
+ g = cc;
+ b = aa;
+ break;
+ case 1:
+ r = bb;
+ g = val;
+ b = aa;
+ break;
+ case 2:
+ r = aa;
+ g = val;
+ b = cc;
+ break;
+ case 3:
+ r = aa;
+ g = bb;
+ b = val;
+ break;
+ case 4:
+ r = cc;
+ g = aa;
+ b = val;
+ break;
+ case 5:
+ r = val;
+ g = aa;
+ b = bb;
+ break;
+ }
+ }
+
+ return FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
+ }
+
+ ///
+ /// Calculate the difference in hue between two s.
+ ///
+ ///
+ /// The first color.
+ ///
+ ///
+ /// The second color.
+ ///
+ ///
+ /// The hue difference.
+ ///
+ public static double HueDifference(OxyColor c1, OxyColor c2)
+ {
+ var hsv1 = c1.ToHsv();
+ var hsv2 = c2.ToHsv();
+ double dh = hsv1[0] - hsv2[0];
+
+ // clamp to [-0.5,0.5]
+ if (dh > 0.5)
+ {
+ dh -= 1.0;
+ }
+
+ if (dh < -0.5)
+ {
+ dh += 1.0;
+ }
+
+ double e = dh * dh;
+ return Math.Sqrt(e);
+ }
+
+ ///
+ /// Creates a color defined by an alpha value and another color.
+ ///
+ ///
+ /// Alpha value.
+ ///
+ ///
+ /// The original color.
+ ///
+ ///
+ /// A color.
+ ///
+ public static OxyColor FromAColor(byte a, OxyColor color)
+ {
+ return new OxyColor { A = a, R = color.R, G = color.G, B = color.B };
+ }
+
+ ///
+ /// Creates a color from the specified ARGB values.
+ ///
+ ///
+ /// The alpha value.
+ ///
+ ///
+ /// The red value.
+ ///
+ ///
+ /// The green value.
+ ///
+ ///
+ /// The blue value.
+ ///
+ ///
+ /// A color.
+ ///
+ public static OxyColor FromArgb(byte a, byte r, byte g, byte b)
+ {
+ return new OxyColor { A = a, R = r, G = g, B = b };
+ }
+
+ ///
+ /// Creates a new structure from the specified RGB values.
+ ///
+ ///
+ /// The red value.
+ ///
+ ///
+ /// The green value.
+ ///
+ ///
+ /// The blue value.
+ ///
+ ///
+ /// A structure with the specified values and an alpha channel value of 1.
+ ///
+ public static OxyColor FromRgb(byte r, byte g, byte b)
+ {
+ // ReSharper restore InconsistentNaming
+ return new OxyColor { A = 255, R = r, G = g, B = b };
+ }
+
+ ///
+ /// Interpolates the specified colors.
+ ///
+ ///
+ /// The color1.
+ ///
+ ///
+ /// The color2.
+ ///
+ ///
+ /// The t.
+ ///
+ ///
+ /// The interpolated color
+ ///
+ public static OxyColor Interpolate(OxyColor color1, OxyColor color2, double t)
+ {
+ double a = (color1.A * (1 - t)) + (color2.A * t);
+ double r = (color1.R * (1 - t)) + (color2.R * t);
+ double g = (color1.G * (1 - t)) + (color2.G * t);
+ double b = (color1.B * (1 - t)) + (color2.B * t);
+ return FromArgb((byte)a, (byte)r, (byte)g, (byte)b);
+ }
+
+ ///
+ /// Convert OxyColor to double string.
+ ///
+ ///
+ /// A OxyColor string, e.g. "255,200,180,50".
+ ///
+ public string ToByteString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", this.A, this.R, this.G, this.B);
+ }
+
+ ///
+ /// Determines whether the specified is equal to this instance.
+ ///
+ ///
+ /// The to compare with this instance.
+ ///
+ ///
+ /// true if the specified is equal to this instance; otherwise, false .
+ ///
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ if (obj.GetType() != typeof(OxyColor))
+ {
+ return false;
+ }
+
+ return this.Equals((OxyColor)obj);
+ }
+
+ ///
+ /// Determines whether the specified is equal to this instance.
+ ///
+ ///
+ /// The to compare with this instance.
+ ///
+ ///
+ /// true if the specified is equal to this instance; otherwise, false .
+ ///
+ public bool Equals(OxyColor other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B;
+ }
+
+ ///
+ /// Gets the color name.
+ ///
+ ///
+ /// The color name.
+ ///
+ public string GetColorName()
+ {
+ var t = typeof(OxyColors);
+ var colors = t.GetFields(BindingFlags.Public | BindingFlags.Static);
+ var colorField = colors.FirstOrDefault(
+ field =>
+ {
+ var color = field.GetValue(null);
+ return this.Equals(color);
+ });
+ return colorField != null ? colorField.Name : null;
+ }
+
+ ///
+ /// Returns a hash code for this instance.
+ ///
+ ///
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int result = this.A.GetHashCode();
+ result = (result * 397) ^ this.R.GetHashCode();
+ result = (result * 397) ^ this.G.GetHashCode();
+ result = (result * 397) ^ this.B.GetHashCode();
+ return result;
+ }
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture, "#{0:x2}{1:x2}{2:x2}{3:x2}", this.A, this.R, this.G, this.B);
+ }
+
+ ///
+ /// Changes the opacity value.
+ ///
+ ///
+ /// The new alpha.
+ ///
+ ///
+ /// The new color.
+ ///
+ public OxyColor ChangeAlpha(byte newAlpha)
+ {
+ return FromArgb(newAlpha, this.R, this.G, this.B);
+ }
+
+ ///
+ /// Calculates the complementary OxyColor.
+ ///
+ ///
+ /// The complementary OxyColor.
+ ///
+ public OxyColor Complementary()
+ {
+ // http://en.wikipedia.org/wiki/Complementary_Color
+ var hsv = this.ToHsv();
+ double newHue = hsv[0] - 0.5;
+
+ // clamp to [0,1]
+ if (newHue < 0)
+ {
+ newHue += 1.0;
+ }
+
+ return FromHsv(newHue, hsv[1], hsv[2]);
+ }
+
+ ///
+ /// Converts from a to HSV values (double)
+ ///
+ ///
+ /// Array of [Hue,Saturation,Value] in the range [0,1]
+ ///
+ public double[] ToHsv()
+ {
+ byte r = this.R;
+ byte g = this.G;
+ byte b = this.B;
+
+ byte min = Math.Min(Math.Min(r, g), b);
+ byte v = Math.Max(Math.Max(r, g), b);
+ double delta = v - min;
+
+ double s = v.Equals(0) ? 0 : delta / v;
+ double h = 0;
+
+ if (s.Equals(0))
+ {
+ h = 0.0;
+ }
+ else
+ {
+ if (r == v)
+ {
+ h = (g - b) / delta;
+ }
+ else if (g == v)
+ {
+ h = 2 + ((b - r) / delta);
+ }
+ else if (b == v)
+ {
+ h = 4 + ((r - g) / delta);
+ }
+
+ h *= 60;
+ if (h < 0.0)
+ {
+ h += 360;
+ }
+ }
+
+ var hsv = new double[3];
+ hsv[0] = h / 360.0;
+ hsv[1] = s;
+ hsv[2] = v / 255.0;
+ return hsv;
+ }
+
+ ///
+ /// Changes the intensity.
+ ///
+ ///
+ /// The factor.
+ ///
+ ///
+ /// The new OxyColor.
+ ///
+ public OxyColor ChangeIntensity(double factor)
+ {
+ var hsv = this.ToHsv();
+ hsv[2] *= factor;
+ if (hsv[2] > 1.0)
+ {
+ hsv[2] = 1.0;
+ }
+
+ return FromHsv(hsv);
+ }
+
+ ///
+ /// Converts to an unsigned integer.
+ ///
+ ///
+ /// The .
+ ///
+ public uint ToUint()
+ {
+ uint u = (uint)this.A << 24;
+ u += (uint)this.R << 16;
+ u += (uint)this.G << 8;
+ u += this.B;
+ return u;
+
+ // (UInt32)((UInt32)c.A << 24 + (UInt32)c.R << 16 + (UInt32)c.G << 8 + (UInt32)c.B);
+ }
+
+ ///
+ /// Returns C# code that generates this instance.
+ ///
+ ///
+ /// The to code.
+ ///
+ public string ToCode()
+ {
+ string name = this.GetColorName();
+ if (name != null)
+ {
+ return string.Format("OxyColors.{0}", name);
+ }
+
+ return string.Format("OxyColor.FromArgb({0}, {1}, {2}, {3})", this.A, this.R, this.G, this.B);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyColorConverter.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyColorConverter.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,135 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Converts colors from one data type to another. Access this class through the TypeDescriptor.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.ComponentModel;
+ using System.Globalization;
+
+ ///
+ /// Converts between and . Access this class through the TypeDescriptor.
+ ///
+ public class OxyColorConverter : TypeConverter
+ {
+ ///
+ /// Determines whether an object can be converted from a given type to an instance of a .
+ ///
+ ///
+ /// Describes the context information of a type.
+ ///
+ ///
+ /// The type of the source that is being evaluated for conversion.
+ ///
+ ///
+ /// True if the type can be converted to a ; otherwise, false.
+ ///
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ return (sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType);
+ }
+
+ ///
+ /// Determines whether an instance of a can be converted to a different type.
+ ///
+ ///
+ /// Describes the context information of a type.
+ ///
+ ///
+ /// The desired type this is being evaluated for conversion.
+ ///
+ ///
+ /// True if this can be converted to destinationType; otherwise, false.
+ ///
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
+ {
+ return (destinationType == typeof(string)) || base.CanConvertTo(context, destinationType);
+ }
+
+ ///
+ /// Attempts to convert the specified object to a .
+ ///
+ ///
+ /// Describes the context information of a type.
+ ///
+ ///
+ /// Cultural information to respect during conversion.
+ ///
+ ///
+ /// The object being converted.
+ ///
+ ///
+ /// The created from converting value.
+ ///
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ var str = value as string;
+ if (str == null)
+ {
+ return base.ConvertFrom(context, culture, value);
+ }
+
+ return OxyColor.Parse(str);
+ }
+
+ ///
+ /// Attempts to convert a to a specified type.
+ ///
+ ///
+ /// Describes the context information of a type.
+ ///
+ ///
+ /// Describes the of the type being converted.
+ ///
+ ///
+ /// The to convert.
+ ///
+ ///
+ /// The type to convert this to.
+ ///
+ ///
+ /// The object created from converting this .
+ ///
+ public override object ConvertTo(
+ ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (destinationType == null)
+ {
+ throw new ArgumentNullException("destinationType");
+ }
+
+ if (destinationType == typeof(string))
+ {
+ return value != null ? value.ToString() : null;
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyColors.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyColors.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,743 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Implements a set of predefined colors.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Implements a set of predefined colors.
+ ///
+ public static class OxyColors
+ {
+ ///
+ /// The alice blue.
+ ///
+ public static readonly OxyColor AliceBlue = OxyColor.FromUInt32(0xFFF0F8FF);
+
+ ///
+ /// The antique white.
+ ///
+ public static readonly OxyColor AntiqueWhite = OxyColor.FromUInt32(0xFFFAEBD7);
+
+ ///
+ /// The aqua.
+ ///
+ public static readonly OxyColor Aqua = OxyColor.FromUInt32(0xFF00FFFF);
+
+ ///
+ /// The aquamarine.
+ ///
+ public static readonly OxyColor Aquamarine = OxyColor.FromUInt32(0xFF7FFFD4);
+
+ ///
+ /// The azure.
+ ///
+ public static readonly OxyColor Azure = OxyColor.FromUInt32(0xFFF0FFFF);
+
+ ///
+ /// The beige.
+ ///
+ public static readonly OxyColor Beige = OxyColor.FromUInt32(0xFFF5F5DC);
+
+ ///
+ /// The bisque.
+ ///
+ public static readonly OxyColor Bisque = OxyColor.FromUInt32(0xFFFFE4C4);
+
+ ///
+ /// The black.
+ ///
+ public static readonly OxyColor Black = OxyColor.FromUInt32(0xFF000000);
+
+ ///
+ /// The blanched almond.
+ ///
+ public static readonly OxyColor BlanchedAlmond = OxyColor.FromUInt32(0xFFFFEBCD);
+
+ ///
+ /// The blue.
+ ///
+ public static readonly OxyColor Blue = OxyColor.FromUInt32(0xFF0000FF);
+
+ ///
+ /// The blue violet.
+ ///
+ public static readonly OxyColor BlueViolet = OxyColor.FromUInt32(0xFF8A2BE2);
+
+ ///
+ /// The brown.
+ ///
+ public static readonly OxyColor Brown = OxyColor.FromUInt32(0xFFA52A2A);
+
+ ///
+ /// The burly wood.
+ ///
+ public static readonly OxyColor BurlyWood = OxyColor.FromUInt32(0xFFDEB887);
+
+ ///
+ /// The cadet blue.
+ ///
+ public static readonly OxyColor CadetBlue = OxyColor.FromUInt32(0xFF5F9EA0);
+
+ ///
+ /// The chartreuse.
+ ///
+ public static readonly OxyColor Chartreuse = OxyColor.FromUInt32(0xFF7FFF00);
+
+ ///
+ /// The chocolate.
+ ///
+ public static readonly OxyColor Chocolate = OxyColor.FromUInt32(0xFFD2691E);
+
+ ///
+ /// The coral.
+ ///
+ public static readonly OxyColor Coral = OxyColor.FromUInt32(0xFFFF7F50);
+
+ ///
+ /// The cornflower blue.
+ ///
+ public static readonly OxyColor CornflowerBlue = OxyColor.FromUInt32(0xFF6495ED);
+
+ ///
+ /// The cornsilk.
+ ///
+ public static readonly OxyColor Cornsilk = OxyColor.FromUInt32(0xFFFFF8DC);
+
+ ///
+ /// The crimson.
+ ///
+ public static readonly OxyColor Crimson = OxyColor.FromUInt32(0xFFDC143C);
+
+ ///
+ /// The cyan.
+ ///
+ public static readonly OxyColor Cyan = OxyColor.FromUInt32(0xFF00FFFF);
+
+ ///
+ /// The dark blue.
+ ///
+ public static readonly OxyColor DarkBlue = OxyColor.FromUInt32(0xFF00008B);
+
+ ///
+ /// The dark cyan.
+ ///
+ public static readonly OxyColor DarkCyan = OxyColor.FromUInt32(0xFF008B8B);
+
+ ///
+ /// The dark goldenrod.
+ ///
+ public static readonly OxyColor DarkGoldenrod = OxyColor.FromUInt32(0xFFB8860B);
+
+ ///
+ /// The dark gray.
+ ///
+ public static readonly OxyColor DarkGray = OxyColor.FromUInt32(0xFFA9A9A9);
+
+ ///
+ /// The dark green.
+ ///
+ public static readonly OxyColor DarkGreen = OxyColor.FromUInt32(0xFF006400);
+
+ ///
+ /// The dark khaki.
+ ///
+ public static readonly OxyColor DarkKhaki = OxyColor.FromUInt32(0xFFBDB76B);
+
+ ///
+ /// The dark magenta.
+ ///
+ public static readonly OxyColor DarkMagenta = OxyColor.FromUInt32(0xFF8B008B);
+
+ ///
+ /// The dark olive green.
+ ///
+ public static readonly OxyColor DarkOliveGreen = OxyColor.FromUInt32(0xFF556B2F);
+
+ ///
+ /// The dark orange.
+ ///
+ public static readonly OxyColor DarkOrange = OxyColor.FromUInt32(0xFFFF8C00);
+
+ ///
+ /// The dark orchid.
+ ///
+ public static readonly OxyColor DarkOrchid = OxyColor.FromUInt32(0xFF9932CC);
+
+ ///
+ /// The dark red.
+ ///
+ public static readonly OxyColor DarkRed = OxyColor.FromUInt32(0xFF8B0000);
+
+ ///
+ /// The dark salmon.
+ ///
+ public static readonly OxyColor DarkSalmon = OxyColor.FromUInt32(0xFFE9967A);
+
+ ///
+ /// The dark sea green.
+ ///
+ public static readonly OxyColor DarkSeaGreen = OxyColor.FromUInt32(0xFF8FBC8F);
+
+ ///
+ /// The dark slate blue.
+ ///
+ public static readonly OxyColor DarkSlateBlue = OxyColor.FromUInt32(0xFF483D8B);
+
+ ///
+ /// The dark slate gray.
+ ///
+ public static readonly OxyColor DarkSlateGray = OxyColor.FromUInt32(0xFF2F4F4F);
+
+ ///
+ /// The dark turquoise.
+ ///
+ public static readonly OxyColor DarkTurquoise = OxyColor.FromUInt32(0xFF00CED1);
+
+ ///
+ /// The dark violet.
+ ///
+ public static readonly OxyColor DarkViolet = OxyColor.FromUInt32(0xFF9400D3);
+
+ ///
+ /// The deep pink.
+ ///
+ public static readonly OxyColor DeepPink = OxyColor.FromUInt32(0xFFFF1493);
+
+ ///
+ /// The deep sky blue.
+ ///
+ public static readonly OxyColor DeepSkyBlue = OxyColor.FromUInt32(0xFF00BFFF);
+
+ ///
+ /// The dim gray.
+ ///
+ public static readonly OxyColor DimGray = OxyColor.FromUInt32(0xFF696969);
+
+ ///
+ /// The dodger blue.
+ ///
+ public static readonly OxyColor DodgerBlue = OxyColor.FromUInt32(0xFF1E90FF);
+
+ ///
+ /// The firebrick.
+ ///
+ public static readonly OxyColor Firebrick = OxyColor.FromUInt32(0xFFB22222);
+
+ ///
+ /// The floral white.
+ ///
+ public static readonly OxyColor FloralWhite = OxyColor.FromUInt32(0xFFFFFAF0);
+
+ ///
+ /// The forest green.
+ ///
+ public static readonly OxyColor ForestGreen = OxyColor.FromUInt32(0xFF228B22);
+
+ ///
+ /// The fuchsia.
+ ///
+ public static readonly OxyColor Fuchsia = OxyColor.FromUInt32(0xFFFF00FF);
+
+ ///
+ /// The gainsboro.
+ ///
+ public static readonly OxyColor Gainsboro = OxyColor.FromUInt32(0xFFDCDCDC);
+
+ ///
+ /// The ghost white.
+ ///
+ public static readonly OxyColor GhostWhite = OxyColor.FromUInt32(0xFFF8F8FF);
+
+ ///
+ /// The gold.
+ ///
+ public static readonly OxyColor Gold = OxyColor.FromUInt32(0xFFFFD700);
+
+ ///
+ /// The goldenrod.
+ ///
+ public static readonly OxyColor Goldenrod = OxyColor.FromUInt32(0xFFDAA520);
+
+ ///
+ /// The gray.
+ ///
+ public static readonly OxyColor Gray = OxyColor.FromUInt32(0xFF808080);
+
+ ///
+ /// The green.
+ ///
+ public static readonly OxyColor Green = OxyColor.FromUInt32(0xFF008000);
+
+ ///
+ /// The green yellow.
+ ///
+ public static readonly OxyColor GreenYellow = OxyColor.FromUInt32(0xFFADFF2F);
+
+ ///
+ /// The honeydew.
+ ///
+ public static readonly OxyColor Honeydew = OxyColor.FromUInt32(0xFFF0FFF0);
+
+ ///
+ /// The hot pink.
+ ///
+ public static readonly OxyColor HotPink = OxyColor.FromUInt32(0xFFFF69B4);
+
+ ///
+ /// The indian red.
+ ///
+ public static readonly OxyColor IndianRed = OxyColor.FromUInt32(0xFFCD5C5C);
+
+ ///
+ /// The indigo.
+ ///
+ public static readonly OxyColor Indigo = OxyColor.FromUInt32(0xFF4B0082);
+
+ ///
+ /// The ivory.
+ ///
+ public static readonly OxyColor Ivory = OxyColor.FromUInt32(0xFFFFFFF0);
+
+ ///
+ /// The khaki.
+ ///
+ public static readonly OxyColor Khaki = OxyColor.FromUInt32(0xFFF0E68C);
+
+ ///
+ /// The lavender.
+ ///
+ public static readonly OxyColor Lavender = OxyColor.FromUInt32(0xFFE6E6FA);
+
+ ///
+ /// The lavender blush.
+ ///
+ public static readonly OxyColor LavenderBlush = OxyColor.FromUInt32(0xFFFFF0F5);
+
+ ///
+ /// The lawn green.
+ ///
+ public static readonly OxyColor LawnGreen = OxyColor.FromUInt32(0xFF7CFC00);
+
+ ///
+ /// The lemon chiffon.
+ ///
+ public static readonly OxyColor LemonChiffon = OxyColor.FromUInt32(0xFFFFFACD);
+
+ ///
+ /// The light blue.
+ ///
+ public static readonly OxyColor LightBlue = OxyColor.FromUInt32(0xFFADD8E6);
+
+ ///
+ /// The light coral.
+ ///
+ public static readonly OxyColor LightCoral = OxyColor.FromUInt32(0xFFF08080);
+
+ ///
+ /// The light cyan.
+ ///
+ public static readonly OxyColor LightCyan = OxyColor.FromUInt32(0xFFE0FFFF);
+
+ ///
+ /// The light goldenrod yellow.
+ ///
+ public static readonly OxyColor LightGoldenrodYellow = OxyColor.FromUInt32(0xFFFAFAD2);
+
+ ///
+ /// The light gray.
+ ///
+ public static readonly OxyColor LightGray = OxyColor.FromUInt32(0xFFD3D3D3);
+
+ ///
+ /// The light green.
+ ///
+ public static readonly OxyColor LightGreen = OxyColor.FromUInt32(0xFF90EE90);
+
+ ///
+ /// The light pink.
+ ///
+ public static readonly OxyColor LightPink = OxyColor.FromUInt32(0xFFFFB6C1);
+
+ ///
+ /// The light salmon.
+ ///
+ public static readonly OxyColor LightSalmon = OxyColor.FromUInt32(0xFFFFA07A);
+
+ ///
+ /// The light sea green.
+ ///
+ public static readonly OxyColor LightSeaGreen = OxyColor.FromUInt32(0xFF20B2AA);
+
+ ///
+ /// The light sky blue.
+ ///
+ public static readonly OxyColor LightSkyBlue = OxyColor.FromUInt32(0xFF87CEFA);
+
+ ///
+ /// The light slate gray.
+ ///
+ public static readonly OxyColor LightSlateGray = OxyColor.FromUInt32(0xFF778899);
+
+ ///
+ /// The light steel blue.
+ ///
+ public static readonly OxyColor LightSteelBlue = OxyColor.FromUInt32(0xFFB0C4DE);
+
+ ///
+ /// The light yellow.
+ ///
+ public static readonly OxyColor LightYellow = OxyColor.FromUInt32(0xFFFFFFE0);
+
+ ///
+ /// The lime.
+ ///
+ public static readonly OxyColor Lime = OxyColor.FromUInt32(0xFF00FF00);
+
+ ///
+ /// The lime green.
+ ///
+ public static readonly OxyColor LimeGreen = OxyColor.FromUInt32(0xFF32CD32);
+
+ ///
+ /// The linen.
+ ///
+ public static readonly OxyColor Linen = OxyColor.FromUInt32(0xFFFAF0E6);
+
+ ///
+ /// The magenta.
+ ///
+ public static readonly OxyColor Magenta = OxyColor.FromUInt32(0xFFFF00FF);
+
+ ///
+ /// The maroon.
+ ///
+ public static readonly OxyColor Maroon = OxyColor.FromUInt32(0xFF800000);
+
+ ///
+ /// The medium aquamarine.
+ ///
+ public static readonly OxyColor MediumAquamarine = OxyColor.FromUInt32(0xFF66CDAA);
+
+ ///
+ /// The medium blue.
+ ///
+ public static readonly OxyColor MediumBlue = OxyColor.FromUInt32(0xFF0000CD);
+
+ ///
+ /// The medium orchid.
+ ///
+ public static readonly OxyColor MediumOrchid = OxyColor.FromUInt32(0xFFBA55D3);
+
+ ///
+ /// The medium purple.
+ ///
+ public static readonly OxyColor MediumPurple = OxyColor.FromUInt32(0xFF9370DB);
+
+ ///
+ /// The medium sea green.
+ ///
+ public static readonly OxyColor MediumSeaGreen = OxyColor.FromUInt32(0xFF3CB371);
+
+ ///
+ /// The medium slate blue.
+ ///
+ public static readonly OxyColor MediumSlateBlue = OxyColor.FromUInt32(0xFF7B68EE);
+
+ ///
+ /// The medium spring green.
+ ///
+ public static readonly OxyColor MediumSpringGreen = OxyColor.FromUInt32(0xFF00FA9A);
+
+ ///
+ /// The medium turquoise.
+ ///
+ public static readonly OxyColor MediumTurquoise = OxyColor.FromUInt32(0xFF48D1CC);
+
+ ///
+ /// The medium violet red.
+ ///
+ public static readonly OxyColor MediumVioletRed = OxyColor.FromUInt32(0xFFC71585);
+
+ ///
+ /// The midnight blue.
+ ///
+ public static readonly OxyColor MidnightBlue = OxyColor.FromUInt32(0xFF191970);
+
+ ///
+ /// The mint cream.
+ ///
+ public static readonly OxyColor MintCream = OxyColor.FromUInt32(0xFFF5FFFA);
+
+ ///
+ /// The misty rose.
+ ///
+ public static readonly OxyColor MistyRose = OxyColor.FromUInt32(0xFFFFE4E1);
+
+ ///
+ /// The moccasin.
+ ///
+ public static readonly OxyColor Moccasin = OxyColor.FromUInt32(0xFFFFE4B5);
+
+ ///
+ /// The navajo white.
+ ///
+ public static readonly OxyColor NavajoWhite = OxyColor.FromUInt32(0xFFFFDEAD);
+
+ ///
+ /// The navy.
+ ///
+ public static readonly OxyColor Navy = OxyColor.FromUInt32(0xFF000080);
+
+ ///
+ /// The old lace.
+ ///
+ public static readonly OxyColor OldLace = OxyColor.FromUInt32(0xFFFDF5E6);
+
+ ///
+ /// The olive.
+ ///
+ public static readonly OxyColor Olive = OxyColor.FromUInt32(0xFF808000);
+
+ ///
+ /// The olive drab.
+ ///
+ public static readonly OxyColor OliveDrab = OxyColor.FromUInt32(0xFF6B8E23);
+
+ ///
+ /// The orange.
+ ///
+ public static readonly OxyColor Orange = OxyColor.FromUInt32(0xFFFFA500);
+
+ ///
+ /// The orange red.
+ ///
+ public static readonly OxyColor OrangeRed = OxyColor.FromUInt32(0xFFFF4500);
+
+ ///
+ /// The orchid.
+ ///
+ public static readonly OxyColor Orchid = OxyColor.FromUInt32(0xFFDA70D6);
+
+ ///
+ /// The pale goldenrod.
+ ///
+ public static readonly OxyColor PaleGoldenrod = OxyColor.FromUInt32(0xFFEEE8AA);
+
+ ///
+ /// The pale green.
+ ///
+ public static readonly OxyColor PaleGreen = OxyColor.FromUInt32(0xFF98FB98);
+
+ ///
+ /// The pale turquoise.
+ ///
+ public static readonly OxyColor PaleTurquoise = OxyColor.FromUInt32(0xFFAFEEEE);
+
+ ///
+ /// The pale violet red.
+ ///
+ public static readonly OxyColor PaleVioletRed = OxyColor.FromUInt32(0xFFDB7093);
+
+ ///
+ /// The papaya whip.
+ ///
+ public static readonly OxyColor PapayaWhip = OxyColor.FromUInt32(0xFFFFEFD5);
+
+ ///
+ /// The peach puff.
+ ///
+ public static readonly OxyColor PeachPuff = OxyColor.FromUInt32(0xFFFFDAB9);
+
+ ///
+ /// The peru.
+ ///
+ public static readonly OxyColor Peru = OxyColor.FromUInt32(0xFFCD853F);
+
+ ///
+ /// The pink.
+ ///
+ public static readonly OxyColor Pink = OxyColor.FromUInt32(0xFFFFC0CB);
+
+ ///
+ /// The plum.
+ ///
+ public static readonly OxyColor Plum = OxyColor.FromUInt32(0xFFDDA0DD);
+
+ ///
+ /// The powder blue.
+ ///
+ public static readonly OxyColor PowderBlue = OxyColor.FromUInt32(0xFFB0E0E6);
+
+ ///
+ /// The purple.
+ ///
+ public static readonly OxyColor Purple = OxyColor.FromUInt32(0xFF800080);
+
+ ///
+ /// The red.
+ ///
+ public static readonly OxyColor Red = OxyColor.FromUInt32(0xFFFF0000);
+
+ ///
+ /// The rosy brown.
+ ///
+ public static readonly OxyColor RosyBrown = OxyColor.FromUInt32(0xFFBC8F8F);
+
+ ///
+ /// The royal blue.
+ ///
+ public static readonly OxyColor RoyalBlue = OxyColor.FromUInt32(0xFF4169E1);
+
+ ///
+ /// The saddle brown.
+ ///
+ public static readonly OxyColor SaddleBrown = OxyColor.FromUInt32(0xFF8B4513);
+
+ ///
+ /// The salmon.
+ ///
+ public static readonly OxyColor Salmon = OxyColor.FromUInt32(0xFFFA8072);
+
+ ///
+ /// The sandy brown.
+ ///
+ public static readonly OxyColor SandyBrown = OxyColor.FromUInt32(0xFFF4A460);
+
+ ///
+ /// The sea green.
+ ///
+ public static readonly OxyColor SeaGreen = OxyColor.FromUInt32(0xFF2E8B57);
+
+ ///
+ /// The sea shell.
+ ///
+ public static readonly OxyColor SeaShell = OxyColor.FromUInt32(0xFFFFF5EE);
+
+ ///
+ /// The sienna.
+ ///
+ public static readonly OxyColor Sienna = OxyColor.FromUInt32(0xFFA0522D);
+
+ ///
+ /// The silver.
+ ///
+ public static readonly OxyColor Silver = OxyColor.FromUInt32(0xFFC0C0C0);
+
+ ///
+ /// The sky blue.
+ ///
+ public static readonly OxyColor SkyBlue = OxyColor.FromUInt32(0xFF87CEEB);
+
+ ///
+ /// The slate blue.
+ ///
+ public static readonly OxyColor SlateBlue = OxyColor.FromUInt32(0xFF6A5ACD);
+
+ ///
+ /// The slate gray.
+ ///
+ public static readonly OxyColor SlateGray = OxyColor.FromUInt32(0xFF708090);
+
+ ///
+ /// The snow.
+ ///
+ public static readonly OxyColor Snow = OxyColor.FromUInt32(0xFFFFFAFA);
+
+ ///
+ /// The spring green.
+ ///
+ public static readonly OxyColor SpringGreen = OxyColor.FromUInt32(0xFF00FF7F);
+
+ ///
+ /// The steel blue.
+ ///
+ public static readonly OxyColor SteelBlue = OxyColor.FromUInt32(0xFF4682B4);
+
+ ///
+ /// The tan.
+ ///
+ public static readonly OxyColor Tan = OxyColor.FromUInt32(0xFFD2B48C);
+
+ ///
+ /// The teal.
+ ///
+ public static readonly OxyColor Teal = OxyColor.FromUInt32(0xFF008080);
+
+ ///
+ /// The thistle.
+ ///
+ public static readonly OxyColor Thistle = OxyColor.FromUInt32(0xFFD8BFD8);
+
+ ///
+ /// The tomato.
+ ///
+ public static readonly OxyColor Tomato = OxyColor.FromUInt32(0xFFFF6347);
+
+ ///
+ /// The transparent.
+ ///
+ public static readonly OxyColor Transparent = OxyColor.FromUInt32(0x00FFFFFF);
+
+ ///
+ /// The turquoise.
+ ///
+ public static readonly OxyColor Turquoise = OxyColor.FromUInt32(0xFF40E0D0);
+
+ ///
+ /// The violet.
+ ///
+ public static readonly OxyColor Violet = OxyColor.FromUInt32(0xFFEE82EE);
+
+ ///
+ /// The wheat.
+ ///
+ public static readonly OxyColor Wheat = OxyColor.FromUInt32(0xFFF5DEB3);
+
+ ///
+ /// The white.
+ ///
+ public static readonly OxyColor White = OxyColor.FromUInt32(0xFFFFFFFF);
+
+ ///
+ /// The white smoke.
+ ///
+ public static readonly OxyColor WhiteSmoke = OxyColor.FromUInt32(0xFFF5F5F5);
+
+ ///
+ /// The yellow.
+ ///
+ public static readonly OxyColor Yellow = OxyColor.FromUInt32(0xFFFFFF00);
+
+ ///
+ /// The yellow green.
+ ///
+ public static readonly OxyColor YellowGreen = OxyColor.FromUInt32(0xFF9ACD32);
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyImage.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyImage.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,444 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an image, encoded as DIB, JPEG or PNG.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+
+ ///
+ /// Represents an image, encoded as DIB, JPEG or PNG.
+ ///
+ public class OxyImage
+ {
+ ///
+ /// The image data.
+ ///
+ private readonly byte[] data;
+
+ ///
+ /// Initializes a new instance of the class from the specified stream.
+ ///
+ ///
+ /// A stream that provides the image data.
+ ///
+ public OxyImage(Stream s)
+ {
+ using (var ms = new MemoryStream())
+ {
+ s.CopyTo(ms);
+ this.data = ms.ToArray();
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class from a byte array.
+ ///
+ ///
+ /// The image bytes.
+ ///
+ public OxyImage(byte[] bytes)
+ {
+ this.data = bytes;
+ }
+
+ ///
+ /// Creates an from the specified array.
+ ///
+ ///
+ /// The pixel data, indexed as [row,column] (from bottom-left).
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ ///
+ /// This method is creating a simple BitmapInfoHeader.
+ ///
+ public static OxyImage FromArgbX(OxyColor[,] data, int dpi = 96)
+ {
+ int height = data.GetLength(0);
+ int width = data.GetLength(1);
+ var bytes = new byte[width * height * 4];
+ int k = 0;
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ bytes[k++] = data[i, j].B;
+ bytes[k++] = data[i, j].G;
+ bytes[k++] = data[i, j].R;
+ bytes[k++] = data[i, j].A;
+ }
+ }
+
+ return FromArgbX(width, height, bytes, dpi);
+ }
+
+ ///
+ /// Creates an from the specified array.
+ ///
+ ///
+ /// The pixel data, indexed as [row,column] (from bottom-left).
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ ///
+ /// This method is creating a Bitmap V4 info header, including channel bit masks and color space information.
+ ///
+ public static OxyImage FromArgb(OxyColor[,] data, int dpi = 96)
+ {
+ int height = data.GetLength(0);
+ int width = data.GetLength(1);
+ var bytes = new byte[width * height * 4];
+ int k = 0;
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ bytes[k++] = data[i, j].B;
+ bytes[k++] = data[i, j].G;
+ bytes[k++] = data[i, j].R;
+ bytes[k++] = data[i, j].A;
+ }
+ }
+
+ return FromArgb(width, height, bytes, dpi);
+ }
+
+ ///
+ /// Creates an from the specified pixel data.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The pixel data (BGRA from bottom-left).
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ ///
+ /// This method is creating a Bitmap V4 info header, including channel bit masks and color space information.
+ ///
+ public static OxyImage FromArgb(int width, int height, byte[] pixelData, int dpi = 96)
+ {
+ var ms = new MemoryStream();
+ var w = new BinaryWriter(ms);
+
+ const int OffBits = 14 + 108;
+ var size = OffBits + pixelData.Length;
+
+ // Bitmap file header (14 bytes)
+ w.Write((byte)'B');
+ w.Write((byte)'M');
+ w.Write((uint)size);
+ w.Write((ushort)0);
+ w.Write((ushort)0);
+ w.Write((uint)OffBits);
+
+ // Bitmap V4 info header (108 bytes)
+ WriteBitmapV4Header(w, width, height, 32, pixelData.Length, dpi);
+
+ // Pixel array (from bottom-left corner)
+ w.Write(pixelData);
+
+ return new OxyImage(ms.ToArray());
+ }
+
+ ///
+ /// Creates an from the specified 8-bit indexed pixel data.
+ ///
+ ///
+ /// The indexed pixel data (from bottom-left).
+ ///
+ ///
+ /// The palette.
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ public static OxyImage FromIndexed8(byte[,] indexedData, OxyColor[] palette, int dpi = 96)
+ {
+ int height = indexedData.GetLength(0);
+ int width = indexedData.GetLength(1);
+ return FromIndexed8(width, height, indexedData.Cast().ToArray(), palette, dpi);
+ }
+
+ ///
+ /// Creates an from the specified 8-bit indexed pixel data.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The indexed pixel data (from bottom-left).
+ ///
+ ///
+ /// The palette.
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ public static OxyImage FromIndexed8(
+ int width, int height, byte[] indexedPixelData, OxyColor[] palette, int dpi = 96)
+ {
+ if (indexedPixelData.Length != width * height)
+ {
+ throw new ArgumentException("Length of data is not correct.", "indexedPixelData");
+ }
+
+ if (palette.Length == 0)
+ {
+ throw new ArgumentException("Palette not defined.", "palette");
+ }
+
+ var ms = new MemoryStream();
+ var w = new BinaryWriter(ms);
+
+ var offBits = 14 + 40 + (4 * palette.Length);
+ var size = offBits + indexedPixelData.Length;
+
+ // Bitmap file header (14 bytes)
+ w.Write((byte)'B');
+ w.Write((byte)'M');
+ w.Write((uint)size);
+ w.Write((ushort)0);
+ w.Write((ushort)0);
+ w.Write((uint)offBits);
+
+ // Bitmap info header
+ WriteBitmapInfoHeader(w, width, height, 8, indexedPixelData.Length, dpi, palette.Length);
+
+ // Color table
+ foreach (var color in palette)
+ {
+ w.Write(color.B);
+ w.Write(color.G);
+ w.Write(color.R);
+ w.Write(color.A);
+ }
+
+ // Pixel array (from bottom-left corner)
+ w.Write(indexedPixelData);
+
+ return new OxyImage(ms.ToArray());
+ }
+
+ ///
+ /// Creates an from the specified pixel data.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The pixel data (BGRA from bottom-left).
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// An .
+ ///
+ ///
+ /// This method is creating a simple BitmapInfoHeader.
+ ///
+ public static OxyImage FromArgbX(int width, int height, byte[] pixelData, int dpi = 96)
+ {
+ var ms = new MemoryStream();
+ var w = new BinaryWriter(ms);
+
+ const int OffBits = 14 + 40;
+ var size = OffBits + pixelData.Length;
+
+ // Bitmap file header (14 bytes)
+ w.Write((byte)'B');
+ w.Write((byte)'M');
+ w.Write((uint)size);
+ w.Write((ushort)0);
+ w.Write((ushort)0);
+ w.Write((uint)OffBits);
+
+ // Bitmap info header
+ WriteBitmapInfoHeader(w, width, height, 32, pixelData.Length, dpi);
+
+ // Pixel array (from bottom-left corner)
+ w.Write(pixelData);
+
+ return new OxyImage(ms.ToArray());
+ }
+
+ ///
+ /// Gets the image data.
+ ///
+ ///
+ /// The image data as a byte array.
+ ///
+ public byte[] GetData()
+ {
+ return this.data;
+ }
+
+ ///
+ /// Writes the bitmap info header.
+ ///
+ ///
+ /// The writer.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The number of bits per pixel.
+ ///
+ ///
+ /// The length of the pixel data.
+ ///
+ ///
+ /// The dpi.
+ ///
+ ///
+ /// The number of colors.
+ ///
+ private static void WriteBitmapInfoHeader(
+ BinaryWriter w, int width, int height, int bitsPerPixel, int length, int dpi, int colors = 0)
+ {
+ // Convert resolution to pixels per meter
+ var ppm = (uint)(dpi / 0.0254);
+
+ w.Write((uint)40);
+ w.Write((uint)width);
+ w.Write((uint)height);
+ w.Write((ushort)1);
+ w.Write((ushort)bitsPerPixel);
+ w.Write((uint)0);
+ w.Write((uint)length);
+ w.Write(ppm);
+ w.Write(ppm);
+ w.Write((uint)colors);
+ w.Write((uint)colors);
+ }
+
+ ///
+ /// Writes the bitmap V4 header.
+ ///
+ ///
+ /// The writer.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The number of bits per pixel.
+ ///
+ ///
+ /// The length.
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// The number of colors.
+ ///
+ private static void WriteBitmapV4Header(
+ BinaryWriter w, int width, int height, int bitsPerPixel, int length, int dpi, int colors = 0)
+ {
+ // Convert resolution to pixels per meter
+ var ppm = (uint)(dpi / 0.0254);
+
+ w.Write((uint)108);
+ w.Write((uint)width);
+ w.Write((uint)height);
+ w.Write((ushort)1);
+ w.Write((ushort)bitsPerPixel);
+ w.Write((uint)3);
+ w.Write((uint)length);
+ w.Write(ppm);
+ w.Write(ppm);
+ w.Write((uint)colors);
+ w.Write((uint)colors);
+
+ // Write the channel bit masks
+ w.Write(0x00FF0000);
+ w.Write(0x0000FF00);
+ w.Write(0x000000FF);
+ w.Write(0xFF000000);
+
+ // Write the color space
+ w.Write((uint)0x206E6957);
+ w.Write(new byte[3 * 3 * 4]);
+
+ // Write the gamma RGB
+ w.Write((uint)0);
+ w.Write((uint)0);
+ w.Write((uint)0);
+ }
+
+ ///
+ /// Creates a PNG image from the specified pixels.
+ ///
+ /// The pixels (bottom line first).
+ /// An OxyImage.
+ public static OxyImage PngFromArgb(OxyColor[,] pixels)
+ {
+ return new OxyImage(PngEncoder.Encode(pixels));
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyPalette.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyPalette.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,102 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a palette of colors.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Represents a palette of colors.
+ ///
+ public class OxyPalette
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public OxyPalette()
+ {
+ this.Colors = new List();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The colors.
+ ///
+ public OxyPalette(params OxyColor[] colors)
+ {
+ this.Colors = new List(colors);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The colors.
+ ///
+ public OxyPalette(IEnumerable colors)
+ {
+ this.Colors = new List(colors);
+ }
+
+ ///
+ /// Gets or sets the colors.
+ ///
+ /// The colors.
+ public IList Colors { get; set; }
+
+ ///
+ /// Interpolates the specified colors to a palette of the specified size.
+ ///
+ ///
+ /// The size of the palette.
+ ///
+ ///
+ /// The colors.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette Interpolate(int paletteSize, params OxyColor[] colors)
+ {
+ var palette = new OxyColor[paletteSize];
+ for (int i = 0; i < paletteSize; i++)
+ {
+ double y = (double)i / (paletteSize - 1);
+ double x = y * (colors.Length - 1);
+ int i0 = (int)x;
+ int i1 = i0 + 1 < colors.Length ? i0 + 1 : i0;
+ palette[i] = OxyColor.Interpolate(colors[i0], colors[i1], x - i0);
+ }
+
+ return new OxyPalette(palette);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyPalettes.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyPalettes.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,208 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides predefined palettes.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides predefined palettes.
+ ///
+ public static class OxyPalettes
+ {
+ ///
+ /// Initializes static members of the class.
+ ///
+ static OxyPalettes()
+ {
+ BlueWhiteRed31 = BlueWhiteRed(31);
+ Hot64 = Hot(64);
+ Hue64 = Hue(64);
+ }
+
+ ///
+ /// Gets the blue white red (31) palette.
+ ///
+ public static OxyPalette BlueWhiteRed31 { get; private set; }
+
+ ///
+ /// Gets the hot (64) palette.
+ ///
+ public static OxyPalette Hot64 { get; private set; }
+
+ ///
+ /// Gets the hue64 palette.
+ ///
+ public static OxyPalette Hue64 { get; private set; }
+
+ ///
+ /// Creates a black/white/red palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette BlackWhiteRed(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(numberOfColors, OxyColors.Black, OxyColors.White, OxyColors.Red);
+ }
+
+ ///
+ /// Creates a blue/white/red palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette BlueWhiteRed(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(numberOfColors, OxyColors.Blue, OxyColors.White, OxyColors.Red);
+ }
+
+ ///
+ /// Creates a 'cool' palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette Cool(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(numberOfColors, OxyColors.Cyan, OxyColors.Magenta);
+ }
+
+ ///
+ /// Creates a gray-scale palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette Gray(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(numberOfColors, OxyColors.Black, OxyColors.White);
+ }
+
+ ///
+ /// Creates a 'hot' palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette Hot(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(
+ numberOfColors,
+ OxyColors.Black,
+ OxyColor.FromRgb(127, 0, 0),
+ OxyColor.FromRgb(255, 127, 0),
+ OxyColor.FromRgb(255, 255, 127),
+ OxyColors.White);
+ }
+
+ ///
+ /// Creates a palette from the hue component of the HSV color model.
+ ///
+ ///
+ /// The number of colors.
+ ///
+ ///
+ /// The palette.
+ ///
+ ///
+ /// This palette is particularly appropriate for displaying periodic functions.
+ ///
+ public static OxyPalette Hue(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(
+ numberOfColors,
+ OxyColors.Red,
+ OxyColors.Yellow,
+ OxyColors.Green,
+ OxyColors.Cyan,
+ OxyColors.Blue,
+ OxyColors.Magenta,
+ OxyColors.Red);
+ }
+
+ ///
+ /// Creates a 'jet' palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ ///
+ /// See http://www.mathworks.se/help/techdoc/ref/colormap.html.
+ ///
+ public static OxyPalette Jet(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(
+ numberOfColors,
+ OxyColors.DarkBlue,
+ OxyColors.Cyan,
+ OxyColors.Yellow,
+ OxyColors.Orange,
+ OxyColors.DarkRed);
+ }
+
+ ///
+ /// Creates a rainbow palette with the specified number of colors.
+ ///
+ ///
+ /// The number of colors to create for the palette.
+ ///
+ ///
+ /// A palette.
+ ///
+ public static OxyPalette Rainbow(int numberOfColors)
+ {
+ return OxyPalette.Interpolate(
+ numberOfColors,
+ OxyColors.Violet,
+ OxyColors.Indigo,
+ OxyColors.Blue,
+ OxyColors.Green,
+ OxyColors.Yellow,
+ OxyColors.Orange,
+ OxyColors.Red);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyPen.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyPen.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,138 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes a pen in terms of color, thickness, line style and line join type.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Describes a pen in terms of color, thickness, line style and line join type.
+ ///
+ public class OxyPen
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ /// The thickness.
+ ///
+ ///
+ /// The line style.
+ ///
+ ///
+ /// The line join.
+ ///
+ public OxyPen(
+ OxyColor color,
+ double thickness = 1.0,
+ LineStyle lineStyle = LineStyle.Solid,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
+ {
+ this.Color = color;
+ this.Thickness = thickness;
+ this.DashArray = LineStyleHelper.GetDashArray(lineStyle);
+ this.LineStyle = lineStyle;
+ this.LineJoin = lineJoin;
+ }
+
+ ///
+ /// Gets or sets the color.
+ ///
+ /// The color.
+ public OxyColor Color { get; set; }
+
+ ///
+ /// Gets or sets the dash array.
+ ///
+ /// The dash array.
+ public double[] DashArray { get; set; }
+
+ ///
+ /// Gets or sets the line join.
+ ///
+ /// The line join.
+ public OxyPenLineJoin LineJoin { get; set; }
+
+ ///
+ /// Gets or sets the line style.
+ ///
+ /// The line style.
+ public LineStyle LineStyle { get; set; }
+
+ ///
+ /// Gets or sets the thickness.
+ ///
+ /// The thickness.
+ public double Thickness { get; set; }
+
+ ///
+ /// Creates the specified pen.
+ ///
+ /// The color.
+ /// The thickness.
+ /// The line style.
+ /// The line join.
+ /// A pen.
+ public static OxyPen Create(
+ OxyColor color,
+ double thickness,
+ LineStyle lineStyle = LineStyle.Solid,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
+ {
+ if (color == null || lineStyle == LineStyle.None || Math.Abs(thickness) < double.Epsilon)
+ {
+ return null;
+ }
+
+ return new OxyPen(color, thickness, lineStyle, lineJoin);
+ }
+
+ ///
+ /// Returns a hash code for this instance.
+ ///
+ ///
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int result = this.Color.GetHashCode();
+ result = (result * 397) ^ this.Thickness.GetHashCode();
+ result = (result * 397) ^ this.LineStyle.GetHashCode();
+ result = (result * 397) ^ this.LineJoin.GetHashCode();
+ return result;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyPenLineJoin.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyPenLineJoin.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,52 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Pen line join.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies how to join line segments.
+ ///
+ public enum OxyPenLineJoin
+ {
+ ///
+ /// Line joins use regular angular vertices.
+ ///
+ Miter,
+
+ ///
+ /// Line joins use rounded vertices.
+ ///
+ Round,
+
+ ///
+ /// Line joins use beveled vertices.
+ ///
+ Bevel
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyRect.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyRect.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,287 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes the width, height, and point origin of a rectangle.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Diagnostics;
+ using System.Globalization;
+
+ ///
+ /// Describes the width, height, and point origin of a rectangle.
+ ///
+ public struct OxyRect
+ {
+ ///
+ /// The height of the rectangle.
+ ///
+ private double height;
+
+ ///
+ /// The x-coordinate location of the left side of the rectangle.
+ ///
+ private double left;
+
+ ///
+ /// The y-coordinate location of the top side of the rectangle.
+ ///
+ private double top;
+
+ ///
+ /// The width of the rectangle.
+ ///
+ private double width;
+
+ ///
+ /// Initializes a new instance of the structure that has the specified x-coordinate, y-coordinate, width, and height.
+ ///
+ ///
+ /// The x-coordinate location of the left side of the rectangle.
+ ///
+ ///
+ /// The y-coordinate location of the top side of the rectangle.
+ ///
+ ///
+ /// The width of the rectangle.
+ ///
+ ///
+ /// The height of the rectangle.
+ ///
+ public OxyRect(double left, double top, double width, double height)
+ {
+ this.left = left;
+ this.top = top;
+ this.width = width;
+ this.height = height;
+ Debug.Assert(width >= 0, "Width should be larger than 0.");
+ Debug.Assert(height >= 0, "Height should be larger than 0.");
+ }
+
+ ///
+ /// Gets or sets the y-axis value of the bottom of the rectangle.
+ ///
+ ///
+ /// The bottom.
+ ///
+ public double Bottom
+ {
+ get
+ {
+ return this.top + this.height;
+ }
+
+ set
+ {
+ this.height = value - this.top;
+ }
+ }
+
+ ///
+ /// Gets or sets the height of the rectangle.
+ ///
+ ///
+ /// The height.
+ ///
+ public double Height
+ {
+ get
+ {
+ return this.height;
+ }
+
+ set
+ {
+ this.height = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the x-axis value of the left side of the rectangle.
+ ///
+ ///
+ /// The left.
+ ///
+ public double Left
+ {
+ get
+ {
+ return this.left;
+ }
+
+ set
+ {
+ this.left = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the x-axis value of the right side of the rectangle.
+ ///
+ ///
+ /// The right.
+ ///
+ public double Right
+ {
+ get
+ {
+ return this.left + this.width;
+ }
+
+ set
+ {
+ this.width = value - this.left;
+ }
+ }
+
+ ///
+ /// Gets or sets the y-axis position of the top of the rectangle.
+ ///
+ ///
+ /// The top.
+ ///
+ public double Top
+ {
+ get
+ {
+ return this.top;
+ }
+
+ set
+ {
+ this.top = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the width of the rectangle.
+ ///
+ ///
+ /// The width.
+ ///
+ public double Width
+ {
+ get
+ {
+ return this.width;
+ }
+
+ set
+ {
+ this.width = value;
+ }
+ }
+
+ ///
+ /// Gets the center point of the rectangle.
+ ///
+ /// The center.
+ public ScreenPoint Center
+ {
+ get
+ {
+ return new ScreenPoint(this.left + (this.width * 0.5), this.top + (this.height * 0.5));
+ }
+ }
+
+ ///
+ /// Creates a rectangle from the specified corner coordinates.
+ ///
+ ///
+ /// The x0.
+ ///
+ ///
+ /// The y0.
+ ///
+ ///
+ /// The x1.
+ ///
+ ///
+ /// The y1.
+ ///
+ ///
+ /// A rectangle.
+ ///
+ public static OxyRect Create(double x0, double y0, double x1, double y1)
+ {
+ return new OxyRect(Math.Min(x0, x1), Math.Min(y0, y1), Math.Abs(x1 - x0), Math.Abs(y1 - y0));
+ }
+
+ ///
+ /// Creates a rectangle from the specified corner coordinates.
+ ///
+ /// The first corner.
+ /// The second corner.
+ /// A rectangle.
+ public static OxyRect Create(ScreenPoint p0, ScreenPoint p1)
+ {
+ return Create(p0.X, p0.Y, p1.X, p1.Y);
+ }
+
+ ///
+ /// Determines whether the specified point is inside the rectangle.
+ ///
+ ///
+ /// The x coordinate.
+ ///
+ ///
+ /// The y coordinate.
+ ///
+ ///
+ /// true if the rectangle contains the specified point; otherwise, false.
+ ///
+ public bool Contains(double x, double y)
+ {
+ return x >= this.Left && x <= this.Right && y >= this.Top && y <= this.Bottom;
+ }
+
+ ///
+ /// Determines whether the specified point is inside the rectangle.
+ ///
+ /// The point.
+ ///
+ /// true if the rectangle contains the specified point; otherwise, false.
+ ///
+ public bool Contains(ScreenPoint p)
+ {
+ return this.Contains(p.x, p.y);
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture, "({0}, {1}, {2}, {3})", this.left, this.top, this.width, this.height);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxySize.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxySize.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,87 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Implements a structure that is used to describe the Size of an object.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Globalization;
+
+ ///
+ /// Implements a structure that is used to describe the size of an object.
+ ///
+ public struct OxySize
+ {
+ ///
+ /// Empty Size.
+ ///
+ public static OxySize Empty = new OxySize(0, 0);
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ public OxySize(double width, double height)
+ : this()
+ {
+ this.Width = width;
+ this.Height = height;
+ }
+
+ ///
+ /// Gets or sets the height.
+ ///
+ ///
+ /// The height.
+ ///
+ public double Height { get; set; }
+
+ ///
+ /// Gets or sets the width.
+ ///
+ ///
+ /// The width.
+ ///
+ public double Width { get; set; }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "({0}, {1})", this.Width, this.Height);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/OxyThickness.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/OxyThickness.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,220 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes the thickness of a frame around a rectangle. Four Double values describe the Left, Top, Right, and Bottom sides of the rectangle, respectively.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Globalization;
+
+ ///
+ /// Describes the thickness of a frame around a rectangle. Four values describe the left, top, right, and bottom sides of the rectangle, respectively.
+ ///
+ public struct OxyThickness : ICodeGenerating
+ {
+ ///
+ /// The bottom.
+ ///
+ private double bottom;
+
+ ///
+ /// The left.
+ ///
+ private double left;
+
+ ///
+ /// The right.
+ ///
+ private double right;
+
+ ///
+ /// The top.
+ ///
+ private double top;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The thickness.
+ ///
+ public OxyThickness(double thickness)
+ : this(thickness, thickness, thickness, thickness)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The left.
+ ///
+ ///
+ /// The top.
+ ///
+ ///
+ /// The right.
+ ///
+ ///
+ /// The bottom.
+ ///
+ public OxyThickness(double left, double top, double right, double bottom)
+ {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ ///
+ /// Gets or sets the bottom thickness.
+ ///
+ ///
+ /// The bottom thickness.
+ ///
+ public double Bottom
+ {
+ get
+ {
+ return this.bottom;
+ }
+
+ set
+ {
+ this.bottom = value;
+ }
+ }
+
+ ///
+ /// Gets the height.
+ ///
+ public double Height
+ {
+ get
+ {
+ return this.Bottom - this.Top;
+ }
+ }
+
+ ///
+ /// Gets or sets the left thickness.
+ ///
+ ///
+ /// The left thickness.
+ ///
+ public double Left
+ {
+ get
+ {
+ return this.left;
+ }
+
+ set
+ {
+ this.left = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the right thickness.
+ ///
+ ///
+ /// The right thickness.
+ ///
+ public double Right
+ {
+ get
+ {
+ return this.right;
+ }
+
+ set
+ {
+ this.right = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the top thickness.
+ ///
+ ///
+ /// The top thickness.
+ ///
+ public double Top
+ {
+ get
+ {
+ return this.top;
+ }
+
+ set
+ {
+ this.top = value;
+ }
+ }
+
+ ///
+ /// Gets the width.
+ ///
+ public double Width
+ {
+ get
+ {
+ return this.Right - this.Left;
+ }
+ }
+
+ ///
+ /// Returns C# code that generates this instance.
+ ///
+ ///
+ /// The to code.
+ ///
+ public string ToCode()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "new OxyThickness({0},{1},{2},{3})",
+ this.Left,
+ this.Top,
+ this.Right,
+ this.Bottom);
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture, "({0}, {1}, {2}, {3})", this.left, this.top, this.right, this.bottom);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Pen.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Pen.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,42 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public class Pen
+ {
+ public Pen(Color c, double th, LineStyle ls)
+ {
+ Color = c;
+ Thickness = th;
+ DashArray = LineStyleHelper.GetDashArray(ls);
+ }
+
+ public Color Color { get; set; }
+ public double Thickness { get; set; }
+ public double[] DashArray { get; set; }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/PlotLength.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/PlotLength.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,91 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents lengths in the plot.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ ///
+ /// Represents lengths in the plot.
+ ///
+ public struct PlotLength
+ {
+ ///
+ /// The unit type
+ ///
+ private readonly PlotLengthUnit unit;
+
+ ///
+ /// The value
+ ///
+ private readonly double value;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The unit.
+ ///
+ public PlotLength(double value, PlotLengthUnit unit)
+ {
+ this.value = value;
+ this.unit = unit;
+ }
+
+ ///
+ /// Gets the value.
+ ///
+ ///
+ /// The value.
+ ///
+ public double Value
+ {
+ get
+ {
+ return this.value;
+ }
+ }
+
+ ///
+ /// Gets the type of the unit.
+ ///
+ ///
+ /// The type of the unit.
+ ///
+ public PlotLengthUnit Unit
+ {
+ get
+ {
+ return this.unit;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/PlotLengthUnit.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/PlotLengthUnit.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,58 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes the kind of value that a object is holding.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ ///
+ /// Describes the kind of value that a object is holding.
+ ///
+ public enum PlotLengthUnit
+ {
+ ///
+ /// The value is in data space (transformed by x/y axis)
+ ///
+ Data = 0,
+
+ ///
+ /// The value is in screen units
+ ///
+ ScreenUnits = 1,
+
+ ///
+ /// The value is relative to the plot viewport (0-1)
+ ///
+ RelativeToViewport = 2,
+
+ ///
+ /// The value is relative to the plot area (0-1)
+ ///
+ RelativeToPlotArea = 3
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/PngEncoder.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/PngEncoder.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,323 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+
+ ///
+ /// Provides encoding of uncompressed png images.
+ ///
+ public class PngEncoder
+ {
+ ///
+ /// The CRC table
+ ///
+ private static readonly ulong[] CrcTable;
+
+ ///
+ /// Initializes static members of the class.
+ ///
+ static PngEncoder()
+ {
+ CrcTable = new ulong[256];
+ for (int n = 0; n < 256; n++)
+ {
+ var c = (ulong)n;
+ for (int k = 0; k < 8; k++)
+ {
+ if ((c & 1) != 0)
+ {
+ c = 0xedb88320L ^ (c >> 1);
+ }
+ else
+ {
+ c = c >> 1;
+ }
+ }
+
+ CrcTable[n] = c;
+ }
+ }
+
+ ///
+ /// Encodes the specified image data to png.
+ ///
+ ///
+ /// The pixel data (bottom line first).
+ ///
+ ///
+ /// The image resolution in dots per inch.
+ ///
+ ///
+ /// The png image data.
+ ///
+ public static byte[] Encode(OxyColor[,] pixels, int dpi = 96)
+ {
+ int height = pixels.GetLength(0);
+ int width = pixels.GetLength(1);
+ var bytes = new byte[(width * height * 4) + height];
+
+ int k = 0;
+ for (int i = height - 1; i >= 0; i--)
+ {
+ bytes[k++] = 0; // Filter
+ for (int j = 0; j < width; j++)
+ {
+ bytes[k++] = pixels[i, j].R;
+ bytes[k++] = pixels[i, j].G;
+ bytes[k++] = pixels[i, j].B;
+ bytes[k++] = pixels[i, j].A;
+ }
+ }
+
+ var w = new MemoryWriter();
+ w.Write((byte)0x89);
+ w.Write("PNG\r\n\x1a\n".ToCharArray());
+ WriteChunk(w, "IHDR", CreateHeaderData(width, height));
+ WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi));
+ WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes));
+ WriteChunk(w, "IEND", new byte[0]);
+ return w.ToArray();
+ }
+
+ ///
+ /// Calculates the Adler-32 check sum.
+ ///
+ ///
+ /// The data.
+ ///
+ ///
+ /// The check sum.
+ ///
+ private static uint Adler32(IEnumerable data)
+ {
+ // http://en.wikipedia.org/wiki/Adler-32
+ uint a = 1;
+ uint b = 0;
+ const uint ModAdler = 65521;
+ foreach (var x in data)
+ {
+ a = (a + x) % ModAdler;
+ b = (b + a) % ModAdler;
+ }
+
+ return (b << 16) | a;
+ }
+
+ ///
+ /// Creates the header data.
+ ///
+ ///
+ /// The width.
+ ///
+ ///
+ /// The height.
+ ///
+ ///
+ /// The header.
+ ///
+ private static byte[] CreateHeaderData(int width, int height)
+ {
+ // http://www.w3.org/TR/PNG-Chunks.html
+ var w = new MemoryWriter();
+ WriteBigEndian(w, width);
+ WriteBigEndian(w, height);
+ w.Write((byte)8); // bit depth
+ w.Write((byte)6); // color type RGBA
+ w.Write((byte)0); // compression method
+ w.Write((byte)0); // filter method
+ w.Write((byte)0); // interlace method
+ return w.ToArray();
+ }
+
+ ///
+ /// Creates the physical dimensions data.
+ ///
+ ///
+ /// The horizontal resolution.
+ ///
+ ///
+ /// The vertical resolution.
+ ///
+ ///
+ /// The data.
+ ///
+ private static byte[] CreatePhysicalDimensionsData(int dpix, int dpiy)
+ {
+ var ppux = (int)(dpix / 0.0254);
+ var ppuy = (int)(dpiy / 0.0254);
+ var w = new MemoryWriter();
+ WriteBigEndian(w, ppux);
+ WriteBigEndian(w, ppuy);
+ w.Write((byte)1); // Unit: metre
+ return w.ToArray();
+ }
+
+ ///
+ /// Creates the uncompressed blocks.
+ ///
+ ///
+ /// The data.
+ ///
+ ///
+ /// The output data.
+ ///
+ private static byte[] CreateUncompressedBlocks(byte[] bytes)
+ {
+ // http://www.w3.org/TR/PNG-Compression.html
+ const int MaxDeflate = 0xFFFF;
+ var w = new MemoryWriter();
+ const uint CompressionMethod = 8;
+ const uint Check = (31 - ((CompressionMethod << 8) % 31)) % 31;
+ w.Write((byte)CompressionMethod);
+ w.Write((byte)Check);
+ for (int i = 0; i < bytes.Length; i += MaxDeflate)
+ {
+ var n = (ushort)Math.Min(bytes.Length - i, MaxDeflate);
+ var last = (byte)(i + n < bytes.Length ? 0 : 1);
+ w.Write(last);
+ w.Write((byte)(n & 0xFF));
+ w.Write((byte)((n >> 8) & 0xFF));
+ var n2 = ~n;
+ w.Write((byte)(n2 & 0xFF));
+ w.Write((byte)((n2 >> 8) & 0xFF));
+ w.Write(bytes, i, n);
+ }
+
+ WriteBigEndian(w, Adler32(bytes));
+ return w.ToArray();
+ }
+
+ ///
+ /// Updates the CRC check sum.
+ ///
+ ///
+ /// The input CRC.
+ ///
+ ///
+ /// The data.
+ ///
+ ///
+ /// The updated CRC.
+ ///
+ private static ulong UpdateCrc(ulong crc, IEnumerable data)
+ {
+ return data.Aggregate(crc, (current, x) => CrcTable[(current ^ x) & 0xff] ^ (current >> 8));
+ }
+
+ ///
+ /// Writes the integer value with big endian byte order.
+ ///
+ ///
+ /// The writer.
+ ///
+ ///
+ /// The value.
+ ///
+ private static void WriteBigEndian(BinaryWriter w, int value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ w.Write(bytes[3]);
+ w.Write(bytes[2]);
+ w.Write(bytes[1]);
+ w.Write(bytes[0]);
+ }
+
+ ///
+ /// Writes the unsigned integer value with big endian byte order.
+ ///
+ ///
+ /// The writer.
+ ///
+ ///
+ /// The value.
+ ///
+ private static void WriteBigEndian(BinaryWriter w, uint value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ w.Write(bytes[3]);
+ w.Write(bytes[2]);
+ w.Write(bytes[1]);
+ w.Write(bytes[0]);
+ }
+
+ ///
+ /// Writes a png chunk.
+ ///
+ ///
+ /// The writer.
+ ///
+ ///
+ /// The chunk type.
+ ///
+ ///
+ /// The chunk data.
+ ///
+ private static void WriteChunk(BinaryWriter w, string type, byte[] data)
+ {
+ var ty = type.ToCharArray().Select(ch => (byte)ch).ToArray();
+ WriteBigEndian(w, data.Length);
+ w.Write(ty);
+ w.Write(data);
+
+ var c = 0xffffffff;
+ c = (uint)UpdateCrc(c, ty);
+ c = (uint)UpdateCrc(c, data);
+ var crc = c ^ 0xffffffff;
+
+ WriteBigEndian(w, crc);
+ }
+
+ ///
+ /// Provides a binary writer that writes to memory.
+ ///
+ private class MemoryWriter : BinaryWriter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MemoryWriter()
+ : base(new MemoryStream())
+ {
+ }
+
+ ///
+ /// Gets the content as a byte array.
+ ///
+ /// The byte array.
+ public byte[] ToArray()
+ {
+ this.BaseStream.Flush();
+ return ((MemoryStream)this.BaseStream).ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Point.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Point.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,58 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public struct Point
+ {
+ internal double x;
+
+ internal double y;
+
+ public Point(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ public double X
+ {
+ get { return x; }
+ set { x = value; }
+ }
+
+ public double Y
+ {
+ get { return y; }
+ set { y = value; }
+ }
+
+ public override string ToString()
+ {
+ return x + " " + y;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Rectangle.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Rectangle.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,36 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public struct Rectangle
+ {
+ public double Top { get; set; }
+ public double Bottom { get; set; }
+ public double Left { get; set; }
+ public double Right { get; set; }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ReflectionHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ReflectionHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,81 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides reflection based support methods.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Reflection;
+
+ ///
+ /// Provides utility methods reflection based support methods.
+ ///
+ public static class ReflectionHelper
+ {
+ ///
+ /// Fills a list by the specified property of a source list/enumerable.
+ ///
+ ///
+ /// The source list.
+ ///
+ ///
+ /// The property name.
+ ///
+ ///
+ /// The list to be filled.
+ ///
+ ///
+ /// The type of the destination list items (and the source property).
+ ///
+ public static void FillList(IEnumerable source, string propertyName, IList list)
+ {
+ PropertyInfo pi = null;
+ Type t = null;
+ foreach (var o in source)
+ {
+ if (pi == null || o.GetType() != t)
+ {
+ t = o.GetType();
+ pi = t.GetProperty(propertyName);
+ if (pi == null)
+ {
+ throw new InvalidOperationException(
+ string.Format("Could not find field {0} on type {1}", propertyName, t));
+ }
+ }
+
+ var v = pi.GetValue(o, null);
+ var value = (T)Convert.ChangeType(v, typeof(T), CultureInfo.InvariantCulture);
+ list.Add(value);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ScreenPoint.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ScreenPoint.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,198 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Describes a point defined in the screen coordinate system.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Represents a point defined in the screen coordinate system.
+ ///
+ ///
+ /// The rendering methods transforms s to s.
+ ///
+ public struct ScreenPoint
+ {
+ ///
+ /// The undefined point.
+ ///
+ public static readonly ScreenPoint Undefined = new ScreenPoint(double.NaN, double.NaN);
+
+ ///
+ /// The x-coordinate.
+ ///
+ internal double x;
+
+ ///
+ /// The y-coordinate.
+ ///
+ internal double y;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The x-coordinate.
+ ///
+ ///
+ /// The y-coordinate.
+ ///
+ public ScreenPoint(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ ///
+ /// Gets or sets the x-coordinate.
+ ///
+ /// The x-coordinate.
+ public double X
+ {
+ get
+ {
+ return this.x;
+ }
+
+ set
+ {
+ this.x = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the y-coordinate.
+ ///
+ /// The y-coordinate.
+ public double Y
+ {
+ get
+ {
+ return this.y;
+ }
+
+ set
+ {
+ this.y = value;
+ }
+ }
+
+ ///
+ /// Determines whether the specified point is undefined.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// true if the specified point is undefined; otherwise, false .
+ ///
+ public static bool IsUndefined(ScreenPoint point)
+ {
+ return double.IsNaN(point.X) && double.IsNaN(point.Y);
+ }
+
+ ///
+ /// Gets the distance to the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The distance.
+ ///
+ public double DistanceTo(ScreenPoint point)
+ {
+ double dx = point.x - this.x;
+ double dy = point.y - this.y;
+ return Math.Sqrt((dx * dx) + (dy * dy));
+ }
+
+ ///
+ /// Gets the squared distance to the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The squared distance.
+ ///
+ public double DistanceToSquared(ScreenPoint point)
+ {
+ double dx = point.x - this.x;
+ double dy = point.y - this.y;
+ return (dx * dx) + (dy * dy);
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return this.x + " " + this.y;
+ }
+
+ ///
+ /// Translates a by a .
+ ///
+ /// The point.
+ /// The vector.
+ /// The translated point.
+ public static ScreenPoint operator +(ScreenPoint p1, ScreenVector p2)
+ {
+ return new ScreenPoint(p1.x + p2.x, p1.y + p2.y);
+ }
+
+ ///
+ /// Subtracts a from a
+ /// and returns the result as a .
+ ///
+ /// The point on which to perform the subtraction.
+ /// The point to subtract from p1.
+ /// A structure that represents the difference between p1 and p2.
+ public static ScreenVector operator -(ScreenPoint p1, ScreenPoint p2)
+ {
+ return new ScreenVector(p1.x - p2.x, p1.y - p2.y);
+ }
+
+ ///
+ /// Subtracts a from a
+ /// and returns the result as a .
+ ///
+ /// The point on which to perform the subtraction.
+ /// The vector to subtract from p1.
+ /// A that represents point translated by the negative vector.
+ public static ScreenPoint operator -(ScreenPoint point, ScreenVector vector)
+ {
+ return new ScreenPoint(point.x - vector.x, point.y - vector.y);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ScreenPointHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ScreenPointHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,255 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides various algorithms for polygons and lines of ScreenPoint.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Provides algorithms for polygons and lines of .
+ ///
+ public static class ScreenPointHelper
+ {
+ ///
+ /// Finds the nearest point on the specified polyline.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The nearest point.
+ ///
+ public static ScreenPoint FindNearestPointOnPolyline(ScreenPoint point, IList points)
+ {
+ double minimumDistance = double.MaxValue;
+ var nearestPoint = default(ScreenPoint);
+
+ for (int i = 0; i + 1 < points.Count; i++)
+ {
+ var p1 = points[i];
+ var p2 = points[i + 1];
+ if (ScreenPoint.IsUndefined(p1) || ScreenPoint.IsUndefined(p2))
+ {
+ continue;
+ }
+
+ // Find the nearest point on the line segment.
+ var nearestPointOnSegment = FindPointOnLine(point, p1, p2);
+
+ if (ScreenPoint.IsUndefined(nearestPointOnSegment))
+ {
+ continue;
+ }
+
+ double l2 = (point - nearestPointOnSegment).LengthSquared;
+
+ if (l2 < minimumDistance)
+ {
+ nearestPoint = nearestPointOnSegment;
+ minimumDistance = l2;
+ }
+ }
+
+ return nearestPoint;
+ }
+
+ ///
+ /// Finds the point on line.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The first point on the line.
+ ///
+ ///
+ /// The second point on the line.
+ ///
+ ///
+ /// The nearest point on the line.
+ ///
+ ///
+ /// See Bourke.
+ ///
+ public static ScreenPoint FindPointOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
+ {
+ double dx = p2.x - p1.x;
+ double dy = p2.y - p1.y;
+ double u = FindPositionOnLine(p, p1, p2);
+
+ if (double.IsNaN(u))
+ {
+ u = 0;
+ }
+
+ if (u < 0)
+ {
+ u = 0;
+ }
+
+ if (u > 1)
+ {
+ u = 1;
+ }
+
+ return new ScreenPoint(p1.x + (u * dx), p1.y + (u * dy));
+ }
+
+ ///
+ /// Finds the nearest point on line.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The start point on the line.
+ ///
+ ///
+ /// The end point on the line.
+ ///
+ ///
+ /// The relative position of the nearest point.
+ ///
+ ///
+ /// See Bourke.
+ ///
+ public static double FindPositionOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
+ {
+ double dx = p2.x - p1.x;
+ double dy = p2.y - p1.y;
+ double u1 = ((p.x - p1.x) * dx) + ((p.y - p1.y) * dy);
+ double u2 = (dx * dx) + (dy * dy);
+
+ if (u2 < 1e-6)
+ {
+ return double.NaN;
+ }
+
+ return u1 / u2;
+ }
+
+ ///
+ /// Determines whether the specified point is in the specified polygon.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The polygon points.
+ ///
+ ///
+ /// true if the point is in the polygon; otherwise, false.
+ ///
+ public static bool IsPointInPolygon(ScreenPoint p, IList pts)
+ {
+ int nvert = pts.Count;
+ bool c = false;
+ for (int i = 0, j = nvert - 1; i < nvert; j = i++)
+ {
+ if (((pts[i].Y > p.Y) != (pts[j].Y > p.Y))
+ && (p.X < ((pts[j].X - pts[i].X) * ((p.Y - pts[i].Y) / (pts[j].Y - pts[i].Y))) + pts[i].X))
+ {
+ c = !c;
+ }
+ }
+
+ return c;
+ }
+
+ ///
+ /// Resamples the points with the specified point distance limit.
+ ///
+ ///
+ /// All points.
+ ///
+ ///
+ /// The minimum squared distance.
+ ///
+ ///
+ /// List of resampled points.
+ ///
+ public static IList ResamplePoints(IList allPoints, double minimumDistance)
+ {
+ double minimumSquaredDistance = minimumDistance * minimumDistance;
+ int n = allPoints.Count;
+ var result = new List(n);
+ if (n > 0)
+ {
+ result.Add(allPoints[0]);
+ int i0 = 0;
+ for (int i = 1; i < n; i++)
+ {
+ double distSquared = allPoints[i0].DistanceToSquared(allPoints[i]);
+ if (distSquared < minimumSquaredDistance && i != n - 1)
+ {
+ continue;
+ }
+
+ i0 = i;
+ result.Add(allPoints[i]);
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// Gets the centroid of the specified polygon.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The centroid.
+ ///
+ public static ScreenPoint GetCentroid(IList points)
+ {
+ double cx = 0;
+ double cy = 0;
+ double a = 0;
+
+ for (int i = 0; i < points.Count; i++)
+ {
+ int i1 = (i + 1) % points.Count;
+ double da = (points[i].x * points[i1].y) - (points[i1].x * points[i].y);
+ cx += (points[i].x + points[i1].x) * da;
+ cy += (points[i].y + points[i1].y) * da;
+ a += da;
+ }
+
+ a *= 0.5;
+ cx /= 6 * a;
+ cy /= 6 * a;
+ return new ScreenPoint(cx, cy);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/ScreenVector.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/ScreenVector.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,155 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a vector defined in the screen coordinate system.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Represents a vector defined in the screen coordinate system.
+ ///
+ public struct ScreenVector
+ {
+ ///
+ /// The x-coordinate.
+ ///
+ internal double x;
+
+ ///
+ /// The y-coordinate.
+ ///
+ internal double y;
+
+ ///
+ /// Initializes a new instance of the structure.
+ ///
+ ///
+ /// The x-coordinate.
+ ///
+ ///
+ /// The y-coordinate.
+ ///
+ public ScreenVector(double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ ///
+ /// Gets the length.
+ ///
+ public double Length
+ {
+ get
+ {
+ return Math.Sqrt((this.x * this.x) + (this.y * this.y));
+ }
+ }
+
+ ///
+ /// Gets the length squared.
+ ///
+ public double LengthSquared
+ {
+ get
+ {
+ return (this.x * this.x) + (this.y * this.y);
+ }
+ }
+
+ ///
+ /// Gets or sets the x-coordinate.
+ ///
+ /// The x-coordinate.
+ public double X
+ {
+ get
+ {
+ return this.x;
+ }
+
+ set
+ {
+ this.x = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the y-coordinate.
+ ///
+ /// The y-coordinate.
+ public double Y
+ {
+ get
+ {
+ return this.y;
+ }
+
+ set
+ {
+ this.y = value;
+ }
+ }
+
+ ///
+ /// Normalizes this vector.
+ ///
+ public void Normalize()
+ {
+ double l = Math.Sqrt((this.x * this.x) + (this.y * this.y));
+ if (l > 0)
+ {
+ this.x /= l;
+ this.y /= l;
+ }
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return this.x + " " + this.y;
+ }
+
+ ///
+ /// Implements the operator *.
+ ///
+ /// The vector.
+ /// The multiplication factor.
+ /// The result of the operator.
+ public static ScreenVector operator *(ScreenVector v, double d)
+ {
+ return new ScreenVector(v.x * d, v.y * d);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/Size.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/Size.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,43 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public struct Size
+ {
+ public double Width { get; set; }
+ public double Height { get; set; }
+
+ public static Size Empty = new Size(0,0);
+
+ public Size(double width, double height)
+ : this()
+ {
+ this.Width = width;
+ this.Height = height;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/StreamExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/StreamExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,25 @@
+namespace OxyPlot
+{
+ using System.IO;
+
+ ///
+ /// Implements extension methods.
+ ///
+ public static class StreamExtensions
+ {
+ ///
+ /// Copies to the specified stream.
+ ///
+ /// The input stream.
+ /// The output stream.
+ public static void CopyTo(this Stream input, Stream output)
+ {
+ var buffer = new byte[32768];
+ int read;
+ while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer, 0, read);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/StringHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/StringHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,169 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides support for string formatting.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections;
+ using System.Text;
+ using System.Text.RegularExpressions;
+
+ ///
+ /// Provides extended string formatting functionality.
+ ///
+ public static class StringHelper
+ {
+ ///
+ /// The formatting expression.
+ ///
+ private static readonly Regex FormattingExpression = new Regex("{(?.+?)(?\\:.*?)?}");
+
+ ///
+ /// Replaces the format items in the specified string.
+ ///
+ ///
+ /// The culture specific format provider.
+ ///
+ ///
+ /// The format string.
+ ///
+ ///
+ /// The item.
+ ///
+ ///
+ /// The values.
+ ///
+ ///
+ /// The formatString and values works as in string.Format. In addition, you can format properties of the item object by using the syntax {PropertyName:Formatstring}. E.g. if you have a "Value" property in your item's class, use "{Value:0.00}" to output the value with two digits. Note that this formatting is using reflection and does not have the same performance as string.Format.
+ ///
+ ///
+ /// The formatted string.
+ ///
+ public static string Format(IFormatProvider provider, string formatString, object item, params object[] values)
+ {
+ // Replace items on the format {Property[:Formatstring]}
+ var s = FormattingExpression.Replace(
+ formatString,
+ delegate(Match match)
+ {
+ var property = match.Groups["Property"].Value;
+ if (property.Length > 0 && char.IsDigit(property[0]))
+ {
+ return match.Value;
+ }
+
+ var pi = item.GetType().GetProperty(property);
+ if (pi == null)
+ {
+ return string.Empty;
+ }
+
+ var v = pi.GetValue(item, null);
+ var format = match.Groups["Format"].Value;
+
+ var fs = "{0" + format + "}";
+ return string.Format(provider, fs, v);
+ });
+
+ // Also apply the standard formatting
+ s = string.Format(provider, s, values);
+ return s;
+ }
+
+ ///
+ /// Creates a valid file name.
+ ///
+ ///
+ /// The title.
+ ///
+ ///
+ /// The extension.
+ ///
+ ///
+ /// A file name.
+ ///
+ public static string CreateValidFileName(string title, string extension)
+ {
+ string validFileName = title.Trim();
+ var invalidFileNameChars = "/?<>\\:*|\0\t\r\n".ToCharArray();
+ foreach (char invalChar in invalidFileNameChars)
+ {
+ validFileName = validFileName.Replace(invalChar.ToString(), string.Empty);
+ }
+
+ foreach (char invalChar in invalidFileNameChars)
+ {
+ validFileName = validFileName.Replace(invalChar.ToString(), string.Empty);
+ }
+
+ if (validFileName.Length > 160)
+ {
+ // safe value threshold is 260
+ validFileName = validFileName.Remove(156) + "...";
+ }
+
+ return validFileName + extension;
+ }
+
+ ///
+ /// Creates a string from a collection of items.
+ ///
+ ///
+ /// The provider.
+ ///
+ ///
+ /// The items.
+ ///
+ ///
+ /// The format string to apply to each item.
+ ///
+ ///
+ /// The separator.
+ ///
+ ///
+ /// The collection as a string.
+ ///
+ public static object CreateList(
+ IFormatProvider provider, IEnumerable items, string formatstring, string separator = ", ")
+ {
+ var sb = new StringBuilder();
+ foreach (var item in items)
+ {
+ if (sb.Length > 0)
+ {
+ sb.Append(separator);
+ }
+
+ sb.Append(string.Format(provider, formatstring, item));
+ }
+
+ return sb.ToString();
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/SutherlandHodgmanClipping.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/SutherlandHodgmanClipping.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,233 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Polygon clipping by the sutherland-hodgman algortihm.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Provides polygon clipping by the Sutherland-Hodgman algortihm.
+ ///
+ public static class SutherlandHodgmanClipping
+ {
+ ///
+ /// The rectangle edge.
+ ///
+ private enum RectangleEdge
+ {
+ ///
+ /// The left.
+ ///
+ Left,
+
+ ///
+ /// The right.
+ ///
+ Right,
+
+ ///
+ /// The top.
+ ///
+ Top,
+
+ ///
+ /// The bottom.
+ ///
+ Bottom
+ }
+
+ ///
+ /// The Sutherland-Hodgman polygon clipping algorithm.
+ ///
+ ///
+ /// See http://ezekiel.vancouver.wsu.edu/~cs442/lectures/clip/clip/index.html
+ ///
+ ///
+ /// The bounds.
+ ///
+ ///
+ /// The polygon points.
+ ///
+ ///
+ /// The clipped points.
+ ///
+ public static List ClipPolygon(OxyRect bounds, IList v)
+ {
+ List p1 = ClipOneAxis(bounds, RectangleEdge.Left, v);
+ List p2 = ClipOneAxis(bounds, RectangleEdge.Right, p1);
+ List p3 = ClipOneAxis(bounds, RectangleEdge.Top, p2);
+ return ClipOneAxis(bounds, RectangleEdge.Bottom, p3);
+ }
+
+ ///
+ /// Clips to one axis.
+ ///
+ ///
+ /// The bounds.
+ ///
+ ///
+ /// The edge.
+ ///
+ ///
+ /// The points of the polygon.
+ ///
+ ///
+ /// The clipped points.
+ ///
+ private static List ClipOneAxis(OxyRect bounds, RectangleEdge edge, IList v)
+ {
+ if (v.Count == 0)
+ {
+ return new List();
+ }
+
+ var polygon = new List(v.Count);
+
+ var s = v[v.Count - 1];
+
+ for (int i = 0; i < v.Count; ++i)
+ {
+ var p = v[i];
+ bool pin = IsInside(bounds, edge, p);
+ bool sin = IsInside(bounds, edge, s);
+
+ if (sin && pin)
+ {
+ // case 1: inside -> inside
+ polygon.Add(p);
+ }
+ else if (sin)
+ {
+ // case 2: inside -> outside
+ polygon.Add(LineIntercept(bounds, edge, s, p));
+ }
+ else if (!pin)
+ {
+ // case 3: outside -> outside
+ // emit nothing
+ }
+ else
+ {
+ // case 4: outside -> inside
+ polygon.Add(LineIntercept(bounds, edge, s, p));
+ polygon.Add(p);
+ }
+
+ s = p;
+ }
+
+ return polygon;
+ }
+
+ ///
+ /// Determines whether the specified point is inside the edge/bounds.
+ ///
+ /// The bounds.
+ /// The edge to test.
+ /// The point.
+ ///
+ /// true if the specified point is inside; otherwise, false.
+ ///
+ private static bool IsInside(OxyRect bounds, RectangleEdge edge, ScreenPoint p)
+ {
+ switch (edge)
+ {
+ case RectangleEdge.Left:
+ return !(p.X < bounds.Left);
+
+ case RectangleEdge.Right:
+ return !(p.X >= bounds.Right);
+
+ case RectangleEdge.Top:
+ return !(p.Y < bounds.Top);
+
+ case RectangleEdge.Bottom:
+ return !(p.Y >= bounds.Bottom);
+
+ default:
+ throw new ArgumentException("edge");
+ }
+ }
+
+ ///
+ /// Fines the edge interception.
+ ///
+ /// The bounds.
+ /// The edge.
+ /// The first point.
+ /// The second point.
+ /// The interception.
+ private static ScreenPoint LineIntercept(OxyRect bounds, RectangleEdge edge, ScreenPoint a, ScreenPoint b)
+ {
+ if (a.x == b.x && a.y == b.y)
+ {
+ return a;
+ }
+
+ switch (edge)
+ {
+ case RectangleEdge.Bottom:
+ if (b.Y == a.Y)
+ {
+ throw new ArgumentException("no intercept found");
+ }
+
+ return new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Bottom - a.Y)) / (b.Y - a.Y)), bounds.Bottom);
+
+ case RectangleEdge.Left:
+ if (b.X == a.X)
+ {
+ throw new ArgumentException("no intercept found");
+ }
+
+ return new ScreenPoint(bounds.Left, a.Y + (((b.Y - a.Y) * (bounds.Left - a.X)) / (b.X - a.X)));
+
+ case RectangleEdge.Right:
+ if (b.X == a.X)
+ {
+ throw new ArgumentException("no intercept found");
+ }
+
+ return new ScreenPoint(bounds.Right, a.Y + (((b.Y - a.Y) * (bounds.Right - a.X)) / (b.X - a.X)));
+
+ case RectangleEdge.Top:
+ if (b.Y == a.Y)
+ {
+ throw new ArgumentException("no intercept found");
+ }
+
+ return new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Top - a.Y)) / (b.Y - a.Y)), bounds.Top);
+ }
+
+ throw new ArgumentException("no intercept found");
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/VerticalAlignment.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/VerticalAlignment.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,52 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Vertical text alignment.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies the vertical alignment.
+ ///
+ public enum VerticalAlignment
+ {
+ ///
+ /// Aligned at the top.
+ ///
+ Top = -1,
+
+ ///
+ /// Aligned in the middle.
+ ///
+ Middle = 0,
+
+ ///
+ /// Aligned at the bottom.
+ ///
+ Bottom = 1
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Foundation/XmlWriterBase.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Foundation/XmlWriterBase.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,233 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Abstract base class for exporters that write xml.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.IO;
+ using System.Text;
+ using System.Xml;
+
+ ///
+ /// Provides an abstract base class for exporters that write xml.
+ ///
+ public abstract class XmlWriterBase : IDisposable
+ {
+ ///
+ /// The xml writer.
+ ///
+ private XmlWriter w;
+
+ ///
+ /// The disposed flag.
+ ///
+ private bool disposed;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected XmlWriterBase()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The stream.
+ ///
+ protected XmlWriterBase(Stream stream)
+ {
+ this.w = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 });
+ }
+
+ ///
+ /// Closes this instance.
+ ///
+ public virtual void Close()
+ {
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Flushes this instance.
+ ///
+ public void Flush()
+ {
+ this.w.Flush();
+ }
+
+ ///
+ /// The write attribute string.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// The value.
+ ///
+ protected void WriteAttributeString(string name, string value)
+ {
+ this.w.WriteAttributeString(name, value);
+ }
+
+ ///
+ /// The write doc type.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// The pubid.
+ ///
+ ///
+ /// The sysid.
+ ///
+ ///
+ /// The subset.
+ ///
+ protected void WriteDocType(string name, string pubid, string sysid, string subset)
+ {
+ this.w.WriteDocType(name, pubid, sysid, subset);
+ }
+
+ ///
+ /// The write element string.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// The text.
+ ///
+ protected void WriteElementString(string name, string text)
+ {
+ this.w.WriteElementString(name, text);
+ }
+
+ ///
+ /// The write end document.
+ ///
+ protected void WriteEndDocument()
+ {
+ this.w.WriteEndDocument();
+ }
+
+ ///
+ /// The write end element.
+ ///
+ protected void WriteEndElement()
+ {
+ this.w.WriteEndElement();
+ }
+
+ ///
+ /// The write raw.
+ ///
+ ///
+ /// The text.
+ ///
+ protected void WriteRaw(string text)
+ {
+ this.w.WriteRaw(text);
+ }
+
+ ///
+ /// The write start document.
+ ///
+ ///
+ /// The standalone.
+ ///
+ protected void WriteStartDocument(bool standalone)
+ {
+ this.w.WriteStartDocument(standalone);
+ }
+
+ ///
+ /// The write start element.
+ ///
+ ///
+ /// The name.
+ ///
+ protected void WriteStartElement(string name)
+ {
+ this.w.WriteStartElement(name);
+ }
+
+ ///
+ /// The write start element.
+ ///
+ ///
+ /// The name.
+ ///
+ ///
+ /// The ns.
+ ///
+ protected void WriteStartElement(string name, string ns)
+ {
+ this.w.WriteStartElement(name, ns);
+ }
+
+ ///
+ /// The write string.
+ ///
+ ///
+ /// The text.
+ ///
+ protected void WriteString(string text)
+ {
+ this.w.WriteString(text);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ private void Dispose(bool disposing)
+ {
+ if (!this.disposed)
+ {
+ if (disposing)
+ {
+ this.Close();
+ }
+ }
+
+ this.disposed = true;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/LibraryDoc.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/LibraryDoc.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,37 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ ///
+ /// The OxyPlot solution provides plotting functionality on many platforms.
+ ///
+ [System.Runtime.CompilerServices.CompilerGenerated]
+ internal class LibraryDoc
+ {
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/CursorType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/CursorType.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,62 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Specifies the cursor type.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies the cursor type.
+ ///
+ public enum CursorType
+ {
+ ///
+ /// The default cursor
+ ///
+ Default = 0,
+
+ ///
+ /// The pan cursor
+ ///
+ Pan,
+
+ ///
+ /// The zoom rectangle cursor
+ ///
+ ZoomRectangle,
+
+ ///
+ /// The horizontal zoom cursor
+ ///
+ ZoomHorizontal,
+
+ ///
+ /// The vertical zoom cursor
+ ///
+ ZoomVertical
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/IPlotControl.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/IPlotControl.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,176 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Interface for Plot controls.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using OxyPlot.Annotations;
+ using OxyPlot.Axes;
+ using OxyPlot.Series;
+
+ ///
+ /// Defines functionality in the Plot controls.
+ ///
+ public interface IPlotControl
+ {
+ ///
+ /// Gets the actual model.
+ ///
+ /// The actual model.
+ PlotModel ActualModel { get; }
+
+ ///
+ /// Gets the axes from a point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The x-axis.
+ ///
+ ///
+ /// The y-axis.
+ ///
+ void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis);
+
+ ///
+ /// Gets the series from point.
+ ///
+ ///
+ /// The point (screen coordinates).
+ ///
+ ///
+ /// The maximum allowed distance.
+ ///
+ ///
+ /// The series.
+ ///
+ Series.Series GetSeriesFromPoint(ScreenPoint pt, double limit = 100);
+
+ ///
+ /// Hides the tracker.
+ ///
+ void HideTracker();
+
+ ///
+ /// Hides the zoom rectangle.
+ ///
+ void HideZoomRectangle();
+
+ ///
+ /// Invalidate the plot (not blocking the UI thread)
+ ///
+ ///
+ /// if set to true, all data collections will be updated.
+ ///
+ void InvalidatePlot(bool updateData = true);
+
+ ///
+ /// Pans the specified axis.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The previous point (screen coordinates).
+ ///
+ ///
+ /// The current point (screen coordinates).
+ ///
+ void Pan(Axis axis, ScreenPoint ppt, ScreenPoint cpt);
+
+ ///
+ /// Refresh the plot immediately (blocking UI thread)
+ ///
+ ///
+ /// if set to true, all data collections will be updated.
+ ///
+ void RefreshPlot(bool updateData = true);
+
+ ///
+ /// Resets the specified axis.
+ ///
+ ///
+ /// The axis.
+ ///
+ void Reset(Axis axis);
+
+ ///
+ /// Sets the cursor type.
+ ///
+ ///
+ /// The cursor type.
+ ///
+ void SetCursorType(CursorType cursorType);
+
+ ///
+ /// Shows the tracker.
+ ///
+ ///
+ /// The tracker data.
+ ///
+ void ShowTracker(TrackerHitResult trackerHitResult);
+
+ ///
+ /// Shows the zoom rectangle.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ void ShowZoomRectangle(OxyRect r);
+
+ ///
+ /// Zooms the specified axis to the specified values.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The new minimum value.
+ ///
+ ///
+ /// The new maximum value.
+ ///
+ void Zoom(Axis axis, double p1, double p2);
+
+ ///
+ /// Zooms at the specified position.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The zoom factor.
+ ///
+ ///
+ /// The position to zoom at.
+ ///
+ void ZoomAt(Axis axis, double factor, double x);
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ManipulationEventArgs.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ManipulationEventArgs.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,67 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides data for the manipulation events.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides data for the manipulation events.
+ ///
+ public class ManipulationEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The current position.
+ ///
+ public ManipulationEventArgs(ScreenPoint currentPosition)
+ {
+ this.CurrentPosition = currentPosition;
+ }
+
+ ///
+ /// Gets the current position.
+ ///
+ /// The current position.
+ public ScreenPoint CurrentPosition { get; private set; }
+
+ ///
+ /// Gets or sets the X scaling factor.
+ ///
+ /// The scale value.
+ public double ScaleX { get; set; }
+
+ ///
+ /// Gets or sets the Y scaling factor.
+ ///
+ /// The scale value.
+ public double ScaleY { get; set; }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ManipulatorBase.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ManipulatorBase.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,151 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The manipulator base.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using OxyPlot.Axes;
+
+ ///
+ /// Provides an absract base class for plot control manipulators.
+ ///
+ public class ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ protected ManipulatorBase(IPlotControl plotControl)
+ {
+ this.PlotControl = plotControl;
+ }
+
+ ///
+ /// Gets the first position of the manipulation.
+ ///
+ public ScreenPoint StartPosition { get; private set; }
+
+ ///
+ /// Gets the plot control.
+ ///
+ protected IPlotControl PlotControl { get; private set; }
+
+ ///
+ /// Gets or sets the X axis.
+ ///
+ /// The X axis.
+ protected Axis XAxis { get; set; }
+
+ ///
+ /// Gets or sets the Y axis.
+ ///
+ /// The Y axis.
+ protected Axis YAxis { get; set; }
+
+ ///
+ /// Occurs when a manipulation is complete.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public virtual void Completed(ManipulationEventArgs e)
+ {
+ this.PlotControl.SetCursorType(CursorType.Default);
+ }
+
+ ///
+ /// Occurs when the input device changes position during a manipulation.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public virtual void Delta(ManipulationEventArgs e)
+ {
+ }
+
+ ///
+ /// Gets the cursor for the manipulation.
+ ///
+ ///
+ /// The cursor.
+ ///
+ public virtual CursorType GetCursorType()
+ {
+ return CursorType.Default;
+ }
+
+ ///
+ /// Occurs when an input device begins a manipulation on the plot.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public virtual void Started(ManipulationEventArgs e)
+ {
+ Axis xaxis;
+ Axis yaxis;
+ this.PlotControl.GetAxesFromPoint(e.CurrentPosition, out xaxis, out yaxis);
+ this.StartPosition = e.CurrentPosition;
+
+ this.XAxis = xaxis;
+ this.YAxis = yaxis;
+
+ this.PlotControl.SetCursorType(this.GetCursorType());
+ }
+
+ ///
+ /// Transforms a point from screen coordinates to data coordinates.
+ ///
+ ///
+ /// The x coordinate.
+ ///
+ ///
+ /// The y coordinate.
+ ///
+ ///
+ /// A data point.
+ ///
+ protected DataPoint InverseTransform(double x, double y)
+ {
+ if (this.XAxis != null)
+ {
+ return this.XAxis.InverseTransform(x, y, this.YAxis);
+ }
+
+ if (this.YAxis != null)
+ {
+ return new DataPoint(0, this.YAxis.InverseTransform(y));
+ }
+
+ return new DataPoint();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/PanManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/PanManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,100 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The pan manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a plot control manipulator for panning functionality.
+ ///
+ public class PanManipulator : ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ public PanManipulator(IPlotControl plotControl)
+ : base(plotControl)
+ {
+ }
+
+ ///
+ /// Gets or sets the previous position.
+ ///
+ private ScreenPoint PreviousPosition { get; set; }
+
+ ///
+ /// Occurs when the input device changes position during a manipulation.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Delta(ManipulationEventArgs e)
+ {
+ base.Delta(e);
+ if (this.XAxis != null)
+ {
+ this.PlotControl.Pan(this.XAxis, this.PreviousPosition, e.CurrentPosition);
+ }
+
+ if (this.YAxis != null)
+ {
+ this.PlotControl.Pan(this.YAxis, this.PreviousPosition, e.CurrentPosition);
+ }
+
+ this.PlotControl.RefreshPlot(false);
+ this.PreviousPosition = e.CurrentPosition;
+ }
+
+ ///
+ /// Gets the cursor for the manipulation.
+ ///
+ ///
+ /// The cursor.
+ ///
+ public override CursorType GetCursorType()
+ {
+ return CursorType.Pan;
+ }
+
+ ///
+ /// Occurs when an input device begins a manipulation on the plot.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Started(ManipulationEventArgs e)
+ {
+ base.Started(e);
+ this.PreviousPosition = e.CurrentPosition;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ResetManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ResetManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,71 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The reset manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a plot control manipulator for reset functionality.
+ ///
+ public class ResetManipulator : ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ public ResetManipulator(IPlotControl plotControl)
+ : base(plotControl)
+ {
+ }
+
+ ///
+ /// Occurs when an input device begins a manipulation on the plot.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Started(ManipulationEventArgs e)
+ {
+ base.Started(e);
+ if (this.XAxis != null)
+ {
+ this.PlotControl.Reset(this.XAxis);
+ }
+
+ if (this.YAxis != null)
+ {
+ this.PlotControl.Reset(this.YAxis);
+ }
+
+ this.PlotControl.InvalidatePlot();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/TrackerHitResult.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/TrackerHitResult.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,162 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Provides a data container for a tracker hit result.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using OxyPlot.Series;
+
+ ///
+ /// Provides a data container for a tracker hit result.
+ ///
+ ///
+ /// This is used as DataContext for the TrackerControl.
+ /// The TrackerControl is visible when the user use the left mouse button to "track" points on the series.
+ ///
+ public class TrackerHitResult
+ {
+ ///
+ /// The default format string.
+ ///
+ private const string DefaultFormatString = "{0}\n{1}: {2}\n{3}: {4}";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The series.
+ /// The data point.
+ /// The screen point.
+ /// The item.
+ /// The index.
+ /// The text.
+ public TrackerHitResult(OxyPlot.Series.Series series, IDataPoint dp, ScreenPoint sp, object item = null, double index = -1, string text = null)
+ {
+ this.DataPoint = dp;
+ this.Position = sp;
+ this.Item = item;
+ this.Index = index;
+ this.Series = series;
+ this.Text = text;
+ var ds = series as DataPointSeries;
+ if (ds != null)
+ {
+ this.XAxis = ds.XAxis;
+ this.YAxis = ds.YAxis;
+ }
+ }
+
+ ///
+ /// Gets or sets the nearest or interpolated data point.
+ ///
+ public IDataPoint DataPoint { get; set; }
+
+ ///
+ /// Gets or sets the source item of the point.
+ /// If the current point is from an ItemsSource and is not interpolated, this property will contain the item.
+ ///
+ public object Item { get; set; }
+
+ ///
+ /// Gets or sets the index for the Item.
+ ///
+ public double Index { get; set; }
+
+ ///
+ /// Gets or sets the horizontal/vertical line extents.
+ ///
+ public OxyRect LineExtents { get; set; }
+
+ ///
+ /// Gets or sets the plot model.
+ ///
+ public PlotModel PlotModel { get; set; }
+
+ ///
+ /// Gets or sets the position in screen coordinates.
+ ///
+ public ScreenPoint Position { get; set; }
+
+ ///
+ /// Gets or sets the series that is being tracked.
+ ///
+ public Series.Series Series { get; set; }
+
+ ///
+ /// Gets or sets the text shown in the tracker.
+ ///
+ public string Text { get; set; }
+
+ ///
+ /// Gets or sets the X axis.
+ ///
+ public Axes.Axis XAxis { get; set; }
+
+ ///
+ /// Gets or sets the Y axis.
+ ///
+ public Axes.Axis YAxis { get; set; }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ if (this.Text != null)
+ {
+ return this.Text;
+ }
+
+ var ts = this.Series as ITrackableSeries;
+ string formatString = DefaultFormatString;
+ if (ts != null && !string.IsNullOrEmpty(ts.TrackerFormatString))
+ {
+ formatString = ts.TrackerFormatString;
+ }
+
+ string xaxisTitle = (this.XAxis != null ? this.XAxis.Title : null) ?? "X";
+ string yaxisTitle = (this.YAxis != null ? this.YAxis.Title : null) ?? "Y";
+ object xvalue = this.XAxis != null ? this.XAxis.GetValue(this.DataPoint.X) : this.DataPoint.X;
+ object yvalue = this.YAxis != null ? this.YAxis.GetValue(this.DataPoint.Y) : this.DataPoint.Y;
+
+ return StringHelper.Format(
+ this.Series.ActualCulture,
+ formatString,
+ this.Item,
+ this.Series.Title,
+ xaxisTitle,
+ xvalue,
+ yaxisTitle,
+ yvalue,
+ this.Item).Trim();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/TrackerManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/TrackerManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,186 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The tracker manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using OxyPlot.Series;
+
+ ///
+ /// Provides a plot control manipulator for tracker functionality.
+ ///
+ public class TrackerManipulator : ManipulatorBase
+ {
+ ///
+ /// The current series.
+ ///
+ private ITrackableSeries currentSeries;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ public TrackerManipulator(IPlotControl plotControl)
+ : base(plotControl)
+ {
+ this.Snap = true;
+ this.PointsOnly = false;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether to show tracker on points only (not interpolating).
+ ///
+ public bool PointsOnly { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to snap to the nearest point.
+ ///
+ public bool Snap { get; set; }
+
+ ///
+ /// Occurs when a manipulation is complete.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Completed(ManipulationEventArgs e)
+ {
+ base.Completed(e);
+
+ if (this.currentSeries == null)
+ {
+ return;
+ }
+
+ this.currentSeries = null;
+ this.PlotControl.HideTracker();
+ }
+
+ ///
+ /// Occurs when the input device changes position during a manipulation.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Delta(ManipulationEventArgs e)
+ {
+ base.Delta(e);
+ if (this.currentSeries == null)
+ {
+ return;
+ }
+
+ if (!this.PlotControl.ActualModel.PlotArea.Contains(e.CurrentPosition.X, e.CurrentPosition.Y))
+ {
+ return;
+ }
+
+ TrackerHitResult result = GetNearestHit(this.currentSeries, e.CurrentPosition, this.Snap, this.PointsOnly);
+ if (result != null)
+ {
+ result.PlotModel = this.PlotControl.ActualModel;
+ this.PlotControl.ShowTracker(result);
+ }
+ }
+
+ ///
+ /// Gets the cursor for the manipulation.
+ ///
+ ///
+ /// The cursor.
+ ///
+ public override CursorType GetCursorType()
+ {
+ return CursorType.Default;
+ }
+
+ ///
+ /// Occurs when an input device begins a manipulation on the plot.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Started(ManipulationEventArgs e)
+ {
+ base.Started(e);
+ this.currentSeries = this.PlotControl.GetSeriesFromPoint(e.CurrentPosition);
+ this.Delta(e);
+ }
+
+ ///
+ /// Gets the nearest tracker hit.
+ ///
+ ///
+ /// The series.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// Snap to points.
+ ///
+ ///
+ /// Check points only (no interpolation).
+ ///
+ ///
+ /// A tracker hit result.
+ ///
+ private static TrackerHitResult GetNearestHit(ITrackableSeries s, ScreenPoint point, bool snap, bool pointsOnly)
+ {
+ if (s == null)
+ {
+ return null;
+ }
+
+ // Check data points only
+ if (snap || pointsOnly)
+ {
+ TrackerHitResult result = s.GetNearestPoint(point, false);
+ if (result != null)
+ {
+ if (result.Position.DistanceTo(point) < 20)
+ {
+ return result;
+ }
+ }
+ }
+
+ // Check between data points (if possible)
+ if (!pointsOnly)
+ {
+ TrackerHitResult result = s.GetNearestPoint(point, true);
+ return result;
+ }
+
+ return null;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ZoomManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,72 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The zoom manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a plot control manipulator for zoom functionality.
+ ///
+ public class ZoomManipulator : ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ public ZoomManipulator(IPlotControl plotControl)
+ : base(plotControl)
+ {
+ }
+
+ ///
+ /// Occurs when the input device changes position during a manipulation.
+ ///
+ /// The instance containing the event data.
+ public override void Delta(ManipulationEventArgs e)
+ {
+ base.Delta(e);
+
+ DataPoint current = this.InverseTransform(e.CurrentPosition.X, e.CurrentPosition.Y);
+
+ if (this.XAxis != null)
+ {
+ this.PlotControl.ZoomAt(this.XAxis, e.ScaleX, current.X);
+ }
+
+ if (this.YAxis != null)
+ {
+ this.PlotControl.ZoomAt(this.YAxis, e.ScaleY, current.Y);
+ }
+
+ this.PlotControl.InvalidatePlot();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ZoomRectangleManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomRectangleManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,154 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The zoom manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides a plot control manipulator for zoom by rectangle functionality.
+ ///
+ public class ZoomRectangleManipulator : ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ public ZoomRectangleManipulator(IPlotControl plotControl)
+ : base(plotControl)
+ {
+ }
+
+ ///
+ /// Gets or sets the zoom rectangle.
+ ///
+ private OxyRect ZoomRectangle { get; set; }
+
+ ///
+ /// Occurs when a manipulation is complete.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Completed(ManipulationEventArgs e)
+ {
+ base.Completed(e);
+
+ this.PlotControl.HideZoomRectangle();
+
+ if (this.ZoomRectangle.Width > 10 && this.ZoomRectangle.Height > 10)
+ {
+ DataPoint p0 = this.InverseTransform(this.ZoomRectangle.Left, this.ZoomRectangle.Top);
+ DataPoint p1 = this.InverseTransform(this.ZoomRectangle.Right, this.ZoomRectangle.Bottom);
+
+ if (this.XAxis != null)
+ {
+ this.PlotControl.Zoom(this.XAxis, p0.X, p1.X);
+ }
+
+ if (this.YAxis != null)
+ {
+ this.PlotControl.Zoom(this.YAxis, p0.Y, p1.Y);
+ }
+
+ this.PlotControl.InvalidatePlot();
+ }
+ }
+
+ ///
+ /// Occurs when the input device changes position during a manipulation.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Delta(ManipulationEventArgs e)
+ {
+ base.Delta(e);
+
+ OxyRect plotArea = this.PlotControl.ActualModel.PlotArea;
+
+ double x = Math.Min(this.StartPosition.X, e.CurrentPosition.X);
+ double w = Math.Abs(this.StartPosition.X - e.CurrentPosition.X);
+ double y = Math.Min(this.StartPosition.Y, e.CurrentPosition.Y);
+ double h = Math.Abs(this.StartPosition.Y - e.CurrentPosition.Y);
+
+ if (this.XAxis == null)
+ {
+ x = plotArea.Left;
+ w = plotArea.Width;
+ }
+
+ if (this.YAxis == null)
+ {
+ y = plotArea.Top;
+ h = plotArea.Height;
+ }
+
+ this.ZoomRectangle = new OxyRect(x, y, w, h);
+ this.PlotControl.ShowZoomRectangle(this.ZoomRectangle);
+ }
+
+ ///
+ /// Gets the cursor for the manipulation.
+ ///
+ ///
+ /// The cursor.
+ ///
+ public override CursorType GetCursorType()
+ {
+ if (this.XAxis == null)
+ {
+ return CursorType.ZoomVertical;
+ }
+
+ if (this.YAxis == null)
+ {
+ return CursorType.ZoomHorizontal;
+ }
+
+ return CursorType.ZoomRectangle;
+ }
+
+ ///
+ /// Occurs when an input device begins a manipulation on the plot.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public override void Started(ManipulationEventArgs e)
+ {
+ base.Started(e);
+ this.ZoomRectangle = new OxyRect(this.StartPosition.X, this.StartPosition.Y, 0, 0);
+ this.PlotControl.ShowZoomRectangle(this.ZoomRectangle);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Manipulators/ZoomStepManipulator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomStepManipulator.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,106 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The step manipulator.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Provides a plot control manipulator for stepwise zoom functionality.
+ ///
+ public class ZoomStepManipulator : ManipulatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The plot control.
+ ///
+ ///
+ /// The step.
+ ///
+ ///
+ /// The fine Control.
+ ///
+ public ZoomStepManipulator(IPlotControl plotControl, double step, bool fineControl)
+ : base(plotControl)
+ {
+ this.Step = step;
+ this.FineControl = fineControl;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether FineControl.
+ ///
+ public bool FineControl { get; set; }
+
+ ///
+ /// Gets or sets Step.
+ ///
+ public double Step { get; set; }
+
+ ///
+ /// The started.
+ ///
+ ///
+ /// The e.
+ ///
+ public override void Started(ManipulationEventArgs e)
+ {
+ base.Started(e);
+
+ DataPoint current = this.InverseTransform(e.CurrentPosition.X, e.CurrentPosition.Y);
+
+ double scale = this.Step;
+ if (this.FineControl)
+ {
+ scale *= 3;
+ }
+
+ scale = 1 + scale;
+
+ // make sure the zoom factor is not negative
+ if (scale < 0.1)
+ {
+ scale = 0.1;
+ }
+
+ if (this.XAxis != null)
+ {
+ this.PlotControl.ZoomAt(this.XAxis, scale, current.X);
+ }
+
+ if (this.YAxis != null)
+ {
+ this.PlotControl.ZoomAt(this.YAxis, scale, current.Y);
+ }
+
+ this.PlotControl.InvalidatePlot();
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/MouseActions/MouseAction.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/MouseActions/MouseAction.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,54 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ public abstract class MouseAction : IMouseAction
+ {
+ protected IPlotControl pc;
+
+ protected MouseAction(IPlotControl pc)
+ {
+ this.pc = pc;
+ }
+
+ public virtual void OnMouseDown(ScreenPoint pt, OxyMouseButton button, int clickCount, bool control, bool shift, bool alt)
+ {
+ }
+
+ public virtual void OnMouseMove(ScreenPoint pt, bool control, bool shift, bool alt)
+ {
+ }
+
+ public virtual void OnMouseUp()
+ {
+ }
+
+ public virtual void OnMouseWheel(ScreenPoint pt, double delta, bool control, bool shift, bool alt)
+ {
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/MouseActions/SliderAction.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/MouseActions/SliderAction.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,106 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ // todo: use screen coordinates instead of original points (problem on log axes)
+ public class SliderAction : MouseAction
+ {
+ public SliderAction(IPlot pc)
+ : base(pc)
+ {
+ }
+
+ private DataSeries currentSeries;
+
+ public override void OnMouseDown(ScreenPoint pt, OxyMouseButton button, int clickCount, bool control, bool shift)
+ {
+ base.OnMouseDown(pt, button, clickCount, control, shift);
+
+ if (button != OxyMouseButton.Left)
+ return;
+
+ // Middle button double click adds an annotation
+ if (clickCount == 2)
+ {
+ // pc.Annotations.
+ pc.Refresh();
+ }
+
+ currentSeries = pc.GetSeriesFromPoint(pt) as DataSeries;
+
+ OnMouseMove(pt, control, shift);
+
+ //pc.CaptureMouse();
+ // pc.Cursor = Cursors.Cross;
+ }
+
+ public override void OnMouseMove(ScreenPoint pt, bool control, bool shift)
+ {
+ if (currentSeries == null)
+ return;
+
+ var current = GetNearestPoint(currentSeries, pt, !control, shift);
+ if (current != null)
+ pc.ShowSlider(currentSeries, current.Value);
+ }
+
+ private static DataPoint? GetNearestPoint(ISeries s, ScreenPoint point, bool snap, bool pointsOnly)
+ {
+ if (s == null)
+ return null;
+
+ if (snap || pointsOnly)
+ {
+ ScreenPoint spn;
+ DataPoint dpn;
+ if (s.GetNearestPoint(point, out dpn, out spn) && snap)
+ {
+ if (spn.DistanceTo(point) < 20)
+ return dpn;
+ }
+ }
+
+ ScreenPoint sp;
+ DataPoint dp;
+
+ if (!pointsOnly)
+ if (s.GetNearestInterpolatedPoint(point, out dp, out sp))
+ return dp;
+
+ return null;
+ }
+
+ public override void OnMouseUp()
+ {
+ base.OnMouseUp();
+ if (currentSeries == null)
+ return;
+ currentSeries = null;
+ pc.HideSlider();
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/NamespaceDoc.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/NamespaceDoc.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,37 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ ///
+ /// The OxyPlot namespace contains the platform independent classes of the library.
+ ///
+ [System.Runtime.CompilerServices.CompilerGenerated]
+ internal class NamespaceDoc
+ {
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/OxyPlot.csproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,237 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {BCC43E58-E473-403E-A84D-63FEDC723040}
+ Library
+ Properties
+ OxyPlot
+ OxyPlot
+ v4.0
+ 512
+ Client
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\Output\NET40x\
+ TRACE
+ prompt
+ 4
+ ..\..\Output\NET40x\OxyPlot.XML
+
+
+ true
+
+
+ OxyPlot.snk
+
+
+
+
+
+
+
+
+
+
+
+
+ Properties\GlobalAssemblyInfo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/OxyPlot.snk
Binary file External/OxyPlot/OxyPlot/OxyPlot.snk has changed
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/HitTestResult.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/HitTestResult.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,79 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a hit test result.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Represents a hit test result.
+ ///
+ public class HitTestResult
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public HitTestResult()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The nearest hit point.
+ /// The item.
+ /// The index.
+ public HitTestResult(ScreenPoint nhp, object item = null, double index = 0)
+ {
+ this.NearestHitPoint = nhp;
+ this.Item = item;
+ this.Index = index;
+ }
+
+ ///
+ /// Gets or sets the index of the hit (if available).
+ ///
+ /// The index.
+ ///
+ /// If the hit was in the middle between point 1 and 2, index = 1.5.
+ ///
+ public double Index { get; set; }
+
+ ///
+ /// Gets or sets the item of the hit.
+ ///
+ /// The item.
+ public object Item { get; set; }
+
+ ///
+ /// Gets or sets the position of the nearest hit point.
+ ///
+ /// The nearest hit point.
+ public ScreenPoint NearestHitPoint { get; set; }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/OxyMouseButton.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/OxyMouseButton.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,67 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The mouse buttons.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ ///
+ /// Specifies constants that define which mouse button was pressed.
+ ///
+ public enum OxyMouseButton
+ {
+ ///
+ /// No mouse button.
+ ///
+ None = 0,
+
+ ///
+ /// The left mouse button.
+ ///
+ Left = 1,
+
+ ///
+ /// The middle mouse button.
+ ///
+ Middle = 2,
+
+ ///
+ /// The right mouse button.
+ ///
+ Right = 3,
+
+ ///
+ /// The first extended mouse button.
+ ///
+ XButton1 = 4,
+
+ ///
+ /// The second extended mouse button.
+ ///
+ XButton2 = 5,
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/OxyMouseEventArgs.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/OxyMouseEventArgs.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,87 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents event arguments for 3D mouse events events.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides data for the mouse events.
+ ///
+ public class OxyMouseEventArgs : EventArgs
+ {
+ ///
+ /// Gets or sets the mouse button that has changed.
+ ///
+ public OxyMouseButton ChangedButton { get; set; }
+
+ ///
+ /// Gets or sets the click count.
+ ///
+ /// The click count.
+ public int ClickCount { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether Handled.
+ ///
+ public bool Handled { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the alt key was pressed when the event was raised.
+ ///
+ public bool IsAltDown { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the control key was pressed when the event was raised.
+ ///
+ public bool IsControlDown { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the shift key was pressed when the event was raised.
+ ///
+ public bool IsShiftDown { get; set; }
+
+ ///
+ /// Gets or sets the hit test result.
+ ///
+ public HitTestResult HitTestResult { get; set; }
+
+ ///
+ /// Gets or sets the plot control.
+ ///
+ /// The plot control.
+ public IPlotControl PlotControl { get; set; }
+
+ ///
+ /// Gets or sets the position.
+ ///
+ public ScreenPoint Position { get; set; }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/PlotElement.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/PlotElement.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,142 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Abstract base class for all plottable elements (Axes, Annotations, Series).
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides an abstract base class for elements contained in a .
+ ///
+ public abstract class PlotElement
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected PlotElement()
+ {
+ this.Font = null;
+ this.FontSize = double.NaN;
+ this.FontWeight = FontWeights.Normal;
+ }
+
+ ///
+ /// Gets or sets the font.
+ ///
+ /// The font.
+ ///
+ /// If the value is null, the parent PlotModel's DefaultFont will be used.
+ ///
+ public string Font { get; set; }
+
+ ///
+ /// Gets or sets the size of the font.
+ ///
+ /// The size of the font.
+ ///
+ /// If the value is NaN, the parent PlotModel's DefaultFontSize will be used.
+ ///
+ public double FontSize { get; set; }
+
+ ///
+ /// Gets or sets the font weight.
+ ///
+ /// The font weight.
+ public double FontWeight { get; set; }
+
+ ///
+ /// Gets the parent plot model.
+ ///
+ public PlotModel PlotModel { get; internal set; }
+
+ ///
+ /// Gets or sets an arbitrary object value that can be used to store custom information about this plot element.
+ ///
+ /// The intended value. This property has no default value.
+ ///
+ /// This property is analogous to Tag properties in other Microsoft programming models. Tag is intended to provide a pre-existing property location where you can store some basic custom information about any PlotElement without requiring you to subclass an element.
+ ///
+ public object Tag { get; set; }
+
+ ///
+ /// Gets or sets the color of the text.
+ ///
+ /// The color of the text.
+ ///
+ /// If the value is null, the TextColor of the parent PlotModel will be used.
+ ///
+ public OxyColor TextColor { get; set; }
+
+ ///
+ /// Gets the actual font.
+ ///
+ protected internal string ActualFont
+ {
+ get
+ {
+ return this.Font ?? this.PlotModel.DefaultFont;
+ }
+ }
+
+ ///
+ /// Gets the actual size of the font.
+ ///
+ /// The actual size of the font.
+ protected internal double ActualFontSize
+ {
+ get
+ {
+ return !double.IsNaN(this.FontSize) ? this.FontSize : this.PlotModel.DefaultFontSize;
+ }
+ }
+
+ ///
+ /// Gets the actual font weight.
+ ///
+ protected internal double ActualFontWeight
+ {
+ get
+ {
+ return this.FontWeight;
+ }
+ }
+
+ ///
+ /// Gets the actual color of the text.
+ ///
+ /// The actual color of the text.
+ protected internal OxyColor ActualTextColor
+ {
+ get
+ {
+ return this.TextColor ?? this.PlotModel.TextColor;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/PlotModel.Legends.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.Legends.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,507 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Partial PlotModel class - this file contains methods related to the series legends.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using OxyPlot.Series;
+
+ public partial class PlotModel
+ {
+ ///
+ /// Makes the LegendOrientation property safe.
+ ///
+ ///
+ /// If Legend is positioned left or right, force it to vertical orientation
+ ///
+ private void EnsureLegendProperties()
+ {
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.LeftTop:
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.LeftBottom:
+ case LegendPosition.RightTop:
+ case LegendPosition.RightMiddle:
+ case LegendPosition.RightBottom:
+ if (this.LegendOrientation == LegendOrientation.Horizontal)
+ {
+ this.LegendOrientation = LegendOrientation.Vertical;
+ }
+
+ break;
+ }
+ }
+
+ ///
+ /// Gets the rectangle of the legend box.
+ ///
+ /// Size of the legend box.
+ /// A rectangle.
+ private OxyRect GetLegendRectangle(OxySize legendSize)
+ {
+ double top = 0;
+ double left = 0;
+ if (this.LegendPlacement == LegendPlacement.Outside)
+ {
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.LeftTop:
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.LeftBottom:
+ left = this.PlotAndAxisArea.Left - legendSize.Width - this.LegendMargin;
+ break;
+ case LegendPosition.RightTop:
+ case LegendPosition.RightMiddle:
+ case LegendPosition.RightBottom:
+ left = this.PlotAndAxisArea.Right + this.LegendMargin;
+ break;
+ case LegendPosition.TopLeft:
+ case LegendPosition.TopCenter:
+ case LegendPosition.TopRight:
+ top = this.PlotAndAxisArea.Top - legendSize.Height - this.LegendMargin;
+ break;
+ case LegendPosition.BottomLeft:
+ case LegendPosition.BottomCenter:
+ case LegendPosition.BottomRight:
+ top = this.PlotAndAxisArea.Bottom + this.LegendMargin;
+ break;
+ }
+
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.TopLeft:
+ case LegendPosition.BottomLeft:
+ left = this.PlotArea.Left;
+ break;
+ case LegendPosition.TopRight:
+ case LegendPosition.BottomRight:
+ left = this.PlotArea.Right - legendSize.Width;
+ break;
+ case LegendPosition.LeftTop:
+ case LegendPosition.RightTop:
+ top = this.PlotArea.Top;
+ break;
+ case LegendPosition.LeftBottom:
+ case LegendPosition.RightBottom:
+ top = this.PlotArea.Bottom - legendSize.Height;
+ break;
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.RightMiddle:
+ top = (this.PlotArea.Top + this.PlotArea.Bottom - legendSize.Height) * 0.5;
+ break;
+ case LegendPosition.TopCenter:
+ case LegendPosition.BottomCenter:
+ left = (this.PlotArea.Left + this.PlotArea.Right - legendSize.Width) * 0.5;
+ break;
+ }
+ }
+ else
+ {
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.LeftTop:
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.LeftBottom:
+ left = this.PlotArea.Left + this.LegendMargin;
+ break;
+ case LegendPosition.RightTop:
+ case LegendPosition.RightMiddle:
+ case LegendPosition.RightBottom:
+ left = this.PlotArea.Right - legendSize.Width - this.LegendMargin;
+ break;
+ case LegendPosition.TopLeft:
+ case LegendPosition.TopCenter:
+ case LegendPosition.TopRight:
+ top = this.PlotArea.Top + this.LegendMargin;
+ break;
+ case LegendPosition.BottomLeft:
+ case LegendPosition.BottomCenter:
+ case LegendPosition.BottomRight:
+ top = this.PlotArea.Bottom - legendSize.Height - this.LegendMargin;
+ break;
+ }
+
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.TopLeft:
+ case LegendPosition.BottomLeft:
+ left = this.PlotArea.Left + this.LegendMargin;
+ break;
+ case LegendPosition.TopRight:
+ case LegendPosition.BottomRight:
+ left = this.PlotArea.Right - legendSize.Width - this.LegendMargin;
+ break;
+ case LegendPosition.LeftTop:
+ case LegendPosition.RightTop:
+ top = this.PlotArea.Top + this.LegendMargin;
+ break;
+ case LegendPosition.LeftBottom:
+ case LegendPosition.RightBottom:
+ top = this.PlotArea.Bottom - legendSize.Height - this.LegendMargin;
+ break;
+
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.RightMiddle:
+ top = (this.PlotArea.Top + this.PlotArea.Bottom - legendSize.Height) * 0.5;
+ break;
+ case LegendPosition.TopCenter:
+ case LegendPosition.BottomCenter:
+ left = (this.PlotArea.Left + this.PlotArea.Right - legendSize.Width) * 0.5;
+ break;
+ }
+ }
+
+ return new OxyRect(left, top, legendSize.Width, legendSize.Height);
+ }
+
+ ///
+ /// Renders the legend for the specified series.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The series.
+ ///
+ ///
+ /// The position and size of the legend.
+ ///
+ private void RenderLegend(IRenderContext rc, Series.Series s, OxyRect rect)
+ {
+ double x = rect.Left;
+ switch (this.LegendItemAlignment)
+ {
+ case HorizontalAlignment.Center:
+ x = (rect.Left + rect.Right) / 2;
+ if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
+ {
+ x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
+ }
+ else
+ {
+ x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
+ }
+
+ break;
+ case HorizontalAlignment.Right:
+ x = rect.Right;
+
+ // if (LegendSymbolPlacement == LegendSymbolPlacement.Right)
+ x -= this.LegendSymbolLength + this.LegendSymbolMargin;
+ break;
+ }
+
+ if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
+ {
+ x += this.LegendSymbolLength + this.LegendSymbolMargin;
+ }
+
+ double y = rect.Top;
+ var maxsize = new OxySize(Math.Max(rect.Right - x, 0), Math.Max(rect.Bottom - y, 0));
+
+ var textSize = rc.DrawMathText(
+ new ScreenPoint(x, y),
+ s.Title,
+ this.LegendTextColor ?? this.TextColor,
+ this.LegendFont ?? this.DefaultFont,
+ this.LegendFontSize,
+ this.LegendFontWeight,
+ 0,
+ this.LegendItemAlignment,
+ VerticalAlignment.Top,
+ maxsize,
+ true);
+ double x0 = x;
+ switch (this.LegendItemAlignment)
+ {
+ case HorizontalAlignment.Center:
+ x0 = x - (textSize.Width * 0.5);
+ break;
+ case HorizontalAlignment.Right:
+ x0 = x - textSize.Width;
+ break;
+ }
+
+ var symbolRect =
+ new OxyRect(
+ this.LegendSymbolPlacement == LegendSymbolPlacement.Right
+ ? x0 + textSize.Width + this.LegendSymbolMargin
+ : x0 - this.LegendSymbolMargin - this.LegendSymbolLength,
+ rect.Top,
+ this.LegendSymbolLength,
+ textSize.Height);
+
+ s.RenderLegend(rc, symbolRect);
+ }
+
+ ///
+ /// Measures the legends.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The available size for the legend box.
+ ///
+ ///
+ /// The size of the legend box.
+ ///
+ private OxySize MeasureLegends(IRenderContext rc, OxySize availableSize)
+ {
+ return this.RenderOrMeasureLegends(rc, new OxyRect(0, 0, availableSize.Width, availableSize.Height), true);
+ }
+
+ ///
+ /// Renders or measures the legends.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ private void RenderLegends(IRenderContext rc, OxyRect rect)
+ {
+ this.RenderOrMeasureLegends(rc, rect);
+ }
+
+ ///
+ /// Renders or measures the legends.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// Provides the available size if measuring, otherwise it provides the position and size of the legend.
+ ///
+ ///
+ /// Specify if the size of the legend box should be measured only (not rendered).
+ ///
+ ///
+ /// The size of the legend box.
+ ///
+ private OxySize RenderOrMeasureLegends(IRenderContext rc, OxyRect rect, bool measureOnly = false)
+ {
+ // Render background and border around legend
+ if (!measureOnly && rect.Width > 0 && rect.Height > 0)
+ {
+ rc.DrawRectangleAsPolygon(rect, this.LegendBackground, this.LegendBorder, this.LegendBorderThickness);
+ }
+
+ double availableWidth = rect.Width;
+ double availableHeight = rect.Height;
+
+ double x = this.LegendPadding;
+ double top = this.LegendPadding;
+
+ var size = new OxySize();
+
+ // Render/measure the legend title
+ if (!string.IsNullOrEmpty(this.LegendTitle))
+ {
+ OxySize titleSize;
+ if (measureOnly)
+ {
+ titleSize = rc.MeasureMathText(
+ this.LegendTitle,
+ this.LegendTitleFont ?? DefaultFont,
+ this.LegendTitleFontSize,
+ this.LegendTitleFontWeight);
+ }
+ else
+ {
+ titleSize = rc.DrawMathText(
+ new ScreenPoint(rect.Left + x, rect.Top + top),
+ this.LegendTitle,
+ this.LegendTitleColor ?? this.TextColor,
+ this.LegendTitleFont ?? this.DefaultFont,
+ this.LegendTitleFontSize,
+ this.LegendTitleFontWeight,
+ 0,
+ HorizontalAlignment.Left,
+ VerticalAlignment.Top,
+ null,
+ true);
+ }
+
+ top += titleSize.Height;
+ size.Width = x + titleSize.Width + this.LegendPadding;
+ size.Height = top + titleSize.Height;
+ }
+
+ double y = top;
+
+ double lineHeight = 0;
+
+ // tolerance for floating-point number comparisons
+ const double Epsilon = 1e-3;
+
+ // the maximum item with in the column being rendered (only used for vertical orientation)
+ double maxItemWidth = 0;
+
+ var items = this.LegendItemOrder == LegendItemOrder.Reverse ? this.VisibleSeries.Reverse() : this.VisibleSeries;
+
+ // When orientation is vertical and alignment is center or right, the items cannot be rendered before
+ // the max item width has been calculated. Render the items for each column, and at the end.
+ var seriesToRender = new Dictionary();
+ Action renderItems = () =>
+ {
+ foreach (var sr in seriesToRender)
+ {
+ var itemRect = sr.Value;
+ var itemSeries = sr.Key;
+
+ double rwidth = itemRect.Width;
+ if (itemRect.Left + rwidth + this.LegendPadding > rect.Left + availableWidth)
+ {
+ rwidth = rect.Left + availableWidth - itemRect.Left - this.LegendPadding;
+ }
+
+ double rheight = itemRect.Height;
+ if (rect.Top + rheight + this.LegendPadding > rect.Top + availableHeight)
+ {
+ rheight = rect.Top + availableHeight - rect.Top - this.LegendPadding;
+ }
+
+ var r = new OxyRect(itemRect.Left, itemRect.Top, Math.Max(rwidth, 0), Math.Max(rheight, 0));
+ this.RenderLegend(rc, itemSeries, r);
+ }
+
+ seriesToRender.Clear();
+ };
+
+ foreach (var s in items)
+ {
+ // Skip series with empty title
+ if (string.IsNullOrEmpty(s.Title))
+ {
+ continue;
+ }
+
+ var textSize = rc.MeasureMathText(s.Title, this.LegendFont ?? DefaultFont, this.LegendFontSize, this.LegendFontWeight);
+ double itemWidth = this.LegendSymbolLength + this.LegendSymbolMargin + textSize.Width;
+ double itemHeight = textSize.Height;
+
+ if (this.LegendOrientation == LegendOrientation.Horizontal)
+ {
+ // Add spacing between items
+ if (x > this.LegendPadding)
+ {
+ x += this.LegendItemSpacing;
+ }
+
+ // Check if the item is too large to fit within the available width
+ if (x + itemWidth > availableWidth - this.LegendPadding + Epsilon)
+ {
+ // new line
+ x = this.LegendPadding;
+ y += lineHeight;
+ lineHeight = 0;
+ }
+
+ // Update the max size of the current line
+ lineHeight = Math.Max(lineHeight, textSize.Height);
+
+ if (!measureOnly)
+ {
+ seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight));
+ }
+
+ x += itemWidth;
+
+ // Update the max width of the legend box
+ size.Width = Math.Max(size.Width, x);
+
+ // Update the max height of the legend box
+ size.Height = Math.Max(size.Height, y + textSize.Height);
+ }
+ else
+ {
+ if (y + itemHeight > availableHeight - this.LegendPadding + Epsilon)
+ {
+ renderItems();
+
+ y = top;
+ x += maxItemWidth + this.LegendColumnSpacing;
+ maxItemWidth = 0;
+ }
+
+ if (!measureOnly)
+ {
+ seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight));
+ }
+
+ y += itemHeight;
+
+ // Update the max size of the items in the current column
+ maxItemWidth = Math.Max(maxItemWidth, itemWidth);
+
+ // Update the max width of the legend box
+ size.Width = Math.Max(size.Width, x + itemWidth);
+
+ // Update the max height of the legend box
+ size.Height = Math.Max(size.Height, y);
+ }
+ }
+
+ renderItems();
+
+ if (size.Width > 0)
+ {
+ size.Width += this.LegendPadding;
+ }
+
+ if (size.Height > 0)
+ {
+ size.Height += this.LegendPadding;
+ }
+
+ if (size.Width > availableWidth)
+ {
+ size.Width = availableWidth;
+ }
+
+ if (size.Height > availableHeight)
+ {
+ size.Height = availableHeight;
+ }
+
+ if (!double.IsNaN(LegendMaxWidth) && size.Width > this.LegendMaxWidth)
+ {
+ size.Width = this.LegendMaxWidth;
+ }
+
+ return size;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/PlotModel.MouseEvents.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.MouseEvents.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,202 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Partial PlotModel class - this file contains mouse events and handlers.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Linq;
+
+ public partial class PlotModel
+ {
+ ///
+ /// The mouse hit tolerance.
+ ///
+ private const double MouseHitTolerance = 10;
+
+ ///
+ /// The current mouse events element.
+ ///
+ private UIPlotElement currentMouseEventElement;
+
+ ///
+ /// Occurs when a mouse button is pressed down on the model.
+ ///
+ public event EventHandler MouseDown;
+
+ ///
+ /// Occurs when the mouse is moved on the plot element (only occurs after MouseDown).
+ ///
+ public event EventHandler MouseMove;
+
+ ///
+ /// Occurs when the mouse button is released on the plot element.
+ ///
+ public event EventHandler MouseUp;
+
+ ///
+ /// Handles the mouse down event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public void HandleMouseDown(object sender, OxyMouseEventArgs e)
+ {
+ // Revert the order to handle the top-level elements first
+ foreach (var element in this.GetElements().Reverse())
+ {
+ var uiElement = element as UIPlotElement;
+ if (uiElement == null)
+ {
+ continue;
+ }
+
+ var result = uiElement.HitTest(e.Position, MouseHitTolerance);
+ if (result != null)
+ {
+ e.HitTestResult = result;
+ uiElement.OnMouseDown(sender, e);
+ if (e.Handled)
+ {
+ this.currentMouseEventElement = uiElement;
+ }
+ }
+
+ if (e.Handled)
+ {
+ break;
+ }
+ }
+
+ if (!e.Handled)
+ {
+ this.OnMouseDown(sender, e);
+ }
+ }
+
+ ///
+ /// Handles the mouse move event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public void HandleMouseMove(object sender, OxyMouseEventArgs e)
+ {
+ if (this.currentMouseEventElement != null)
+ {
+ this.currentMouseEventElement.OnMouseMove(sender, e);
+ }
+
+ if (!e.Handled)
+ {
+ this.OnMouseMove(sender, e);
+ }
+ }
+
+ ///
+ /// Handles the mouse up event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ public void HandleMouseUp(object sender, OxyMouseEventArgs e)
+ {
+ if (this.currentMouseEventElement != null)
+ {
+ this.currentMouseEventElement.OnMouseUp(sender, e);
+ this.currentMouseEventElement = null;
+ }
+
+ if (!e.Handled)
+ {
+ this.OnMouseUp(sender, e);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected virtual void OnMouseDown(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseDown != null && !e.Handled)
+ {
+ this.MouseDown(sender, e);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected virtual void OnMouseMove(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseMove != null)
+ {
+ this.MouseMove(sender, e);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected virtual void OnMouseUp(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseUp != null)
+ {
+ this.MouseUp(sender, e);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/PlotModel.Rendering.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.Rendering.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,481 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Partial PlotModel class - this file contains rendering methods.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using OxyPlot.Annotations;
+ using OxyPlot.Axes;
+ using OxyPlot.Series;
+
+ public partial class PlotModel
+ {
+ ///
+ /// Renders the plot with the specified rendering context.
+ ///
+ /// The rendering context.
+ /// The width.
+ /// The height.
+ public void Render(IRenderContext rc, double width, double height)
+ {
+ lock (this.syncRoot)
+ {
+ if (width <= 0 || height <= 0)
+ {
+ return;
+ }
+
+ this.Width = width;
+ this.Height = height;
+
+ this.ActualPlotMargins = this.PlotMargins;
+ this.EnsureLegendProperties();
+
+ while (true)
+ {
+ this.UpdatePlotArea(rc);
+ this.UpdateAxisTransforms();
+ this.UpdateIntervals();
+ if (!this.AutoAdjustPlotMargins)
+ {
+ break;
+ }
+
+ if (!this.AdjustPlotMargins(rc))
+ {
+ break;
+ }
+ }
+
+ if (this.PlotType == PlotType.Cartesian)
+ {
+ this.EnforceCartesianTransforms();
+ this.UpdateIntervals();
+ }
+
+ this.RenderBackgrounds(rc);
+ this.RenderAnnotations(rc, AnnotationLayer.BelowAxes);
+ this.RenderAxes(rc, AxisLayer.BelowSeries);
+ this.RenderAnnotations(rc, AnnotationLayer.BelowSeries);
+ this.RenderSeries(rc);
+ this.RenderAnnotations(rc, AnnotationLayer.AboveSeries);
+ this.RenderTitle(rc);
+ this.RenderBox(rc);
+ this.RenderAxes(rc, AxisLayer.AboveSeries);
+
+ if (this.IsLegendVisible)
+ {
+ this.RenderLegends(rc, this.LegendArea);
+ }
+ }
+ }
+
+ ///
+ /// Calculates the maximum size of the specified axes.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The axes of position tier.
+ ///
+ ///
+ /// The maximum size.
+ ///
+ private static double MaxSizeOfPositionTier(IRenderContext rc, IEnumerable axesOfPositionTier)
+ {
+ double maxSizeOfPositionTier = 0;
+ foreach (var axis in axesOfPositionTier)
+ {
+ OxySize size = axis.Measure(rc);
+ if (axis.IsHorizontal())
+ {
+ if (size.Height > maxSizeOfPositionTier)
+ {
+ maxSizeOfPositionTier = size.Height;
+ }
+ }
+ else
+ {
+ if (size.Width > maxSizeOfPositionTier)
+ {
+ maxSizeOfPositionTier = size.Width;
+ }
+ }
+ }
+
+ return maxSizeOfPositionTier;
+ }
+
+ ///
+ /// Adjust the plot margins.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The adjust plot margins.
+ ///
+ private bool AdjustPlotMargins(IRenderContext rc)
+ {
+ bool isAdjusted = false;
+ var newPlotMargins = new Dictionary
+ {
+ { AxisPosition.Left, this.ActualPlotMargins.Left },
+ { AxisPosition.Top, this.ActualPlotMargins.Top },
+ { AxisPosition.Right, this.ActualPlotMargins.Right },
+ { AxisPosition.Bottom, this.ActualPlotMargins.Bottom }
+ };
+
+ for (var position = AxisPosition.Left; position <= AxisPosition.Bottom; position++)
+ {
+ double maxValueOfPositionTier = 0;
+ var axesOfPosition = this.Axes.Where(a => a.Position == position).ToList();
+ foreach (var positionTier in axesOfPosition.Select(a => a.PositionTier).Distinct().OrderBy(l => l))
+ {
+ var axesOfPositionTier = axesOfPosition.Where(a => a.PositionTier == positionTier).ToList();
+ double maxSizeOfPositionTier = MaxSizeOfPositionTier(rc, axesOfPositionTier);
+ double minValueOfPositionTier = maxValueOfPositionTier;
+
+ if (Math.Abs(maxValueOfPositionTier) > 1e-5)
+ {
+ maxValueOfPositionTier += this.AxisTierDistance;
+ }
+
+ maxValueOfPositionTier += maxSizeOfPositionTier;
+
+ foreach (Axis axis in axesOfPositionTier)
+ {
+ axis.PositionTierSize = maxSizeOfPositionTier;
+ axis.PositionTierMinShift = minValueOfPositionTier;
+ axis.PositionTierMaxShift = maxValueOfPositionTier;
+ }
+ }
+
+ if (maxValueOfPositionTier > newPlotMargins[position])
+ {
+ newPlotMargins[position] = maxValueOfPositionTier;
+ isAdjusted = true;
+ }
+ }
+
+ if (isAdjusted)
+ {
+ this.ActualPlotMargins = new OxyThickness(
+ newPlotMargins[AxisPosition.Left],
+ newPlotMargins[AxisPosition.Top],
+ newPlotMargins[AxisPosition.Right],
+ newPlotMargins[AxisPosition.Bottom]);
+ }
+
+ return isAdjusted;
+ }
+
+ ///
+ /// Measures the size of the title and subtitle.
+ ///
+ ///
+ /// The rendering context.
+ ///
+ ///
+ /// Size of the titles.
+ ///
+ private OxySize MeasureTitles(IRenderContext rc)
+ {
+ OxySize size1 = rc.MeasureText(this.Title, this.ActualTitleFont, this.TitleFontSize, this.TitleFontWeight);
+ OxySize size2 = rc.MeasureText(
+ this.Subtitle, this.SubtitleFont ?? this.ActualSubtitleFont, this.SubtitleFontSize, this.SubtitleFontWeight);
+ double height = size1.Height + size2.Height;
+ double width = Math.Max(size1.Width, size2.Width);
+ return new OxySize(width, height);
+ }
+
+ ///
+ /// Renders the annotations.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The layer.
+ ///
+ private void RenderAnnotations(IRenderContext rc, AnnotationLayer layer)
+ {
+ foreach (var a in this.Annotations.Where(a => a.Layer == layer))
+ {
+ a.Render(rc, this);
+ }
+ }
+
+ ///
+ /// Renders the axes.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The layer.
+ ///
+ private void RenderAxes(IRenderContext rc, AxisLayer layer)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ foreach (var a in this.Axes)
+ {
+ if (a.IsAxisVisible && a.Layer == layer)
+ {
+ a.Render(rc, this, layer, i);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Renders the series backgrounds.
+ ///
+ ///
+ /// The render context.
+ ///
+ private void RenderBackgrounds(IRenderContext rc)
+ {
+ // Render the main background of the plot area (only if there are axes)
+ // The border is rendered by DrawRectangleAsPolygon to ensure that it is pixel aligned with the tick marks.
+ if (this.Axes.Count > 0 && this.PlotAreaBackground != null)
+ {
+ rc.DrawRectangleAsPolygon(this.PlotArea, this.PlotAreaBackground, null, 0);
+ }
+
+ foreach (var s in this.VisibleSeries)
+ {
+ var s2 = s as XYAxisSeries;
+ if (s2 == null || s2.Background == null)
+ {
+ continue;
+ }
+
+ rc.DrawRectangle(s2.GetScreenRectangle(), s2.Background, null, 0);
+ }
+ }
+
+ ///
+ /// Renders the border around the plot area.
+ ///
+ ///
+ /// The border will only by rendered if there are axes in the plot.
+ ///
+ ///
+ /// The render context.
+ ///
+ private void RenderBox(IRenderContext rc)
+ {
+ // The border is rendered by DrawBox to ensure that it is pixel aligned with the tick marks (cannot use DrawRectangle here).
+ if (this.Axes.Count > 0)
+ {
+ rc.DrawRectangleAsPolygon(this.PlotArea, null, this.PlotAreaBorderColor, this.PlotAreaBorderThickness);
+ }
+ }
+
+ ///
+ /// Renders the series.
+ ///
+ ///
+ /// The render context.
+ ///
+ private void RenderSeries(IRenderContext rc)
+ {
+ // Update undefined colors
+ this.ResetDefaultColor();
+ foreach (var s in this.VisibleSeries)
+ {
+ s.SetDefaultValues(this);
+ }
+
+ foreach (var s in this.VisibleSeries)
+ {
+ s.Render(rc, this);
+ }
+ }
+
+ ///
+ /// Renders the title and subtitle.
+ ///
+ ///
+ /// The render context.
+ ///
+ private void RenderTitle(IRenderContext rc)
+ {
+ OxySize size1 = rc.MeasureText(this.Title, this.ActualTitleFont, this.TitleFontSize, this.TitleFontWeight);
+ rc.MeasureText(
+ this.Subtitle, this.SubtitleFont ?? this.ActualSubtitleFont, this.SubtitleFontSize, this.SubtitleFontWeight);
+
+ // double height = size1.Height + size2.Height;
+ // double dy = (TitleArea.Top+TitleArea.Bottom-height)*0.5;
+ double dy = this.TitleArea.Top;
+ double dx = (this.TitleArea.Left + this.TitleArea.Right) * 0.5;
+
+ if (!string.IsNullOrEmpty(this.Title))
+ {
+ rc.DrawMathText(
+ new ScreenPoint(dx, dy),
+ this.Title,
+ this.TitleColor ?? this.TextColor,
+ this.ActualTitleFont,
+ this.TitleFontSize,
+ this.TitleFontWeight,
+ 0,
+ HorizontalAlignment.Center,
+ VerticalAlignment.Top);
+ dy += size1.Height;
+ }
+
+ if (!string.IsNullOrEmpty(this.Subtitle))
+ {
+ rc.DrawMathText(
+ new ScreenPoint(dx, dy),
+ this.Subtitle,
+ this.SubtitleColor ?? this.TextColor,
+ this.ActualSubtitleFont,
+ this.SubtitleFontSize,
+ this.SubtitleFontWeight,
+ 0,
+ HorizontalAlignment.Center,
+ VerticalAlignment.Top);
+ }
+ }
+
+ ///
+ /// Calculates the plot area (subtract padding, title size and outside legends)
+ ///
+ ///
+ /// The rendering context.
+ ///
+ private void UpdatePlotArea(IRenderContext rc)
+ {
+ var plotArea = new OxyRect(
+ this.Padding.Left,
+ this.Padding.Top,
+ this.Width - this.Padding.Left - this.Padding.Right,
+ this.Height - this.Padding.Top - this.Padding.Bottom);
+
+ var titleSize = this.MeasureTitles(rc);
+
+ if (titleSize.Height > 0)
+ {
+ double titleHeight = titleSize.Height + this.TitlePadding;
+ plotArea.Height -= titleHeight;
+ plotArea.Top += titleHeight;
+ }
+
+ plotArea.Top += this.ActualPlotMargins.Top;
+ plotArea.Height -= this.ActualPlotMargins.Top;
+
+ plotArea.Height -= this.ActualPlotMargins.Bottom;
+
+ plotArea.Left += this.ActualPlotMargins.Left;
+ plotArea.Width -= this.ActualPlotMargins.Left;
+
+ plotArea.Width -= this.ActualPlotMargins.Right;
+
+ // Find the available size for the legend box
+ double availableLegendWidth = plotArea.Width;
+ double availableLegendHeight = plotArea.Height;
+ if (this.LegendPlacement == LegendPlacement.Inside)
+ {
+ availableLegendWidth -= this.LegendMargin * 2;
+ availableLegendHeight -= this.LegendMargin * 2;
+ }
+
+ if (availableLegendWidth < 0)
+ {
+ availableLegendWidth = 0;
+ }
+
+ if (availableLegendHeight < 0)
+ {
+ availableLegendHeight = 0;
+ }
+
+ // Calculate the size of the legend box
+ var legendSize = this.MeasureLegends(rc, new OxySize(availableLegendWidth, availableLegendHeight));
+
+ // Adjust the plot area after the size of the legend box has been calculated
+ if (this.IsLegendVisible && this.LegendPlacement == LegendPlacement.Outside)
+ {
+ switch (this.LegendPosition)
+ {
+ case LegendPosition.LeftTop:
+ case LegendPosition.LeftMiddle:
+ case LegendPosition.LeftBottom:
+ plotArea.Left += legendSize.Width + this.LegendMargin;
+ plotArea.Width -= legendSize.Width + this.LegendMargin;
+ break;
+ case LegendPosition.RightTop:
+ case LegendPosition.RightMiddle:
+ case LegendPosition.RightBottom:
+ plotArea.Width -= legendSize.Width + this.LegendMargin;
+ break;
+ case LegendPosition.TopLeft:
+ case LegendPosition.TopCenter:
+ case LegendPosition.TopRight:
+ plotArea.Top += legendSize.Height + this.LegendMargin;
+ plotArea.Height -= legendSize.Height + this.LegendMargin;
+ break;
+ case LegendPosition.BottomLeft:
+ case LegendPosition.BottomCenter:
+ case LegendPosition.BottomRight:
+ plotArea.Height -= legendSize.Height + this.LegendMargin;
+ break;
+ }
+ }
+
+ // Ensure the plot area is valid
+ if (plotArea.Height < 0)
+ {
+ plotArea.Bottom = plotArea.Top + 1;
+ }
+
+ if (plotArea.Width < 0)
+ {
+ plotArea.Right = plotArea.Left + 1;
+ }
+
+ this.PlotArea = plotArea;
+ this.PlotAndAxisArea = new OxyRect(
+ plotArea.Left - this.ActualPlotMargins.Left,
+ plotArea.Top - this.ActualPlotMargins.Top,
+ plotArea.Width + this.ActualPlotMargins.Left + this.ActualPlotMargins.Right,
+ plotArea.Height + this.ActualPlotMargins.Top + this.ActualPlotMargins.Bottom);
+ this.TitleArea = new OxyRect(this.PlotArea.Left, this.Padding.Top, this.PlotArea.Width, titleSize.Height + (this.TitlePadding * 2));
+ this.LegendArea = this.GetLegendRectangle(legendSize);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/PlotModel.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,1485 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Plot coordinate system type
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+
+ using OxyPlot.Annotations;
+ using OxyPlot.Axes;
+ using OxyPlot.Reporting;
+ using OxyPlot.Series;
+
+ ///
+ /// Specifies the coordinate system type.
+ ///
+ public enum PlotType
+ {
+ ///
+ /// XY coordinate system - two perpendicular axes
+ ///
+ XY,
+
+ ///
+ /// Cartesian coordinate system - perpendicular axes with the same scaling.
+ ///
+ ///
+ /// See http://en.wikipedia.org/wiki/Cartesian_coordinate_system
+ ///
+ Cartesian,
+
+ ///
+ /// Polar coordinate system - with radial and angular axes
+ ///
+ ///
+ /// See http://en.wikipedia.org/wiki/Polar_coordinate_system
+ ///
+ Polar
+ }
+
+ ///
+ /// Specifies the placement of the legend box.
+ ///
+ public enum LegendPlacement
+ {
+ ///
+ /// Place the legends inside the plot area.
+ ///
+ Inside,
+
+ ///
+ /// Place the legends outside the plot area.
+ ///
+ Outside
+ }
+
+ ///
+ /// Specifies the position of the legend box.
+ ///
+ public enum LegendPosition
+ {
+ ///
+ /// Place the legend box in the top-left corner.
+ ///
+ TopLeft,
+
+ ///
+ /// Place the legend box centered at the top.
+ ///
+ TopCenter,
+
+ ///
+ /// Place the legend box in the top-right corner.
+ ///
+ TopRight,
+
+ ///
+ /// Place the legend box in the bottom-left corner.
+ ///
+ BottomLeft,
+
+ ///
+ /// Place the legend box centered at the bottom.
+ ///
+ BottomCenter,
+
+ ///
+ /// Place the legend box in the bottom-right corner.
+ ///
+ BottomRight,
+
+ ///
+ /// Place the legend box in the left-top corner.
+ ///
+ LeftTop,
+
+ ///
+ /// Place the legend box centered at the left.
+ ///
+ LeftMiddle,
+
+ ///
+ /// Place the legend box in the left-bottom corner.
+ ///
+ LeftBottom,
+
+ ///
+ /// Place the legend box in the right-top corner.
+ ///
+ RightTop,
+
+ ///
+ /// Place the legend box centered at the right.
+ ///
+ RightMiddle,
+
+ ///
+ /// Place the legend box in the right-bottom corner.
+ ///
+ RightBottom
+ }
+
+ ///
+ /// Specifies the orientation of the items in the legend box.
+ ///
+ public enum LegendOrientation
+ {
+ ///
+ /// Orient the items horizontally.
+ ///
+ Horizontal,
+
+ ///
+ /// Orient the items vertically.
+ ///
+ Vertical
+ }
+
+ ///
+ /// Specifies the item order of the legends.
+ ///
+ public enum LegendItemOrder
+ {
+ ///
+ /// Render the items in the normal order.
+ ///
+ Normal,
+
+ ///
+ /// Render the items in the reverse order.
+ ///
+ Reverse
+ }
+
+ ///
+ /// Specifies the placement of the legend symbols.
+ ///
+ public enum LegendSymbolPlacement
+ {
+ ///
+ /// Render symbols to the left of the labels.
+ ///
+ Left,
+
+ ///
+ /// Render symbols to the right of the labels.
+ ///
+ Right
+ }
+
+ ///
+ /// Represents a plot (including axes, series and annotations).
+ ///
+ public partial class PlotModel
+ {
+ ///
+ /// The default selection color.
+ ///
+ internal static readonly OxyColor DefaultSelectionColor = OxyColors.Yellow;
+
+ ///
+ /// The default font.
+ ///
+ private const string PrivateDefaultFont = "Segoe UI";
+
+ ///
+ /// The current color index.
+ ///
+ private int currentColorIndex;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PlotModel()
+ {
+ this.Axes = new Collection();
+ this.Series = new Collection();
+ this.Annotations = new Collection();
+
+ this.PlotType = PlotType.XY;
+
+ this.PlotMargins = new OxyThickness(60, 4, 4, 40);
+ this.Padding = new OxyThickness(8, 8, 16, 8);
+ this.AutoAdjustPlotMargins = true;
+
+ this.DefaultFont = PrivateDefaultFont;
+ this.DefaultFontSize = 12;
+
+ this.TitleFont = null;
+ this.TitleFontSize = 18;
+ this.TitleFontWeight = FontWeights.Bold;
+ this.SubtitleFont = null;
+ this.SubtitleFontSize = 14;
+ this.SubtitleFontWeight = FontWeights.Normal;
+ this.TitlePadding = 6;
+
+ this.TextColor = OxyColors.Black;
+ this.PlotAreaBorderColor = OxyColors.Black;
+ this.PlotAreaBorderThickness = 1;
+
+ this.IsLegendVisible = true;
+ this.LegendTitleFont = null;
+ this.LegendTitleFontSize = 12;
+ this.LegendTitleFontWeight = FontWeights.Bold;
+ this.LegendFont = null;
+ this.LegendFontSize = 12;
+ this.LegendFontWeight = FontWeights.Normal;
+ this.LegendSymbolLength = 16;
+ this.LegendSymbolMargin = 4;
+ this.LegendPadding = 8;
+ this.LegendColumnSpacing = 8;
+ this.LegendItemSpacing = 24;
+ this.LegendMargin = 8;
+
+ this.LegendBackground = null;
+ this.LegendBorder = null;
+ this.LegendBorderThickness = 1;
+
+ this.LegendMaxWidth = double.NaN;
+ this.LegendPlacement = LegendPlacement.Inside;
+ this.LegendPosition = LegendPosition.RightTop;
+ this.LegendOrientation = LegendOrientation.Vertical;
+ this.LegendItemOrder = LegendItemOrder.Normal;
+ this.LegendItemAlignment = HorizontalAlignment.Left;
+ this.LegendSymbolPlacement = LegendSymbolPlacement.Left;
+
+ this.DefaultColors = new List
+ {
+ OxyColor.FromRgb(0x4E, 0x9A, 0x06),
+ OxyColor.FromRgb(0xC8, 0x8D, 0x00),
+ OxyColor.FromRgb(0xCC, 0x00, 0x00),
+ OxyColor.FromRgb(0x20, 0x4A, 0x87),
+ OxyColors.Red,
+ OxyColors.Orange,
+ OxyColors.Yellow,
+ OxyColors.Green,
+ OxyColors.Blue,
+ OxyColors.Indigo,
+ OxyColors.Violet
+ };
+
+ this.AxisTierDistance = 4.0;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The title.
+ ///
+ ///
+ /// The subtitle.
+ ///
+ public PlotModel(string title, string subtitle = null)
+ : this()
+ {
+ this.Title = title;
+ this.Subtitle = subtitle;
+ }
+
+ ///
+ /// The synchronization root object.
+ ///
+ private object syncRoot = new object();
+
+ ///
+ /// Gets an object that can be used to synchronize access to the PlotModel.
+ ///
+ /// The sync root.
+ public object SyncRoot { get { return this.syncRoot; } }
+
+ ///
+ /// Occurs when the plot has been updated.
+ ///
+ public event EventHandler Updated;
+
+ ///
+ /// Occurs when the plot is about to be updated.
+ ///
+ public event EventHandler Updating;
+
+ ///
+ /// Gets or sets the default font.
+ ///
+ /// The default font.
+ ///
+ /// This font is used for text on axes, series, legends and plot titles unless other fonts are specified.
+ ///
+ public string DefaultFont { get; set; }
+
+ ///
+ /// Gets or sets the default size of the fonts.
+ ///
+ ///
+ /// The default size of the font.
+ ///
+ public double DefaultFontSize { get; set; }
+
+ ///
+ /// Gets the actual culture.
+ ///
+ public CultureInfo ActualCulture
+ {
+ get
+ {
+ return this.Culture ?? CultureInfo.CurrentCulture;
+ }
+ }
+
+ ///
+ /// Gets the actual plot margins.
+ ///
+ /// The actual plot margins.
+ public OxyThickness ActualPlotMargins { get; private set; }
+
+ ///
+ /// Gets the plot control that renders this plot.
+ ///
+ ///
+ /// Only one PlotControl can render the plot at the same time.
+ ///
+ /// The plot control.
+ public IPlotControl PlotControl { get; private set; }
+
+ ///
+ /// Gets or sets the annotations.
+ ///
+ /// The annotations.
+ public Collection Annotations { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to auto adjust plot margins.
+ ///
+ public bool AutoAdjustPlotMargins { get; set; }
+
+ ///
+ /// Gets or sets the axes.
+ ///
+ /// The axes.
+ public Collection Axes { get; set; }
+
+ ///
+ /// Gets or sets the color of the background of the plot.
+ ///
+ public OxyColor Background { get; set; }
+
+ ///
+ /// Gets or sets the culture.
+ ///
+ /// The culture.
+ public CultureInfo Culture { get; set; }
+
+ ///
+ /// Gets or sets the default colors.
+ ///
+ /// The default colors.
+ public IList DefaultColors { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the legend is visible. The titles of the series must be set to use the legend.
+ ///
+ public bool IsLegendVisible { get; set; }
+
+ ///
+ /// Gets the legend area.
+ ///
+ /// The legend area.
+ public OxyRect LegendArea { get; private set; }
+
+ ///
+ /// Gets or sets the background color of the legend. Use null for no background.
+ ///
+ /// The legend background.
+ public OxyColor LegendBackground { get; set; }
+
+ ///
+ /// Gets or sets the border color of the legend.
+ ///
+ /// The legend border.
+ public OxyColor LegendBorder { get; set; }
+
+ ///
+ /// Gets or sets the thickness of the legend border. Use 0 for no border.
+ ///
+ /// The legend border thickness.
+ public double LegendBorderThickness { get; set; }
+
+ ///
+ /// Gets or sets the legend column spacing.
+ ///
+ /// The legend column spacing.
+ public double LegendColumnSpacing { get; set; }
+
+ ///
+ /// Gets or sets the legend font.
+ ///
+ /// The legend font.
+ public string LegendFont { get; set; }
+
+ ///
+ /// Gets or sets the size of the legend font.
+ ///
+ /// The size of the legend font.
+ public double LegendFontSize { get; set; }
+
+ ///
+ /// Gets or sets the color of the legend text.
+ ///
+ ///
+ /// The color of the legend text.
+ ///
+ ///
+ /// If this value is null, the TextColor will be used.
+ ///
+ public OxyColor LegendTextColor { get; set; }
+
+ ///
+ /// Gets or sets the legend font weight.
+ ///
+ /// The legend font weight.
+ public double LegendFontWeight { get; set; }
+
+ ///
+ /// Gets or sets the legend item alignment.
+ ///
+ /// The legend item alignment.
+ public HorizontalAlignment LegendItemAlignment { get; set; }
+
+ ///
+ /// Gets or sets the legend item order.
+ ///
+ /// The legend item order.
+ public LegendItemOrder LegendItemOrder { get; set; }
+
+ ///
+ /// Gets or sets the legend spacing.
+ ///
+ /// The legend spacing.
+ public double LegendItemSpacing { get; set; }
+
+ ///
+ /// Gets or sets the legend margin.
+ ///
+ /// The legend margin.
+ public double LegendMargin { get; set; }
+
+ ///
+ /// Gets or sets the max width of the legend.
+ ///
+ /// The max width of the legend.
+ public double LegendMaxWidth { get; set; }
+
+ ///
+ /// Gets or sets the legend orientation.
+ ///
+ /// The legend orientation.
+ public LegendOrientation LegendOrientation { get; set; }
+
+ ///
+ /// Gets or sets the legend padding.
+ ///
+ /// The legend padding.
+ public double LegendPadding { get; set; }
+
+ ///
+ /// Gets or sets the legend placement.
+ ///
+ /// The legend placement.
+ public LegendPlacement LegendPlacement { get; set; }
+
+ ///
+ /// Gets or sets the legend position.
+ ///
+ /// The legend position.
+ public LegendPosition LegendPosition { get; set; }
+
+ ///
+ /// Gets or sets the length of the legend symbols (the default value is 16).
+ ///
+ public double LegendSymbolLength { get; set; }
+
+ ///
+ /// Gets or sets the legend symbol margins (distance between the symbol and the text).
+ ///
+ /// The legend symbol margin.
+ public double LegendSymbolMargin { get; set; }
+
+ ///
+ /// Gets or sets the legend symbol placement.
+ ///
+ /// The legend symbol placement.
+ public LegendSymbolPlacement LegendSymbolPlacement { get; set; }
+
+ ///
+ /// Gets or sets the legend title.
+ ///
+ /// The legend title.
+ public string LegendTitle { get; set; }
+
+ ///
+ /// Gets or sets the color of the legend title.
+ ///
+ ///
+ /// The color of the legend title.
+ ///
+ ///
+ /// If this value is null, the TextColor will be used.
+ ///
+ public OxyColor LegendTitleColor { get; set; }
+
+ ///
+ /// Gets or sets the legend title font.
+ ///
+ /// The legend title font.
+ public string LegendTitleFont { get; set; }
+
+ ///
+ /// Gets or sets the size of the legend title font.
+ ///
+ /// The size of the legend title font.
+ public double LegendTitleFontSize { get; set; }
+
+ ///
+ /// Gets or sets the legend title font weight.
+ ///
+ /// The legend title font weight.
+ public double LegendTitleFontWeight { get; set; }
+
+ ///
+ /// Gets or sets the padding around the plot.
+ ///
+ /// The padding.
+ public OxyThickness Padding { get; set; }
+
+ ///
+ /// Gets the total width of the plot (in device units).
+ ///
+ public double Width { get; private set; }
+
+ ///
+ /// Gets the total height of the plot (in device units).
+ ///
+ public double Height { get; private set; }
+
+ ///
+ /// Gets the area including both the plot and the axes. Outside legends are rendered outside this rectangle.
+ ///
+ /// The plot and axis area.
+ public OxyRect PlotAndAxisArea { get; private set; }
+
+ ///
+ /// Gets the plot area. This area is used to draw the series (not including axes or legends).
+ ///
+ /// The plot area.
+ public OxyRect PlotArea { get; private set; }
+
+ ///
+ /// Gets or sets the distance between two neighbourhood tiers of the same AxisPosition.
+ ///
+ public double AxisTierDistance { get; set; }
+
+ ///
+ /// Gets or sets the color of the background of the plot area.
+ ///
+ public OxyColor PlotAreaBackground { get; set; }
+
+ ///
+ /// Gets or sets the color of the border around the plot area.
+ ///
+ /// The color of the box.
+ public OxyColor PlotAreaBorderColor { get; set; }
+
+ ///
+ /// Gets or sets the thickness of the border around the plot area.
+ ///
+ /// The box thickness.
+ public double PlotAreaBorderThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum margins around the plot (this should be large enough to fit the axes). The default value is (60, 4, 4, 40). Set AutoAdjustPlotMargins if you want the margins to be adjusted when the axes require more space.
+ ///
+ public OxyThickness PlotMargins { get; set; }
+
+ ///
+ /// Gets or sets the type of the coordinate system.
+ ///
+ /// The type of the plot.
+ public PlotType PlotType { get; set; }
+
+ ///
+ /// Gets or sets the color of the selection.
+ ///
+ ///
+ /// The color of the selection.
+ ///
+ public OxyColor SelectionColor { get; set; }
+
+ ///
+ /// Gets or sets the series.
+ ///
+ /// The series.
+ public Collection Series { get; set; }
+
+ ///
+ /// Gets or sets the subtitle.
+ ///
+ /// The subtitle.
+ public string Subtitle { get; set; }
+
+ ///
+ /// Gets or sets the subtitle font. If this property is null, the Title font will be used.
+ ///
+ /// The subtitle font.
+ public string SubtitleFont { get; set; }
+
+ ///
+ /// Gets or sets the size of the subtitle font.
+ ///
+ /// The size of the subtitle font.
+ public double SubtitleFontSize { get; set; }
+
+ ///
+ /// Gets or sets the subtitle font weight.
+ ///
+ /// The subtitle font weight.
+ public double SubtitleFontWeight { get; set; }
+
+ ///
+ /// Gets or sets the default color of the text in the plot (titles, legends, annotations, axes).
+ ///
+ /// The color of the text.
+ public OxyColor TextColor { get; set; }
+
+ ///
+ /// Gets or sets the title.
+ ///
+ /// The title.
+ public string Title { get; set; }
+
+ ///
+ /// Gets or sets the color of the title.
+ ///
+ ///
+ /// The color of the title.
+ ///
+ ///
+ /// If the value is null, the TextColor will be used.
+ ///
+ public OxyColor TitleColor { get; set; }
+
+ ///
+ /// Gets or sets the color of the subtitle.
+ ///
+ ///
+ /// The color of the subtitle.
+ ///
+ public OxyColor SubtitleColor { get; set; }
+
+ ///
+ /// Gets the title area.
+ ///
+ /// The title area.
+ public OxyRect TitleArea { get; private set; }
+
+ ///
+ /// Gets or sets the title font.
+ ///
+ /// The title font.
+ public string TitleFont { get; set; }
+
+ ///
+ /// Gets or sets the size of the title font.
+ ///
+ /// The size of the title font.
+ public double TitleFontSize { get; set; }
+
+ ///
+ /// Gets or sets the title font weight.
+ ///
+ /// The title font weight.
+ public double TitleFontWeight { get; set; }
+
+ ///
+ /// Gets or sets the padding around the title.
+ ///
+ /// The title padding.
+ public double TitlePadding { get; set; }
+
+ ///
+ /// Gets the default angle axis.
+ ///
+ /// The default angle axis.
+ public AngleAxis DefaultAngleAxis { get; private set; }
+
+ ///
+ /// Gets the default magnitude axis.
+ ///
+ /// The default magnitude axis.
+ public MagnitudeAxis DefaultMagnitudeAxis { get; private set; }
+
+ ///
+ /// Gets the default X axis.
+ ///
+ /// The default X axis.
+ public Axis DefaultXAxis { get; private set; }
+
+ ///
+ /// Gets the default Y axis.
+ ///
+ /// The default Y axis.
+ public Axis DefaultYAxis { get; private set; }
+
+ ///
+ /// Gets the default color axis.
+ ///
+ /// The default color axis.
+ public ColorAxis DefaultColorAxis { get; private set; }
+
+ ///
+ /// Gets the actual title font.
+ ///
+ protected string ActualTitleFont
+ {
+ get
+ {
+ return this.TitleFont ?? this.DefaultFont;
+ }
+ }
+
+ ///
+ /// Gets the actual subtitle font.
+ ///
+ protected string ActualSubtitleFont
+ {
+ get
+ {
+ return this.SubtitleFont ?? this.DefaultFont;
+ }
+ }
+
+ ///
+ /// Gets the visible series.
+ ///
+ /// The visible series.
+ private IEnumerable VisibleSeries
+ {
+ get
+ {
+ return this.Series.Where(s => s.IsVisible);
+ }
+ }
+
+ ///
+ /// Attaches this model to the specified plot control.
+ ///
+ /// The plot control.
+ ///
+ /// Only one plot control can be attached to the plot model.
+ /// The plot model contains data (e.g. axis scaling) that is only relevant to the current plot control.
+ ///
+ public void AttachPlotControl(IPlotControl plotControl)
+ {
+ this.PlotControl = plotControl;
+ }
+
+ ///
+ /// Creates a report for the plot.
+ ///
+ ///
+ /// A report.
+ ///
+ public Report CreateReport()
+ {
+ var r = new Report { Culture = CultureInfo.InvariantCulture };
+
+ r.AddHeader(1, "P L O T R E P O R T");
+ r.AddHeader(2, "=== PlotModel ===");
+ r.AddPropertyTable("PlotModel", this);
+
+ r.AddHeader(2, "=== Axes ===");
+ foreach (Axis a in this.Axes)
+ {
+ r.AddPropertyTable(a.GetType().Name, a);
+ }
+
+ r.AddHeader(2, "=== Annotations ===");
+ foreach (var a in this.Annotations)
+ {
+ r.AddPropertyTable(a.GetType().Name, a);
+ }
+
+ r.AddHeader(2, "=== Series ===");
+ foreach (var s in this.Series)
+ {
+ r.AddPropertyTable(s.GetType().Name, s);
+ var ds = s as DataPointSeries;
+ if (ds != null)
+ {
+ var fields = new List { new ItemsTableField("X", "X"), new ItemsTableField("Y", "Y") };
+ r.AddItemsTable("Data", ds.Points, fields);
+ }
+ }
+
+ var assemblyName = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
+ r.AddParagraph(string.Format("Report generated by OxyPlot {0}", assemblyName.Version.ToString(3)));
+
+ return r;
+ }
+
+ ///
+ /// Creates a text report for the plot.
+ ///
+ ///
+ /// The create text report.
+ ///
+ public string CreateTextReport()
+ {
+ using (var ms = new MemoryStream())
+ {
+ var trw = new TextReportWriter(ms);
+ Report report = this.CreateReport();
+ report.Write(trw);
+ trw.Flush();
+ ms.Position = 0;
+ var r = new StreamReader(ms);
+ return r.ReadToEnd();
+ }
+ }
+
+ ///
+ /// Refreshes the plot.
+ ///
+ /// Updates all data sources if set to true.
+ public void RefreshPlot(bool updateData)
+ {
+ if (this.PlotControl == null)
+ {
+ return;
+ }
+
+ this.PlotControl.RefreshPlot(updateData);
+ }
+
+ ///
+ /// Invalidates the plot.
+ ///
+ /// Updates all data sources if set to true.
+ public void InvalidatePlot(bool updateData)
+ {
+ if (this.PlotControl == null)
+ {
+ return;
+ }
+
+ this.PlotControl.InvalidatePlot(updateData);
+ }
+
+ ///
+ /// Gets the first axes that covers the area of the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The xaxis.
+ ///
+ ///
+ /// The yaxis.
+ ///
+ public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
+ {
+ xaxis = yaxis = null;
+
+ // Get the axis position of the given point. Using null if the point is inside the plot area.
+ AxisPosition? position = null;
+ double plotAreaValue = 0;
+ if (pt.X < this.PlotArea.Left)
+ {
+ position = AxisPosition.Left;
+ plotAreaValue = this.PlotArea.Left;
+ }
+
+ if (pt.X > this.PlotArea.Right)
+ {
+ position = AxisPosition.Right;
+ plotAreaValue = this.PlotArea.Right;
+ }
+
+ if (pt.Y < this.PlotArea.Top)
+ {
+ position = AxisPosition.Top;
+ plotAreaValue = this.PlotArea.Top;
+ }
+
+ if (pt.Y > this.PlotArea.Bottom)
+ {
+ position = AxisPosition.Bottom;
+ plotAreaValue = this.PlotArea.Bottom;
+ }
+
+ foreach (var axis in this.Axes)
+ {
+ if (axis is ColorAxis)
+ {
+ continue;
+ }
+
+ if (axis is MagnitudeAxis)
+ {
+ xaxis = axis;
+ continue;
+ }
+
+ if (axis is AngleAxis)
+ {
+ yaxis = axis;
+ continue;
+ }
+
+ double x = double.NaN;
+ if (axis.IsHorizontal())
+ {
+ x = axis.InverseTransform(pt.X);
+ }
+
+ if (axis.IsVertical())
+ {
+ x = axis.InverseTransform(pt.Y);
+ }
+
+ if (x >= axis.ActualMinimum && x <= axis.ActualMaximum)
+ {
+ if (position == null)
+ {
+ if (axis.IsHorizontal())
+ {
+ if (xaxis == null)
+ {
+ xaxis = axis;
+ }
+ }
+ else if (axis.IsVertical())
+ {
+ if (yaxis == null)
+ {
+ yaxis = axis;
+ }
+ }
+ }
+ else if (position == axis.Position)
+ {
+ // Choose right tier
+ double positionTierMinShift = axis.PositionTierMinShift;
+ double positionTierMaxShift = axis.PositionTierMaxShift;
+
+ double posValue = axis.IsHorizontal() ? pt.Y : pt.X;
+ bool isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left;
+ if ((posValue >= plotAreaValue + positionTierMinShift
+ && posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop)
+ ||
+ (posValue <= plotAreaValue - positionTierMinShift
+ && posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop))
+ {
+ if (axis.IsHorizontal())
+ {
+ if (xaxis == null)
+ {
+ xaxis = axis;
+ }
+ }
+ else if (axis.IsVertical())
+ {
+ if (yaxis == null)
+ {
+ yaxis = axis;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the default color from the DefaultColors palette.
+ ///
+ ///
+ /// The next default color.
+ ///
+ public OxyColor GetDefaultColor()
+ {
+ return this.DefaultColors[this.currentColorIndex++ % this.DefaultColors.Count];
+ }
+
+ ///
+ /// Gets the default line style.
+ ///
+ ///
+ /// The next default line style.
+ ///
+ public LineStyle GetDefaultLineStyle()
+ {
+ return (LineStyle)((this.currentColorIndex / this.DefaultColors.Count) % (int)LineStyle.None);
+ }
+
+ ///
+ /// Gets a series from the specified point.
+ ///
+ ///
+ /// The point.
+ ///
+ ///
+ /// The limit.
+ ///
+ ///
+ /// The nearest series.
+ ///
+ public Series.Series GetSeriesFromPoint(ScreenPoint point, double limit)
+ {
+ double mindist = double.MaxValue;
+ Series.Series closest = null;
+ foreach (var s in this.VisibleSeries.Reverse())
+ {
+ var ts = s as ITrackableSeries;
+ if (ts == null)
+ {
+ continue;
+ }
+
+ var thr = ts.GetNearestPoint(point, true) ?? ts.GetNearestPoint(point, false);
+
+ if (thr == null)
+ {
+ continue;
+ }
+
+ // find distance to this point on the screen
+ double dist = point.DistanceTo(thr.Position);
+ if (dist < mindist)
+ {
+ closest = s;
+ mindist = dist;
+ }
+ }
+
+ if (mindist < limit)
+ {
+ return closest;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Generates C# code of the model.
+ ///
+ ///
+ /// C# code.
+ ///
+ public string ToCode()
+ {
+ var cg = new CodeGenerator(this);
+ return cg.ToCode();
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return this.Title;
+ }
+
+ ///
+ /// Create an svg model and return it as a string.
+ ///
+ /// The width (points).
+ /// The height (points).
+ /// if set to true, the xml headers will be included (?xml and !DOCTYPE).
+ /// The text measurer.
+ /// The svg string.
+ public string ToSvg(double width, double height, bool isDocument, IRenderContext textMeasurer)
+ {
+ return SvgExporter.ExportToString(this, width, height, isDocument, textMeasurer);
+ }
+
+ ///
+ /// Gets all elements of the plot model.
+ ///
+ /// An enumerator of the plot elements.
+ public IEnumerable GetElements()
+ {
+ foreach (var axis in this.Axes)
+ {
+ yield return axis;
+ }
+
+ foreach (var annotation in this.Annotations)
+ {
+ yield return annotation;
+ }
+
+ foreach (var s in this.Series)
+ {
+ yield return s;
+ }
+ }
+
+ ///
+ /// Updates all axes and series. 0. Updates the owner PlotModel of all plot items (axes, series and annotations)
+ /// 1. Updates the data of each Series (only if updateData==true).
+ /// 2. Ensure that all series have axes assigned.
+ /// 3. Updates the max and min of the axes.
+ ///
+ ///
+ /// if set to true , all data collections will be updated.
+ ///
+ public void Update(bool updateData = true)
+ {
+ lock (this.syncRoot)
+ {
+ this.OnUpdating();
+
+ // update the owner PlotModel
+ foreach (var s in this.VisibleSeries)
+ {
+ s.PlotModel = this;
+ }
+
+ foreach (var a in this.Annotations)
+ {
+ a.PlotModel = this;
+ }
+
+ // Updates the default axes
+ this.EnsureDefaultAxes();
+
+ // Update data of the series
+ if (updateData)
+ {
+ foreach (var s in this.VisibleSeries)
+ {
+ s.UpdateData();
+ }
+ }
+
+ foreach (var a in this.Axes)
+ {
+ a.PlotModel = this;
+ }
+
+ foreach (var c in this.Axes.OfType())
+ {
+ c.UpdateLabels(this.VisibleSeries);
+ }
+
+ // Update valid data of the series
+ if (updateData)
+ {
+ foreach (var s in this.VisibleSeries)
+ {
+ s.UpdateValidData();
+ }
+ }
+
+ // Updates axes with information from the series
+ // This is used by the category axis that need to know the number of series using the axis.
+ foreach (var a in this.Axes)
+ {
+ a.UpdateFromSeries(this.VisibleSeries);
+ }
+
+ // Update the max and min of the axes
+ this.UpdateMaxMin(updateData);
+ this.OnUpdated();
+ }
+ }
+
+ ///
+ /// Updates the axis transforms.
+ ///
+ public void UpdateAxisTransforms()
+ {
+ // Update the axis transforms
+ foreach (var a in this.Axes)
+ {
+ a.UpdateTransform(this.PlotArea);
+ }
+ }
+
+ ///
+ /// Gets the axis for the specified key.
+ ///
+ /// The key.
+ /// The default axis.
+ /// The axis, or the defaultAxis if the key is not found.
+ public Axis GetAxisOrDefault(string key, Axis defaultAxis)
+ {
+ if (key != null)
+ {
+ return this.Axes.FirstOrDefault(a => a.Key == key) ?? defaultAxis;
+ }
+
+ return defaultAxis;
+ }
+
+ ///
+ /// Raises the Updated event.
+ ///
+ protected virtual void OnUpdated()
+ {
+ var handler = this.Updated;
+ if (handler != null)
+ {
+ var args = new EventArgs();
+ handler(this, args);
+ }
+ }
+
+ ///
+ /// Raises the Updating event.
+ ///
+ protected virtual void OnUpdating()
+ {
+ var handler = this.Updating;
+ if (handler != null)
+ {
+ var args = new EventArgs();
+ handler(this, args);
+ }
+ }
+
+ ///
+ /// Enforces the same scale on all axes.
+ ///
+ private void EnforceCartesianTransforms()
+ {
+ // Set the same scaling on all axes
+ double sharedScale = this.Axes.Min(a => Math.Abs(a.Scale));
+ foreach (var a in this.Axes)
+ {
+ a.Zoom(sharedScale);
+ }
+
+ sharedScale = this.Axes.Max(a => Math.Abs(a.Scale));
+ foreach (var a in this.Axes)
+ {
+ a.Zoom(sharedScale);
+ }
+
+ foreach (var a in this.Axes)
+ {
+ a.UpdateTransform(this.PlotArea);
+ }
+ }
+
+ ///
+ /// Updates the intervals (major and minor step values).
+ ///
+ private void UpdateIntervals()
+ {
+ // Update the intervals for all axes
+ foreach (var a in this.Axes)
+ {
+ a.UpdateIntervals(this.PlotArea);
+ }
+ }
+
+ ///
+ /// Finds and sets the default horizontal and vertical axes (the first horizontal/vertical axes in the Axes collection).
+ ///
+ private void EnsureDefaultAxes()
+ {
+ this.DefaultXAxis = this.Axes.FirstOrDefault(a => a.IsHorizontal() && a.IsXyAxis());
+ this.DefaultYAxis = this.Axes.FirstOrDefault(a => a.IsVertical() && a.IsXyAxis());
+ this.DefaultMagnitudeAxis = this.Axes.FirstOrDefault(a => a is MagnitudeAxis) as MagnitudeAxis;
+ this.DefaultAngleAxis = this.Axes.FirstOrDefault(a => a is AngleAxis) as AngleAxis;
+ this.DefaultColorAxis = this.Axes.FirstOrDefault(a => a is ColorAxis) as ColorAxis;
+
+ if (this.DefaultXAxis == null)
+ {
+ this.DefaultXAxis = this.DefaultMagnitudeAxis;
+ }
+
+ if (this.DefaultYAxis == null)
+ {
+ this.DefaultYAxis = this.DefaultAngleAxis;
+ }
+
+ if (this.PlotType == PlotType.Polar)
+ {
+ if (this.DefaultXAxis == null)
+ {
+ this.DefaultXAxis = this.DefaultMagnitudeAxis = new MagnitudeAxis();
+ }
+
+ if (this.DefaultYAxis == null)
+ {
+ this.DefaultYAxis = this.DefaultAngleAxis = new AngleAxis();
+ }
+ }
+ else
+ {
+ bool createdlinearxaxis = false;
+ bool createdlinearyaxis = false;
+ if (this.DefaultXAxis == null)
+ {
+ if (this.Series.Any(series => series is ColumnSeries))
+ {
+ this.DefaultXAxis = new CategoryAxis { Position = AxisPosition.Bottom };
+ }
+ else
+ {
+ this.DefaultXAxis = new LinearAxis { Position = AxisPosition.Bottom };
+ createdlinearxaxis = true;
+ }
+ }
+
+ if (this.DefaultYAxis == null)
+ {
+ if (this.Series.Any(series => series is BarSeries))
+ {
+ this.DefaultYAxis = new CategoryAxis { Position = AxisPosition.Left };
+ }
+ else
+ {
+ this.DefaultYAxis = new LinearAxis { Position = AxisPosition.Left };
+ createdlinearyaxis = true;
+ }
+ }
+
+ if (createdlinearxaxis && this.DefaultYAxis is CategoryAxis)
+ {
+ this.DefaultXAxis.MinimumPadding = 0;
+ }
+
+ if (createdlinearyaxis && this.DefaultXAxis is CategoryAxis)
+ {
+ this.DefaultYAxis.MinimumPadding = 0;
+ }
+ }
+
+ bool areAxesRequired = false;
+ foreach (var s in this.VisibleSeries)
+ {
+ if (s.AreAxesRequired())
+ {
+ areAxesRequired = true;
+ }
+ }
+
+ if (areAxesRequired)
+ {
+ if (!this.Axes.Contains(this.DefaultXAxis))
+ {
+ Debug.Assert(this.DefaultXAxis != null, "Default x-axis not created.");
+ if (this.DefaultXAxis != null)
+ {
+ this.Axes.Add(this.DefaultXAxis);
+ }
+ }
+
+ if (!this.Axes.Contains(this.DefaultYAxis))
+ {
+ Debug.Assert(this.DefaultYAxis != null, "Default y-axis not created.");
+ if (this.DefaultYAxis != null)
+ {
+ this.Axes.Add(this.DefaultYAxis);
+ }
+ }
+ }
+
+ // Update the x/index axes of series without axes defined
+ foreach (var s in this.VisibleSeries)
+ {
+ if (s.AreAxesRequired())
+ {
+ s.EnsureAxes();
+ }
+ }
+
+ // Update the x/index axes of annotations without axes defined
+ foreach (var a in this.Annotations)
+ {
+ a.EnsureAxes();
+ }
+ }
+
+ ///
+ /// Resets the default color index.
+ ///
+ private void ResetDefaultColor()
+ {
+ this.currentColorIndex = 0;
+ }
+
+ ///
+ /// Updates maximum and minimum values of the axes from values of all data series.
+ ///
+ ///
+ /// if set to true , the data has been updated.
+ ///
+ private void UpdateMaxMin(bool isDataUpdated)
+ {
+ if (isDataUpdated)
+ {
+ foreach (var a in this.Axes)
+ {
+ a.ResetDataMaxMin();
+ }
+
+ // data has been updated, so we need to calculate the max/min of the series again
+ foreach (var s in this.VisibleSeries)
+ {
+ s.UpdateMaxMin();
+ }
+ }
+
+ foreach (var s in this.VisibleSeries)
+ {
+ s.UpdateAxisMaxMin();
+ }
+
+ foreach (var a in this.Axes)
+ {
+ a.UpdateActualMaxMin();
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/SelectablePlotElement.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/SelectablePlotElement.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,159 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a plot element that supports selection.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides an abstract base class for plot elements that support selection.
+ ///
+ public abstract class SelectablePlotElement : PlotElement
+ {
+ ///
+ /// The is selected.
+ ///
+ private bool isSelected;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected SelectablePlotElement()
+ {
+ this.Selectable = true;
+ this.IsSelected = false;
+ }
+
+ ///
+ /// Occurs when the IsSelected property is changed.
+ ///
+ public event EventHandler Selected;
+
+ ///
+ /// Gets or sets the index of the selected item (or -1 if all items are selected).
+ ///
+ ///
+ /// The index of the selected.
+ ///
+ public int SelectedIndex { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this plot element is selected.
+ ///
+ public bool IsSelected
+ {
+ get
+ {
+ return this.isSelected;
+ }
+
+ set
+ {
+ if (value == this.isSelected)
+ {
+ return;
+ }
+
+ this.isSelected = value;
+ this.OnIsSelectedChanged();
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether this plot element can be selected.
+ ///
+ public bool Selectable { get; set; }
+
+ ///
+ /// Gets the actual selection color.
+ ///
+ /// The actual selection color.
+ protected OxyColor ActualSelectedColor
+ {
+ get
+ {
+ if (this.PlotModel != null)
+ {
+ return this.PlotModel.SelectionColor ?? PlotModel.DefaultSelectionColor;
+ }
+
+ return PlotModel.DefaultSelectionColor;
+ }
+ }
+
+ ///
+ /// Gets the selection color it the element is selected, or the specified color if it is not.
+ ///
+ /// The unselected color of the element.
+ /// The index of the item to check (use -1 for all items).
+ ///
+ /// A color.
+ ///
+ protected OxyColor GetSelectableColor(OxyColor originalColor, int index = -1)
+ {
+ if (originalColor == null)
+ {
+ return null;
+ }
+
+ if (this.IsSelected && (index == -1 || index == this.SelectedIndex))
+ {
+ return this.ActualSelectedColor;
+ }
+
+ return originalColor;
+ }
+
+ ///
+ /// Gets the selection fill color it the element is selected, or the specified fill color if it is not.
+ ///
+ /// The unselected fill color of the element.
+ /// The index of the item to check (use -1 for all items).
+ ///
+ /// A fill color.
+ ///
+ protected OxyColor GetSelectableFillColor(OxyColor originalColor, int index = -1)
+ {
+ return this.GetSelectableColor(originalColor, index);
+ }
+
+ ///
+ /// Raises the Selected event.
+ ///
+ protected void OnIsSelectedChanged()
+ {
+ var eh = this.Selected;
+ if (eh != null)
+ {
+ eh(this, new EventArgs());
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/PlotModel/UIPlotElement.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/PlotModel/UIPlotElement.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,116 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a plot element that handles mouse events.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides an abstract base class for plot elements that handle mouse events.
+ ///
+ public abstract class UIPlotElement : SelectablePlotElement
+ {
+ ///
+ /// Occurs when a mouse button is pressed down on the model.
+ ///
+ public event EventHandler MouseDown;
+
+ ///
+ /// Occurs when the mouse is moved on the plot element (only occurs after MouseDown).
+ ///
+ public event EventHandler MouseMove;
+
+ ///
+ /// Occurs when the mouse button is released on the plot element.
+ ///
+ public event EventHandler MouseUp;
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected internal virtual void OnMouseDown(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseDown != null)
+ {
+ this.MouseDown(sender, e);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected internal virtual void OnMouseMove(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseMove != null)
+ {
+ this.MouseMove(sender, e);
+ }
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The sender.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ protected internal virtual void OnMouseUp(object sender, OxyMouseEventArgs e)
+ {
+ if (this.MouseUp != null)
+ {
+ this.MouseUp(sender, e);
+ }
+ }
+
+ ///
+ /// Tests if the plot element is hit by the specified point.
+ ///
+ /// The point.
+ /// The tolerance.
+ ///
+ /// A hit test result.
+ ///
+ protected internal abstract HitTestResult HitTest(ScreenPoint point, double tolerance);
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Properties/AssemblyInfo.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Properties/AssemblyInfo.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,10 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// http://oxyplot.codeplex.com, license: MIT
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+using System.Reflection;
+
+[assembly: AssemblyTitle("OxyPlot")]
+[assembly: AssemblyDescription("OxyPlot core library")]
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/AngleAxisRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/AngleAxisRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,166 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The angle axis renderer.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Provides functionality to render .
+ ///
+ public class AngleAxisRenderer : AxisRendererBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot.
+ ///
+ public AngleAxisRenderer(IRenderContext rc, PlotModel plot)
+ : base(rc, plot)
+ {
+ }
+
+ ///
+ /// Renders the specified axis.
+ ///
+ /// The axis.
+ /// The render pass.
+ /// Magnitude axis not defined.
+ public override void Render(Axis axis, int pass)
+ {
+ base.Render(axis, pass);
+
+ var magnitudeAxis = this.Plot.DefaultMagnitudeAxis;
+
+ if (axis.RelatedAxis != null)
+ {
+ magnitudeAxis = axis.RelatedAxis as MagnitudeAxis;
+ }
+
+ if (magnitudeAxis == null)
+ {
+ throw new InvalidOperationException("Magnitude axis not defined.");
+ }
+
+ double eps = axis.MinorStep * 1e-3;
+
+ if (axis.ShowMinorTicks)
+ {
+ foreach (double value in this.MinorTickValues)
+ {
+ if (value < axis.ActualMinimum - eps || value > axis.ActualMaximum + eps)
+ {
+ continue;
+ }
+
+ if (this.MajorTickValues.Contains(value))
+ {
+ continue;
+ }
+
+ var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
+
+ if (this.MinorPen != null)
+ {
+ this.rc.DrawLine(magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, pt.x, pt.y, this.MinorPen, false);
+ }
+ }
+ }
+
+ var angleAxis = (AngleAxis)axis;
+ bool isFullCircle = Math.Abs(Math.Abs(angleAxis.EndAngle - angleAxis.StartAngle) - 360) < 1e-6;
+
+ foreach (double value in this.MajorTickValues)
+ {
+ // skip the last value (overlapping with the first)
+ if (isFullCircle && value > axis.ActualMaximum - eps)
+ {
+ continue;
+ }
+
+ if (value < axis.ActualMinimum - eps || value > axis.ActualMaximum + eps)
+ {
+ continue;
+ }
+
+ ScreenPoint pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
+ if (this.MajorPen != null)
+ {
+ this.rc.DrawLine(
+ magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, pt.x, pt.y, this.MajorPen, false);
+ }
+ }
+
+ foreach (double value in this.MajorLabelValues)
+ {
+ // skip the last value (overlapping with the first)
+ if (isFullCircle && value > axis.ActualMaximum - eps)
+ {
+ continue;
+ }
+
+ var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
+ double angle = Math.Atan2(pt.y - magnitudeAxis.MidPoint.y, pt.x - magnitudeAxis.MidPoint.x);
+
+ // add some margin
+ pt.x += Math.Cos(angle) * axis.AxisTickToLabelDistance;
+ pt.y += Math.Sin(angle) * axis.AxisTickToLabelDistance;
+
+ // Convert to degrees
+ angle *= 180 / Math.PI;
+
+ string text = axis.FormatValue(value);
+
+ var ha = HorizontalAlignment.Left;
+ var va = VerticalAlignment.Middle;
+
+ if (Math.Abs(Math.Abs(angle) - 90) < 10)
+ {
+ ha = HorizontalAlignment.Center;
+ va = angle > 90 ? VerticalAlignment.Top : VerticalAlignment.Bottom;
+ angle = 0;
+ }
+ else if (angle > 90 || angle < -90)
+ {
+ angle -= 180;
+ ha = HorizontalAlignment.Right;
+ }
+
+ this.rc.DrawMathText(
+ pt, text, axis.ActualTextColor, axis.ActualFont, axis.ActualFontSize, axis.ActualFontWeight, angle, ha, va);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/AxisRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/AxisRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,532 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+
+namespace OxyPlot
+{
+ public class AxisRenderer
+ {
+ private const double AXIS_LEGEND_DIST = 4; // distance from axis number to axis legend
+ private const double TICK_DIST = 8; // distance from axis tick to number
+
+ private OxyPen extraPen;
+ private OxyPen majorPen;
+ private OxyPen majorTickPen;
+
+ private ICollection majorTickValues;
+ private OxyPen minorPen;
+ private OxyPen minorTickPen;
+ private ICollection minorTickValues;
+ private OxyPen zeroPen;
+
+ protected readonly PlotModel Plot;
+ protected readonly IRenderContext rc;
+
+ public AxisRenderer(IRenderContext rc, PlotModel plot)
+ {
+ this.Plot = plot;
+ this.rc = rc;
+ }
+
+ public void Render(Axis axis)
+ {
+ if (axis == null)
+ return;
+
+ axis.GetTickValues(out majorTickValues, out minorTickValues);
+
+ CreatePens(axis);
+
+ if (axis.IsHorizontal())
+ {
+ RenderHorizontalAxis(axis, Plot.DefaultYAxis);
+ }
+ if (axis.IsVertical())
+ {
+ RenderVerticalAxis(axis, Plot.DefaultXAxis);
+ }
+ if (axis.Position == AxisPosition.Angle)
+ {
+ RenderAngleAxis(axis, Plot.DefaultMagnitudeAxis);
+ }
+ if (axis.Position == AxisPosition.Magnitude)
+ {
+ RenderMagnitudeAxis(axis, Plot.DefaultAngleAxis);
+ }
+ }
+
+ private void RenderMagnitudeAxis(Axis axis, Axis angleAxis)
+ {
+ if (axis.RelatedAxis != null)
+ angleAxis = axis.RelatedAxis;
+
+ if (axis.ShowMinorTicks)
+ {
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
+
+ foreach (double xValue in minorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (majorTickValues.Contains(xValue))
+ {
+ continue;
+ }
+
+ var pts = new List();
+ for (double th = angleAxis.ActualMinimum;
+ th <= angleAxis.ActualMaximum;
+ th += angleAxis.MinorStep*0.1)
+ {
+ pts.Add(axis.Transform(xValue, th, angleAxis));
+ }
+
+ if (minorPen != null)
+ {
+ rc.DrawLine(pts, minorPen.Color, minorPen.Thickness, minorPen.DashArray);
+ }
+ // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
+ }
+ }
+
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
+
+ foreach (double xValue in majorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ var pts = new List();
+ for (double th = angleAxis.ActualMinimum; th <= angleAxis.ActualMaximum; th += angleAxis.MinorStep*0.1)
+ {
+ pts.Add(axis.Transform(xValue, th, angleAxis));
+ }
+
+ if (majorPen != null)
+ {
+ rc.DrawLine(pts, majorPen.Color, majorPen.Thickness, majorPen.DashArray);
+ }
+
+ // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
+
+ //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
+ //string text = axis.FormatValue(xValue);
+ //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
+
+ //rc.DrawText(pt, text, plot.TextColor,
+ // axis.FontFamily, axis.FontSize, axis.FontWeight,
+ // axis.Angle,
+ // HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
+
+ //maxh = Math.Max(maxh, h);
+ }
+ }
+
+ private void RenderAngleAxis(Axis axis, Axis magnitudeAxis)
+ {
+ if (axis.RelatedAxis != null)
+ magnitudeAxis = axis.RelatedAxis;
+
+ if (axis.ShowMinorTicks)
+ {
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
+
+ foreach (double xValue in minorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (majorTickValues.Contains(xValue))
+ {
+ continue;
+ }
+
+ var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);
+
+ if (minorPen != null)
+ {
+ RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, minorPen, false);
+ }
+ // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
+ }
+ }
+
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
+
+ foreach (double xValue in majorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);
+
+ if (majorPen != null)
+ {
+ RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, majorPen, false);
+ }
+ // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
+
+ //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
+ //string text = axis.FormatValue(xValue);
+ //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
+
+ //rc.DrawText(pt, text, plot.TextColor,
+ // axis.FontFamily, axis.FontSize, axis.FontWeight,
+ // axis.Angle,
+ // HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
+
+ //maxh = Math.Max(maxh, h);
+ }
+ }
+
+ private void RenderLine(double x0, double y0, double x1, double y1, OxyPen pen, bool aliased = true)
+ {
+ if (pen == null)
+ return;
+
+ rc.DrawLine(new[]
+ {
+ new ScreenPoint(x0, y0),
+ new ScreenPoint(x1, y1)
+ }, pen.Color, pen.Thickness, pen.DashArray, aliased);
+ }
+
+ private void GetVerticalTickPositions(Axis axis, TickStyle glt, double ticksize,
+ out double y0, out double y1)
+ {
+ y0 = 0;
+ y1 = 0;
+ bool istop = axis.Position == AxisPosition.Top;
+ double topsign = istop ? -1 : 1;
+ switch (glt)
+ {
+ case TickStyle.Crossing:
+ y0 = -ticksize*topsign;
+ y1 = ticksize*topsign;
+ break;
+ case TickStyle.Inside:
+ y0 = -ticksize*topsign;
+ break;
+ case TickStyle.Outside:
+ y1 = ticksize*topsign;
+ break;
+ }
+ }
+
+ private void GetHorizontalTickPositions(Axis axis, TickStyle glt, double ticksize, out double x0,
+ out double x1)
+ {
+ x0 = 0;
+ x1 = 0;
+ bool isLeft = axis.Position == AxisPosition.Left;
+ double leftSign = isLeft ? -1 : 1;
+ switch (glt)
+ {
+ case TickStyle.Crossing:
+ x0 = -ticksize*leftSign;
+ x1 = ticksize*leftSign;
+ break;
+ case TickStyle.Inside:
+ x0 = -ticksize*leftSign;
+ break;
+ case TickStyle.Outside:
+ x1 = ticksize*leftSign;
+ break;
+ }
+ }
+
+ public void CreatePens(Axis axis)
+ {
+ minorPen = CreatePen(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
+ majorPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
+ minorTickPen = CreatePen(axis.TicklineColor, axis.MinorGridlineThickness, LineStyle.Solid);
+ majorTickPen = CreatePen(axis.TicklineColor, axis.MajorGridlineThickness, LineStyle.Solid);
+ zeroPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
+ extraPen = CreatePen(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
+ }
+
+ private void RenderHorizontalAxis(Axis axis, Axis perpendicularAxis)
+ {
+ double y = Plot.Bounds.Bottom;
+ switch (axis.Position)
+ {
+ case AxisPosition.Top:
+ y = Plot.Bounds.Top;
+ break;
+ case AxisPosition.Bottom:
+ y = Plot.Bounds.Bottom;
+ break;
+ }
+ if (axis.PositionAtZeroCrossing)
+ {
+ y = perpendicularAxis.TransformX(0);
+ }
+
+ double y0, y1;
+
+ if (axis.ShowMinorTicks)
+ {
+ GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
+
+ foreach (double xValue in minorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (majorTickValues.Contains(xValue))
+ {
+ continue;
+ }
+
+ double x = axis.TransformX(xValue);
+ if (minorPen != null)
+ {
+ RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, minorPen);
+ }
+ RenderLine(x, y + y0, x, y + y1, minorTickPen);
+ }
+ }
+
+ GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
+
+ double maxh = 0;
+ bool istop = axis.Position == AxisPosition.Top;
+ foreach (double xValue in majorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ double x = axis.TransformX(xValue);
+
+ if (majorPen != null)
+ {
+ RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);
+ }
+ RenderLine(x, y + y0, x, y + y1, majorTickPen);
+
+ if (xValue == 0 && axis.PositionAtZeroCrossing)
+ continue;
+
+ var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
+ string text = axis.FormatValue(xValue);
+ double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
+
+ rc.DrawText(pt, text, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight,
+ axis.Angle,
+ HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
+
+ maxh = Math.Max(maxh, h);
+ }
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ double x = axis.TransformX(0);
+ RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, zeroPen);
+ }
+
+ if (axis.ExtraGridlines != null)
+ {
+ foreach (double x in axis.ExtraGridlines)
+ {
+ if (!IsWithin(x, axis.ActualMinimum, axis.ActualMaximum))
+ continue;
+ double sx = axis.TransformX(x);
+ RenderLine(sx, Plot.Bounds.Top, sx, Plot.Bounds.Bottom, extraPen);
+ }
+ }
+
+ // The horizontal axis line
+ RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);
+
+ // The horizontal axis legend (centered horizontally)
+ double legendX = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);
+ HorizontalTextAlign halign = HorizontalTextAlign.Center;
+ VerticalTextAlign valign = VerticalTextAlign.Bottom;
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ legendX = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
+ }
+
+ double legendY = rc.Height - AXIS_LEGEND_DIST;
+ if (istop)
+ {
+ legendY = AXIS_LEGEND_DIST;
+ valign = VerticalTextAlign.Top;
+ }
+ rc.DrawText(new ScreenPoint(legendX, legendY),
+ axis.Title, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight, 0, halign, valign);
+ }
+
+ private OxyPen CreatePen(OxyColor c, double th, LineStyle ls)
+ {
+ if (ls == LineStyle.None || th == 0)
+ return null;
+ return new OxyPen(c, th, ls);
+ }
+
+ private void RenderVerticalAxis(Axis axis, Axis perpendicularAxis)
+ {
+ double x = Plot.Bounds.Left;
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ x = Plot.Bounds.Left;
+ break;
+ case AxisPosition.Right:
+ x = Plot.Bounds.Right;
+ break;
+ }
+ if (axis.PositionAtZeroCrossing)
+ x = perpendicularAxis.TransformX(0);
+
+ double x0, x1;
+
+ if (axis.ShowMinorTicks)
+ {
+ GetHorizontalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out x0, out x1);
+ foreach (double yValue in minorTickValues)
+ {
+ if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (majorTickValues.Contains(yValue))
+ {
+ continue;
+ }
+ double y = axis.TransformX(yValue);
+
+ if (minorPen != null)
+ {
+ RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, minorPen);
+ }
+
+ RenderLine(x + x0, y, x + x1, y, minorTickPen);
+ }
+ }
+
+ GetHorizontalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out x0, out x1);
+ double maxw = 0;
+
+ bool isleft = axis.Position == AxisPosition.Left;
+
+ foreach (double yValue in majorTickValues)
+ {
+ if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
+ continue;
+
+ double y = axis.TransformX(yValue);
+
+ if (majorPen != null)
+ {
+ RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);
+ }
+
+ RenderLine(x + x0, y, x + x1, y, majorTickPen);
+
+ if (yValue == 0 && axis.PositionAtZeroCrossing)
+ continue;
+
+ var pt = new ScreenPoint(isleft ? x + x1 - TICK_DIST : x + x1 + TICK_DIST, y);
+ string text = axis.FormatValue(yValue);
+ double w = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
+ rc.DrawText(pt, text, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight,
+ axis.Angle,
+ isleft ? HorizontalTextAlign.Right : HorizontalTextAlign.Left, VerticalTextAlign.Middle);
+ maxw = Math.Max(maxw, w);
+ }
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ double y = axis.TransformX(0);
+ RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, zeroPen);
+ }
+
+ if (axis.ExtraGridlines != null)
+ foreach (double y in axis.ExtraGridlines)
+ {
+ if (!IsWithin(y, axis.ActualMinimum, axis.ActualMaximum))
+ continue;
+ double sy = axis.TransformX(y);
+ RenderLine(Plot.Bounds.Left, sy, Plot.Bounds.Right, sy, extraPen);
+ }
+
+ RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);
+
+ double ymid = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);
+
+ HorizontalTextAlign halign = HorizontalTextAlign.Center;
+ VerticalTextAlign valign = VerticalTextAlign.Top;
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ ymid = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
+ // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
+ }
+
+ if (isleft)
+ {
+ x = AXIS_LEGEND_DIST;
+ }
+ else
+ {
+ x = rc.Width - AXIS_LEGEND_DIST;
+ valign = VerticalTextAlign.Bottom;
+ }
+
+ rc.DrawText(new ScreenPoint(x, ymid), axis.Title, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight,
+ -90, halign, valign);
+ }
+
+ private bool IsWithin(double d, double min, double max)
+ {
+ if (d < min) return false;
+ if (d > max) return false;
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/AxisRendererBase.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/AxisRendererBase.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,217 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The axis renderer base.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Collections.Generic;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Provides an abstract base class for axis renderers.
+ ///
+ public abstract class AxisRendererBase
+ {
+ ///
+ /// The plot.
+ ///
+ protected readonly PlotModel Plot;
+
+ ///
+ /// The render context.
+ ///
+ protected readonly IRenderContext rc;
+
+ ///
+ /// The axis lines pen.
+ ///
+ protected OxyPen AxislinePen;
+
+ ///
+ /// The extra grid lines pen.
+ ///
+ protected OxyPen ExtraPen;
+
+ ///
+ /// The major label values.
+ ///
+ protected IList MajorLabelValues;
+
+ ///
+ /// The major grid lines pen.
+ ///
+ protected OxyPen MajorPen;
+
+ ///
+ /// The major tick pen.
+ ///
+ protected OxyPen MajorTickPen;
+
+ ///
+ /// The major tick values.
+ ///
+ protected IList MajorTickValues;
+
+ ///
+ /// The minor grid lines pen.
+ ///
+ protected OxyPen MinorPen;
+
+ ///
+ /// The minor tick pen.
+ ///
+ protected OxyPen MinorTickPen;
+
+ ///
+ /// The minor tick values.
+ ///
+ protected IList MinorTickValues;
+
+ ///
+ /// The zero grid line pen.
+ ///
+ protected OxyPen ZeroPen;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot.
+ ///
+ protected AxisRendererBase(IRenderContext rc, PlotModel plot)
+ {
+ this.Plot = plot;
+ this.rc = rc;
+ }
+
+ ///
+ /// Renders the specified axis.
+ ///
+ /// The axis.
+ /// The pass.
+ public virtual void Render(Axis axis, int pass)
+ {
+ if (axis == null)
+ {
+ return;
+ }
+
+ axis.GetTickValues(out this.MajorLabelValues, out this.MajorTickValues, out this.MinorTickValues);
+ this.CreatePens(axis);
+ }
+
+ ///
+ /// The create pens.
+ ///
+ ///
+ /// The axis.
+ ///
+ protected void CreatePens(Axis axis)
+ {
+ this.MinorPen = OxyPen.Create(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
+ this.MajorPen = OxyPen.Create(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
+ this.MinorTickPen = OxyPen.Create(axis.TicklineColor, axis.MinorGridlineThickness);
+ this.MajorTickPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
+ this.ZeroPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
+ this.ExtraPen = OxyPen.Create(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
+ this.AxislinePen = OxyPen.Create(axis.AxislineColor, axis.AxislineThickness, axis.AxislineStyle);
+ }
+
+ ///
+ /// The get tick positions.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The glt.
+ ///
+ ///
+ /// The ticksize.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The x 0.
+ ///
+ ///
+ /// The x 1.
+ ///
+ protected void GetTickPositions(
+ Axis axis, TickStyle glt, double ticksize, AxisPosition position, out double x0, out double x1)
+ {
+ x0 = 0;
+ x1 = 0;
+ bool isTopOrLeft = position == AxisPosition.Top || position == AxisPosition.Left;
+ double sign = isTopOrLeft ? -1 : 1;
+ switch (glt)
+ {
+ case TickStyle.Crossing:
+ x0 = -ticksize * sign * 0.75;
+ x1 = ticksize * sign * 0.75;
+ break;
+ case TickStyle.Inside:
+ x0 = -ticksize * sign;
+ break;
+ case TickStyle.Outside:
+ x1 = ticksize * sign;
+ break;
+ }
+ }
+
+ ///
+ /// Determines whether the specified value is within the specified range.
+ ///
+ /// The value to check.
+ /// The minium value of the range.
+ /// The maximum value of the range.
+ ///
+ /// true if the specified value is within the range; otherwise, false.
+ ///
+ protected bool IsWithin(double d, double min, double max)
+ {
+ if (d < min)
+ {
+ return false;
+ }
+
+ if (d > max)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/HorizontalAndVerticalAxisRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/HorizontalAndVerticalAxisRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,642 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+// associated documentation files (the "Software"), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge, publish, distribute,
+// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Rendering helper class for horizontal and vertical axes (both linear and logarithmic)
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Preovides functionality to render horizontal and vertical axes.
+ ///
+ public class HorizontalAndVerticalAxisRenderer : AxisRendererBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot.
+ ///
+ public HorizontalAndVerticalAxisRenderer(IRenderContext rc, PlotModel plot)
+ : base(rc, plot)
+ {
+ }
+
+ ///
+ /// Renders the specified axis.
+ ///
+ /// The axis.
+ /// The pass.
+ public override void Render(Axis axis, int pass)
+ {
+ base.Render(axis, pass);
+
+ double totalShift = axis.PositionTierMinShift;
+ double tierSize = axis.PositionTierSize - this.Plot.AxisTierDistance;
+
+ // store properties locally for performance
+ double plotAreaLeft = this.Plot.PlotArea.Left;
+ double plotAreaRight = this.Plot.PlotArea.Right;
+ double plotAreaTop = this.Plot.PlotArea.Top;
+ double plotAreaBottom = this.Plot.PlotArea.Bottom;
+
+ // Axis position (x or y screen coordinate)
+ double axisPosition = 0;
+ double titlePosition = 0;
+
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ axisPosition = plotAreaLeft - totalShift;
+ titlePosition = axisPosition - tierSize;
+ break;
+ case AxisPosition.Right:
+ axisPosition = plotAreaRight + totalShift;
+ titlePosition = axisPosition + tierSize;
+ break;
+ case AxisPosition.Top:
+ axisPosition = plotAreaTop - totalShift;
+ titlePosition = axisPosition - tierSize;
+ break;
+ case AxisPosition.Bottom:
+ axisPosition = plotAreaBottom + totalShift;
+ titlePosition = axisPosition + tierSize;
+ break;
+ }
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
+ axisPosition = perpendicularAxis.Transform(0);
+ }
+
+ if (pass == 0)
+ {
+ this.RenderMinorItems(axis, axisPosition);
+ }
+
+ if (pass == 1)
+ {
+ this.RenderMajorItems(axis, axisPosition, titlePosition);
+ }
+ }
+
+ ///
+ /// Gets the axis title position, rotation and alignment.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The title position.
+ ///
+ ///
+ /// The angle.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ ///
+ /// The .
+ ///
+ protected virtual ScreenPoint GetAxisTitlePositionAndAlignment(
+ Axis axis,
+ double titlePosition,
+ ref double angle,
+ ref HorizontalAlignment halign,
+ ref VerticalAlignment valign)
+ {
+ double middle = axis.IsHorizontal()
+ ? Lerp(axis.ScreenMin.X, axis.ScreenMax.X, axis.TitlePosition)
+ : Lerp(axis.ScreenMax.Y, axis.ScreenMin.Y, axis.TitlePosition);
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
+ middle = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
+ }
+
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ return new ScreenPoint(titlePosition, middle);
+ case AxisPosition.Right:
+ valign = VerticalAlignment.Bottom;
+ return new ScreenPoint(titlePosition, middle);
+ case AxisPosition.Top:
+ halign = HorizontalAlignment.Center;
+ valign = VerticalAlignment.Top;
+ angle = 0;
+ return new ScreenPoint(middle, titlePosition);
+ case AxisPosition.Bottom:
+ halign = HorizontalAlignment.Center;
+ valign = VerticalAlignment.Bottom;
+ angle = 0;
+ return new ScreenPoint(middle, titlePosition);
+ default:
+ throw new ArgumentOutOfRangeException("axis");
+ }
+ }
+
+ ///
+ /// Gets the alignments given the specified rotation angle.
+ ///
+ ///
+ /// The angle.
+ ///
+ ///
+ /// The default horizontal alignment.
+ ///
+ ///
+ /// The default vertical alignment.
+ ///
+ ///
+ /// The rotated horizontal alignment.
+ ///
+ ///
+ /// The rotated vertical alignment.
+ ///
+ protected virtual void GetRotatedAlignments(
+ double angle,
+ HorizontalAlignment defaultHorizontalAlignment,
+ VerticalAlignment defaultVerticalAlignment,
+ out HorizontalAlignment ha,
+ out VerticalAlignment va)
+ {
+ ha = defaultHorizontalAlignment;
+ va = defaultVerticalAlignment;
+
+ Debug.Assert(angle <= 180 && angle >= -180, "Axis angle should be in the interval [-180,180] degrees.");
+
+ if (angle > -45 && angle < 45)
+ {
+ return;
+ }
+
+ if (angle > 135 || angle < -135)
+ {
+ ha = (HorizontalAlignment)(-(int)defaultHorizontalAlignment);
+ va = (VerticalAlignment)(-(int)defaultVerticalAlignment);
+ return;
+ }
+
+ if (angle > 45)
+ {
+ ha = (HorizontalAlignment)((int)defaultVerticalAlignment);
+ va = (VerticalAlignment)(-(int)defaultHorizontalAlignment);
+ return;
+ }
+
+ if (angle < -45)
+ {
+ ha = (HorizontalAlignment)(-(int)defaultVerticalAlignment);
+ va = (VerticalAlignment)((int)defaultHorizontalAlignment);
+ }
+ }
+
+ ///
+ /// Linear interpolation
+ /// http://en.wikipedia.org/wiki/Linear_interpolation
+ ///
+ ///
+ /// The x0.
+ ///
+ ///
+ /// The x1.
+ ///
+ ///
+ /// The interpolation factor.
+ ///
+ ///
+ /// The interpolated value.
+ ///
+ private static double Lerp(double x0, double x1, double f)
+ {
+ return (x0 * (1 - f)) + (x1 * f);
+ }
+
+ ///
+ /// Snaps v to value if it is within the the specified distance.
+ ///
+ ///
+ /// The target value.
+ ///
+ ///
+ /// The value to snap.
+ ///
+ ///
+ /// The distance tolerance.
+ ///
+ private static void SnapTo(double target, ref double v, double eps = 0.5)
+ {
+ if (v > target - eps && v < target + eps)
+ {
+ v = target;
+ }
+ }
+
+ ///
+ /// Renders the axis title.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The title position.
+ ///
+ private void RenderAxisTitle(Axis axis, double titlePosition)
+ {
+ bool isHorizontal = axis.IsHorizontal();
+
+ OxySize? maxSize = null;
+
+ if (axis.ClipTitle)
+ {
+ // Calculate the title clipping dimensions
+ double screenLength = isHorizontal
+ ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X)
+ : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y);
+
+ maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue);
+ }
+
+ double angle = -90;
+
+ var halign = HorizontalAlignment.Center;
+ var valign = VerticalAlignment.Top;
+
+ var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign);
+
+ this.rc.SetToolTip(axis.ToolTip);
+ this.rc.DrawMathText(
+ lpt,
+ axis.ActualTitle,
+ axis.ActualTitleColor,
+ axis.ActualTitleFont,
+ axis.ActualTitleFontSize,
+ axis.ActualTitleFontWeight,
+ angle,
+ halign,
+ valign,
+ maxSize);
+ this.rc.SetToolTip(null);
+ }
+
+ ///
+ /// Renders the major items.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The axis position.
+ ///
+ ///
+ /// The title position.
+ ///
+ private void RenderMajorItems(Axis axis, double axisPosition, double titlePosition)
+ {
+ double eps = axis.ActualMinorStep * 1e-3;
+
+ double actualMinimum = axis.ActualMinimum;
+ double actualMaximum = axis.ActualMaximum;
+
+ double plotAreaLeft = this.Plot.PlotArea.Left;
+ double plotAreaRight = this.Plot.PlotArea.Right;
+ double plotAreaTop = this.Plot.PlotArea.Top;
+ double plotAreaBottom = this.Plot.PlotArea.Bottom;
+ bool isHorizontal = axis.IsHorizontal();
+
+ double a0;
+ double a1;
+ var majorSegments = new List();
+ var majorTickSegments = new List();
+ this.GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);
+
+ foreach (double value in this.MajorTickValues)
+ {
+ if (value < actualMinimum - eps || value > actualMaximum + eps)
+ {
+ continue;
+ }
+
+ if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
+ {
+ continue;
+ }
+
+ double transformedValue = axis.Transform(value);
+ if (isHorizontal)
+ {
+ SnapTo(plotAreaLeft, ref transformedValue);
+ SnapTo(plotAreaRight, ref transformedValue);
+ }
+ else
+ {
+ SnapTo(plotAreaTop, ref transformedValue);
+ SnapTo(plotAreaBottom, ref transformedValue);
+ }
+
+ if (this.MajorPen != null)
+ {
+ if (isHorizontal)
+ {
+ majorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
+ majorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
+ }
+ else
+ {
+ majorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
+ majorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
+ }
+ }
+
+ if (axis.TickStyle != TickStyle.None)
+ {
+ if (isHorizontal)
+ {
+ majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
+ majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
+ }
+ else
+ {
+ majorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
+ majorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
+ }
+ }
+ }
+
+ // Render the axis labels (numbers or category names)
+ foreach (double value in this.MajorLabelValues)
+ {
+ if (value < actualMinimum - eps || value > actualMaximum + eps)
+ {
+ continue;
+ }
+
+ if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
+ {
+ continue;
+ }
+
+ double transformedValue = axis.Transform(value);
+ if (isHorizontal)
+ {
+ SnapTo(plotAreaLeft, ref transformedValue);
+ SnapTo(plotAreaRight, ref transformedValue);
+ }
+ else
+ {
+ SnapTo(plotAreaTop, ref transformedValue);
+ SnapTo(plotAreaBottom, ref transformedValue);
+ }
+
+ var pt = new ScreenPoint();
+ var ha = HorizontalAlignment.Right;
+ var va = VerticalAlignment.Middle;
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue);
+ this.GetRotatedAlignments(
+ axis.Angle, HorizontalAlignment.Right, VerticalAlignment.Middle, out ha, out va);
+ break;
+ case AxisPosition.Right:
+ pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue);
+ this.GetRotatedAlignments(
+ axis.Angle, HorizontalAlignment.Left, VerticalAlignment.Middle, out ha, out va);
+ break;
+ case AxisPosition.Top:
+ pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance);
+ this.GetRotatedAlignments(
+ axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Bottom, out ha, out va);
+ break;
+ case AxisPosition.Bottom:
+ pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance);
+ this.GetRotatedAlignments(
+ axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Top, out ha, out va);
+ break;
+ }
+
+ string text = axis.FormatValue(value);
+ this.rc.DrawMathText(
+ pt,
+ text,
+ axis.ActualTextColor,
+ axis.ActualFont,
+ axis.ActualFontSize,
+ axis.ActualFontWeight,
+ axis.Angle,
+ ha,
+ va);
+ }
+
+ // Draw the zero crossing line
+ if (axis.PositionAtZeroCrossing && this.ZeroPen != null)
+ {
+ double t0 = axis.Transform(0);
+ if (isHorizontal)
+ {
+ this.rc.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen);
+ }
+ else
+ {
+ this.rc.DrawLine(plotAreaLeft, t0, plotAreaRight, t0, this.ZeroPen);
+ }
+ }
+
+ // Draw extra grid lines
+ if (axis.ExtraGridlines != null && this.ExtraPen != null)
+ {
+ foreach (double value in axis.ExtraGridlines)
+ {
+ if (!this.IsWithin(value, actualMinimum, actualMaximum))
+ {
+ continue;
+ }
+
+ double transformedValue = axis.Transform(value);
+ if (isHorizontal)
+ {
+ this.rc.DrawLine(transformedValue, plotAreaTop, transformedValue, plotAreaBottom, this.ExtraPen);
+ }
+ else
+ {
+ this.rc.DrawLine(plotAreaLeft, transformedValue, plotAreaRight, transformedValue, this.ExtraPen);
+ }
+ }
+ }
+
+ // Draw the axis line (across the tick marks)
+ if (isHorizontal)
+ {
+ this.rc.DrawLine(
+ axis.Transform(actualMinimum),
+ axisPosition,
+ axis.Transform(actualMaximum),
+ axisPosition,
+ this.AxislinePen);
+ }
+ else
+ {
+ this.rc.DrawLine(
+ axisPosition,
+ axis.Transform(actualMinimum),
+ axisPosition,
+ axis.Transform(actualMaximum),
+ this.AxislinePen);
+ }
+
+ // Draw the axis title
+ if (!string.IsNullOrEmpty(axis.ActualTitle))
+ {
+ this.RenderAxisTitle(axis, titlePosition);
+ }
+
+ if (this.MajorPen != null)
+ {
+ this.rc.DrawLineSegments(majorSegments, this.MajorPen);
+ }
+
+ if (this.MajorTickPen != null)
+ {
+ this.rc.DrawLineSegments(majorTickSegments, this.MajorTickPen);
+ }
+ }
+
+ ///
+ /// Renders the minor items.
+ ///
+ ///
+ /// The axis.
+ ///
+ ///
+ /// The axis position.
+ ///
+ private void RenderMinorItems(Axis axis, double axisPosition)
+ {
+ double eps = axis.ActualMinorStep * 1e-3;
+ double actualMinimum = axis.ActualMinimum;
+ double actualMaximum = axis.ActualMaximum;
+
+ double plotAreaLeft = this.Plot.PlotArea.Left;
+ double plotAreaRight = this.Plot.PlotArea.Right;
+ double plotAreaTop = this.Plot.PlotArea.Top;
+ double plotAreaBottom = this.Plot.PlotArea.Bottom;
+ bool isHorizontal = axis.IsHorizontal();
+
+ double a0;
+ double a1;
+ var minorSegments = new List();
+ var minorTickSegments = new List();
+ this.GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);
+
+ foreach (double value in this.MinorTickValues)
+ {
+ if (value < actualMinimum - eps || value > actualMaximum + eps)
+ {
+ continue;
+ }
+
+ if (this.MajorTickValues.Contains(value))
+ {
+ continue;
+ }
+
+ if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
+ {
+ continue;
+ }
+
+ double transformedValue = axis.Transform(value);
+
+ if (isHorizontal)
+ {
+ SnapTo(plotAreaLeft, ref transformedValue);
+ SnapTo(plotAreaRight, ref transformedValue);
+ }
+ else
+ {
+ SnapTo(plotAreaTop, ref transformedValue);
+ SnapTo(plotAreaBottom, ref transformedValue);
+ }
+
+ // Draw the minor grid line
+ if (this.MinorPen != null)
+ {
+ if (isHorizontal)
+ {
+ minorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
+ minorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
+ }
+ else
+ {
+ if (transformedValue < plotAreaTop || transformedValue > plotAreaBottom)
+ {
+ }
+
+ minorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
+ minorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
+ }
+ }
+
+ // Draw the minor tick
+ if (axis.TickStyle != TickStyle.None)
+ {
+ if (isHorizontal)
+ {
+ minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
+ minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
+ }
+ else
+ {
+ minorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
+ minorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
+ }
+ }
+ }
+
+ // Draw all the line segments);
+ if (this.MinorPen != null)
+ {
+ this.rc.DrawLineSegments(minorSegments, this.MinorPen);
+ }
+
+ if (this.MinorTickPen != null)
+ {
+ this.rc.DrawLineSegments(minorTickSegments, this.MinorTickPen);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/IRenderContext.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/IRenderContext.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,400 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Render context interface.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Defines rendering functionality.
+ ///
+ public interface IRenderContext
+ {
+ ///
+ /// Gets a value indicating whether the context renders to screen.
+ ///
+ ///
+ /// true if the context renders to screen; otherwise, false.
+ ///
+ bool RendersToScreen { get; }
+
+ ///
+ /// Draws an ellipse.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The thickness.
+ ///
+ void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1.0);
+
+ ///
+ /// Draws the collection of ellipses, where all have the same stroke and fill.
+ /// This performs better than calling DrawEllipse multiple times.
+ ///
+ ///
+ /// The rectangles.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stroke, double thickness = 1.0);
+
+ ///
+ /// Draws the polyline from the specified points.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ void DrawLine(
+ IList points,
+ OxyColor stroke,
+ double thickness = 1.0,
+ double[] dashArray = null,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
+ bool aliased = false);
+
+ ///
+ /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc.
+ /// This should have better performance than calling DrawLine for each segment.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ void DrawLineSegments(
+ IList points,
+ OxyColor stroke,
+ double thickness = 1.0,
+ double[] dashArray = null,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
+ bool aliased = false);
+
+ ///
+ /// Draws the polygon from the specified points. The polygon can have stroke and/or fill.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ void DrawPolygon(
+ IList points,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness = 1.0,
+ double[] dashArray = null,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
+ bool aliased = false);
+
+ ///
+ /// Draws a collection of polygons, where all polygons have the same stroke and fill.
+ /// This performs better than calling DrawPolygon multiple times.
+ ///
+ ///
+ /// The polygons.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ void DrawPolygons(
+ IList> polygons,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness = 1.0,
+ double[] dashArray = null,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
+ bool aliased = false);
+
+ ///
+ /// Draws the rectangle.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1.0);
+
+ ///
+ /// Draws a collection of rectangles, where all have the same stroke and fill.
+ /// This performs better than calling DrawRectangle multiple times.
+ ///
+ ///
+ /// The rectangles.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ void DrawRectangles(IList rectangles, OxyColor fill, OxyColor stroke, double thickness = 1.0);
+
+ ///
+ /// Draws the text.
+ ///
+ ///
+ /// The position.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// Size of the font.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The rotation angle.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ ///
+ /// The maximum size of the text.
+ ///
+ void DrawText(
+ ScreenPoint p,
+ string text,
+ OxyColor fill,
+ string fontFamily = null,
+ double fontSize = 10,
+ double fontWeight = 500,
+ double rotate = 0,
+ HorizontalAlignment halign = HorizontalAlignment.Left,
+ VerticalAlignment valign = VerticalAlignment.Top,
+ OxySize? maxSize = null);
+
+ ///
+ /// Measures the text.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// Size of the font.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The text size.
+ ///
+ OxySize MeasureText(string text, string fontFamily = null, double fontSize = 10, double fontWeight = 500);
+
+ ///
+ /// Sets the tool tip for the following items.
+ ///
+ ///
+ /// This is only used in the plot controls.
+ ///
+ ///
+ /// The text in the tooltip.
+ ///
+ void SetToolTip(string text);
+
+ ///
+ /// Cleans up resources not in use.
+ ///
+ ///
+ /// This method is called at the end of each rendering.
+ ///
+ void CleanUp();
+
+ ///
+ /// Gets the size of the specified image.
+ ///
+ /// The image source.
+ /// The image info.
+ OxyImageInfo GetImageInfo(OxyImage source);
+
+ ///
+ /// Draws the specified portion of the specified at the specified location and with the specified size.
+ ///
+ /// The source.
+ /// The x-coordinate of the upper-left corner of the portion of the source image to draw.
+ /// The y-coordinate of the upper-left corner of the portion of the source image to draw.
+ /// Width of the portion of the source image to draw.
+ /// Height of the portion of the source image to draw.
+ /// The x-coordinate of the upper-left corner of drawn image.
+ /// The y-coordinate of the upper-left corner of drawn image.
+ /// The width of the drawn image.
+ /// The height of the drawn image.
+ /// The opacity.
+ /// interpolate if set to true.
+ void DrawImage(OxyImage source, uint srcX, uint srcY, uint srcWidth, uint srcHeight, double destX, double destY, double destWidth, double destHeight, double opacity, bool interpolate);
+
+ ///
+ /// Sets the clip rectangle.
+ ///
+ /// The clip rectangle.
+ /// True if the clip rectangle was set.
+ bool SetClip(OxyRect rect);
+
+ ///
+ /// Resets the clip rectangle.
+ ///
+ void ResetClip();
+ }
+
+ ///
+ /// Provides information about the size of an image.
+ ///
+ public class OxyImageInfo
+ {
+ ///
+ /// Gets or sets the width in pixels.
+ ///
+ ///
+ /// The width.
+ ///
+ public uint Width { get; set; }
+
+ ///
+ /// Gets or sets the height in pixels.
+ ///
+ ///
+ /// The height.
+ ///
+ public uint Height { get; set; }
+
+ ///
+ /// Gets or sets the horizontal resolution in dpi.
+ ///
+ ///
+ /// The dpi X.
+ ///
+ public double DpiX { get; set; }
+
+ ///
+ /// Gets or sets the vertical resolution in dpi.
+ ///
+ ///
+ /// The dpi Y.
+ ///
+ public double DpiY { get; set; }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/MagnitudeAxisRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/MagnitudeAxisRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,145 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The magnitude axis renderer.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+
+ using OxyPlot.Axes;
+
+ ///
+ /// Provides functionality to render .
+ ///
+ public class MagnitudeAxisRenderer : AxisRendererBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The plot.
+ ///
+ public MagnitudeAxisRenderer(IRenderContext rc, PlotModel plot)
+ : base(rc, plot)
+ {
+ }
+
+ ///
+ /// Renders the specified axis.
+ ///
+ /// The axis.
+ /// The pass.
+ /// Angle axis should not be null.
+ public override void Render(Axis axis, int pass)
+ {
+ base.Render(axis, pass);
+
+ var angleAxis = this.Plot.DefaultAngleAxis as Axis;
+ if (axis.RelatedAxis != null)
+ {
+ angleAxis = axis.RelatedAxis;
+ }
+
+ if (angleAxis == null)
+ {
+ throw new NullReferenceException("Angle axis should not be null.");
+ }
+
+ if (axis.ShowMinorTicks)
+ {
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
+
+ foreach (double xValue in this.MinorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (this.MajorTickValues.Contains(xValue))
+ {
+ continue;
+ }
+
+ var pts = new List();
+ for (double th = angleAxis.ActualMinimum;
+ th <= angleAxis.ActualMaximum + angleAxis.MinorStep * 0.01;
+ th += angleAxis.MinorStep * 0.1)
+ {
+ pts.Add(axis.Transform(xValue, th, angleAxis));
+ }
+
+ if (this.MinorPen != null)
+ {
+ this.rc.DrawLine(pts, this.MinorPen.Color, this.MinorPen.Thickness, this.MinorPen.DashArray);
+ }
+
+ // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
+ }
+ }
+
+ // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
+
+ foreach (double xValue in this.MajorTickValues)
+ {
+ if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ var pts = new List();
+ for (double th = angleAxis.ActualMinimum;
+ th <= angleAxis.ActualMaximum + angleAxis.MinorStep * 0.01;
+ th += angleAxis.MinorStep * 0.1)
+ {
+ pts.Add(axis.Transform(xValue, th, angleAxis));
+ }
+
+ if (this.MajorPen != null)
+ {
+ this.rc.DrawLine(pts, this.MajorPen.Color, this.MajorPen.Thickness, this.MajorPen.DashArray);
+ }
+
+ // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
+ // var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
+ // string text = axis.FormatValue(xValue);
+ // double h = rc.MeasureText(text, axis.Font, axis.FontSize, axis.FontWeight).Height;
+ // rc.DrawText(pt, text, axis.LabelColor ?? plot.TextColor,
+ // axis.Font, axis.FontSize, axis.FontWeight,
+ // axis.Angle,
+ // HorizontalAlignment.Center, istop ? VerticalAlignment.Bottom : VerticalAlignment.Top);
+ // maxh = Math.Max(maxh, h);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/MathRenderingExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/MathRenderingExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,347 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The math rendering extensions.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System;
+
+ ///
+ /// Provides functionality to render mathematic expressions (TeX syntax).
+ ///
+ public static class MathRenderingExtensions
+ {
+ ///
+ /// Initializes static members of the class.
+ ///
+ static MathRenderingExtensions()
+ {
+ SubAlignment = 0.6;
+ SubSize = 0.62;
+ SuperAlignment = 0;
+ SuperSize = 0.62;
+ }
+
+ ///
+ /// Gets or sets the subscript alignment.
+ ///
+ private static double SubAlignment { get; set; }
+
+ ///
+ /// Gets or sets the subscript size.
+ ///
+ private static double SubSize { get; set; }
+
+ ///
+ /// Gets or sets the superscript alignment.
+ ///
+ private static double SuperAlignment { get; set; }
+
+ ///
+ /// Gets or sets the superscript size.
+ ///
+ private static double SuperSize { get; set; }
+
+ ///
+ /// Draws or measures text containing sub- and superscript.
+ ///
+ /// The render context.
+ /// The point.
+ /// The text.
+ /// Color of the text.
+ /// The font family.
+ /// The font size.
+ /// The font weight.
+ /// The angle.
+ /// The horizontal alignment.
+ /// The vertical alignment.
+ /// The maximum size of the text.
+ /// Measure the size of the text if set to true.
+ /// The size of the text.
+ ///
+ /// Subscript: H_{2}O
+ /// Superscript: E=mc^{2}
+ /// Both: A^{2}_{i,j}
+ ///
+ public static OxySize DrawMathText(
+ this IRenderContext rc,
+ ScreenPoint pt,
+ string text,
+ OxyColor textColor,
+ string fontFamily,
+ double fontSize,
+ double fontWeight,
+ double angle,
+ HorizontalAlignment ha,
+ VerticalAlignment va,
+ OxySize? maxsize,
+ bool measure)
+ {
+ if (string.IsNullOrEmpty(text))
+ {
+ return OxySize.Empty;
+ }
+
+ if (angle.Equals(0) && (text.Contains("^{") || text.Contains("_{")))
+ {
+ double x = pt.X;
+ double y = pt.Y;
+
+ // Measure
+ var size = InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, true);
+
+ switch (ha)
+ {
+ case HorizontalAlignment.Right:
+ x -= size.Width;
+ break;
+ case HorizontalAlignment.Center:
+ x -= size.Width * 0.5;
+ break;
+ }
+
+ switch (va)
+ {
+ case VerticalAlignment.Bottom:
+ y -= size.Height;
+ break;
+ case VerticalAlignment.Middle:
+ y -= size.Height * 0.5;
+ break;
+ }
+
+ InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, false);
+ return measure ? size : OxySize.Empty;
+ }
+
+ rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize);
+ if (measure)
+ {
+ return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
+ }
+
+ return OxySize.Empty;
+ }
+
+ ///
+ /// Draws text containing sub- and superscript.
+ ///
+ /// The render context.
+ /// The point.
+ /// The text.
+ /// Color of the text.
+ /// The font family.
+ /// The font size.
+ /// The font weight.
+ /// The angle.
+ /// The horizontal alignment.
+ /// The vertical alignment.
+ /// The maximum size of the text.
+ ///
+ /// Subscript: H_{2}O
+ /// Superscript: E=mc^{2}
+ /// Both: A^{2}_{i,j}
+ ///
+ public static void DrawMathText(
+ this IRenderContext rc,
+ ScreenPoint pt,
+ string text,
+ OxyColor textColor,
+ string fontFamily,
+ double fontSize,
+ double fontWeight,
+ double angle,
+ HorizontalAlignment ha,
+ VerticalAlignment va,
+ OxySize? maxsize = null)
+ {
+ DrawMathText(rc, pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize, false);
+ }
+
+ ///
+ /// The measure math text.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// The font size.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The size of the text.
+ ///
+ public static OxySize MeasureMathText(
+ this IRenderContext rc, string text, string fontFamily, double fontSize, double fontWeight)
+ {
+ if (text.Contains("^{") || text.Contains("_{"))
+ {
+ return InternalDrawMathText(rc, 0, 0, text, null, fontFamily, fontSize, fontWeight, true);
+ }
+
+ return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
+ }
+
+ ///
+ /// The internal draw math text.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The x.
+ ///
+ ///
+ /// The y.
+ ///
+ ///
+ /// The s.
+ ///
+ ///
+ /// The text color.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// The font size.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The measure only.
+ ///
+ ///
+ /// The size of the text.
+ ///
+ private static OxySize InternalDrawMathText(
+ IRenderContext rc,
+ double x,
+ double y,
+ string s,
+ OxyColor textColor,
+ string fontFamily,
+ double fontSize,
+ double fontWeight,
+ bool measureOnly)
+ {
+ int i = 0;
+
+ double currentX = x;
+ double maximumX = x;
+ double maxHeight = 0;
+
+ // http://en.wikipedia.org/wiki/Subscript_and_superscript
+ double superscriptY = y + fontSize * SuperAlignment;
+ double superscriptFontSize = fontSize * SuperSize;
+ double subscriptY = y + fontSize * SubAlignment;
+ double subscriptFontSize = fontSize * SubSize;
+
+ Func drawText = (xb, yb, text, fSize) =>
+ {
+ if (!measureOnly)
+ {
+ rc.DrawText(new ScreenPoint(xb, yb), text, textColor, fontFamily, fSize, fontWeight);
+ }
+
+ return rc.MeasureText(text, fontFamily, fSize, fontWeight);
+ };
+
+ while (i < s.Length)
+ {
+ // Superscript
+ if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{')
+ {
+ int i1 = s.IndexOf('}', i);
+ if (i1 != -1)
+ {
+ string supString = s.Substring(i + 2, i1 - i - 2);
+ i = i1 + 1;
+ OxySize size = drawText(currentX, superscriptY, supString, superscriptFontSize);
+ if (currentX + size.Width > maximumX)
+ {
+ maximumX = currentX + size.Width;
+ }
+
+ continue;
+ }
+ }
+
+ // Subscript
+ if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{')
+ {
+ int i1 = s.IndexOf('}', i);
+ if (i1 != -1)
+ {
+ string subString = s.Substring(i + 2, i1 - i - 2);
+ i = i1 + 1;
+ OxySize size = drawText(currentX, subscriptY, subString, subscriptFontSize);
+ if (currentX + size.Width > maximumX)
+ {
+ maximumX = currentX + size.Width;
+ }
+
+ continue;
+ }
+ }
+
+ // Regular text
+ int i2 = s.IndexOfAny("^_".ToCharArray(), i);
+ string regularString;
+ if (i2 == -1)
+ {
+ regularString = s.Substring(i);
+ i = s.Length;
+ }
+ else
+ {
+ regularString = s.Substring(i, i2 - i);
+ i = i2;
+ }
+
+ currentX = maximumX + 2;
+ OxySize size2 = drawText(currentX, y, regularString, fontSize);
+ currentX += size2.Width + 2;
+ maxHeight = Math.Max(maxHeight, size2.Height);
+ maximumX = currentX;
+ }
+
+ return new OxySize(maximumX - x, maxHeight);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/PlotRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/PlotRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,159 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+
+namespace OxyPlot
+{
+ public class PlotRenderer
+ {
+ protected readonly PlotModel plot;
+ protected readonly IRenderContext rc;
+
+ public PlotRenderer(IRenderContext rc, PlotModel p)
+ {
+ this.rc = rc;
+ plot = p;
+ }
+
+ public void RenderTitle(string title, string subtitle)
+ {
+ OxySize size1 = rc.MeasureText(title, plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight);
+ OxySize size2 = rc.MeasureText(subtitle, plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight);
+ double height = size1.Height + size2.Height;
+ double dy = (plot.AxisMargins.Top - height) * 0.5;
+ double dx = (plot.Bounds.Left + plot.Bounds.Right) * 0.5;
+
+ if (!String.IsNullOrEmpty(title))
+ rc.DrawText(
+ new ScreenPoint(dx, dy), title, plot.TextColor,
+ plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight,
+ 0,
+ HorizontalTextAlign.Center, VerticalTextAlign.Top);
+ if (!String.IsNullOrEmpty(subtitle))
+ rc.DrawText(new ScreenPoint(dx, dy + size1.Height), subtitle, plot.TextColor,
+ plot.TitleFont, plot.SubtitleFontSize, plot.SubtitleFontWeight, 0,
+ HorizontalTextAlign.Center, VerticalTextAlign.Top);
+ }
+
+ public void RenderRect(OxyRect bounds, OxyColor fill, OxyColor borderColor, double borderThickness)
+ {
+ var border = new[]
+ {
+ new ScreenPoint(bounds.Left, bounds.Top), new ScreenPoint(bounds.Right, bounds.Top),
+ new ScreenPoint(bounds.Right, bounds.Bottom), new ScreenPoint(bounds.Left, bounds.Bottom),
+ new ScreenPoint(bounds.Left, bounds.Top)
+ };
+
+ rc.DrawPolygon(border, fill, borderColor, borderThickness, null, true);
+ }
+
+ private static readonly double LEGEND_PADDING = 8;
+
+ public void RenderLegends()
+ {
+ double maxWidth = 0;
+ double maxHeight = 0;
+ double totalHeight = 0;
+
+ // Measure
+ foreach (var s in plot.Series)
+ {
+ if (String.IsNullOrEmpty(s.Title))
+ continue;
+ var oxySize = rc.MeasureText(s.Title, plot.LegendFont, plot.LegendFontSize);
+ if (oxySize.Width > maxWidth) maxWidth = oxySize.Width;
+ if (oxySize.Height > maxHeight) maxHeight = oxySize.Height;
+ totalHeight += oxySize.Height;
+ }
+
+ double lineLength = plot.LegendSymbolLength;
+
+ // Arrange
+ double x0 = double.NaN, x1 = double.NaN, y0 = double.NaN;
+
+ // padding padding
+ // lineLength
+ // y0 -----o---- seriesName
+ // x0 x1
+
+ double sign = 1;
+ if (plot.IsLegendOutsidePlotArea)
+ sign = -1;
+
+ // Horizontal alignment
+ HorizontalTextAlign ha = HorizontalTextAlign.Left;
+ switch (plot.LegendPosition)
+ {
+ case LegendPosition.TopRight:
+ case LegendPosition.BottomRight:
+ x0 = plot.Bounds.Right - LEGEND_PADDING * sign;
+ x1 = x0 - lineLength * sign - LEGEND_PADDING * sign;
+ ha = sign == 1 ? HorizontalTextAlign.Right : HorizontalTextAlign.Left;
+ break;
+ case LegendPosition.TopLeft:
+ case LegendPosition.BottomLeft:
+ x0 = plot.Bounds.Left + LEGEND_PADDING * sign;
+ x1 = x0 + lineLength * sign + LEGEND_PADDING * sign;
+ ha = sign == 1 ? HorizontalTextAlign.Left : HorizontalTextAlign.Right;
+ break;
+ }
+
+ // Vertical alignment
+ VerticalTextAlign va = VerticalTextAlign.Middle;
+ switch (plot.LegendPosition)
+ {
+ case LegendPosition.TopRight:
+ case LegendPosition.TopLeft:
+ y0 = plot.Bounds.Top + LEGEND_PADDING + maxHeight / 2;
+ break;
+ case LegendPosition.BottomRight:
+ case LegendPosition.BottomLeft:
+ y0 = plot.Bounds.Bottom - maxHeight + LEGEND_PADDING;
+ break;
+ }
+
+ foreach (var s in plot.Series)
+ {
+ if (String.IsNullOrEmpty(s.Title))
+ continue;
+ rc.DrawText(new ScreenPoint(x1, y0),
+ s.Title, plot.TextColor,
+ plot.LegendFont, plot.LegendFontSize, 500, 0,
+ ha, va);
+ OxyRect rect = new OxyRect(x0 - lineLength, y0 - maxHeight / 2, lineLength, maxHeight);
+ if (ha == HorizontalTextAlign.Left)
+ rect = new OxyRect(x0, y0 - maxHeight / 2, lineLength, maxHeight);
+
+ s.RenderLegend(rc, rect);
+ if (plot.LegendPosition == LegendPosition.TopLeft || plot.LegendPosition == LegendPosition.TopRight)
+ y0 += maxHeight;
+ else
+ y0 -= maxHeight;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/RenderContextBase.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/RenderContextBase.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,423 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The abstract render context base class.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Provides an abstract base class for rendering contexts.
+ ///
+ public abstract class RenderContextBase : IRenderContext
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected RenderContextBase()
+ {
+ this.RendersToScreen = true;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the context renders to screen.
+ ///
+ ///
+ /// true if the context renders to screen; otherwise, false.
+ ///
+ public bool RendersToScreen { get; set; }
+
+ ///
+ /// Draws an ellipse.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The thickness.
+ ///
+ public abstract void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
+
+ ///
+ /// Draws the collection of ellipses, where all have the same stroke and fill.
+ /// This performs better than calling DrawEllipse multiple times.
+ ///
+ ///
+ /// The rectangles.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ public virtual void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stroke, double thickness)
+ {
+ foreach (var r in rectangles)
+ {
+ this.DrawEllipse(r, fill, stroke, thickness);
+ }
+ }
+
+ ///
+ /// Draws the polyline from the specified points.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ public abstract void DrawLine(
+ IList points,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased);
+
+ ///
+ /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc.
+ /// This should have better performance than calling DrawLine for each segment.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ public virtual void DrawLineSegments(
+ IList points,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased)
+ {
+ for (int i = 0; i + 1 < points.Count; i += 2)
+ {
+ this.DrawLine(new[] { points[i], points[i + 1] }, stroke, thickness, dashArray, lineJoin, aliased);
+ }
+ }
+
+ ///
+ /// Draws the polygon from the specified points. The polygon can have stroke and/or fill.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ public abstract void DrawPolygon(
+ IList points,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased);
+
+ ///
+ /// Draws a collection of polygons, where all polygons have the same stroke and fill.
+ /// This performs better than calling DrawPolygon multiple times.
+ ///
+ ///
+ /// The polygons.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The dash array.
+ ///
+ ///
+ /// The line join type.
+ ///
+ ///
+ /// if set to true the shape will be aliased.
+ ///
+ public virtual void DrawPolygons(
+ IList> polygons,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness,
+ double[] dashArray,
+ OxyPenLineJoin lineJoin,
+ bool aliased)
+ {
+ foreach (var polygon in polygons)
+ {
+ this.DrawPolygon(polygon, fill, stroke, thickness, dashArray, lineJoin, aliased);
+ }
+ }
+
+ ///
+ /// Draws the rectangle.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ public abstract void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
+
+ ///
+ /// Draws a collection of rectangles, where all have the same stroke and fill.
+ /// This performs better than calling DrawRectangle multiple times.
+ ///
+ ///
+ /// The rectangles.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ public virtual void DrawRectangles(IList rectangles, OxyColor fill, OxyColor stroke, double thickness)
+ {
+ foreach (var r in rectangles)
+ {
+ this.DrawRectangle(r, fill, stroke, thickness);
+ }
+ }
+
+ ///
+ /// Draws the text.
+ ///
+ ///
+ /// The p.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// Size of the font.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The rotation angle.
+ ///
+ ///
+ /// The horizontal alignment.
+ ///
+ ///
+ /// The vertical alignment.
+ ///
+ ///
+ /// The maximum size of the text.
+ ///
+ public abstract void DrawText(
+ ScreenPoint p,
+ string text,
+ OxyColor fill,
+ string fontFamily,
+ double fontSize,
+ double fontWeight,
+ double rotate,
+ HorizontalAlignment halign,
+ VerticalAlignment valign,
+ OxySize? maxSize);
+
+ ///
+ /// Measures the text.
+ ///
+ ///
+ /// The text.
+ ///
+ ///
+ /// The font family.
+ ///
+ ///
+ /// Size of the font.
+ ///
+ ///
+ /// The font weight.
+ ///
+ ///
+ /// The text size.
+ ///
+ public abstract OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight);
+
+ ///
+ /// Sets the tool tip for the following items.
+ ///
+ ///
+ /// The text in the tooltip.
+ ///
+ ///
+ /// This is only used in the plot controls.
+ ///
+ public virtual void SetToolTip(string text)
+ {
+ }
+
+ ///
+ /// Cleans up resources not in use.
+ ///
+ ///
+ /// This method is called at the end of each rendering.
+ ///
+ public virtual void CleanUp()
+ {
+ }
+
+ ///
+ /// Gets the size of the specified image.
+ ///
+ /// The image source.
+ ///
+ /// The image info.
+ ///
+ public virtual OxyImageInfo GetImageInfo(OxyImage source)
+ {
+ return null;
+ }
+
+ ///
+ /// Draws the image.
+ ///
+ /// The source.
+ /// The SRC X.
+ /// The SRC Y.
+ /// Width of the SRC.
+ /// Height of the SRC.
+ /// The x.
+ /// The y.
+ /// The w.
+ /// The h.
+ /// The opacity.
+ /// interpolate if set to true.
+ public virtual void DrawImage(
+ OxyImage source,
+ uint srcX,
+ uint srcY,
+ uint srcWidth,
+ uint srcHeight,
+ double x,
+ double y,
+ double w,
+ double h,
+ double opacity,
+ bool interpolate)
+ {
+ }
+
+ ///
+ /// Sets the clip rectangle.
+ ///
+ /// The clip rectangle.
+ ///
+ /// True if the clip rectangle was set.
+ ///
+ public virtual bool SetClip(OxyRect rect)
+ {
+ return false;
+ }
+
+ ///
+ /// Resets the clip rectangle.
+ ///
+ public virtual void ResetClip()
+ {
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/RenderingExtensions.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/RenderingExtensions.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,1109 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The rendering extensions.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Provides extension methods for .
+ ///
+ public static class RenderingExtensions
+ {
+ /* Length constants used to draw triangles and stars
+ ___
+ /\ |
+ / \ |
+ / \ | M2
+ / \ |
+ / \ |
+ / + \ ---
+ / \ |
+ / \ | M1
+ /________________\ _|_
+ |--------|-------|
+ 1 1
+
+ |
+ \ | / ---
+ \ | / | M3
+ \ | / |
+ ---------+-------- ---
+ / | \ | M3
+ / | \ |
+ / | \ ---
+ |
+ |-----|-----|
+ M3 M3
+ */
+
+ ///
+ /// The vertical distance to the bottom points of the triangles.
+ ///
+ private static readonly double M1 = Math.Tan(Math.PI / 6);
+
+ ///
+ /// The vertical distance to the top points of the triangles .
+ ///
+ private static readonly double M2 = Math.Sqrt(1 + (M1 * M1));
+
+ ///
+ /// The horizontal/vertical distance to the end points of the stars.
+ ///
+ private static readonly double M3 = Math.Tan(Math.PI / 4);
+
+ ///
+ /// Draws the clipped line.
+ ///
+ /// The render context.
+ /// The points.
+ /// The clipping rectangle.
+ /// The squared minimum distance.
+ /// The stroke.
+ /// The stroke thickness.
+ /// The line style.
+ /// The line join.
+ /// if set to true [aliased].
+ /// The points rendered callback.
+ public static void DrawClippedLine(
+ this IRenderContext rc,
+ IList points,
+ OxyRect clippingRectangle,
+ double minDistSquared,
+ OxyColor stroke,
+ double strokeThickness,
+ LineStyle lineStyle,
+ OxyPenLineJoin lineJoin,
+ bool aliased,
+ Action> pointsRendered = null)
+ {
+ var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom);
+
+ var pts = new List();
+ int n = points.Count;
+ if (n > 0)
+ {
+ if (n == 1)
+ {
+ pts.Add(points[0]);
+ }
+
+ var last = points[0];
+ for (int i = 1; i < n; i++)
+ {
+ var s0 = points[i - 1];
+ var s1 = points[i];
+
+ // Clipped version of this and next point.
+ var sc0 = s0;
+ var sc1 = s1;
+ bool isInside = clipping.ClipLine(ref sc0, ref sc1);
+
+ if (!isInside)
+ {
+ // keep the previous coordinate
+ continue;
+ }
+
+ // render from s0c-s1c
+ double dx = sc1.x - last.x;
+ double dy = sc1.y - last.y;
+
+ if ((dx * dx) + (dy * dy) > minDistSquared || i == 1 || i == n - 1)
+ {
+ if (!sc0.Equals(last) || i == 1)
+ {
+ pts.Add(sc0);
+ }
+
+ pts.Add(sc1);
+ last = sc1;
+ }
+
+ // render the line if we are leaving the clipping region););
+ if (!clipping.IsInside(s1))
+ {
+ if (pts.Count > 0)
+ {
+ EnsureNonEmptyLineIsVisible(pts);
+ rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+ if (pointsRendered != null)
+ {
+ pointsRendered(pts);
+ }
+
+ pts = new List();
+ }
+ }
+ }
+
+ if (pts.Count > 0)
+ {
+ EnsureNonEmptyLineIsVisible(pts);
+ rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+
+ // Execute the 'callback'.
+ if (pointsRendered != null)
+ {
+ pointsRendered(pts);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Draws the clipped line segments.
+ ///
+ /// The render context.
+ /// The points.
+ /// The clipping rectangle.
+ /// The stroke.
+ /// The stroke thickness.
+ /// The line style.
+ /// The line join.
+ /// if set to true [aliased].
+ public static void DrawClippedLineSegments(
+ this IRenderContext rc,
+ IList points,
+ OxyRect clippingRectangle,
+ OxyColor stroke,
+ double strokeThickness,
+ LineStyle lineStyle,
+ OxyPenLineJoin lineJoin,
+ bool aliased)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawLineSegments(points, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+ rc.ResetClip();
+ return;
+ }
+
+ var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom);
+
+ var clippedPoints = new List(points.Count);
+ for (int i = 0; i + 1 < points.Count; i += 2)
+ {
+ var s0 = points[i];
+ var s1 = points[i + 1];
+ if (clipping.ClipLine(ref s0, ref s1))
+ {
+ clippedPoints.Add(s0);
+ clippedPoints.Add(s1);
+ }
+ }
+
+ rc.DrawLineSegments(clippedPoints, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+ }
+
+ ///
+ /// Draws the specified image.
+ ///
+ /// The render context.
+ /// The image.
+ /// The destination X position.
+ /// The destination Y position.
+ /// The width.
+ /// The height.
+ /// The opacity.
+ /// Interpolate the image if set to true.
+ public static void DrawImage(
+ this IRenderContext rc,
+ OxyImage image,
+ double x,
+ double y,
+ double w,
+ double h,
+ double opacity,
+ bool interpolate)
+ {
+ var info = rc.GetImageInfo(image);
+ if (info == null)
+ {
+ return;
+ }
+
+ rc.DrawImage(image, 0, 0, info.Width, info.Height, x, y, w, h, opacity, interpolate);
+ }
+
+ ///
+ /// Draws the clipped image.
+ ///
+ /// The render context.
+ /// The clipping rectangle.
+ /// The source.
+ /// The destination X position.
+ /// The destination Y position.
+ /// The width.
+ /// The height.
+ /// The opacity.
+ /// interpolate if set to true.
+ public static void DrawClippedImage(
+ this IRenderContext rc,
+ OxyRect clippingRect,
+ OxyImage source,
+ double x,
+ double y,
+ double w,
+ double h,
+ double opacity,
+ bool interpolate)
+ {
+ if (x > clippingRect.Right || x + w < clippingRect.Left || y > clippingRect.Bottom || y + h < clippingRect.Top)
+ {
+ return;
+ }
+
+ if (rc.SetClip(clippingRect))
+ {
+ // The render context supports clipping, then we can draw the whole image
+ rc.DrawImage(source, x, y, w, h, opacity, interpolate);
+ rc.ResetClip();
+ return;
+ }
+
+ // The render context does not support clipping, we must calculate the rectangle
+ var info = rc.GetImageInfo(source);
+ if (info == null)
+ {
+ return;
+ }
+
+ // Fint the positions of the clipping rectangle normalized to image coordinates (0,1)
+ var i0 = (clippingRect.Left - x) / w;
+ var i1 = (clippingRect.Right - x) / w;
+ var j0 = (clippingRect.Top - y) / h;
+ var j1 = (clippingRect.Bottom - y) / h;
+
+ // Find the origin of the clipped source rectangle
+ var srcx = i0 < 0 ? 0u : i0 * info.Width;
+ var srcy = j0 < 0 ? 0u : j0 * info.Height;
+ srcx = (int)Math.Ceiling(srcx);
+ srcy = (int)Math.Ceiling(srcy);
+
+ // Find the size of the clipped source rectangle
+ var srcw = i1 > 1 ? info.Width - srcx : (i1 * info.Width) - srcx;
+ var srch = j1 > 1 ? info.Height - srcy : (j1 * info.Height) - srcy;
+ srcw = (int)srcw;
+ srch = (int)srch;
+
+ if ((int)srcw <= 0 || (int)srch <= 0)
+ {
+ return;
+ }
+
+ // The clipped destination rectangle
+ var destx = i0 < 0 ? x : x + (srcx / info.Width * w);
+ var desty = j0 < 0 ? y : y + (srcy / info.Height * h);
+ var destw = w * srcw / info.Width;
+ var desth = h * srch / info.Height;
+
+ rc.DrawImage(source, (uint)srcx, (uint)srcy, (uint)srcw, (uint)srch, destx, desty, destw, desth, opacity, interpolate);
+ }
+
+ ///
+ /// Draws the polygon within the specified clipping rectangle.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// The squared minimum distance between points.
+ ///
+ ///
+ /// The fill.
+ ///
+ ///
+ /// The stroke.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ ///
+ /// The line style.
+ ///
+ ///
+ /// The line join.
+ ///
+ ///
+ /// The aliased.
+ ///
+ public static void DrawClippedPolygon(
+ this IRenderContext rc,
+ IList points,
+ OxyRect clippingRectangle,
+ double minDistSquared,
+ OxyColor fill,
+ OxyColor stroke,
+ double strokeThickness = 1.0,
+ LineStyle lineStyle = LineStyle.Solid,
+ OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
+ bool aliased = false)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawPolygon(points, fill, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+ rc.ResetClip();
+ return;
+ }
+
+ var clippedPoints = SutherlandHodgmanClipping.ClipPolygon(clippingRectangle, points);
+
+ rc.DrawPolygon(
+ clippedPoints, fill, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
+ }
+
+ ///
+ /// Draws the clipped rectangle.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The rectangle to draw.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ public static void DrawClippedRectangle(
+ this IRenderContext rc,
+ OxyRect rect,
+ OxyRect clippingRectangle,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawRectangle(rect, fill, stroke, thickness);
+ rc.ResetClip();
+ return;
+ }
+
+ var clippedRect = ClipRect(rect, clippingRectangle);
+ if (clippedRect == null)
+ {
+ return;
+ }
+
+ rc.DrawRectangle(clippedRect.Value, fill, stroke, thickness);
+ }
+
+ ///
+ /// Draws the clipped rectangle as a polygon.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The rectangle to draw.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// The fill color.
+ ///
+ ///
+ /// The stroke color.
+ ///
+ ///
+ /// The stroke thickness.
+ ///
+ public static void DrawClippedRectangleAsPolygon(
+ this IRenderContext rc,
+ OxyRect rect,
+ OxyRect clippingRectangle,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawRectangleAsPolygon(rect, fill, stroke, thickness);
+ rc.ResetClip();
+ return;
+ }
+
+ var clippedRect = ClipRect(rect, clippingRectangle);
+ if (clippedRect == null)
+ {
+ return;
+ }
+
+ rc.DrawRectangleAsPolygon(clippedRect.Value, fill, stroke, thickness);
+ }
+
+ ///
+ /// Draws a clipped ellipse.
+ ///
+ /// The render context.
+ /// The clipping rectangle.
+ /// The rectangle.
+ /// The fill color.
+ /// The stroke color.
+ /// The stroke thickness.
+ /// The number of points around the ellipse.
+ public static void DrawClippedEllipse(
+ this IRenderContext rc,
+ OxyRect clippingRectangle,
+ OxyRect rect,
+ OxyColor fill,
+ OxyColor stroke,
+ double thickness,
+ int n = 100)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawEllipse(rect, fill, stroke, thickness);
+ rc.ResetClip();
+ return;
+ }
+
+ var points = new ScreenPoint[n];
+ double cx = (rect.Left + rect.Right) / 2;
+ double cy = (rect.Top + rect.Bottom) / 2;
+ double rx = (rect.Right - rect.Left) / 2;
+ double ry = (rect.Bottom - rect.Top) / 2;
+ for (int i = 0; i < n; i++)
+ {
+ double a = Math.PI * 2 * i / (n - 1);
+ points[i] = new ScreenPoint(cx + (rx * Math.Cos(a)), cy + (ry * Math.Sin(a)));
+ }
+
+ rc.DrawClippedPolygon(points, clippingRectangle, 4, fill, stroke, thickness);
+ }
+
+ ///
+ /// Draws the clipped text.
+ ///
+ /// The rendering context.
+ /// The clipping rectangle.
+ /// The position.
+ /// The text.
+ /// The fill color.
+ /// The font family.
+ /// Size of the font.
+ /// The font weight.
+ /// The rotation angle.
+ /// The horizontal align.
+ /// The vertical align.
+ /// Size of the max.
+ public static void DrawClippedText(
+ this IRenderContext rc,
+ OxyRect clippingRectangle,
+ ScreenPoint p,
+ string text,
+ OxyColor fill,
+ string fontFamily = null,
+ double fontSize = 10,
+ double fontWeight = 500,
+ double rotate = 0,
+ HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment verticalAlignment = VerticalAlignment.Top,
+ OxySize? maxSize = null)
+ {
+ if (rc.SetClip(clippingRectangle))
+ {
+ rc.DrawText(p, text, fill, fontFamily, fontSize, fontWeight, rotate, horizontalAlignment, verticalAlignment, maxSize);
+ rc.ResetClip();
+ return;
+ }
+
+ // fall back simply check position
+ if (clippingRectangle.Contains(p.X, p.Y))
+ {
+ rc.DrawText(p, text, fill, fontFamily, fontSize, fontWeight, rotate, horizontalAlignment, verticalAlignment, maxSize);
+ }
+ }
+
+ ///
+ /// Draws a line specified by coordinates.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The x0.
+ ///
+ ///
+ /// The y0.
+ ///
+ ///
+ /// The x1.
+ ///
+ ///
+ /// The y1.
+ ///
+ ///
+ /// The pen.
+ ///
+ ///
+ /// Aliased line if set to true.
+ ///
+ public static void DrawLine(
+ this IRenderContext rc, double x0, double y0, double x1, double y1, OxyPen pen, bool aliased = true)
+ {
+ if (pen == null)
+ {
+ return;
+ }
+
+ rc.DrawLine(
+ new[] { new ScreenPoint(x0, y0), new ScreenPoint(x1, y1) },
+ pen.Color,
+ pen.Thickness,
+ pen.DashArray,
+ pen.LineJoin,
+ aliased);
+ }
+
+ ///
+ /// Draws the line segments.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The points.
+ ///
+ ///
+ /// The pen.
+ ///
+ ///
+ /// if set to true [aliased].
+ ///
+ public static void DrawLineSegments(
+ this IRenderContext rc, IList points, OxyPen pen, bool aliased = true)
+ {
+ if (pen == null)
+ {
+ return;
+ }
+
+ rc.DrawLineSegments(points, pen.Color, pen.Thickness, pen.DashArray, pen.LineJoin, aliased);
+ }
+
+ ///
+ /// Renders the marker.
+ ///
+ /// The render context.
+ /// The center point of the marker.
+ /// The clipping rectangle.
+ /// The marker type.
+ /// The outline.
+ /// The size of the marker.
+ /// The fill color.
+ /// The stroke color.
+ /// The stroke thickness.
+ public static void DrawMarker(
+ this IRenderContext rc,
+ ScreenPoint p,
+ OxyRect clippingRect,
+ MarkerType type,
+ IList outline,
+ double size,
+ OxyColor fill,
+ OxyColor stroke,
+ double strokeThickness)
+ {
+ rc.DrawMarkers(new[] { p }, clippingRect, type, outline, new[] { size }, fill, stroke, strokeThickness);
+ }
+
+ ///
+ /// Draws a list of markers.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The marker points.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// Type of the marker.
+ ///
+ ///
+ /// The marker outline.
+ ///
+ ///
+ /// Size of the marker.
+ ///
+ ///
+ /// The marker fill.
+ ///
+ ///
+ /// The marker stroke.
+ ///
+ ///
+ /// The marker stroke thickness.
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// The bin Offset.
+ ///
+ public static void DrawMarkers(
+ this IRenderContext rc,
+ IList markerPoints,
+ OxyRect clippingRect,
+ MarkerType markerType,
+ IList markerOutline,
+ double markerSize,
+ OxyColor markerFill,
+ OxyColor markerStroke,
+ double markerStrokeThickness,
+ int resolution = 0,
+ ScreenPoint binOffset = new ScreenPoint())
+ {
+ DrawMarkers(
+ rc,
+ markerPoints,
+ clippingRect,
+ markerType,
+ markerOutline,
+ new[] { markerSize },
+ markerFill,
+ markerStroke,
+ markerStrokeThickness,
+ resolution,
+ binOffset);
+ }
+
+ ///
+ /// Draws a list of markers.
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The marker points.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// Type of the marker.
+ ///
+ ///
+ /// The marker outline.
+ ///
+ ///
+ /// Size of the markers.
+ ///
+ ///
+ /// The marker fill.
+ ///
+ ///
+ /// The marker stroke.
+ ///
+ ///
+ /// The marker stroke thickness.
+ ///
+ ///
+ /// The resolution.
+ ///
+ ///
+ /// The bin Offset.
+ ///
+ public static void DrawMarkers(
+ this IRenderContext rc,
+ IList markerPoints,
+ OxyRect clippingRect,
+ MarkerType markerType,
+ IList markerOutline,
+ IList markerSize,
+ OxyColor markerFill,
+ OxyColor markerStroke,
+ double markerStrokeThickness,
+ int resolution = 0,
+ ScreenPoint binOffset = new ScreenPoint())
+ {
+ if (markerType == MarkerType.None)
+ {
+ return;
+ }
+
+ int n = markerPoints.Count;
+ var ellipses = new List(n);
+ var rects = new List(n);
+ var polygons = new List>(n);
+ var lines = new List(n);
+
+ var hashset = new Dictionary();
+
+ int i = 0;
+
+ double minx = clippingRect.Left;
+ double maxx = clippingRect.Right;
+ double miny = clippingRect.Top;
+ double maxy = clippingRect.Bottom;
+
+ foreach (var p in markerPoints)
+ {
+ if (resolution > 1)
+ {
+ var x = (int)((p.X - binOffset.X) / resolution);
+ var y = (int)((p.Y - binOffset.Y) / resolution);
+ uint hash = (uint)(x << 16) + (uint)y;
+ if (hashset.ContainsKey(hash))
+ {
+ i++;
+ continue;
+ }
+
+ hashset.Add(hash, true);
+ }
+
+ bool outside = p.x < minx || p.x > maxx || p.y < miny || p.y > maxy;
+ if (!outside)
+ {
+ int j = i < markerSize.Count ? i : 0;
+ AddMarkerGeometry(p, markerType, markerOutline, markerSize[j], ellipses, rects, polygons, lines);
+ }
+
+ i++;
+ }
+
+ if (ellipses.Count > 0)
+ {
+ rc.DrawEllipses(ellipses, markerFill, markerStroke, markerStrokeThickness);
+ }
+
+ if (rects.Count > 0)
+ {
+ rc.DrawRectangles(rects, markerFill, markerStroke, markerStrokeThickness);
+ }
+
+ if (polygons.Count > 0)
+ {
+ rc.DrawPolygons(polygons, markerFill, markerStroke, markerStrokeThickness);
+ }
+
+ if (lines.Count > 0)
+ {
+ rc.DrawLineSegments(lines, markerStroke, markerStrokeThickness);
+ }
+ }
+
+ ///
+ /// Draws the rectangle as an aliased polygon.
+ /// (makes sure pixel alignment is the same as for lines)
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill.
+ ///
+ ///
+ /// The stroke.
+ ///
+ ///
+ /// The thickness.
+ ///
+ public static void DrawRectangleAsPolygon(
+ this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
+ {
+ var sp0 = new ScreenPoint(rect.Left, rect.Top);
+ var sp1 = new ScreenPoint(rect.Right, rect.Top);
+ var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
+ var sp3 = new ScreenPoint(rect.Left, rect.Bottom);
+ rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, stroke, thickness, null, OxyPenLineJoin.Miter, true);
+ }
+
+ ///
+ /// Draws the rectangle as an aliased polygon.
+ /// (makes sure pixel alignment is the same as for lines)
+ ///
+ ///
+ /// The render context.
+ ///
+ ///
+ /// The rectangle.
+ ///
+ ///
+ /// The fill.
+ ///
+ ///
+ /// The stroke.
+ ///
+ ///
+ /// The thickness.
+ ///
+ public static void DrawRectangleAsPolygon(
+ this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness)
+ {
+ if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top)
+ && thickness.Left.Equals(thickness.Bottom))
+ {
+ DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left);
+ return;
+ }
+
+ var sp0 = new ScreenPoint(rect.Left, rect.Top);
+ var sp1 = new ScreenPoint(rect.Right, rect.Top);
+ var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
+ var sp3 = new ScreenPoint(rect.Left, rect.Bottom);
+ rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, null, 0, null, OxyPenLineJoin.Miter, true);
+ rc.DrawPolygon(new[] { sp0, sp1 }, null, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true);
+ rc.DrawPolygon(new[] { sp1, sp2 }, null, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true);
+ rc.DrawPolygon(new[] { sp2, sp3 }, null, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true);
+ rc.DrawPolygon(new[] { sp3, sp0 }, null, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true);
+ }
+
+ ///
+ /// Adds a marker geometry.
+ ///
+ ///
+ /// The position of the marker.
+ ///
+ ///
+ /// The type.
+ ///
+ ///
+ /// The outline.
+ ///
+ ///
+ /// The size.
+ ///
+ ///
+ /// The ellipse collection.
+ ///
+ ///
+ /// The rectangle collection.
+ ///
+ ///
+ /// The polygon collection.
+ ///
+ ///
+ /// The line collection.
+ ///
+ private static void AddMarkerGeometry(
+ ScreenPoint p,
+ MarkerType type,
+ IEnumerable outline,
+ double size,
+ IList ellipses,
+ IList rects,
+ IList> polygons,
+ IList lines)
+ {
+ if (type == MarkerType.Custom)
+ {
+ if (outline == null)
+ {
+ throw new ArgumentNullException("outline", "The outline should be set when MarkerType is 'Custom'.");
+ }
+
+ var poly = outline.Select(o => new ScreenPoint(p.X + (o.x * size), p.Y + (o.y * size))).ToList();
+ polygons.Add(poly);
+ return;
+ }
+
+ switch (type)
+ {
+ case MarkerType.Circle:
+ {
+ ellipses.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
+ break;
+ }
+
+ case MarkerType.Square:
+ {
+ rects.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
+ break;
+ }
+
+ case MarkerType.Diamond:
+ {
+ polygons.Add(
+ new[]
+ {
+ new ScreenPoint(p.x, p.y - (M2 * size)), new ScreenPoint(p.x + (M2 * size), p.y),
+ new ScreenPoint(p.x, p.y + (M2 * size)), new ScreenPoint(p.x - (M2 * size), p.y)
+ });
+ break;
+ }
+
+ case MarkerType.Triangle:
+ {
+ polygons.Add(
+ new[]
+ {
+ new ScreenPoint(p.x - size, p.y + (M1 * size)),
+ new ScreenPoint(p.x + size, p.y + (M1 * size)), new ScreenPoint(p.x, p.y - (M2 * size))
+ });
+ break;
+ }
+
+ case MarkerType.Plus:
+ case MarkerType.Star:
+ {
+ lines.Add(new ScreenPoint(p.x - size, p.y));
+ lines.Add(new ScreenPoint(p.x + size, p.y));
+ lines.Add(new ScreenPoint(p.x, p.y - size));
+ lines.Add(new ScreenPoint(p.x, p.y + size));
+ break;
+ }
+ }
+
+ switch (type)
+ {
+ case MarkerType.Cross:
+ case MarkerType.Star:
+ {
+ lines.Add(new ScreenPoint(p.x - (size * M3), p.y - (size * M3)));
+ lines.Add(new ScreenPoint(p.x + (size * M3), p.y + (size * M3)));
+ lines.Add(new ScreenPoint(p.x - (size * M3), p.y + (size * M3)));
+ lines.Add(new ScreenPoint(p.x + (size * M3), p.y - (size * M3)));
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Calculates the clipped version of a rectangle.
+ ///
+ ///
+ /// The rectangle to clip.
+ ///
+ ///
+ /// The clipping rectangle.
+ ///
+ ///
+ /// The clipped rectangle, or null if the rectangle is outside the clipping area.
+ ///
+ private static OxyRect? ClipRect(OxyRect rect, OxyRect clippingRectangle)
+ {
+ if (rect.Right < clippingRectangle.Left)
+ {
+ return null;
+ }
+
+ if (rect.Left > clippingRectangle.Right)
+ {
+ return null;
+ }
+
+ if (rect.Top > clippingRectangle.Bottom)
+ {
+ return null;
+ }
+
+ if (rect.Bottom < clippingRectangle.Top)
+ {
+ return null;
+ }
+
+ if (rect.Right > clippingRectangle.Right)
+ {
+ rect.Right = clippingRectangle.Right;
+ }
+
+ if (rect.Left < clippingRectangle.Left)
+ {
+ rect.Width = rect.Right - clippingRectangle.Left;
+ rect.Left = clippingRectangle.Left;
+ }
+
+ if (rect.Top < clippingRectangle.Top)
+ {
+ rect.Height = rect.Bottom - clippingRectangle.Top;
+ rect.Top = clippingRectangle.Top;
+ }
+
+ if (rect.Bottom > clippingRectangle.Bottom)
+ {
+ rect.Bottom = clippingRectangle.Bottom;
+ }
+
+ if (rect.Width <= 0 || rect.Height <= 0)
+ {
+ return null;
+ }
+
+ return rect;
+ }
+
+ ///
+ /// Makes sure that a non empty line is visible.
+ ///
+ /// The points (screen coordinates).
+ ///
+ /// If the line contains one point, another point is added.
+ /// If the line contains two points at the same position, the points are moved 2 pixels apart.
+ ///
+ private static void EnsureNonEmptyLineIsVisible(IList pts)
+ {
+ // Check if the line contains two points and they are at the same point
+ if (pts.Count == 2)
+ {
+ if (pts[0].DistanceTo(pts[1]) < 1)
+ {
+ // Modify to a small horizontal line to make sure it is being rendered
+ pts[1] = new ScreenPoint(pts[0].X + 1, pts[0].Y);
+ pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
+ }
+ }
+
+ // Check if the line contains a single point
+ if (pts.Count == 1)
+ {
+ // Add a second point to make sure the line is being rendered as a small dot
+ pts.Add(new ScreenPoint(pts[0].X + 1, pts[0].Y));
+ pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Render/VerticalAxisRenderer.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Render/VerticalAxisRenderer.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,318 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Gets the rotated alignments given the specified angle.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System;
+using System.Diagnostics;
+
+namespace OxyPlot
+{
+ public class VerticalAxisRendererBase : AxisRendererBase
+ {
+ public VerticalAxisRendererBase(IRenderContext rc, PlotModel plot)
+ : base(rc, plot)
+ {
+ }
+
+ public override void Render(Axis axis)
+ {
+ base.Render(axis);
+
+ var perpendicularAxis = Plot.DefaultXAxis;
+ bool isHorizontal = true;
+
+ // Axis position (x or y screen coordinate)
+ double apos = 0;
+
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ apos = Plot.PlotArea.Left;
+ isHorizontal = false;
+ break;
+ case AxisPosition.Right:
+ apos = Plot.PlotArea.Right;
+ isHorizontal = false;
+ break;
+ case AxisPosition.Top:
+ apos = Plot.PlotArea.Top;
+ perpendicularAxis = Plot.DefaultYAxis;
+ break;
+ case AxisPosition.Bottom:
+ apos = Plot.PlotArea.Bottom;
+ perpendicularAxis = Plot.DefaultYAxis;
+ break;
+ }
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ apos = perpendicularAxis.Transform(0);
+ }
+
+ double a0, a1;
+
+ if (axis.ShowMinorTicks)
+ {
+ GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);
+
+ foreach (double value in MinorTickValues)
+ {
+ if (value < axis.ActualMinimum || value > axis.ActualMaximum)
+ {
+ continue;
+ }
+
+ if (MajorTickValues.Contains(value))
+ {
+ continue;
+ }
+
+ double transformedValue = axis.Transform(value);
+
+ if (MinorPen != null)
+ {
+ if (isHorizontal)
+ {
+ rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MinorPen);
+
+ }
+ else
+ {
+ rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MinorPen);
+ }
+ }
+ if (isHorizontal)
+ {
+ rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MinorTickPen);
+
+ }
+ else
+ {
+ rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MinorTickPen);
+ }
+ }
+ }
+
+ GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);
+
+ double maxWidth = 0;
+ double maxHeight = 0;
+
+ foreach (double value in MajorTickValues)
+ {
+ if (value < axis.ActualMinimum || value > axis.ActualMaximum)
+ continue;
+
+ double transformedValue = axis.Transform(value);
+
+ if (MajorPen != null)
+ {
+ if (isHorizontal)
+ {
+ rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MajorPen);
+
+ }
+ else
+ {
+ rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MajorPen);
+ }
+ }
+
+ if (isHorizontal)
+ {
+ rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MajorTickPen);
+
+ }
+ else
+ {
+ rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MajorTickPen);
+ }
+
+ if (value == 0 && axis.PositionAtZeroCrossing)
+ continue;
+
+ var pt = new ScreenPoint();
+ var ha = HorizontalTextAlign.Right;
+ var va = VerticalTextAlign.Middle;
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ pt = new ScreenPoint(apos + a1 - TICK_DIST, transformedValue);
+ GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va);
+ break;
+ case AxisPosition.Right:
+ pt = new ScreenPoint(apos + a1 + TICK_DIST, transformedValue);
+ GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va);
+ break;
+ case AxisPosition.Top:
+ pt = new ScreenPoint(transformedValue, apos + a1 - TICK_DIST);
+ GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va);
+ break;
+ case AxisPosition.Bottom:
+ pt = new ScreenPoint(transformedValue, apos + a1 + TICK_DIST);
+ GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va);
+ break;
+
+ }
+
+ string text = axis.FormatValue(value);
+ var size = rc.DrawMathText(pt, text, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight,
+ axis.Angle, ha, va);
+
+ maxWidth = Math.Max(maxWidth, size.Width);
+ maxHeight = Math.Max(maxHeight, size.Height);
+ }
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ double t0 = axis.Transform(0);
+ if (isHorizontal)
+ {
+ rc.DrawLine(t0, Plot.PlotArea.Top, t0, Plot.PlotArea.Bottom, ZeroPen);
+
+ }
+ else
+ {
+ rc.DrawLine(Plot.PlotArea.Left, t0, Plot.PlotArea.Right, t0, ZeroPen);
+ }
+ }
+
+ if (axis.ExtraGridlines != null)
+ {
+ foreach (double value in axis.ExtraGridlines)
+ {
+ if (!IsWithin(value, axis.ActualMinimum, axis.ActualMaximum))
+ continue;
+
+ double transformedValue = axis.Transform(value);
+ if (isHorizontal)
+ {
+ rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, ExtraPen);
+
+ }
+ else
+ {
+ rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, ExtraPen);
+ }
+ }
+ }
+ if (isHorizontal)
+ {
+ rc.DrawLine(Plot.PlotArea.Left, apos, Plot.PlotArea.Right, apos, MajorPen);
+
+ }
+ else
+ {
+ rc.DrawLine(apos, Plot.PlotArea.Top, apos, Plot.PlotArea.Bottom, MajorPen);
+ }
+
+ if (!String.IsNullOrWhiteSpace(axis.Title))
+ {
+ // Axis legend
+ double ymid = axis.Transform((axis.ActualMinimum + axis.ActualMaximum) / 2);
+ double angle = -90;
+ var lpt = new ScreenPoint();
+
+ var halign = HorizontalTextAlign.Center;
+ var valign = VerticalTextAlign.Top;
+
+ if (axis.PositionAtZeroCrossing)
+ {
+ ymid = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
+ // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
+ }
+
+ switch (axis.Position)
+ {
+ case AxisPosition.Left:
+ lpt = new ScreenPoint(AXIS_LEGEND_DIST, ymid);
+ break;
+ case AxisPosition.Right:
+ lpt = new ScreenPoint(rc.Width - AXIS_LEGEND_DIST, ymid);
+ valign = VerticalTextAlign.Bottom;
+ break;
+ case AxisPosition.Top:
+ lpt = new ScreenPoint(ymid, AXIS_LEGEND_DIST);
+ halign = HorizontalTextAlign.Center;
+ valign = VerticalTextAlign.Top;
+ angle = 0;
+ break;
+ case AxisPosition.Bottom:
+ lpt = new ScreenPoint(ymid, rc.Height - AXIS_LEGEND_DIST);
+ halign = HorizontalTextAlign.Center;
+ valign = VerticalTextAlign.Bottom;
+ angle = 0;
+ break;
+ }
+
+ rc.DrawText(lpt, axis.Title, Plot.TextColor,
+ axis.FontFamily, axis.FontSize, axis.FontWeight,
+ angle, halign, valign);
+ }
+ }
+
+ ///
+ /// Gets the rotated alignments given the specified angle.
+ ///
+ /// The angle.
+ /// The default horizontal alignment.
+ /// The default vertical alignment.
+ /// The rotated horizontal alignment.
+ /// The rotated vertical alignment.
+ private static void GetRotatedAlignments(double angle, HorizontalTextAlign defaultHorizontalAlignment, VerticalTextAlign defaultVerticalAlignment,
+ out HorizontalTextAlign ha, out VerticalTextAlign va)
+ {
+ ha = defaultHorizontalAlignment;
+ va = defaultVerticalAlignment;
+
+ Debug.Assert(angle <= 180 && angle >= -180, "Axis angle should be in the interval [-180,180] degrees.");
+
+ if (angle > -45 && angle < 45)
+ return;
+ if (angle > 135 || angle < -135)
+ {
+ ha = (HorizontalTextAlign)(-(int)defaultHorizontalAlignment);
+ va = (VerticalTextAlign)(-(int)defaultVerticalAlignment);
+ return;
+ }
+ if (angle > 45)
+ {
+ ha = (HorizontalTextAlign)((int)defaultVerticalAlignment);
+ va = (VerticalTextAlign)(-(int)defaultHorizontalAlignment);
+ return;
+ }
+ if (angle < -45)
+ {
+ ha = (HorizontalTextAlign)(-(int)defaultVerticalAlignment);
+ va = (VerticalTextAlign)((int)defaultHorizontalAlignment);
+ return;
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/NamespaceDoc.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/NamespaceDoc.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,39 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace OxyPlot.Reporting
+{
+ using System.Runtime.CompilerServices;
+
+ ///
+ /// The OxyPlot.Reporting namespace contains a simple report model.
+ ///
+ [CompilerGenerated]
+ internal class NamespaceDoc
+ {
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Content.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Content.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,75 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// --------------------------------------------------------------------------------------------------------------------
+using System.Collections.Generic;
+
+namespace OxyPlot.Reporting
+{
+ public class Content : Table
+ {
+ public List Contents { get; set; }
+ public ReportItem Base { get; set; }
+
+ public Content(ReportItem b)
+ {
+ this.Base = b;
+ Class = "content";
+ Contents = new List();
+ Columns.Add(new TableColumn(null, "Chapter"));
+ Columns.Add(new TableColumn(null, "Title"));
+ Items = Contents;
+ }
+
+ public class ContentItem
+ {
+ public string Chapter { get; set; }
+ public string Title { get; set; }
+ }
+
+ public override void Update()
+ {
+ Contents.Clear();
+ var hh = new HeaderHelper();
+ Search(Base, hh);
+ base.Update();
+ }
+
+ private void Search(ReportItem item, HeaderHelper hh)
+ {
+ var h = item as Header;
+ if (h != null)
+ {
+ h.Chapter = hh.GetHeader(h.Level);
+ Contents.Add(new ContentItem() { Chapter = h.Chapter, Title = h.Text });
+ }
+ foreach (var c in item.Children)
+ Search(c,hh);
+ }
+ public override void WriteContent(IReportWriter w)
+ {
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Drawing.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Drawing.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,46 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Drawing currently only supports SVG format.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Drawing currently only supports SVG format.
+ ///
+ public class Drawing : Figure
+ {
+ public enum DrawingFormat { Svg }
+ public DrawingFormat Format { get; set; }
+ public string Content { get; set; }
+
+ public override void WriteContent(IReportWriter w)
+ {
+ w.WriteDrawing(this);
+ }
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/DrawingFigure.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/DrawingFigure.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,73 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a drawing report item.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Represents a drawing report item.
+ ///
+ ///
+ /// Drawing currently only supports SVG format.
+ ///
+ public class DrawingFigure : Figure
+ {
+ ///
+ /// The drawing format.
+ ///
+ public enum DrawingFormat
+ {
+ ///
+ /// The svg.
+ ///
+ Svg
+ }
+
+ ///
+ /// Gets or sets Content.
+ ///
+ public string Content { get; set; }
+
+ ///
+ /// Gets or sets Format.
+ ///
+ public DrawingFormat Format { get; set; }
+
+ ///
+ /// The write content.
+ ///
+ ///
+ /// The w.
+ ///
+ public override void WriteContent(IReportWriter w)
+ {
+ w.WriteDrawing(this);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Equation.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Equation.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,59 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an equation.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Represents an equation.
+ ///
+ public class Equation : ReportItem
+ {
+ ///
+ /// Gets or sets Caption.
+ ///
+ public string Caption { get; set; }
+
+ ///
+ /// Gets or sets Content.
+ ///
+ public string Content { get; set; }
+
+ ///
+ /// The write content.
+ ///
+ ///
+ /// The w.
+ ///
+ public override void WriteContent(IReportWriter w)
+ {
+ w.WriteEquation(this);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Figure.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Figure.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,62 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a figure (abstract base class for DrawingFigure, Image and PlotFigure).
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Represents a figure (abstract base class for DrawingFigure, Image and PlotFigure).
+ ///
+ public abstract class Figure : ReportItem
+ {
+ ///
+ /// Gets or sets FigureNumber.
+ ///
+ public int FigureNumber { get; set; }
+
+ ///
+ /// Gets or sets FigureText.
+ ///
+ public string FigureText { get; set; }
+
+ ///
+ /// The get full caption.
+ ///
+ ///
+ /// The style.
+ ///
+ ///
+ /// The get full caption.
+ ///
+ public string GetFullCaption(ReportStyle style)
+ {
+ return string.Format(style.FigureTextFormatString, this.FigureNumber, this.FigureText);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Header.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Header.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,82 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a header.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Represents a header.
+ ///
+ public class Header : ReportItem
+ {
+ ///
+ /// Gets or sets the chapter number(s).
+ ///
+ public string Chapter { get; set; }
+
+ ///
+ /// Gets or sets the level of the header (1-5).
+ ///
+ public int Level { get; set; }
+
+ ///
+ /// Gets or sets the header text.
+ ///
+ public string Text { get; set; }
+
+ ///
+ /// The to string.
+ ///
+ ///
+ /// The to string.
+ ///
+ public override string ToString()
+ {
+ string h = string.Empty;
+ if (this.Chapter != null)
+ {
+ h += this.Chapter + " ";
+ }
+
+ h += this.Text;
+ return h;
+ }
+
+ ///
+ /// The write content.
+ ///
+ ///
+ /// The w.
+ ///
+ public override void WriteContent(IReportWriter w)
+ {
+ w.WriteHeader(this);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/HeaderHelper.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/HeaderHelper.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,82 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// The header helper.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// The header helper.
+ ///
+ public class HeaderHelper
+ {
+ ///
+ /// The header level.
+ ///
+ private readonly int[] headerLevel = new int[10];
+
+ ///
+ /// The get header.
+ ///
+ ///
+ /// The level.
+ ///
+ ///
+ /// The get header.
+ ///
+ public string GetHeader(int level)
+ {
+ for (int i = level - 1; i > 0; i--)
+ {
+ if (this.headerLevel[i] == 0)
+ {
+ this.headerLevel[i] = 1;
+ }
+ }
+
+ this.headerLevel[level]++;
+ for (int i = level + 1; i < 10; i++)
+ {
+ this.headerLevel[i] = 0;
+ }
+
+ string levelString = string.Empty;
+ for (int i = 1; i <= level; i++)
+ {
+ if (i > 1)
+ {
+ levelString += ".";
+ }
+
+ levelString += this.headerLevel[i];
+ }
+
+ return levelString;
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/Image.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/Image.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,54 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents an image report item.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ ///
+ /// Represents an image report item.
+ ///
+ public class Image : Figure
+ {
+ ///
+ /// Gets or sets Source.
+ ///
+ public string Source { get; set; }
+
+ ///
+ /// The write content.
+ ///
+ ///
+ /// The w.
+ ///
+ public override void WriteContent(IReportWriter w)
+ {
+ w.WriteImage(this);
+ }
+
+ }
+}
\ No newline at end of file
diff -r 88d699a65cc2 -r 5be8f2773237 External/OxyPlot/OxyPlot/Reporting/Report/ItemsTable.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/External/OxyPlot/OxyPlot/Reporting/Report/ItemsTable.cs Sat Jun 08 16:53:22 2013 +0000
@@ -0,0 +1,243 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2012 Oystein Bjorke
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Represents a table of items.
+//
+// --------------------------------------------------------------------------------------------------------------------
+namespace OxyPlot.Reporting
+{
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+
+ ///
+ /// Represents a table of items.
+ ///
+ public class ItemsTable : Table
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The items in rows.
+ ///
+ public ItemsTable(bool itemsInRows = true)
+ {
+ this.Fields = new List();
+ this.ItemsInRows = itemsInRows;
+ this.Alignment = Alignment.Center;
+ }
+
+ ///
+ /// Gets or sets Alignment.
+ ///
+ public Alignment Alignment { get; set; }
+
+ ///
+ /// Gets or sets Fields.
+ ///
+ public IList Fields { get; set; }
+
+ ///
+ /// Gets or sets the items.
+ /// The table will be filled when this property is set.
+ ///
+ /// The items.
+ public IEnumerable Items { get; set; }
+
+ ///
+ /// Gets a value indicating whether ItemsInRows.
+ ///
+ public bool ItemsInRows { get; private set; }
+
+ ///
+ /// The has header.
+ ///
+ ///
+ /// The has header.
+ ///
+ public bool HasHeader()
+ {
+ foreach (var c in this.Fields)
+ {
+ if (c.Header != null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// The to array.
+ ///
+ ///
+ ///
+ public string[,] ToArray()
+ {
+ List