Added the source code of OxyPlot as of commit d190d7748a73 (6.5.2013).
authormoel.mich
Sat, 08 Jun 2013 16:53:22 +0000
changeset 3915be8f2773237
parent 390 88d699a65cc2
child 392 4b43228a9894
Added the source code of OxyPlot as of commit d190d7748a73 (6.5.2013).
External/OxyPlot/GlobalAssemblyInfo.cs
External/OxyPlot/OxyPlot.WindowsForms/GraphicsRenderContext.cs
External/OxyPlot/OxyPlot.WindowsForms/Helpers/ConverterExtensions.cs
External/OxyPlot/OxyPlot.WindowsForms/NamespaceDoc.cs
External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj
External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk
External/OxyPlot/OxyPlot.WindowsForms/Plot.cs
External/OxyPlot/OxyPlot.WindowsForms/PlotControl.cs
External/OxyPlot/OxyPlot.WindowsForms/PngExporter.cs
External/OxyPlot/OxyPlot.WindowsForms/Properties/AssemblyInfo.cs
External/OxyPlot/OxyPlot.sln
External/OxyPlot/OxyPlot/Annotations/Annotation.cs
External/OxyPlot/OxyPlot/Annotations/AnnotationLayer.cs
External/OxyPlot/OxyPlot/Annotations/ArrowAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/EllipseAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/ImageAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/LineAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/LineAnnotationType.cs
External/OxyPlot/OxyPlot/Annotations/PolygonAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/RectangleAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/TextAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/TextualAnnotation.cs
External/OxyPlot/OxyPlot/Annotations/TileMapAnnotation.cs
External/OxyPlot/OxyPlot/Axes/AngleAxis.cs
External/OxyPlot/OxyPlot/Axes/Axis.cs
External/OxyPlot/OxyPlot/Axes/AxisChangeTypes.cs
External/OxyPlot/OxyPlot/Axes/AxisChangedEventArgs.cs
External/OxyPlot/OxyPlot/Axes/AxisLayer.cs
External/OxyPlot/OxyPlot/Axes/AxisPosition.cs
External/OxyPlot/OxyPlot/Axes/CategoryAxis.cs
External/OxyPlot/OxyPlot/Axes/ColorAxis.cs
External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs
External/OxyPlot/OxyPlot/Axes/DateTimeIntervalType.cs
External/OxyPlot/OxyPlot/Axes/LinearAxis.cs
External/OxyPlot/OxyPlot/Axes/LogarithmicAxis.cs
External/OxyPlot/OxyPlot/Axes/MagnitudeAxis.cs
External/OxyPlot/OxyPlot/Axes/RangeAxis.cs
External/OxyPlot/OxyPlot/Axes/TickStyle.cs
External/OxyPlot/OxyPlot/Axes/TimeAxis.cs
External/OxyPlot/OxyPlot/Axes/TimeSpanAxis.cs
External/OxyPlot/OxyPlot/ClassDiagrams/PlotModel.cd
External/OxyPlot/OxyPlot/ClassDiagrams/Reporting.cd
External/OxyPlot/OxyPlot/ClassDiagrams/Series.cd
External/OxyPlot/OxyPlot/Foundation/ArrayHelper.cs
External/OxyPlot/OxyPlot/Foundation/CanonicalSplineHelper.cs
External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerationAttribute.cs
External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerator.cs
External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGeneratorStringExtensions.cs
External/OxyPlot/OxyPlot/Foundation/CodeGenerator/ICodeGenerating.cs
External/OxyPlot/OxyPlot/Foundation/CohenSutherlandClipping.cs
External/OxyPlot/OxyPlot/Foundation/Color.cs
External/OxyPlot/OxyPlot/Foundation/Colors.cs
External/OxyPlot/OxyPlot/Foundation/Conrec.cs
External/OxyPlot/OxyPlot/Foundation/DataPoint.cs
External/OxyPlot/OxyPlot/Foundation/DataPointConverter.cs
External/OxyPlot/OxyPlot/Foundation/DoubleExtensions.cs
External/OxyPlot/OxyPlot/Foundation/FontWeights.cs
External/OxyPlot/OxyPlot/Foundation/FractionHelper.cs
External/OxyPlot/OxyPlot/Foundation/HorizontalAlignment.cs
External/OxyPlot/OxyPlot/Foundation/IDataPoint.cs
External/OxyPlot/OxyPlot/Foundation/IDataPointProvider.cs
External/OxyPlot/OxyPlot/Foundation/LineStyle.cs
External/OxyPlot/OxyPlot/Foundation/LineStyleHelper.cs
External/OxyPlot/OxyPlot/Foundation/ListFiller.cs
External/OxyPlot/OxyPlot/Foundation/MarkerType.cs
External/OxyPlot/OxyPlot/Foundation/OxyColor.cs
External/OxyPlot/OxyPlot/Foundation/OxyColorConverter.cs
External/OxyPlot/OxyPlot/Foundation/OxyColors.cs
External/OxyPlot/OxyPlot/Foundation/OxyImage.cs
External/OxyPlot/OxyPlot/Foundation/OxyPalette.cs
External/OxyPlot/OxyPlot/Foundation/OxyPalettes.cs
External/OxyPlot/OxyPlot/Foundation/OxyPen.cs
External/OxyPlot/OxyPlot/Foundation/OxyPenLineJoin.cs
External/OxyPlot/OxyPlot/Foundation/OxyRect.cs
External/OxyPlot/OxyPlot/Foundation/OxySize.cs
External/OxyPlot/OxyPlot/Foundation/OxyThickness.cs
External/OxyPlot/OxyPlot/Foundation/Pen.cs
External/OxyPlot/OxyPlot/Foundation/PlotLength.cs
External/OxyPlot/OxyPlot/Foundation/PlotLengthUnit.cs
External/OxyPlot/OxyPlot/Foundation/PngEncoder.cs
External/OxyPlot/OxyPlot/Foundation/Point.cs
External/OxyPlot/OxyPlot/Foundation/Rectangle.cs
External/OxyPlot/OxyPlot/Foundation/ReflectionHelper.cs
External/OxyPlot/OxyPlot/Foundation/ScreenPoint.cs
External/OxyPlot/OxyPlot/Foundation/ScreenPointHelper.cs
External/OxyPlot/OxyPlot/Foundation/ScreenVector.cs
External/OxyPlot/OxyPlot/Foundation/Size.cs
External/OxyPlot/OxyPlot/Foundation/StreamExtensions.cs
External/OxyPlot/OxyPlot/Foundation/StringHelper.cs
External/OxyPlot/OxyPlot/Foundation/SutherlandHodgmanClipping.cs
External/OxyPlot/OxyPlot/Foundation/VerticalAlignment.cs
External/OxyPlot/OxyPlot/Foundation/XmlWriterBase.cs
External/OxyPlot/OxyPlot/LibraryDoc.cs
External/OxyPlot/OxyPlot/Manipulators/CursorType.cs
External/OxyPlot/OxyPlot/Manipulators/IPlotControl.cs
External/OxyPlot/OxyPlot/Manipulators/ManipulationEventArgs.cs
External/OxyPlot/OxyPlot/Manipulators/ManipulatorBase.cs
External/OxyPlot/OxyPlot/Manipulators/PanManipulator.cs
External/OxyPlot/OxyPlot/Manipulators/ResetManipulator.cs
External/OxyPlot/OxyPlot/Manipulators/TrackerHitResult.cs
External/OxyPlot/OxyPlot/Manipulators/TrackerManipulator.cs
External/OxyPlot/OxyPlot/Manipulators/ZoomManipulator.cs
External/OxyPlot/OxyPlot/Manipulators/ZoomRectangleManipulator.cs
External/OxyPlot/OxyPlot/Manipulators/ZoomStepManipulator.cs
External/OxyPlot/OxyPlot/MouseActions/MouseAction.cs
External/OxyPlot/OxyPlot/MouseActions/SliderAction.cs
External/OxyPlot/OxyPlot/NamespaceDoc.cs
External/OxyPlot/OxyPlot/OxyPlot.csproj
External/OxyPlot/OxyPlot/OxyPlot.snk
External/OxyPlot/OxyPlot/PlotModel/HitTestResult.cs
External/OxyPlot/OxyPlot/PlotModel/OxyMouseButton.cs
External/OxyPlot/OxyPlot/PlotModel/OxyMouseEventArgs.cs
External/OxyPlot/OxyPlot/PlotModel/PlotElement.cs
External/OxyPlot/OxyPlot/PlotModel/PlotModel.Legends.cs
External/OxyPlot/OxyPlot/PlotModel/PlotModel.MouseEvents.cs
External/OxyPlot/OxyPlot/PlotModel/PlotModel.Rendering.cs
External/OxyPlot/OxyPlot/PlotModel/PlotModel.cs
External/OxyPlot/OxyPlot/PlotModel/SelectablePlotElement.cs
External/OxyPlot/OxyPlot/PlotModel/UIPlotElement.cs
External/OxyPlot/OxyPlot/Properties/AssemblyInfo.cs
External/OxyPlot/OxyPlot/Render/AngleAxisRenderer.cs
External/OxyPlot/OxyPlot/Render/AxisRenderer.cs
External/OxyPlot/OxyPlot/Render/AxisRendererBase.cs
External/OxyPlot/OxyPlot/Render/HorizontalAndVerticalAxisRenderer.cs
External/OxyPlot/OxyPlot/Render/IRenderContext.cs
External/OxyPlot/OxyPlot/Render/MagnitudeAxisRenderer.cs
External/OxyPlot/OxyPlot/Render/MathRenderingExtensions.cs
External/OxyPlot/OxyPlot/Render/PlotRenderer.cs
External/OxyPlot/OxyPlot/Render/RenderContextBase.cs
External/OxyPlot/OxyPlot/Render/RenderingExtensions.cs
External/OxyPlot/OxyPlot/Render/VerticalAxisRenderer.cs
External/OxyPlot/OxyPlot/Reporting/NamespaceDoc.cs
External/OxyPlot/OxyPlot/Reporting/Report/Content.cs
External/OxyPlot/OxyPlot/Reporting/Report/Drawing.cs
External/OxyPlot/OxyPlot/Reporting/Report/DrawingFigure.cs
External/OxyPlot/OxyPlot/Reporting/Report/Equation.cs
External/OxyPlot/OxyPlot/Reporting/Report/Figure.cs
External/OxyPlot/OxyPlot/Reporting/Report/Header.cs
External/OxyPlot/OxyPlot/Reporting/Report/HeaderHelper.cs
External/OxyPlot/OxyPlot/Reporting/Report/Image.cs
External/OxyPlot/OxyPlot/Reporting/Report/ItemsTable.cs
External/OxyPlot/OxyPlot/Reporting/Report/ItemsTableField.cs
External/OxyPlot/OxyPlot/Reporting/Report/Paragraph.cs
External/OxyPlot/OxyPlot/Reporting/Report/ParagraphStyle.cs
External/OxyPlot/OxyPlot/Reporting/Report/Plot.cs
External/OxyPlot/OxyPlot/Reporting/Report/PlotFigure.cs
External/OxyPlot/OxyPlot/Reporting/Report/PropertyTable.cs
External/OxyPlot/OxyPlot/Reporting/Report/Report.cs
External/OxyPlot/OxyPlot/Reporting/Report/ReportItem.cs
External/OxyPlot/OxyPlot/Reporting/Report/ReportSection.cs
External/OxyPlot/OxyPlot/Reporting/Report/ReportStyle.cs
External/OxyPlot/OxyPlot/Reporting/Report/Table.cs
External/OxyPlot/OxyPlot/Reporting/Report/TableColumn.cs
External/OxyPlot/OxyPlot/Reporting/Report/TableOfContents.cs
External/OxyPlot/OxyPlot/Reporting/ReportWriters/HtmlReportWriter.cs
External/OxyPlot/OxyPlot/Reporting/ReportWriters/IReportWriter.cs
External/OxyPlot/OxyPlot/Reporting/ReportWriters/StringExtensions.cs
External/OxyPlot/OxyPlot/Reporting/ReportWriters/TextReportWriter.cs
External/OxyPlot/OxyPlot/Reporting/ReportWriters/WikiReportWriter.cs
External/OxyPlot/OxyPlot/Series/AreaSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/BarItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/BarItemBase.cs
External/OxyPlot/OxyPlot/Series/BarSeries/BarSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/BarSeriesBase.cs
External/OxyPlot/OxyPlot/Series/BarSeries/BarSeriesBase{T}.cs
External/OxyPlot/OxyPlot/Series/BarSeries/CategorizedItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/CategorizedSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/ColumnItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/ColumnSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/ErrorColumnItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/ErrorColumnSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/IStackableSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/IntervalBarItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/IntervalBarSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/LabelPlacement.cs
External/OxyPlot/OxyPlot/Series/BarSeries/RectangleBarItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/RectangleBarSeries.cs
External/OxyPlot/OxyPlot/Series/BarSeries/TornadoBarItem.cs
External/OxyPlot/OxyPlot/Series/BarSeries/TornadoBarSeries.cs
External/OxyPlot/OxyPlot/Series/BoxPlotItem.cs
External/OxyPlot/OxyPlot/Series/BoxPlotSeries.cs
External/OxyPlot/OxyPlot/Series/CandleStickSeries.cs
External/OxyPlot/OxyPlot/Series/ContourSeries.cs
External/OxyPlot/OxyPlot/Series/DataPointSeries.cs
External/OxyPlot/OxyPlot/Series/DataSeries.cs
External/OxyPlot/OxyPlot/Series/FunctionSeries.cs
External/OxyPlot/OxyPlot/Series/HeatMapSeries.cs
External/OxyPlot/OxyPlot/Series/HighLowItem.cs
External/OxyPlot/OxyPlot/Series/HighLowSeries.cs
External/OxyPlot/OxyPlot/Series/ITrackableSeries.cs
External/OxyPlot/OxyPlot/Series/ItemsSeries.cs
External/OxyPlot/OxyPlot/Series/LineLegendPosition.cs
External/OxyPlot/OxyPlot/Series/LineSeries.cs
External/OxyPlot/OxyPlot/Series/PieSeries.cs
External/OxyPlot/OxyPlot/Series/PieSlice.cs
External/OxyPlot/OxyPlot/Series/PlotSeriesBase.cs
External/OxyPlot/OxyPlot/Series/ScatterPoint.cs
External/OxyPlot/OxyPlot/Series/ScatterSeries.cs
External/OxyPlot/OxyPlot/Series/Series.cs
External/OxyPlot/OxyPlot/Series/StairStepSeries.cs
External/OxyPlot/OxyPlot/Series/StemSeries.cs
External/OxyPlot/OxyPlot/Series/TwoColorLineSeries.cs
External/OxyPlot/OxyPlot/Series/XYAxisSeries.cs
External/OxyPlot/OxyPlot/Svg/NativeMethods.cs
External/OxyPlot/OxyPlot/Svg/SvgExporter.cs
External/OxyPlot/OxyPlot/Svg/SvgRenderContext.cs
External/OxyPlot/OxyPlot/Svg/SvgWriter.cs
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/External/OxyPlot/GlobalAssemblyInfo.cs	Sat Jun 08 16:53:22 2013 +0000
     1.3 @@ -0,0 +1,38 @@
     1.4 +//-----------------------------------------------------------------------
     1.5 +// <copyright file="GlobalAssemblyInfo.cs" company="OxyPlot">
     1.6 +//   The MIT License (MIT)
     1.7 +//
     1.8 +//   Copyright (c) 2012 Oystein Bjorke
     1.9 +//
    1.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    1.11 +//   copy of this software and associated documentation files (the
    1.12 +//   "Software"), to deal in the Software without restriction, including
    1.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    1.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    1.15 +//   permit persons to whom the Software is furnished to do so, subject to
    1.16 +//   the following conditions:
    1.17 +//
    1.18 +//   The above copyright notice and this permission notice shall be included
    1.19 +//   in all copies or substantial portions of the Software.
    1.20 +//
    1.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    1.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    1.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    1.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    1.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    1.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    1.28 +// </copyright>
    1.29 +//-----------------------------------------------------------------------
    1.30 +
    1.31 +using System.Reflection;
    1.32 +
    1.33 +[assembly: AssemblyConfiguration("")]
    1.34 +[assembly: AssemblyProduct("OxyPlot")]
    1.35 +[assembly: AssemblyCompany("OxyPlot")]
    1.36 +[assembly: AssemblyCopyright("Copyright (C) OxyPlot 2012.")]
    1.37 +[assembly: AssemblyTrademark("")]
    1.38 +[assembly: AssemblyCulture("")]
    1.39 +
    1.40 +[assembly: AssemblyVersion("2013.1.1.1")]
    1.41 +[assembly: AssemblyFileVersion("2013.1.1.1")]
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/GraphicsRenderContext.cs	Sat Jun 08 16:53:22 2013 +0000
     2.3 @@ -0,0 +1,558 @@
     2.4 +// --------------------------------------------------------------------------------------------------------------------
     2.5 +// <copyright file="GraphicsRenderContext.cs" company="OxyPlot">
     2.6 +//   The MIT License (MIT)
     2.7 +//
     2.8 +//   Copyright (c) 2012 Oystein Bjorke
     2.9 +//
    2.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    2.11 +//   copy of this software and associated documentation files (the
    2.12 +//   "Software"), to deal in the Software without restriction, including
    2.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    2.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    2.15 +//   permit persons to whom the Software is furnished to do so, subject to
    2.16 +//   the following conditions:
    2.17 +//
    2.18 +//   The above copyright notice and this permission notice shall be included
    2.19 +//   in all copies or substantial portions of the Software.
    2.20 +//
    2.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    2.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    2.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    2.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    2.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    2.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    2.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    2.28 +// </copyright>
    2.29 +// <summary>
    2.30 +//   The graphics render context.
    2.31 +// </summary>
    2.32 +// --------------------------------------------------------------------------------------------------------------------
    2.33 +namespace OxyPlot.WindowsForms
    2.34 +{
    2.35 +    using System;
    2.36 +    using System.Collections.Generic;
    2.37 +    using System.Drawing;
    2.38 +    using System.Drawing.Drawing2D;
    2.39 +    using System.Drawing.Imaging;
    2.40 +    using System.IO;
    2.41 +    using System.Linq;
    2.42 +
    2.43 +    using OxyPlot;
    2.44 +
    2.45 +    /// <summary>
    2.46 +    /// The graphics render context.
    2.47 +    /// </summary>
    2.48 +    internal class GraphicsRenderContext : RenderContextBase
    2.49 +    {
    2.50 +        /// <summary>
    2.51 +        /// The font size factor.
    2.52 +        /// </summary>
    2.53 +        private const float FontsizeFactor = 0.8f;
    2.54 +
    2.55 +        /// <summary>
    2.56 +        /// The GDI+ drawing surface.
    2.57 +        /// </summary>
    2.58 +        private Graphics g;
    2.59 +
    2.60 +        /// <summary>
    2.61 +        /// Initializes a new instance of the <see cref="GraphicsRenderContext"/> class.
    2.62 +        /// </summary>
    2.63 +        public GraphicsRenderContext()
    2.64 +        {
    2.65 +        }
    2.66 +
    2.67 +        /// <summary>
    2.68 +        /// Sets the graphics target.
    2.69 +        /// </summary>
    2.70 +        /// <param name="graphics">The graphics surface.</param>
    2.71 +        public void SetGraphicsTarget(Graphics graphics)
    2.72 +        {
    2.73 +            this.g = graphics;
    2.74 +        }
    2.75 +
    2.76 +        /// <summary>
    2.77 +        /// Draws the ellipse.
    2.78 +        /// </summary>
    2.79 +        /// <param name="rect">The rect.</param>
    2.80 +        /// <param name="fill">The fill.</param>
    2.81 +        /// <param name="stroke">The stroke.</param>
    2.82 +        /// <param name="thickness">The thickness.</param>
    2.83 +        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
    2.84 +        {
    2.85 +            if (fill != null)
    2.86 +            {
    2.87 +                this.g.FillEllipse(
    2.88 +                    this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
    2.89 +            }
    2.90 +
    2.91 +            if (stroke == null || thickness <= 0)
    2.92 +            {
    2.93 +                return;
    2.94 +            }
    2.95 +
    2.96 +            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
    2.97 +            {
    2.98 +                this.g.SmoothingMode = SmoothingMode.HighQuality;
    2.99 +                this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
   2.100 +            }
   2.101 +        }
   2.102 +
   2.103 +        /// <summary>
   2.104 +        /// Draws the line.
   2.105 +        /// </summary>
   2.106 +        /// <param name="points">The points.</param>
   2.107 +        /// <param name="stroke">The stroke.</param>
   2.108 +        /// <param name="thickness">The thickness.</param>
   2.109 +        /// <param name="dashArray">The dash array.</param>
   2.110 +        /// <param name="lineJoin">The line join.</param>
   2.111 +        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
   2.112 +        public override void DrawLine(
   2.113 +            IList<ScreenPoint> points,
   2.114 +            OxyColor stroke,
   2.115 +            double thickness,
   2.116 +            double[] dashArray,
   2.117 +            OxyPenLineJoin lineJoin,
   2.118 +            bool aliased)
   2.119 +        {
   2.120 +            if (stroke == null || thickness <= 0 || points.Count < 2)
   2.121 +            {
   2.122 +                return;
   2.123 +            }
   2.124 +
   2.125 +            this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
   2.126 +            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
   2.127 +            {
   2.128 +
   2.129 +                if (dashArray != null)
   2.130 +                {
   2.131 +                    pen.DashPattern = this.ToFloatArray(dashArray);
   2.132 +                }
   2.133 +
   2.134 +                switch (lineJoin)
   2.135 +                {
   2.136 +                    case OxyPenLineJoin.Round:
   2.137 +                        pen.LineJoin = LineJoin.Round;
   2.138 +                        break;
   2.139 +                    case OxyPenLineJoin.Bevel:
   2.140 +                        pen.LineJoin = LineJoin.Bevel;
   2.141 +                        break;
   2.142 +
   2.143 +                    // The default LineJoin is Miter
   2.144 +                }
   2.145 +
   2.146 +                this.g.DrawLines(pen, this.ToPoints(points));
   2.147 +            }
   2.148 +        }
   2.149 +
   2.150 +        /// <summary>
   2.151 +        /// Draws the polygon.
   2.152 +        /// </summary>
   2.153 +        /// <param name="points">The points.</param>
   2.154 +        /// <param name="fill">The fill.</param>
   2.155 +        /// <param name="stroke">The stroke.</param>
   2.156 +        /// <param name="thickness">The thickness.</param>
   2.157 +        /// <param name="dashArray">The dash array.</param>
   2.158 +        /// <param name="lineJoin">The line join.</param>
   2.159 +        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
   2.160 +        public override void DrawPolygon(
   2.161 +            IList<ScreenPoint> points,
   2.162 +            OxyColor fill,
   2.163 +            OxyColor stroke,
   2.164 +            double thickness,
   2.165 +            double[] dashArray,
   2.166 +            OxyPenLineJoin lineJoin,
   2.167 +            bool aliased)
   2.168 +        {
   2.169 +            if (points.Count < 2)
   2.170 +            {
   2.171 +                return;
   2.172 +            }
   2.173 +
   2.174 +            this.g.SmoothingMode = aliased ? SmoothingMode.None : SmoothingMode.HighQuality;
   2.175 +
   2.176 +            PointF[] pts = this.ToPoints(points);
   2.177 +            if (fill != null)
   2.178 +            {
   2.179 +                this.g.FillPolygon(this.ToBrush(fill), pts);
   2.180 +            }
   2.181 +
   2.182 +            if (stroke != null && thickness > 0)
   2.183 +            {
   2.184 +                using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
   2.185 +                {
   2.186 +
   2.187 +                    if (dashArray != null)
   2.188 +                    {
   2.189 +                        pen.DashPattern = this.ToFloatArray(dashArray);
   2.190 +                    }
   2.191 +
   2.192 +                    switch (lineJoin)
   2.193 +                    {
   2.194 +                        case OxyPenLineJoin.Round:
   2.195 +                            pen.LineJoin = LineJoin.Round;
   2.196 +                            break;
   2.197 +                        case OxyPenLineJoin.Bevel:
   2.198 +                            pen.LineJoin = LineJoin.Bevel;
   2.199 +                            break;
   2.200 +
   2.201 +                        // The default LineJoin is Miter
   2.202 +                    }
   2.203 +
   2.204 +                    this.g.DrawPolygon(pen, pts);
   2.205 +                }
   2.206 +            }
   2.207 +        }
   2.208 +
   2.209 +        /// <summary>
   2.210 +        /// The draw rectangle.
   2.211 +        /// </summary>
   2.212 +        /// <param name="rect">
   2.213 +        /// The rect.
   2.214 +        /// </param>
   2.215 +        /// <param name="fill">
   2.216 +        /// The fill.
   2.217 +        /// </param>
   2.218 +        /// <param name="stroke">
   2.219 +        /// The stroke.
   2.220 +        /// </param>
   2.221 +        /// <param name="thickness">
   2.222 +        /// The thickness.
   2.223 +        /// </param>
   2.224 +        public override void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
   2.225 +        {
   2.226 +            if (fill != null)
   2.227 +            {
   2.228 +                this.g.FillRectangle(
   2.229 +                    this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
   2.230 +            }
   2.231 +
   2.232 +            if (stroke == null || thickness <= 0)
   2.233 +            {
   2.234 +                return;
   2.235 +            }
   2.236 +
   2.237 +            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
   2.238 +            {
   2.239 +                this.g.DrawRectangle(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
   2.240 +            }
   2.241 +        }
   2.242 +
   2.243 +        /// <summary>
   2.244 +        /// The draw text.
   2.245 +        /// </summary>
   2.246 +        /// <param name="p">
   2.247 +        /// The p.
   2.248 +        /// </param>
   2.249 +        /// <param name="text">
   2.250 +        /// The text.
   2.251 +        /// </param>
   2.252 +        /// <param name="fill">
   2.253 +        /// The fill.
   2.254 +        /// </param>
   2.255 +        /// <param name="fontFamily">
   2.256 +        /// The font family.
   2.257 +        /// </param>
   2.258 +        /// <param name="fontSize">
   2.259 +        /// The font size.
   2.260 +        /// </param>
   2.261 +        /// <param name="fontWeight">
   2.262 +        /// The font weight.
   2.263 +        /// </param>
   2.264 +        /// <param name="rotate">
   2.265 +        /// The rotate.
   2.266 +        /// </param>
   2.267 +        /// <param name="halign">
   2.268 +        /// The halign.
   2.269 +        /// </param>
   2.270 +        /// <param name="valign">
   2.271 +        /// The valign.
   2.272 +        /// </param>
   2.273 +        /// <param name="maxSize">
   2.274 +        /// The maximum size of the text.
   2.275 +        /// </param>
   2.276 +        public override void DrawText(
   2.277 +            ScreenPoint p,
   2.278 +            string text,
   2.279 +            OxyColor fill,
   2.280 +            string fontFamily,
   2.281 +            double fontSize,
   2.282 +            double fontWeight,
   2.283 +            double rotate,
   2.284 +            HorizontalAlignment halign,
   2.285 +            VerticalAlignment valign,
   2.286 +            OxySize? maxSize)
   2.287 +        {
   2.288 +            var fs = FontStyle.Regular;
   2.289 +            if (fontWeight >= 700)
   2.290 +            {
   2.291 +                fs = FontStyle.Bold;
   2.292 +            }
   2.293 +
   2.294 +            using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
   2.295 +            {
   2.296 +                using (var sf = new StringFormat { Alignment = StringAlignment.Near })
   2.297 +                {
   2.298 +                    var size = this.g.MeasureString(text, font);
   2.299 +                    if (maxSize != null)
   2.300 +                    {
   2.301 +                        if (size.Width > maxSize.Value.Width)
   2.302 +                        {
   2.303 +                            size.Width = (float)maxSize.Value.Width;
   2.304 +                        }
   2.305 +
   2.306 +                        if (size.Height > maxSize.Value.Height)
   2.307 +                        {
   2.308 +                            size.Height = (float)maxSize.Value.Height;
   2.309 +                        }
   2.310 +                    }
   2.311 +
   2.312 +                    float dx = 0;
   2.313 +                    if (halign == HorizontalAlignment.Center)
   2.314 +                    {
   2.315 +                        dx = -size.Width / 2;
   2.316 +                    }
   2.317 +
   2.318 +                    if (halign == HorizontalAlignment.Right)
   2.319 +                    {
   2.320 +                        dx = -size.Width;
   2.321 +                    }
   2.322 +
   2.323 +                    float dy = 0;
   2.324 +                    sf.LineAlignment = StringAlignment.Near;
   2.325 +                    if (valign == VerticalAlignment.Middle)
   2.326 +                    {
   2.327 +                        dy = -size.Height / 2;
   2.328 +                    }
   2.329 +
   2.330 +                    if (valign == VerticalAlignment.Bottom)
   2.331 +                    {
   2.332 +                        dy = -size.Height;
   2.333 +                    }
   2.334 +
   2.335 +                    this.g.TranslateTransform((float)p.X, (float)p.Y);
   2.336 +                    if (Math.Abs(rotate) > double.Epsilon)
   2.337 +                    {
   2.338 +                        this.g.RotateTransform((float)rotate);
   2.339 +                    }
   2.340 +
   2.341 +                    this.g.TranslateTransform(dx, dy);
   2.342 +
   2.343 +                    var layoutRectangle = new RectangleF(0, 0, size.Width, size.Height);
   2.344 +                    this.g.DrawString(text, font, this.ToBrush(fill), layoutRectangle, sf);
   2.345 +
   2.346 +                    this.g.ResetTransform();
   2.347 +                }
   2.348 +            }
   2.349 +        }
   2.350 +
   2.351 +        /// <summary>
   2.352 +        /// The measure text.
   2.353 +        /// </summary>
   2.354 +        /// <param name="text">The text.</param>
   2.355 +        /// <param name="fontFamily">The font family.</param>
   2.356 +        /// <param name="fontSize">The font size.</param>
   2.357 +        /// <param name="fontWeight">The font weight.</param>
   2.358 +        /// <returns>The size of the text.</returns>
   2.359 +        public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight)
   2.360 +        {
   2.361 +            if (text == null)
   2.362 +            {
   2.363 +                return OxySize.Empty;
   2.364 +            }
   2.365 +
   2.366 +            var fs = FontStyle.Regular;
   2.367 +            if (fontWeight >= 700)
   2.368 +            {
   2.369 +                fs = FontStyle.Bold;
   2.370 +            }
   2.371 +
   2.372 +            using (var font = new Font(fontFamily, (float)fontSize * FontsizeFactor, fs))
   2.373 +            {
   2.374 +                var size = this.g.MeasureString(text, font);
   2.375 +                return new OxySize(size.Width, size.Height);
   2.376 +            }
   2.377 +        }
   2.378 +
   2.379 +        /// <summary>
   2.380 +        /// Converts a fill color to a System.Drawing.Brush.
   2.381 +        /// </summary>
   2.382 +        /// <param name="fill">
   2.383 +        /// The fill color.
   2.384 +        /// </param>
   2.385 +        /// <returns>
   2.386 +        /// The brush.
   2.387 +        /// </returns>
   2.388 +        private Brush ToBrush(OxyColor fill)
   2.389 +        {
   2.390 +            if (fill != null)
   2.391 +            {
   2.392 +                return new SolidBrush(this.ToColor(fill));
   2.393 +            }
   2.394 +
   2.395 +            return null;
   2.396 +        }
   2.397 +
   2.398 +        /// <summary>
   2.399 +        /// Converts a color to a System.Drawing.Color.
   2.400 +        /// </summary>
   2.401 +        /// <param name="c">
   2.402 +        /// The color.
   2.403 +        /// </param>
   2.404 +        /// <returns>
   2.405 +        /// The System.Drawing.Color.
   2.406 +        /// </returns>
   2.407 +        private Color ToColor(OxyColor c)
   2.408 +        {
   2.409 +            return Color.FromArgb(c.A, c.R, c.G, c.B);
   2.410 +        }
   2.411 +
   2.412 +        /// <summary>
   2.413 +        /// Converts a double array to a float array.
   2.414 +        /// </summary>
   2.415 +        /// <param name="a">
   2.416 +        /// The a.
   2.417 +        /// </param>
   2.418 +        /// <returns>
   2.419 +        /// The float array.
   2.420 +        /// </returns>
   2.421 +        private float[] ToFloatArray(double[] a)
   2.422 +        {
   2.423 +            if (a == null)
   2.424 +            {
   2.425 +                return null;
   2.426 +            }
   2.427 +
   2.428 +            var r = new float[a.Length];
   2.429 +            for (int i = 0; i < a.Length; i++)
   2.430 +            {
   2.431 +                r[i] = (float)a[i];
   2.432 +            }
   2.433 +
   2.434 +            return r;
   2.435 +        }
   2.436 +
   2.437 +        /// <summary>
   2.438 +        /// Converts a list of point to an array of PointF.
   2.439 +        /// </summary>
   2.440 +        /// <param name="points">
   2.441 +        /// The points.
   2.442 +        /// </param>
   2.443 +        /// <returns>
   2.444 +        /// An array of points.
   2.445 +        /// </returns>
   2.446 +        private PointF[] ToPoints(IList<ScreenPoint> points)
   2.447 +        {
   2.448 +            if (points == null)
   2.449 +            {
   2.450 +                return null;
   2.451 +            }
   2.452 +
   2.453 +            var r = new PointF[points.Count()];
   2.454 +            int i = 0;
   2.455 +            foreach (ScreenPoint p in points)
   2.456 +            {
   2.457 +                r[i++] = new PointF((float)p.X, (float)p.Y);
   2.458 +            }
   2.459 +
   2.460 +            return r;
   2.461 +        }
   2.462 +
   2.463 +        public override void CleanUp()
   2.464 +        {
   2.465 +            var imagesToRelease = imageCache.Keys.Where(i => !imagesInUse.Contains(i));
   2.466 +            foreach (var i in imagesToRelease)
   2.467 +            {
   2.468 +                var image = this.GetImage(i);
   2.469 +                image.Dispose();
   2.470 +                imageCache.Remove(i);
   2.471 +            }
   2.472 +
   2.473 +            imagesInUse.Clear();
   2.474 +        }
   2.475 +
   2.476 +        public override OxyImageInfo GetImageInfo(OxyImage source)
   2.477 +        {
   2.478 +            var image = this.GetImage(source);
   2.479 +            return image == null ? null : new OxyImageInfo { Width = (uint)image.Width, Height = (uint)image.Height, DpiX = image.HorizontalResolution, DpiY = image.VerticalResolution };
   2.480 +        }
   2.481 +
   2.482 +        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)
   2.483 +        {
   2.484 +            var image = this.GetImage(source);
   2.485 +            if (image != null)
   2.486 +            {
   2.487 +                ImageAttributes ia = null;
   2.488 +                if (opacity < 1)
   2.489 +                {
   2.490 +                    var cm = new ColorMatrix
   2.491 +                                 {
   2.492 +                                     Matrix00 = 1f,
   2.493 +                                     Matrix11 = 1f,
   2.494 +                                     Matrix22 = 1f,
   2.495 +                                     Matrix33 = 1f,
   2.496 +                                     Matrix44 = (float)opacity
   2.497 +                                 };
   2.498 +
   2.499 +                    ia = new ImageAttributes();
   2.500 +                    ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
   2.501 +                }
   2.502 +
   2.503 +                g.InterpolationMode = interpolate ? InterpolationMode.HighQualityBicubic : InterpolationMode.NearestNeighbor;
   2.504 +                int sx = (int)Math.Round(x);
   2.505 +                int sy = (int)Math.Round(y);
   2.506 +                int sw = (int)Math.Round(x + w) - sx;
   2.507 +                int sh = (int)Math.Round(y + h) - sy;
   2.508 +                g.DrawImage(image, new Rectangle(sx, sy, sw, sh), srcX, srcY, srcWidth, srcHeight, GraphicsUnit.Pixel, ia);
   2.509 +            }
   2.510 +        }
   2.511 +
   2.512 +        private HashSet<OxyImage> imagesInUse = new HashSet<OxyImage>();
   2.513 +
   2.514 +        private Dictionary<OxyImage, Image> imageCache = new Dictionary<OxyImage, Image>();
   2.515 +
   2.516 +
   2.517 +        private Image GetImage(OxyImage source)
   2.518 +        {
   2.519 +            if (source == null)
   2.520 +            {
   2.521 +                return null;
   2.522 +            }
   2.523 +
   2.524 +            if (!this.imagesInUse.Contains(source))
   2.525 +            {
   2.526 +                this.imagesInUse.Add(source);
   2.527 +            }
   2.528 +
   2.529 +            Image src;
   2.530 +            if (this.imageCache.TryGetValue(source, out src))
   2.531 +            {
   2.532 +                return src;
   2.533 +            }
   2.534 +
   2.535 +            if (source != null)
   2.536 +            {
   2.537 +                Image btm;
   2.538 +                using (var ms = new MemoryStream(source.GetData()))
   2.539 +                {
   2.540 +                    btm = Image.FromStream(ms);
   2.541 +                }
   2.542 +
   2.543 +                this.imageCache.Add(source, btm);
   2.544 +                return btm;
   2.545 +            }
   2.546 +
   2.547 +            return null;
   2.548 +        }
   2.549 +
   2.550 +        public override bool SetClip(OxyRect rect)
   2.551 +        {
   2.552 +            this.g.SetClip(rect.ToRect(false));
   2.553 +            return true;
   2.554 +        }
   2.555 +
   2.556 +        public override void ResetClip()
   2.557 +        {
   2.558 +            this.g.ResetClip();
   2.559 +        }
   2.560 +    }
   2.561 +}
   2.562 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/Helpers/ConverterExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
     3.3 @@ -0,0 +1,251 @@
     3.4 +// --------------------------------------------------------------------------------------------------------------------
     3.5 +// <copyright file="ConverterExtensions.cs" company="OxyPlot">
     3.6 +//   The MIT License (MIT)
     3.7 +//
     3.8 +//   Copyright (c) 2012 Oystein Bjorke
     3.9 +//
    3.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    3.11 +//   copy of this software and associated documentation files (the
    3.12 +//   "Software"), to deal in the Software without restriction, including
    3.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    3.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    3.15 +//   permit persons to whom the Software is furnished to do so, subject to
    3.16 +//   the following conditions:
    3.17 +//
    3.18 +//   The above copyright notice and this permission notice shall be included
    3.19 +//   in all copies or substantial portions of the Software.
    3.20 +//
    3.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    3.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    3.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    3.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    3.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    3.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    3.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    3.28 +// </copyright>
    3.29 +// <summary>
    3.30 +//   Extension method used to convert to/from Windows/Windows.Media classes.
    3.31 +// </summary>
    3.32 +// --------------------------------------------------------------------------------------------------------------------
    3.33 +namespace OxyPlot.WindowsForms
    3.34 +{
    3.35 +    using System;
    3.36 +    using System.Drawing;
    3.37 +    using System.Windows.Forms;
    3.38 +
    3.39 +    /// <summary>
    3.40 +    /// Extension method used to convert to/from Windows/Windows.Media classes.
    3.41 +    /// </summary>
    3.42 +    public static class ConverterExtensions
    3.43 +    {
    3.44 +        /// <summary>
    3.45 +        /// Calculate the distance between two points.
    3.46 +        /// </summary>
    3.47 +        /// <param name="p1">
    3.48 +        /// The first point.
    3.49 +        /// </param>
    3.50 +        /// <param name="p2">
    3.51 +        /// The second point.
    3.52 +        /// </param>
    3.53 +        /// <returns>
    3.54 +        /// The distance.
    3.55 +        /// </returns>
    3.56 +        public static double DistanceTo(this Point p1, Point p2)
    3.57 +        {
    3.58 +            double dx = p1.X - p2.X;
    3.59 +            double dy = p1.Y - p2.Y;
    3.60 +            return Math.Sqrt((dx * dx) + (dy * dy));
    3.61 +        }
    3.62 +
    3.63 +        /// <summary>
    3.64 +        /// Converts a color to a Brush.
    3.65 +        /// </summary>
    3.66 +        /// <param name="c">
    3.67 +        /// The color.
    3.68 +        /// </param>
    3.69 +        /// <returns>
    3.70 +        /// A SolidColorBrush.
    3.71 +        /// </returns>
    3.72 +        public static Brush ToBrush(this OxyColor c)
    3.73 +        {
    3.74 +            return new SolidBrush(c.ToColor());
    3.75 +        }
    3.76 +
    3.77 +        /// <summary>
    3.78 +        /// Converts an OxyColor to a Color.
    3.79 +        /// </summary>
    3.80 +        /// <param name="c">
    3.81 +        /// The color.
    3.82 +        /// </param>
    3.83 +        /// <returns>
    3.84 +        /// A Color.
    3.85 +        /// </returns>
    3.86 +        public static Color ToColor(this OxyColor c)
    3.87 +        {
    3.88 +            return Color.FromArgb(c.A, c.R, c.G, c.B);
    3.89 +        }
    3.90 +
    3.91 +        /// <summary>
    3.92 +        /// Converts a HorizontalAlignment to a HorizontalTextAlign.
    3.93 +        /// </summary>
    3.94 +        /// <param name="alignment">
    3.95 +        /// The alignment.
    3.96 +        /// </param>
    3.97 +        /// <returns>
    3.98 +        /// A HorizontalTextAlign.
    3.99 +        /// </returns>
   3.100 +        public static OxyPlot.HorizontalAlignment ToHorizontalTextAlign(this HorizontalAlignment alignment)
   3.101 +        {
   3.102 +            switch (alignment)
   3.103 +            {
   3.104 +                case HorizontalAlignment.Center:
   3.105 +                    return OxyPlot.HorizontalAlignment.Center;
   3.106 +                case HorizontalAlignment.Right:
   3.107 +                    return OxyPlot.HorizontalAlignment.Right;
   3.108 +                default:
   3.109 +                    return OxyPlot.HorizontalAlignment.Left;
   3.110 +            }
   3.111 +        }
   3.112 +
   3.113 +        /// <summary>
   3.114 +        /// Converts a Color to an OxyColor.
   3.115 +        /// </summary>
   3.116 +        /// <param name="color">
   3.117 +        /// The color.
   3.118 +        /// </param>
   3.119 +        /// <returns>
   3.120 +        /// An OxyColor.
   3.121 +        /// </returns>
   3.122 +        public static OxyColor ToOxyColor(this Color color)
   3.123 +        {
   3.124 +            return OxyColor.FromArgb(color.A, color.R, color.G, color.B);
   3.125 +        }
   3.126 +
   3.127 +        /// <summary>
   3.128 +        /// Converts a nullable Color to an OxyColor.
   3.129 +        /// </summary>
   3.130 +        /// <param name="color">
   3.131 +        /// The color.
   3.132 +        /// </param>
   3.133 +        /// <returns>
   3.134 +        /// An OxyColor.
   3.135 +        /// </returns>
   3.136 +        public static OxyColor ToOxyColor(this Color? color)
   3.137 +        {
   3.138 +            return color.HasValue ? color.Value.ToOxyColor() : null;
   3.139 +        }
   3.140 +
   3.141 +        /// <summary>
   3.142 +        /// Converts a Brush to an OxyColor.
   3.143 +        /// </summary>
   3.144 +        /// <param name="brush">
   3.145 +        /// The brush.
   3.146 +        /// </param>
   3.147 +        /// <returns>
   3.148 +        /// An oxycolor.
   3.149 +        /// </returns>
   3.150 +        public static OxyColor ToOxyColor(this Brush brush)
   3.151 +        {
   3.152 +            var scb = brush as SolidBrush;
   3.153 +            return scb != null ? scb.Color.ToOxyColor() : null;
   3.154 +        }
   3.155 +
   3.156 +        /// <summary>
   3.157 +        /// Converts a Thickness to an OxyThickness.
   3.158 +        /// </summary>
   3.159 +        /// <returns>
   3.160 +        /// An OxyPlot thickness.
   3.161 +        /// </returns>
   3.162 +        /// <summary>
   3.163 +        /// Converts a ScreenPoint to a Point.
   3.164 +        /// </summary>
   3.165 +        /// <param name="pt">
   3.166 +        /// The screen point.
   3.167 +        /// </param>
   3.168 +        /// <param name="aliased">
   3.169 +        /// use pixel alignment conversion if set to <c>true</c>.
   3.170 +        /// </param>
   3.171 +        /// <returns>
   3.172 +        /// A point.
   3.173 +        /// </returns>
   3.174 +        public static Point ToPoint(this ScreenPoint pt, bool aliased)
   3.175 +        {
   3.176 +            // adding 0.5 to get pixel boundary alignment, seems to work
   3.177 +            // http://weblogs.asp.net/mschwarz/archive/2008/01/04/silverlight-rectangles-paths-and-line-comparison.aspx
   3.178 +            // http://www.wynapse.com/Silverlight/Tutor/Silverlight_Rectangles_Paths_And_Lines_Comparison.aspx
   3.179 +            if (aliased)
   3.180 +            {
   3.181 +                return new Point((int)pt.X, (int)pt.Y);
   3.182 +            }
   3.183 +
   3.184 +            return new Point((int)Math.Round(pt.X), (int)Math.Round(pt.Y));
   3.185 +        }
   3.186 +
   3.187 +        /// <summary>
   3.188 +        /// Converts an OxyRect to a Rect.
   3.189 +        /// </summary>
   3.190 +        /// <param name="r">
   3.191 +        /// The rectangle.
   3.192 +        /// </param>
   3.193 +        /// <param name="aliased">
   3.194 +        /// use pixel alignment if set to <c>true</c>.
   3.195 +        /// </param>
   3.196 +        /// <returns>
   3.197 +        /// A rect.
   3.198 +        /// </returns>
   3.199 +        public static Rectangle ToRect(this OxyRect r, bool aliased)
   3.200 +        {
   3.201 +            if (aliased)
   3.202 +            {
   3.203 +                var x = (int)r.Left;
   3.204 +                var y = (int)r.Top;
   3.205 +                var ri = (int)r.Right;
   3.206 +                var bo = (int)r.Bottom;
   3.207 +                return new Rectangle(x, y, ri - x, bo - y);
   3.208 +            }
   3.209 +
   3.210 +            return new Rectangle(
   3.211 +                (int)Math.Round(r.Left), (int)Math.Round(r.Top), (int)Math.Round(r.Width), (int)Math.Round(r.Height));
   3.212 +        }
   3.213 +
   3.214 +        /// <summary>
   3.215 +        /// Converts a point to a ScreenPoint.
   3.216 +        /// </summary>
   3.217 +        /// <param name="pt">
   3.218 +        /// The point.
   3.219 +        /// </param>
   3.220 +        /// <returns>
   3.221 +        /// A screen point.
   3.222 +        /// </returns>
   3.223 +        public static ScreenPoint ToScreenPoint(this Point pt)
   3.224 +        {
   3.225 +            return new ScreenPoint(pt.X, pt.Y);
   3.226 +        }
   3.227 +
   3.228 +        /// <summary>
   3.229 +        /// Converts a Point array to a ScreenPoint array.
   3.230 +        /// </summary>
   3.231 +        /// <param name="points">
   3.232 +        /// The points.
   3.233 +        /// </param>
   3.234 +        /// <returns>
   3.235 +        /// A ScreenPoint array.
   3.236 +        /// </returns>
   3.237 +        public static ScreenPoint[] ToScreenPointArray(this Point[] points)
   3.238 +        {
   3.239 +            if (points == null)
   3.240 +            {
   3.241 +                return null;
   3.242 +            }
   3.243 +
   3.244 +            var pts = new ScreenPoint[points.Length];
   3.245 +            for (int i = 0; i < points.Length; i++)
   3.246 +            {
   3.247 +                pts[i] = points[i].ToScreenPoint();
   3.248 +            }
   3.249 +
   3.250 +            return pts;
   3.251 +        }
   3.252 +
   3.253 +    }
   3.254 +}
   3.255 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/NamespaceDoc.cs	Sat Jun 08 16:53:22 2013 +0000
     4.3 @@ -0,0 +1,37 @@
     4.4 +// --------------------------------------------------------------------------------------------------------------------
     4.5 +// <copyright file="NamespaceDoc.cs" company="OxyPlot">
     4.6 +//   The MIT License (MIT)
     4.7 +//   
     4.8 +//   Copyright (c) 2012 Oystein Bjorke
     4.9 +//   
    4.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    4.11 +//   copy of this software and associated documentation files (the
    4.12 +//   "Software"), to deal in the Software without restriction, including
    4.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    4.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    4.15 +//   permit persons to whom the Software is furnished to do so, subject to
    4.16 +//   the following conditions:
    4.17 +//   
    4.18 +//   The above copyright notice and this permission notice shall be included
    4.19 +//   in all copies or substantial portions of the Software.
    4.20 +//   
    4.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    4.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    4.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    4.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    4.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    4.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    4.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    4.28 +// </copyright>
    4.29 +// --------------------------------------------------------------------------------------------------------------------
    4.30 +
    4.31 +namespace OxyPlot.WindowsForms
    4.32 +{
    4.33 +    /// <summary>
    4.34 +    /// The OxyPlot.WindowsForms namespace contains controls for Windows Forms and a bitmap exporter.
    4.35 +    /// </summary>
    4.36 +    [System.Runtime.CompilerServices.CompilerGenerated]
    4.37 +    internal class NamespaceDoc
    4.38 +    {
    4.39 +    }
    4.40 +}
    4.41 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj	Sat Jun 08 16:53:22 2013 +0000
     5.3 @@ -0,0 +1,79 @@
     5.4 +<?xml version="1.0" encoding="utf-8"?>
     5.5 +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     5.6 +  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
     5.7 +  <PropertyGroup>
     5.8 +    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     5.9 +    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    5.10 +    <ProjectGuid>{D4554296-094E-4CAC-8EAE-44EB250666C6}</ProjectGuid>
    5.11 +    <OutputType>Library</OutputType>
    5.12 +    <AppDesignerFolder>Properties</AppDesignerFolder>
    5.13 +    <RootNamespace>OxyPlot.WindowsForms</RootNamespace>
    5.14 +    <AssemblyName>OxyPlot.WindowsForms</AssemblyName>
    5.15 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    5.16 +    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
    5.17 +    <FileAlignment>512</FileAlignment>
    5.18 +  </PropertyGroup>
    5.19 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    5.20 +    <DebugSymbols>true</DebugSymbols>
    5.21 +    <DebugType>full</DebugType>
    5.22 +    <Optimize>false</Optimize>
    5.23 +    <OutputPath>bin\Debug\NET40\</OutputPath>
    5.24 +    <IntermediateOutputPath>obj\Debug\NET40\</IntermediateOutputPath>
    5.25 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
    5.26 +    <ErrorReport>prompt</ErrorReport>
    5.27 +    <WarningLevel>4</WarningLevel>
    5.28 +  </PropertyGroup>
    5.29 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    5.30 +    <DebugType>pdbonly</DebugType>
    5.31 +    <Optimize>true</Optimize>
    5.32 +    <OutputPath>..\..\Output\NET40\</OutputPath>
    5.33 +    <IntermediateOutputPath>obj\Release\NET40\</IntermediateOutputPath>
    5.34 +    <DefineConstants>TRACE</DefineConstants>
    5.35 +    <ErrorReport>prompt</ErrorReport>
    5.36 +    <WarningLevel>4</WarningLevel>
    5.37 +    <DocumentationFile>..\..\Output\NET40\OxyPlot.WindowsForms.XML</DocumentationFile>
    5.38 +  </PropertyGroup>
    5.39 +  <PropertyGroup>
    5.40 +    <SignAssembly>true</SignAssembly>
    5.41 +  </PropertyGroup>
    5.42 +  <PropertyGroup>
    5.43 +    <AssemblyOriginatorKeyFile>OxyPlot.WindowsForms.snk</AssemblyOriginatorKeyFile>
    5.44 +  </PropertyGroup>
    5.45 +  <ItemGroup>
    5.46 +    <Reference Include="System" />
    5.47 +    <Reference Include="System.Core" />
    5.48 +    <Reference Include="System.Drawing" />
    5.49 +    <Reference Include="System.Windows.Forms" />
    5.50 +  </ItemGroup>
    5.51 +  <ItemGroup>
    5.52 +    <Compile Include="..\GlobalAssemblyInfo.cs">
    5.53 +      <Link>Properties\GlobalAssemblyInfo.cs</Link>
    5.54 +    </Compile>
    5.55 +    <Compile Include="Helpers\ConverterExtensions.cs" />
    5.56 +    <Compile Include="GraphicsRenderContext.cs" />
    5.57 +    <Compile Include="NamespaceDoc.cs" />
    5.58 +    <Compile Include="Plot.cs">
    5.59 +      <SubType>Component</SubType>
    5.60 +    </Compile>
    5.61 +    <Compile Include="PngExporter.cs" />
    5.62 +    <Compile Include="Properties\AssemblyInfo.cs" />
    5.63 +    <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
    5.64 +  </ItemGroup>
    5.65 +  <ItemGroup>
    5.66 +    <None Include="OxyPlot.WindowsForms.snk" />
    5.67 +  </ItemGroup>
    5.68 +  <ItemGroup>
    5.69 +    <ProjectReference Include="..\OxyPlot\OxyPlot.csproj">
    5.70 +      <Project>{7a0b35c0-dd17-4964-8e9a-44d6cecdc692}</Project>
    5.71 +      <Name>OxyPlot</Name>
    5.72 +    </ProjectReference>
    5.73 +  </ItemGroup>
    5.74 +  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    5.75 +  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
    5.76 +       Other similar extension points exist, see Microsoft.Common.targets.
    5.77 +  <Target Name="BeforeBuild">
    5.78 +  </Target>
    5.79 +  <Target Name="AfterBuild">
    5.80 +  </Target>
    5.81 +  -->
    5.82 +</Project>
    5.83 \ No newline at end of file
     6.1 Binary file External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk has changed
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/Plot.cs	Sat Jun 08 16:53:22 2013 +0000
     7.3 @@ -0,0 +1,897 @@
     7.4 +// --------------------------------------------------------------------------------------------------------------------
     7.5 +// <copyright file="Plot.cs" company="OxyPlot">
     7.6 +//   The MIT License (MIT)
     7.7 +//
     7.8 +//   Copyright (c) 2012 Oystein Bjorke
     7.9 +//
    7.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    7.11 +//   copy of this software and associated documentation files (the
    7.12 +//   "Software"), to deal in the Software without restriction, including
    7.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    7.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    7.15 +//   permit persons to whom the Software is furnished to do so, subject to
    7.16 +//   the following conditions:
    7.17 +//
    7.18 +//   The above copyright notice and this permission notice shall be included
    7.19 +//   in all copies or substantial portions of the Software.
    7.20 +//
    7.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    7.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    7.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    7.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    7.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    7.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    7.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    7.28 +// </copyright>
    7.29 +// <summary>
    7.30 +//   Represents a control that displays a plot.
    7.31 +// </summary>
    7.32 +// --------------------------------------------------------------------------------------------------------------------
    7.33 +namespace OxyPlot.WindowsForms
    7.34 +{
    7.35 +    using System;
    7.36 +    using System.ComponentModel;
    7.37 +    using System.Diagnostics;
    7.38 +    using System.Drawing;
    7.39 +    using System.Runtime.InteropServices;
    7.40 +    using System.Windows.Forms;
    7.41 +
    7.42 +    using OxyPlot.Axes;
    7.43 +    using OxyPlot.Series;
    7.44 +
    7.45 +    /// <summary>
    7.46 +    /// Represents a control that displays a plot.
    7.47 +    /// </summary>
    7.48 +    [Serializable]
    7.49 +    public class Plot : Control, IPlotControl
    7.50 +    {
    7.51 +        /// <summary>
    7.52 +        /// The category for the properties of this control.
    7.53 +        /// </summary>
    7.54 +        private const string OxyPlotCategory = "OxyPlot";
    7.55 +
    7.56 +        /// <summary>
    7.57 +        /// The invalidate lock.
    7.58 +        /// </summary>
    7.59 +        private readonly object invalidateLock = new object();
    7.60 +
    7.61 +        /// <summary>
    7.62 +        /// The model lock.
    7.63 +        /// </summary>
    7.64 +        private readonly object modelLock = new object();
    7.65 +
    7.66 +        /// <summary>
    7.67 +        /// The rendering lock.
    7.68 +        /// </summary>
    7.69 +        private readonly object renderingLock = new object();
    7.70 +
    7.71 +        /// <summary>
    7.72 +        /// The current model (holding a reference to this plot control).
    7.73 +        /// </summary>
    7.74 +        [NonSerialized]
    7.75 +        private PlotModel currentModel;
    7.76 +
    7.77 +        /// <summary>
    7.78 +        /// The is model invalidated.
    7.79 +        /// </summary>
    7.80 +        private bool isModelInvalidated;
    7.81 +
    7.82 +        /// <summary>
    7.83 +        /// The model.
    7.84 +        /// </summary>
    7.85 +        private PlotModel model;
    7.86 +
    7.87 +        /// <summary>
    7.88 +        /// The mouse manipulator.
    7.89 +        /// </summary>
    7.90 +        [NonSerialized]
    7.91 +        private ManipulatorBase mouseManipulator;
    7.92 +
    7.93 +        /// <summary>
    7.94 +        /// The update data flag.
    7.95 +        /// </summary>
    7.96 +        private bool updateDataFlag = true;
    7.97 +
    7.98 +        /// <summary>
    7.99 +        /// The zoom rectangle.
   7.100 +        /// </summary>
   7.101 +        private Rectangle zoomRectangle;
   7.102 +
   7.103 +        /// <summary>
   7.104 +        /// The render context.
   7.105 +        /// </summary>
   7.106 +        private GraphicsRenderContext renderContext;
   7.107 +
   7.108 +        /// <summary>
   7.109 +        /// Initializes a new instance of the <see cref="Plot"/> class.
   7.110 +        /// </summary>
   7.111 +        public Plot()
   7.112 +        {
   7.113 +            this.renderContext = new GraphicsRenderContext();
   7.114 +
   7.115 +            // ReSharper disable DoNotCallOverridableMethodsInConstructor
   7.116 +            this.DoubleBuffered = true;
   7.117 +            // ReSharper restore DoNotCallOverridableMethodsInConstructor
   7.118 +            this.KeyboardPanHorizontalStep = 0.1;
   7.119 +            this.KeyboardPanVerticalStep = 0.1;
   7.120 +            this.PanCursor = Cursors.Hand;
   7.121 +            this.ZoomRectangleCursor = Cursors.SizeNWSE;
   7.122 +            this.ZoomHorizontalCursor = Cursors.SizeWE;
   7.123 +            this.ZoomVerticalCursor = Cursors.SizeNS;
   7.124 +        }
   7.125 +
   7.126 +        /// <summary>
   7.127 +        /// Gets the actual model.
   7.128 +        /// </summary>
   7.129 +        /// <value> The actual model. </value>
   7.130 +        public PlotModel ActualModel
   7.131 +        {
   7.132 +            get
   7.133 +            {
   7.134 +                return this.Model;
   7.135 +            }
   7.136 +        }
   7.137 +
   7.138 +        /// <summary>
   7.139 +        /// Gets or sets the keyboard pan horizontal step.
   7.140 +        /// </summary>
   7.141 +        /// <value> The keyboard pan horizontal step. </value>
   7.142 +        [Category(OxyPlotCategory)]
   7.143 +        public double KeyboardPanHorizontalStep { get; set; }
   7.144 +
   7.145 +        /// <summary>
   7.146 +        /// Gets or sets the keyboard pan vertical step.
   7.147 +        /// </summary>
   7.148 +        /// <value> The keyboard pan vertical step. </value>
   7.149 +        [Category(OxyPlotCategory)]
   7.150 +        public double KeyboardPanVerticalStep { get; set; }
   7.151 +
   7.152 +        /// <summary>
   7.153 +        /// Gets or sets the model.
   7.154 +        /// </summary>
   7.155 +        [Browsable(false)]
   7.156 +        [DefaultValue(null)]
   7.157 +        [Category(OxyPlotCategory)]
   7.158 +        public PlotModel Model
   7.159 +        {
   7.160 +            get
   7.161 +            {
   7.162 +                return this.model;
   7.163 +            }
   7.164 +
   7.165 +            set
   7.166 +            {
   7.167 +                if (this.model != value)
   7.168 +                {
   7.169 +                    this.model = value;
   7.170 +                    this.OnModelChanged();
   7.171 +                }
   7.172 +            }
   7.173 +        }
   7.174 +
   7.175 +        /// <summary>
   7.176 +        /// Gets or sets the pan cursor.
   7.177 +        /// </summary>
   7.178 +        [Category(OxyPlotCategory)]
   7.179 +        public Cursor PanCursor { get; set; }
   7.180 +
   7.181 +        /// <summary>
   7.182 +        /// Gets or sets the horizontal zoom cursor.
   7.183 +        /// </summary>
   7.184 +        [Category(OxyPlotCategory)]
   7.185 +        public Cursor ZoomHorizontalCursor { get; set; }
   7.186 +
   7.187 +        /// <summary>
   7.188 +        /// Gets or sets the rectangle zoom cursor.
   7.189 +        /// </summary>
   7.190 +        [Category(OxyPlotCategory)]
   7.191 +        public Cursor ZoomRectangleCursor { get; set; }
   7.192 +
   7.193 +        /// <summary>
   7.194 +        /// Gets or sets vertical zoom cursor.
   7.195 +        /// </summary>
   7.196 +        [Category(OxyPlotCategory)]
   7.197 +        public Cursor ZoomVerticalCursor { get; set; }
   7.198 +
   7.199 +        /// <summary>
   7.200 +        /// Get the axes from a point.
   7.201 +        /// </summary>
   7.202 +        /// <param name="pt">
   7.203 +        /// The point.
   7.204 +        /// </param>
   7.205 +        /// <param name="xaxis">
   7.206 +        /// The x axis.
   7.207 +        /// </param>
   7.208 +        /// <param name="yaxis">
   7.209 +        /// The y axis.
   7.210 +        /// </param>
   7.211 +        public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
   7.212 +        {
   7.213 +            if (this.Model == null)
   7.214 +            {
   7.215 +                xaxis = null;
   7.216 +                yaxis = null;
   7.217 +                return;
   7.218 +            }
   7.219 +
   7.220 +            this.Model.GetAxesFromPoint(pt, out xaxis, out yaxis);
   7.221 +        }
   7.222 +
   7.223 +        /// <summary>
   7.224 +        /// Get the series from a point.
   7.225 +        /// </summary>
   7.226 +        /// <param name="pt">
   7.227 +        /// The point (screen coordinates).
   7.228 +        /// </param>
   7.229 +        /// <param name="limit">
   7.230 +        /// The limit.
   7.231 +        /// </param>
   7.232 +        /// <returns>
   7.233 +        /// The series.
   7.234 +        /// </returns>
   7.235 +        public Series GetSeriesFromPoint(ScreenPoint pt, double limit)
   7.236 +        {
   7.237 +            if (this.Model == null)
   7.238 +            {
   7.239 +                return null;
   7.240 +            }
   7.241 +
   7.242 +            return this.Model.GetSeriesFromPoint(pt, limit);
   7.243 +        }
   7.244 +
   7.245 +        /// <summary>
   7.246 +        /// The hide tracker.
   7.247 +        /// </summary>
   7.248 +        public void HideTracker()
   7.249 +        {
   7.250 +        }
   7.251 +
   7.252 +        /// <summary>
   7.253 +        /// The hide zoom rectangle.
   7.254 +        /// </summary>
   7.255 +        public void HideZoomRectangle()
   7.256 +        {
   7.257 +            this.zoomRectangle = Rectangle.Empty;
   7.258 +            this.Invalidate();
   7.259 +        }
   7.260 +
   7.261 +        /// <summary>
   7.262 +        /// The invalidate plot.
   7.263 +        /// </summary>
   7.264 +        /// <param name="updateData">
   7.265 +        /// The update data.
   7.266 +        /// </param>
   7.267 +        public void InvalidatePlot(bool updateData)
   7.268 +        {
   7.269 +            lock (this.invalidateLock)
   7.270 +            {
   7.271 +                this.isModelInvalidated = true;
   7.272 +                this.updateDataFlag = this.updateDataFlag || updateData;
   7.273 +            }
   7.274 +
   7.275 +            this.Invalidate();
   7.276 +        }
   7.277 +
   7.278 +        /// <summary>
   7.279 +        /// Called when the Model property has been changed.
   7.280 +        /// </summary>
   7.281 +        public void OnModelChanged()
   7.282 +        {
   7.283 +            lock (this.modelLock)
   7.284 +            {
   7.285 +                if (this.currentModel != null)
   7.286 +                {
   7.287 +                    this.currentModel.AttachPlotControl(null);
   7.288 +                }
   7.289 +
   7.290 +                if (this.Model != null)
   7.291 +                {
   7.292 +                    if (this.Model.PlotControl != null)
   7.293 +                    {
   7.294 +                        throw new InvalidOperationException(
   7.295 +                            "This PlotModel is already in use by some other plot control.");
   7.296 +                    }
   7.297 +
   7.298 +                    this.Model.AttachPlotControl(this);
   7.299 +                    this.currentModel = this.Model;
   7.300 +                }
   7.301 +            }
   7.302 +
   7.303 +            this.InvalidatePlot(true);
   7.304 +        }
   7.305 +
   7.306 +        /// <summary>
   7.307 +        /// The pan.
   7.308 +        /// </summary>
   7.309 +        /// <param name="axis">
   7.310 +        /// The axis.
   7.311 +        /// </param>
   7.312 +        /// <param name="x0">
   7.313 +        /// The x 0.
   7.314 +        /// </param>
   7.315 +        /// <param name="x1">
   7.316 +        /// The x 1.
   7.317 +        /// </param>
   7.318 +        public void Pan(Axis axis, ScreenPoint x0, ScreenPoint x1)
   7.319 +        {
   7.320 +            axis.Pan(x0, x1);
   7.321 +            this.InvalidatePlot(false);
   7.322 +        }
   7.323 +
   7.324 +        /// <summary>
   7.325 +        /// Pans all axes.
   7.326 +        /// </summary>
   7.327 +        /// <param name="deltax">
   7.328 +        /// The horizontal delta.
   7.329 +        /// </param>
   7.330 +        /// <param name="deltay">
   7.331 +        /// The vertical delta.
   7.332 +        /// </param>
   7.333 +        public void PanAll(double deltax, double deltay)
   7.334 +        {
   7.335 +            foreach (var a in this.ActualModel.Axes)
   7.336 +            {
   7.337 +                a.Pan(a.IsHorizontal() ? deltax : deltay);
   7.338 +            }
   7.339 +
   7.340 +            this.InvalidatePlot(false);
   7.341 +        }
   7.342 +
   7.343 +        /// <summary>
   7.344 +        /// The refresh plot.
   7.345 +        /// </summary>
   7.346 +        /// <param name="updateData">
   7.347 +        /// The update data.
   7.348 +        /// </param>
   7.349 +        public void RefreshPlot(bool updateData)
   7.350 +        {
   7.351 +            lock (this.invalidateLock)
   7.352 +            {
   7.353 +                this.isModelInvalidated = true;
   7.354 +                this.updateDataFlag = this.updateDataFlag || updateData;
   7.355 +            }
   7.356 +
   7.357 +            this.Refresh();
   7.358 +        }
   7.359 +
   7.360 +        /// <summary>
   7.361 +        /// The reset.
   7.362 +        /// </summary>
   7.363 +        /// <param name="axis">
   7.364 +        /// The axis.
   7.365 +        /// </param>
   7.366 +        public void Reset(Axis axis)
   7.367 +        {
   7.368 +            axis.Reset();
   7.369 +            this.InvalidatePlot(false);
   7.370 +        }
   7.371 +
   7.372 +        /// <summary>
   7.373 +        /// Sets the cursor type.
   7.374 +        /// </summary>
   7.375 +        /// <param name="cursorType">
   7.376 +        /// The cursor type.
   7.377 +        /// </param>
   7.378 +        public void SetCursorType(CursorType cursorType)
   7.379 +        {
   7.380 +            switch (cursorType)
   7.381 +            {
   7.382 +                case CursorType.Pan:
   7.383 +                    this.Cursor = this.PanCursor;
   7.384 +                    break;
   7.385 +                case CursorType.ZoomRectangle:
   7.386 +                    this.Cursor = this.ZoomRectangleCursor;
   7.387 +                    break;
   7.388 +                case CursorType.ZoomHorizontal:
   7.389 +                    this.Cursor = this.ZoomHorizontalCursor;
   7.390 +                    break;
   7.391 +                case CursorType.ZoomVertical:
   7.392 +                    this.Cursor = this.ZoomVerticalCursor;
   7.393 +                    break;
   7.394 +                default:
   7.395 +                    this.Cursor = Cursors.Arrow;
   7.396 +                    break;
   7.397 +            }
   7.398 +        }
   7.399 +
   7.400 +        /// <summary>
   7.401 +        /// The show tracker.
   7.402 +        /// </summary>
   7.403 +        /// <param name="data">
   7.404 +        /// The data.
   7.405 +        /// </param>
   7.406 +        public void ShowTracker(TrackerHitResult data)
   7.407 +        {
   7.408 +            // not implemented for WindowsForms
   7.409 +        }
   7.410 +
   7.411 +        /// <summary>
   7.412 +        /// The show zoom rectangle.
   7.413 +        /// </summary>
   7.414 +        /// <param name="r">
   7.415 +        /// The r.
   7.416 +        /// </param>
   7.417 +        public void ShowZoomRectangle(OxyRect r)
   7.418 +        {
   7.419 +            this.zoomRectangle = new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height);
   7.420 +            this.Invalidate();
   7.421 +        }
   7.422 +
   7.423 +        /// <summary>
   7.424 +        /// The zoom.
   7.425 +        /// </summary>
   7.426 +        /// <param name="axis">
   7.427 +        /// The axis.
   7.428 +        /// </param>
   7.429 +        /// <param name="p1">
   7.430 +        /// The p 1.
   7.431 +        /// </param>
   7.432 +        /// <param name="p2">
   7.433 +        /// The p 2.
   7.434 +        /// </param>
   7.435 +        public void Zoom(Axis axis, double p1, double p2)
   7.436 +        {
   7.437 +            axis.Zoom(p1, p2);
   7.438 +            this.InvalidatePlot(false);
   7.439 +        }
   7.440 +
   7.441 +        /// <summary>
   7.442 +        /// The zoom all.
   7.443 +        /// </summary>
   7.444 +        public void ZoomAll()
   7.445 +        {
   7.446 +            foreach (var a in this.Model.Axes)
   7.447 +            {
   7.448 +                a.Reset();
   7.449 +            }
   7.450 +
   7.451 +            this.InvalidatePlot(false);
   7.452 +        }
   7.453 +
   7.454 +        /// <summary>
   7.455 +        /// Zooms all axes.
   7.456 +        /// </summary>
   7.457 +        /// <param name="delta">
   7.458 +        /// The delta.
   7.459 +        /// </param>
   7.460 +        public void ZoomAllAxes(double delta)
   7.461 +        {
   7.462 +            foreach (var a in this.ActualModel.Axes)
   7.463 +            {
   7.464 +                this.ZoomAt(a, delta);
   7.465 +            }
   7.466 +
   7.467 +            this.RefreshPlot(false);
   7.468 +        }
   7.469 +
   7.470 +        /// <summary>
   7.471 +        /// The zoom at.
   7.472 +        /// </summary>
   7.473 +        /// <param name="axis">
   7.474 +        /// The axis.
   7.475 +        /// </param>
   7.476 +        /// <param name="factor">
   7.477 +        /// The factor.
   7.478 +        /// </param>
   7.479 +        /// <param name="x">
   7.480 +        /// The x.
   7.481 +        /// </param>
   7.482 +        public void ZoomAt(Axis axis, double factor, double x = double.NaN)
   7.483 +        {
   7.484 +            if (double.IsNaN(x))
   7.485 +            {
   7.486 +                double sx = (axis.Transform(axis.ActualMaximum) + axis.Transform(axis.ActualMinimum)) * 0.5;
   7.487 +                x = axis.InverseTransform(sx);
   7.488 +            }
   7.489 +
   7.490 +            axis.ZoomAt(factor, x);
   7.491 +            this.InvalidatePlot(false);
   7.492 +        }
   7.493 +
   7.494 +        /// <summary>
   7.495 +        /// The on mouse down.
   7.496 +        /// </summary>
   7.497 +        /// <param name="e">
   7.498 +        /// The e.
   7.499 +        /// </param>
   7.500 +        protected override void OnMouseDown(MouseEventArgs e)
   7.501 +        {
   7.502 +            base.OnMouseDown(e);
   7.503 +
   7.504 +            if (this.mouseManipulator != null)
   7.505 +            {
   7.506 +                return;
   7.507 +            }
   7.508 +
   7.509 +            this.Focus();
   7.510 +            this.Capture = true;
   7.511 +
   7.512 +            if (this.ActualModel != null)
   7.513 +            {
   7.514 +                var args = this.CreateMouseEventArgs(e);
   7.515 +                this.ActualModel.HandleMouseDown(this, args);
   7.516 +                if (args.Handled)
   7.517 +                {
   7.518 +                    return;
   7.519 +                }
   7.520 +            }
   7.521 +
   7.522 +            this.mouseManipulator = this.GetManipulator(e);
   7.523 +
   7.524 +            if (this.mouseManipulator != null)
   7.525 +            {
   7.526 +                this.mouseManipulator.Started(this.CreateManipulationEventArgs(e));
   7.527 +            }
   7.528 +        }
   7.529 +
   7.530 +        /// <summary>
   7.531 +        /// The on mouse move.
   7.532 +        /// </summary>
   7.533 +        /// <param name="e">
   7.534 +        /// The e.
   7.535 +        /// </param>
   7.536 +        protected override void OnMouseMove(MouseEventArgs e)
   7.537 +        {
   7.538 +            base.OnMouseMove(e);
   7.539 +
   7.540 +            if (this.ActualModel != null)
   7.541 +            {
   7.542 +                var args = this.CreateMouseEventArgs(e);
   7.543 +                this.ActualModel.HandleMouseMove(this, args);
   7.544 +                if (args.Handled)
   7.545 +                {
   7.546 +                    return;
   7.547 +                }
   7.548 +            }
   7.549 +
   7.550 +            if (this.mouseManipulator != null)
   7.551 +            {
   7.552 +                this.mouseManipulator.Delta(this.CreateManipulationEventArgs(e));
   7.553 +            }
   7.554 +        }
   7.555 +
   7.556 +        /// <summary>
   7.557 +        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event.
   7.558 +        /// </summary>
   7.559 +        /// <param name="e">
   7.560 +        /// A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.
   7.561 +        /// </param>
   7.562 +        protected override void OnMouseUp(MouseEventArgs e)
   7.563 +        {
   7.564 +            base.OnMouseUp(e);
   7.565 +            this.Capture = false;
   7.566 +
   7.567 +            if (this.ActualModel != null)
   7.568 +            {
   7.569 +                var args = this.CreateMouseEventArgs(e);
   7.570 +                this.ActualModel.HandleMouseUp(this, args);
   7.571 +                if (args.Handled)
   7.572 +                {
   7.573 +                    return;
   7.574 +                }
   7.575 +            }
   7.576 +
   7.577 +            if (this.mouseManipulator != null)
   7.578 +            {
   7.579 +                this.mouseManipulator.Completed(this.CreateManipulationEventArgs(e));
   7.580 +            }
   7.581 +
   7.582 +            this.mouseManipulator = null;
   7.583 +        }
   7.584 +
   7.585 +        /// <summary>
   7.586 +        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseWheel"/> event.
   7.587 +        /// </summary>
   7.588 +        /// <param name="e">
   7.589 +        /// A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.
   7.590 +        /// </param>
   7.591 +        protected override void OnMouseWheel(MouseEventArgs e)
   7.592 +        {
   7.593 +            base.OnMouseWheel(e);
   7.594 +            bool isControlDown = ModifierKeys == Keys.Control;
   7.595 +            var m = new ZoomStepManipulator(this, e.Delta * 0.001, isControlDown);
   7.596 +            m.Started(new ManipulationEventArgs(e.Location.ToScreenPoint()));
   7.597 +        }
   7.598 +
   7.599 +        /// <summary>
   7.600 +        /// Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
   7.601 +        /// </summary>
   7.602 +        /// <param name="e">
   7.603 +        /// A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.
   7.604 +        /// </param>
   7.605 +        protected override void OnPaint(PaintEventArgs e)
   7.606 +        {
   7.607 +            base.OnPaint(e);
   7.608 +            try
   7.609 +            {
   7.610 +                lock (this.invalidateLock)
   7.611 +                {
   7.612 +                    if (this.isModelInvalidated)
   7.613 +                    {
   7.614 +                        if (this.model != null)
   7.615 +                        {
   7.616 +                            this.model.Update(this.updateDataFlag);
   7.617 +                            this.updateDataFlag = false;
   7.618 +                        }
   7.619 +
   7.620 +                        this.isModelInvalidated = false;
   7.621 +                    }
   7.622 +                }
   7.623 +
   7.624 +                lock (this.renderingLock)
   7.625 +                {
   7.626 +                    this.renderContext.SetGraphicsTarget(e.Graphics);
   7.627 +                    if (this.model != null)
   7.628 +                    {
   7.629 +                        this.model.Render(this.renderContext, this.Width, this.Height);
   7.630 +                    }
   7.631 +
   7.632 +                    if (this.zoomRectangle != Rectangle.Empty)
   7.633 +                    {
   7.634 +                        using (var zoomBrush = new SolidBrush(Color.FromArgb(0x40, 0xFF, 0xFF, 0x00)))
   7.635 +                        using (var zoomPen = new Pen(Color.Black))
   7.636 +                        {
   7.637 +                            zoomPen.DashPattern = new float[] { 3, 1 };
   7.638 +                            e.Graphics.FillRectangle(zoomBrush, this.zoomRectangle);
   7.639 +                            e.Graphics.DrawRectangle(zoomPen, this.zoomRectangle);
   7.640 +                        }
   7.641 +                    }
   7.642 +                }
   7.643 +            }
   7.644 +            catch (Exception paintException)
   7.645 +            {
   7.646 +                var trace = new StackTrace(paintException);
   7.647 +                Debug.WriteLine(paintException);
   7.648 +                Debug.WriteLine(trace);
   7.649 +                using (var font = new Font("Arial", 10))
   7.650 +                {
   7.651 +                    e.Graphics.DrawString(
   7.652 +                        "OxyPlot paint exception: " + paintException.Message, font, Brushes.Red, 10, 10);
   7.653 +                }
   7.654 +            }
   7.655 +        }
   7.656 +
   7.657 +        /// <summary>
   7.658 +        /// Raises the <see cref="E:System.Windows.Forms.Control.PreviewKeyDown"/> event.
   7.659 +        /// </summary>
   7.660 +        /// <param name="e">
   7.661 +        /// A <see cref="T:System.Windows.Forms.PreviewKeyDownEventArgs"/> that contains the event data.
   7.662 +        /// </param>
   7.663 +        protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
   7.664 +        {
   7.665 +            base.OnPreviewKeyDown(e);
   7.666 +            if (e.KeyCode == Keys.A)
   7.667 +            {
   7.668 +                this.ZoomAll();
   7.669 +            }
   7.670 +
   7.671 +            bool control = (e.Modifiers & Keys.Control) == Keys.Control;
   7.672 +            bool alt = (e.Modifiers & Keys.Alt) == Keys.Alt;
   7.673 +
   7.674 +            double deltax = 0;
   7.675 +            double deltay = 0;
   7.676 +            double zoom = 0;
   7.677 +            switch (e.KeyCode)
   7.678 +            {
   7.679 +                case Keys.Up:
   7.680 +                    deltay = -1;
   7.681 +                    break;
   7.682 +                case Keys.Down:
   7.683 +                    deltay = 1;
   7.684 +                    break;
   7.685 +                case Keys.Left:
   7.686 +                    deltax = -1;
   7.687 +                    break;
   7.688 +                case Keys.Right:
   7.689 +                    deltax = 1;
   7.690 +                    break;
   7.691 +                case Keys.Add:
   7.692 +                case Keys.Oemplus:
   7.693 +                case Keys.PageUp:
   7.694 +                    zoom = 1;
   7.695 +                    break;
   7.696 +                case Keys.Subtract:
   7.697 +                case Keys.OemMinus:
   7.698 +                case Keys.PageDown:
   7.699 +                    zoom = -1;
   7.700 +                    break;
   7.701 +            }
   7.702 +
   7.703 +            if ((deltax * deltax) + (deltay * deltay) > 0)
   7.704 +            {
   7.705 +                deltax = deltax * this.ActualModel.PlotArea.Width * this.KeyboardPanHorizontalStep;
   7.706 +                deltay = deltay * this.ActualModel.PlotArea.Height * this.KeyboardPanVerticalStep;
   7.707 +
   7.708 +                // small steps if the user is pressing control
   7.709 +                if (control)
   7.710 +                {
   7.711 +                    deltax *= 0.2;
   7.712 +                    deltay *= 0.2;
   7.713 +                }
   7.714 +
   7.715 +                this.PanAll(deltax, deltay);
   7.716 +
   7.717 +                // e.Handled = true;
   7.718 +            }
   7.719 +
   7.720 +            if (Math.Abs(zoom) > 1e-8)
   7.721 +            {
   7.722 +                if (control)
   7.723 +                {
   7.724 +                    zoom *= 0.2;
   7.725 +                }
   7.726 +
   7.727 +                this.ZoomAllAxes(1 + (zoom * 0.12));
   7.728 +
   7.729 +                // e.Handled = true;
   7.730 +            }
   7.731 +
   7.732 +            if (control && alt && this.ActualModel != null)
   7.733 +            {
   7.734 +                switch (e.KeyCode)
   7.735 +                {
   7.736 +                    case Keys.R:
   7.737 +                        this.SetClipboardText(this.ActualModel.CreateTextReport());
   7.738 +                        break;
   7.739 +                    case Keys.C:
   7.740 +                        this.SetClipboardText(this.ActualModel.ToCode());
   7.741 +                        break;
   7.742 +                    case Keys.X:
   7.743 +
   7.744 +                        // this.SetClipboardText(this.ActualModel.ToXml());
   7.745 +                        break;
   7.746 +                }
   7.747 +            }
   7.748 +        }
   7.749 +
   7.750 +        /// <summary>
   7.751 +        /// Raises the <see cref="E:System.Windows.Forms.Control.Resize"/> event.
   7.752 +        /// </summary>
   7.753 +        /// <param name="e">
   7.754 +        /// An <see cref="T:System.EventArgs"/> that contains the event data.
   7.755 +        /// </param>
   7.756 +        protected override void OnResize(EventArgs e)
   7.757 +        {
   7.758 +            base.OnResize(e);
   7.759 +            this.InvalidatePlot(false);
   7.760 +        }
   7.761 +
   7.762 +        /// <summary>
   7.763 +        /// Converts the changed button.
   7.764 +        /// </summary>
   7.765 +        /// <param name="e">
   7.766 +        /// The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.
   7.767 +        /// </param>
   7.768 +        /// <returns>
   7.769 +        /// The mouse button.
   7.770 +        /// </returns>
   7.771 +        private static OxyMouseButton ConvertChangedButton(MouseEventArgs e)
   7.772 +        {
   7.773 +            switch (e.Button)
   7.774 +            {
   7.775 +                case MouseButtons.Left:
   7.776 +                    return OxyMouseButton.Left;
   7.777 +                case MouseButtons.Middle:
   7.778 +                    return OxyMouseButton.Middle;
   7.779 +                case MouseButtons.Right:
   7.780 +                    return OxyMouseButton.Right;
   7.781 +                case MouseButtons.XButton1:
   7.782 +                    return OxyMouseButton.XButton1;
   7.783 +                case MouseButtons.XButton2:
   7.784 +                    return OxyMouseButton.XButton2;
   7.785 +            }
   7.786 +
   7.787 +            return OxyMouseButton.Left;
   7.788 +        }
   7.789 +
   7.790 +        /// <summary>
   7.791 +        /// Creates the mouse event arguments.
   7.792 +        /// </summary>
   7.793 +        /// <param name="e">
   7.794 +        /// The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.
   7.795 +        /// </param>
   7.796 +        /// <returns>
   7.797 +        /// Mouse event arguments.
   7.798 +        /// </returns>
   7.799 +        private OxyMouseEventArgs CreateMouseEventArgs(MouseEventArgs e)
   7.800 +        {
   7.801 +            return new OxyMouseEventArgs
   7.802 +            {
   7.803 +                ChangedButton = ConvertChangedButton(e),
   7.804 +                Position = new ScreenPoint(e.Location.X, e.Location.Y),
   7.805 +                IsShiftDown = (ModifierKeys & Keys.Shift) == Keys.Shift,
   7.806 +                IsControlDown = (ModifierKeys & Keys.Control) == Keys.Control,
   7.807 +                IsAltDown = (ModifierKeys & Keys.Alt) == Keys.Alt,
   7.808 +            };
   7.809 +        }
   7.810 +
   7.811 +        /// <summary>
   7.812 +        /// Creates the manipulation event args.
   7.813 +        /// </summary>
   7.814 +        /// <param name="e">
   7.815 +        /// The MouseEventArgs instance containing the event data.
   7.816 +        /// </param>
   7.817 +        /// <returns>
   7.818 +        /// A manipulation event args object.
   7.819 +        /// </returns>
   7.820 +        private ManipulationEventArgs CreateManipulationEventArgs(MouseEventArgs e)
   7.821 +        {
   7.822 +            return new ManipulationEventArgs(e.Location.ToScreenPoint());
   7.823 +        }
   7.824 +
   7.825 +        /// <summary>
   7.826 +        /// Gets the manipulator for the current mouse button and modifier keys.
   7.827 +        /// </summary>
   7.828 +        /// <param name="e">
   7.829 +        /// The event args.
   7.830 +        /// </param>
   7.831 +        /// <returns>
   7.832 +        /// A manipulator or null if no gesture was recognized.
   7.833 +        /// </returns>
   7.834 +        private ManipulatorBase GetManipulator(MouseEventArgs e)
   7.835 +        {
   7.836 +            bool control = (ModifierKeys & Keys.Control) == Keys.Control;
   7.837 +            bool shift = (ModifierKeys & Keys.Shift) == Keys.Shift;
   7.838 +            bool alt = (ModifierKeys & Keys.Alt) == Keys.Alt;
   7.839 +
   7.840 +            bool lmb = e.Button == MouseButtons.Left;
   7.841 +            bool rmb = e.Button == MouseButtons.Right;
   7.842 +            bool mmb = e.Button == MouseButtons.Middle;
   7.843 +            bool xb1 = e.Button == MouseButtons.XButton1;
   7.844 +            bool xb2 = e.Button == MouseButtons.XButton2;
   7.845 +
   7.846 +            // MMB / control RMB / control+alt LMB
   7.847 +            if (mmb || (control && rmb) || (control && alt && lmb))
   7.848 +            {
   7.849 +                if (e.Clicks == 2)
   7.850 +                {
   7.851 +                    return new ResetManipulator(this);
   7.852 +                }
   7.853 +
   7.854 +                return new ZoomRectangleManipulator(this);
   7.855 +            }
   7.856 +
   7.857 +            // Right mouse button / alt+left mouse button
   7.858 +            if (rmb || (lmb && alt))
   7.859 +            {
   7.860 +                return new PanManipulator(this);
   7.861 +            }
   7.862 +
   7.863 +            // Left mouse button
   7.864 +            if (lmb)
   7.865 +            {
   7.866 +                return new TrackerManipulator(this) { Snap = !control, PointsOnly = shift };
   7.867 +            }
   7.868 +
   7.869 +            // XButtons are zoom-stepping
   7.870 +            if (xb1 || xb2)
   7.871 +            {
   7.872 +                double d = xb1 ? 0.05 : -0.05;
   7.873 +                return new ZoomStepManipulator(this, d, control);
   7.874 +            }
   7.875 +
   7.876 +            return null;
   7.877 +        }
   7.878 +
   7.879 +        /// <summary>
   7.880 +        /// The set clipboard text.
   7.881 +        /// </summary>
   7.882 +        /// <param name="text">
   7.883 +        /// The text.
   7.884 +        /// </param>
   7.885 +        private void SetClipboardText(string text)
   7.886 +        {
   7.887 +            try
   7.888 +            {
   7.889 +                // todo: can't get the following solution to work
   7.890 +                // http://stackoverflow.com/questions/5707990/requested-clipboard-operation-did-not-succeed
   7.891 +                Clipboard.SetText(text);
   7.892 +            }
   7.893 +            catch (ExternalException ee)
   7.894 +            {
   7.895 +                // Requested Clipboard operation did not succeed.
   7.896 +                MessageBox.Show(this, ee.Message, "OxyPlot");
   7.897 +            }
   7.898 +        }
   7.899 +    }
   7.900 +}
   7.901 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/PlotControl.cs	Sat Jun 08 16:53:22 2013 +0000
     8.3 @@ -0,0 +1,237 @@
     8.4 +// --------------------------------------------------------------------------------------------------------------------
     8.5 +// <copyright file="PlotControl.cs" company="OxyPlot">
     8.6 +//   The MIT License (MIT)
     8.7 +//
     8.8 +//   Copyright (c) 2012 Oystein Bjorke
     8.9 +//
    8.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    8.11 +//   copy of this software and associated documentation files (the
    8.12 +//   "Software"), to deal in the Software without restriction, including
    8.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    8.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    8.15 +//   permit persons to whom the Software is furnished to do so, subject to
    8.16 +//   the following conditions:
    8.17 +//
    8.18 +//   The above copyright notice and this permission notice shall be included
    8.19 +//   in all copies or substantial portions of the Software.
    8.20 +//
    8.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    8.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    8.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    8.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    8.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    8.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    8.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    8.28 +// </copyright>
    8.29 +// --------------------------------------------------------------------------------------------------------------------
    8.30 +using System;
    8.31 +using System.Collections.Generic;
    8.32 +using System.ComponentModel;
    8.33 +using System.Drawing;
    8.34 +using System.Windows.Forms;
    8.35 +using OxyPlot;
    8.36 +
    8.37 +namespace Oxyplot.WindowsForms
    8.38 +{
    8.39 +    public class PlotControl : Control, IPlotControl
    8.40 +    {
    8.41 +        public List<MouseAction> MouseActions { get; private set; }
    8.42 +
    8.43 +        private readonly PanAction panAction;
    8.44 +        private readonly SliderAction sliderAction;
    8.45 +        private readonly ZoomAction zoomAction;
    8.46 +        private Rectangle zoomRectangle;
    8.47 +
    8.48 +        public PlotControl()
    8.49 +        {
    8.50 +            //    InitializeComponent();
    8.51 +            DoubleBuffered = true;
    8.52 +            Model = new PlotModel();
    8.53 +
    8.54 +            panAction = new PanAction(this);
    8.55 +            zoomAction = new ZoomAction(this);
    8.56 +            sliderAction = new SliderAction(this);
    8.57 +
    8.58 +            MouseActions = new List<MouseAction>();
    8.59 +            MouseActions.Add(panAction);
    8.60 +            MouseActions.Add(zoomAction);
    8.61 +            MouseActions.Add(sliderAction);
    8.62 +        }
    8.63 +
    8.64 +        private PlotModel model;
    8.65 +
    8.66 +        [Browsable(false), DefaultValue(null)]
    8.67 +        public PlotModel Model
    8.68 +        {
    8.69 +            get { return model; }
    8.70 +            set
    8.71 +            {
    8.72 +                model = value;
    8.73 +                Refresh();
    8.74 +            }
    8.75 +        }
    8.76 +
    8.77 +        public override void Refresh()
    8.78 +        {
    8.79 +            if (model != null)
    8.80 +                model.UpdateData();
    8.81 +            base.Refresh();
    8.82 +        }
    8.83 +
    8.84 +        protected override void OnResize(EventArgs e)
    8.85 +        {
    8.86 +            base.OnResize(e);
    8.87 +            Invalidate();
    8.88 +        }
    8.89 +
    8.90 +        protected override void OnPaint(PaintEventArgs e)
    8.91 +        {
    8.92 +            base.OnPaint(e);
    8.93 +
    8.94 +            var rc = new GraphicsRenderContext(this, e.Graphics, e.ClipRectangle);
    8.95 +            if (model != null)
    8.96 +                model.Render(rc);
    8.97 +            if (zoomRectangle != Rectangle.Empty)
    8.98 +            {
    8.99 +                using (var zoomBrush = new SolidBrush(Color.FromArgb(0x40, 0xFF, 0xFF, 0x00)))
   8.100 +                using (var zoomPen = new Pen(Color.Black))
   8.101 +                {
   8.102 +                    zoomPen.DashPattern = new float[] { 3, 1 };
   8.103 +                    e.Graphics.FillRectangle(zoomBrush, zoomRectangle);
   8.104 +                    e.Graphics.DrawRectangle(zoomPen, zoomRectangle);
   8.105 +                }
   8.106 +            }
   8.107 +        }
   8.108 +
   8.109 +        protected override void OnKeyDown(KeyEventArgs e)
   8.110 +        {
   8.111 +            base.OnKeyDown(e);
   8.112 +            if (e.KeyCode == Keys.A)
   8.113 +            {
   8.114 +                ZoomAll();
   8.115 +            }
   8.116 +        }
   8.117 +
   8.118 +        public void ZoomAll()
   8.119 +        {
   8.120 +            foreach (var a in Model.Axes)
   8.121 +                a.Reset();
   8.122 +            Refresh();
   8.123 +        }
   8.124 +
   8.125 +        protected override void OnMouseDown(MouseEventArgs e)
   8.126 +        {
   8.127 +            base.OnMouseDown(e);
   8.128 +
   8.129 +            Focus();
   8.130 +            Capture = true;
   8.131 +
   8.132 +            bool control = Control.ModifierKeys == Keys.Control;
   8.133 +            bool shift = Control.ModifierKeys == Keys.Shift;
   8.134 +
   8.135 +            var button = OxyMouseButton.Left;
   8.136 +            if (e.Button == MouseButtons.Middle)
   8.137 +                button = OxyMouseButton.Middle;
   8.138 +            if (e.Button == MouseButtons.Right)
   8.139 +                button = OxyMouseButton.Right;
   8.140 +            if (e.Button == MouseButtons.XButton1)
   8.141 +                button = OxyMouseButton.XButton1;
   8.142 +            if (e.Button == MouseButtons.XButton2)
   8.143 +                button = OxyMouseButton.XButton2;
   8.144 +
   8.145 +            var p = new ScreenPoint(e.X, e.Y);
   8.146 +            foreach (var a in MouseActions)
   8.147 +                a.OnMouseDown(p, button, e.Clicks, control, shift);
   8.148 +        }
   8.149 +
   8.150 +        protected override void OnMouseMove(MouseEventArgs e)
   8.151 +        {
   8.152 +            base.OnMouseMove(e);
   8.153 +            bool control = Control.ModifierKeys == Keys.Control;
   8.154 +            bool shift = Control.ModifierKeys == Keys.Shift;
   8.155 +            var p = new ScreenPoint(e.X, e.Y);
   8.156 +            foreach (var a in MouseActions)
   8.157 +                a.OnMouseMove(p, control, shift);
   8.158 +        }
   8.159 +
   8.160 +        protected override void OnMouseUp(MouseEventArgs e)
   8.161 +        {
   8.162 +            base.OnMouseUp(e);
   8.163 +            foreach (var a in MouseActions)
   8.164 +                a.OnMouseUp();
   8.165 +            Capture = false;
   8.166 +        }
   8.167 +
   8.168 +        protected override void OnMouseWheel(MouseEventArgs e)
   8.169 +        {
   8.170 +            base.OnMouseWheel(e);
   8.171 +            bool control = Control.ModifierKeys == Keys.Control;
   8.172 +            bool shift = Control.ModifierKeys == Keys.Shift;
   8.173 +            var p = new ScreenPoint(e.X, e.Y);
   8.174 +            foreach (var a in MouseActions)
   8.175 +                a.OnMouseWheel(p, e.Delta, control, shift);
   8.176 +        }
   8.177 +
   8.178 +        public void GetAxesFromPoint(ScreenPoint pt, out AxisBase xaxis, out AxisBase yaxis)
   8.179 +        {
   8.180 +            Model.GetAxesFromPoint(pt, out xaxis, out yaxis);
   8.181 +        }
   8.182 +
   8.183 +        public DataSeries GetSeriesFromPoint(ScreenPoint pt, double limit)
   8.184 +        {
   8.185 +            return Model.GetSeriesFromPoint(pt, limit);
   8.186 +        }
   8.187 +
   8.188 +        public void Refresh(bool refreshData)
   8.189 +        {
   8.190 +            if (refreshData)
   8.191 +                Model.UpdateData();
   8.192 +            Invalidate();
   8.193 +        }
   8.194 +
   8.195 +        public void Pan(AxisBase axis, double dx)
   8.196 +        {
   8.197 +            axis.Pan(dx);
   8.198 +        }
   8.199 +
   8.200 +        public void Reset(AxisBase axis)
   8.201 +        {
   8.202 +            axis.Reset();
   8.203 +        }
   8.204 +
   8.205 +        public void Zoom(AxisBase axis, double p1, double p2)
   8.206 +        {
   8.207 +            axis.Zoom(p1, p2);
   8.208 +        }
   8.209 +
   8.210 +        public void ZoomAt(AxisBase axis, double factor, double x)
   8.211 +        {
   8.212 +            axis.ZoomAt(factor, x);
   8.213 +        }
   8.214 +
   8.215 +        public OxyRect GetPlotArea()
   8.216 +        {
   8.217 +            return Model.PlotArea;
   8.218 +        }
   8.219 +
   8.220 +        public void ShowSlider(DataSeries s, DataPoint dp)
   8.221 +        {
   8.222 +        }
   8.223 +
   8.224 +        public void HideSlider()
   8.225 +        {
   8.226 +        }
   8.227 +
   8.228 +        public void ShowZoomRectangle(OxyRect r)
   8.229 +        {
   8.230 +            zoomRectangle = new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height);
   8.231 +            Invalidate();
   8.232 +        }
   8.233 +
   8.234 +        public void HideZoomRectangle()
   8.235 +        {
   8.236 +            zoomRectangle = Rectangle.Empty;
   8.237 +            Invalidate();
   8.238 +        }
   8.239 +    }
   8.240 +}
   8.241 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/PngExporter.cs	Sat Jun 08 16:53:22 2013 +0000
     9.3 @@ -0,0 +1,81 @@
     9.4 +// --------------------------------------------------------------------------------------------------------------------
     9.5 +// <copyright file="PngExporter.cs" company="OxyPlot">
     9.6 +//   The MIT License (MIT)
     9.7 +//
     9.8 +//   Copyright (c) 2012 Oystein Bjorke
     9.9 +//
    9.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
    9.11 +//   copy of this software and associated documentation files (the
    9.12 +//   "Software"), to deal in the Software without restriction, including
    9.13 +//   without limitation the rights to use, copy, modify, merge, publish,
    9.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
    9.15 +//   permit persons to whom the Software is furnished to do so, subject to
    9.16 +//   the following conditions:
    9.17 +//
    9.18 +//   The above copyright notice and this permission notice shall be included
    9.19 +//   in all copies or substantial portions of the Software.
    9.20 +//
    9.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    9.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    9.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    9.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    9.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    9.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    9.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    9.28 +// </copyright>
    9.29 +// <summary>
    9.30 +//   The png exporter.
    9.31 +// </summary>
    9.32 +// --------------------------------------------------------------------------------------------------------------------
    9.33 +namespace OxyPlot.WindowsForms
    9.34 +{
    9.35 +    using System.Drawing;
    9.36 +    using System.Drawing.Imaging;
    9.37 +
    9.38 +    using OxyPlot.WindowsForms;
    9.39 +
    9.40 +    /// <summary>
    9.41 +    /// The png exporter.
    9.42 +    /// </summary>
    9.43 +    public static class PngExporter
    9.44 +    {
    9.45 +        /// <summary>
    9.46 +        /// The export.
    9.47 +        /// </summary>
    9.48 +        /// <param name="model">
    9.49 +        /// The model.
    9.50 +        /// </param>
    9.51 +        /// <param name="fileName">
    9.52 +        /// The file name.
    9.53 +        /// </param>
    9.54 +        /// <param name="width">
    9.55 +        /// The width.
    9.56 +        /// </param>
    9.57 +        /// <param name="height">
    9.58 +        /// The height.
    9.59 +        /// </param>
    9.60 +        /// <param name="background">
    9.61 +        /// The background.
    9.62 +        /// </param>
    9.63 +        public static void Export(PlotModel model, string fileName, int width, int height, Brush background = null)
    9.64 +        {
    9.65 +            using (var bm = new Bitmap(width, height))
    9.66 +            {
    9.67 +                using (Graphics g = Graphics.FromImage(bm))
    9.68 +                {
    9.69 +                    if (background != null)
    9.70 +                    {
    9.71 +                        g.FillRectangle(background, 0, 0, width, height);
    9.72 +                    }
    9.73 +
    9.74 +                    var rc = new GraphicsRenderContext { RendersToScreen = false };
    9.75 +                    rc.SetGraphicsTarget(g);
    9.76 +                    model.Update();
    9.77 +                    model.Render(rc, width, height);
    9.78 +                    bm.Save(fileName, ImageFormat.Png);
    9.79 +                }
    9.80 +            }
    9.81 +        }
    9.82 +
    9.83 +    }
    9.84 +}
    9.85 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/Properties/AssemblyInfo.cs	Sat Jun 08 16:53:22 2013 +0000
    10.3 @@ -0,0 +1,10 @@
    10.4 +//-----------------------------------------------------------------------
    10.5 +// <copyright file="AssemblyInfo.cs" company="OxyPlot">
    10.6 +//     http://oxyplot.codeplex.com, license: MIT
    10.7 +// </copyright>
    10.8 +//-----------------------------------------------------------------------
    10.9 +
   10.10 +using System.Reflection;
   10.11 +
   10.12 +[assembly: AssemblyTitle("OxyPlot for Windows Forms")]
   10.13 +[assembly: AssemblyDescription("OxyPlot controls for Windows Forms.")]
   10.14 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/External/OxyPlot/OxyPlot.sln	Sat Jun 08 16:53:22 2013 +0000
    11.3 @@ -0,0 +1,26 @@
    11.4 +
    11.5 +Microsoft Visual Studio Solution File, Format Version 11.00
    11.6 +# Visual Studio 2010
    11.7 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot", "OxyPlot\OxyPlot.csproj", "{BCC43E58-E473-403E-A84D-63FEDC723040}"
    11.8 +EndProject
    11.9 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot.WindowsForms", "OxyPlot.WindowsForms\OxyPlot.WindowsForms.csproj", "{D4554296-094E-4CAC-8EAE-44EB250666C6}"
   11.10 +EndProject
   11.11 +Global
   11.12 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   11.13 +		Debug|Any CPU = Debug|Any CPU
   11.14 +		Release|Any CPU = Release|Any CPU
   11.15 +	EndGlobalSection
   11.16 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   11.17 +		{BCC43E58-E473-403E-A84D-63FEDC723040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
   11.18 +		{BCC43E58-E473-403E-A84D-63FEDC723040}.Debug|Any CPU.Build.0 = Debug|Any CPU
   11.19 +		{BCC43E58-E473-403E-A84D-63FEDC723040}.Release|Any CPU.ActiveCfg = Release|Any CPU
   11.20 +		{BCC43E58-E473-403E-A84D-63FEDC723040}.Release|Any CPU.Build.0 = Release|Any CPU
   11.21 +		{D4554296-094E-4CAC-8EAE-44EB250666C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
   11.22 +		{D4554296-094E-4CAC-8EAE-44EB250666C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
   11.23 +		{D4554296-094E-4CAC-8EAE-44EB250666C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
   11.24 +		{D4554296-094E-4CAC-8EAE-44EB250666C6}.Release|Any CPU.Build.0 = Release|Any CPU
   11.25 +	EndGlobalSection
   11.26 +	GlobalSection(SolutionProperties) = preSolution
   11.27 +		HideSolutionNode = FALSE
   11.28 +	EndGlobalSection
   11.29 +EndGlobal
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/External/OxyPlot/OxyPlot/Annotations/Annotation.cs	Sat Jun 08 16:53:22 2013 +0000
    12.3 @@ -0,0 +1,181 @@
    12.4 +// --------------------------------------------------------------------------------------------------------------------
    12.5 +// <copyright file="Annotation.cs" company="OxyPlot">
    12.6 +//   The MIT License (MIT)
    12.7 +//   
    12.8 +//   Copyright (c) 2012 Oystein Bjorke
    12.9 +//   
   12.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   12.11 +//   copy of this software and associated documentation files (the
   12.12 +//   "Software"), to deal in the Software without restriction, including
   12.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   12.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   12.15 +//   permit persons to whom the Software is furnished to do so, subject to
   12.16 +//   the following conditions:
   12.17 +//   
   12.18 +//   The above copyright notice and this permission notice shall be included
   12.19 +//   in all copies or substantial portions of the Software.
   12.20 +//   
   12.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   12.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   12.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   12.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   12.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   12.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   12.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   12.28 +// </copyright>
   12.29 +// <summary>
   12.30 +//   Annotation base class.
   12.31 +// </summary>
   12.32 +// --------------------------------------------------------------------------------------------------------------------
   12.33 +namespace OxyPlot.Annotations
   12.34 +{
   12.35 +    using System;
   12.36 +    using System.Globalization;
   12.37 +
   12.38 +    using OxyPlot.Axes;
   12.39 +
   12.40 +    /// <summary>
   12.41 +    /// Provides an abstract base class for annotations.
   12.42 +    /// </summary>
   12.43 +    public abstract class Annotation : UIPlotElement
   12.44 +    {
   12.45 +        /// <summary>
   12.46 +        /// Gets the actual culture.
   12.47 +        /// </summary>
   12.48 +        /// <remarks>
   12.49 +        /// The culture is defined in the parent PlotModel.
   12.50 +        /// </remarks>
   12.51 +        public CultureInfo ActualCulture
   12.52 +        {
   12.53 +            get
   12.54 +            {
   12.55 +                return this.PlotModel != null ? this.PlotModel.ActualCulture : CultureInfo.CurrentCulture;
   12.56 +            }
   12.57 +        }
   12.58 +
   12.59 +        /// <summary>
   12.60 +        /// Gets or sets the layer.
   12.61 +        /// </summary>
   12.62 +        public AnnotationLayer Layer { get; set; }
   12.63 +
   12.64 +        /// <summary>
   12.65 +        /// Gets or sets the X axis.
   12.66 +        /// </summary>
   12.67 +        /// <value>The X axis.</value>
   12.68 +        public Axis XAxis { get; set; }
   12.69 +
   12.70 +        /// <summary>
   12.71 +        /// Gets or sets the X axis key.
   12.72 +        /// </summary>
   12.73 +        /// <value>The X axis key.</value>
   12.74 +        public string XAxisKey { get; set; }
   12.75 +
   12.76 +        /// <summary>
   12.77 +        /// Gets or sets the Y axis.
   12.78 +        /// </summary>
   12.79 +        /// <value>The Y axis.</value>
   12.80 +        public Axis YAxis { get; set; }
   12.81 +
   12.82 +        /// <summary>
   12.83 +        /// Gets or sets the Y axis key.
   12.84 +        /// </summary>
   12.85 +        /// <value>The Y axis key.</value>
   12.86 +        public string YAxisKey { get; set; }
   12.87 +
   12.88 +        /// <summary>
   12.89 +        /// Ensures that the annotation axes are set.
   12.90 +        /// </summary>
   12.91 +        public void EnsureAxes()
   12.92 +        {
   12.93 +            this.XAxis = this.PlotModel.GetAxisOrDefault(this.XAxisKey, this.PlotModel.DefaultXAxis);
   12.94 +            this.YAxis = this.PlotModel.GetAxisOrDefault(this.YAxisKey, this.PlotModel.DefaultYAxis);
   12.95 +        }
   12.96 +
   12.97 +        /// <summary>
   12.98 +        /// Renders the annotation on the specified context.
   12.99 +        /// </summary>
  12.100 +        /// <param name="rc">
  12.101 +        /// The render context.
  12.102 +        /// </param>
  12.103 +        /// <param name="model">
  12.104 +        /// The model.
  12.105 +        /// </param>
  12.106 +        public virtual void Render(IRenderContext rc, PlotModel model)
  12.107 +        {
  12.108 +        }
  12.109 +
  12.110 +        /// <summary>
  12.111 +        /// Tests if the plot element is hit by the specified point.
  12.112 +        /// </summary>
  12.113 +        /// <param name="point">The point.</param>
  12.114 +        /// <param name="tolerance">The tolerance.</param>
  12.115 +        /// <returns>
  12.116 +        /// A hit test result.
  12.117 +        /// </returns>
  12.118 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  12.119 +        {
  12.120 +            return null;
  12.121 +        }
  12.122 +
  12.123 +        /// <summary>
  12.124 +        /// Transforms the specified coordinates to a screen point.
  12.125 +        /// </summary>
  12.126 +        /// <param name="x">
  12.127 +        /// The x coordinate.
  12.128 +        /// </param>
  12.129 +        /// <param name="y">
  12.130 +        /// The y coordinate.
  12.131 +        /// </param>
  12.132 +        /// <returns>
  12.133 +        /// A screen point.
  12.134 +        /// </returns>
  12.135 +        public ScreenPoint Transform(double x, double y)
  12.136 +        {
  12.137 +            return this.XAxis.Transform(x, y, this.YAxis);
  12.138 +        }
  12.139 +
  12.140 +        /// <summary>
  12.141 +        /// Transforms the specified data point to a screen point.
  12.142 +        /// </summary>
  12.143 +        /// <param name="p">
  12.144 +        /// The point.
  12.145 +        /// </param>
  12.146 +        /// <returns>
  12.147 +        /// A screen point.
  12.148 +        /// </returns>
  12.149 +        public ScreenPoint Transform(IDataPoint p)
  12.150 +        {
  12.151 +            return this.XAxis.Transform(p.X, p.Y, this.YAxis);
  12.152 +        }
  12.153 +
  12.154 +        /// <summary>
  12.155 +        /// Transforms the specified screen position to a data point.
  12.156 +        /// </summary>
  12.157 +        /// <param name="position">
  12.158 +        /// The position.
  12.159 +        /// </param>
  12.160 +        /// <returns>
  12.161 +        /// A data point
  12.162 +        /// </returns>
  12.163 +        public DataPoint InverseTransform(ScreenPoint position)
  12.164 +        {
  12.165 +            return Axis.InverseTransform(position, this.XAxis, this.YAxis);
  12.166 +        }
  12.167 +
  12.168 +        /// <summary>
  12.169 +        /// Gets the clipping rectangle.
  12.170 +        /// </summary>
  12.171 +        /// <returns>
  12.172 +        /// The clipping rectangle.
  12.173 +        /// </returns>
  12.174 +        protected OxyRect GetClippingRect()
  12.175 +        {
  12.176 +            double minX = Math.Min(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
  12.177 +            double minY = Math.Min(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
  12.178 +            double maxX = Math.Max(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
  12.179 +            double maxY = Math.Max(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
  12.180 +
  12.181 +            return new OxyRect(minX, minY, maxX - minX, maxY - minY);
  12.182 +        }
  12.183 +    }
  12.184 +}
  12.185 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/External/OxyPlot/OxyPlot/Annotations/AnnotationLayer.cs	Sat Jun 08 16:53:22 2013 +0000
    13.3 @@ -0,0 +1,52 @@
    13.4 +// --------------------------------------------------------------------------------------------------------------------
    13.5 +// <copyright file="AnnotationLayer.cs" company="OxyPlot">
    13.6 +//   The MIT License (MIT)
    13.7 +//
    13.8 +//   Copyright (c) 2012 Oystein Bjorke
    13.9 +//
   13.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   13.11 +//   copy of this software and associated documentation files (the
   13.12 +//   "Software"), to deal in the Software without restriction, including
   13.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   13.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   13.15 +//   permit persons to whom the Software is furnished to do so, subject to
   13.16 +//   the following conditions:
   13.17 +//
   13.18 +//   The above copyright notice and this permission notice shall be included
   13.19 +//   in all copies or substantial portions of the Software.
   13.20 +//
   13.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   13.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   13.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   13.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   13.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   13.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   13.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   13.28 +// </copyright>
   13.29 +// <summary>
   13.30 +//   The annotation layer.
   13.31 +// </summary>
   13.32 +// --------------------------------------------------------------------------------------------------------------------
   13.33 +namespace OxyPlot.Annotations
   13.34 +{
   13.35 +    /// <summary>
   13.36 +    /// Specifies the layer for an <see cref="Annotation"/>.
   13.37 +    /// </summary>
   13.38 +    public enum AnnotationLayer
   13.39 +    {
   13.40 +        /// <summary>
   13.41 +        /// Render the annotation below the gridlines of the axes.
   13.42 +        /// </summary>
   13.43 +        BelowAxes,
   13.44 +
   13.45 +        /// <summary>
   13.46 +        /// Render the annotation below the series.
   13.47 +        /// </summary>
   13.48 +        BelowSeries,
   13.49 +
   13.50 +        /// <summary>
   13.51 +        /// Render the annotation above the series.
   13.52 +        /// </summary>
   13.53 +        AboveSeries
   13.54 +    }
   13.55 +}
   13.56 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/External/OxyPlot/OxyPlot/Annotations/ArrowAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    14.3 @@ -0,0 +1,228 @@
    14.4 +// --------------------------------------------------------------------------------------------------------------------
    14.5 +// <copyright file="ArrowAnnotation.cs" company="OxyPlot">
    14.6 +//   The MIT License (MIT)
    14.7 +//   
    14.8 +//   Copyright (c) 2012 Oystein Bjorke
    14.9 +//   
   14.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   14.11 +//   copy of this software and associated documentation files (the
   14.12 +//   "Software"), to deal in the Software without restriction, including
   14.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   14.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   14.15 +//   permit persons to whom the Software is furnished to do so, subject to
   14.16 +//   the following conditions:
   14.17 +//   
   14.18 +//   The above copyright notice and this permission notice shall be included
   14.19 +//   in all copies or substantial portions of the Software.
   14.20 +//   
   14.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   14.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   14.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   14.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   14.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   14.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   14.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   14.28 +// </copyright>
   14.29 +// <summary>
   14.30 +//   Represents an arrow annotation.
   14.31 +// </summary>
   14.32 +// --------------------------------------------------------------------------------------------------------------------
   14.33 +namespace OxyPlot.Annotations
   14.34 +{
   14.35 +    /// <summary>
   14.36 +    /// Represents an arrow annotation.
   14.37 +    /// </summary>
   14.38 +    public class ArrowAnnotation : TextualAnnotation
   14.39 +    {
   14.40 +        /// <summary>
   14.41 +        /// The end point in screen coordinates.
   14.42 +        /// </summary>
   14.43 +        private ScreenPoint screenEndPoint;
   14.44 +
   14.45 +        /// <summary>
   14.46 +        /// The start point in screen coordinates.
   14.47 +        /// </summary>
   14.48 +        private ScreenPoint screenStartPoint;
   14.49 +
   14.50 +        /// <summary>
   14.51 +        /// Initializes a new instance of the <see cref="ArrowAnnotation"/> class.
   14.52 +        /// </summary>
   14.53 +        public ArrowAnnotation()
   14.54 +        {
   14.55 +            this.HeadLength = 10;
   14.56 +            this.HeadWidth = 3;
   14.57 +            this.Color = OxyColors.Blue;
   14.58 +            this.StrokeThickness = 2;
   14.59 +            this.LineStyle = LineStyle.Solid;
   14.60 +            this.LineJoin = OxyPenLineJoin.Miter;
   14.61 +        }
   14.62 +
   14.63 +        /// <summary>
   14.64 +        /// Gets or sets the arrow direction.
   14.65 +        /// </summary>
   14.66 +        /// <remarks>
   14.67 +        /// Setting this property overrides the StartPoint property.
   14.68 +        /// </remarks>
   14.69 +        public ScreenVector ArrowDirection { get; set; }
   14.70 +
   14.71 +        /// <summary>
   14.72 +        /// Gets or sets the color of the arrow.
   14.73 +        /// </summary>
   14.74 +        public OxyColor Color { get; set; }
   14.75 +
   14.76 +        /// <summary>
   14.77 +        /// Gets or sets the end point.
   14.78 +        /// </summary>
   14.79 +        public DataPoint EndPoint { get; set; }
   14.80 +
   14.81 +        /// <summary>
   14.82 +        /// Gets or sets the length of the head (relative to the stroke thickness) (the default value is 10).
   14.83 +        /// </summary>
   14.84 +        /// <value> The length of the head. </value>
   14.85 +        public double HeadLength { get; set; }
   14.86 +
   14.87 +        /// <summary>
   14.88 +        /// Gets or sets the width of the head (relative to the stroke thickness) (the default value is 3).
   14.89 +        /// </summary>
   14.90 +        /// <value> The width of the head. </value>
   14.91 +        public double HeadWidth { get; set; }
   14.92 +
   14.93 +        /// <summary>
   14.94 +        /// Gets or sets the line join type.
   14.95 +        /// </summary>
   14.96 +        /// <value> The line join type. </value>
   14.97 +        public OxyPenLineJoin LineJoin { get; set; }
   14.98 +
   14.99 +        /// <summary>
  14.100 +        /// Gets or sets the line style.
  14.101 +        /// </summary>
  14.102 +        /// <value> The line style. </value>
  14.103 +        public LineStyle LineStyle { get; set; }
  14.104 +
  14.105 +        /// <summary>
  14.106 +        /// Gets or sets the start point.
  14.107 +        /// </summary>
  14.108 +        /// <remarks>
  14.109 +        /// This property is overridden by the ArrowDirection property, if set.
  14.110 +        /// </remarks>
  14.111 +        public DataPoint StartPoint { get; set; }
  14.112 +
  14.113 +        /// <summary>
  14.114 +        /// Gets or sets the stroke thickness (the default value is 2).
  14.115 +        /// </summary>
  14.116 +        /// <value> The stroke thickness. </value>
  14.117 +        public double StrokeThickness { get; set; }
  14.118 +
  14.119 +        /// <summary>
  14.120 +        /// Gets or sets the 'veeness' of the arrow head (relative to thickness) (the default value is 0).
  14.121 +        /// </summary>
  14.122 +        /// <value> The 'veeness'. </value>
  14.123 +        public double Veeness { get; set; }
  14.124 +
  14.125 +        /// <summary>
  14.126 +        /// Renders the arrow annotation.
  14.127 +        /// </summary>
  14.128 +        /// <param name="rc">
  14.129 +        /// The render context.
  14.130 +        /// </param>
  14.131 +        /// <param name="model">
  14.132 +        /// The plot model.
  14.133 +        /// </param>
  14.134 +        public override void Render(IRenderContext rc, PlotModel model)
  14.135 +        {
  14.136 +            base.Render(rc, model);
  14.137 +
  14.138 +            this.screenEndPoint = this.Transform(this.EndPoint);
  14.139 +
  14.140 +            if (!this.ArrowDirection.x.IsZero() || !this.ArrowDirection.y.IsZero())
  14.141 +            {
  14.142 +                this.screenStartPoint = this.screenEndPoint - this.ArrowDirection;
  14.143 +            }
  14.144 +            else
  14.145 +            {
  14.146 +                this.screenStartPoint = this.Transform(this.StartPoint);
  14.147 +            }
  14.148 +
  14.149 +            var d = this.screenEndPoint - this.screenStartPoint;
  14.150 +            d.Normalize();
  14.151 +            var n = new ScreenVector(d.Y, -d.X);
  14.152 +
  14.153 +            var p1 = this.screenEndPoint - (d * this.HeadLength * this.StrokeThickness);
  14.154 +            var p2 = p1 + (n * this.HeadWidth * this.StrokeThickness);
  14.155 +            var p3 = p1 - (n * this.HeadWidth * this.StrokeThickness);
  14.156 +            var p4 = p1 + (d * this.Veeness * this.StrokeThickness);
  14.157 +
  14.158 +            OxyRect clippingRect = this.GetClippingRect();
  14.159 +            const double MinimumSegmentLength = 4;
  14.160 +
  14.161 +            rc.DrawClippedLine(
  14.162 +                new[] { this.screenStartPoint, p4 },
  14.163 +                clippingRect,
  14.164 +                MinimumSegmentLength * MinimumSegmentLength,
  14.165 +                this.GetSelectableColor(this.Color),
  14.166 +                this.StrokeThickness,
  14.167 +                this.LineStyle,
  14.168 +                this.LineJoin,
  14.169 +                false);
  14.170 +
  14.171 +            rc.DrawClippedPolygon(
  14.172 +                new[] { p3, this.screenEndPoint, p2, p4 },
  14.173 +                clippingRect,
  14.174 +                MinimumSegmentLength * MinimumSegmentLength,
  14.175 +                this.GetSelectableColor(this.Color),
  14.176 +                null);
  14.177 +
  14.178 +            if (!string.IsNullOrEmpty(this.Text))
  14.179 +            {
  14.180 +                var ha = d.X < 0 ? HorizontalAlignment.Left : HorizontalAlignment.Right;
  14.181 +                var va = d.Y < 0 ? VerticalAlignment.Top : VerticalAlignment.Bottom;
  14.182 +
  14.183 +                var textPoint = this.screenStartPoint;
  14.184 +                rc.DrawClippedText(
  14.185 +                    clippingRect,
  14.186 +                    textPoint,
  14.187 +                    this.Text,
  14.188 +                    this.ActualTextColor,
  14.189 +                    this.ActualFont,
  14.190 +                    this.ActualFontSize,
  14.191 +                    this.ActualFontWeight,
  14.192 +                    0,
  14.193 +                    ha,
  14.194 +                    va);
  14.195 +            }
  14.196 +        }
  14.197 +
  14.198 +        /// <summary>
  14.199 +        /// Tests if the plot element is hit by the specified point.
  14.200 +        /// </summary>
  14.201 +        /// <param name="point">
  14.202 +        /// The point.
  14.203 +        /// </param>
  14.204 +        /// <param name="tolerance">
  14.205 +        /// The tolerance.
  14.206 +        /// </param>
  14.207 +        /// <returns>
  14.208 +        /// A hit test result.
  14.209 +        /// </returns>
  14.210 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  14.211 +        {
  14.212 +            if ((point - this.screenStartPoint).Length < tolerance)
  14.213 +            {
  14.214 +                return new HitTestResult(this.screenStartPoint, null, 1);
  14.215 +            }
  14.216 +
  14.217 +            if ((point - this.screenEndPoint).Length < tolerance)
  14.218 +            {
  14.219 +                return new HitTestResult(this.screenEndPoint, null, 2);
  14.220 +            }
  14.221 +
  14.222 +            var p = ScreenPointHelper.FindPointOnLine(point, this.screenStartPoint, this.screenEndPoint);
  14.223 +            if ((p - point).Length < tolerance)
  14.224 +            {
  14.225 +                return new HitTestResult(p);
  14.226 +            }
  14.227 +
  14.228 +            return null;
  14.229 +        }
  14.230 +    }
  14.231 +}
  14.232 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/External/OxyPlot/OxyPlot/Annotations/EllipseAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    15.3 @@ -0,0 +1,152 @@
    15.4 +// --------------------------------------------------------------------------------------------------------------------
    15.5 +// <copyright file="RectangleAnnotation.cs" company="OxyPlot">
    15.6 +//   The MIT License (MIT)
    15.7 +//
    15.8 +//   Copyright (c) 2012 Oystein Bjorke
    15.9 +//
   15.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   15.11 +//   copy of this software and associated documentation files (the
   15.12 +//   "Software"), to deal in the Software without restriction, including
   15.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   15.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   15.15 +//   permit persons to whom the Software is furnished to do so, subject to
   15.16 +//   the following conditions:
   15.17 +//
   15.18 +//   The above copyright notice and this permission notice shall be included
   15.19 +//   in all copies or substantial portions of the Software.
   15.20 +//
   15.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   15.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   15.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   15.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   15.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   15.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   15.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   15.28 +// </copyright>
   15.29 +// <summary>
   15.30 +//   Represents a rectangle annotation.
   15.31 +// </summary>
   15.32 +// --------------------------------------------------------------------------------------------------------------------
   15.33 +namespace OxyPlot.Annotations
   15.34 +{
   15.35 +    /// <summary>
   15.36 +    /// Represents an ellipse annotation.
   15.37 +    /// </summary>
   15.38 +    public class EllipseAnnotation : TextualAnnotation
   15.39 +    {
   15.40 +        /// <summary>
   15.41 +        /// The rectangle transformed to screen coordinates.
   15.42 +        /// </summary>
   15.43 +        private OxyRect screenRectangle;
   15.44 +
   15.45 +        /// <summary>
   15.46 +        /// Initializes a new instance of the <see cref="EllipseAnnotation"/> class.
   15.47 +        /// </summary>
   15.48 +        public EllipseAnnotation()
   15.49 +        {
   15.50 +            this.Stroke = OxyColors.Black;
   15.51 +            this.Fill = OxyColors.LightBlue;
   15.52 +        }
   15.53 +
   15.54 +        /// <summary>
   15.55 +        /// Gets or sets the fill color.
   15.56 +        /// </summary>
   15.57 +        /// <value> The fill. </value>
   15.58 +        public OxyColor Fill { get; set; }
   15.59 +
   15.60 +        /// <summary>
   15.61 +        /// Gets or sets the stroke color.
   15.62 +        /// </summary>
   15.63 +        public OxyColor Stroke { get; set; }
   15.64 +
   15.65 +        /// <summary>
   15.66 +        /// Gets or sets the stroke thickness.
   15.67 +        /// </summary>
   15.68 +        public double StrokeThickness { get; set; }
   15.69 +
   15.70 +        /// <summary>
   15.71 +        /// Gets or sets the x-coordinate of the center.
   15.72 +        /// </summary>
   15.73 +        public double X { get; set; }
   15.74 +
   15.75 +        /// <summary>
   15.76 +        /// Gets or sets the y-coordinate of the center.
   15.77 +        /// </summary>
   15.78 +        public double Y { get; set; }
   15.79 +
   15.80 +        /// <summary>
   15.81 +        /// Gets or sets the width of the ellipse.
   15.82 +        /// </summary>
   15.83 +        public double Width { get; set; }
   15.84 +
   15.85 +        /// <summary>
   15.86 +        /// Gets or sets the height of the ellipse.
   15.87 +        /// </summary>
   15.88 +        public double Height { get; set; }
   15.89 +
   15.90 +        /// <summary>
   15.91 +        /// Gets or sets the text rotation (degrees).
   15.92 +        /// </summary>
   15.93 +        /// <value>The text rotation in degrees.</value>
   15.94 +        public double TextRotation { get; set; }
   15.95 +
   15.96 +        /// <summary>
   15.97 +        /// Renders the polygon annotation.
   15.98 +        /// </summary>
   15.99 +        /// <param name="rc">
  15.100 +        /// The render context.
  15.101 +        /// </param>
  15.102 +        /// <param name="model">
  15.103 +        /// The plot model.
  15.104 +        /// </param>
  15.105 +        public override void Render(IRenderContext rc, PlotModel model)
  15.106 +        {
  15.107 +            base.Render(rc, model);
  15.108 +
  15.109 +            this.screenRectangle = OxyRect.Create(this.Transform(this.X - (Width / 2), Y - (Height / 2)), this.Transform(X + (Width / 2), Y + (Height / 2)));
  15.110 +
  15.111 +            // clip to the area defined by the axes
  15.112 +            var clipping = this.GetClippingRect();
  15.113 +
  15.114 +            rc.DrawClippedEllipse(clipping, this.screenRectangle, this.Fill, this.Stroke, this.StrokeThickness);
  15.115 +
  15.116 +            if (!string.IsNullOrEmpty(this.Text))
  15.117 +            {
  15.118 +                var textPosition = this.screenRectangle.Center;
  15.119 +                rc.DrawClippedText(
  15.120 +                    clipping,
  15.121 +                    textPosition,
  15.122 +                    this.Text,
  15.123 +                    this.ActualTextColor,
  15.124 +                    this.ActualFont,
  15.125 +                    this.ActualFontSize,
  15.126 +                    this.ActualFontWeight,
  15.127 +                    this.TextRotation,
  15.128 +                    HorizontalAlignment.Center,
  15.129 +                    VerticalAlignment.Middle);
  15.130 +            }
  15.131 +        }
  15.132 +
  15.133 +        /// <summary>
  15.134 +        /// Tests if the plot element is hit by the specified point.
  15.135 +        /// </summary>
  15.136 +        /// <param name="point">
  15.137 +        /// The point.
  15.138 +        /// </param>
  15.139 +        /// <param name="tolerance">
  15.140 +        /// The tolerance.
  15.141 +        /// </param>
  15.142 +        /// <returns>
  15.143 +        /// A hit test result.
  15.144 +        /// </returns>
  15.145 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  15.146 +        {
  15.147 +            if (this.screenRectangle.Contains(point))
  15.148 +            {
  15.149 +                return new HitTestResult(point);
  15.150 +            }
  15.151 +
  15.152 +            return null;
  15.153 +        }
  15.154 +    }
  15.155 +}
  15.156 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/External/OxyPlot/OxyPlot/Annotations/ImageAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    16.3 @@ -0,0 +1,451 @@
    16.4 +// --------------------------------------------------------------------------------------------------------------------
    16.5 +// <copyright file="ImageAnnotation.cs" company="OxyPlot">
    16.6 +//   The MIT License (MIT)
    16.7 +//   
    16.8 +//   Copyright (c) 2012 Oystein Bjorke
    16.9 +//   
   16.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   16.11 +//   copy of this software and associated documentation files (the
   16.12 +//   "Software"), to deal in the Software without restriction, including
   16.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   16.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   16.15 +//   permit persons to whom the Software is furnished to do so, subject to
   16.16 +//   the following conditions:
   16.17 +//   
   16.18 +//   The above copyright notice and this permission notice shall be included
   16.19 +//   in all copies or substantial portions of the Software.
   16.20 +//   
   16.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   16.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   16.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   16.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   16.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   16.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   16.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   16.28 +// </copyright>
   16.29 +// <summary>
   16.30 +//   Represents a text object annotation.
   16.31 +// </summary>
   16.32 +// --------------------------------------------------------------------------------------------------------------------
   16.33 +namespace OxyPlot.Annotations
   16.34 +{
   16.35 +    /// <summary>
   16.36 +    /// Represents a text annotation.
   16.37 +    /// </summary>
   16.38 +    public class ImageAnnotation : Annotation
   16.39 +    {
   16.40 +        /// <summary>
   16.41 +        /// The actual bounds of the rendered image.
   16.42 +        /// </summary>
   16.43 +        private OxyRect actualBounds;
   16.44 +
   16.45 +        /// <summary>
   16.46 +        /// Initializes a new instance of the <see cref="ImageAnnotation" /> class.
   16.47 +        /// </summary>
   16.48 +        public ImageAnnotation()
   16.49 +        {
   16.50 +            this.X = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea);
   16.51 +            this.Y = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea);
   16.52 +            this.OffsetX = new PlotLength(0, PlotLengthUnit.ScreenUnits);
   16.53 +            this.OffsetY = new PlotLength(0, PlotLengthUnit.ScreenUnits);
   16.54 +            this.Width = new PlotLength(double.NaN, PlotLengthUnit.ScreenUnits);
   16.55 +            this.Height = new PlotLength(double.NaN, PlotLengthUnit.ScreenUnits);
   16.56 +            this.Opacity = 1.0;
   16.57 +            this.Interpolate = true;
   16.58 +            this.HorizontalAlignment = OxyPlot.HorizontalAlignment.Center;
   16.59 +            this.VerticalAlignment = OxyPlot.VerticalAlignment.Middle;
   16.60 +        }
   16.61 +
   16.62 +        /// <summary>
   16.63 +        /// Initializes a new instance of the <see cref="ImageAnnotation"/> class.
   16.64 +        /// </summary>
   16.65 +        /// <param name="image">
   16.66 +        /// The image.
   16.67 +        /// </param>
   16.68 +        /// <param name="position">
   16.69 +        /// The position in screen coordinates.
   16.70 +        /// </param>
   16.71 +        /// <param name="horizontalAlignment">
   16.72 +        /// The horizontal alignment.
   16.73 +        /// </param>
   16.74 +        /// <param name="verticalAlignment">
   16.75 +        /// The vertical alignment.
   16.76 +        /// </param>
   16.77 +        public ImageAnnotation(
   16.78 +            OxyImage image, 
   16.79 +            ScreenPoint position, 
   16.80 +            HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center, 
   16.81 +            VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
   16.82 +            : this()
   16.83 +        {
   16.84 +            this.ImageSource = image;
   16.85 +            this.X = new PlotLength(position.X, PlotLengthUnit.ScreenUnits);
   16.86 +            this.Y = new PlotLength(position.Y, PlotLengthUnit.ScreenUnits);
   16.87 +            this.HorizontalAlignment = horizontalAlignment;
   16.88 +            this.VerticalAlignment = verticalAlignment;
   16.89 +        }
   16.90 +
   16.91 +        /// <summary>
   16.92 +        /// Initializes a new instance of the <see cref="ImageAnnotation"/> class.
   16.93 +        /// </summary>
   16.94 +        /// <param name="image">
   16.95 +        /// The image.
   16.96 +        /// </param>
   16.97 +        /// <param name="position">
   16.98 +        /// The position in data coordinates.
   16.99 +        /// </param>
  16.100 +        /// <param name="horizontalAlignment">
  16.101 +        /// The horizontal alignment.
  16.102 +        /// </param>
  16.103 +        /// <param name="verticalAlignment">
  16.104 +        /// The vertical alignment.
  16.105 +        /// </param>
  16.106 +        public ImageAnnotation(
  16.107 +            OxyImage image, 
  16.108 +            IDataPoint position, 
  16.109 +            HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center, 
  16.110 +            VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
  16.111 +            : this()
  16.112 +        {
  16.113 +            this.ImageSource = image;
  16.114 +            this.X = new PlotLength(position.X, PlotLengthUnit.Data);
  16.115 +            this.Y = new PlotLength(position.Y, PlotLengthUnit.Data);
  16.116 +            this.HorizontalAlignment = horizontalAlignment;
  16.117 +            this.VerticalAlignment = verticalAlignment;
  16.118 +        }
  16.119 +
  16.120 +        /// <summary>
  16.121 +        /// Initializes a new instance of the <see cref="ImageAnnotation"/> class.
  16.122 +        /// </summary>
  16.123 +        /// <param name="image">
  16.124 +        /// The image.
  16.125 +        /// </param>
  16.126 +        /// <param name="relativeX">
  16.127 +        /// The x-coordinate relative to the plot area (0-1).
  16.128 +        /// </param>
  16.129 +        /// <param name="relativeY">
  16.130 +        /// The y-coordinate relative to the plot area (0-1).
  16.131 +        /// </param>
  16.132 +        /// <param name="horizontalAlignment">
  16.133 +        /// The horizontal alignment.
  16.134 +        /// </param>
  16.135 +        /// <param name="verticalAlignment">
  16.136 +        /// The vertical alignment.
  16.137 +        /// </param>
  16.138 +        public ImageAnnotation(
  16.139 +            OxyImage image, 
  16.140 +            double relativeX, 
  16.141 +            double relativeY, 
  16.142 +            HorizontalAlignment horizontalAlignment = OxyPlot.HorizontalAlignment.Center, 
  16.143 +            VerticalAlignment verticalAlignment = OxyPlot.VerticalAlignment.Middle)
  16.144 +            : this()
  16.145 +        {
  16.146 +            this.ImageSource = image;
  16.147 +            this.X = new PlotLength(relativeX, PlotLengthUnit.RelativeToPlotArea);
  16.148 +            this.Y = new PlotLength(relativeY, PlotLengthUnit.RelativeToPlotArea);
  16.149 +            this.HorizontalAlignment = horizontalAlignment;
  16.150 +            this.VerticalAlignment = verticalAlignment;
  16.151 +        }
  16.152 +
  16.153 +        /// <summary>
  16.154 +        /// Gets or sets the image source.
  16.155 +        /// </summary>
  16.156 +        /// <value>
  16.157 +        /// The image source.
  16.158 +        /// </value>
  16.159 +        public OxyImage ImageSource { get; set; }
  16.160 +
  16.161 +        /// <summary>
  16.162 +        /// Gets or sets the horizontal alignment.
  16.163 +        /// </summary>
  16.164 +        /// <value> The horizontal alignment. </value>
  16.165 +        public HorizontalAlignment HorizontalAlignment { get; set; }
  16.166 +
  16.167 +        /// <summary>
  16.168 +        /// Gets or sets the X position of the image.
  16.169 +        /// </summary>
  16.170 +        /// <value>
  16.171 +        /// The X.
  16.172 +        /// </value>
  16.173 +        public PlotLength X { get; set; }
  16.174 +
  16.175 +        /// <summary>
  16.176 +        /// Gets or sets the Y position of the image.
  16.177 +        /// </summary>
  16.178 +        /// <value>
  16.179 +        /// The Y.
  16.180 +        /// </value>
  16.181 +        public PlotLength Y { get; set; }
  16.182 +
  16.183 +        /// <summary>
  16.184 +        /// Gets or sets the X offset.
  16.185 +        /// </summary>
  16.186 +        /// <value>
  16.187 +        /// The offset X.
  16.188 +        /// </value>
  16.189 +        public PlotLength OffsetX { get; set; }
  16.190 +
  16.191 +        /// <summary>
  16.192 +        /// Gets or sets the Y offset.
  16.193 +        /// </summary>
  16.194 +        /// <value>
  16.195 +        /// The offset Y.
  16.196 +        /// </value>
  16.197 +        public PlotLength OffsetY { get; set; }
  16.198 +
  16.199 +        /// <summary>
  16.200 +        /// Gets or sets the width.
  16.201 +        /// </summary>
  16.202 +        /// <value>
  16.203 +        /// The width.
  16.204 +        /// </value>
  16.205 +        public PlotLength Width { get; set; }
  16.206 +
  16.207 +        /// <summary>
  16.208 +        /// Gets or sets the height.
  16.209 +        /// </summary>
  16.210 +        /// <value>
  16.211 +        /// The height.
  16.212 +        /// </value>
  16.213 +        public PlotLength Height { get; set; }
  16.214 +
  16.215 +        /// <summary>
  16.216 +        /// Gets or sets the opacity (0-1).
  16.217 +        /// </summary>
  16.218 +        /// <value>
  16.219 +        /// The opacity value.
  16.220 +        /// </value>
  16.221 +        public double Opacity { get; set; }
  16.222 +
  16.223 +        /// <summary>
  16.224 +        /// Gets or sets a value indicating whether to apply smooth interpolation to the image.
  16.225 +        /// </summary>
  16.226 +        /// <value>
  16.227 +        ///   <c>true</c> if the image should be interpolated (using a high-quality bi-cubic interpolation); <c>false</c> if the nearest neighbor should be used.
  16.228 +        /// </value>
  16.229 +        public bool Interpolate { get; set; }
  16.230 +
  16.231 +        /// <summary>
  16.232 +        /// Gets or sets the vertical alignment.
  16.233 +        /// </summary>
  16.234 +        /// <value> The vertical alignment. </value>
  16.235 +        public VerticalAlignment VerticalAlignment { get; set; }
  16.236 +
  16.237 +        /// <summary>
  16.238 +        /// Renders the image annotation.
  16.239 +        /// </summary>
  16.240 +        /// <param name="rc">
  16.241 +        /// The render context.
  16.242 +        /// </param>
  16.243 +        /// <param name="model">
  16.244 +        /// The plot model.
  16.245 +        /// </param>
  16.246 +        public override void Render(IRenderContext rc, PlotModel model)
  16.247 +        {
  16.248 +            base.Render(rc, model);
  16.249 +
  16.250 +            var p = this.GetPoint(this.X, this.Y, rc, model);
  16.251 +            var o = this.GetVector(this.OffsetX, this.OffsetY, rc, model);
  16.252 +            var position = p + o;
  16.253 +
  16.254 +            var clippingRect = this.GetClippingRect();
  16.255 +
  16.256 +            var imageInfo = rc.GetImageInfo(this.ImageSource);
  16.257 +            if (imageInfo == null)
  16.258 +            {
  16.259 +                return;
  16.260 +            }
  16.261 +
  16.262 +            var s = this.GetVector(this.Width, this.Height, rc, model);
  16.263 +
  16.264 +            var width = s.X;
  16.265 +            var height = s.Y;
  16.266 +
  16.267 +            if (double.IsNaN(width) && double.IsNaN(height))
  16.268 +            {
  16.269 +                width = imageInfo.Width;
  16.270 +                height = imageInfo.Height;
  16.271 +            }
  16.272 +
  16.273 +            if (double.IsNaN(width))
  16.274 +            {
  16.275 +                width = height / imageInfo.Height * imageInfo.Width;
  16.276 +            }
  16.277 +
  16.278 +            if (double.IsNaN(height))
  16.279 +            {
  16.280 +                height = width / imageInfo.Width * imageInfo.Height;
  16.281 +            }
  16.282 +
  16.283 +            double x = position.X;
  16.284 +            double y = position.Y;
  16.285 +
  16.286 +            if (this.HorizontalAlignment == HorizontalAlignment.Center)
  16.287 +            {
  16.288 +                x -= width * 0.5;
  16.289 +            }
  16.290 +
  16.291 +            if (this.HorizontalAlignment == HorizontalAlignment.Right)
  16.292 +            {
  16.293 +                x -= width;
  16.294 +            }
  16.295 +
  16.296 +            if (this.VerticalAlignment == VerticalAlignment.Middle)
  16.297 +            {
  16.298 +                y -= height * 0.5;
  16.299 +            }
  16.300 +
  16.301 +            if (this.VerticalAlignment == VerticalAlignment.Bottom)
  16.302 +            {
  16.303 +                y -= height;
  16.304 +            }
  16.305 +
  16.306 +            this.actualBounds = new OxyRect(x, y, width, height);
  16.307 +
  16.308 +            if (this.X.Unit == PlotLengthUnit.Data || this.Y.Unit == PlotLengthUnit.Data)
  16.309 +            {
  16.310 +                rc.DrawClippedImage(clippingRect, this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
  16.311 +            }
  16.312 +            else
  16.313 +            {
  16.314 +                rc.DrawImage(this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
  16.315 +            }
  16.316 +        }
  16.317 +
  16.318 +        /// <summary>
  16.319 +        /// Tests if the plot element is hit by the specified point.
  16.320 +        /// </summary>
  16.321 +        /// <param name="point">
  16.322 +        /// The point.
  16.323 +        /// </param>
  16.324 +        /// <param name="tolerance">
  16.325 +        /// The tolerance.
  16.326 +        /// </param>
  16.327 +        /// <returns>
  16.328 +        /// A hit test result.
  16.329 +        /// </returns>
  16.330 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  16.331 +        {
  16.332 +            if (this.actualBounds.Contains(point))
  16.333 +            {
  16.334 +                return new HitTestResult(point);
  16.335 +            }
  16.336 +
  16.337 +            return null;
  16.338 +        }
  16.339 +
  16.340 +        /// <summary>
  16.341 +        /// Gets the point.
  16.342 +        /// </summary>
  16.343 +        /// <param name="x">
  16.344 +        /// The x.
  16.345 +        /// </param>
  16.346 +        /// <param name="y">
  16.347 +        /// The y.
  16.348 +        /// </param>
  16.349 +        /// <param name="rc">
  16.350 +        /// The render context.
  16.351 +        /// </param>
  16.352 +        /// <param name="model">
  16.353 +        /// The model.
  16.354 +        /// </param>
  16.355 +        /// <returns>
  16.356 +        /// The point in screen coordinates.
  16.357 +        /// </returns>
  16.358 +        protected ScreenPoint GetPoint(PlotLength x, PlotLength y, IRenderContext rc, PlotModel model)
  16.359 +        {
  16.360 +            if (x.Unit == PlotLengthUnit.Data || y.Unit == PlotLengthUnit.Data)
  16.361 +            {
  16.362 +                return this.XAxis.Transform(x.Value, y.Value, this.YAxis);
  16.363 +            }
  16.364 +
  16.365 +            double sx;
  16.366 +            double sy;
  16.367 +            switch (x.Unit)
  16.368 +            {
  16.369 +                case PlotLengthUnit.RelativeToPlotArea:
  16.370 +                    sx = model.PlotArea.Left + (model.PlotArea.Width * x.Value);
  16.371 +                    break;
  16.372 +                case PlotLengthUnit.RelativeToViewport:
  16.373 +                    sx = model.Width * x.Value;
  16.374 +                    break;
  16.375 +                default:
  16.376 +                    sx = x.Value;
  16.377 +                    break;
  16.378 +            }
  16.379 +
  16.380 +            switch (y.Unit)
  16.381 +            {
  16.382 +                case PlotLengthUnit.RelativeToPlotArea:
  16.383 +                    sy = model.PlotArea.Top + (model.PlotArea.Height * y.Value);
  16.384 +                    break;
  16.385 +                case PlotLengthUnit.RelativeToViewport:
  16.386 +                    sy = model.Height * y.Value;
  16.387 +                    break;
  16.388 +                default:
  16.389 +                    sy = y.Value;
  16.390 +                    break;
  16.391 +            }
  16.392 +
  16.393 +            return new ScreenPoint(sx, sy);
  16.394 +        }
  16.395 +
  16.396 +        /// <summary>
  16.397 +        /// Gets the vector.
  16.398 +        /// </summary>
  16.399 +        /// <param name="x">
  16.400 +        /// The x component.
  16.401 +        /// </param>
  16.402 +        /// <param name="y">
  16.403 +        /// The y component.
  16.404 +        /// </param>
  16.405 +        /// <param name="rc">
  16.406 +        /// The render context.
  16.407 +        /// </param>
  16.408 +        /// <param name="model">
  16.409 +        /// The model.
  16.410 +        /// </param>
  16.411 +        /// <returns>
  16.412 +        /// The vector in screen coordinates.
  16.413 +        /// </returns>
  16.414 +        protected ScreenVector GetVector(PlotLength x, PlotLength y, IRenderContext rc, PlotModel model)
  16.415 +        {
  16.416 +            double sx;
  16.417 +            double sy;
  16.418 +
  16.419 +            switch (x.Unit)
  16.420 +            {
  16.421 +                case PlotLengthUnit.Data:
  16.422 +                    sx = this.XAxis.Transform(x.Value) - this.XAxis.Transform(0);
  16.423 +                    break;
  16.424 +                case PlotLengthUnit.RelativeToPlotArea:
  16.425 +                    sx = model.PlotArea.Width * x.Value;
  16.426 +                    break;
  16.427 +                case PlotLengthUnit.RelativeToViewport:
  16.428 +                    sx = model.Width * x.Value;
  16.429 +                    break;
  16.430 +                default:
  16.431 +                    sx = x.Value;
  16.432 +                    break;
  16.433 +            }
  16.434 +
  16.435 +            switch (y.Unit)
  16.436 +            {
  16.437 +                case PlotLengthUnit.Data:
  16.438 +                    sy = this.YAxis.Transform(y.Value) - this.YAxis.Transform(0);
  16.439 +                    break;
  16.440 +                case PlotLengthUnit.RelativeToPlotArea:
  16.441 +                    sy = model.PlotArea.Height * y.Value;
  16.442 +                    break;
  16.443 +                case PlotLengthUnit.RelativeToViewport:
  16.444 +                    sy = model.Height * y.Value;
  16.445 +                    break;
  16.446 +                default:
  16.447 +                    sy = y.Value;
  16.448 +                    break;
  16.449 +            }
  16.450 +
  16.451 +            return new ScreenVector(sx, sy);
  16.452 +        }
  16.453 +    }
  16.454 +}
  16.455 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/External/OxyPlot/OxyPlot/Annotations/LineAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    17.3 @@ -0,0 +1,528 @@
    17.4 +// --------------------------------------------------------------------------------------------------------------------
    17.5 +// <copyright file="LineAnnotation.cs" company="OxyPlot">
    17.6 +//   The MIT License (MIT)
    17.7 +//
    17.8 +//   Copyright (c) 2012 Oystein Bjorke
    17.9 +//
   17.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   17.11 +//   copy of this software and associated documentation files (the
   17.12 +//   "Software"), to deal in the Software without restriction, including
   17.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   17.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   17.15 +//   permit persons to whom the Software is furnished to do so, subject to
   17.16 +//   the following conditions:
   17.17 +//
   17.18 +//   The above copyright notice and this permission notice shall be included
   17.19 +//   in all copies or substantial portions of the Software.
   17.20 +//
   17.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   17.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   17.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   17.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   17.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   17.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   17.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   17.28 +// </copyright>
   17.29 +// <summary>
   17.30 +//   Specify the orientation of the annotation text
   17.31 +// </summary>
   17.32 +// --------------------------------------------------------------------------------------------------------------------
   17.33 +namespace OxyPlot.Annotations
   17.34 +{
   17.35 +    using System;
   17.36 +    using System.Collections.Generic;
   17.37 +    using System.Linq;
   17.38 +
   17.39 +    using OxyPlot.Axes;
   17.40 +
   17.41 +    /// <summary>
   17.42 +    /// Specifes the orientation of the annotation text
   17.43 +    /// </summary>
   17.44 +    public enum AnnotationTextOrientation
   17.45 +    {
   17.46 +        /// <summary>
   17.47 +        /// Horizontal text.
   17.48 +        /// </summary>
   17.49 +        Horizontal,
   17.50 +
   17.51 +        /// <summary>
   17.52 +        /// Vertical text.
   17.53 +        /// </summary>
   17.54 +        Vertical,
   17.55 +
   17.56 +        /// <summary>
   17.57 +        /// Oriented along the line.
   17.58 +        /// </summary>
   17.59 +        AlongLine
   17.60 +    }
   17.61 +
   17.62 +    /// <summary>
   17.63 +    /// Represents a line annotation.
   17.64 +    /// </summary>
   17.65 +    public class LineAnnotation : TextualAnnotation
   17.66 +    {
   17.67 +        /// <summary>
   17.68 +        /// The points of the line, transformed to screen coordinates.
   17.69 +        /// </summary>
   17.70 +        private IList<ScreenPoint> screenPoints;
   17.71 +
   17.72 +        /// <summary>
   17.73 +        /// Initializes a new instance of the <see cref = "LineAnnotation" /> class.
   17.74 +        /// </summary>
   17.75 +        public LineAnnotation()
   17.76 +        {
   17.77 +            this.Type = LineAnnotationType.LinearEquation;
   17.78 +            this.MinimumX = double.MinValue;
   17.79 +            this.MaximumX = double.MaxValue;
   17.80 +            this.MinimumY = double.MinValue;
   17.81 +            this.MaximumY = double.MaxValue;
   17.82 +            this.Color = OxyColors.Blue;
   17.83 +            this.StrokeThickness = 1;
   17.84 +            this.LineStyle = LineStyle.Dash;
   17.85 +            this.LineJoin = OxyPenLineJoin.Miter;
   17.86 +            this.ClipByXAxis = true;
   17.87 +            this.ClipByYAxis = true;
   17.88 +
   17.89 +            this.TextPosition = 1;
   17.90 +            this.TextOrientation = AnnotationTextOrientation.AlongLine;
   17.91 +            this.TextMargin = 12;
   17.92 +            this.TextHorizontalAlignment = HorizontalAlignment.Right;
   17.93 +            this.TextVerticalAlignment = VerticalAlignment.Top;
   17.94 +        }
   17.95 +
   17.96 +        /// <summary>
   17.97 +        /// Gets or sets the color of the line.
   17.98 +        /// </summary>
   17.99 +        public OxyColor Color { get; set; }
  17.100 +
  17.101 +        /// <summary>
  17.102 +        /// Gets or sets the y=f(x) equation when Type is Equation.
  17.103 +        /// </summary>
  17.104 +        public Func<double, double> Equation { get; set; }
  17.105 +
  17.106 +        /// <summary>
  17.107 +        /// Gets or sets the y-intercept when Type is LinearEquation.
  17.108 +        /// </summary>
  17.109 +        /// <value>The intercept value.</value>
  17.110 +        /// <remarks>
  17.111 +        /// Linear equation y-intercept (the b in y=mx+b).
  17.112 +        /// http://en.wikipedia.org/wiki/Linear_equation
  17.113 +        /// </remarks>
  17.114 +        public double Intercept { get; set; }
  17.115 +
  17.116 +        /// <summary>
  17.117 +        /// Gets or sets the line join.
  17.118 +        /// </summary>
  17.119 +        /// <value>The line join.</value>
  17.120 +        public OxyPenLineJoin LineJoin { get; set; }
  17.121 +
  17.122 +        /// <summary>
  17.123 +        /// Gets or sets the line style.
  17.124 +        /// </summary>
  17.125 +        /// <value>The line style.</value>
  17.126 +        public LineStyle LineStyle { get; set; }
  17.127 +
  17.128 +        /// <summary>
  17.129 +        /// Gets or sets the maximum X coordinate for the line.
  17.130 +        /// </summary>
  17.131 +        public double MaximumX { get; set; }
  17.132 +
  17.133 +        /// <summary>
  17.134 +        /// Gets or sets the maximum Y coordinate for the line.
  17.135 +        /// </summary>
  17.136 +        public double MaximumY { get; set; }
  17.137 +
  17.138 +        /// <summary>
  17.139 +        /// Gets or sets the minimum X coordinate for the line.
  17.140 +        /// </summary>
  17.141 +        public double MinimumX { get; set; }
  17.142 +
  17.143 +        /// <summary>
  17.144 +        /// Gets or sets the minimum Y coordinate for the line.
  17.145 +        /// </summary>
  17.146 +        public double MinimumY { get; set; }
  17.147 +
  17.148 +        /// <summary>
  17.149 +        /// Gets or sets the slope when Type is LinearEquation.
  17.150 +        /// </summary>
  17.151 +        /// <value>The slope value.</value>
  17.152 +        /// <remarks>
  17.153 +        /// Linear equation slope (the m in y=mx+b)
  17.154 +        /// http://en.wikipedia.org/wiki/Linear_equation
  17.155 +        /// </remarks>
  17.156 +        public double Slope { get; set; }
  17.157 +
  17.158 +        /// <summary>
  17.159 +        /// Gets or sets the stroke thickness.
  17.160 +        /// </summary>
  17.161 +        /// <value>The stroke thickness.</value>
  17.162 +        public double StrokeThickness { get; set; }
  17.163 +
  17.164 +        /// <summary>
  17.165 +        /// Gets or sets the text horizontal alignment.
  17.166 +        /// </summary>
  17.167 +        /// <value>The text horizontal alignment.</value>
  17.168 +        public HorizontalAlignment TextHorizontalAlignment { get; set; }
  17.169 +
  17.170 +        /// <summary>
  17.171 +        /// Gets or sets the text margin (along the line).
  17.172 +        /// </summary>
  17.173 +        /// <value>The text margin.</value>
  17.174 +        public double TextMargin { get; set; }
  17.175 +
  17.176 +        /// <summary>
  17.177 +        /// Gets or sets the text padding (in the direction of the text).
  17.178 +        /// </summary>
  17.179 +        /// <value>The text padding.</value>
  17.180 +        public double TextPadding { get; set; }
  17.181 +
  17.182 +        /// <summary>
  17.183 +        /// Gets or sets the text orientation.
  17.184 +        /// </summary>
  17.185 +        /// <value>The text orientation.</value>
  17.186 +        public AnnotationTextOrientation TextOrientation { get; set; }
  17.187 +
  17.188 +        /// <summary>
  17.189 +        /// Gets or sets the text position fraction.
  17.190 +        /// </summary>
  17.191 +        /// <value>The text position in the interval [0,1].</value>
  17.192 +        /// <remarks>
  17.193 +        /// Positions smaller than 0.25 are left aligned at the start of the line
  17.194 +        /// Positions larger than 0.75 are right aligned at the end of the line
  17.195 +        /// Other positions are center aligned at the specified position
  17.196 +        /// </remarks>
  17.197 +        public double TextPosition { get; set; }
  17.198 +
  17.199 +        /// <summary>
  17.200 +        /// Gets or sets the vertical alignment of text (above or below the line).
  17.201 +        /// </summary>
  17.202 +        public VerticalAlignment TextVerticalAlignment { get; set; }
  17.203 +
  17.204 +        /// <summary>
  17.205 +        /// Gets or sets the type of line equation.
  17.206 +        /// </summary>
  17.207 +        public LineAnnotationType Type { get; set; }
  17.208 +
  17.209 +        /// <summary>
  17.210 +        /// Gets or sets the X position for vertical lines (only for Type==Vertical).
  17.211 +        /// </summary>
  17.212 +        public double X { get; set; }
  17.213 +
  17.214 +        /// <summary>
  17.215 +        /// Gets or sets the Y position for horizontal lines (only for Type==Horizontal)
  17.216 +        /// </summary>
  17.217 +        public double Y { get; set; }
  17.218 +
  17.219 +        /// <summary>
  17.220 +        /// Gets or sets a value indicating whether to clip the annotation line by the X axis range.
  17.221 +        /// </summary>
  17.222 +        /// <value><c>true</c> if clipping by the X axis is enabled; otherwise, <c>false</c>.</value>
  17.223 +        public bool ClipByXAxis { get; set; }
  17.224 +
  17.225 +        /// <summary>
  17.226 +        /// Gets or sets a value indicating whether to clip the annotation line by the Y axis range.
  17.227 +        /// </summary>
  17.228 +        /// <value><c>true</c> if clipping by the Y axis is enabled; otherwise, <c>false</c>.</value>
  17.229 +        public bool ClipByYAxis { get; set; }
  17.230 +
  17.231 +        /// <summary>
  17.232 +        /// Renders the line annotation.
  17.233 +        /// </summary>
  17.234 +        /// <param name="rc">
  17.235 +        /// The render context.
  17.236 +        /// </param>
  17.237 +        /// <param name="model">
  17.238 +        /// The plot model.
  17.239 +        /// </param>
  17.240 +        public override void Render(IRenderContext rc, PlotModel model)
  17.241 +        {
  17.242 +            base.Render(rc, model);
  17.243 +
  17.244 +            bool aliased = false;
  17.245 +
  17.246 +            double actualMinimumX = Math.Max(this.MinimumX, this.XAxis.ActualMinimum);
  17.247 +            double actualMaximumX = Math.Min(this.MaximumX, this.XAxis.ActualMaximum);
  17.248 +            double actualMinimumY = Math.Max(this.MinimumY, this.YAxis.ActualMinimum);
  17.249 +            double actualMaximumY = Math.Min(this.MaximumY, this.YAxis.ActualMaximum);
  17.250 +
  17.251 +            if (!this.ClipByXAxis)
  17.252 +            {
  17.253 +                double right = XAxis.InverseTransform(PlotModel.PlotArea.Right);
  17.254 +                double left = XAxis.InverseTransform(PlotModel.PlotArea.Left);
  17.255 +                actualMaximumX = Math.Max(left, right);
  17.256 +                actualMinimumX = Math.Min(left, right);
  17.257 +            }
  17.258 +
  17.259 +            if (!this.ClipByYAxis)
  17.260 +            {
  17.261 +                double bottom = YAxis.InverseTransform(PlotModel.PlotArea.Bottom);
  17.262 +                double top = YAxis.InverseTransform(PlotModel.PlotArea.Top);
  17.263 +                actualMaximumY = Math.Max(top, bottom);
  17.264 +                actualMinimumY = Math.Min(top, bottom);
  17.265 +            }
  17.266 +
  17.267 +            // y=f(x)
  17.268 +            Func<double, double> fx = null;
  17.269 +
  17.270 +            // x=f(y)
  17.271 +            Func<double, double> fy = null;
  17.272 +
  17.273 +            switch (this.Type)
  17.274 +            {
  17.275 +                case LineAnnotationType.Horizontal:
  17.276 +                    fx = x => this.Y;
  17.277 +                    break;
  17.278 +                case LineAnnotationType.Vertical:
  17.279 +                    fy = y => this.X;
  17.280 +                    break;
  17.281 +                case LineAnnotationType.EquationY:
  17.282 +                    fx = this.Equation;
  17.283 +                    break;
  17.284 +                case LineAnnotationType.EquationX:
  17.285 +                    fy = this.Equation;
  17.286 +                    break;
  17.287 +                default:
  17.288 +                    fx = x => (this.Slope * x) + this.Intercept;
  17.289 +                    break;
  17.290 +            }
  17.291 +
  17.292 +            var points = new List<DataPoint>();
  17.293 +
  17.294 +            bool isCurvedLine = !(this.XAxis is LinearAxis) || !(this.YAxis is LinearAxis) || this.Type == LineAnnotationType.EquationY;
  17.295 +
  17.296 +            if (!isCurvedLine)
  17.297 +            {
  17.298 +                // we only need to calculate two points if it is a straight line
  17.299 +                if (fx != null)
  17.300 +                {
  17.301 +                    points.Add(new DataPoint(actualMinimumX, fx(actualMinimumX)));
  17.302 +                    points.Add(new DataPoint(actualMaximumX, fx(actualMaximumX)));
  17.303 +                }
  17.304 +                else if (fy != null)
  17.305 +                {
  17.306 +                    points.Add(new DataPoint(fy(actualMinimumY), actualMinimumY));
  17.307 +                    points.Add(new DataPoint(fy(actualMaximumY), actualMaximumY));
  17.308 +                }
  17.309 +
  17.310 +                if (this.Type == LineAnnotationType.Horizontal || this.Type == LineAnnotationType.Vertical)
  17.311 +                {
  17.312 +                    // use aliased line drawing for horizontal and vertical lines
  17.313 +                    aliased = true;
  17.314 +                }
  17.315 +            }
  17.316 +            else
  17.317 +            {
  17.318 +                if (fx != null)
  17.319 +                {
  17.320 +                    double x = actualMinimumX;
  17.321 +
  17.322 +                    // todo: the step size should be adaptive
  17.323 +                    double dx = (actualMaximumX - actualMinimumX) / 100;
  17.324 +                    while (true)
  17.325 +                    {
  17.326 +                        points.Add(new DataPoint(x, fx(x)));
  17.327 +                        if (x > actualMaximumX)
  17.328 +                        {
  17.329 +                            break;
  17.330 +                        }
  17.331 +
  17.332 +                        x += dx;
  17.333 +                    }
  17.334 +                }
  17.335 +                else if (fy != null)
  17.336 +                {
  17.337 +                    double y = actualMinimumY;
  17.338 +
  17.339 +                    // todo: the step size should be adaptive
  17.340 +                    double dy = (actualMaximumY - actualMinimumY) / 100;
  17.341 +                    while (true)
  17.342 +                    {
  17.343 +                        points.Add(new DataPoint(fy(y), y));
  17.344 +                        if (y > actualMaximumY)
  17.345 +                        {
  17.346 +                            break;
  17.347 +                        }
  17.348 +
  17.349 +                        y += dy;
  17.350 +                    }
  17.351 +                }
  17.352 +            }
  17.353 +
  17.354 +            // transform to screen coordinates
  17.355 +            this.screenPoints = points.Select(p => this.Transform(p)).ToList();
  17.356 +
  17.357 +            // clip to the area defined by the axes
  17.358 +            var clippingRectangle = OxyRect.Create(
  17.359 +                this.ClipByXAxis ? this.XAxis.ScreenMin.X : PlotModel.PlotArea.Left,
  17.360 +                this.ClipByYAxis ? this.YAxis.ScreenMin.Y : PlotModel.PlotArea.Top,
  17.361 +                this.ClipByXAxis ? this.XAxis.ScreenMax.X : PlotModel.PlotArea.Right,
  17.362 +                this.ClipByYAxis ? this.YAxis.ScreenMax.Y : PlotModel.PlotArea.Bottom);
  17.363 +
  17.364 +            const double MinimumSegmentLength = 4;
  17.365 +
  17.366 +            IList<ScreenPoint> clippedPoints = null;
  17.367 +
  17.368 +            rc.DrawClippedLine(
  17.369 +               this.screenPoints,
  17.370 +               clippingRectangle,
  17.371 +               MinimumSegmentLength * MinimumSegmentLength,
  17.372 +               this.GetSelectableColor(this.Color),
  17.373 +               this.StrokeThickness,
  17.374 +               this.LineStyle,
  17.375 +                this.LineJoin,
  17.376 +                aliased,
  17.377 +                pts => clippedPoints = pts);
  17.378 +
  17.379 +            ScreenPoint position;
  17.380 +            double angle;
  17.381 +            double margin = this.TextMargin;
  17.382 +
  17.383 +            if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
  17.384 +            {
  17.385 +                margin = 0;
  17.386 +            }
  17.387 +            else
  17.388 +            {
  17.389 +                margin *= this.TextPosition < 0.5 ? 1 : -1;
  17.390 +            }
  17.391 +
  17.392 +            if (clippedPoints != null && GetPointAtRelativeDistance(clippedPoints, this.TextPosition, margin, out position, out angle))
  17.393 +            {
  17.394 +                if (angle < -90)
  17.395 +                {
  17.396 +                    angle += 180;
  17.397 +                }
  17.398 +
  17.399 +                if (angle > 90)
  17.400 +                {
  17.401 +                    angle -= 180;
  17.402 +                }
  17.403 +
  17.404 +                switch (this.TextOrientation)
  17.405 +                {
  17.406 +                    case AnnotationTextOrientation.Horizontal:
  17.407 +                        angle = 0;
  17.408 +                        break;
  17.409 +                    case AnnotationTextOrientation.Vertical:
  17.410 +                        angle = -90;
  17.411 +                        break;
  17.412 +                }
  17.413 +
  17.414 +                // Apply 'padding' to the position
  17.415 +                var angleInRadians = angle / 180 * Math.PI;
  17.416 +                var f = 1;
  17.417 +
  17.418 +                if (this.TextHorizontalAlignment == HorizontalAlignment.Right)
  17.419 +                {
  17.420 +                    f = -1;
  17.421 +                }
  17.422 +
  17.423 +                if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
  17.424 +                {
  17.425 +                    f = 0;
  17.426 +                }
  17.427 +
  17.428 +                position.X += f * this.TextPadding * Math.Cos(angleInRadians);
  17.429 +                position.Y += f * this.TextPadding * Math.Sin(angleInRadians);
  17.430 +
  17.431 +                var cs = new CohenSutherlandClipping(clippingRectangle);
  17.432 +                if (!string.IsNullOrEmpty(this.Text) && cs.IsInside(position))
  17.433 +                {
  17.434 +                    rc.DrawClippedText(
  17.435 +                        clippingRectangle,
  17.436 +                        position,
  17.437 +                        this.Text,
  17.438 +                        this.ActualTextColor,
  17.439 +                        this.ActualFont,
  17.440 +                        this.ActualFontSize,
  17.441 +                        this.ActualFontWeight,
  17.442 +                        angle,
  17.443 +                        this.TextHorizontalAlignment,
  17.444 +                        this.TextVerticalAlignment);
  17.445 +                }
  17.446 +            }
  17.447 +        }
  17.448 +
  17.449 +        /// <summary>
  17.450 +        /// Tests if the plot element is hit by the specified point.
  17.451 +        /// </summary>
  17.452 +        /// <param name="point">The point.</param>
  17.453 +        /// <param name="tolerance">The tolerance.</param>
  17.454 +        /// <returns>
  17.455 +        /// A hit test result.
  17.456 +        /// </returns>
  17.457 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  17.458 +        {
  17.459 +            var nearestPoint = ScreenPointHelper.FindNearestPointOnPolyline(point, this.screenPoints);
  17.460 +            double dist = (point - nearestPoint).Length;
  17.461 +            if (dist < tolerance)
  17.462 +            {
  17.463 +                return new HitTestResult(nearestPoint);
  17.464 +            }
  17.465 +
  17.466 +            return null;
  17.467 +        }
  17.468 +
  17.469 +        /// <summary>
  17.470 +        /// Gets the point on a curve at the specified relative distance along the curve.
  17.471 +        /// </summary>
  17.472 +        /// <param name="pts">
  17.473 +        /// The curve points.
  17.474 +        /// </param>
  17.475 +        /// <param name="p">
  17.476 +        /// The relative distance along the curve.
  17.477 +        /// </param>
  17.478 +        /// <param name="margin">
  17.479 +        /// The margins.
  17.480 +        /// </param>
  17.481 +        /// <param name="position">
  17.482 +        /// The position.
  17.483 +        /// </param>
  17.484 +        /// <param name="angle">
  17.485 +        /// The angle.
  17.486 +        /// </param>
  17.487 +        /// <returns>
  17.488 +        /// True if a position was found.
  17.489 +        /// </returns>
  17.490 +        private static bool GetPointAtRelativeDistance(
  17.491 +            IList<ScreenPoint> pts, double p, double margin, out ScreenPoint position, out double angle)
  17.492 +        {
  17.493 +            if (pts == null || pts.Count == 0)
  17.494 +            {
  17.495 +                position = new ScreenPoint();
  17.496 +                angle = 0;
  17.497 +                return false;
  17.498 +            }
  17.499 +
  17.500 +            double length = 0;
  17.501 +            for (int i = 1; i < pts.Count; i++)
  17.502 +            {
  17.503 +                length += (pts[i] - pts[i - 1]).Length;
  17.504 +            }
  17.505 +
  17.506 +            double l = (length * p) + margin;
  17.507 +            length = 0;
  17.508 +            for (int i = 1; i < pts.Count; i++)
  17.509 +            {
  17.510 +                double dl = (pts[i] - pts[i - 1]).Length;
  17.511 +                if (l >= length && l <= length + dl)
  17.512 +                {
  17.513 +                    double f = (l - length) / dl;
  17.514 +                    double x = (pts[i].X * f) + (pts[i - 1].X * (1 - f));
  17.515 +                    double y = (pts[i].Y * f) + (pts[i - 1].Y * (1 - f));
  17.516 +                    position = new ScreenPoint(x, y);
  17.517 +                    double dx = pts[i].X - pts[i - 1].X;
  17.518 +                    double dy = pts[i].Y - pts[i - 1].Y;
  17.519 +                    angle = Math.Atan2(dy, dx) / Math.PI * 180;
  17.520 +                    return true;
  17.521 +                }
  17.522 +
  17.523 +                length += dl;
  17.524 +            }
  17.525 +
  17.526 +            position = pts[0];
  17.527 +            angle = 0;
  17.528 +            return false;
  17.529 +        }
  17.530 +    }
  17.531 +}
  17.532 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/External/OxyPlot/OxyPlot/Annotations/LineAnnotationType.cs	Sat Jun 08 16:53:22 2013 +0000
    18.3 @@ -0,0 +1,62 @@
    18.4 +// --------------------------------------------------------------------------------------------------------------------
    18.5 +// <copyright file="LineAnnotationType.cs" company="OxyPlot">
    18.6 +//   The MIT License (MIT)
    18.7 +//
    18.8 +//   Copyright (c) 2012 Oystein Bjorke
    18.9 +//
   18.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   18.11 +//   copy of this software and associated documentation files (the
   18.12 +//   "Software"), to deal in the Software without restriction, including
   18.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   18.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   18.15 +//   permit persons to whom the Software is furnished to do so, subject to
   18.16 +//   the following conditions:
   18.17 +//
   18.18 +//   The above copyright notice and this permission notice shall be included
   18.19 +//   in all copies or substantial portions of the Software.
   18.20 +//
   18.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   18.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   18.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   18.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   18.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   18.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   18.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   18.28 +// </copyright>
   18.29 +// <summary>
   18.30 +//   The line annotation type.
   18.31 +// </summary>
   18.32 +// --------------------------------------------------------------------------------------------------------------------
   18.33 +namespace OxyPlot.Annotations
   18.34 +{
   18.35 +    /// <summary>
   18.36 +    /// Specifies the definition of the line in a <see cref="LineAnnotation"/>.
   18.37 +    /// </summary>
   18.38 +    public enum LineAnnotationType
   18.39 +    {
   18.40 +        /// <summary>
   18.41 +        /// Horizontal line given by the Y property
   18.42 +        /// </summary>
   18.43 +        Horizontal,
   18.44 +
   18.45 +        /// <summary>
   18.46 +        /// Vertical line given by the X property
   18.47 +        /// </summary>
   18.48 +        Vertical,
   18.49 +
   18.50 +        /// <summary>
   18.51 +        /// Linear equation y=mx+b given by the Slope and Intercept properties
   18.52 +        /// </summary>
   18.53 +        LinearEquation,
   18.54 +
   18.55 +        /// <summary>
   18.56 +        /// Curve equation x=f(y) given by the Equation property
   18.57 +        /// </summary>
   18.58 +        EquationX,
   18.59 +
   18.60 +        /// <summary>
   18.61 +        /// Curve equation y=f(x) given by the Equation property
   18.62 +        /// </summary>
   18.63 +        EquationY
   18.64 +    }
   18.65 +}
   18.66 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/External/OxyPlot/OxyPlot/Annotations/PolygonAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    19.3 @@ -0,0 +1,166 @@
    19.4 +// --------------------------------------------------------------------------------------------------------------------
    19.5 +// <copyright file="PolygonAnnotation.cs" company="OxyPlot">
    19.6 +//   The MIT License (MIT)
    19.7 +//   
    19.8 +//   Copyright (c) 2012 Oystein Bjorke
    19.9 +//   
   19.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   19.11 +//   copy of this software and associated documentation files (the
   19.12 +//   "Software"), to deal in the Software without restriction, including
   19.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   19.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   19.15 +//   permit persons to whom the Software is furnished to do so, subject to
   19.16 +//   the following conditions:
   19.17 +//   
   19.18 +//   The above copyright notice and this permission notice shall be included
   19.19 +//   in all copies or substantial portions of the Software.
   19.20 +//   
   19.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   19.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   19.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   19.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   19.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   19.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   19.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   19.28 +// </copyright>
   19.29 +// <summary>
   19.30 +//   Represents a polygon annotation.
   19.31 +// </summary>
   19.32 +// --------------------------------------------------------------------------------------------------------------------
   19.33 +namespace OxyPlot.Annotations
   19.34 +{
   19.35 +    using System.Collections.Generic;
   19.36 +    using System.Linq;
   19.37 +
   19.38 +    /// <summary>
   19.39 +    /// Represents a polygon annotation.
   19.40 +    /// </summary>
   19.41 +    public class PolygonAnnotation : TextualAnnotation
   19.42 +    {
   19.43 +        /// <summary>
   19.44 +        /// The polygon points transformed to screen coordinates.
   19.45 +        /// </summary>
   19.46 +        private IList<ScreenPoint> screenPoints;
   19.47 +
   19.48 +        /// <summary>
   19.49 +        /// Initializes a new instance of the <see cref="PolygonAnnotation"/> class.
   19.50 +        /// </summary>
   19.51 +        public PolygonAnnotation()
   19.52 +        {
   19.53 +            this.Color = OxyColors.Blue;
   19.54 +            this.Fill = OxyColors.LightBlue;
   19.55 +            this.StrokeThickness = 1;
   19.56 +            this.LineStyle = LineStyle.Solid;
   19.57 +            this.LineJoin = OxyPenLineJoin.Miter;
   19.58 +        }
   19.59 +
   19.60 +        /// <summary>
   19.61 +        /// Gets or sets the color of the line.
   19.62 +        /// </summary>
   19.63 +        public OxyColor Color { get; set; }
   19.64 +
   19.65 +        /// <summary>
   19.66 +        /// Gets or sets the fill color.
   19.67 +        /// </summary>
   19.68 +        /// <value> The fill. </value>
   19.69 +        public OxyColor Fill { get; set; }
   19.70 +
   19.71 +        /// <summary>
   19.72 +        /// Gets or sets the line join.
   19.73 +        /// </summary>
   19.74 +        /// <value> The line join. </value>
   19.75 +        public OxyPenLineJoin LineJoin { get; set; }
   19.76 +
   19.77 +        /// <summary>
   19.78 +        /// Gets or sets the line style.
   19.79 +        /// </summary>
   19.80 +        /// <value> The line style. </value>
   19.81 +        public LineStyle LineStyle { get; set; }
   19.82 +
   19.83 +        /// <summary>
   19.84 +        /// Gets or sets the points.
   19.85 +        /// </summary>
   19.86 +        /// <value> The points. </value>
   19.87 +        public IList<DataPoint> Points { get; set; }
   19.88 +
   19.89 +        /// <summary>
   19.90 +        /// Gets or sets the stroke thickness.
   19.91 +        /// </summary>
   19.92 +        /// <value> The stroke thickness. </value>
   19.93 +        public double StrokeThickness { get; set; }
   19.94 +
   19.95 +        /// <summary>
   19.96 +        /// Renders the polygon annotation.
   19.97 +        /// </summary>
   19.98 +        /// <param name="rc">
   19.99 +        /// The render context.
  19.100 +        /// </param>
  19.101 +        /// <param name="model">
  19.102 +        /// The plot model.
  19.103 +        /// </param>
  19.104 +        public override void Render(IRenderContext rc, PlotModel model)
  19.105 +        {
  19.106 +            base.Render(rc, model);
  19.107 +            if (this.Points == null)
  19.108 +            {
  19.109 +                return;
  19.110 +            }
  19.111 +
  19.112 +            // transform to screen coordinates
  19.113 +            this.screenPoints = this.Points.Select(p => this.Transform(p)).ToList();
  19.114 +            if (this.screenPoints.Count == 0)
  19.115 +            {
  19.116 +                return;
  19.117 +            }
  19.118 +
  19.119 +            // clip to the area defined by the axes
  19.120 +            var clipping = this.GetClippingRect();
  19.121 +
  19.122 +            const double MinimumSegmentLength = 4;
  19.123 +
  19.124 +            rc.DrawClippedPolygon(
  19.125 +                this.screenPoints, 
  19.126 +                clipping, 
  19.127 +                MinimumSegmentLength * MinimumSegmentLength, 
  19.128 +                this.GetSelectableFillColor(this.Fill), 
  19.129 +                this.GetSelectableColor(this.Color), 
  19.130 +                this.StrokeThickness, 
  19.131 +                this.LineStyle, 
  19.132 +                this.LineJoin);
  19.133 +
  19.134 +            if (!string.IsNullOrEmpty(this.Text))
  19.135 +            {
  19.136 +                var textPosition = ScreenPointHelper.GetCentroid(this.screenPoints);
  19.137 +
  19.138 +                rc.DrawClippedText(
  19.139 +                    clipping, 
  19.140 +                    textPosition, 
  19.141 +                    this.Text, 
  19.142 +                    this.ActualTextColor, 
  19.143 +                    this.ActualFont, 
  19.144 +                    this.ActualFontSize, 
  19.145 +                    this.ActualFontWeight, 
  19.146 +                    0, 
  19.147 +                    HorizontalAlignment.Center, 
  19.148 +                    VerticalAlignment.Middle);
  19.149 +            }
  19.150 +        }
  19.151 +
  19.152 +        /// <summary>
  19.153 +        /// Tests if the plot element is hit by the specified point.
  19.154 +        /// </summary>
  19.155 +        /// <param name="point">
  19.156 +        /// The point.
  19.157 +        /// </param>
  19.158 +        /// <param name="tolerance">
  19.159 +        /// The tolerance.
  19.160 +        /// </param>
  19.161 +        /// <returns>
  19.162 +        /// A hit test result.
  19.163 +        /// </returns>
  19.164 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  19.165 +        {
  19.166 +            return ScreenPointHelper.IsPointInPolygon(point, this.screenPoints) ? new HitTestResult(point) : null;
  19.167 +        }
  19.168 +    }
  19.169 +}
  19.170 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/External/OxyPlot/OxyPlot/Annotations/RectangleAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    20.3 @@ -0,0 +1,174 @@
    20.4 +// --------------------------------------------------------------------------------------------------------------------
    20.5 +// <copyright file="RectangleAnnotation.cs" company="OxyPlot">
    20.6 +//   The MIT License (MIT)
    20.7 +//   
    20.8 +//   Copyright (c) 2012 Oystein Bjorke
    20.9 +//   
   20.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   20.11 +//   copy of this software and associated documentation files (the
   20.12 +//   "Software"), to deal in the Software without restriction, including
   20.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   20.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   20.15 +//   permit persons to whom the Software is furnished to do so, subject to
   20.16 +//   the following conditions:
   20.17 +//   
   20.18 +//   The above copyright notice and this permission notice shall be included
   20.19 +//   in all copies or substantial portions of the Software.
   20.20 +//   
   20.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   20.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   20.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   20.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   20.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   20.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   20.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   20.28 +// </copyright>
   20.29 +// <summary>
   20.30 +//   Represents a rectangle annotation.
   20.31 +// </summary>
   20.32 +// --------------------------------------------------------------------------------------------------------------------
   20.33 +namespace OxyPlot.Annotations
   20.34 +{
   20.35 +    /// <summary>
   20.36 +    /// Represents a rectangle annotation.
   20.37 +    /// </summary>
   20.38 +    public class RectangleAnnotation : TextualAnnotation
   20.39 +    {
   20.40 +        /// <summary>
   20.41 +        /// The rectangle transformed to screen coordinates.
   20.42 +        /// </summary>
   20.43 +        private OxyRect screenRectangle;
   20.44 +
   20.45 +        /// <summary>
   20.46 +        /// Initializes a new instance of the <see cref="RectangleAnnotation"/> class.
   20.47 +        /// </summary>
   20.48 +        public RectangleAnnotation()
   20.49 +        {
   20.50 +            this.Stroke = OxyColors.Black;
   20.51 +            this.Fill = OxyColors.LightBlue;
   20.52 +            this.MinimumX = double.MinValue;
   20.53 +            this.MaximumX = double.MaxValue;
   20.54 +            this.MinimumY = double.MinValue;
   20.55 +            this.MaximumY = double.MaxValue;
   20.56 +            this.TextRotation = 0;
   20.57 +        }
   20.58 +
   20.59 +        /// <summary>
   20.60 +        /// Gets or sets the fill color.
   20.61 +        /// </summary>
   20.62 +        /// <value> The fill. </value>
   20.63 +        public OxyColor Fill { get; set; }
   20.64 +
   20.65 +        /// <summary>
   20.66 +        /// Gets or sets the stroke color.
   20.67 +        /// </summary>
   20.68 +        public OxyColor Stroke { get; set; }
   20.69 +
   20.70 +        /// <summary>
   20.71 +        /// Gets or sets the stroke thickness.
   20.72 +        /// </summary>
   20.73 +        public double StrokeThickness { get; set; }
   20.74 +
   20.75 +        /// <summary>
   20.76 +        /// Gets or sets the minimum X.
   20.77 +        /// </summary>
   20.78 +        /// <value>The minimum X.</value>
   20.79 +        public double MinimumX { get; set; }
   20.80 +
   20.81 +        /// <summary>
   20.82 +        /// Gets or sets the maximum X.
   20.83 +        /// </summary>
   20.84 +        /// <value>The maximum X.</value>
   20.85 +        public double MaximumX { get; set; }
   20.86 +
   20.87 +        /// <summary>
   20.88 +        /// Gets or sets the minimum Y.
   20.89 +        /// </summary>
   20.90 +        /// <value>The minimum Y.</value>
   20.91 +        public double MinimumY { get; set; }
   20.92 +
   20.93 +        /// <summary>
   20.94 +        /// Gets or sets the maximum Y.
   20.95 +        /// </summary>
   20.96 +        /// <value>The maximum Y.</value>
   20.97 +        public double MaximumY { get; set; }
   20.98 +
   20.99 +        /// <summary>
  20.100 +        /// Gets or sets the text rotation (degrees).
  20.101 +        /// </summary>
  20.102 +        /// <value>The text rotation in degrees.</value>
  20.103 +        public double TextRotation { get; set; }
  20.104 +
  20.105 +        /// <summary>
  20.106 +        /// Renders the polygon annotation.
  20.107 +        /// </summary>
  20.108 +        /// <param name="rc">
  20.109 +        /// The render context.
  20.110 +        /// </param>
  20.111 +        /// <param name="model">
  20.112 +        /// The plot model.
  20.113 +        /// </param>
  20.114 +        public override void Render(IRenderContext rc, PlotModel model)
  20.115 +        {
  20.116 +            base.Render(rc, model);
  20.117 +
  20.118 +            double x0 = double.IsNaN(this.MinimumX) || this.MinimumX.Equals(double.MinValue)
  20.119 +                            ? this.XAxis.ActualMinimum
  20.120 +                            : this.MinimumX;
  20.121 +            double x1 = double.IsNaN(this.MaximumX) || this.MaximumX.Equals(double.MaxValue)
  20.122 +                            ? this.XAxis.ActualMaximum
  20.123 +                            : this.MaximumX;
  20.124 +            double y0 = double.IsNaN(this.MinimumY) || this.MinimumY.Equals(double.MinValue)
  20.125 +                            ? this.YAxis.ActualMinimum
  20.126 +                            : this.MinimumY;
  20.127 +            double y1 = double.IsNaN(this.MaximumY) || this.MaximumY.Equals(double.MaxValue)
  20.128 +                            ? this.YAxis.ActualMaximum
  20.129 +                            : this.MaximumY;
  20.130 +
  20.131 +            this.screenRectangle = OxyRect.Create(this.Transform(x0, y0), this.Transform(x1, y1));
  20.132 +
  20.133 +            // clip to the area defined by the axes
  20.134 +            var clipping = this.GetClippingRect();
  20.135 +
  20.136 +            rc.DrawClippedRectangle(this.screenRectangle, clipping, this.Fill, this.Stroke, this.StrokeThickness);
  20.137 +
  20.138 +            if (!string.IsNullOrEmpty(this.Text))
  20.139 +            {
  20.140 +                var textPosition = this.screenRectangle.Center;
  20.141 +                rc.DrawClippedText(
  20.142 +                    clipping, 
  20.143 +                    textPosition, 
  20.144 +                    this.Text, 
  20.145 +                    this.ActualTextColor, 
  20.146 +                    this.ActualFont, 
  20.147 +                    this.ActualFontSize, 
  20.148 +                    this.ActualFontWeight, 
  20.149 +                    this.TextRotation, 
  20.150 +                    HorizontalAlignment.Center, 
  20.151 +                    VerticalAlignment.Middle);
  20.152 +            }
  20.153 +        }
  20.154 +
  20.155 +        /// <summary>
  20.156 +        /// Tests if the plot element is hit by the specified point.
  20.157 +        /// </summary>
  20.158 +        /// <param name="point">
  20.159 +        /// The point.
  20.160 +        /// </param>
  20.161 +        /// <param name="tolerance">
  20.162 +        /// The tolerance.
  20.163 +        /// </param>
  20.164 +        /// <returns>
  20.165 +        /// A hit test result.
  20.166 +        /// </returns>
  20.167 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  20.168 +        {
  20.169 +            if (this.screenRectangle.Contains(point))
  20.170 +            {
  20.171 +                return new HitTestResult(point);
  20.172 +            }
  20.173 +
  20.174 +            return null;
  20.175 +        }
  20.176 +    }
  20.177 +}
  20.178 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/External/OxyPlot/OxyPlot/Annotations/TextAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    21.3 @@ -0,0 +1,254 @@
    21.4 +// --------------------------------------------------------------------------------------------------------------------
    21.5 +// <copyright file="TextAnnotation.cs" company="OxyPlot">
    21.6 +//   The MIT License (MIT)
    21.7 +//   
    21.8 +//   Copyright (c) 2012 Oystein Bjorke
    21.9 +//   
   21.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   21.11 +//   copy of this software and associated documentation files (the
   21.12 +//   "Software"), to deal in the Software without restriction, including
   21.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   21.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   21.15 +//   permit persons to whom the Software is furnished to do so, subject to
   21.16 +//   the following conditions:
   21.17 +//   
   21.18 +//   The above copyright notice and this permission notice shall be included
   21.19 +//   in all copies or substantial portions of the Software.
   21.20 +//   
   21.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   21.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   21.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   21.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   21.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   21.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   21.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   21.28 +// </copyright>
   21.29 +// <summary>
   21.30 +//   Represents a text object annotation.
   21.31 +// </summary>
   21.32 +// --------------------------------------------------------------------------------------------------------------------
   21.33 +namespace OxyPlot.Annotations
   21.34 +{
   21.35 +    using System;
   21.36 +    using System.Collections.Generic;
   21.37 +
   21.38 +    /// <summary>
   21.39 +    /// Represents a text annotation.
   21.40 +    /// </summary>
   21.41 +    public class TextAnnotation : TextualAnnotation
   21.42 +    {
   21.43 +        /// <summary>
   21.44 +        /// The actual bounds of the text.
   21.45 +        /// </summary>
   21.46 +        private IList<ScreenPoint> actualBounds;
   21.47 +
   21.48 +        /// <summary>
   21.49 +        /// Initializes a new instance of the <see cref="TextAnnotation" /> class.
   21.50 +        /// </summary>
   21.51 +        public TextAnnotation()
   21.52 +        {
   21.53 +            this.TextColor = OxyColors.Blue;
   21.54 +            this.Stroke = OxyColors.Black;
   21.55 +            this.Background = null;
   21.56 +            this.StrokeThickness = 1;
   21.57 +            this.Rotation = 0;
   21.58 +            this.HorizontalAlignment = OxyPlot.HorizontalAlignment.Center;
   21.59 +            this.VerticalAlignment = OxyPlot.VerticalAlignment.Bottom;
   21.60 +            this.Padding = new OxyThickness(4);
   21.61 +        }
   21.62 +
   21.63 +        /// <summary>
   21.64 +        /// Gets or sets the fill color of the background rectangle.
   21.65 +        /// </summary>
   21.66 +        /// <value> The background. </value>
   21.67 +        public OxyColor Background { get; set; }
   21.68 +
   21.69 +        /// <summary>
   21.70 +        /// Gets or sets the horizontal alignment.
   21.71 +        /// </summary>
   21.72 +        /// <value> The horizontal alignment. </value>
   21.73 +        public HorizontalAlignment HorizontalAlignment { get; set; }
   21.74 +
   21.75 +        /// <summary>
   21.76 +        /// Gets or sets the position offset (screen coordinates).
   21.77 +        /// </summary>
   21.78 +        /// <value> The offset. </value>
   21.79 +        public ScreenVector Offset { get; set; }
   21.80 +
   21.81 +        /// <summary>
   21.82 +        /// Gets or sets the padding of the background rectangle.
   21.83 +        /// </summary>
   21.84 +        /// <value> The padding. </value>
   21.85 +        public OxyThickness Padding { get; set; }
   21.86 +
   21.87 +        /// <summary>
   21.88 +        /// Gets or sets the position of the text.
   21.89 +        /// </summary>
   21.90 +        public DataPoint Position { get; set; }
   21.91 +
   21.92 +        /// <summary>
   21.93 +        /// Gets or sets the rotation angle (degrees).
   21.94 +        /// </summary>
   21.95 +        /// <value> The rotation. </value>
   21.96 +        public double Rotation { get; set; }
   21.97 +
   21.98 +        /// <summary>
   21.99 +        /// Gets or sets the stroke color of the background rectangle.
  21.100 +        /// </summary>
  21.101 +        /// <value> The stroke color. </value>
  21.102 +        public OxyColor Stroke { get; set; }
  21.103 +
  21.104 +        /// <summary>
  21.105 +        /// Gets or sets the stroke thickness of the background rectangle.
  21.106 +        /// </summary>
  21.107 +        /// <value> The stroke thickness. </value>
  21.108 +        public double StrokeThickness { get; set; }
  21.109 +
  21.110 +        /// <summary>
  21.111 +        /// Gets or sets the vertical alignment.
  21.112 +        /// </summary>
  21.113 +        /// <value> The vertical alignment. </value>
  21.114 +        public VerticalAlignment VerticalAlignment { get; set; }
  21.115 +
  21.116 +        /// <summary>
  21.117 +        /// Renders the text annotation.
  21.118 +        /// </summary>
  21.119 +        /// <param name="rc">
  21.120 +        /// The render context.
  21.121 +        /// </param>
  21.122 +        /// <param name="model">
  21.123 +        /// The plot model.
  21.124 +        /// </param>
  21.125 +        public override void Render(IRenderContext rc, PlotModel model)
  21.126 +        {
  21.127 +            base.Render(rc, model);
  21.128 +
  21.129 +            var position = this.Transform(this.Position);
  21.130 +            position.X += this.Offset.X;
  21.131 +            position.Y += this.Offset.Y;
  21.132 +
  21.133 +            var clippingRect = this.GetClippingRect();
  21.134 +
  21.135 +            var textSize = rc.MeasureText(this.Text, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
  21.136 +
  21.137 +            const double MinDistSquared = 4;
  21.138 +
  21.139 +            this.actualBounds = GetTextBounds(
  21.140 +                position, textSize, this.Padding, this.Rotation, this.HorizontalAlignment, this.VerticalAlignment);
  21.141 +            rc.DrawClippedPolygon(
  21.142 +                this.actualBounds, clippingRect, MinDistSquared, this.Background, this.Stroke, this.StrokeThickness);
  21.143 +
  21.144 +            rc.DrawClippedText(
  21.145 +                clippingRect,
  21.146 +                position,
  21.147 +                this.Text,
  21.148 +                this.GetSelectableFillColor(this.ActualTextColor),
  21.149 +                this.ActualFont,
  21.150 +                this.ActualFontSize,
  21.151 +                this.ActualFontWeight,
  21.152 +                this.Rotation,
  21.153 +                this.HorizontalAlignment,
  21.154 +                this.VerticalAlignment);
  21.155 +        }
  21.156 +
  21.157 +        /// <summary>
  21.158 +        /// Tests if the plot element is hit by the specified point.
  21.159 +        /// </summary>
  21.160 +        /// <param name="point">
  21.161 +        /// The point.
  21.162 +        /// </param>
  21.163 +        /// <param name="tolerance">
  21.164 +        /// The tolerance.
  21.165 +        /// </param>
  21.166 +        /// <returns>
  21.167 +        /// A hit test result.
  21.168 +        /// </returns>
  21.169 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  21.170 +        {
  21.171 +            if (this.actualBounds == null)
  21.172 +            {
  21.173 +                return null;
  21.174 +            }
  21.175 +
  21.176 +            // Todo: see if performance can be improved by checking rectangle (with rotation and alignment), not polygon
  21.177 +            return ScreenPointHelper.IsPointInPolygon(point, this.actualBounds) ? new HitTestResult(point) : null;
  21.178 +        }
  21.179 +
  21.180 +        /// <summary>
  21.181 +        /// Gets the coordinates of the (rotated) background rectangle.
  21.182 +        /// </summary>
  21.183 +        /// <param name="position">
  21.184 +        /// The position.
  21.185 +        /// </param>
  21.186 +        /// <param name="size">
  21.187 +        /// The size.
  21.188 +        /// </param>
  21.189 +        /// <param name="padding">
  21.190 +        /// The padding.
  21.191 +        /// </param>
  21.192 +        /// <param name="rotation">
  21.193 +        /// The rotation.
  21.194 +        /// </param>
  21.195 +        /// <param name="horizontalAlignment">
  21.196 +        /// The horizontal alignment.
  21.197 +        /// </param>
  21.198 +        /// <param name="verticalAlignment">
  21.199 +        /// The vertical alignment.
  21.200 +        /// </param>
  21.201 +        /// <returns>
  21.202 +        /// The background rectangle coordinates.
  21.203 +        /// </returns>
  21.204 +        private static IList<ScreenPoint> GetTextBounds(
  21.205 +            ScreenPoint position,
  21.206 +            OxySize size,
  21.207 +            OxyThickness padding,
  21.208 +            double rotation,
  21.209 +            HorizontalAlignment horizontalAlignment,
  21.210 +            VerticalAlignment verticalAlignment)
  21.211 +        {
  21.212 +            double left, right, top, bottom;
  21.213 +            switch (horizontalAlignment)
  21.214 +            {
  21.215 +                case HorizontalAlignment.Center:
  21.216 +                    left = -size.Width * 0.5;
  21.217 +                    right = -left;
  21.218 +                    break;
  21.219 +                case HorizontalAlignment.Right:
  21.220 +                    left = -size.Width;
  21.221 +                    right = 0;
  21.222 +                    break;
  21.223 +                default:
  21.224 +                    left = 0;
  21.225 +                    right = size.Width;
  21.226 +                    break;
  21.227 +            }
  21.228 +
  21.229 +            switch (verticalAlignment)
  21.230 +            {
  21.231 +                case VerticalAlignment.Middle:
  21.232 +                    top = -size.Height * 0.5;
  21.233 +                    bottom = -top;
  21.234 +                    break;
  21.235 +                case VerticalAlignment.Bottom:
  21.236 +                    top = -size.Height;
  21.237 +                    bottom = 0;
  21.238 +                    break;
  21.239 +                default:
  21.240 +                    top = 0;
  21.241 +                    bottom = size.Height;
  21.242 +                    break;
  21.243 +            }
  21.244 +
  21.245 +            double cost = Math.Cos(rotation / 180 * Math.PI);
  21.246 +            double sint = Math.Sin(rotation / 180 * Math.PI);
  21.247 +            var u = new ScreenVector(cost, sint);
  21.248 +            var v = new ScreenVector(-sint, cost);
  21.249 +            var polygon = new ScreenPoint[4];
  21.250 +            polygon[0] = position + (u * (left - padding.Left)) + (v * (top - padding.Top));
  21.251 +            polygon[1] = position + (u * (right + padding.Right)) + (v * (top - padding.Top));
  21.252 +            polygon[2] = position + (u * (right + padding.Right)) + (v * (bottom + padding.Bottom));
  21.253 +            polygon[3] = position + (u * (left - padding.Left)) + (v * (bottom + padding.Bottom));
  21.254 +            return polygon;
  21.255 +        }
  21.256 +    }
  21.257 +}
  21.258 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/External/OxyPlot/OxyPlot/Annotations/TextualAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    22.3 @@ -0,0 +1,46 @@
    22.4 +// --------------------------------------------------------------------------------------------------------------------
    22.5 +// <copyright file="TextualAnnotation.cs" company="OxyPlot">
    22.6 +//   The MIT License (MIT)
    22.7 +//   
    22.8 +//   Copyright (c) 2012 Oystein Bjorke
    22.9 +//   
   22.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   22.11 +//   copy of this software and associated documentation files (the
   22.12 +//   "Software"), to deal in the Software without restriction, including
   22.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   22.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   22.15 +//   permit persons to whom the Software is furnished to do so, subject to
   22.16 +//   the following conditions:
   22.17 +//   
   22.18 +//   The above copyright notice and this permission notice shall be included
   22.19 +//   in all copies or substantial portions of the Software.
   22.20 +//   
   22.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   22.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   22.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   22.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   22.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   22.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   22.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   22.28 +// </copyright>
   22.29 +// <summary>
   22.30 +//   Provides an abstract base class for annotations that contains text.
   22.31 +// </summary>
   22.32 +// --------------------------------------------------------------------------------------------------------------------
   22.33 +
   22.34 +namespace OxyPlot.Annotations
   22.35 +{
   22.36 +    /// <summary>
   22.37 +    /// Provides an abstract base class for annotations that contains text.
   22.38 +    /// </summary>
   22.39 +    public abstract class TextualAnnotation : Annotation
   22.40 +    {
   22.41 +        /// <summary>
   22.42 +        /// Gets or sets the annotation text.
   22.43 +        /// </summary>
   22.44 +        /// <value>
   22.45 +        /// The text.
   22.46 +        /// </value>
   22.47 +        public string Text { get; set; }
   22.48 +    }
   22.49 +}
   22.50 \ No newline at end of file
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/External/OxyPlot/OxyPlot/Annotations/TileMapAnnotation.cs	Sat Jun 08 16:53:22 2013 +0000
    23.3 @@ -0,0 +1,457 @@
    23.4 +// --------------------------------------------------------------------------------------------------------------------
    23.5 +// <copyright file="TileMapAnnotation.cs" company="OxyPlot">
    23.6 +//   The MIT License (MIT)
    23.7 +//   
    23.8 +//   Copyright (c) 2012 Oystein Bjorke
    23.9 +//   
   23.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   23.11 +//   copy of this software and associated documentation files (the
   23.12 +//   "Software"), to deal in the Software without restriction, including
   23.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   23.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   23.15 +//   permit persons to whom the Software is furnished to do so, subject to
   23.16 +//   the following conditions:
   23.17 +//   
   23.18 +//   The above copyright notice and this permission notice shall be included
   23.19 +//   in all copies or substantial portions of the Software.
   23.20 +//   
   23.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   23.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   23.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   23.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   23.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   23.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   23.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   23.28 +// </copyright>
   23.29 +// <summary>
   23.30 +//   Provides a tile map annotation.
   23.31 +// </summary>
   23.32 +// --------------------------------------------------------------------------------------------------------------------
   23.33 +
   23.34 +namespace OxyPlot.Annotations
   23.35 +{
   23.36 +    using System;
   23.37 +    using System.Collections.Generic;
   23.38 +    using System.Globalization;
   23.39 +    using System.IO;
   23.40 +    using System.Net;
   23.41 +    using System.Threading;
   23.42 +
   23.43 +    /// <summary>
   23.44 +    /// Provides a tile map annotation.
   23.45 +    /// </summary>
   23.46 +    /// <remarks>
   23.47 +    /// The longitude and latitude range of the map is defined by the range of the x and y axis, respectively.
   23.48 +    /// </remarks>
   23.49 +    public class TileMapAnnotation : Annotation
   23.50 +    {
   23.51 +        /// <summary>
   23.52 +        /// The image cache.
   23.53 +        /// </summary>
   23.54 +        private readonly Dictionary<string, OxyImage> images = new Dictionary<string, OxyImage>();
   23.55 +
   23.56 +        /// <summary>
   23.57 +        /// The download queue.
   23.58 +        /// </summary>
   23.59 +        private readonly Queue<string> queue = new Queue<string>();
   23.60 +
   23.61 +        /// <summary>
   23.62 +        /// The current number of downloads
   23.63 +        /// </summary>
   23.64 +        private int numberOfDownloads;
   23.65 +
   23.66 +        /// <summary>
   23.67 +        /// Initializes a new instance of the <see cref="TileMapAnnotation" /> class.
   23.68 +        /// </summary>
   23.69 +        public TileMapAnnotation()
   23.70 +        {
   23.71 +            this.TileSize = 256;
   23.72 +            this.MinZoomLevel = 0;
   23.73 +            this.MaxZoomLevel = 20;
   23.74 +            this.Opacity = 1.0;
   23.75 +            this.MaxNumberOfDownloads = 8;
   23.76 +        }
   23.77 +
   23.78 +        /// <summary>
   23.79 +        /// Gets or sets the max number of simultaneous downloads.
   23.80 +        /// </summary>
   23.81 +        /// <value>
   23.82 +        /// The max number of downloads.
   23.83 +        /// </value>
   23.84 +        public int MaxNumberOfDownloads { get; set; }
   23.85 +
   23.86 +        /// <summary>
   23.87 +        /// Gets or sets the URL.
   23.88 +        /// </summary>
   23.89 +        /// <value>
   23.90 +        /// The URL.
   23.91 +        /// </value>
   23.92 +        public string Url { get; set; }
   23.93 +
   23.94 +        /// <summary>
   23.95 +        /// Gets or sets the copyright notice.
   23.96 +        /// </summary>
   23.97 +        /// <value>
   23.98 +        /// The copyright notice.
   23.99 +        /// </value>
  23.100 +        public string CopyrightNotice { get; set; }
  23.101 +
  23.102 +        /// <summary>
  23.103 +        /// Gets or sets the size of the tiles.
  23.104 +        /// </summary>
  23.105 +        /// <value>
  23.106 +        /// The size of the tiles.
  23.107 +        /// </value>
  23.108 +        public int TileSize { get; set; }
  23.109 +
  23.110 +        /// <summary>
  23.111 +        /// Gets or sets the min zoom level.
  23.112 +        /// </summary>
  23.113 +        /// <value>
  23.114 +        /// The min zoom level.
  23.115 +        /// </value>
  23.116 +        public int MinZoomLevel { get; set; }
  23.117 +
  23.118 +        /// <summary>
  23.119 +        /// Gets or sets the max zoom level.
  23.120 +        /// </summary>
  23.121 +        /// <value>
  23.122 +        /// The max zoom level.
  23.123 +        /// </value>
  23.124 +        public int MaxZoomLevel { get; set; }
  23.125 +
  23.126 +        /// <summary>
  23.127 +        /// Gets or sets the opacity.
  23.128 +        /// </summary>
  23.129 +        /// <value>
  23.130 +        /// The opacity.
  23.131 +        /// </value>
  23.132 +        public double Opacity { get; set; }
  23.133 +
  23.134 +        /// <summary>
  23.135 +        /// Renders the annotation on the specified context.
  23.136 +        /// </summary>
  23.137 +        /// <param name="rc">
  23.138 +        /// The render context.
  23.139 +        /// </param>
  23.140 +        /// <param name="model">
  23.141 +        /// The model.
  23.142 +        /// </param>
  23.143 +        public override void Render(IRenderContext rc, PlotModel model)
  23.144 +        {
  23.145 +            base.Render(rc, model);
  23.146 +            var clippingRect = this.GetClippingRect();
  23.147 +            var lon0 = this.XAxis.ActualMinimum;
  23.148 +            var lon1 = this.XAxis.ActualMaximum;
  23.149 +            var lat0 = this.YAxis.ActualMinimum;
  23.150 +            var lat1 = this.YAxis.ActualMaximum;
  23.151 +
  23.152 +            // the desired number of tiles horizontally
  23.153 +            double tilesx = model.Width / this.TileSize;
  23.154 +
  23.155 +            // calculate the desired zoom level
  23.156 +            var n = tilesx / (((lon1 + 180) / 360) - ((lon0 + 180) / 360));
  23.157 +            var zoom = (int)Math.Round(Math.Log(n) / Math.Log(2));
  23.158 +            if (zoom < this.MinZoomLevel)
  23.159 +            {
  23.160 +                zoom = this.MinZoomLevel;
  23.161 +            }
  23.162 +
  23.163 +            if (zoom > this.MaxZoomLevel)
  23.164 +            {
  23.165 +                zoom = this.MaxZoomLevel;
  23.166 +            }
  23.167 +
  23.168 +            // find tile coordinates for the corners
  23.169 +            double x0, y0;
  23.170 +            LatLonToTile(lat0, lon0, zoom, out x0, out y0);
  23.171 +            double x1, y1;
  23.172 +            LatLonToTile(lat1, lon1, zoom, out x1, out y1);
  23.173 +
  23.174 +            double xmax = Math.Max(x0, x1);
  23.175 +            double xmin = Math.Min(x0, x1);
  23.176 +            double ymax = Math.Max(y0, y1);
  23.177 +            double ymin = Math.Min(y0, y1);
  23.178 +
  23.179 +            // Add the tiles
  23.180 +            for (var x = (int)xmin; x < xmax; x++)
  23.181 +            {
  23.182 +                for (var y = (int)ymin; y < ymax; y++)
  23.183 +                {
  23.184 +                    string uri = this.GetTileUri(x, y, zoom);
  23.185 +                    var img = this.GetImage(uri, rc.RendersToScreen);
  23.186 +
  23.187 +                    if (img == null)
  23.188 +                    {
  23.189 +                        continue;
  23.190 +                    }
  23.191 +
  23.192 +                    // transform from tile coordinates to lat/lon
  23.193 +                    double latitude0, latitude1, longitude0, longitude1;
  23.194 +                    TileToLatLon(x, y, zoom, out latitude0, out longitude0);
  23.195 +                    TileToLatLon(x + 1, y + 1, zoom, out latitude1, out longitude1);
  23.196 +
  23.197 +                    // transform from lat/lon to screen coordinates
  23.198 +                    var s00 = this.Transform(longitude0, latitude0);
  23.199 +                    var s11 = this.Transform(longitude1, latitude1);
  23.200 +
  23.201 +                    var r = OxyRect.Create(s00.X, s00.Y, s11.X, s11.Y);
  23.202 +
  23.203 +                    // draw the image
  23.204 +                    rc.DrawClippedImage(clippingRect, img, r.Left, r.Top, r.Width, r.Height, this.Opacity, true);
  23.205 +                }
  23.206 +            }
  23.207 +
  23.208 +            // draw the copyright notice
  23.209 +            var p = new ScreenPoint(clippingRect.Right - 5, clippingRect.Bottom - 5);
  23.210 +            var textSize = rc.MeasureText(this.CopyrightNotice, null, 12);
  23.211 +            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);
  23.212 +
  23.213 +            rc.DrawText(
  23.214 +                p,
  23.215 +                this.CopyrightNotice,
  23.216 +                OxyColors.Black,
  23.217 +                null,
  23.218 +                12,
  23.219 +                500,
  23.220 +                0,
  23.221 +                HorizontalAlignment.Right,
  23.222 +                VerticalAlignment.Bottom);
  23.223 +        }
  23.224 +
  23.225 +        /// <summary>
  23.226 +        /// Tests if the plot element is hit by the specified point.
  23.227 +        /// </summary>
  23.228 +        /// <param name="point">
  23.229 +        /// The point.
  23.230 +        /// </param>
  23.231 +        /// <param name="tolerance">
  23.232 +        /// The tolerance.
  23.233 +        /// </param>
  23.234 +        /// <returns>
  23.235 +        /// A hit test result.
  23.236 +        /// </returns>
  23.237 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
  23.238 +        {
  23.239 +            return null;
  23.240 +        }
  23.241 +
  23.242 +        /// <summary>
  23.243 +        /// Transforms a position to a tile coordinate.
  23.244 +        /// </summary>
  23.245 +        /// <param name="latitude">The latitude.</param>
  23.246 +        /// <param name="longitude">The longitude.</param>
  23.247 +        /// <param name="zoom">The zoom.</param>
  23.248 +        /// <param name="x">The x.</param>
  23.249 +        /// <param name="y">The y.</param>
  23.250 +        private static void LatLonToTile(double latitude, double longitude, int zoom, out double x, out double y)
  23.251 +        {
  23.252 +            // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames            
  23.253 +            int n = 1 << zoom;
  23.254 +            double lat = latitude / 180 * Math.PI;
  23.255 +            x = (longitude + 180.0) / 360.0 * n;
  23.256 +            y = (1.0 - Math.Log(Math.Tan(lat) + 1.0 / Math.Cos(lat)) / Math.PI) / 2.0 * n;
  23.257 +        }
  23.258 +
  23.259 +        /// <summary>
  23.260 +        /// Transforms a tile coordinate (x,y) to a position.
  23.261 +        /// </summary>
  23.262 +        /// <param name="x">The x.</param>
  23.263 +        /// <param name="y">The y.</param>
  23.264 +        /// <param name="zoom">The zoom.</param>
  23.265 +        /// <param name="latitude">The latitude.</param>
  23.266 +        /// <param name="longitude">The longitude.</param>
  23.267 +        private static void TileToLatLon(double x, double y, int zoom, out double latitude, out double longitude)
  23.268 +        {
  23.269 +            int n = 1 << zoom;
  23.270 +            longitude = (x / n * 360.0) - 180.0;
  23.271 +            double lat = Math.Atan(Math.Sinh(Math.PI * (1 - (2 * y / n))));
  23.272 +            latitude = lat * 180.0 / Math.PI;
  23.273 +        }
  23.274 +
  23.275 +        /// <summary>
  23.276 +        /// Gets the image from the specified uri.
  23.277 +        /// </summary>
  23.278 +        /// <param name="uri">The URI.</param>
  23.279 +        /// <param name="async">Get the image asynchronously if set to <c>true</c>. The plot model will be invalidated when the image has been downloaded.</param>
  23.280 +        /// <returns>
  23.281 +        /// The image.
  23.282 +        /// </returns>
  23.283 +        /// <remarks>
  23.284 +        /// This method gets the image from cache, or starts an async download.
  23.285 +        /// </remarks>
  23.286 +        private OxyImage GetImage(string uri, bool async)
  23.287 +        {
  23.288 +            OxyImage img;
  23.289 +            if (this.images.TryGetValue(uri, out img))
  23.290 +            {
  23.291 +                return img;
  23.292 +            }
  23.293 +
  23.294 +            if (!async)
  23.295 +            {
  23.296 +                return this.Download(uri);
  23.297 +            }
  23.298 +
  23.299 +            lock (this.queue)
  23.300 +            {
  23.301 +                // 'reserve' an image (otherwise multiple downloads of the same uri may happen)
  23.302 +                this.images[uri] = null;
  23.303 +                this.queue.Enqueue(uri);
  23.304 +            }
  23.305 +
  23.306 +            this.BeginDownload();
  23.307 +            return null;
  23.308 +        }
  23.309 +
  23.310 +        /// <summary>
  23.311 +        /// Downloads the image from the specified URI.
  23.312 +        /// </summary>
  23.313 +        /// <param name="uri">The URI.</param>
  23.314 +        /// <returns>The image</returns>
  23.315 +        private OxyImage Download(string uri)
  23.316 +        {
  23.317 +            OxyImage img = null;
  23.318 +            var mre = new ManualResetEvent(false);
  23.319 +            var request = (HttpWebRequest)WebRequest.Create(uri);
  23.320 +            request.Method = "GET";
  23.321 +            request.BeginGetResponse(
  23.322 +               r =>
  23.323 +               {
  23.324 +                   try
  23.325 +                   {
  23.326 +                       if (request.HaveResponse)
  23.327 +                       {
  23.328 +                           var response = request.EndGetResponse(r);
  23.329 +                           var stream = response.GetResponseStream();
  23.330 +
  23.331 +                           var ms = new MemoryStream();
  23.332 +                           stream.CopyTo(ms);
  23.333 +                           var buffer = ms.ToArray();
  23.334 +
  23.335 +                           img = new OxyImage(buffer);
  23.336 +                           this.images[uri] = img;
  23.337 +                       }
  23.338 +
  23.339 +                   }
  23.340 +                   catch (Exception e)
  23.341 +                   {
  23.342 +                       var ie = e;
  23.343 +                       while (ie != null)
  23.344 +                       {
  23.345 +                           System.Diagnostics.Debug.WriteLine(ie.Message);
  23.346 +                           ie = ie.InnerException;
  23.347 +                       }
  23.348 +                   }
  23.349 +                   finally
  23.350 +                   {
  23.351 +                       mre.Set();                       
  23.352 +                   }
  23.353 +               },
  23.354 +               request);
  23.355 +
  23.356 +            mre.WaitOne();
  23.357 +            return img;
  23.358 +        }
  23.359 +
  23.360 +        /// <summary>
  23.361 +        /// Starts the next download in the queue.
  23.362 +        /// </summary>
  23.363 +        private void BeginDownload()
  23.364 +        {
  23.365 +            if (this.numberOfDownloads >= this.MaxNumberOfDownloads)
  23.366 +            {
  23.367 +                return;
  23.368 +            }
  23.369 +
  23.370 +            string uri = this.queue.Dequeue();
  23.371 +            var request = (HttpWebRequest)WebRequest.Create(uri);
  23.372 +            request.Method = "GET";
  23.373 +            Interlocked.Increment(ref this.numberOfDownloads);
  23.374 +            request.BeginGetResponse(
  23.375 +                r =>
  23.376 +                {
  23.377 +                    Interlocked.Decrement(ref this.numberOfDownloads);
  23.378 +                    try
  23.379 +                    {
  23.380 +                        if (request.HaveResponse)
  23.381 +                        {
  23.382 +                            var response = request.EndGetResponse(r);
  23.383 +                            var stream = response.GetResponseStream();
  23.384 +                            this.DownloadCompleted(uri, stream);
  23.385 +                        }
  23.386 +                    }
  23.387 +                    catch (Exception e)
  23.388 +                    {
  23.389 +                        var ie = e;
  23.390 +                        while (ie != null)
  23.391 +                        {
  23.392 +                            System.Diagnostics.Debug.WriteLine(ie.Message);
  23.393 +                            ie = ie.InnerException;
  23.394 +                        }
  23.395 +                    }
  23.396 +                },
  23.397 +                request);
  23.398 +        }
  23.399 +
  23.400 +        /// <summary>
  23.401 +        /// The download completed, set the image.
  23.402 +        /// </summary>
  23.403 +        /// <param name="uri">The URI.</param>
  23.404 +        /// <param name="result">The result.</param>
  23.405 +        private void DownloadCompleted(string uri, Stream result)
  23.406 +        {
  23.407 +            if (result == null)
  23.408 +            {
  23.409 +                return;
  23.410 +            }
  23.411 +
  23.412 +            var ms = new MemoryStream();
  23.413 +            result.CopyTo(ms);
  23.414 +            var buffer = ms.ToArray();
  23.415 +
  23.416 +            var img = new OxyImage(buffer);
  23.417 +            this.images[uri] = img;
  23.418 +
  23.419 +            lock (this.queue)
  23.420 +            {
  23.421 +                // Clear old items in the queue, new ones will be added when the plot is refreshed
  23.422 +                foreach (var queuedUri in this.queue)
  23.423 +                {
  23.424 +                    // Remove the 'reserved' image
  23.425 +                    this.images.Remove(queuedUri);
  23.426 +                }
  23.427 +
  23.428 +                this.queue.Clear();
  23.429 +            }
  23.430 +
  23.431 +            this.PlotModel.InvalidatePlot(false);
  23.432 +            if (this.queue.Count > 0)
  23.433 +            {
  23.434 +                this.BeginDownload();
  23.435 +            }
  23.436 +        }
  23.437 +
  23.438 +        /// <summary>
  23.439 +        /// Gets the tile URI.
  23.440 +        /// </summary>
  23.441 +        /// <param name="x">
  23.442 +        /// The tile x.
  23.443 +        /// </param>
  23.444 +        /// <param name="y">
  23.445 +        /// The tile y.
  23.446 +        /// </param>
  23.447 +        /// <param name="zoom">
  23.448 +        /// The zoom.
  23.449 +        /// </param>
  23.450 +        /// <returns>
  23.451 +        /// The uri.
  23.452 +        /// </returns>
  23.453 +        private string GetTileUri(int x, int y, int zoom)
  23.454 +        {
  23.455 +            string url = this.Url.Replace("{X}", x.ToString(CultureInfo.InvariantCulture));
  23.456 +            url = url.Replace("{Y}", y.ToString(CultureInfo.InvariantCulture));
  23.457 +            return url.Replace("{Z}", zoom.ToString(CultureInfo.InvariantCulture));
  23.458 +        }
  23.459 +    }
  23.460 +}
  23.461 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/External/OxyPlot/OxyPlot/Axes/AngleAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    24.3 @@ -0,0 +1,184 @@
    24.4 +// --------------------------------------------------------------------------------------------------------------------
    24.5 +// <copyright file="AngleAxis.cs" company="OxyPlot">
    24.6 +//   The MIT License (MIT)
    24.7 +//
    24.8 +//   Copyright (c) 2012 Oystein Bjorke
    24.9 +//
   24.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   24.11 +//   copy of this software and associated documentation files (the
   24.12 +//   "Software"), to deal in the Software without restriction, including
   24.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   24.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   24.15 +//   permit persons to whom the Software is furnished to do so, subject to
   24.16 +//   the following conditions:
   24.17 +//
   24.18 +//   The above copyright notice and this permission notice shall be included
   24.19 +//   in all copies or substantial portions of the Software.
   24.20 +//
   24.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   24.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   24.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   24.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   24.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   24.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   24.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   24.28 +// </copyright>
   24.29 +// <summary>
   24.30 +//   Represents an angular axis for polar plots.
   24.31 +// </summary>
   24.32 +// --------------------------------------------------------------------------------------------------------------------
   24.33 +namespace OxyPlot.Axes
   24.34 +{
   24.35 +    using System;
   24.36 +
   24.37 +    /// <summary>
   24.38 +    /// Represents an angular axis for polar plots.
   24.39 +    /// </summary>
   24.40 +    public class AngleAxis : LinearAxis
   24.41 +    {
   24.42 +        /// <summary>
   24.43 +        /// Initializes a new instance of the <see cref="AngleAxis"/> class.
   24.44 +        /// </summary>
   24.45 +        public AngleAxis()
   24.46 +        {
   24.47 +            this.IsPanEnabled = false;
   24.48 +            this.IsZoomEnabled = false;
   24.49 +            this.MajorGridlineStyle = LineStyle.Solid;
   24.50 +            this.MinorGridlineStyle = LineStyle.Solid;
   24.51 +            this.StartAngle = 0;
   24.52 +            this.EndAngle = 360;
   24.53 +        }
   24.54 +
   24.55 +        /// <summary>
   24.56 +        /// Initializes a new instance of the <see cref="AngleAxis"/> class.
   24.57 +        /// </summary>
   24.58 +        /// <param name="minimum">
   24.59 +        /// The minimum.
   24.60 +        /// </param>
   24.61 +        /// <param name="maximum">
   24.62 +        /// The maximum.
   24.63 +        /// </param>
   24.64 +        /// <param name="majorStep">
   24.65 +        /// The major step.
   24.66 +        /// </param>
   24.67 +        /// <param name="minorStep">
   24.68 +        /// The minor step.
   24.69 +        /// </param>
   24.70 +        /// <param name="title">
   24.71 +        /// The title.
   24.72 +        /// </param>
   24.73 +        public AngleAxis(
   24.74 +            double minimum = double.NaN,
   24.75 +            double maximum = double.NaN,
   24.76 +            double majorStep = double.NaN,
   24.77 +            double minorStep = double.NaN,
   24.78 +            string title = null)
   24.79 +            : this()
   24.80 +        {
   24.81 +            this.Minimum = minimum;
   24.82 +            this.Maximum = maximum;
   24.83 +            this.MajorStep = majorStep;
   24.84 +            this.MinorStep = minorStep;
   24.85 +            this.Title = title;
   24.86 +            this.StartAngle = 0;
   24.87 +            this.EndAngle = 360;
   24.88 +        }
   24.89 +
   24.90 +        /// <summary>
   24.91 +        /// Gets or sets the start angle (degrees).
   24.92 +        /// </summary>
   24.93 +        public double StartAngle { get; set; }
   24.94 +
   24.95 +        /// <summary>
   24.96 +        /// Gets or sets the end angle (degrees).
   24.97 +        /// </summary>
   24.98 +        public double EndAngle { get; set; }
   24.99 +
  24.100 +        /// <summary>
  24.101 +        /// Inverse transform the specified screen point.
  24.102 +        /// </summary>
  24.103 +        /// <param name="x">The x coordinate.</param>
  24.104 +        /// <param name="y">The y coordinate.</param>
  24.105 +        /// <param name="yaxis">The y-axis.</param>
  24.106 +        /// <returns>
  24.107 +        /// The data point.
  24.108 +        /// </returns>
  24.109 +        public override DataPoint InverseTransform(double x, double y, Axis yaxis)
  24.110 +        {
  24.111 +            throw new InvalidOperationException("Angle axis should always be the y-axis.");
  24.112 +        }
  24.113 +
  24.114 +        /// <summary>
  24.115 +        /// Determines whether the axis is used for X/Y values.
  24.116 +        /// </summary>
  24.117 +        /// <returns>
  24.118 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  24.119 +        /// </returns>
  24.120 +        public override bool IsXyAxis()
  24.121 +        {
  24.122 +            return false;
  24.123 +        }
  24.124 +
  24.125 +        /// <summary>
  24.126 +        /// Renders the axis on the specified render context.
  24.127 +        /// </summary>
  24.128 +        /// <param name="rc">The render context.</param>
  24.129 +        /// <param name="model">The model.</param>
  24.130 +        /// <param name="axisLayer">The rendering order.</param>
  24.131 +        /// <param name="pass"></param>
  24.132 +        public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
  24.133 +        {
  24.134 +            if (this.Layer != axisLayer)
  24.135 +            {
  24.136 +                return;
  24.137 +            }
  24.138 +
  24.139 +            var r = new AngleAxisRenderer(rc, model);
  24.140 +            r.Render(this, pass);
  24.141 +        }
  24.142 +
  24.143 +        /// <summary>
  24.144 +        /// Transforms the specified point to screen coordinates.
  24.145 +        /// </summary>
  24.146 +        /// <param name="x">
  24.147 +        /// The x value (for the current axis).
  24.148 +        /// </param>
  24.149 +        /// <param name="y">
  24.150 +        /// The y value.
  24.151 +        /// </param>
  24.152 +        /// <param name="yaxis">
  24.153 +        /// The y axis.
  24.154 +        /// </param>
  24.155 +        /// <returns>
  24.156 +        /// The transformed point.
  24.157 +        /// </returns>
  24.158 +        public override ScreenPoint Transform(double x, double y, Axis yaxis)
  24.159 +        {
  24.160 +            throw new InvalidOperationException("Angle axis should always be the y-axis.");
  24.161 +        }
  24.162 +
  24.163 +        /// <summary>
  24.164 +        /// The update transform.
  24.165 +        /// </summary>
  24.166 +        /// <param name="bounds">
  24.167 +        /// The bounds.
  24.168 +        /// </param>
  24.169 +        internal override void UpdateTransform(OxyRect bounds)
  24.170 +        {
  24.171 +            double x0 = bounds.Left;
  24.172 +            double x1 = bounds.Right;
  24.173 +            double y0 = bounds.Bottom;
  24.174 +            double y1 = bounds.Top;
  24.175 +
  24.176 +            this.ScreenMin = new ScreenPoint(x0, y1);
  24.177 +            this.ScreenMax = new ScreenPoint(x1, y0);
  24.178 +
  24.179 +            double startAngle = this.StartAngle / 180 * Math.PI;
  24.180 +            double endAngle = this.EndAngle / 180 * Math.PI;
  24.181 +
  24.182 +            this.Scale = (endAngle - startAngle) / (this.ActualMaximum - this.ActualMinimum);
  24.183 +            this.Offset = this.ActualMinimum - (startAngle / this.Scale);
  24.184 +        }
  24.185 +
  24.186 +    }
  24.187 +}
  24.188 \ No newline at end of file
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/External/OxyPlot/OxyPlot/Axes/Axis.cs	Sat Jun 08 16:53:22 2013 +0000
    25.3 @@ -0,0 +1,1753 @@
    25.4 +// --------------------------------------------------------------------------------------------------------------------
    25.5 +// <copyright file="Axis.cs" company="OxyPlot">
    25.6 +//   The MIT License (MIT)
    25.7 +//
    25.8 +//   Copyright (c) 2012 Oystein Bjorke
    25.9 +//
   25.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   25.11 +//   copy of this software and associated documentation files (the
   25.12 +//   "Software"), to deal in the Software without restriction, including
   25.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   25.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   25.15 +//   permit persons to whom the Software is furnished to do so, subject to
   25.16 +//   the following conditions:
   25.17 +//
   25.18 +//   The above copyright notice and this permission notice shall be included
   25.19 +//   in all copies or substantial portions of the Software.
   25.20 +//
   25.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   25.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   25.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   25.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   25.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   25.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   25.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   25.28 +// </copyright>
   25.29 +// <summary>
   25.30 +//   Abstract base class for axes.
   25.31 +// </summary>
   25.32 +// --------------------------------------------------------------------------------------------------------------------
   25.33 +namespace OxyPlot.Axes
   25.34 +{
   25.35 +    using System;
   25.36 +    using System.Collections.Generic;
   25.37 +    using System.Diagnostics.CodeAnalysis;
   25.38 +    using System.Globalization;
   25.39 +
   25.40 +    using OxyPlot.Series;
   25.41 +
   25.42 +    /// <summary>
   25.43 +    /// Provides an abstract base class for axes.
   25.44 +    /// </summary>
   25.45 +    public abstract class Axis : PlotElement
   25.46 +    {
   25.47 +        /// <summary>
   25.48 +        /// Exponent function.
   25.49 +        /// </summary>
   25.50 +        protected static readonly Func<double, double> Exponent = x => Math.Round(Math.Log(Math.Abs(x), 10));
   25.51 +
   25.52 +        /// <summary>
   25.53 +        /// Mantissa function. http://en.wikipedia.org/wiki/Mantissa
   25.54 +        /// </summary>
   25.55 +        protected static readonly Func<double, double> Mantissa = x => x / Math.Pow(10, Exponent(x));
   25.56 +
   25.57 +        /// <summary>
   25.58 +        /// The offset.
   25.59 +        /// </summary>
   25.60 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate",
   25.61 +            Justification = "Reviewed. Suppression is OK here.")]
   25.62 +        protected double offset;
   25.63 +
   25.64 +        /// <summary>
   25.65 +        /// The scale.
   25.66 +        /// </summary>
   25.67 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate",
   25.68 +            Justification = "Reviewed. Suppression is OK here.")]
   25.69 +        protected double scale;
   25.70 +
   25.71 +        /// <summary>
   25.72 +        /// The position.
   25.73 +        /// </summary>
   25.74 +        private AxisPosition position;
   25.75 +
   25.76 +        /// <summary>
   25.77 +        /// Initializes a new instance of the <see cref="Axis"/> class.
   25.78 +        /// </summary>
   25.79 +        protected Axis()
   25.80 +        {
   25.81 +            this.Position = AxisPosition.Left;
   25.82 +            this.PositionTier = 0;
   25.83 +            this.IsAxisVisible = true;
   25.84 +            this.Layer = AxisLayer.BelowSeries;
   25.85 +
   25.86 +            this.ViewMaximum = double.NaN;
   25.87 +            this.ViewMinimum = double.NaN;
   25.88 +
   25.89 +            this.AbsoluteMaximum = double.MaxValue;
   25.90 +            this.AbsoluteMinimum = double.MinValue;
   25.91 +
   25.92 +            this.Minimum = double.NaN;
   25.93 +            this.Maximum = double.NaN;
   25.94 +            this.MinorStep = double.NaN;
   25.95 +            this.MajorStep = double.NaN;
   25.96 +
   25.97 +            this.MinimumPadding = 0.01;
   25.98 +            this.MaximumPadding = 0.01;
   25.99 +            this.MinimumRange = 0;
  25.100 +
  25.101 +            this.TickStyle = TickStyle.Outside;
  25.102 +            this.TicklineColor = OxyColors.Black;
  25.103 +
  25.104 +            this.AxislineStyle = LineStyle.None;
  25.105 +            this.AxislineColor = OxyColors.Black;
  25.106 +            this.AxislineThickness = 1.0;
  25.107 +
  25.108 +            this.MajorGridlineStyle = LineStyle.None;
  25.109 +            this.MajorGridlineColor = OxyColor.FromArgb(0x40, 0, 0, 0);
  25.110 +            this.MajorGridlineThickness = 1;
  25.111 +
  25.112 +            this.MinorGridlineStyle = LineStyle.None;
  25.113 +            this.MinorGridlineColor = OxyColor.FromArgb(0x20, 0, 0, 0x00);
  25.114 +            this.MinorGridlineThickness = 1;
  25.115 +
  25.116 +            this.ExtraGridlineStyle = LineStyle.Solid;
  25.117 +            this.ExtraGridlineColor = OxyColors.Black;
  25.118 +            this.ExtraGridlineThickness = 1;
  25.119 +
  25.120 +            this.ShowMinorTicks = true;
  25.121 +
  25.122 +            this.MinorTickSize = 4;
  25.123 +            this.MajorTickSize = 7;
  25.124 +
  25.125 +            this.StartPosition = 0;
  25.126 +            this.EndPosition = 1;
  25.127 +
  25.128 +            this.TitlePosition = 0.5;
  25.129 +            this.TitleFormatString = "{0} [{1}]";
  25.130 +            this.TitleClippingLength = 0.9;
  25.131 +            this.TitleColor = null;
  25.132 +            this.TitleFontSize = double.NaN;
  25.133 +            this.TitleFontWeight = FontWeights.Normal;
  25.134 +            this.ClipTitle = true;
  25.135 +
  25.136 +            this.Angle = 0;
  25.137 +
  25.138 +            this.IsZoomEnabled = true;
  25.139 +            this.IsPanEnabled = true;
  25.140 +
  25.141 +            this.FilterMinValue = double.MinValue;
  25.142 +            this.FilterMaxValue = double.MaxValue;
  25.143 +            this.FilterFunction = null;
  25.144 +
  25.145 +            this.IntervalLength = 60;
  25.146 +
  25.147 +            this.AxisTitleDistance = 4;
  25.148 +            this.AxisTickToLabelDistance = 4;
  25.149 +        }
  25.150 +
  25.151 +        /// <summary>
  25.152 +        /// Initializes a new instance of the <see cref="Axis"/> class.
  25.153 +        /// </summary>
  25.154 +        /// <param name="pos">
  25.155 +        /// The position of the axis.
  25.156 +        /// </param>
  25.157 +        /// <param name="minimum">
  25.158 +        /// The minimum value.
  25.159 +        /// </param>
  25.160 +        /// <param name="maximum">
  25.161 +        /// The maximum value.
  25.162 +        /// </param>
  25.163 +        /// <param name="title">
  25.164 +        /// The axis title.
  25.165 +        /// </param>
  25.166 +        protected Axis(AxisPosition pos, double minimum, double maximum, string title = null)
  25.167 +            : this()
  25.168 +        {
  25.169 +            this.Position = pos;
  25.170 +            this.Minimum = minimum;
  25.171 +            this.Maximum = maximum;
  25.172 +
  25.173 +            this.AbsoluteMaximum = double.NaN;
  25.174 +            this.AbsoluteMinimum = double.NaN;
  25.175 +
  25.176 +            this.Title = title;
  25.177 +        }
  25.178 +
  25.179 +        /// <summary>
  25.180 +        /// Occurs when the axis has been changed (by zooming, panning or resetting).
  25.181 +        /// </summary>
  25.182 +        public event EventHandler<AxisChangedEventArgs> AxisChanged;
  25.183 +
  25.184 +        /// <summary>
  25.185 +        /// 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.
  25.186 +        /// </summary>
  25.187 +        /// <value> The absolute maximum. </value>
  25.188 +        public double AbsoluteMaximum { get; set; }
  25.189 +
  25.190 +        /// <summary>
  25.191 +        /// 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.
  25.192 +        /// </summary>
  25.193 +        /// <value> The absolute minimum. </value>
  25.194 +        public double AbsoluteMinimum { get; set; }
  25.195 +
  25.196 +        /// <summary>
  25.197 +        /// Gets the actual culture.
  25.198 +        /// </summary>
  25.199 +        /// <remarks>
  25.200 +        /// The culture is defined in the parent PlotModel.
  25.201 +        /// </remarks>
  25.202 +        public CultureInfo ActualCulture
  25.203 +        {
  25.204 +            get
  25.205 +            {
  25.206 +                return this.PlotModel != null ? this.PlotModel.ActualCulture : CultureInfo.CurrentCulture;
  25.207 +            }
  25.208 +        }
  25.209 +
  25.210 +        /// <summary>
  25.211 +        /// Gets or sets the actual major step.
  25.212 +        /// </summary>
  25.213 +        public double ActualMajorStep { get; protected set; }
  25.214 +
  25.215 +        /// <summary>
  25.216 +        /// Gets or sets the actual maximum value of the axis.
  25.217 +        /// </summary>
  25.218 +        /// <remarks>
  25.219 +        /// If ViewMaximum is not NaN, this value will be defined by ViewMaximum.
  25.220 +        /// Otherwise, if Maximum is not NaN, this value will be defined by Maximum.
  25.221 +        /// Otherwise, this value will be defined by the maximum (+padding) of the data.
  25.222 +        /// </remarks>
  25.223 +        public double ActualMaximum { get; protected set; }
  25.224 +
  25.225 +        /// <summary>
  25.226 +        /// Gets or sets the actual minimum value of the axis.
  25.227 +        /// </summary>
  25.228 +        /// <remarks>
  25.229 +        /// If ViewMinimum is not NaN, this value will be defined by ViewMinimum.
  25.230 +        /// Otherwise, if Minimum is not NaN, this value will be defined by Minimum.
  25.231 +        /// Otherwise this value will be defined by the minimum (+padding) of the data.
  25.232 +        /// </remarks>
  25.233 +        public double ActualMinimum { get; protected set; }
  25.234 +
  25.235 +        /// <summary>
  25.236 +        /// Gets or sets the maximum value of the data displayed on this axis.
  25.237 +        /// </summary>
  25.238 +        /// <value>The data maximum.</value>
  25.239 +        public double DataMaximum { get; protected set; }
  25.240 +
  25.241 +        /// <summary>
  25.242 +        /// Gets or sets the minimum value of the data displayed on this axis.
  25.243 +        /// </summary>
  25.244 +        /// <value>The data minimum.</value>
  25.245 +        public double DataMinimum { get; protected set; }
  25.246 +
  25.247 +        /// <summary>
  25.248 +        /// Gets or sets the actual minor step.
  25.249 +        /// </summary>
  25.250 +        public double ActualMinorStep { get; protected set; }
  25.251 +
  25.252 +        /// <summary>
  25.253 +        /// Gets or sets the actual string format being used.
  25.254 +        /// </summary>
  25.255 +        public string ActualStringFormat { get; protected set; }
  25.256 +
  25.257 +        /// <summary>
  25.258 +        /// Gets the actual title (including Unit if Unit is set).
  25.259 +        /// </summary>
  25.260 +        /// <value> The actual title. </value>
  25.261 +        public string ActualTitle
  25.262 +        {
  25.263 +            get
  25.264 +            {
  25.265 +                if (this.Unit != null)
  25.266 +                {
  25.267 +                    return string.Format(this.TitleFormatString, this.Title, this.Unit);
  25.268 +                }
  25.269 +
  25.270 +                return this.Title;
  25.271 +            }
  25.272 +        }
  25.273 +
  25.274 +        /// <summary>
  25.275 +        /// Gets or sets the angle for the axis values.
  25.276 +        /// </summary>
  25.277 +        public double Angle { get; set; }
  25.278 +
  25.279 +        /// <summary>
  25.280 +        /// Gets or sets the distance from axis tick to number label.
  25.281 +        /// </summary>
  25.282 +        /// <value> The axis tick to label distance. </value>
  25.283 +        public double AxisTickToLabelDistance { get; set; }
  25.284 +
  25.285 +        /// <summary>
  25.286 +        /// Gets or sets the distance from axis number to axis title.
  25.287 +        /// </summary>
  25.288 +        /// <value> The axis title distance. </value>
  25.289 +        public double AxisTitleDistance { get; set; }
  25.290 +
  25.291 +        /// <summary>
  25.292 +        /// Gets or sets the color of the axis line.
  25.293 +        /// </summary>
  25.294 +        public OxyColor AxislineColor { get; set; }
  25.295 +
  25.296 +        /// <summary>
  25.297 +        /// Gets or sets the axis line.
  25.298 +        /// </summary>
  25.299 +        public LineStyle AxislineStyle { get; set; }
  25.300 +
  25.301 +        /// <summary>
  25.302 +        /// Gets or sets the axis line.
  25.303 +        /// </summary>
  25.304 +        public double AxislineThickness { get; set; }
  25.305 +
  25.306 +        /// <summary>
  25.307 +        /// Gets or sets a value indicating whether to clip the axis title.
  25.308 +        /// </summary>
  25.309 +        /// <remarks>
  25.310 +        /// The default value is true.
  25.311 +        /// </remarks>
  25.312 +        public bool ClipTitle { get; set; }
  25.313 +
  25.314 +        /// <summary>
  25.315 +        /// 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).
  25.316 +        /// </summary>
  25.317 +        public double EndPosition { get; set; }
  25.318 +
  25.319 +        /// <summary>
  25.320 +        /// Gets or sets the color of the extra gridlines.
  25.321 +        /// </summary>
  25.322 +        public OxyColor ExtraGridlineColor { get; set; }
  25.323 +
  25.324 +        /// <summary>
  25.325 +        /// Gets or sets the extra gridlines line style.
  25.326 +        /// </summary>
  25.327 +        public LineStyle ExtraGridlineStyle { get; set; }
  25.328 +
  25.329 +        /// <summary>
  25.330 +        /// Gets or sets the extra gridline thickness.
  25.331 +        /// </summary>
  25.332 +        public double ExtraGridlineThickness { get; set; }
  25.333 +
  25.334 +        /// <summary>
  25.335 +        /// Gets or sets the values for extra gridlines.
  25.336 +        /// </summary>
  25.337 +        public double[] ExtraGridlines { get; set; }
  25.338 +
  25.339 +        /// <summary>
  25.340 +        /// Gets or sets the filter function.
  25.341 +        /// </summary>
  25.342 +        /// <value> The filter function. </value>
  25.343 +        public Func<double, bool> FilterFunction { get; set; }
  25.344 +
  25.345 +        /// <summary>
  25.346 +        /// Gets or sets the maximum value that can be shown using this axis. Values greater or equal to this value will not be shown.
  25.347 +        /// </summary>
  25.348 +        /// <value> The filter max value. </value>
  25.349 +        public double FilterMaxValue { get; set; }
  25.350 +
  25.351 +        /// <summary>
  25.352 +        /// Gets or sets the minimum value that can be shown using this axis. Values smaller or equal to this value will not be shown.
  25.353 +        /// </summary>
  25.354 +        /// <value> The filter min value. </value>
  25.355 +        public double FilterMinValue { get; set; }
  25.356 +
  25.357 +        /// <summary>
  25.358 +        /// 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.
  25.359 +        /// </summary>
  25.360 +        public double IntervalLength { get; set; }
  25.361 +
  25.362 +        /// <summary>
  25.363 +        /// Gets or sets a value indicating whether this axis is visible.
  25.364 +        /// </summary>
  25.365 +        public bool IsAxisVisible { get; set; }
  25.366 +
  25.367 +        /// <summary>
  25.368 +        /// Gets or sets a value indicating whether pan is enabled.
  25.369 +        /// </summary>
  25.370 +        public bool IsPanEnabled { get; set; }
  25.371 +
  25.372 +        /// <summary>
  25.373 +        /// Gets a value indicating whether this axis is reversed. It is reversed if StartPosition>EndPosition.
  25.374 +        /// </summary>
  25.375 +        public bool IsReversed
  25.376 +        {
  25.377 +            get
  25.378 +            {
  25.379 +                return this.StartPosition > this.EndPosition;
  25.380 +            }
  25.381 +        }
  25.382 +
  25.383 +        /// <summary>
  25.384 +        /// Gets or sets a value indicating whether zoom is enabled.
  25.385 +        /// </summary>
  25.386 +        public bool IsZoomEnabled { get; set; }
  25.387 +
  25.388 +        /// <summary>
  25.389 +        /// 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.
  25.390 +        /// </summary>
  25.391 +        public string Key { get; set; }
  25.392 +
  25.393 +        /// <summary>
  25.394 +        /// Gets or sets the layer.
  25.395 +        /// </summary>
  25.396 +        /// <value> The layer. </value>
  25.397 +        public AxisLayer Layer { get; set; }
  25.398 +
  25.399 +        /// <summary>
  25.400 +        /// Gets or sets the color of the major gridline.
  25.401 +        /// </summary>
  25.402 +        public OxyColor MajorGridlineColor { get; set; }
  25.403 +
  25.404 +        /// <summary>
  25.405 +        /// Gets or sets the major gridline style.
  25.406 +        /// </summary>
  25.407 +        public LineStyle MajorGridlineStyle { get; set; }
  25.408 +
  25.409 +        /// <summary>
  25.410 +        /// Gets or sets the major gridline thickness.
  25.411 +        /// </summary>
  25.412 +        public double MajorGridlineThickness { get; set; }
  25.413 +
  25.414 +        /// <summary>
  25.415 +        /// Gets or sets the major step. (the interval between large ticks with numbers).
  25.416 +        /// </summary>
  25.417 +        public double MajorStep { get; set; }
  25.418 +
  25.419 +        /// <summary>
  25.420 +        /// Gets or sets the size of the major tick.
  25.421 +        /// </summary>
  25.422 +        public double MajorTickSize { get; set; }
  25.423 +
  25.424 +        /// <summary>
  25.425 +        /// Gets or sets the maximum value of the axis.
  25.426 +        /// </summary>
  25.427 +        public double Maximum { get; set; }
  25.428 +
  25.429 +        /// <summary>
  25.430 +        /// 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.
  25.431 +        /// </summary>
  25.432 +        public double MaximumPadding { get; set; }
  25.433 +
  25.434 +        /// <summary>
  25.435 +        /// Gets or sets the minimum value of the axis.
  25.436 +        /// </summary>
  25.437 +        public double Minimum { get; set; }
  25.438 +
  25.439 +        /// <summary>
  25.440 +        /// 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.
  25.441 +        /// </summary>
  25.442 +        public double MinimumPadding { get; set; }
  25.443 +
  25.444 +        /// <summary>
  25.445 +        /// Gets or sets the minimum range of the axis. Setting this property ensures that ActualMaximum-ActualMinimum > MinimumRange.
  25.446 +        /// </summary>
  25.447 +        public double MinimumRange { get; set; }
  25.448 +
  25.449 +        /// <summary>
  25.450 +        /// Gets or sets the color of the minor gridline.
  25.451 +        /// </summary>
  25.452 +        public OxyColor MinorGridlineColor { get; set; }
  25.453 +
  25.454 +        /// <summary>
  25.455 +        /// Gets or sets the minor gridline style.
  25.456 +        /// </summary>
  25.457 +        public LineStyle MinorGridlineStyle { get; set; }
  25.458 +
  25.459 +        /// <summary>
  25.460 +        /// Gets or sets the minor gridline thickness.
  25.461 +        /// </summary>
  25.462 +        public double MinorGridlineThickness { get; set; }
  25.463 +
  25.464 +        /// <summary>
  25.465 +        /// Gets or sets the minor step (the interval between small ticks without number).
  25.466 +        /// </summary>
  25.467 +        public double MinorStep { get; set; }
  25.468 +
  25.469 +        /// <summary>
  25.470 +        /// Gets or sets the size of the minor tick.
  25.471 +        /// </summary>
  25.472 +        public double MinorTickSize { get; set; }
  25.473 +
  25.474 +        /// <summary>
  25.475 +        /// Gets or sets the offset. This is used to transform between data and screen coordinates.
  25.476 +        /// </summary>
  25.477 +        public double Offset
  25.478 +        {
  25.479 +            get
  25.480 +            {
  25.481 +                return this.offset;
  25.482 +            }
  25.483 +
  25.484 +            protected set
  25.485 +            {
  25.486 +                this.offset = value;
  25.487 +            }
  25.488 +        }
  25.489 +
  25.490 +        /// <summary>
  25.491 +        /// Gets or sets the position of the axis.
  25.492 +        /// </summary>
  25.493 +        public AxisPosition Position
  25.494 +        {
  25.495 +            get
  25.496 +            {
  25.497 +                return this.position;
  25.498 +            }
  25.499 +
  25.500 +            set
  25.501 +            {
  25.502 +                this.position = value;
  25.503 +            }
  25.504 +        }
  25.505 +
  25.506 +        /// <summary>
  25.507 +        /// Gets or sets a value indicating whether the axis should be positioned on the zero-crossing of the related axis.
  25.508 +        /// </summary>
  25.509 +        public bool PositionAtZeroCrossing { get; set; }
  25.510 +
  25.511 +        /// <summary>
  25.512 +        /// Gets or sets the position tier which defines in which tier the axis is displayed.
  25.513 +        /// </summary>
  25.514 +        /// <remarks>
  25.515 +        /// The bigger the value the the further afar is the axis from the graph.
  25.516 +        /// </remarks>
  25.517 +        public int PositionTier { get; set; }
  25.518 +
  25.519 +        /// <summary>
  25.520 +        /// Gets or sets the related axis. This is used for polar coordinate systems where the angle and magnitude axes are related.
  25.521 +        /// </summary>
  25.522 +        public Axis RelatedAxis { get; set; }
  25.523 +
  25.524 +        /// <summary>
  25.525 +        /// Gets or sets the scaling factor of the axis. This is used to transform between data and screen coordinates.
  25.526 +        /// </summary>
  25.527 +        public double Scale
  25.528 +        {
  25.529 +            get
  25.530 +            {
  25.531 +                return this.scale;
  25.532 +            }
  25.533 +
  25.534 +            protected set
  25.535 +            {
  25.536 +                this.scale = value;
  25.537 +            }
  25.538 +        }
  25.539 +
  25.540 +        /// <summary>
  25.541 +        /// Gets or sets the screen coordinate of the Maximum point on the axis.
  25.542 +        /// </summary>
  25.543 +        public ScreenPoint ScreenMax { get; protected set; }
  25.544 +
  25.545 +        /// <summary>
  25.546 +        /// Gets or sets the screen coordinate of the Minimum point on the axis.
  25.547 +        /// </summary>
  25.548 +        public ScreenPoint ScreenMin { get; protected set; }
  25.549 +
  25.550 +        /// <summary>
  25.551 +        /// Gets or sets a value indicating whether minor ticks should be shown.
  25.552 +        /// </summary>
  25.553 +        public bool ShowMinorTicks { get; set; }
  25.554 +
  25.555 +        /// <summary>
  25.556 +        /// 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).
  25.557 +        /// </summary>
  25.558 +        public double StartPosition { get; set; }
  25.559 +
  25.560 +        /// <summary>
  25.561 +        /// Gets or sets the string format used for formatting the axis values.
  25.562 +        /// </summary>
  25.563 +        public string StringFormat { get; set; }
  25.564 +
  25.565 +        /// <summary>
  25.566 +        /// Gets or sets the tick style (both for major and minor ticks).
  25.567 +        /// </summary>
  25.568 +        public TickStyle TickStyle { get; set; }
  25.569 +
  25.570 +        /// <summary>
  25.571 +        /// Gets or sets the color of the ticks (both major and minor ticks).
  25.572 +        /// </summary>
  25.573 +        public OxyColor TicklineColor { get; set; }
  25.574 +
  25.575 +        /// <summary>
  25.576 +        /// Gets or sets the title of the axis.
  25.577 +        /// </summary>
  25.578 +        public string Title { get; set; }
  25.579 +
  25.580 +        /// <summary>
  25.581 +        /// Gets or sets the length of the title clipping rectangle (fraction of the available length of the axis).
  25.582 +        /// </summary>
  25.583 +        /// <remarks>
  25.584 +        /// The default value is 0.9
  25.585 +        /// </remarks>
  25.586 +        public double TitleClippingLength { get; set; }
  25.587 +
  25.588 +        /// <summary>
  25.589 +        /// Gets or sets the color of the title.
  25.590 +        /// </summary>
  25.591 +        /// <value> The color of the title. </value>
  25.592 +        /// <remarks>
  25.593 +        /// If TitleColor is null, the parent PlotModel's TextColor will be used.
  25.594 +        /// </remarks>
  25.595 +        public OxyColor TitleColor { get; set; }
  25.596 +
  25.597 +        /// <summary>
  25.598 +        /// Gets or sets the title font.
  25.599 +        /// </summary>
  25.600 +        /// <value> The title font. </value>
  25.601 +        public string TitleFont { get; set; }
  25.602 +
  25.603 +        /// <summary>
  25.604 +        /// Gets or sets the size of the title font.
  25.605 +        /// </summary>
  25.606 +        /// <value> The size of the title font. </value>
  25.607 +        public double TitleFontSize { get; set; }
  25.608 +
  25.609 +        /// <summary>
  25.610 +        /// Gets or sets the title font weight.
  25.611 +        /// </summary>
  25.612 +        /// <value> The title font weight. </value>
  25.613 +        public double TitleFontWeight { get; set; }
  25.614 +
  25.615 +        /// <summary>
  25.616 +        /// 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.
  25.617 +        /// </summary>
  25.618 +        public string TitleFormatString { get; set; }
  25.619 +
  25.620 +        /// <summary>
  25.621 +        /// Gets or sets the position of the title (0.5 is in the middle).
  25.622 +        /// </summary>
  25.623 +        public double TitlePosition { get; set; }
  25.624 +
  25.625 +        /// <summary>
  25.626 +        /// Gets or sets the tool tip.
  25.627 +        /// </summary>
  25.628 +        /// <value> The tool tip. </value>
  25.629 +        public string ToolTip { get; set; }
  25.630 +
  25.631 +        /// <summary>
  25.632 +        /// Gets or sets the unit of the axis.
  25.633 +        /// </summary>
  25.634 +        public string Unit { get; set; }
  25.635 +
  25.636 +        /// <summary>
  25.637 +        /// 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}
  25.638 +        /// </summary>
  25.639 +        public bool UseSuperExponentialFormat { get; set; }
  25.640 +
  25.641 +        /// <summary>
  25.642 +        /// Gets or sets the position tier max shift.
  25.643 +        /// </summary>
  25.644 +        /// <value> The position tier max shift. </value>
  25.645 +        internal double PositionTierMaxShift { get; set; }
  25.646 +
  25.647 +        /// <summary>
  25.648 +        /// Gets or sets the position tier min shift.
  25.649 +        /// </summary>
  25.650 +        /// <value> The position tier min shift. </value>
  25.651 +        internal double PositionTierMinShift { get; set; }
  25.652 +
  25.653 +        /// <summary>
  25.654 +        /// Gets or sets the size of the position tier.
  25.655 +        /// </summary>
  25.656 +        /// <value> The size of the position tier. </value>
  25.657 +        internal double PositionTierSize { get; set; }
  25.658 +
  25.659 +        /// <summary>
  25.660 +        /// Gets the actual color of the title.
  25.661 +        /// </summary>
  25.662 +        /// <value> The actual color of the title. </value>
  25.663 +        protected internal OxyColor ActualTitleColor
  25.664 +        {
  25.665 +            get
  25.666 +            {
  25.667 +                return this.TitleColor ?? this.PlotModel.TextColor;
  25.668 +            }
  25.669 +        }
  25.670 +
  25.671 +        /// <summary>
  25.672 +        /// Gets the actual title font.
  25.673 +        /// </summary>
  25.674 +        protected internal string ActualTitleFont
  25.675 +        {
  25.676 +            get
  25.677 +            {
  25.678 +                return this.TitleFont ?? this.PlotModel.DefaultFont;
  25.679 +            }
  25.680 +        }
  25.681 +
  25.682 +        /// <summary>
  25.683 +        /// Gets the actual size of the title font.
  25.684 +        /// </summary>
  25.685 +        /// <value> The actual size of the title font. </value>
  25.686 +        protected internal double ActualTitleFontSize
  25.687 +        {
  25.688 +            get
  25.689 +            {
  25.690 +                return !double.IsNaN(this.TitleFontSize) ? this.TitleFontSize : this.ActualFontSize;
  25.691 +            }
  25.692 +        }
  25.693 +
  25.694 +        /// <summary>
  25.695 +        /// Gets the actual title font weight.
  25.696 +        /// </summary>
  25.697 +        protected internal double ActualTitleFontWeight
  25.698 +        {
  25.699 +            get
  25.700 +            {
  25.701 +                return !double.IsNaN(this.TitleFontWeight) ? this.TitleFontWeight : this.ActualFontWeight;
  25.702 +            }
  25.703 +        }
  25.704 +
  25.705 +        /// <summary>
  25.706 +        /// Gets or sets the current view's maximum. This value is used when the user zooms or pans.
  25.707 +        /// </summary>
  25.708 +        /// <value> The view maximum. </value>
  25.709 +        protected double ViewMaximum { get; set; }
  25.710 +
  25.711 +        /// <summary>
  25.712 +        /// Gets or sets the current view's minimum. This value is used when the user zooms or pans.
  25.713 +        /// </summary>
  25.714 +        /// <value> The view minimum. </value>
  25.715 +        protected double ViewMinimum { get; set; }
  25.716 +
  25.717 +        /// <summary>
  25.718 +        /// Transforms the specified point to screen coordinates.
  25.719 +        /// </summary>
  25.720 +        /// <param name="p">
  25.721 +        /// The point.
  25.722 +        /// </param>
  25.723 +        /// <param name="xaxis">
  25.724 +        /// The x axis.
  25.725 +        /// </param>
  25.726 +        /// <param name="yaxis">
  25.727 +        /// The y axis.
  25.728 +        /// </param>
  25.729 +        /// <returns>
  25.730 +        /// The transformed point.
  25.731 +        /// </returns>
  25.732 +        public static ScreenPoint Transform(DataPoint p, Axis xaxis, Axis yaxis)
  25.733 +        {
  25.734 +            return xaxis.Transform(p.x, p.y, yaxis);
  25.735 +        }
  25.736 +
  25.737 +        /// <summary>
  25.738 +        /// Transform the specified screen point to data coordinates.
  25.739 +        /// </summary>
  25.740 +        /// <param name="p">The point.</param>
  25.741 +        /// <param name="xaxis">The x axis.</param>
  25.742 +        /// <param name="yaxis">The y axis.</param>
  25.743 +        /// <returns>The data point.</returns>
  25.744 +        public static DataPoint InverseTransform(ScreenPoint p, Axis xaxis, Axis yaxis)
  25.745 +        {
  25.746 +            return xaxis.InverseTransform(p.x, p.y, yaxis);
  25.747 +        }
  25.748 +
  25.749 +        /// <summary>
  25.750 +        /// Transforms the specified point to screen coordinates.
  25.751 +        /// </summary>
  25.752 +        /// <param name="p">
  25.753 +        /// The point.
  25.754 +        /// </param>
  25.755 +        /// <param name="xaxis">
  25.756 +        /// The x axis.
  25.757 +        /// </param>
  25.758 +        /// <param name="yaxis">
  25.759 +        /// The y axis.
  25.760 +        /// </param>
  25.761 +        /// <returns>
  25.762 +        /// The transformed point.
  25.763 +        /// </returns>
  25.764 +        public static ScreenPoint Transform(IDataPoint p, Axis xaxis, Axis yaxis)
  25.765 +        {
  25.766 +            return xaxis.Transform(p.X, p.Y, yaxis);
  25.767 +        }
  25.768 +
  25.769 +        /// <summary>
  25.770 +        /// Coerces the actual maximum and minimum values.
  25.771 +        /// </summary>
  25.772 +        public virtual void CoerceActualMaxMin()
  25.773 +        {
  25.774 +            // Coerce actual minimum
  25.775 +            if (double.IsNaN(this.ActualMinimum) || double.IsInfinity(this.ActualMinimum))
  25.776 +            {
  25.777 +                this.ActualMinimum = 0;
  25.778 +            }
  25.779 +
  25.780 +            // Coerce actual maximum
  25.781 +            if (double.IsNaN(this.ActualMaximum) || double.IsInfinity(this.ActualMaximum))
  25.782 +            {
  25.783 +                this.ActualMaximum = 100;
  25.784 +            }
  25.785 +
  25.786 +            if (this.ActualMaximum <= this.ActualMinimum)
  25.787 +            {
  25.788 +                this.ActualMaximum = this.ActualMinimum + 100;
  25.789 +            }
  25.790 +
  25.791 +            // Coerce the minimum range
  25.792 +            double range = this.ActualMaximum - this.ActualMinimum;
  25.793 +            if (range < this.MinimumRange)
  25.794 +            {
  25.795 +                double avg = (this.ActualMaximum + this.ActualMinimum) * 0.5;
  25.796 +                this.ActualMinimum = avg - (this.MinimumRange * 0.5);
  25.797 +                this.ActualMaximum = avg + (this.MinimumRange * 0.5);
  25.798 +            }
  25.799 +
  25.800 +            if (this.AbsoluteMaximum <= this.AbsoluteMinimum)
  25.801 +            {
  25.802 +                throw new InvalidOperationException("AbsoluteMaximum should be larger than AbsoluteMinimum.");
  25.803 +            }
  25.804 +        }
  25.805 +
  25.806 +        /// <summary>
  25.807 +        /// Formats the value to be used on the axis.
  25.808 +        /// </summary>
  25.809 +        /// <param name="x">
  25.810 +        /// The value.
  25.811 +        /// </param>
  25.812 +        /// <returns>
  25.813 +        /// The formatted value.
  25.814 +        /// </returns>
  25.815 +        public virtual string FormatValue(double x)
  25.816 +        {
  25.817 +            // The "SuperExponentialFormat" renders the number with superscript exponents. E.g. 10^2
  25.818 +            if (this.UseSuperExponentialFormat)
  25.819 +            {
  25.820 +                // if (x == 1 || x == 10 || x == -1 || x == -10)
  25.821 +                // return x.ToString();
  25.822 +                double exp = Exponent(x);
  25.823 +                double mantissa = Mantissa(x);
  25.824 +                string fmt;
  25.825 +                if (this.StringFormat == null)
  25.826 +                {
  25.827 +                    fmt = Math.Abs(mantissa - 1.0) < 1e-6 ? "10^{{{1:0}}}" : "{0}·10^{{{1:0}}}";
  25.828 +                }
  25.829 +                else
  25.830 +                {
  25.831 +                    fmt = "{0:" + this.StringFormat + "}·10^{{{1:0}}}";
  25.832 +                }
  25.833 +
  25.834 +                return string.Format(this.ActualCulture, fmt, mantissa, exp);
  25.835 +            }
  25.836 +
  25.837 +            string format = this.ActualStringFormat ?? this.StringFormat ?? string.Empty;
  25.838 +            return x.ToString(format, this.ActualCulture);
  25.839 +        }
  25.840 +
  25.841 +        /// <summary>
  25.842 +        /// Formats the value to be used by the tracker.
  25.843 +        /// </summary>
  25.844 +        /// <param name="x">
  25.845 +        /// The value.
  25.846 +        /// </param>
  25.847 +        /// <returns>
  25.848 +        /// The formatted value.
  25.849 +        /// </returns>
  25.850 +        public virtual string FormatValueForTracker(double x)
  25.851 +        {
  25.852 +            return x.ToString(this.ActualCulture);
  25.853 +        }
  25.854 +
  25.855 +        /// <summary>
  25.856 +        /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
  25.857 +        /// </summary>
  25.858 +        /// <param name="majorLabelValues">
  25.859 +        /// The major label values.
  25.860 +        /// </param>
  25.861 +        /// <param name="majorTickValues">
  25.862 +        /// The major tick values.
  25.863 +        /// </param>
  25.864 +        /// <param name="minorTickValues">
  25.865 +        /// The minor tick values.
  25.866 +        /// </param>
  25.867 +        public virtual void GetTickValues(
  25.868 +            out IList<double> majorLabelValues, out IList<double> majorTickValues, out IList<double> minorTickValues)
  25.869 +        {
  25.870 +            minorTickValues = CreateTickValues(this.ActualMinimum, this.ActualMaximum, this.ActualMinorStep);
  25.871 +            majorTickValues = CreateTickValues(this.ActualMinimum, this.ActualMaximum, this.ActualMajorStep);
  25.872 +            majorLabelValues = majorTickValues;
  25.873 +        }
  25.874 +
  25.875 +        /// <summary>
  25.876 +        /// 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.
  25.877 +        /// </summary>
  25.878 +        /// <param name="x">
  25.879 +        /// The coordinate.
  25.880 +        /// </param>
  25.881 +        /// <returns>
  25.882 +        /// The value.
  25.883 +        /// </returns>
  25.884 +        public virtual object GetValue(double x)
  25.885 +        {
  25.886 +            return x;
  25.887 +        }
  25.888 +
  25.889 +        /// <summary>
  25.890 +        /// Inverse transform the specified screen point.
  25.891 +        /// </summary>
  25.892 +        /// <param name="x">
  25.893 +        /// The x coordinate.
  25.894 +        /// </param>
  25.895 +        /// <param name="y">
  25.896 +        /// The y coordinate.
  25.897 +        /// </param>
  25.898 +        /// <param name="yaxis">
  25.899 +        /// The y-axis.
  25.900 +        /// </param>
  25.901 +        /// <returns>
  25.902 +        /// The data point.
  25.903 +        /// </returns>
  25.904 +        public virtual DataPoint InverseTransform(double x, double y, Axis yaxis)
  25.905 +        {
  25.906 +            return new DataPoint(this.InverseTransform(x), yaxis != null ? yaxis.InverseTransform(y) : 0);
  25.907 +        }
  25.908 +
  25.909 +        /// <summary>
  25.910 +        /// Inverse transform the specified screen coordinate. This method can only be used with non-polar coordinate systems.
  25.911 +        /// </summary>
  25.912 +        /// <param name="sx">
  25.913 +        /// The screen coordinate.
  25.914 +        /// </param>
  25.915 +        /// <returns>
  25.916 +        /// The value.
  25.917 +        /// </returns>
  25.918 +        public virtual double InverseTransform(double sx)
  25.919 +        {
  25.920 +            return this.PostInverseTransform((sx / this.scale) + this.offset);
  25.921 +        }
  25.922 +
  25.923 +        /// <summary>
  25.924 +        /// Determines whether this axis is horizontal.
  25.925 +        /// </summary>
  25.926 +        /// <returns>
  25.927 +        /// <c>true</c> if this axis is horizontal; otherwise, <c>false</c> .
  25.928 +        /// </returns>
  25.929 +        public bool IsHorizontal()
  25.930 +        {
  25.931 +            return this.position == AxisPosition.Top || this.position == AxisPosition.Bottom;
  25.932 +        }
  25.933 +
  25.934 +        /// <summary>
  25.935 +        /// Determines whether the specified value is valid.
  25.936 +        /// </summary>
  25.937 +        /// <param name="value">
  25.938 +        /// The value.
  25.939 +        /// </param>
  25.940 +        /// <returns>
  25.941 +        /// <c>true</c> if the specified value is valid; otherwise, <c>false</c> .
  25.942 +        /// </returns>
  25.943 +        public virtual bool IsValidValue(double value)
  25.944 +        {
  25.945 +            return !double.IsNaN(value) && !double.IsInfinity(value) && value < this.FilterMaxValue
  25.946 +                   && value > this.FilterMinValue && (this.FilterFunction == null || this.FilterFunction(value));
  25.947 +        }
  25.948 +
  25.949 +        /// <summary>
  25.950 +        /// Determines whether this axis is vertical.
  25.951 +        /// </summary>
  25.952 +        /// <returns>
  25.953 +        /// <c>true</c> if this axis is vertical; otherwise, <c>false</c> .
  25.954 +        /// </returns>
  25.955 +        public bool IsVertical()
  25.956 +        {
  25.957 +            return this.position == AxisPosition.Left || this.position == AxisPosition.Right;
  25.958 +        }
  25.959 +
  25.960 +        /// <summary>
  25.961 +        /// Determines whether the axis is used for X/Y values.
  25.962 +        /// </summary>
  25.963 +        /// <returns>
  25.964 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  25.965 +        /// </returns>
  25.966 +        public abstract bool IsXyAxis();
  25.967 +
  25.968 +        /// <summary>
  25.969 +        /// Measures the size of the axis (maximum axis label width/height).
  25.970 +        /// </summary>
  25.971 +        /// <param name="rc">
  25.972 +        /// The render context.
  25.973 +        /// </param>
  25.974 +        /// <returns>
  25.975 +        /// The size of the axis.
  25.976 +        /// </returns>
  25.977 +        public virtual OxySize Measure(IRenderContext rc)
  25.978 +        {
  25.979 +            IList<double> majorTickValues;
  25.980 +            IList<double> minorTickValues;
  25.981 +            IList<double> majorLabelValues;
  25.982 +
  25.983 +            this.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
  25.984 +
  25.985 +            var maximumTextSize = new OxySize();
  25.986 +            foreach (double v in majorLabelValues)
  25.987 +            {
  25.988 +                string s = this.FormatValue(v);
  25.989 +                var size = rc.MeasureText(s, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
  25.990 +                if (size.Width > maximumTextSize.Width)
  25.991 +                {
  25.992 +                    maximumTextSize.Width = size.Width;
  25.993 +                }
  25.994 +
  25.995 +                if (size.Height > maximumTextSize.Height)
  25.996 +                {
  25.997 +                    maximumTextSize.Height = size.Height;
  25.998 +                }
  25.999 +            }
 25.1000 +
 25.1001 +            var labelTextSize = rc.MeasureText(
 25.1002 +                this.ActualTitle, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
 25.1003 +
 25.1004 +            double width = 0;
 25.1005 +            double height = 0;
 25.1006 +
 25.1007 +            if (this.IsHorizontal())
 25.1008 +            {
 25.1009 +                switch (this.TickStyle)
 25.1010 +                {
 25.1011 +                    case TickStyle.Outside:
 25.1012 +                        height += this.MajorTickSize;
 25.1013 +                        break;
 25.1014 +                    case TickStyle.Crossing:
 25.1015 +                        height += this.MajorTickSize * 0.75;
 25.1016 +                        break;
 25.1017 +                }
 25.1018 +
 25.1019 +                height += this.AxisTickToLabelDistance;
 25.1020 +                height += maximumTextSize.Height;
 25.1021 +                if (labelTextSize.Height > 0)
 25.1022 +                {
 25.1023 +                    height += this.AxisTitleDistance;
 25.1024 +                    height += labelTextSize.Height;
 25.1025 +                }
 25.1026 +            }
 25.1027 +            else
 25.1028 +            {
 25.1029 +                switch (this.TickStyle)
 25.1030 +                {
 25.1031 +                    case TickStyle.Outside:
 25.1032 +                        width += this.MajorTickSize;
 25.1033 +                        break;
 25.1034 +                    case TickStyle.Crossing:
 25.1035 +                        width += this.MajorTickSize * 0.75;
 25.1036 +                        break;
 25.1037 +                }
 25.1038 +
 25.1039 +                width += this.AxisTickToLabelDistance;
 25.1040 +                width += maximumTextSize.Width;
 25.1041 +                if (labelTextSize.Height > 0)
 25.1042 +                {
 25.1043 +                    width += this.AxisTitleDistance;
 25.1044 +                    width += labelTextSize.Height;
 25.1045 +                }
 25.1046 +            }
 25.1047 +
 25.1048 +            return new OxySize(width, height);
 25.1049 +        }
 25.1050 +
 25.1051 +        /// <summary>
 25.1052 +        /// Pans the specified axis.
 25.1053 +        /// </summary>
 25.1054 +        /// <param name="ppt">
 25.1055 +        /// The previous point (screen coordinates).
 25.1056 +        /// </param>
 25.1057 +        /// <param name="cpt">
 25.1058 +        /// The current point (screen coordinates).
 25.1059 +        /// </param>
 25.1060 +        public virtual void Pan(ScreenPoint ppt, ScreenPoint cpt)
 25.1061 +        {
 25.1062 +            if (!this.IsPanEnabled)
 25.1063 +            {
 25.1064 +                return;
 25.1065 +            }
 25.1066 +
 25.1067 +            bool isHorizontal = this.IsHorizontal();
 25.1068 +
 25.1069 +            double dsx = isHorizontal ? cpt.X - ppt.X : cpt.Y - ppt.Y;
 25.1070 +            this.Pan(dsx);
 25.1071 +        }
 25.1072 +
 25.1073 +        /// <summary>
 25.1074 +        /// Pans the specified axis.
 25.1075 +        /// </summary>
 25.1076 +        /// <param name="delta">
 25.1077 +        /// The delta.
 25.1078 +        /// </param>
 25.1079 +        public virtual void Pan(double delta)
 25.1080 +        {
 25.1081 +            if (!this.IsPanEnabled)
 25.1082 +            {
 25.1083 +                return;
 25.1084 +            }
 25.1085 +
 25.1086 +            double dx = delta / this.Scale;
 25.1087 +
 25.1088 +            double newMinimum = this.ActualMinimum - dx;
 25.1089 +            double newMaximum = this.ActualMaximum - dx;
 25.1090 +            if (newMinimum < this.AbsoluteMinimum)
 25.1091 +            {
 25.1092 +                newMinimum = this.AbsoluteMinimum;
 25.1093 +                newMaximum = newMinimum + this.ActualMaximum - this.ActualMinimum;
 25.1094 +            }
 25.1095 +
 25.1096 +            if (newMaximum > this.AbsoluteMaximum)
 25.1097 +            {
 25.1098 +                newMaximum = this.AbsoluteMaximum;
 25.1099 +                newMinimum = newMaximum - (this.ActualMaximum - this.ActualMinimum);
 25.1100 +            }
 25.1101 +
 25.1102 +            this.ViewMinimum = newMinimum;
 25.1103 +            this.ViewMaximum = newMaximum;
 25.1104 +            this.UpdateActualMaxMin();
 25.1105 +
 25.1106 +            this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Pan));
 25.1107 +        }
 25.1108 +
 25.1109 +        /// <summary>
 25.1110 +        /// Renders the axis on the specified render context.
 25.1111 +        /// </summary>
 25.1112 +        /// <param name="rc">The render context.</param>
 25.1113 +        /// <param name="model">The model.</param>
 25.1114 +        /// <param name="axisLayer">The rendering order.</param>
 25.1115 +        /// <param name="pass">The pass.</param>
 25.1116 +        public virtual void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
 25.1117 +        {
 25.1118 +            var r = new HorizontalAndVerticalAxisRenderer(rc, model);
 25.1119 +            r.Render(this, pass);
 25.1120 +        }
 25.1121 +
 25.1122 +        /// <summary>
 25.1123 +        /// Resets the user's modification (zooming/panning) to minimum and maximum of this axis.
 25.1124 +        /// </summary>
 25.1125 +        public virtual void Reset()
 25.1126 +        {
 25.1127 +            this.ViewMinimum = double.NaN;
 25.1128 +            this.ViewMaximum = double.NaN;
 25.1129 +            this.UpdateActualMaxMin();
 25.1130 +            this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Reset));
 25.1131 +        }
 25.1132 +
 25.1133 +        /// <summary>
 25.1134 +        /// Returns a <see cref="System.String"/> that represents this instance.
 25.1135 +        /// </summary>
 25.1136 +        /// <returns>
 25.1137 +        /// A <see cref="System.String"/> that represents this instance.
 25.1138 +        /// </returns>
 25.1139 +        public override string ToString()
 25.1140 +        {
 25.1141 +            return string.Format(
 25.1142 +                CultureInfo.InvariantCulture,
 25.1143 +                "{0}({1}, {2}, {3}, {4})",
 25.1144 +                this.GetType().Name,
 25.1145 +                this.Position,
 25.1146 +                this.ActualMinimum,
 25.1147 +                this.ActualMaximum,
 25.1148 +                this.ActualMajorStep);
 25.1149 +        }
 25.1150 +
 25.1151 +        /// <summary>
 25.1152 +        /// Transforms the specified point to screen coordinates.
 25.1153 +        /// </summary>
 25.1154 +        /// <param name="x">
 25.1155 +        /// The x value (for the current axis).
 25.1156 +        /// </param>
 25.1157 +        /// <param name="y">
 25.1158 +        /// The y value.
 25.1159 +        /// </param>
 25.1160 +        /// <param name="yaxis">
 25.1161 +        /// The y axis.
 25.1162 +        /// </param>
 25.1163 +        /// <returns>
 25.1164 +        /// The transformed point.
 25.1165 +        /// </returns>
 25.1166 +        public virtual ScreenPoint Transform(double x, double y, Axis yaxis)
 25.1167 +        {
 25.1168 +            if (yaxis == null)
 25.1169 +            {
 25.1170 +                throw new NullReferenceException("Y axis should not be null when transforming.");
 25.1171 +            }
 25.1172 +
 25.1173 +            return new ScreenPoint(this.Transform(x), yaxis.Transform(y));
 25.1174 +        }
 25.1175 +
 25.1176 +        /// <summary>
 25.1177 +        /// Transforms the specified coordinate to screen coordinates. This method can only be used with non-polar coordinate systems.
 25.1178 +        /// </summary>
 25.1179 +        /// <param name="x">
 25.1180 +        /// The value.
 25.1181 +        /// </param>
 25.1182 +        /// <returns>
 25.1183 +        /// The transformed value (screen coordinate).
 25.1184 +        /// </returns>
 25.1185 +        public virtual double Transform(double x)
 25.1186 +        {
 25.1187 +            return (x - this.offset) * this.scale;
 25.1188 +
 25.1189 +            // return (this.PreTransform(x) - this.Offset) * this.Scale;
 25.1190 +        }
 25.1191 +
 25.1192 +        /// <summary>
 25.1193 +        /// Zoom to the specified scale.
 25.1194 +        /// </summary>
 25.1195 +        /// <param name="newScale">
 25.1196 +        /// The new scale.
 25.1197 +        /// </param>
 25.1198 +        public virtual void Zoom(double newScale)
 25.1199 +        {
 25.1200 +            double sx1 = this.Transform(this.ActualMaximum);
 25.1201 +            double sx0 = this.Transform(this.ActualMinimum);
 25.1202 +
 25.1203 +            double sgn = Math.Sign(this.scale);
 25.1204 +            double mid = (this.ActualMaximum + this.ActualMinimum) / 2;
 25.1205 +
 25.1206 +            double dx = (this.offset - mid) * this.scale;
 25.1207 +            this.scale = sgn * newScale;
 25.1208 +            this.offset = (dx / this.scale) + mid;
 25.1209 +
 25.1210 +            double newMaximum = this.InverseTransform(sx1);
 25.1211 +            double newMinimum = this.InverseTransform(sx0);
 25.1212 +
 25.1213 +            if (newMinimum < this.AbsoluteMinimum && newMaximum > this.AbsoluteMaximum)
 25.1214 +            {
 25.1215 +                newMinimum = this.AbsoluteMinimum;
 25.1216 +                newMaximum = this.AbsoluteMaximum;
 25.1217 +            }
 25.1218 +            else
 25.1219 +            {
 25.1220 +                if (newMinimum < this.AbsoluteMinimum)
 25.1221 +                {
 25.1222 +                    double d = newMaximum - newMinimum;
 25.1223 +                    newMinimum = this.AbsoluteMinimum;
 25.1224 +                    newMaximum = this.AbsoluteMinimum + d;
 25.1225 +                    if (newMaximum > this.AbsoluteMaximum)
 25.1226 +                    {
 25.1227 +                        newMaximum = this.AbsoluteMaximum;
 25.1228 +                    }
 25.1229 +                }
 25.1230 +                else if (newMaximum > this.AbsoluteMaximum)
 25.1231 +                {
 25.1232 +                    double d = newMaximum - newMinimum;
 25.1233 +                    newMaximum = this.AbsoluteMaximum;
 25.1234 +                    newMinimum = this.AbsoluteMaximum - d;
 25.1235 +                    if (newMinimum < this.AbsoluteMinimum)
 25.1236 +                    {
 25.1237 +                        newMinimum = this.AbsoluteMinimum;
 25.1238 +                    }
 25.1239 +                }
 25.1240 +            }
 25.1241 +
 25.1242 +            this.ViewMaximum = newMaximum;
 25.1243 +            this.ViewMinimum = newMinimum;
 25.1244 +            this.UpdateActualMaxMin();
 25.1245 +        }
 25.1246 +
 25.1247 +        /// <summary>
 25.1248 +        /// Zooms the axis to the range [x0,x1].
 25.1249 +        /// </summary>
 25.1250 +        /// <param name="x0">
 25.1251 +        /// The new minimum.
 25.1252 +        /// </param>
 25.1253 +        /// <param name="x1">
 25.1254 +        /// The new maximum.
 25.1255 +        /// </param>
 25.1256 +        public virtual void Zoom(double x0, double x1)
 25.1257 +        {
 25.1258 +            if (!this.IsZoomEnabled)
 25.1259 +            {
 25.1260 +                return;
 25.1261 +            }
 25.1262 +
 25.1263 +            double newMinimum = Math.Max(Math.Min(x0, x1), this.AbsoluteMinimum);
 25.1264 +            double newMaximum = Math.Min(Math.Max(x0, x1), this.AbsoluteMaximum);
 25.1265 +
 25.1266 +            this.ViewMinimum = newMinimum;
 25.1267 +            this.ViewMaximum = newMaximum;
 25.1268 +            this.UpdateActualMaxMin();
 25.1269 +
 25.1270 +            this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Zoom));
 25.1271 +        }
 25.1272 +
 25.1273 +        /// <summary>
 25.1274 +        /// Zooms the axis at the specified coordinate.
 25.1275 +        /// </summary>
 25.1276 +        /// <param name="factor">
 25.1277 +        /// The zoom factor.
 25.1278 +        /// </param>
 25.1279 +        /// <param name="x">
 25.1280 +        /// The coordinate to zoom at.
 25.1281 +        /// </param>
 25.1282 +        public virtual void ZoomAt(double factor, double x)
 25.1283 +        {
 25.1284 +            if (!this.IsZoomEnabled)
 25.1285 +            {
 25.1286 +                return;
 25.1287 +            }
 25.1288 +
 25.1289 +            double dx0 = (this.ActualMinimum - x) * this.scale;
 25.1290 +            double dx1 = (this.ActualMaximum - x) * this.scale;
 25.1291 +            this.scale *= factor;
 25.1292 +
 25.1293 +            double newMinimum = Math.Max((dx0 / this.scale) + x, this.AbsoluteMinimum);
 25.1294 +            double newMaximum = Math.Min((dx1 / this.scale) + x, this.AbsoluteMaximum);
 25.1295 +
 25.1296 +            this.ViewMinimum = newMinimum;
 25.1297 +            this.ViewMaximum = newMaximum;
 25.1298 +            this.UpdateActualMaxMin();
 25.1299 +
 25.1300 +            this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Zoom));
 25.1301 +        }
 25.1302 +
 25.1303 +        /// <summary>
 25.1304 +        /// Modifies the data range of the axis [DataMinimum,DataMaximum] to includes the specified value.
 25.1305 +        /// </summary>
 25.1306 +        /// <param name="value">
 25.1307 +        /// The value.
 25.1308 +        /// </param>
 25.1309 +        public virtual void Include(double value)
 25.1310 +        {
 25.1311 +            if (!this.IsValidValue(value))
 25.1312 +            {
 25.1313 +                return;
 25.1314 +            }
 25.1315 +
 25.1316 +            this.DataMinimum = double.IsNaN(this.DataMinimum) ? value : Math.Min(this.DataMinimum, value);
 25.1317 +            this.DataMaximum = double.IsNaN(this.DataMaximum) ? value : Math.Max(this.DataMaximum, value);
 25.1318 +        }
 25.1319 +
 25.1320 +        /// <summary>
 25.1321 +        /// Applies a transformation after the inverse transform of the value. This is used in logarithmic axis.
 25.1322 +        /// </summary>
 25.1323 +        /// <param name="x">
 25.1324 +        /// The value to transform.
 25.1325 +        /// </param>
 25.1326 +        /// <returns>
 25.1327 +        /// The transformed value.
 25.1328 +        /// </returns>
 25.1329 +        internal virtual double PostInverseTransform(double x)
 25.1330 +        {
 25.1331 +            return x;
 25.1332 +        }
 25.1333 +
 25.1334 +        /// <summary>
 25.1335 +        /// Applies a transformation before the transform the value. This is used in logarithmic axis.
 25.1336 +        /// </summary>
 25.1337 +        /// <param name="x">
 25.1338 +        /// The value to transform.
 25.1339 +        /// </param>
 25.1340 +        /// <returns>
 25.1341 +        /// The transformed value.
 25.1342 +        /// </returns>
 25.1343 +        internal virtual double PreTransform(double x)
 25.1344 +        {
 25.1345 +            return x;
 25.1346 +        }
 25.1347 +
 25.1348 +        /// <summary>
 25.1349 +        /// Resets the data maximum and minimum.
 25.1350 +        /// </summary>
 25.1351 +        internal virtual void ResetDataMaxMin()
 25.1352 +        {
 25.1353 +            this.DataMaximum = this.DataMinimum = double.NaN;
 25.1354 +        }
 25.1355 +
 25.1356 +        /// <summary>
 25.1357 +        /// 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'.
 25.1358 +        /// </summary>
 25.1359 +        internal virtual void UpdateActualMaxMin()
 25.1360 +        {
 25.1361 +            // Use the minimum/maximum of the data as default
 25.1362 +            this.ActualMaximum = this.DataMaximum;
 25.1363 +            this.ActualMinimum = this.DataMinimum;
 25.1364 +
 25.1365 +            double range = this.ActualMaximum - this.ActualMinimum;
 25.1366 +            double zeroRange = this.ActualMaximum > 0 ? this.ActualMaximum : 1;
 25.1367 +
 25.1368 +            if (!double.IsNaN(this.ViewMaximum))
 25.1369 +            {
 25.1370 +                // Override the ActualMaximum by the ViewMaximum value (from zoom/pan)
 25.1371 +                this.ActualMaximum = this.ViewMaximum;
 25.1372 +            }
 25.1373 +            else if (!double.IsNaN(this.Maximum))
 25.1374 +            {
 25.1375 +                // Override the ActualMaximum by the Maximum value
 25.1376 +                this.ActualMaximum = this.Maximum;
 25.1377 +            }
 25.1378 +            else
 25.1379 +            {
 25.1380 +                if (range < double.Epsilon)
 25.1381 +                {
 25.1382 +                    this.ActualMaximum += zeroRange * 0.5;
 25.1383 +                }
 25.1384 +
 25.1385 +                if (!double.IsNaN(this.ActualMinimum) && !double.IsNaN(this.ActualMaximum))
 25.1386 +                {
 25.1387 +                    double x1 = this.PreTransform(this.ActualMaximum);
 25.1388 +                    double x0 = this.PreTransform(this.ActualMinimum);
 25.1389 +                    double dx = this.MaximumPadding * (x1 - x0);
 25.1390 +                    this.ActualMaximum = this.PostInverseTransform(x1 + dx);
 25.1391 +                }
 25.1392 +            }
 25.1393 +
 25.1394 +            if (!double.IsNaN(this.ViewMinimum))
 25.1395 +            {
 25.1396 +                this.ActualMinimum = this.ViewMinimum;
 25.1397 +            }
 25.1398 +            else if (!double.IsNaN(this.Minimum))
 25.1399 +            {
 25.1400 +                this.ActualMinimum = this.Minimum;
 25.1401 +            }
 25.1402 +            else
 25.1403 +            {
 25.1404 +                if (range < double.Epsilon)
 25.1405 +                {
 25.1406 +                    this.ActualMinimum -= zeroRange * 0.5;
 25.1407 +                }
 25.1408 +
 25.1409 +                if (!double.IsNaN(this.ActualMaximum) && !double.IsNaN(this.ActualMaximum))
 25.1410 +                {
 25.1411 +                    double x1 = this.PreTransform(this.ActualMaximum);
 25.1412 +                    double x0 = this.PreTransform(this.ActualMinimum);
 25.1413 +                    double dx = this.MinimumPadding * (x1 - x0);
 25.1414 +                    this.ActualMinimum = this.PostInverseTransform(x0 - dx);
 25.1415 +                }
 25.1416 +            }
 25.1417 +
 25.1418 +            this.CoerceActualMaxMin();
 25.1419 +        }
 25.1420 +
 25.1421 +        /// <summary>
 25.1422 +        /// Updates the axis with information from the plot series.
 25.1423 +        /// </summary>
 25.1424 +        /// <param name="series">
 25.1425 +        /// The series collection.
 25.1426 +        /// </param>
 25.1427 +        /// <remarks>
 25.1428 +        /// This is used by the category axis that need to know the number of series using the axis.
 25.1429 +        /// </remarks>
 25.1430 +        internal virtual void UpdateFromSeries(IEnumerable<Series> series)
 25.1431 +        {
 25.1432 +        }
 25.1433 +
 25.1434 +        /// <summary>
 25.1435 +        /// Updates the actual minor and major step intervals.
 25.1436 +        /// </summary>
 25.1437 +        /// <param name="plotArea">
 25.1438 +        /// The plot area rectangle.
 25.1439 +        /// </param>
 25.1440 +        internal virtual void UpdateIntervals(OxyRect plotArea)
 25.1441 +        {
 25.1442 +            double labelSize = this.IntervalLength;
 25.1443 +            double length = this.IsHorizontal() ? plotArea.Width : plotArea.Height;
 25.1444 +            length *= Math.Abs(this.EndPosition - this.StartPosition);
 25.1445 +
 25.1446 +            this.ActualMajorStep = !double.IsNaN(this.MajorStep)
 25.1447 +                                       ? this.MajorStep
 25.1448 +                                       : this.CalculateActualInterval(length, labelSize);
 25.1449 +
 25.1450 +            this.ActualMinorStep = !double.IsNaN(this.MinorStep)
 25.1451 +                                       ? this.MinorStep
 25.1452 +                                       : this.CalculateMinorInterval(this.ActualMajorStep);
 25.1453 +
 25.1454 +            if (double.IsNaN(this.ActualMinorStep))
 25.1455 +            {
 25.1456 +                this.ActualMinorStep = 2;
 25.1457 +            }
 25.1458 +
 25.1459 +            if (double.IsNaN(this.ActualMajorStep))
 25.1460 +            {
 25.1461 +                this.ActualMajorStep = 10;
 25.1462 +            }
 25.1463 +
 25.1464 +            this.ActualStringFormat = this.StringFormat;
 25.1465 +
 25.1466 +            // if (ActualStringFormat==null)
 25.1467 +            // {
 25.1468 +            // if (ActualMaximum > 1e6 || ActualMinimum < 1e-6)
 25.1469 +            // ActualStringFormat = "#.#e-0";
 25.1470 +            // }
 25.1471 +        }
 25.1472 +
 25.1473 +        /// <summary>
 25.1474 +        /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
 25.1475 +        /// </summary>
 25.1476 +        /// <param name="bounds">
 25.1477 +        /// The bounds.
 25.1478 +        /// </param>
 25.1479 +        internal virtual void UpdateTransform(OxyRect bounds)
 25.1480 +        {
 25.1481 +            double x0 = bounds.Left;
 25.1482 +            double x1 = bounds.Right;
 25.1483 +            double y0 = bounds.Bottom;
 25.1484 +            double y1 = bounds.Top;
 25.1485 +
 25.1486 +            this.ScreenMin = new ScreenPoint(x0, y1);
 25.1487 +            this.ScreenMax = new ScreenPoint(x1, y0);
 25.1488 +
 25.1489 +            // this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);
 25.1490 +
 25.1491 +            // if (this.Position == AxisPosition.Angle)
 25.1492 +            // {
 25.1493 +            // this.scale = 2 * Math.PI / (this.ActualMaximum - this.ActualMinimum);
 25.1494 +            // this.Offset = this.ActualMinimum;
 25.1495 +            // return;
 25.1496 +            // }
 25.1497 +
 25.1498 +            // if (this.Position == AxisPosition.Magnitude)
 25.1499 +            // {
 25.1500 +            // this.ActualMinimum = 0;
 25.1501 +            // double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
 25.1502 +            // this.scale = 0.5 * r / (this.ActualMaximum - this.ActualMinimum);
 25.1503 +            // this.Offset = this.ActualMinimum;
 25.1504 +            // return;
 25.1505 +            // }
 25.1506 +            double a0 = this.IsHorizontal() ? x0 : y0;
 25.1507 +            double a1 = this.IsHorizontal() ? x1 : y1;
 25.1508 +
 25.1509 +            double dx = a1 - a0;
 25.1510 +            a1 = a0 + (this.EndPosition * dx);
 25.1511 +            a0 = a0 + (this.StartPosition * dx);
 25.1512 +            this.ScreenMin = new ScreenPoint(a0, a1);
 25.1513 +            this.ScreenMax = new ScreenPoint(a1, a0);
 25.1514 +
 25.1515 +            if (this.ActualMaximum - this.ActualMinimum < double.Epsilon)
 25.1516 +            {
 25.1517 +                this.ActualMaximum = this.ActualMinimum + 1;
 25.1518 +            }
 25.1519 +
 25.1520 +            double max = this.PreTransform(this.ActualMaximum);
 25.1521 +            double min = this.PreTransform(this.ActualMinimum);
 25.1522 +
 25.1523 +            double da = a0 - a1;
 25.1524 +            if (Math.Abs(da) > double.Epsilon)
 25.1525 +            {
 25.1526 +                this.offset = (a0 / da * max) - (a1 / da * min);
 25.1527 +            }
 25.1528 +            else
 25.1529 +            {
 25.1530 +                this.offset = 0;
 25.1531 +            }
 25.1532 +
 25.1533 +            double range = max - min;
 25.1534 +            if (Math.Abs(range) > double.Epsilon)
 25.1535 +            {
 25.1536 +                this.scale = (a1 - a0) / range;
 25.1537 +            }
 25.1538 +            else
 25.1539 +            {
 25.1540 +                this.scale = 1;
 25.1541 +            }
 25.1542 +        }
 25.1543 +
 25.1544 +        /// <summary>
 25.1545 +        /// Creates tick values at the specified interval.
 25.1546 +        /// </summary>
 25.1547 +        /// <param name="min">
 25.1548 +        /// The minimum coordinate.
 25.1549 +        /// </param>
 25.1550 +        /// <param name="max">
 25.1551 +        /// The maximum coordinate.
 25.1552 +        /// </param>
 25.1553 +        /// <param name="step">
 25.1554 +        /// The interval.
 25.1555 +        /// </param>
 25.1556 +        /// <returns>
 25.1557 +        /// A list of tick values.
 25.1558 +        /// </returns>
 25.1559 +        protected static IList<double> CreateTickValues(double min, double max, double step)
 25.1560 +        {
 25.1561 +            if (max <= min)
 25.1562 +            {
 25.1563 +                throw new ArgumentException("Axis: Maximum should be larger than minimum.", "max");
 25.1564 +            }
 25.1565 +
 25.1566 +            if (step <= 0)
 25.1567 +            {
 25.1568 +                throw new ArgumentException("Axis: Step cannot be zero or negative.", "step");
 25.1569 +            }
 25.1570 +
 25.1571 +            double x0 = Math.Round(min / step) * step;
 25.1572 +            int n = Math.Max((int)((max - min) / step), 1);
 25.1573 +            var values = new List<double>(n);
 25.1574 +
 25.1575 +            // Limit the maximum number of iterations (in case something is wrong with the step size)
 25.1576 +            int i = 0;
 25.1577 +            const int MaxIterations = 1000;
 25.1578 +            double x = x0;
 25.1579 +            double eps = step * 1e-3;
 25.1580 +
 25.1581 +            while (x <= max + eps && i < MaxIterations)
 25.1582 +            {
 25.1583 +                x = x0 + (i * step);
 25.1584 +                i++;
 25.1585 +                if (x >= min - eps && x <= max + eps)
 25.1586 +                {
 25.1587 +                    x = x.RemoveNoise();
 25.1588 +                    values.Add(x);
 25.1589 +                }
 25.1590 +            }
 25.1591 +
 25.1592 +            return values;
 25.1593 +        }
 25.1594 +
 25.1595 +        /// <summary>
 25.1596 +        /// Calculates the actual interval.
 25.1597 +        /// </summary>
 25.1598 +        /// <param name="availableSize">
 25.1599 +        /// Size of the available area.
 25.1600 +        /// </param>
 25.1601 +        /// <param name="maxIntervalSize">
 25.1602 +        /// Maximum length of the intervals.
 25.1603 +        /// </param>
 25.1604 +        /// <returns>
 25.1605 +        /// The calculate actual interval.
 25.1606 +        /// </returns>
 25.1607 +        protected virtual double CalculateActualInterval(double availableSize, double maxIntervalSize)
 25.1608 +        {
 25.1609 +            return this.CalculateActualInterval(availableSize, maxIntervalSize, this.ActualMaximum - this.ActualMinimum);
 25.1610 +        }
 25.1611 +
 25.1612 +        // alternative algorithm not in use
 25.1613 +        /*        private double CalculateActualIntervalOldAlgorithm(double availableSize, double maxIntervalSize)
 25.1614 +                {
 25.1615 +                    const int minimumTags = 5;
 25.1616 +                    const int maximumTags = 20;
 25.1617 +                    var numberOfTags = (int) (availableSize/maxIntervalSize);
 25.1618 +                    double range = ActualMaximum - ActualMinimum;
 25.1619 +                    double interval = range/numberOfTags;
 25.1620 +                    const int k1 = 10;
 25.1621 +                    interval = Math.Log10(interval/k1);
 25.1622 +                    interval = Math.Ceiling(interval);
 25.1623 +                    interval = Math.Pow(10, interval)*k1;
 25.1624 +
 25.1625 +                    if (range/interval > maximumTags) interval *= 5;
 25.1626 +                    if (range/interval < minimumTags) interval *= 0.5;
 25.1627 +
 25.1628 +                    if (interval <= 0) interval = 1;
 25.1629 +                    return interval;
 25.1630 +                }*/
 25.1631 +
 25.1632 +        // ===
 25.1633 +        // the following algorithm is from
 25.1634 +        // System.Windows.Controls.DataVisualization.Charting.LinearAxis.cs
 25.1635 +
 25.1636 +        // (c) Copyright Microsoft Corporation.
 25.1637 +        // This source is subject to the Microsoft Public License (MIT).
 25.1638 +        // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 25.1639 +        // All other rights reserved.
 25.1640 +
 25.1641 +        /// <summary>
 25.1642 +        /// Returns the actual interval to use to determine which values are displayed in the axis.
 25.1643 +        /// </summary>
 25.1644 +        /// <param name="availableSize">
 25.1645 +        /// The available size.
 25.1646 +        /// </param>
 25.1647 +        /// <param name="maxIntervalSize">
 25.1648 +        /// The maximum interval size.
 25.1649 +        /// </param>
 25.1650 +        /// <param name="range">
 25.1651 +        /// The range.
 25.1652 +        /// </param>
 25.1653 +        /// <returns>
 25.1654 +        /// Actual interval to use to determine which values are displayed in the axis.
 25.1655 +        /// </returns>
 25.1656 +        protected double CalculateActualInterval(double availableSize, double maxIntervalSize, double range)
 25.1657 +        {
 25.1658 +            if (availableSize <= 0)
 25.1659 +            {
 25.1660 +                return maxIntervalSize;
 25.1661 +            }
 25.1662 +
 25.1663 +            Func<double, double> exponent = x => Math.Ceiling(Math.Log(x, 10));
 25.1664 +            Func<double, double> mantissa = x => x / Math.Pow(10, exponent(x) - 1);
 25.1665 +
 25.1666 +            // reduce intervals for horizontal axis.
 25.1667 +            // double maxIntervals = Orientation == AxisOrientation.x ? MaximumAxisIntervalsPer200Pixels * 0.8 : MaximumAxisIntervalsPer200Pixels;
 25.1668 +            // real maximum interval count
 25.1669 +            double maxIntervalCount = availableSize / maxIntervalSize;
 25.1670 +
 25.1671 +            range = Math.Abs(range);
 25.1672 +            double interval = Math.Pow(10, exponent(range));
 25.1673 +            double tempInterval = interval;
 25.1674 +
 25.1675 +            // decrease interval until interval count becomes less than maxIntervalCount
 25.1676 +            while (true)
 25.1677 +            {
 25.1678 +                var m = (int)mantissa(tempInterval);
 25.1679 +                if (m == 5)
 25.1680 +                {
 25.1681 +                    // reduce 5 to 2
 25.1682 +                    tempInterval = (tempInterval / 2.5).RemoveNoiseFromDoubleMath();
 25.1683 +                }
 25.1684 +                else if (m == 2 || m == 1 || m == 10)
 25.1685 +                {
 25.1686 +                    // reduce 2 to 1, 10 to 5, 1 to 0.5
 25.1687 +                    tempInterval = (tempInterval / 2.0).RemoveNoiseFromDoubleMath();
 25.1688 +                }
 25.1689 +                else
 25.1690 +                {
 25.1691 +                    tempInterval = (tempInterval / 2.0).RemoveNoiseFromDoubleMath();
 25.1692 +                }
 25.1693 +
 25.1694 +                if (range / tempInterval > maxIntervalCount)
 25.1695 +                {
 25.1696 +                    break;
 25.1697 +                }
 25.1698 +
 25.1699 +                if (double.IsNaN(tempInterval) || double.IsInfinity(tempInterval))
 25.1700 +                {
 25.1701 +                    break;
 25.1702 +                }
 25.1703 +
 25.1704 +                interval = tempInterval;
 25.1705 +            }
 25.1706 +
 25.1707 +            return interval;
 25.1708 +        }
 25.1709 +
 25.1710 +        /// <summary>
 25.1711 +        /// The calculate minor interval.
 25.1712 +        /// </summary>
 25.1713 +        /// <param name="majorInterval">
 25.1714 +        /// The major interval.
 25.1715 +        /// </param>
 25.1716 +        /// <returns>
 25.1717 +        /// The minor interval.
 25.1718 +        /// </returns>
 25.1719 +        protected double CalculateMinorInterval(double majorInterval)
 25.1720 +        {
 25.1721 +            // if major interval is 100, the minor interval will be 20.
 25.1722 +            return majorInterval / 5;
 25.1723 +
 25.1724 +            // The following obsolete code divided major intervals into 4 minor intervals, unless the major interval's mantissa was 5.
 25.1725 +            // e.g. Major interval 100 => minor interval 25.
 25.1726 +
 25.1727 +            // Func<double, double> exponent = x => Math.Ceiling(Math.Log(x, 10));
 25.1728 +            // Func<double, double> mantissa = x => x / Math.Pow(10, exponent(x) - 1);
 25.1729 +            // var m = (int)mantissa(majorInterval);
 25.1730 +            // switch (m)
 25.1731 +            // {
 25.1732 +            // case 5:
 25.1733 +            // return majorInterval / 5;
 25.1734 +            // default:
 25.1735 +            // return majorInterval / 4;
 25.1736 +            // }
 25.1737 +        }
 25.1738 +
 25.1739 +        /// <summary>
 25.1740 +        /// Raises the AxisChanged event.
 25.1741 +        /// </summary>
 25.1742 +        /// <param name="args">
 25.1743 +        /// The <see cref="OxyPlot.Axes.AxisChangedEventArgs"/> instance containing the event data.
 25.1744 +        /// </param>
 25.1745 +        protected virtual void OnAxisChanged(AxisChangedEventArgs args)
 25.1746 +        {
 25.1747 +            this.UpdateActualMaxMin();
 25.1748 +
 25.1749 +            var handler = this.AxisChanged;
 25.1750 +            if (handler != null)
 25.1751 +            {
 25.1752 +                handler(this, args);
 25.1753 +            }
 25.1754 +        }
 25.1755 +    }
 25.1756 +}
 25.1757 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/External/OxyPlot/OxyPlot/Axes/AxisChangeTypes.cs	Sat Jun 08 16:53:22 2013 +0000
    26.3 @@ -0,0 +1,52 @@
    26.4 +// --------------------------------------------------------------------------------------------------------------------
    26.5 +// <copyright file="AxisChangeTypes.cs" company="OxyPlot">
    26.6 +//   The MIT License (MIT)
    26.7 +//
    26.8 +//   Copyright (c) 2012 Oystein Bjorke
    26.9 +//
   26.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   26.11 +//   copy of this software and associated documentation files (the
   26.12 +//   "Software"), to deal in the Software without restriction, including
   26.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   26.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   26.15 +//   permit persons to whom the Software is furnished to do so, subject to
   26.16 +//   the following conditions:
   26.17 +//
   26.18 +//   The above copyright notice and this permission notice shall be included
   26.19 +//   in all copies or substantial portions of the Software.
   26.20 +//
   26.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   26.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   26.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   26.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   26.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   26.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   26.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   26.28 +// </copyright>
   26.29 +// <summary>
   26.30 +//   Change types of the Axis.AxisChanged event.
   26.31 +// </summary>
   26.32 +// --------------------------------------------------------------------------------------------------------------------
   26.33 +namespace OxyPlot.Axes
   26.34 +{
   26.35 +    /// <summary>
   26.36 +    /// Specifies change types for the <see cref="Axis.AxisChanged"/> event.
   26.37 +    /// </summary>
   26.38 +    public enum AxisChangeTypes
   26.39 +    {
   26.40 +        /// <summary>
   26.41 +        /// The axis was zoomed by the user.
   26.42 +        /// </summary>
   26.43 +        Zoom,
   26.44 +
   26.45 +        /// <summary>
   26.46 +        /// The axis was panned by the user.
   26.47 +        /// </summary>
   26.48 +        Pan,
   26.49 +
   26.50 +        /// <summary>
   26.51 +        /// The axis zoom/pan was reset by the user.
   26.52 +        /// </summary>
   26.53 +        Reset
   26.54 +    }
   26.55 +}
   26.56 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/External/OxyPlot/OxyPlot/Axes/AxisChangedEventArgs.cs	Sat Jun 08 16:53:22 2013 +0000
    27.3 @@ -0,0 +1,57 @@
    27.4 +// --------------------------------------------------------------------------------------------------------------------
    27.5 +// <copyright file="AxisChangedEventArgs.cs" company="OxyPlot">
    27.6 +//   The MIT License (MIT)
    27.7 +//
    27.8 +//   Copyright (c) 2012 Oystein Bjorke
    27.9 +//
   27.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   27.11 +//   copy of this software and associated documentation files (the
   27.12 +//   "Software"), to deal in the Software without restriction, including
   27.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   27.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   27.15 +//   permit persons to whom the Software is furnished to do so, subject to
   27.16 +//   the following conditions:
   27.17 +//
   27.18 +//   The above copyright notice and this permission notice shall be included
   27.19 +//   in all copies or substantial portions of the Software.
   27.20 +//
   27.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   27.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   27.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   27.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   27.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   27.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   27.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   27.28 +// </copyright>
   27.29 +// <summary>
   27.30 +//   EventArgs for the Axis.AxisChanged event.
   27.31 +// </summary>
   27.32 +// --------------------------------------------------------------------------------------------------------------------
   27.33 +namespace OxyPlot.Axes
   27.34 +{
   27.35 +    using System;
   27.36 +
   27.37 +    /// <summary>
   27.38 +    /// Provides additional data for the <see cref="Axis.AxisChanged"/> event.
   27.39 +    /// </summary>
   27.40 +    public class AxisChangedEventArgs : EventArgs
   27.41 +    {
   27.42 +        /// <summary>
   27.43 +        /// Initializes a new instance of the <see cref="AxisChangedEventArgs"/> class.
   27.44 +        /// </summary>
   27.45 +        /// <param name="changeType">
   27.46 +        /// Type of the change.
   27.47 +        /// </param>
   27.48 +        public AxisChangedEventArgs(AxisChangeTypes changeType)
   27.49 +        {
   27.50 +            this.ChangeType = changeType;
   27.51 +        }
   27.52 +
   27.53 +        /// <summary>
   27.54 +        /// Gets or sets the type of the change.
   27.55 +        /// </summary>
   27.56 +        /// <value>The type of the change.</value>
   27.57 +        public AxisChangeTypes ChangeType { get; set; }
   27.58 +
   27.59 +    }
   27.60 +}
   27.61 \ No newline at end of file
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/External/OxyPlot/OxyPlot/Axes/AxisLayer.cs	Sat Jun 08 16:53:22 2013 +0000
    28.3 @@ -0,0 +1,47 @@
    28.4 +// --------------------------------------------------------------------------------------------------------------------
    28.5 +// <copyright file="AxisLayer.cs" company="OxyPlot">
    28.6 +//   The MIT License (MIT)
    28.7 +//
    28.8 +//   Copyright (c) 2012 Oystein Bjorke
    28.9 +//
   28.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   28.11 +//   copy of this software and associated documentation files (the
   28.12 +//   "Software"), to deal in the Software without restriction, including
   28.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   28.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   28.15 +//   permit persons to whom the Software is furnished to do so, subject to
   28.16 +//   the following conditions:
   28.17 +//
   28.18 +//   The above copyright notice and this permission notice shall be included
   28.19 +//   in all copies or substantial portions of the Software.
   28.20 +//
   28.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   28.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   28.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   28.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   28.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   28.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   28.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   28.28 +// </copyright>
   28.29 +// <summary>
   28.30 +//   Axis layer position.
   28.31 +// </summary>
   28.32 +// --------------------------------------------------------------------------------------------------------------------
   28.33 +namespace OxyPlot.Axes
   28.34 +{
   28.35 +    /// <summary>
   28.36 +    /// Specifies the layer position of an <see cref="Axis"/>.
   28.37 +    /// </summary>
   28.38 +    public enum AxisLayer
   28.39 +    {
   28.40 +        /// <summary>
   28.41 +        /// Below all series.
   28.42 +        /// </summary>
   28.43 +        BelowSeries,
   28.44 +
   28.45 +        /// <summary>
   28.46 +        /// Above all series.
   28.47 +        /// </summary>
   28.48 +        AboveSeries
   28.49 +    }
   28.50 +}
   28.51 \ No newline at end of file
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/External/OxyPlot/OxyPlot/Axes/AxisPosition.cs	Sat Jun 08 16:53:22 2013 +0000
    29.3 @@ -0,0 +1,62 @@
    29.4 +// --------------------------------------------------------------------------------------------------------------------
    29.5 +// <copyright file="AxisPosition.cs" company="OxyPlot">
    29.6 +//   The MIT License (MIT)
    29.7 +//
    29.8 +//   Copyright (c) 2012 Oystein Bjorke
    29.9 +//
   29.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   29.11 +//   copy of this software and associated documentation files (the
   29.12 +//   "Software"), to deal in the Software without restriction, including
   29.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   29.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   29.15 +//   permit persons to whom the Software is furnished to do so, subject to
   29.16 +//   the following conditions:
   29.17 +//
   29.18 +//   The above copyright notice and this permission notice shall be included
   29.19 +//   in all copies or substantial portions of the Software.
   29.20 +//
   29.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   29.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   29.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   29.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   29.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   29.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   29.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   29.28 +// </copyright>
   29.29 +// <summary>
   29.30 +//   Axis positions.
   29.31 +// </summary>
   29.32 +// --------------------------------------------------------------------------------------------------------------------
   29.33 +namespace OxyPlot.Axes
   29.34 +{
   29.35 +    /// <summary>
   29.36 +    /// Specifies the position of an <see cref="Axis"/>.
   29.37 +    /// </summary>
   29.38 +    public enum AxisPosition
   29.39 +    {
   29.40 +        /// <summary>
   29.41 +        /// No position.
   29.42 +        /// </summary>
   29.43 +        None,
   29.44 +
   29.45 +        /// <summary>
   29.46 +        /// Left of the plot area.
   29.47 +        /// </summary>
   29.48 +        Left,
   29.49 +
   29.50 +        /// <summary>
   29.51 +        /// Right of the plot area.
   29.52 +        /// </summary>
   29.53 +        Right,
   29.54 +
   29.55 +        /// <summary>
   29.56 +        /// Top of the plot area.
   29.57 +        /// </summary>
   29.58 +        Top,
   29.59 +
   29.60 +        /// <summary>
   29.61 +        /// Bottom of the plot area.
   29.62 +        /// </summary>
   29.63 +        Bottom
   29.64 +    }
   29.65 +}
   29.66 \ No newline at end of file
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/External/OxyPlot/OxyPlot/Axes/CategoryAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    30.3 @@ -0,0 +1,501 @@
    30.4 +// --------------------------------------------------------------------------------------------------------------------
    30.5 +// <copyright file="CategoryAxis.cs" company="OxyPlot">
    30.6 +//   The MIT License (MIT)
    30.7 +//
    30.8 +//   Copyright (c) 2012 Oystein Bjorke
    30.9 +//
   30.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   30.11 +//   copy of this software and associated documentation files (the
   30.12 +//   "Software"), to deal in the Software without restriction, including
   30.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   30.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   30.15 +//   permit persons to whom the Software is furnished to do so, subject to
   30.16 +//   the following conditions:
   30.17 +//
   30.18 +//   The above copyright notice and this permission notice shall be included
   30.19 +//   in all copies or substantial portions of the Software.
   30.20 +//
   30.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   30.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   30.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   30.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   30.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   30.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   30.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   30.28 +// </copyright>
   30.29 +// <summary>
   30.30 +//   Represents a category axes.
   30.31 +// </summary>
   30.32 +// --------------------------------------------------------------------------------------------------------------------
   30.33 +namespace OxyPlot.Axes
   30.34 +{
   30.35 +    using System.Collections;
   30.36 +    using System.Collections.Generic;
   30.37 +    using System.Globalization;
   30.38 +    using System.Linq;
   30.39 +
   30.40 +    using OxyPlot.Series;
   30.41 +
   30.42 +    /// <summary>
   30.43 +    /// Represents a category axis.
   30.44 +    /// </summary>
   30.45 +    /// <remarks>
   30.46 +    /// 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).
   30.47 +    /// </remarks>
   30.48 +    public class CategoryAxis : LinearAxis
   30.49 +    {
   30.50 +        /// <summary>
   30.51 +        /// Initializes a new instance of the <see cref="CategoryAxis"/> class.
   30.52 +        /// </summary>
   30.53 +        public CategoryAxis()
   30.54 +        {
   30.55 +            this.Labels = new List<string>();
   30.56 +            this.TickStyle = TickStyle.Outside;
   30.57 +            this.Position = AxisPosition.Bottom;
   30.58 +            this.MinimumPadding = 0;
   30.59 +            this.MaximumPadding = 0;
   30.60 +            this.MajorStep = 1;
   30.61 +            this.GapWidth = 1;
   30.62 +        }
   30.63 +
   30.64 +        /// <summary>
   30.65 +        /// Initializes a new instance of the <see cref="CategoryAxis"/> class.
   30.66 +        /// </summary>
   30.67 +        /// <param name="position">The position.</param>
   30.68 +        /// <param name="title">The title.</param>
   30.69 +        /// <param name="categories">The categories.</param>
   30.70 +        public CategoryAxis(AxisPosition position, string title = null, params string[] categories)
   30.71 +            : this(title, categories)
   30.72 +        {
   30.73 +            this.Position = position;
   30.74 +        }
   30.75 +
   30.76 +        /// <summary>
   30.77 +        /// Initializes a new instance of the <see cref="CategoryAxis"/> class.
   30.78 +        /// </summary>
   30.79 +        /// <param name="title">
   30.80 +        /// The title.
   30.81 +        /// </param>
   30.82 +        /// <param name="categories">
   30.83 +        /// The categories.
   30.84 +        /// </param>
   30.85 +        public CategoryAxis(string title, params string[] categories)
   30.86 +            : this()
   30.87 +        {
   30.88 +            this.Title = title;
   30.89 +            if (categories != null)
   30.90 +            {
   30.91 +                foreach (var c in categories)
   30.92 +                {
   30.93 +                    this.Labels.Add(c);
   30.94 +                }
   30.95 +            }
   30.96 +        }
   30.97 +
   30.98 +        /// <summary>
   30.99 +        /// Gets or sets the gap width.
  30.100 +        /// </summary>
  30.101 +        /// <remarks>
  30.102 +        /// 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.
  30.103 +        /// </remarks>
  30.104 +        public double GapWidth { get; set; }
  30.105 +
  30.106 +        /// <summary>
  30.107 +        /// 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.
  30.108 +        /// </summary>
  30.109 +        public bool IsTickCentered { get; set; }
  30.110 +
  30.111 +        /// <summary>
  30.112 +        /// Gets or sets the items source (used to update the Labels collection).
  30.113 +        /// </summary>
  30.114 +        /// <value>
  30.115 +        /// The items source.
  30.116 +        /// </value>
  30.117 +        public IEnumerable ItemsSource { get; set; }
  30.118 +
  30.119 +        /// <summary>
  30.120 +        /// Gets or sets the data field for the labels.
  30.121 +        /// </summary>
  30.122 +        public string LabelField { get; set; }
  30.123 +
  30.124 +        /// <summary>
  30.125 +        /// Gets or sets the labels collection.
  30.126 +        /// </summary>
  30.127 +        public IList<string> Labels { get; set; }
  30.128 +
  30.129 +        /// <summary>
  30.130 +        /// Gets or sets the current offset of the bars (not used for stacked bar series).
  30.131 +        /// </summary>
  30.132 +        internal double[] BarOffset { get; set; }
  30.133 +
  30.134 +        /// <summary>
  30.135 +        /// Gets or sets the max value per StackIndex and Label (only used for stacked bar series).
  30.136 +        /// </summary>
  30.137 +        internal double[,] MaxValue { get; set; }
  30.138 +
  30.139 +        /// <summary>
  30.140 +        /// Gets or sets the maximal width of all labels
  30.141 +        /// </summary>
  30.142 +        internal double MaxWidth { get; set; }
  30.143 +
  30.144 +        /// <summary>
  30.145 +        /// Gets or sets the min value per StackIndex and Label (only used for stacked bar series).
  30.146 +        /// </summary>
  30.147 +        internal double[,] MinValue { get; set; }
  30.148 +
  30.149 +        /// <summary>
  30.150 +        /// Gets or sets per StackIndex and Label the base value for negative values of stacked bar series.
  30.151 +        /// </summary>
  30.152 +        internal double[,] NegativeBaseValues { get; set; }
  30.153 +
  30.154 +        /// <summary>
  30.155 +        /// Gets or sets per StackIndex and Label the base value for positive values of stacked bar series.
  30.156 +        /// </summary>
  30.157 +        internal double[,] PositiveBaseValues { get; set; }
  30.158 +
  30.159 +        /// <summary>
  30.160 +        /// Gets or sets the StackIndexMapping. The mapping indicates to which rank a specific stack index belongs.
  30.161 +        /// </summary>
  30.162 +        internal Dictionary<string, int> StackIndexMapping { get; set; }
  30.163 +
  30.164 +        /// <summary>
  30.165 +        /// Gets or sets the offset of the bars per StackIndex and Label (only used for stacked bar series).
  30.166 +        /// </summary>
  30.167 +        internal double[,] StackedBarOffset { get; set; }
  30.168 +
  30.169 +        /// <summary>
  30.170 +        /// Gets or sets sum of the widths of the single bars per label. This is used to find the bar width of BarSeries
  30.171 +        /// </summary>
  30.172 +        internal double[] TotalWidthPerCategory { get; set; }
  30.173 +
  30.174 +        /// <summary>
  30.175 +        /// Fills the specified array.
  30.176 +        /// </summary>
  30.177 +        /// <param name="array">
  30.178 +        /// The array.
  30.179 +        /// </param>
  30.180 +        /// <param name="value">
  30.181 +        /// The value.
  30.182 +        /// </param>
  30.183 +        public static void Fill(double[] array, double value)
  30.184 +        {
  30.185 +            for (var i = 0; i < array.Length; i++)
  30.186 +            {
  30.187 +                array[i] = value;
  30.188 +            }
  30.189 +        }
  30.190 +
  30.191 +        /// <summary>
  30.192 +        /// Fills the specified array.
  30.193 +        /// </summary>
  30.194 +        /// <param name="array">
  30.195 +        /// The array.
  30.196 +        /// </param>
  30.197 +        /// <param name="value">
  30.198 +        /// The value.
  30.199 +        /// </param>
  30.200 +        public static void Fill(double[,] array, double value)
  30.201 +        {
  30.202 +            for (var i = 0; i < array.GetLength(0); i++)
  30.203 +            {
  30.204 +                for (var j = 0; j < array.GetLength(1); j++)
  30.205 +                {
  30.206 +                    array[i, j] = value;
  30.207 +                }
  30.208 +            }
  30.209 +        }
  30.210 +
  30.211 +        /// <summary>
  30.212 +        /// Formats the value to be used on the axis.
  30.213 +        /// </summary>
  30.214 +        /// <param name="x">
  30.215 +        /// The value.
  30.216 +        /// </param>
  30.217 +        /// <returns>
  30.218 +        /// The formatted value.
  30.219 +        /// </returns>
  30.220 +        public override string FormatValue(double x)
  30.221 +        {
  30.222 +            var index = (int)x;
  30.223 +            if (this.Labels != null && index >= 0 && index < this.Labels.Count)
  30.224 +            {
  30.225 +                return this.Labels[index];
  30.226 +            }
  30.227 +
  30.228 +            return null;
  30.229 +        }
  30.230 +
  30.231 +        /// <summary>
  30.232 +        /// Formats the value to be used by the tracker.
  30.233 +        /// </summary>
  30.234 +        /// <param name="x">
  30.235 +        /// The value.
  30.236 +        /// </param>
  30.237 +        /// <returns>
  30.238 +        /// The formatted value.
  30.239 +        /// </returns>
  30.240 +        public override string FormatValueForTracker(double x)
  30.241 +        {
  30.242 +            return this.FormatValue(x);
  30.243 +        }
  30.244 +
  30.245 +        /// <summary>
  30.246 +        /// Gets the category value.
  30.247 +        /// </summary>
  30.248 +        /// <param name="categoryIndex">
  30.249 +        /// Index of the category.
  30.250 +        /// </param>
  30.251 +        /// <param name="stackIndex">
  30.252 +        /// Index of the stack.
  30.253 +        /// </param>
  30.254 +        /// <param name="actualBarWidth">
  30.255 +        /// Actual width of the bar.
  30.256 +        /// </param>
  30.257 +        /// <returns>
  30.258 +        /// The get category value.
  30.259 +        /// </returns>
  30.260 +        public double GetCategoryValue(int categoryIndex, int stackIndex, double actualBarWidth)
  30.261 +        {
  30.262 +            var offsetBegin = this.StackedBarOffset[stackIndex, categoryIndex];
  30.263 +            var offsetEnd = this.StackedBarOffset[stackIndex + 1, categoryIndex];
  30.264 +            return categoryIndex - 0.5 + ((offsetEnd + offsetBegin - actualBarWidth) * 0.5);
  30.265 +        }
  30.266 +
  30.267 +        /// <summary>
  30.268 +        /// Gets the category value.
  30.269 +        /// </summary>
  30.270 +        /// <param name="categoryIndex">
  30.271 +        /// Index of the category.
  30.272 +        /// </param>
  30.273 +        /// <returns>
  30.274 +        /// The get category value.
  30.275 +        /// </returns>
  30.276 +        public double GetCategoryValue(int categoryIndex)
  30.277 +        {
  30.278 +            return categoryIndex - 0.5 + this.BarOffset[categoryIndex];
  30.279 +        }
  30.280 +
  30.281 +        /// <summary>
  30.282 +        /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
  30.283 +        /// </summary>
  30.284 +        /// <param name="majorLabelValues">
  30.285 +        /// The major label values.
  30.286 +        /// </param>
  30.287 +        /// <param name="majorTickValues">
  30.288 +        /// The major tick values.
  30.289 +        /// </param>
  30.290 +        /// <param name="minorTickValues">
  30.291 +        /// The minor tick values.
  30.292 +        /// </param>
  30.293 +        public override void GetTickValues(
  30.294 +            out IList<double> majorLabelValues, out IList<double> majorTickValues, out IList<double> minorTickValues)
  30.295 +        {
  30.296 +            base.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
  30.297 +            minorTickValues.Clear();
  30.298 +
  30.299 +            if (!this.IsTickCentered)
  30.300 +            {
  30.301 +                // Subtract 0.5 from the label values to get the tick values.
  30.302 +                // Add one extra tick at the end.
  30.303 +                var mv = new List<double>(majorLabelValues.Count);
  30.304 +                mv.AddRange(majorLabelValues.Select(v => v - 0.5));
  30.305 +                if (mv.Count > 0)
  30.306 +                {
  30.307 +                    mv.Add(mv[mv.Count - 1] + 1);
  30.308 +                }
  30.309 +
  30.310 +                majorTickValues = mv;
  30.311 +            }
  30.312 +        }
  30.313 +
  30.314 +        /// <summary>
  30.315 +        /// 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.
  30.316 +        /// </summary>
  30.317 +        /// <param name="x">
  30.318 +        /// The coordinate.
  30.319 +        /// </param>
  30.320 +        /// <returns>
  30.321 +        /// The value.
  30.322 +        /// </returns>
  30.323 +        public override object GetValue(double x)
  30.324 +        {
  30.325 +            return this.FormatValue(x);
  30.326 +        }
  30.327 +
  30.328 +        /// <summary>
  30.329 +        /// 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'.
  30.330 +        /// </summary>
  30.331 +        internal override void UpdateActualMaxMin()
  30.332 +        {
  30.333 +            // Update the DataMinimum/DataMaximum from the number of categories
  30.334 +            this.Include(-0.5);
  30.335 +
  30.336 +            if (this.Labels != null && this.Labels.Count > 0)
  30.337 +            {
  30.338 +                this.Include((this.Labels.Count - 1) + 0.5);
  30.339 +            }
  30.340 +            else
  30.341 +            {
  30.342 +                this.Include(0.5);
  30.343 +            }
  30.344 +
  30.345 +            base.UpdateActualMaxMin();
  30.346 +
  30.347 +            this.MinorStep = 1;
  30.348 +        }
  30.349 +
  30.350 +        /// <summary>
  30.351 +        /// Updates the axis with information from the plot series.
  30.352 +        /// </summary>
  30.353 +        /// <param name="series">
  30.354 +        /// The series collection.
  30.355 +        /// </param>
  30.356 +        /// <remarks>
  30.357 +        /// This is used by the category axis that need to know the number of series using the axis.
  30.358 +        /// </remarks>
  30.359 +        internal override void UpdateFromSeries(IEnumerable<Series> series)
  30.360 +        {
  30.361 +            if (this.Labels.Count == 0)
  30.362 +            {
  30.363 +                this.TotalWidthPerCategory = null;
  30.364 +                this.MaxWidth = double.NaN;
  30.365 +                this.BarOffset = null;
  30.366 +                this.StackedBarOffset = null;
  30.367 +                this.StackIndexMapping = null;
  30.368 +                this.PositiveBaseValues = null;
  30.369 +                this.NegativeBaseValues = null;
  30.370 +                this.MaxValue = null;
  30.371 +                this.MinValue = null;
  30.372 +
  30.373 +                return;
  30.374 +            }
  30.375 +
  30.376 +            this.TotalWidthPerCategory = new double[this.Labels.Count];
  30.377 +
  30.378 +            var usedSeries = series.Where(s => s.IsUsing(this)).ToList();
  30.379 +
  30.380 +            // Add width of stacked series
  30.381 +            var categorizedSeries = usedSeries.OfType<CategorizedSeries>().ToList();
  30.382 +            var stackedSeries = categorizedSeries.OfType<IStackableSeries>().Where(s => s.IsStacked).ToList();
  30.383 +            var stackIndices = stackedSeries.Select(s => s.StackGroup).Distinct().ToList();
  30.384 +            var stackRankBarWidth = new Dictionary<int, double>();
  30.385 +            for (var j = 0; j < stackIndices.Count; j++)
  30.386 +            {
  30.387 +                var maxBarWidth =
  30.388 +                    stackedSeries.Where(s => s.StackGroup == stackIndices[j]).Select(
  30.389 +                        s => ((CategorizedSeries)s).GetBarWidth()).Concat(new[] { 0.0 }).Max();
  30.390 +                for (var i = 0; i < this.Labels.Count; i++)
  30.391 +                {
  30.392 +                    int k = 0;
  30.393 +                    if (
  30.394 +                        stackedSeries.SelectMany(s => ((CategorizedSeries)s).GetItems()).Any(
  30.395 +                            item => item.GetCategoryIndex(k++) == i))
  30.396 +                    {
  30.397 +                        this.TotalWidthPerCategory[i] += maxBarWidth;
  30.398 +                    }
  30.399 +                }
  30.400 +
  30.401 +                stackRankBarWidth[j] = maxBarWidth;
  30.402 +            }
  30.403 +
  30.404 +            // Add width of unstacked series
  30.405 +            var unstackedBarSeries =
  30.406 +                categorizedSeries.Where(s => !(s is IStackableSeries) || !((IStackableSeries)s).IsStacked).ToList();
  30.407 +            foreach (var s in unstackedBarSeries)
  30.408 +            {
  30.409 +                for (var i = 0; i < this.Labels.Count; i++)
  30.410 +                {
  30.411 +                    int j = 0;
  30.412 +                    var numberOfItems = s.GetItems().Count(item => item.GetCategoryIndex(j++) == i);
  30.413 +                    this.TotalWidthPerCategory[i] += s.GetBarWidth() * numberOfItems;
  30.414 +                }
  30.415 +            }
  30.416 +
  30.417 +            this.MaxWidth = this.TotalWidthPerCategory.Max();
  30.418 +
  30.419 +            // Calculate BarOffset and StackedBarOffset
  30.420 +            this.BarOffset = new double[this.Labels.Count];
  30.421 +            this.StackedBarOffset = new double[stackIndices.Count + 1, this.Labels.Count];
  30.422 +
  30.423 +            var factor = 0.5 / (1 + this.GapWidth) / this.MaxWidth;
  30.424 +            for (var i = 0; i < this.Labels.Count; i++)
  30.425 +            {
  30.426 +                this.BarOffset[i] = 0.5 - (this.TotalWidthPerCategory[i] * factor);
  30.427 +            }
  30.428 +
  30.429 +            for (var j = 0; j <= stackIndices.Count; j++)
  30.430 +            {
  30.431 +                for (var i = 0; i < this.Labels.Count; i++)
  30.432 +                {
  30.433 +                    int k = 0;
  30.434 +                    if (
  30.435 +                        stackedSeries.SelectMany(s => ((CategorizedSeries)s).GetItems()).All(
  30.436 +                            item => item.GetCategoryIndex(k++) != i))
  30.437 +                    {
  30.438 +                        continue;
  30.439 +                    }
  30.440 +
  30.441 +                    this.StackedBarOffset[j, i] = this.BarOffset[i];
  30.442 +                    if (j < stackIndices.Count)
  30.443 +                    {
  30.444 +                        this.BarOffset[i] += stackRankBarWidth[j] / (1 + this.GapWidth) / this.MaxWidth;
  30.445 +                    }
  30.446 +                }
  30.447 +            }
  30.448 +
  30.449 +            stackIndices.Sort();
  30.450 +            this.StackIndexMapping = new Dictionary<string, int>();
  30.451 +            for (var i = 0; i < stackIndices.Count; i++)
  30.452 +            {
  30.453 +                this.StackIndexMapping.Add(stackIndices[i], i);
  30.454 +            }
  30.455 +
  30.456 +            this.PositiveBaseValues = new double[stackIndices.Count, this.Labels.Count];
  30.457 +            Fill(this.PositiveBaseValues, double.NaN);
  30.458 +            this.NegativeBaseValues = new double[stackIndices.Count, this.Labels.Count];
  30.459 +            Fill(this.NegativeBaseValues, double.NaN);
  30.460 +
  30.461 +            this.MaxValue = new double[stackIndices.Count, this.Labels.Count];
  30.462 +            Fill(this.MaxValue, double.NaN);
  30.463 +            this.MinValue = new double[stackIndices.Count, this.Labels.Count];
  30.464 +            Fill(this.MinValue, double.NaN);
  30.465 +        }
  30.466 +
  30.467 +        /// <summary>
  30.468 +        /// Creates Labels list if no labels were set
  30.469 +        /// </summary>
  30.470 +        /// <param name="series">
  30.471 +        /// The list of series which are rendered
  30.472 +        /// </param>
  30.473 +        internal void UpdateLabels(IEnumerable<Series> series)
  30.474 +        {
  30.475 +            if (this.ItemsSource != null)
  30.476 +            {
  30.477 +                this.Labels.Clear();
  30.478 +                ReflectionHelper.FillList(this.ItemsSource, this.LabelField, this.Labels);
  30.479 +            }
  30.480 +
  30.481 +            if (this.Labels.Count == 0)
  30.482 +            {
  30.483 +                foreach (var s in series)
  30.484 +                {
  30.485 +                    if (!s.IsUsing(this))
  30.486 +                    {
  30.487 +                        continue;
  30.488 +                    }
  30.489 +
  30.490 +                    var bsb = s as CategorizedSeries;
  30.491 +                    if (bsb != null)
  30.492 +                    {
  30.493 +                        int max = bsb.GetItems().Count;
  30.494 +                        while (this.Labels.Count < max)
  30.495 +                        {
  30.496 +                            this.Labels.Add((this.Labels.Count + 1).ToString(CultureInfo.InvariantCulture));
  30.497 +                        }
  30.498 +                    }
  30.499 +                }
  30.500 +            }
  30.501 +        }
  30.502 +
  30.503 +    }
  30.504 +}
  30.505 \ No newline at end of file
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/External/OxyPlot/OxyPlot/Axes/ColorAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    31.3 @@ -0,0 +1,283 @@
    31.4 +// --------------------------------------------------------------------------------------------------------------------
    31.5 +// <copyright file="ColorAxis.cs" company="OxyPlot">
    31.6 +//   The MIT License (MIT)
    31.7 +//
    31.8 +//   Copyright (c) 2012 Oystein Bjorke
    31.9 +//
   31.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   31.11 +//   copy of this software and associated documentation files (the
   31.12 +//   "Software"), to deal in the Software without restriction, including
   31.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   31.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   31.15 +//   permit persons to whom the Software is furnished to do so, subject to
   31.16 +//   the following conditions:
   31.17 +//
   31.18 +//   The above copyright notice and this permission notice shall be included
   31.19 +//   in all copies or substantial portions of the Software.
   31.20 +//
   31.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   31.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   31.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   31.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   31.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   31.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   31.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   31.28 +// </copyright>
   31.29 +// <summary>
   31.30 +//   The color axis.
   31.31 +// </summary>
   31.32 +// --------------------------------------------------------------------------------------------------------------------
   31.33 +namespace OxyPlot.Axes
   31.34 +{
   31.35 +    using System;
   31.36 +    using System.Collections.Generic;
   31.37 +
   31.38 +    /// <summary>
   31.39 +    /// Represents a color axis.
   31.40 +    /// </summary>
   31.41 +    public class ColorAxis : Axis
   31.42 +    {
   31.43 +        /// <summary>
   31.44 +        /// Initializes a new instance of the <see cref="ColorAxis"/> class.
   31.45 +        /// </summary>
   31.46 +        public ColorAxis()
   31.47 +        {
   31.48 +            this.Position = AxisPosition.None;
   31.49 +            this.IsPanEnabled = false;
   31.50 +            this.IsZoomEnabled = false;
   31.51 +        }
   31.52 +
   31.53 +        /// <summary>
   31.54 +        /// Gets or sets the color of values above the maximum value.
   31.55 +        /// </summary>
   31.56 +        /// <value> The color of the high values. </value>
   31.57 +        public OxyColor HighColor { get; set; }
   31.58 +
   31.59 +        /// <summary>
   31.60 +        /// Gets or sets the color of values below the minimum value.
   31.61 +        /// </summary>
   31.62 +        /// <value> The color of the low values. </value>
   31.63 +        public OxyColor LowColor { get; set; }
   31.64 +
   31.65 +        /// <summary>
   31.66 +        /// Gets or sets the palette.
   31.67 +        /// </summary>
   31.68 +        /// <value> The palette. </value>
   31.69 +        public OxyPalette Palette { get; set; }
   31.70 +
   31.71 +        /// <summary>
   31.72 +        /// Gets the color.
   31.73 +        /// </summary>
   31.74 +        /// <param name="paletteIndex">
   31.75 +        /// The color map index (less than NumberOfEntries).
   31.76 +        /// </param>
   31.77 +        /// <returns>
   31.78 +        /// The color.
   31.79 +        /// </returns>
   31.80 +        public OxyColor GetColor(int paletteIndex)
   31.81 +        {
   31.82 +            if (paletteIndex == 0)
   31.83 +            {
   31.84 +                return this.LowColor;
   31.85 +            }
   31.86 +
   31.87 +            if (paletteIndex == this.Palette.Colors.Count + 1)
   31.88 +            {
   31.89 +                return this.HighColor;
   31.90 +            }
   31.91 +
   31.92 +            return this.Palette.Colors[paletteIndex - 1];
   31.93 +        }
   31.94 +
   31.95 +        /// <summary>
   31.96 +        /// Gets the color for the specified value.
   31.97 +        /// </summary>
   31.98 +        /// <param name="value">
   31.99 +        /// The value.
  31.100 +        /// </param>
  31.101 +        /// <returns>
  31.102 +        /// The color.
  31.103 +        /// </returns>
  31.104 +        public OxyColor GetColor(double value)
  31.105 +        {
  31.106 +            return this.GetColor(this.GetPaletteIndex(value));
  31.107 +        }
  31.108 +
  31.109 +        /// <summary>
  31.110 +        /// Gets the colors.
  31.111 +        /// </summary>
  31.112 +        /// <returns>The colors.</returns>
  31.113 +        public IEnumerable<OxyColor> GetColors()
  31.114 +        {
  31.115 +            yield return this.LowColor;
  31.116 +            foreach (var color in this.Palette.Colors)
  31.117 +            {
  31.118 +                yield return color;
  31.119 +            }
  31.120 +
  31.121 +            yield return this.HighColor;
  31.122 +        }
  31.123 +
  31.124 +        /// <summary>
  31.125 +        /// Gets the palette index of the specified value.
  31.126 +        /// </summary>
  31.127 +        /// <param name="value">
  31.128 +        /// The value.
  31.129 +        /// </param>
  31.130 +        /// <returns>
  31.131 +        /// The palette index.
  31.132 +        /// </returns>
  31.133 +        /// <remarks>
  31.134 +        /// If the value is less than minimum, 0 is returned. If the value is greater than maximum, Palette.Colors.Count+1 is returned.
  31.135 +        /// </remarks>
  31.136 +        public int GetPaletteIndex(double value)
  31.137 +        {
  31.138 +            if (this.LowColor != null && value < this.Minimum)
  31.139 +            {
  31.140 +                return 0;
  31.141 +            }
  31.142 +
  31.143 +            if (this.HighColor != null && value > this.Maximum)
  31.144 +            {
  31.145 +                return this.Palette.Colors.Count + 1;
  31.146 +            }
  31.147 +
  31.148 +            int index = 1 + (int)((value - this.ActualMinimum) / (this.ActualMaximum - this.ActualMinimum) * this.Palette.Colors.Count);
  31.149 +
  31.150 +            if (index < 1)
  31.151 +            {
  31.152 +                index = 1;
  31.153 +            }
  31.154 +
  31.155 +            if (index > this.Palette.Colors.Count)
  31.156 +            {
  31.157 +                index = this.Palette.Colors.Count;
  31.158 +            }
  31.159 +
  31.160 +            return index;
  31.161 +        }
  31.162 +
  31.163 +        /// <summary>
  31.164 +        /// Determines whether the axis is used for X/Y values.
  31.165 +        /// </summary>
  31.166 +        /// <returns>
  31.167 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  31.168 +        /// </returns>
  31.169 +        public override bool IsXyAxis()
  31.170 +        {
  31.171 +            return false;
  31.172 +        }
  31.173 +
  31.174 +        /// <summary>
  31.175 +        /// Renders the axis on the specified render context.
  31.176 +        /// </summary>
  31.177 +        /// <param name="rc">The render context.</param>
  31.178 +        /// <param name="model">The model.</param>
  31.179 +        /// <param name="axisLayer">The rendering order.</param>
  31.180 +        /// <param name="pass">The render pass.</param>
  31.181 +        public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
  31.182 +        {
  31.183 +            if (this.Position == AxisPosition.None)
  31.184 +            {
  31.185 +                return;
  31.186 +            }
  31.187 +
  31.188 +            if (pass == 0)
  31.189 +            {
  31.190 +                double left = model.PlotArea.Left;
  31.191 +                double top = model.PlotArea.Top;
  31.192 +                double width = this.MajorTickSize - 2;
  31.193 +                double height = this.MajorTickSize - 2;
  31.194 +
  31.195 +                switch (this.Position)
  31.196 +                {
  31.197 +                    case AxisPosition.Left:
  31.198 +                        left = model.PlotArea.Left - this.PositionTierMinShift - width;
  31.199 +                        top = model.PlotArea.Top;
  31.200 +                        break;
  31.201 +                    case AxisPosition.Right:
  31.202 +                        left = model.PlotArea.Right + this.PositionTierMinShift;
  31.203 +                        top = model.PlotArea.Top;
  31.204 +                        break;
  31.205 +                    case AxisPosition.Top:
  31.206 +                        left = model.PlotArea.Left;
  31.207 +                        top = model.PlotArea.Top - this.PositionTierMinShift - height;
  31.208 +                        break;
  31.209 +                    case AxisPosition.Bottom:
  31.210 +                        left = model.PlotArea.Left;
  31.211 +                        top = model.PlotArea.Bottom + this.PositionTierMinShift;
  31.212 +                        break;
  31.213 +                }
  31.214 +
  31.215 +                Action<double, double, OxyColor> drawColorRect = (ylow, yhigh, color) =>
  31.216 +                    {
  31.217 +                        double ymin = Math.Min(ylow, yhigh);
  31.218 +                        double ymax = Math.Max(ylow, yhigh);
  31.219 +                        rc.DrawRectangle(
  31.220 +                            this.IsHorizontal()
  31.221 +                                ? new OxyRect(ymin, top, ymax - ymin, height)
  31.222 +                                : new OxyRect(left, ymin, width, ymax - ymin),
  31.223 +                            color,
  31.224 +                            null);
  31.225 +                    };
  31.226 +
  31.227 +                int n = this.Palette.Colors.Count;
  31.228 +                for (int i = 0; i < n; i++)
  31.229 +                {
  31.230 +                    double ylow = this.Transform(this.GetLowValue(i));
  31.231 +                    double yhigh = this.Transform(this.GetHighValue(i));
  31.232 +                    drawColorRect(ylow, yhigh, this.Palette.Colors[i]);
  31.233 +                }
  31.234 +
  31.235 +                double highLowLength = 10;
  31.236 +                if (this.IsHorizontal())
  31.237 +                {
  31.238 +                    highLowLength *= -1;
  31.239 +                }
  31.240 +
  31.241 +                if (this.LowColor != null)
  31.242 +                {
  31.243 +                    double ylow = this.Transform(this.ActualMinimum);
  31.244 +                    drawColorRect(ylow, ylow + highLowLength, this.LowColor);
  31.245 +                }
  31.246 +
  31.247 +                if (this.HighColor != null)
  31.248 +                {
  31.249 +                    double yhigh = this.Transform(this.ActualMaximum);
  31.250 +                    drawColorRect(yhigh, yhigh - highLowLength, this.HighColor);
  31.251 +                }
  31.252 +            }
  31.253 +
  31.254 +            base.Render(rc, model, axisLayer, pass);
  31.255 +        }
  31.256 +
  31.257 +        /// <summary>
  31.258 +        /// Gets the high value of the specified palette index.
  31.259 +        /// </summary>
  31.260 +        /// <param name="paletteIndex">
  31.261 +        /// Index of the palette.
  31.262 +        /// </param>
  31.263 +        /// <returns>
  31.264 +        /// The value.
  31.265 +        /// </returns>
  31.266 +        protected double GetHighValue(int paletteIndex)
  31.267 +        {
  31.268 +            return this.GetLowValue(paletteIndex + 1);
  31.269 +        }
  31.270 +
  31.271 +        /// <summary>
  31.272 +        /// Gets the low value of the specified palette index.
  31.273 +        /// </summary>
  31.274 +        /// <param name="paletteIndex">
  31.275 +        /// Index of the palette.
  31.276 +        /// </param>
  31.277 +        /// <returns>
  31.278 +        /// The value.
  31.279 +        /// </returns>
  31.280 +        protected double GetLowValue(int paletteIndex)
  31.281 +        {
  31.282 +            return ((double)paletteIndex / this.Palette.Colors.Count * (this.ActualMaximum - this.ActualMinimum))
  31.283 +                   + this.ActualMinimum;
  31.284 +        }
  31.285 +    }
  31.286 +}
  31.287 \ No newline at end of file
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    32.3 @@ -0,0 +1,679 @@
    32.4 +// --------------------------------------------------------------------------------------------------------------------
    32.5 +// <copyright file="DateTimeAxis.cs" company="OxyPlot">
    32.6 +//   The MIT License (MIT)
    32.7 +//   
    32.8 +//   Copyright (c) 2012 Oystein Bjorke
    32.9 +//   
   32.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   32.11 +//   copy of this software and associated documentation files (the
   32.12 +//   "Software"), to deal in the Software without restriction, including
   32.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   32.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   32.15 +//   permit persons to whom the Software is furnished to do so, subject to
   32.16 +//   the following conditions:
   32.17 +//   
   32.18 +//   The above copyright notice and this permission notice shall be included
   32.19 +//   in all copies or substantial portions of the Software.
   32.20 +//   
   32.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   32.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   32.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   32.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   32.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   32.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   32.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   32.28 +// </copyright>
   32.29 +// <summary>
   32.30 +//   Represents a DateTime axis.
   32.31 +// </summary>
   32.32 +// --------------------------------------------------------------------------------------------------------------------
   32.33 +
   32.34 +namespace OxyPlot.Axes
   32.35 +{
   32.36 +    using System;
   32.37 +    using System.Collections.Generic;
   32.38 +    using System.Collections.ObjectModel;
   32.39 +    using System.Globalization;
   32.40 +    using System.Linq;
   32.41 +
   32.42 +    /// <summary>
   32.43 +    /// Represents a axis presenting <see cref="System.DateTime"/> values.
   32.44 +    /// </summary>
   32.45 +    /// <remarks>
   32.46 +    /// The actual numeric values on the axis are days since 1900/01/01.
   32.47 +    /// Use the static ToDouble and ToDateTime to convert numeric values to DateTimes.
   32.48 +    /// The StringFormat value can be used to force formatting of the axis values
   32.49 +    /// "yyyy-MM-dd" shows date
   32.50 +    /// "w" or "ww" shows week number
   32.51 +    /// "h:mm" shows hours and minutes
   32.52 +    /// </remarks>
   32.53 +    public class DateTimeAxis : LinearAxis
   32.54 +    {
   32.55 +        /// <summary>
   32.56 +        /// The time origin.
   32.57 +        /// </summary>
   32.58 +        /// <remarks>
   32.59 +        /// Same date values as Excel
   32.60 +        /// </remarks>
   32.61 +        private static DateTime timeOrigin = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
   32.62 +
   32.63 +        /// <summary>
   32.64 +        /// The actual interval type.
   32.65 +        /// </summary>
   32.66 +        private DateTimeIntervalType actualIntervalType;
   32.67 +
   32.68 +        /// <summary>
   32.69 +        /// The actual minor interval type.
   32.70 +        /// </summary>
   32.71 +        private DateTimeIntervalType actualMinorIntervalType;
   32.72 +
   32.73 +        /// <summary>
   32.74 +        /// Initializes a new instance of the <see cref = "DateTimeAxis" /> class.
   32.75 +        /// </summary>
   32.76 +        public DateTimeAxis()
   32.77 +        {
   32.78 +            this.Position = AxisPosition.Bottom;
   32.79 +            this.IntervalType = DateTimeIntervalType.Auto;
   32.80 +            this.FirstDayOfWeek = DayOfWeek.Monday;
   32.81 +            this.CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek;
   32.82 +        }
   32.83 +
   32.84 +        /// <summary>
   32.85 +        /// Initializes a new instance of the <see cref="DateTimeAxis"/> class.
   32.86 +        /// </summary>
   32.87 +        /// <param name="pos">
   32.88 +        /// The position.
   32.89 +        /// </param>
   32.90 +        /// <param name="title">
   32.91 +        /// The axis title.
   32.92 +        /// </param>
   32.93 +        /// <param name="format">
   32.94 +        /// The string format for the axis values.
   32.95 +        /// </param>
   32.96 +        /// <param name="intervalType">
   32.97 +        /// The interval type.
   32.98 +        /// </param>
   32.99 +        public DateTimeAxis(
  32.100 +            AxisPosition pos = AxisPosition.Bottom,
  32.101 +            string title = null,
  32.102 +            string format = null,
  32.103 +            DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
  32.104 +            : base(pos, title)
  32.105 +        {
  32.106 +            this.FirstDayOfWeek = DayOfWeek.Monday;
  32.107 +            this.CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek;
  32.108 +
  32.109 +            this.StringFormat = format;
  32.110 +            this.IntervalType = intervalType;
  32.111 +        }
  32.112 +
  32.113 +        /// <summary>
  32.114 +        /// Initializes a new instance of the <see cref="DateTimeAxis"/> class.
  32.115 +        /// </summary>
  32.116 +        /// <param name="firstDateTime">
  32.117 +        /// The first date/time on the axis.
  32.118 +        /// </param>
  32.119 +        /// <param name="lastDateTime">
  32.120 +        /// The last date/time on the axis.
  32.121 +        /// </param>
  32.122 +        /// <param name="pos">
  32.123 +        /// The position of the axis.
  32.124 +        /// </param>
  32.125 +        /// <param name="title">
  32.126 +        /// The axis title.
  32.127 +        /// </param>
  32.128 +        /// <param name="format">
  32.129 +        /// The string format for the axis values.
  32.130 +        /// </param>
  32.131 +        /// <param name="intervalType">
  32.132 +        /// The interval type.
  32.133 +        /// </param>
  32.134 +        [Obsolete]
  32.135 +        public DateTimeAxis(
  32.136 +            DateTime firstDateTime,
  32.137 +            DateTime lastDateTime,
  32.138 +            AxisPosition pos = AxisPosition.Bottom,
  32.139 +            string title = null,
  32.140 +            string format = null,
  32.141 +            DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
  32.142 +            : this(pos, title, format, intervalType)
  32.143 +        {
  32.144 +            this.Minimum = ToDouble(firstDateTime);
  32.145 +            this.Maximum = ToDouble(lastDateTime);
  32.146 +        }
  32.147 +
  32.148 +        /// <summary>
  32.149 +        /// Initializes a new instance of the <see cref="DateTimeAxis" /> class.
  32.150 +        /// </summary>
  32.151 +        /// <param name="pos">The position of the axis.</param>
  32.152 +        /// <param name="firstDateTime">The first date/time on the axis.</param>
  32.153 +        /// <param name="lastDateTime">The last date/time on the axis.</param>
  32.154 +        /// <param name="title">The axis title.</param>
  32.155 +        /// <param name="format">The string format for the axis values.</param>
  32.156 +        /// <param name="intervalType">The interval type.</param>
  32.157 +        public DateTimeAxis(
  32.158 +        AxisPosition pos,
  32.159 +        DateTime firstDateTime,
  32.160 +        DateTime lastDateTime,
  32.161 +        string title = null,
  32.162 +        string format = null,
  32.163 +        DateTimeIntervalType intervalType = DateTimeIntervalType.Auto)
  32.164 +            : this(pos, title, format, intervalType)
  32.165 +        {
  32.166 +            this.Minimum = ToDouble(firstDateTime);
  32.167 +            this.Maximum = ToDouble(lastDateTime);
  32.168 +        }
  32.169 +
  32.170 +        /// <summary>
  32.171 +        /// Gets or sets CalendarWeekRule.
  32.172 +        /// </summary>
  32.173 +        public CalendarWeekRule CalendarWeekRule { get; set; }
  32.174 +
  32.175 +        /// <summary>
  32.176 +        /// Gets or sets FirstDayOfWeek.
  32.177 +        /// </summary>
  32.178 +        public DayOfWeek FirstDayOfWeek { get; set; }
  32.179 +
  32.180 +        /// <summary>
  32.181 +        /// Gets or sets IntervalType.
  32.182 +        /// </summary>
  32.183 +        public DateTimeIntervalType IntervalType { get; set; }
  32.184 +
  32.185 +        /// <summary>
  32.186 +        /// Gets or sets MinorIntervalType.
  32.187 +        /// </summary>
  32.188 +        public DateTimeIntervalType MinorIntervalType { get; set; }
  32.189 +
  32.190 +        /// <summary>
  32.191 +        /// Gets or sets the time zone (used when formatting date/time values).
  32.192 +        /// </summary>
  32.193 +        /// <remarks>
  32.194 +        /// No date/time conversion will be performed if this property is null.
  32.195 +        /// </remarks>
  32.196 +        /// <value>
  32.197 +        /// The time zone info.
  32.198 +        /// </value>
  32.199 +        public TimeZoneInfo TimeZone { get; set; }
  32.200 +
  32.201 +        /// <summary>
  32.202 +        /// Creates a data point.
  32.203 +        /// </summary>
  32.204 +        /// <param name="x">
  32.205 +        /// The x value.
  32.206 +        /// </param>
  32.207 +        /// <param name="y">
  32.208 +        /// The y value.
  32.209 +        /// </param>
  32.210 +        /// <returns>
  32.211 +        /// A data point.
  32.212 +        /// </returns>
  32.213 +        public static DataPoint CreateDataPoint(DateTime x, double y)
  32.214 +        {
  32.215 +            return new DataPoint(ToDouble(x), y);
  32.216 +        }
  32.217 +
  32.218 +        /// <summary>
  32.219 +        /// Creates a data point.
  32.220 +        /// </summary>
  32.221 +        /// <param name="x">
  32.222 +        /// The x value.
  32.223 +        /// </param>
  32.224 +        /// <param name="y">
  32.225 +        /// The y value. 
  32.226 +        /// </param>
  32.227 +        /// <returns>
  32.228 +        /// A data point.
  32.229 +        /// </returns>
  32.230 +        public static DataPoint CreateDataPoint(DateTime x, DateTime y)
  32.231 +        {
  32.232 +            return new DataPoint(ToDouble(x), ToDouble(y));
  32.233 +        }
  32.234 +
  32.235 +        /// <summary>
  32.236 +        /// Creates a data point.
  32.237 +        /// </summary>
  32.238 +        /// <param name="x">
  32.239 +        /// The x value.
  32.240 +        /// </param>
  32.241 +        /// <param name="y">
  32.242 +        /// The y value.
  32.243 +        /// </param>
  32.244 +        /// <returns>
  32.245 +        /// A data point.
  32.246 +        /// </returns>
  32.247 +        public static DataPoint CreateDataPoint(double x, DateTime y)
  32.248 +        {
  32.249 +            return new DataPoint(x, ToDouble(y));
  32.250 +        }
  32.251 +
  32.252 +        /// <summary>
  32.253 +        /// Converts a numeric representation of the date (number of days after the time origin) to a DateTime structure.
  32.254 +        /// </summary>
  32.255 +        /// <param name="value">
  32.256 +        /// The number of days after the time origin.
  32.257 +        /// </param>
  32.258 +        /// <returns>
  32.259 +        /// A date/time structure.
  32.260 +        /// </returns>
  32.261 +        public static DateTime ToDateTime(double value)
  32.262 +        {
  32.263 +            if (double.IsNaN(value))
  32.264 +            {
  32.265 +                return new DateTime();
  32.266 +            }
  32.267 +
  32.268 +            return timeOrigin.AddDays(value - 1);
  32.269 +        }
  32.270 +
  32.271 +        /// <summary>
  32.272 +        /// Converts a DateTime to days after the time origin.
  32.273 +        /// </summary>
  32.274 +        /// <param name="value">
  32.275 +        /// The date/time structure.
  32.276 +        /// </param>
  32.277 +        /// <returns>
  32.278 +        /// The number of days after the time origin.
  32.279 +        /// </returns>
  32.280 +        public static double ToDouble(DateTime value)
  32.281 +        {
  32.282 +            var span = value - timeOrigin;
  32.283 +            return span.TotalDays + 1;
  32.284 +        }
  32.285 +
  32.286 +        /// <summary>
  32.287 +        /// Formats the specified value by the axis' ActualStringFormat.
  32.288 +        /// </summary>
  32.289 +        /// <param name="x">
  32.290 +        /// The x.
  32.291 +        /// </param>
  32.292 +        /// <returns>
  32.293 +        /// The formatted DateTime value
  32.294 +        /// </returns>
  32.295 +        public override string FormatValue(double x)
  32.296 +        {
  32.297 +            // convert the double value to a DateTime
  32.298 +            var time = ToDateTime(x);
  32.299 +
  32.300 +            // If a time zone is specified, convert the time
  32.301 +            if (this.TimeZone != null)
  32.302 +            {
  32.303 +                time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
  32.304 +            }
  32.305 +
  32.306 +            string fmt = this.ActualStringFormat;
  32.307 +            if (fmt == null)
  32.308 +            {
  32.309 +                return time.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern);
  32.310 +            }
  32.311 +
  32.312 +            int week = this.GetWeek(time);
  32.313 +            fmt = fmt.Replace("ww", week.ToString("00"));
  32.314 +            fmt = fmt.Replace("w", week.ToString(CultureInfo.InvariantCulture));
  32.315 +            return time.ToString(fmt, this.ActualCulture);
  32.316 +        }
  32.317 +
  32.318 +        /// <summary>
  32.319 +        /// Gets the tick values.
  32.320 +        /// </summary>
  32.321 +        /// <param name="majorLabelValues">
  32.322 +        /// The major label values.
  32.323 +        /// </param>
  32.324 +        /// <param name="majorTickValues">
  32.325 +        /// The major tick values.
  32.326 +        /// </param>
  32.327 +        /// <param name="minorTickValues">
  32.328 +        /// The minor tick values.
  32.329 +        /// </param>
  32.330 +        public override void GetTickValues(
  32.331 +            out IList<double> majorLabelValues, out IList<double> majorTickValues, out IList<double> minorTickValues)
  32.332 +        {
  32.333 +            minorTickValues = this.CreateDateTimeTickValues(
  32.334 +                this.ActualMinimum, this.ActualMaximum, this.ActualMinorStep, this.actualMinorIntervalType);
  32.335 +            majorTickValues = this.CreateDateTimeTickValues(
  32.336 +                this.ActualMinimum, this.ActualMaximum, this.ActualMajorStep, this.actualIntervalType);
  32.337 +            majorLabelValues = majorTickValues;
  32.338 +        }
  32.339 +
  32.340 +        /// <summary>
  32.341 +        /// Gets the value from an axis coordinate, converts from double to the correct data type if necessary.
  32.342 +        /// e.g. DateTimeAxis returns the DateTime and CategoryAxis returns category strings.
  32.343 +        /// </summary>
  32.344 +        /// <param name="x">
  32.345 +        /// The coordinate.
  32.346 +        /// </param>
  32.347 +        /// <returns>
  32.348 +        /// The value.
  32.349 +        /// </returns>
  32.350 +        public override object GetValue(double x)
  32.351 +        {
  32.352 +            var time = ToDateTime(x);
  32.353 +
  32.354 +            if (this.TimeZone != null)
  32.355 +            {
  32.356 +                time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
  32.357 +            }
  32.358 +
  32.359 +            return time;
  32.360 +        }
  32.361 +
  32.362 +        /// <summary>
  32.363 +        /// Updates the intervals.
  32.364 +        /// </summary>
  32.365 +        /// <param name="plotArea">
  32.366 +        /// The plot area.
  32.367 +        /// </param>
  32.368 +        internal override void UpdateIntervals(OxyRect plotArea)
  32.369 +        {
  32.370 +            base.UpdateIntervals(plotArea);
  32.371 +            switch (this.actualIntervalType)
  32.372 +            {
  32.373 +                case DateTimeIntervalType.Years:
  32.374 +                    this.ActualMinorStep = 31;
  32.375 +                    this.actualMinorIntervalType = DateTimeIntervalType.Years;
  32.376 +                    if (this.ActualStringFormat == null)
  32.377 +                    {
  32.378 +                        this.ActualStringFormat = "yyyy";
  32.379 +                    }
  32.380 +
  32.381 +                    break;
  32.382 +                case DateTimeIntervalType.Months:
  32.383 +                    this.actualMinorIntervalType = DateTimeIntervalType.Months;
  32.384 +                    if (this.ActualStringFormat == null)
  32.385 +                    {
  32.386 +                        this.ActualStringFormat = "yyyy-MM-dd";
  32.387 +                    }
  32.388 +
  32.389 +                    break;
  32.390 +                case DateTimeIntervalType.Weeks:
  32.391 +                    this.actualMinorIntervalType = DateTimeIntervalType.Days;
  32.392 +                    this.ActualMajorStep = 7;
  32.393 +                    this.ActualMinorStep = 1;
  32.394 +                    if (this.ActualStringFormat == null)
  32.395 +                    {
  32.396 +                        this.ActualStringFormat = "yyyy/ww";
  32.397 +                    }
  32.398 +
  32.399 +                    break;
  32.400 +                case DateTimeIntervalType.Days:
  32.401 +                    this.ActualMinorStep = this.ActualMajorStep;
  32.402 +                    if (this.ActualStringFormat == null)
  32.403 +                    {
  32.404 +                        this.ActualStringFormat = "yyyy-MM-dd";
  32.405 +                    }
  32.406 +
  32.407 +                    break;
  32.408 +                case DateTimeIntervalType.Hours:
  32.409 +                    this.ActualMinorStep = this.ActualMajorStep;
  32.410 +                    if (this.ActualStringFormat == null)
  32.411 +                    {
  32.412 +                        this.ActualStringFormat = "HH:mm";
  32.413 +                    }
  32.414 +
  32.415 +                    break;
  32.416 +                case DateTimeIntervalType.Minutes:
  32.417 +                    this.ActualMinorStep = this.ActualMajorStep;
  32.418 +                    if (this.ActualStringFormat == null)
  32.419 +                    {
  32.420 +                        this.ActualStringFormat = "HH:mm";
  32.421 +                    }
  32.422 +
  32.423 +                    break;
  32.424 +                case DateTimeIntervalType.Seconds:
  32.425 +                    this.ActualMinorStep = this.ActualMajorStep;
  32.426 +                    if (this.ActualStringFormat == null)
  32.427 +                    {
  32.428 +                        this.ActualStringFormat = "HH:mm:ss";
  32.429 +                    }
  32.430 +
  32.431 +                    break;
  32.432 +                case DateTimeIntervalType.Manual:
  32.433 +                    break;
  32.434 +                case DateTimeIntervalType.Auto:
  32.435 +                    break;
  32.436 +            }
  32.437 +        }
  32.438 +
  32.439 +        /// <summary>
  32.440 +        /// Calculates the actual interval.
  32.441 +        /// </summary>
  32.442 +        /// <param name="availableSize">
  32.443 +        /// Size of the available area.
  32.444 +        /// </param>
  32.445 +        /// <param name="maxIntervalSize">
  32.446 +        /// Maximum length of the intervals.
  32.447 +        /// </param>
  32.448 +        /// <returns>
  32.449 +        /// The calculate actual interval.
  32.450 +        /// </returns>
  32.451 +        protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
  32.452 +        {
  32.453 +            const double Year = 365.25;
  32.454 +            const double Month = 30.5;
  32.455 +            const double Week = 7;
  32.456 +            const double Day = 1.0;
  32.457 +            const double Hour = Day / 24;
  32.458 +            const double Minute = Hour / 60;
  32.459 +            const double Second = Minute / 60;
  32.460 +
  32.461 +            double range = Math.Abs(this.ActualMinimum - this.ActualMaximum);
  32.462 +
  32.463 +            var goodIntervals = new[]
  32.464 +                                    {
  32.465 +                                        Second, 2 * Second, 5 * Second, 10 * Second, 30 * Second, Minute, 2 * Minute, 
  32.466 +                                        5 * Minute, 10 * Minute, 30 * Minute, Hour, 4 * Hour, 8 * Hour, 12 * Hour, Day, 
  32.467 +                                        2 * Day, 5 * Day, Week, 2 * Week, Month, 2 * Month, 3 * Month, 4 * Month, 
  32.468 +                                        6 * Month, Year
  32.469 +                                    };
  32.470 +
  32.471 +            double interval = goodIntervals[0];
  32.472 +
  32.473 +            int maxNumberOfIntervals = Math.Max((int)(availableSize / maxIntervalSize), 2);
  32.474 +
  32.475 +            while (true)
  32.476 +            {
  32.477 +                if (range / interval < maxNumberOfIntervals)
  32.478 +                {
  32.479 +                    break;
  32.480 +                }
  32.481 +
  32.482 +                double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
  32.483 +                if (Math.Abs(nextInterval) < double.Epsilon)
  32.484 +                {
  32.485 +                    nextInterval = interval * 2;
  32.486 +                }
  32.487 +
  32.488 +                interval = nextInterval;
  32.489 +            }
  32.490 +
  32.491 +            this.actualIntervalType = this.IntervalType;
  32.492 +            this.actualMinorIntervalType = this.MinorIntervalType;
  32.493 +
  32.494 +            if (this.IntervalType == DateTimeIntervalType.Auto)
  32.495 +            {
  32.496 +                this.actualIntervalType = DateTimeIntervalType.Seconds;
  32.497 +                if (interval >= 1.0 / 24 / 60)
  32.498 +                {
  32.499 +                    this.actualIntervalType = DateTimeIntervalType.Minutes;
  32.500 +                }
  32.501 +
  32.502 +                if (interval >= 1.0 / 24)
  32.503 +                {
  32.504 +                    this.actualIntervalType = DateTimeIntervalType.Hours;
  32.505 +                }
  32.506 +
  32.507 +                if (interval >= 1)
  32.508 +                {
  32.509 +                    this.actualIntervalType = DateTimeIntervalType.Days;
  32.510 +                }
  32.511 +
  32.512 +                if (interval >= 30)
  32.513 +                {
  32.514 +                    this.actualIntervalType = DateTimeIntervalType.Months;
  32.515 +                }
  32.516 +
  32.517 +                if (range >= 365.25)
  32.518 +                {
  32.519 +                    this.actualIntervalType = DateTimeIntervalType.Years;
  32.520 +                }
  32.521 +            }
  32.522 +
  32.523 +            if (this.actualIntervalType == DateTimeIntervalType.Months)
  32.524 +            {
  32.525 +                double monthsRange = range / 30.5;
  32.526 +                interval = this.CalculateActualInterval(availableSize, maxIntervalSize, monthsRange);
  32.527 +            }
  32.528 +
  32.529 +            if (this.actualIntervalType == DateTimeIntervalType.Years)
  32.530 +            {
  32.531 +                double yearsRange = range / 365.25;
  32.532 +                interval = this.CalculateActualInterval(availableSize, maxIntervalSize, yearsRange);
  32.533 +            }
  32.534 +
  32.535 +            if (this.actualMinorIntervalType == DateTimeIntervalType.Auto)
  32.536 +            {
  32.537 +                switch (this.actualIntervalType)
  32.538 +                {
  32.539 +                    case DateTimeIntervalType.Years:
  32.540 +                        this.actualMinorIntervalType = DateTimeIntervalType.Months;
  32.541 +                        break;
  32.542 +                    case DateTimeIntervalType.Months:
  32.543 +                        this.actualMinorIntervalType = DateTimeIntervalType.Days;
  32.544 +                        break;
  32.545 +                    case DateTimeIntervalType.Weeks:
  32.546 +                        this.actualMinorIntervalType = DateTimeIntervalType.Days;
  32.547 +                        break;
  32.548 +                    case DateTimeIntervalType.Days:
  32.549 +                        this.actualMinorIntervalType = DateTimeIntervalType.Hours;
  32.550 +                        break;
  32.551 +                    case DateTimeIntervalType.Hours:
  32.552 +                        this.actualMinorIntervalType = DateTimeIntervalType.Minutes;
  32.553 +                        break;
  32.554 +                    default:
  32.555 +                        this.actualMinorIntervalType = DateTimeIntervalType.Days;
  32.556 +                        break;
  32.557 +                }
  32.558 +            }
  32.559 +
  32.560 +            return interval;
  32.561 +        }
  32.562 +
  32.563 +        /// <summary>
  32.564 +        /// Creates the date tick values.
  32.565 +        /// </summary>
  32.566 +        /// <param name="min">
  32.567 +        /// The min.
  32.568 +        /// </param>
  32.569 +        /// <param name="max">
  32.570 +        /// The max.
  32.571 +        /// </param>
  32.572 +        /// <param name="step">
  32.573 +        /// The step.
  32.574 +        /// </param>
  32.575 +        /// <param name="intervalType">
  32.576 +        /// Type of the interval.
  32.577 +        /// </param>
  32.578 +        /// <returns>
  32.579 +        /// Date tick values.
  32.580 +        /// </returns>
  32.581 +        private IList<double> CreateDateTickValues(
  32.582 +            double min, double max, double step, DateTimeIntervalType intervalType)
  32.583 +        {
  32.584 +            DateTime start = ToDateTime(min);
  32.585 +            switch (intervalType)
  32.586 +            {
  32.587 +                case DateTimeIntervalType.Weeks:
  32.588 +
  32.589 +                    // make sure the first tick is at the 1st day of a week
  32.590 +                    start = start.AddDays(-(int)start.DayOfWeek + (int)this.FirstDayOfWeek);
  32.591 +                    break;
  32.592 +                case DateTimeIntervalType.Months:
  32.593 +
  32.594 +                    // make sure the first tick is at the 1st of a month
  32.595 +                    start = new DateTime(start.Year, start.Month, 1);
  32.596 +                    break;
  32.597 +                case DateTimeIntervalType.Years:
  32.598 +
  32.599 +                    // make sure the first tick is at Jan 1st
  32.600 +                    start = new DateTime(start.Year, 1, 1);
  32.601 +                    break;
  32.602 +            }
  32.603 +
  32.604 +            // Adds a tick to the end time to make sure the end DateTime is included.
  32.605 +            DateTime end = ToDateTime(max).AddTicks(1);
  32.606 +
  32.607 +            DateTime current = start;
  32.608 +            var values = new Collection<double>();
  32.609 +            double eps = step * 1e-3;
  32.610 +            DateTime minDateTime = ToDateTime(min - eps);
  32.611 +            DateTime maxDateTime = ToDateTime(max + eps);
  32.612 +            while (current < end)
  32.613 +            {
  32.614 +                if (current > minDateTime && current < maxDateTime)
  32.615 +                {
  32.616 +                    values.Add(ToDouble(current));
  32.617 +                }
  32.618 +
  32.619 +                switch (intervalType)
  32.620 +                {
  32.621 +                    case DateTimeIntervalType.Months:
  32.622 +                        current = current.AddMonths((int)Math.Ceiling(step));
  32.623 +                        break;
  32.624 +                    case DateTimeIntervalType.Years:
  32.625 +                        current = current.AddYears((int)Math.Ceiling(step));
  32.626 +                        break;
  32.627 +                    default:
  32.628 +                        current = current.AddDays(step);
  32.629 +                        break;
  32.630 +                }
  32.631 +            }
  32.632 +
  32.633 +            return values;
  32.634 +        }
  32.635 +
  32.636 +        /// <summary>
  32.637 +        /// Creates date/time tick values.
  32.638 +        /// </summary>
  32.639 +        /// <param name="min">
  32.640 +        /// The min.
  32.641 +        /// </param>
  32.642 +        /// <param name="max">
  32.643 +        /// The max.
  32.644 +        /// </param>
  32.645 +        /// <param name="interval">
  32.646 +        /// The interval.
  32.647 +        /// </param>
  32.648 +        /// <param name="intervalType">
  32.649 +        /// The interval type.
  32.650 +        /// </param>
  32.651 +        /// DateTime tick values.
  32.652 +        /// <returns>
  32.653 +        /// DateTime tick values.
  32.654 +        /// </returns>
  32.655 +        private IList<double> CreateDateTimeTickValues(
  32.656 +            double min, double max, double interval, DateTimeIntervalType intervalType)
  32.657 +        {
  32.658 +            // 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...
  32.659 +            if (intervalType > DateTimeIntervalType.Days)
  32.660 +            {
  32.661 +                return this.CreateDateTickValues(min, max, interval, intervalType);
  32.662 +            }
  32.663 +
  32.664 +            // For shorter step sizes we use the method from Axis
  32.665 +            return CreateTickValues(min, max, interval);
  32.666 +        }
  32.667 +
  32.668 +        /// <summary>
  32.669 +        /// Gets the week number for the specified date.
  32.670 +        /// </summary>
  32.671 +        /// <param name="date">
  32.672 +        /// The date.
  32.673 +        /// </param>
  32.674 +        /// <returns>
  32.675 +        /// The week number for the current culture.
  32.676 +        /// </returns>
  32.677 +        private int GetWeek(DateTime date)
  32.678 +        {
  32.679 +            return this.ActualCulture.Calendar.GetWeekOfYear(date, this.CalendarWeekRule, this.FirstDayOfWeek);
  32.680 +        }
  32.681 +    }
  32.682 +}
  32.683 \ No newline at end of file
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/External/OxyPlot/OxyPlot/Axes/DateTimeIntervalType.cs	Sat Jun 08 16:53:22 2013 +0000
    33.3 @@ -0,0 +1,87 @@
    33.4 +// --------------------------------------------------------------------------------------------------------------------
    33.5 +// <copyright file="DateTimeIntervalType.cs" company="OxyPlot">
    33.6 +//   The MIT License (MIT)
    33.7 +//
    33.8 +//   Copyright (c) 2012 Oystein Bjorke
    33.9 +//
   33.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   33.11 +//   copy of this software and associated documentation files (the
   33.12 +//   "Software"), to deal in the Software without restriction, including
   33.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   33.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   33.15 +//   permit persons to whom the Software is furnished to do so, subject to
   33.16 +//   the following conditions:
   33.17 +//
   33.18 +//   The above copyright notice and this permission notice shall be included
   33.19 +//   in all copies or substantial portions of the Software.
   33.20 +//
   33.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   33.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   33.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   33.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   33.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   33.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   33.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   33.28 +// </copyright>
   33.29 +// <summary>
   33.30 +//   Defines the date time interval for DateTimeAxis.
   33.31 +// </summary>
   33.32 +// --------------------------------------------------------------------------------------------------------------------
   33.33 +namespace OxyPlot.Axes
   33.34 +{
   33.35 +    /// <summary>
   33.36 +    /// Specifies the date time interval for <see cref="DateTimeAxis"/>.
   33.37 +    /// </summary>
   33.38 +    public enum DateTimeIntervalType
   33.39 +    {
   33.40 +        /// <summary>
   33.41 +        /// Automatically determine interval.
   33.42 +        /// </summary>
   33.43 +        Auto = 0,
   33.44 +
   33.45 +        /// <summary>
   33.46 +        /// Manual definition of intervals.
   33.47 +        /// </summary>
   33.48 +        Manual = 1,
   33.49 +
   33.50 +        /// <summary>
   33.51 +        /// Interval type is milliseconds.
   33.52 +        /// </summary>
   33.53 +        Milliseconds = 2,
   33.54 +
   33.55 +        /// <summary>
   33.56 +        /// Interval type is seconds.
   33.57 +        /// </summary>
   33.58 +        Seconds = 3,
   33.59 +
   33.60 +        /// <summary>
   33.61 +        /// Interval type is minutes.
   33.62 +        /// </summary>
   33.63 +        Minutes = 4,
   33.64 +
   33.65 +        /// <summary>
   33.66 +        /// Interval type is hours.
   33.67 +        /// </summary>
   33.68 +        Hours = 5,
   33.69 +
   33.70 +        /// <summary>
   33.71 +        /// Interval type is days.
   33.72 +        /// </summary>
   33.73 +        Days = 6,
   33.74 +
   33.75 +        /// <summary>
   33.76 +        /// Interval type is weeks.
   33.77 +        /// </summary>
   33.78 +        Weeks = 7,
   33.79 +
   33.80 +        /// <summary>
   33.81 +        /// Interval type is months.
   33.82 +        /// </summary>
   33.83 +        Months = 8,
   33.84 +
   33.85 +        /// <summary>
   33.86 +        /// Interval type is years.
   33.87 +        /// </summary>
   33.88 +        Years = 9,
   33.89 +    }
   33.90 +}
   33.91 \ No newline at end of file
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/External/OxyPlot/OxyPlot/Axes/LinearAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    34.3 @@ -0,0 +1,164 @@
    34.4 +// --------------------------------------------------------------------------------------------------------------------
    34.5 +// <copyright file="LinearAxis.cs" company="OxyPlot">
    34.6 +//   The MIT License (MIT)
    34.7 +//
    34.8 +//   Copyright (c) 2012 Oystein Bjorke
    34.9 +//
   34.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   34.11 +//   copy of this software and associated documentation files (the
   34.12 +//   "Software"), to deal in the Software without restriction, including
   34.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   34.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   34.15 +//   permit persons to whom the Software is furnished to do so, subject to
   34.16 +//   the following conditions:
   34.17 +//
   34.18 +//   The above copyright notice and this permission notice shall be included
   34.19 +//   in all copies or substantial portions of the Software.
   34.20 +//
   34.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   34.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   34.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   34.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   34.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   34.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   34.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   34.28 +// </copyright>
   34.29 +// <summary>
   34.30 +//   Represents an axis with linear scale.
   34.31 +// </summary>
   34.32 +// --------------------------------------------------------------------------------------------------------------------
   34.33 +namespace OxyPlot.Axes
   34.34 +{
   34.35 +    /// <summary>
   34.36 +    /// Represents an axis with linear scale.
   34.37 +    /// </summary>
   34.38 +    public class LinearAxis : Axis
   34.39 +    {
   34.40 +        /// <summary>
   34.41 +        /// Initializes a new instance of the <see cref="LinearAxis"/> class.
   34.42 +        /// </summary>
   34.43 +        public LinearAxis()
   34.44 +        {
   34.45 +            this.FractionUnit = 1.0;
   34.46 +            this.FractionUnitSymbol = null;
   34.47 +            this.FormatAsFractions = false;
   34.48 +        }
   34.49 +
   34.50 +        /// <summary>
   34.51 +        /// Initializes a new instance of the <see cref="LinearAxis"/> class.
   34.52 +        /// </summary>
   34.53 +        /// <param name="pos">
   34.54 +        /// The pos.
   34.55 +        /// </param>
   34.56 +        /// <param name="title">
   34.57 +        /// The title.
   34.58 +        /// </param>
   34.59 +        public LinearAxis(AxisPosition pos, string title)
   34.60 +            : this()
   34.61 +        {
   34.62 +            this.Position = pos;
   34.63 +            this.Title = title;
   34.64 +        }
   34.65 +
   34.66 +        /// <summary>
   34.67 +        /// Initializes a new instance of the <see cref="LinearAxis"/> class.
   34.68 +        /// </summary>
   34.69 +        /// <param name="pos">
   34.70 +        /// The pos.
   34.71 +        /// </param>
   34.72 +        /// <param name="minimum">
   34.73 +        /// The minimum.
   34.74 +        /// </param>
   34.75 +        /// <param name="maximum">
   34.76 +        /// The maximum.
   34.77 +        /// </param>
   34.78 +        /// <param name="title">
   34.79 +        /// The title.
   34.80 +        /// </param>
   34.81 +        public LinearAxis(
   34.82 +            AxisPosition pos, double minimum = double.NaN, double maximum = double.NaN, string title = null)
   34.83 +            : this(pos, minimum, maximum, double.NaN, double.NaN, title)
   34.84 +        {
   34.85 +        }
   34.86 +
   34.87 +        /// <summary>
   34.88 +        /// Initializes a new instance of the <see cref="LinearAxis"/> class.
   34.89 +        /// </summary>
   34.90 +        /// <param name="pos">
   34.91 +        /// The pos.
   34.92 +        /// </param>
   34.93 +        /// <param name="minimum">
   34.94 +        /// The minimum.
   34.95 +        /// </param>
   34.96 +        /// <param name="maximum">
   34.97 +        /// The maximum.
   34.98 +        /// </param>
   34.99 +        /// <param name="majorStep">
  34.100 +        /// The major step.
  34.101 +        /// </param>
  34.102 +        /// <param name="minorStep">
  34.103 +        /// The minor step.
  34.104 +        /// </param>
  34.105 +        /// <param name="title">
  34.106 +        /// The title.
  34.107 +        /// </param>
  34.108 +        public LinearAxis(
  34.109 +            AxisPosition pos, double minimum, double maximum, double majorStep, double minorStep, string title = null)
  34.110 +            : this(pos, title)
  34.111 +        {
  34.112 +            this.Minimum = minimum;
  34.113 +            this.Maximum = maximum;
  34.114 +            this.MajorStep = majorStep;
  34.115 +            this.MinorStep = minorStep;
  34.116 +        }
  34.117 +
  34.118 +        /// <summary>
  34.119 +        /// Gets or sets a value indicating whether to format numbers as fractions.
  34.120 +        /// </summary>
  34.121 +        public bool FormatAsFractions { get; set; }
  34.122 +
  34.123 +        /// <summary>
  34.124 +        /// Gets or sets the fraction unit. Remember to set FormatAsFractions to true.
  34.125 +        /// </summary>
  34.126 +        /// <value> The fraction unit. </value>
  34.127 +        public double FractionUnit { get; set; }
  34.128 +
  34.129 +        /// <summary>
  34.130 +        /// 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.
  34.131 +        /// </summary>
  34.132 +        /// <value> The fraction unit symbol. </value>
  34.133 +        public string FractionUnitSymbol { get; set; }
  34.134 +
  34.135 +        /// <summary>
  34.136 +        /// Formats the value to be used on the axis.
  34.137 +        /// </summary>
  34.138 +        /// <param name="x">
  34.139 +        /// The value.
  34.140 +        /// </param>
  34.141 +        /// <returns>
  34.142 +        /// The formatted value.
  34.143 +        /// </returns>
  34.144 +        public override string FormatValue(double x)
  34.145 +        {
  34.146 +            if (this.FormatAsFractions)
  34.147 +            {
  34.148 +                return FractionHelper.ConvertToFractionString(
  34.149 +                    x, this.FractionUnit, this.FractionUnitSymbol, 1e-6, this.ActualCulture);
  34.150 +            }
  34.151 +
  34.152 +            return base.FormatValue(x);
  34.153 +        }
  34.154 +
  34.155 +        /// <summary>
  34.156 +        /// Determines whether the axis is used for X/Y values.
  34.157 +        /// </summary>
  34.158 +        /// <returns>
  34.159 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  34.160 +        /// </returns>
  34.161 +        public override bool IsXyAxis()
  34.162 +        {
  34.163 +            return true;
  34.164 +        }
  34.165 +
  34.166 +    }
  34.167 +}
  34.168 \ No newline at end of file
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/External/OxyPlot/OxyPlot/Axes/LogarithmicAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    35.3 @@ -0,0 +1,406 @@
    35.4 +// --------------------------------------------------------------------------------------------------------------------
    35.5 +// <copyright file="LogarithmicAxis.cs" company="OxyPlot">
    35.6 +//   The MIT License (MIT)
    35.7 +//
    35.8 +//   Copyright (c) 2012 Oystein Bjorke
    35.9 +//
   35.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   35.11 +//   copy of this software and associated documentation files (the
   35.12 +//   "Software"), to deal in the Software without restriction, including
   35.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   35.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   35.15 +//   permit persons to whom the Software is furnished to do so, subject to
   35.16 +//   the following conditions:
   35.17 +//
   35.18 +//   The above copyright notice and this permission notice shall be included
   35.19 +//   in all copies or substantial portions of the Software.
   35.20 +//
   35.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   35.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   35.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   35.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   35.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   35.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   35.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   35.28 +// </copyright>
   35.29 +// <summary>
   35.30 +//   Represents an axis with logarithmic scale.
   35.31 +// </summary>
   35.32 +// --------------------------------------------------------------------------------------------------------------------
   35.33 +namespace OxyPlot.Axes
   35.34 +{
   35.35 +    using System;
   35.36 +    using System.Collections.Generic;
   35.37 +    using System.Diagnostics;
   35.38 +
   35.39 +    /// <summary>
   35.40 +    /// Represents an axis with logarithmic scale.
   35.41 +    /// </summary>
   35.42 +    /// <remarks>
   35.43 +    /// See http://en.wikipedia.org/wiki/Logarithmic_scale.
   35.44 +    /// </remarks>
   35.45 +    public class LogarithmicAxis : Axis
   35.46 +    {
   35.47 +        /// <summary>
   35.48 +        /// Initializes a new instance of the <see cref = "LogarithmicAxis" /> class.
   35.49 +        /// </summary>
   35.50 +        public LogarithmicAxis()
   35.51 +        {
   35.52 +            this.PowerPadding = true;
   35.53 +            this.Base = 10;
   35.54 +            this.FilterMinValue = 0;
   35.55 +        }
   35.56 +
   35.57 +        /// <summary>
   35.58 +        /// Initializes a new instance of the <see cref="LogarithmicAxis"/> class.
   35.59 +        /// </summary>
   35.60 +        /// <param name="pos">
   35.61 +        /// The position.
   35.62 +        /// </param>
   35.63 +        /// <param name="title">
   35.64 +        /// The title.
   35.65 +        /// </param>
   35.66 +        public LogarithmicAxis(AxisPosition pos, string title)
   35.67 +            : this()
   35.68 +        {
   35.69 +            this.Position = pos;
   35.70 +            this.Title = title;
   35.71 +        }
   35.72 +
   35.73 +        /// <summary>
   35.74 +        /// Initializes a new instance of the <see cref="LogarithmicAxis"/> class.
   35.75 +        /// </summary>
   35.76 +        /// <param name="position">
   35.77 +        /// The position.
   35.78 +        /// </param>
   35.79 +        /// <param name="minimum">
   35.80 +        /// The minimum.
   35.81 +        /// </param>
   35.82 +        /// <param name="maximum">
   35.83 +        /// The maximum.
   35.84 +        /// </param>
   35.85 +        /// <param name="title">
   35.86 +        /// The title.
   35.87 +        /// </param>
   35.88 +        public LogarithmicAxis(
   35.89 +            AxisPosition position, double minimum = double.NaN, double maximum = double.NaN, string title = null)
   35.90 +            : this()
   35.91 +        {
   35.92 +            this.Position = position;
   35.93 +            this.Title = title;
   35.94 +            this.Minimum = minimum;
   35.95 +            this.Maximum = maximum;
   35.96 +        }
   35.97 +
   35.98 +        /// <summary>
   35.99 +        /// Gets or sets the logarithmic base (normally 10).
  35.100 +        /// </summary>
  35.101 +        /// <remarks>
  35.102 +        /// See http://en.wikipedia.org/wiki/Logarithm.
  35.103 +        /// </remarks>
  35.104 +        /// <value>The logarithmic base.</value>
  35.105 +        public double Base { get; set; }
  35.106 +
  35.107 +        /// <summary>
  35.108 +        /// Gets or sets a value indicating whether the ActualMaximum and ActualMinimum values should be padded to the nearest power of the Base.
  35.109 +        /// </summary>
  35.110 +        public bool PowerPadding { get; set; }
  35.111 +
  35.112 +        /// <summary>
  35.113 +        /// Coerces the actual maximum and minimum values.
  35.114 +        /// </summary>
  35.115 +        public override void CoerceActualMaxMin()
  35.116 +        {
  35.117 +            if (double.IsNaN(this.ActualMinimum) || double.IsInfinity(this.ActualMinimum))
  35.118 +            {
  35.119 +                this.ActualMinimum = 1;
  35.120 +            }
  35.121 +
  35.122 +            if (this.ActualMinimum <= 0)
  35.123 +            {
  35.124 +                this.ActualMinimum = 1;
  35.125 +            }
  35.126 +
  35.127 +            if (this.ActualMaximum <= this.ActualMinimum)
  35.128 +            {
  35.129 +                this.ActualMaximum = this.ActualMinimum * 100;
  35.130 +            }
  35.131 +
  35.132 +            base.CoerceActualMaxMin();
  35.133 +        }
  35.134 +
  35.135 +        /// <summary>
  35.136 +        /// Gets the coordinates used to draw ticks and tick labels (numbers or category names).
  35.137 +        /// </summary>
  35.138 +        /// <param name="majorLabelValues">
  35.139 +        /// The major label values.
  35.140 +        /// </param>
  35.141 +        /// <param name="majorTickValues">
  35.142 +        /// The major tick values.
  35.143 +        /// </param>
  35.144 +        /// <param name="minorTickValues">
  35.145 +        /// The minor tick values.
  35.146 +        /// </param>
  35.147 +        public override void GetTickValues(
  35.148 +            out IList<double> majorLabelValues, out IList<double> majorTickValues, out IList<double> minorTickValues)
  35.149 +        {
  35.150 +            if (this.ActualMinimum <= 0)
  35.151 +            {
  35.152 +                this.ActualMinimum = 0.1;
  35.153 +            }
  35.154 +
  35.155 +            double logBase = Math.Log(this.Base);
  35.156 +            var e0 = (int)Math.Floor(Math.Log(this.ActualMinimum) / logBase);
  35.157 +            var e1 = (int)Math.Ceiling(Math.Log(this.ActualMaximum) / logBase);
  35.158 +
  35.159 +            // find the min & max values for the specified base
  35.160 +            // round to max 10 digits
  35.161 +            double p0 = Math.Pow(this.Base, e0);
  35.162 +            double p1 = Math.Pow(this.Base, e1);
  35.163 +            double d0 = Math.Round(p0, 10);
  35.164 +            double d1 = Math.Round(p1, 10);
  35.165 +            if (d0 <= 0)
  35.166 +            {
  35.167 +                d0 = p0;
  35.168 +            }
  35.169 +
  35.170 +            double d = d0;
  35.171 +            majorTickValues = new List<double>();
  35.172 +            minorTickValues = new List<double>();
  35.173 +
  35.174 +            double epsMin = this.ActualMinimum * 1e-6;
  35.175 +            double epsMax = this.ActualMaximum * 1e-6;
  35.176 +
  35.177 +            while (d <= d1 + epsMax)
  35.178 +            {
  35.179 +                // d = RemoveNoiseFromDoubleMath(d);
  35.180 +                if (d >= this.ActualMinimum - epsMin && d <= this.ActualMaximum + epsMax)
  35.181 +                {
  35.182 +                    majorTickValues.Add(d);
  35.183 +                }
  35.184 +
  35.185 +                for (int i = 1; i < this.Base; i++)
  35.186 +                {
  35.187 +                    double d2 = d * (i + 1);
  35.188 +                    if (d2 > d1 + double.Epsilon)
  35.189 +                    {
  35.190 +                        break;
  35.191 +                    }
  35.192 +
  35.193 +                    if (d2 > this.ActualMaximum)
  35.194 +                    {
  35.195 +                        break;
  35.196 +                    }
  35.197 +
  35.198 +                    if (d2 >= this.ActualMinimum && d2 <= this.ActualMaximum)
  35.199 +                    {
  35.200 +                        minorTickValues.Add(d2);
  35.201 +                    }
  35.202 +                }
  35.203 +
  35.204 +                d *= this.Base;
  35.205 +                if (double.IsInfinity(d))
  35.206 +                {
  35.207 +                    break;
  35.208 +                }
  35.209 +
  35.210 +                if (d < double.Epsilon)
  35.211 +                {
  35.212 +                    break;
  35.213 +                }
  35.214 +
  35.215 +                if (double.IsNaN(d))
  35.216 +                {
  35.217 +                    break;
  35.218 +                }
  35.219 +            }
  35.220 +
  35.221 +            if (majorTickValues.Count < 2)
  35.222 +            {
  35.223 +                base.GetTickValues(out majorLabelValues, out majorTickValues, out minorTickValues);
  35.224 +            }
  35.225 +            else
  35.226 +            {
  35.227 +                majorLabelValues = majorTickValues;
  35.228 +            }
  35.229 +        }
  35.230 +
  35.231 +        /// <summary>
  35.232 +        /// Determines whether the specified value is valid.
  35.233 +        /// </summary>
  35.234 +        /// <param name="value">
  35.235 +        /// The value.
  35.236 +        /// </param>
  35.237 +        /// <returns>
  35.238 +        /// <c>true</c> if the specified value is valid; otherwise, <c>false</c>.
  35.239 +        /// </returns>
  35.240 +        public override bool IsValidValue(double value)
  35.241 +        {
  35.242 +            return value > 0 && base.IsValidValue(value);
  35.243 +        }
  35.244 +
  35.245 +        /// <summary>
  35.246 +        /// Determines whether the axis is used for X/Y values.
  35.247 +        /// </summary>
  35.248 +        /// <returns>
  35.249 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  35.250 +        /// </returns>
  35.251 +        public override bool IsXyAxis()
  35.252 +        {
  35.253 +            return true;
  35.254 +        }
  35.255 +
  35.256 +        /// <summary>
  35.257 +        /// Pans the specified axis.
  35.258 +        /// </summary>
  35.259 +        /// <param name="ppt">
  35.260 +        /// The previous point (screen coordinates).
  35.261 +        /// </param>
  35.262 +        /// <param name="cpt">
  35.263 +        /// The current point (screen coordinates).
  35.264 +        /// </param>
  35.265 +        public override void Pan(ScreenPoint ppt, ScreenPoint cpt)
  35.266 +        {
  35.267 +            if (!this.IsPanEnabled)
  35.268 +            {
  35.269 +                return;
  35.270 +            }
  35.271 +
  35.272 +            bool isHorizontal = this.IsHorizontal();
  35.273 +
  35.274 +            double x0 = this.InverseTransform(isHorizontal ? ppt.X : ppt.Y);
  35.275 +            double x1 = this.InverseTransform(isHorizontal ? cpt.X : cpt.Y);
  35.276 +
  35.277 +            if (Math.Abs(x1) < double.Epsilon)
  35.278 +            {
  35.279 +                return;
  35.280 +            }
  35.281 +
  35.282 +            double dx = x0 / x1;
  35.283 +
  35.284 +            double newMinimum = this.ActualMinimum * dx;
  35.285 +            double newMaximum = this.ActualMaximum * dx;
  35.286 +            if (newMinimum < this.AbsoluteMinimum)
  35.287 +            {
  35.288 +                newMinimum = this.AbsoluteMinimum;
  35.289 +                newMaximum = newMinimum * this.ActualMaximum / this.ActualMinimum;
  35.290 +            }
  35.291 +
  35.292 +            if (newMaximum > this.AbsoluteMaximum)
  35.293 +            {
  35.294 +                newMaximum = this.AbsoluteMaximum;
  35.295 +                newMinimum = newMaximum * this.ActualMaximum / this.ActualMinimum;
  35.296 +            }
  35.297 +
  35.298 +            this.ViewMinimum = newMinimum;
  35.299 +            this.ViewMaximum = newMaximum;
  35.300 +
  35.301 +            this.OnAxisChanged(new AxisChangedEventArgs(AxisChangeTypes.Pan));
  35.302 +        }
  35.303 +
  35.304 +        /// <summary>
  35.305 +        /// Transforms the specified coordinate to screen coordinates.
  35.306 +        /// </summary>
  35.307 +        /// <param name="x">
  35.308 +        /// The value.
  35.309 +        /// </param>
  35.310 +        /// <returns>
  35.311 +        /// The transformed value (screen coordinate).
  35.312 +        /// </returns>
  35.313 +        public override double Transform(double x)
  35.314 +        {
  35.315 +            Debug.Assert(x > 0, "Value should be positive.");
  35.316 +            if (x <= 0)
  35.317 +            {
  35.318 +                return -1;
  35.319 +            }
  35.320 +
  35.321 +            return (Math.Log(x) - this.offset) * this.scale;
  35.322 +        }
  35.323 +
  35.324 +        /// <summary>
  35.325 +        /// Zooms the axis at the specified coordinate.
  35.326 +        /// </summary>
  35.327 +        /// <param name="factor">
  35.328 +        /// The zoom factor.
  35.329 +        /// </param>
  35.330 +        /// <param name="x">
  35.331 +        /// The coordinate to zoom at.
  35.332 +        /// </param>
  35.333 +        public override void ZoomAt(double factor, double x)
  35.334 +        {
  35.335 +            if (!this.IsZoomEnabled)
  35.336 +            {
  35.337 +                return;
  35.338 +            }
  35.339 +
  35.340 +            double px = this.PreTransform(x);
  35.341 +            double dx0 = this.PreTransform(this.ActualMinimum) - px;
  35.342 +            double dx1 = this.PreTransform(this.ActualMaximum) - px;
  35.343 +            double newViewMinimum = this.PostInverseTransform((dx0 / factor) + px);
  35.344 +            double newViewMaximum = this.PostInverseTransform((dx1 / factor) + px);
  35.345 +
  35.346 +            this.ViewMinimum = Math.Max(newViewMinimum, this.AbsoluteMinimum);
  35.347 +            this.ViewMaximum = Math.Min(newViewMaximum, this.AbsoluteMaximum);
  35.348 +        }
  35.349 +
  35.350 +        /// <summary>
  35.351 +        /// Applies a transformation after the inverse transform of the value. This is used in logarithmic axis.
  35.352 +        /// </summary>
  35.353 +        /// <param name="x">The value to transform.</param>
  35.354 +        /// <returns>
  35.355 +        /// The transformed value.
  35.356 +        /// </returns>
  35.357 +        internal override double PostInverseTransform(double x)
  35.358 +        {
  35.359 +            return Math.Exp(x);
  35.360 +        }
  35.361 +
  35.362 +        /// <summary>
  35.363 +        /// Applies a transformation before the transform the value. This is used in logarithmic axis.
  35.364 +        /// </summary>
  35.365 +        /// <param name="x">The value to transform.</param>
  35.366 +        /// <returns>
  35.367 +        /// The transformed value.
  35.368 +        /// </returns>
  35.369 +        internal override double PreTransform(double x)
  35.370 +        {
  35.371 +            Debug.Assert(x > 0, "Value should be positive.");
  35.372 +
  35.373 +            if (x <= 0)
  35.374 +            {
  35.375 +                return 0;
  35.376 +            }
  35.377 +
  35.378 +            return Math.Log(x);
  35.379 +        }
  35.380 +
  35.381 +        /// <summary>
  35.382 +        /// Updates the actual maximum and minimum values.
  35.383 +        /// If the user has zoomed/panned the axis, the internal ViewMaximum/ViewMinimum values will be used.
  35.384 +        /// If Maximum or Minimum have been set, these values will be used.
  35.385 +        /// Otherwise the maximum and minimum values of the series will be used, including the 'padding'.
  35.386 +        /// </summary>
  35.387 +        internal override void UpdateActualMaxMin()
  35.388 +        {
  35.389 +            if (this.PowerPadding)
  35.390 +            {
  35.391 +                double logBase = Math.Log(this.Base);
  35.392 +                var e0 = (int)Math.Floor(Math.Log(this.ActualMinimum) / logBase);
  35.393 +                var e1 = (int)Math.Ceiling(Math.Log(this.ActualMaximum) / logBase);
  35.394 +                if (!double.IsNaN(this.ActualMinimum))
  35.395 +                {
  35.396 +                    this.ActualMinimum = Math.Exp(e0 * logBase).RemoveNoiseFromDoubleMath();
  35.397 +                }
  35.398 +
  35.399 +                if (!double.IsNaN(this.ActualMaximum))
  35.400 +                {
  35.401 +                    this.ActualMaximum = Math.Exp(e1 * logBase).RemoveNoiseFromDoubleMath();
  35.402 +                }
  35.403 +            }
  35.404 +
  35.405 +            base.UpdateActualMaxMin();
  35.406 +        }
  35.407 +
  35.408 +    }
  35.409 +}
  35.410 \ No newline at end of file
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/External/OxyPlot/OxyPlot/Axes/MagnitudeAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    36.3 @@ -0,0 +1,205 @@
    36.4 +// --------------------------------------------------------------------------------------------------------------------
    36.5 +// <copyright file="MagnitudeAxis.cs" company="OxyPlot">
    36.6 +//   The MIT License (MIT)
    36.7 +//
    36.8 +//   Copyright (c) 2012 Oystein Bjorke
    36.9 +//
   36.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   36.11 +//   copy of this software and associated documentation files (the
   36.12 +//   "Software"), to deal in the Software without restriction, including
   36.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   36.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   36.15 +//   permit persons to whom the Software is furnished to do so, subject to
   36.16 +//   the following conditions:
   36.17 +//
   36.18 +//   The above copyright notice and this permission notice shall be included
   36.19 +//   in all copies or substantial portions of the Software.
   36.20 +//
   36.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   36.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   36.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   36.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   36.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   36.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   36.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   36.28 +// </copyright>
   36.29 +// <summary>
   36.30 +//   Represents a magnitude axis for polar plots.
   36.31 +// </summary>
   36.32 +// --------------------------------------------------------------------------------------------------------------------
   36.33 +namespace OxyPlot.Axes
   36.34 +{
   36.35 +    using System;
   36.36 +
   36.37 +    /// <summary>
   36.38 +    /// Represents a magnitude axis for polar plots.
   36.39 +    /// </summary>
   36.40 +    public class MagnitudeAxis : LinearAxis
   36.41 +    {
   36.42 +        /// <summary>
   36.43 +        /// Initializes a new instance of the <see cref="MagnitudeAxis"/> class.
   36.44 +        /// </summary>
   36.45 +        public MagnitudeAxis()
   36.46 +        {
   36.47 +            this.Position = AxisPosition.Bottom;
   36.48 +            this.IsPanEnabled = false;
   36.49 +            this.IsZoomEnabled = false;
   36.50 +
   36.51 +            this.MajorGridlineStyle = LineStyle.Solid;
   36.52 +            this.MinorGridlineStyle = LineStyle.Solid;
   36.53 +        }
   36.54 +
   36.55 +        /// <summary>
   36.56 +        /// Initializes a new instance of the <see cref="MagnitudeAxis"/> class.
   36.57 +        /// </summary>
   36.58 +        /// <param name="minimum">
   36.59 +        /// The minimum.
   36.60 +        /// </param>
   36.61 +        /// <param name="maximum">
   36.62 +        /// The maximum.
   36.63 +        /// </param>
   36.64 +        /// <param name="majorStep">
   36.65 +        /// The major step.
   36.66 +        /// </param>
   36.67 +        /// <param name="minorStep">
   36.68 +        /// The minor step.
   36.69 +        /// </param>
   36.70 +        /// <param name="title">
   36.71 +        /// The title.
   36.72 +        /// </param>
   36.73 +        public MagnitudeAxis(
   36.74 +            double minimum = double.NaN,
   36.75 +            double maximum = double.NaN,
   36.76 +            double majorStep = double.NaN,
   36.77 +            double minorStep = double.NaN,
   36.78 +            string title = null)
   36.79 +            : this()
   36.80 +        {
   36.81 +            this.Minimum = minimum;
   36.82 +            this.Maximum = maximum;
   36.83 +            this.MajorStep = majorStep;
   36.84 +            this.MinorStep = minorStep;
   36.85 +            this.Title = title;
   36.86 +        }
   36.87 +
   36.88 +        /// <summary>
   36.89 +        /// Gets or sets the midpoint (screen coordinates) of the plot area. This is used by polar coordinate systems.
   36.90 +        /// </summary>
   36.91 +        internal ScreenPoint MidPoint { get; set; }
   36.92 +
   36.93 +        /// <summary>
   36.94 +        /// Inverse transform the specified screen point.
   36.95 +        /// </summary>
   36.96 +        /// <param name="x">
   36.97 +        /// The x coordinate.
   36.98 +        /// </param>
   36.99 +        /// <param name="y">
  36.100 +        /// The y coordinate.
  36.101 +        /// </param>
  36.102 +        /// <param name="yaxis">
  36.103 +        /// The y-axis.
  36.104 +        /// </param>
  36.105 +        /// <returns>
  36.106 +        /// The data point.
  36.107 +        /// </returns>
  36.108 +        public override DataPoint InverseTransform(double x, double y, Axis yaxis)
  36.109 +        {
  36.110 +            var angleAxis = yaxis as AngleAxis;
  36.111 +            if (angleAxis == null)
  36.112 +            {
  36.113 +                throw new InvalidOperationException("Polar angle axis not defined!");
  36.114 +            }
  36.115 +
  36.116 +            x -= this.MidPoint.x;
  36.117 +            y -= this.MidPoint.y;
  36.118 +            double th = Math.Atan2(y, x);
  36.119 +            double r = Math.Sqrt((x * x) + (y * y));
  36.120 +            x = (r / this.scale) + this.offset;
  36.121 +            y = (th / angleAxis.Scale) + angleAxis.Offset;
  36.122 +            return new DataPoint(x, y);
  36.123 +        }
  36.124 +
  36.125 +        /// <summary>
  36.126 +        /// Determines whether the axis is used for X/Y values.
  36.127 +        /// </summary>
  36.128 +        /// <returns>
  36.129 +        /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
  36.130 +        /// </returns>
  36.131 +        public override bool IsXyAxis()
  36.132 +        {
  36.133 +            return false;
  36.134 +        }
  36.135 +
  36.136 +        /// <summary>
  36.137 +        /// Renders the axis on the specified render context.
  36.138 +        /// </summary>
  36.139 +        /// <param name="rc">The render context.</param>
  36.140 +        /// <param name="model">The model.</param>
  36.141 +        /// <param name="axisLayer">The rendering order.</param>
  36.142 +        /// <param name="pass"></param>
  36.143 +        public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
  36.144 +        {
  36.145 +            if (this.Layer != axisLayer)
  36.146 +            {
  36.147 +                return;
  36.148 +            }
  36.149 +
  36.150 +            var r = new MagnitudeAxisRenderer(rc, model);
  36.151 +            r.Render(this, pass);
  36.152 +        }
  36.153 +
  36.154 +        /// <summary>
  36.155 +        /// Transforms the specified point to screen coordinates.
  36.156 +        /// </summary>
  36.157 +        /// <param name="x">
  36.158 +        /// The x value (for the current axis).
  36.159 +        /// </param>
  36.160 +        /// <param name="y">
  36.161 +        /// The y value.
  36.162 +        /// </param>
  36.163 +        /// <param name="yaxis">
  36.164 +        /// The y axis.
  36.165 +        /// </param>
  36.166 +        /// <returns>
  36.167 +        /// The transformed point.
  36.168 +        /// </returns>
  36.169 +        public override ScreenPoint Transform(double x, double y, Axis yaxis)
  36.170 +        {
  36.171 +            var angleAxis = yaxis as AngleAxis;
  36.172 +            if (angleAxis == null)
  36.173 +            {
  36.174 +                throw new InvalidOperationException("Polar angle axis not defined!");
  36.175 +            }
  36.176 +
  36.177 +            double r = (x - this.Offset) * this.scale;
  36.178 +            double theta = (y - angleAxis.Offset) * angleAxis.Scale;
  36.179 +
  36.180 +            return new ScreenPoint(this.MidPoint.x + (r * Math.Cos(theta)), this.MidPoint.y - (r * Math.Sin(theta)));
  36.181 +        }
  36.182 +
  36.183 +        /// <summary>
  36.184 +        /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
  36.185 +        /// </summary>
  36.186 +        /// <param name="bounds">
  36.187 +        /// The bounds.
  36.188 +        /// </param>
  36.189 +        internal override void UpdateTransform(OxyRect bounds)
  36.190 +        {
  36.191 +            double x0 = bounds.Left;
  36.192 +            double x1 = bounds.Right;
  36.193 +            double y0 = bounds.Bottom;
  36.194 +            double y1 = bounds.Top;
  36.195 +
  36.196 +            this.ScreenMin = new ScreenPoint(x0, y1);
  36.197 +            this.ScreenMax = new ScreenPoint(x1, y0);
  36.198 +
  36.199 +            this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);
  36.200 +
  36.201 +            this.ActualMinimum = 0;
  36.202 +            double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
  36.203 +            this.scale = 0.5 * r / (this.ActualMaximum - this.ActualMinimum);
  36.204 +            this.Offset = this.ActualMinimum;
  36.205 +        }
  36.206 +
  36.207 +    }
  36.208 +}
  36.209 \ No newline at end of file
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/External/OxyPlot/OxyPlot/Axes/RangeAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    37.3 @@ -0,0 +1,469 @@
    37.4 +// --------------------------------------------------------------------------------------------------------------------
    37.5 +// <copyright file="RangeAxis.cs" company="OxyPlot">
    37.6 +//   The MIT License (MIT)
    37.7 +//
    37.8 +//   Copyright (c) 2012 Oystein Bjorke
    37.9 +//
   37.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   37.11 +//   copy of this software and associated documentation files (the
   37.12 +//   "Software"), to deal in the Software without restriction, including
   37.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   37.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   37.15 +//   permit persons to whom the Software is furnished to do so, subject to
   37.16 +//   the following conditions:
   37.17 +//
   37.18 +//   The above copyright notice and this permission notice shall be included
   37.19 +//   in all copies or substantial portions of the Software.
   37.20 +//
   37.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   37.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   37.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   37.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   37.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   37.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   37.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   37.28 +// </copyright>
   37.29 +// <summary>
   37.30 +//   Updates the minor/major step intervals if they are undefined.
   37.31 +// </summary>
   37.32 +// --------------------------------------------------------------------------------------------------------------------
   37.33 +using System;
   37.34 +using System.Collections.Generic;
   37.35 +using System.Collections.ObjectModel;
   37.36 +using System.Diagnostics;
   37.37 +using System.Globalization;
   37.38 +
   37.39 +namespace OxyPlot
   37.40 +{
   37.41 +    public class Axis : IAxis
   37.42 +    {
   37.43 +        public Axis()
   37.44 +        {
   37.45 +            Position = AxisPosition.Left;
   37.46 +            IsVisible = true;
   37.47 +
   37.48 +            Minimum = double.NaN;
   37.49 +            Maximum = double.NaN;
   37.50 +            MinorStep = double.NaN;
   37.51 +            MajorStep = double.NaN;
   37.52 +
   37.53 +            MinimumPadding = 0.01;
   37.54 +            MaximumPadding = 0.01;
   37.55 +
   37.56 +            TickStyle = TickStyle.Inside;
   37.57 +            MajorGridlineStyle = LineStyle.None;
   37.58 +            MinorGridlineStyle = LineStyle.None;
   37.59 +            TicklineColor = Colors.Black;
   37.60 +            MajorGridlineColor = Color.FromARGB(0x40, 0, 0, 0);
   37.61 +            TicklineColor = Colors.Black;
   37.62 +            MinorGridlineColor = Color.FromARGB(0x20, 0, 0, 0x00);
   37.63 +            MajorGridlineThickness = 1;
   37.64 +            MinorGridlineThickness = 1;
   37.65 +
   37.66 +            ExtraGridlineStyle = LineStyle.Solid;
   37.67 +            ExtraGridlineColor = Colors.Black;
   37.68 +            ExtraGridlineThickness = 1;
   37.69 +
   37.70 +            ShowMinorTicks = true;
   37.71 +
   37.72 +            FontFamily = "Segoe UI";
   37.73 +            FontSize = 12;
   37.74 +
   37.75 +            MinorTickSize = 4;
   37.76 +            MajorTickSize = 7;
   37.77 +
   37.78 +            StartPosition = 0;
   37.79 +            EndPosition = 1;
   37.80 +
   37.81 +            Angle = 0;
   37.82 +        }
   37.83 +
   37.84 +        public Axis(AxisPosition pos, double minimum, double maximum)
   37.85 +            : this()
   37.86 +        {
   37.87 +            Position = pos;
   37.88 +            Minimum = minimum;
   37.89 +            Maximum = maximum;
   37.90 +        }
   37.91 +        public string Key { get; set; }
   37.92 +
   37.93 +        public AxisPosition Position { get; set; }
   37.94 +        public bool PositionAtZeroCrossing { get; set; }
   37.95 +        public bool IsHorizontal { get { return Position == AxisPosition.Top || Position == AxisPosition.Bottom; } }
   37.96 +        public bool IsVertical { get { return Position == AxisPosition.Left || Position == AxisPosition.Right; } }
   37.97 +        public bool IsPolar { get { return Position == AxisPosition.Magnitude || Position == AxisPosition.Angle; } }
   37.98 +
   37.99 +        public bool IsVisible { get; set; }
  37.100 +
  37.101 +        public double ActualMinimum { get; set; }
  37.102 +        public double ActualMaximum { get; set; }
  37.103 +        internal double ActualMinorStep { get; set; }
  37.104 +        internal double ActualMajorStep { get; set; }
  37.105 +
  37.106 +        public double Minimum { get; set; }
  37.107 +        public double Maximum { get; set; }
  37.108 +        public double MinorStep { get; set; }
  37.109 +        public double MajorStep { get; set; }
  37.110 +
  37.111 +        public double MinimumPadding { get; set; }
  37.112 +        public double MaximumPadding { get; set; }
  37.113 +
  37.114 +        public TickStyle TickStyle { get; set; }
  37.115 +        public double MinorTickSize { get; set; }
  37.116 +        public double MajorTickSize { get; set; }
  37.117 +        public Color TicklineColor { get; set; }
  37.118 +        public bool ShowMinorTicks { get; set; }
  37.119 +
  37.120 +        public LineStyle MajorGridlineStyle { get; set; }
  37.121 +        public LineStyle MinorGridlineStyle { get; set; }
  37.122 +        public Color MajorGridlineColor { get; set; }
  37.123 +        public Color MinorGridlineColor { get; set; }
  37.124 +        public double MajorGridlineThickness { get; set; }
  37.125 +        public double MinorGridlineThickness { get; set; }
  37.126 +
  37.127 +        public double[] ExtraGridlines { get; set; }
  37.128 +        public LineStyle ExtraGridlineStyle { get; set; }
  37.129 +        public Color ExtraGridlineColor { get; set; }
  37.130 +        public double ExtraGridlineThickness { get; set; }
  37.131 +
  37.132 +        public double Angle { get; set; }
  37.133 +        public string StringFormat { get; set; }
  37.134 +        internal string ActualStringFormat { get; set; }
  37.135 +        public string Title { get; set; }
  37.136 +        public string Unit { get; set; }
  37.137 +
  37.138 +        public string FontFamily { get; set; }
  37.139 +        public double FontSize { get; set; }
  37.140 +        public double FontWeight { get; set; }
  37.141 +
  37.142 +        public double StartPosition { get; set; }
  37.143 +        public double EndPosition { get; set; }
  37.144 +
  37.145 +        public Axis RelatedAxis { get; set; }
  37.146 +
  37.147 +        public bool IsReversed { get { return StartPosition > EndPosition; } }
  37.148 +
  37.149 +        internal double Offset;
  37.150 +        internal double Scale;
  37.151 +        internal Point MidPoint;
  37.152 +        internal Point ScreenMin;
  37.153 +        internal Point ScreenMax;
  37.154 +
  37.155 +        public override string ToString()
  37.156 +        {
  37.157 +            return String.Format(CultureInfo.InvariantCulture, "{0}({1}, {2}, {3}, {4})", GetType().Name, Position, ActualMinimum, ActualMaximum, ActualMajorStep);
  37.158 +        }
  37.159 +
  37.160 +        public virtual void GetTickValues(out ICollection<double> majorValues, out ICollection<double> minorValues)
  37.161 +        {
  37.162 +            minorValues = CreateTickValues(ActualMinimum, ActualMaximum, ActualMinorStep);
  37.163 +            majorValues = CreateTickValues(ActualMinimum, ActualMaximum, ActualMajorStep);
  37.164 +        }
  37.165 +
  37.166 +        public virtual string FormatValue(double x)
  37.167 +        {
  37.168 +            return x.ToString(ActualStringFormat, CultureInfo.InvariantCulture);
  37.169 +        }
  37.170 +
  37.171 +        private static ICollection<double> CreateTickValues(double min, double max, double step)
  37.172 +        {
  37.173 +            if (max <= min)
  37.174 +                throw new InvalidOperationException("Axis: Maximum should be larger than minimum.");
  37.175 +            if (step <= 0)
  37.176 +                throw new InvalidOperationException("Axis: Step cannot be negative.");
  37.177 +
  37.178 +            double x = (int)Math.Round(min / step) * step;
  37.179 +
  37.180 +            var values = new Collection<double>();
  37.181 +            // Maximum number of iterations (in case of very small step size)
  37.182 +            int it = 0;
  37.183 +            const int maxit = 1000;
  37.184 +            double epsilon = Math.Abs(max - min) * 1e-6;
  37.185 +            while (x <= max + epsilon && it++ < maxit)
  37.186 +            {
  37.187 +                if (x >= min - epsilon && x <= max + epsilon)
  37.188 +                {
  37.189 +                    x = RemoveNoiseFromDoubleMath(x);
  37.190 +                    values.Add(x);
  37.191 +                }
  37.192 +                x += step;
  37.193 +            }
  37.194 +            return values;
  37.195 +        }
  37.196 +
  37.197 +        protected virtual double PreTransform(double x)
  37.198 +        {
  37.199 +            return x;
  37.200 +        }
  37.201 +
  37.202 +        protected virtual double PostInverseTransform(double x)
  37.203 +        {
  37.204 +            return x;
  37.205 +        }
  37.206 +
  37.207 +        public virtual Point Transform(double x, double y, Axis yAxis)
  37.208 +        {
  37.209 +            Debug.Assert(yAxis != null);
  37.210 +            if (IsPolar)
  37.211 +            {
  37.212 +                double r = (x - Offset) * Scale;
  37.213 +                double th = yAxis != null ? (y - yAxis.Offset) * yAxis.Scale : double.NaN;
  37.214 +                return new Point(MidPoint.X + r * Math.Cos(th), MidPoint.Y + r * Math.Sin(th));
  37.215 +            }
  37.216 +            if (yAxis == null)
  37.217 +                return new Point();
  37.218 +            return new Point(TransformX(x), yAxis != null ? yAxis.TransformX(y) : double.NaN);
  37.219 +        }
  37.220 +
  37.221 +        public double TransformX(double x)
  37.222 +        {
  37.223 +            return (PreTransform(x) - Offset) * Scale;
  37.224 +        }
  37.225 +
  37.226 +        public virtual Point InverseTransform(double x, double y, Axis yAxis)
  37.227 +        {
  37.228 +            Debug.Assert(yAxis != null);
  37.229 +            if (IsPolar)
  37.230 +            {
  37.231 +                x -= MidPoint.X;
  37.232 +                y -= MidPoint.Y;
  37.233 +                double th = Math.Atan2(y, x);
  37.234 +                double r = Math.Sqrt(x * x + y * y);
  37.235 +                x = r / Scale + Offset;
  37.236 +                y = yAxis != null ? th / yAxis.Scale + yAxis.Offset : double.NaN;
  37.237 +                return new Point(x, y);
  37.238 +            }
  37.239 +
  37.240 +            return new Point(InverseTransformX(x), yAxis.InverseTransformX(y));
  37.241 +        }
  37.242 +
  37.243 +        public double InverseTransformX(double x)
  37.244 +        {
  37.245 +            return PostInverseTransform(x / Scale + Offset);
  37.246 +        }
  37.247 +
  37.248 +        public double UpdateTransform(double x0, double x1, double y0, double y1)
  37.249 +        {
  37.250 +            ScreenMin = new Point(x0, y1);
  37.251 +            ScreenMax = new Point(x1, y0);
  37.252 +
  37.253 +            if (Position == AxisPosition.Angle)
  37.254 +            {
  37.255 +                MidPoint = new Point((x0 + x1) / 2, (y0 + y1) / 2);
  37.256 +                Scale = 2 * Math.PI / (ActualMaximum - ActualMinimum);
  37.257 +                Offset = ActualMinimum;
  37.258 +                return Scale;
  37.259 +            }
  37.260 +            if (Position == AxisPosition.Magnitude)
  37.261 +            {
  37.262 +                ActualMinimum = 0;
  37.263 +                MidPoint = new Point((x0 + x1) / 2, (y0 + y1) / 2);
  37.264 +                double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
  37.265 +                Scale = 0.5 * r / (ActualMaximum - ActualMinimum);
  37.266 +                Offset = ActualMinimum;
  37.267 +                return Scale;
  37.268 +            }
  37.269 +            double a0 = IsHorizontal ? x0 : y0;
  37.270 +            double a1 = IsHorizontal ? x1 : y1;
  37.271 +
  37.272 +            double dx = a1 - a0;
  37.273 +            a1 = a0 + EndPosition * dx;
  37.274 +            a0 = a0 + StartPosition * dx;
  37.275 +
  37.276 +            if (ActualMaximum - ActualMinimum < double.Epsilon)
  37.277 +                ActualMaximum = ActualMinimum + 1;
  37.278 +
  37.279 +            double max = PreTransform(ActualMaximum);
  37.280 +            double min = PreTransform(ActualMinimum);
  37.281 +
  37.282 +            const double eps = 1e-6;
  37.283 +            if (max - min < eps) max = min + 1;
  37.284 +
  37.285 +            if (Math.Abs(a0 - a1) != 0)
  37.286 +                Offset = (a0 * max - min * a1) / (a0 - a1);
  37.287 +            else
  37.288 +                Offset = 0;
  37.289 +
  37.290 +            Scale = (a1 - a0) / (max - min);
  37.291 +
  37.292 +            return Scale;
  37.293 +        }
  37.294 +
  37.295 +        public void SetScale(double scale)
  37.296 +        {
  37.297 +            double sgn = Math.Sign(Scale);
  37.298 +            double mid = (ActualMaximum + ActualMinimum) / 2;
  37.299 +            double dx = (Offset - mid) * Scale;
  37.300 +            Scale = sgn * scale;
  37.301 +            Offset = dx / Scale + mid;
  37.302 +        }
  37.303 +
  37.304 +        public virtual void Pan(double dx)
  37.305 +        {
  37.306 +            Minimum = ActualMinimum + dx;
  37.307 +            Maximum = ActualMaximum + dx;
  37.308 +        }
  37.309 +
  37.310 +        public virtual void ScaleAt(double factor, double x)
  37.311 +        {
  37.312 +            double dx0 = (ActualMinimum - x) * Scale;
  37.313 +            double dx1 = (ActualMaximum - x) * Scale;
  37.314 +            Scale *= factor;
  37.315 +            Minimum = dx0 / Scale + x;
  37.316 +            Maximum = dx1 / Scale + x;
  37.317 +        }
  37.318 +
  37.319 +        public virtual void Zoom(double x0, double x1)
  37.320 +        {
  37.321 +            Minimum = Math.Min(x0, x1);
  37.322 +            Maximum = Math.Max(x0, x1);
  37.323 +        }
  37.324 +
  37.325 +        public virtual void Reset()
  37.326 +        {
  37.327 +            Minimum = double.NaN;
  37.328 +            Maximum = double.NaN;
  37.329 +        }
  37.330 +
  37.331 +        /// <summary>
  37.332 +        /// Updates the minor/major step intervals if they are undefined.
  37.333 +        /// </summary>
  37.334 +        public void UpdateIntervals(double dx, double dy)
  37.335 +        {
  37.336 +            double labelSize = GetLabelSize();
  37.337 +            double length = IsHorizontal ? dx : dy;
  37.338 +
  37.339 +            if (!double.IsNaN(MajorStep))
  37.340 +                ActualMajorStep = MajorStep;
  37.341 +            else
  37.342 +                ActualMajorStep = CalculateActualInterval(length, labelSize);
  37.343 +
  37.344 +            if (!double.IsNaN(MinorStep))
  37.345 +                ActualMinorStep = MinorStep;
  37.346 +            else
  37.347 +                ActualMinorStep = ActualMajorStep / 5;
  37.348 +
  37.349 +            if (double.IsNaN(ActualMinorStep))
  37.350 +                ActualMinorStep = 2;
  37.351 +            if (double.IsNaN(ActualMajorStep))
  37.352 +                ActualMajorStep = 10;
  37.353 +
  37.354 +            ActualStringFormat = StringFormat;
  37.355 +        }
  37.356 +
  37.357 +        private double GetLabelSize()
  37.358 +        {
  37.359 +            if (IsHorizontal)
  37.360 +                return 100;
  37.361 +            if (IsVertical)
  37.362 +                return 30;
  37.363 +            if (Position == AxisPosition.Angle)
  37.364 +                return 50;
  37.365 +            if (Position == AxisPosition.Magnitude)
  37.366 +                return 100;
  37.367 +            return 50;
  37.368 +        }
  37.369 +
  37.370 +        protected virtual double CalculateActualInterval(double availableSize, double maxIntervalSize)
  37.371 +        {
  37.372 +            return CalculateActualInterval2(availableSize, maxIntervalSize);
  37.373 +        }
  37.374 +
  37.375 +        private double CalculateActualInterval1(double availableSize, double maxIntervalSize)
  37.376 +        {
  37.377 +            int minTags = 5;
  37.378 +            int maxTags = 20;
  37.379 +            int numberOfTags = (int)(availableSize / maxIntervalSize);
  37.380 +            double range = ActualMaximum - ActualMinimum;
  37.381 +            double interval = range / numberOfTags;
  37.382 +            const int k1 = 10;
  37.383 +            interval = Math.Log10(interval / k1);
  37.384 +            interval = Math.Ceiling(interval);
  37.385 +            interval = Math.Pow(10, interval) * k1;
  37.386 +
  37.387 +            if (range / interval > maxTags) interval *= 5;
  37.388 +            if (range / interval < minTags) interval *= 0.5;
  37.389 +
  37.390 +            if (interval <= 0) interval = 1;
  37.391 +            return interval;
  37.392 +        }
  37.393 +
  37.394 +        /// <summary>
  37.395 +        /// Returns the actual interval to use to determine which values are
  37.396 +        /// displayed in the axis.
  37.397 +        /// </summary>
  37.398 +        /// <param name="availableSize">The available size.</param>
  37.399 +        /// <returns>Actual interval to use to determine which values are
  37.400 +        /// displayed in the axis.
  37.401 +        /// </returns>
  37.402 +        private double CalculateActualInterval2(double availableSize, double maxIntervalSize)
  37.403 +        {
  37.404 +            Func<double, double> Exponent = x => Math.Ceiling(Math.Log(x, 10));
  37.405 +            Func<double, double> Mantissa = x => x / Math.Pow(10, Exponent(x) - 1);
  37.406 +
  37.407 +            // reduce intervals for horizontal axis.
  37.408 +            // double maxIntervals = Orientation == AxisOrientation.X ? MaximumAxisIntervalsPer200Pixels * 0.8 : MaximumAxisIntervalsPer200Pixels;
  37.409 +            // real maximum interval count
  37.410 +            double maxIntervalCount = availableSize / maxIntervalSize;
  37.411 +
  37.412 +            double range = Math.Abs(ActualMinimum - ActualMaximum);
  37.413 +            double interval = Math.Pow(10, Exponent(range));
  37.414 +            double tempInterval = interval;
  37.415 +
  37.416 +            // decrease interval until interval count becomes less than maxIntervalCount
  37.417 +            while (true)
  37.418 +            {
  37.419 +                int mantissa = (int)Mantissa(tempInterval);
  37.420 +                if (mantissa == 5)
  37.421 +                {
  37.422 +                    // reduce 5 to 2
  37.423 +                    tempInterval = RemoveNoiseFromDoubleMath(tempInterval / 2.5);
  37.424 +                }
  37.425 +                else if (mantissa == 2 || mantissa == 1 || mantissa == 10)
  37.426 +                {
  37.427 +                    // reduce 2 to 1,10 to 5,1 to 0.5
  37.428 +                    tempInterval = RemoveNoiseFromDoubleMath(tempInterval / 2.0);
  37.429 +                }
  37.430 +
  37.431 +                if (range / tempInterval > maxIntervalCount)
  37.432 +                {
  37.433 +                    break;
  37.434 +                }
  37.435 +
  37.436 +                interval = tempInterval;
  37.437 +            }
  37.438 +            return interval;
  37.439 +        }
  37.440 +
  37.441 +        /// <summary>
  37.442 +        /// Removes the noise from double math.
  37.443 +        /// </summary>
  37.444 +        /// <param name="value">The value.</param>
  37.445 +        /// <returns>A double without a noise.</returns>
  37.446 +        internal static double RemoveNoiseFromDoubleMath(double value)
  37.447 +        {
  37.448 +            if (value == 0.0 || Math.Abs((Math.Log10(Math.Abs(value)))) < 27)
  37.449 +            {
  37.450 +                return (double)((decimal)value);
  37.451 +            }
  37.452 +            return Double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
  37.453 +        }
  37.454 +
  37.455 +        public void Include(double p)
  37.456 +        {
  37.457 +            if (double.IsNaN(p) || double.IsInfinity(p))
  37.458 +                return;
  37.459 +
  37.460 +            if (double.IsNaN(ActualMinimum))
  37.461 +                ActualMinimum = p;
  37.462 +            else
  37.463 +                ActualMinimum = Math.Min(ActualMinimum, p);
  37.464 +
  37.465 +            if (double.IsNaN(ActualMaximum))
  37.466 +                ActualMaximum = p;
  37.467 +            else
  37.468 +                ActualMaximum = Math.Max(ActualMaximum, p);
  37.469 +        }
  37.470 +
  37.471 +    }
  37.472 +}
  37.473 \ No newline at end of file
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/External/OxyPlot/OxyPlot/Axes/TickStyle.cs	Sat Jun 08 16:53:22 2013 +0000
    38.3 @@ -0,0 +1,57 @@
    38.4 +// --------------------------------------------------------------------------------------------------------------------
    38.5 +// <copyright file="TickStyle.cs" company="OxyPlot">
    38.6 +//   The MIT License (MIT)
    38.7 +//
    38.8 +//   Copyright (c) 2012 Oystein Bjorke
    38.9 +//
   38.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   38.11 +//   copy of this software and associated documentation files (the
   38.12 +//   "Software"), to deal in the Software without restriction, including
   38.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   38.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   38.15 +//   permit persons to whom the Software is furnished to do so, subject to
   38.16 +//   the following conditions:
   38.17 +//
   38.18 +//   The above copyright notice and this permission notice shall be included
   38.19 +//   in all copies or substantial portions of the Software.
   38.20 +//
   38.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   38.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   38.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   38.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   38.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   38.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   38.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   38.28 +// </copyright>
   38.29 +// <summary>
   38.30 +//   Tick styles.
   38.31 +// </summary>
   38.32 +// --------------------------------------------------------------------------------------------------------------------
   38.33 +namespace OxyPlot.Axes
   38.34 +{
   38.35 +    /// <summary>
   38.36 +    /// Specifies the style of axis ticks.
   38.37 +    /// </summary>
   38.38 +    public enum TickStyle
   38.39 +    {
   38.40 +        /// <summary>
   38.41 +        /// The ticks are rendered crossing the axis line.
   38.42 +        /// </summary>
   38.43 +        Crossing,
   38.44 +
   38.45 +        /// <summary>
   38.46 +        /// The ticks are rendered inside of the plot area.
   38.47 +        /// </summary>
   38.48 +        Inside,
   38.49 +
   38.50 +        /// <summary>
   38.51 +        /// The ticks are rendered Outside the plot area.
   38.52 +        /// </summary>
   38.53 +        Outside,
   38.54 +
   38.55 +        /// <summary>
   38.56 +        /// The ticks are not rendered.
   38.57 +        /// </summary>
   38.58 +        None
   38.59 +    }
   38.60 +}
   38.61 \ No newline at end of file
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/External/OxyPlot/OxyPlot/Axes/TimeAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    39.3 @@ -0,0 +1,120 @@
    39.4 +// --------------------------------------------------------------------------------------------------------------------
    39.5 +// <copyright file="TimeAxis.cs" company="OxyPlot">
    39.6 +//   The MIT License (MIT)
    39.7 +//
    39.8 +//   Copyright (c) 2012 Oystein Bjorke
    39.9 +//
   39.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   39.11 +//   copy of this software and associated documentation files (the
   39.12 +//   "Software"), to deal in the Software without restriction, including
   39.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   39.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   39.15 +//   permit persons to whom the Software is furnished to do so, subject to
   39.16 +//   the following conditions:
   39.17 +//
   39.18 +//   The above copyright notice and this permission notice shall be included
   39.19 +//   in all copies or substantial portions of the Software.
   39.20 +//
   39.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   39.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   39.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   39.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   39.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   39.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   39.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   39.28 +// </copyright>
   39.29 +// <summary>
   39.30 +//   Time Axis
   39.31 +//   The values should be in seconds.
   39.32 +//   The StringFormat value can be used to force formatting of the axis values
   39.33 +//   "h:mm" shows hours and minutes
   39.34 +//   "m:ss" shows minutes and seconds
   39.35 +// </summary>
   39.36 +// --------------------------------------------------------------------------------------------------------------------
   39.37 +using System;
   39.38 +using System.Linq;
   39.39 +
   39.40 +namespace OxyPlot
   39.41 +{
   39.42 +    /// <summary>
   39.43 +    /// Time Axis
   39.44 +    /// The values should be in seconds.
   39.45 +    /// The StringFormat value can be used to force formatting of the axis values
   39.46 +    /// "h:mm" shows hours and minutes
   39.47 +    /// "m:ss" shows minutes and seconds
   39.48 +    /// </summary>
   39.49 +    public class TimeAxis : LinearAxis
   39.50 +    {
   39.51 +        /// <summary>
   39.52 +        /// Initializes a new instance of the <see cref = "TimeAxis" /> class.
   39.53 +        /// </summary>
   39.54 +        /// <param name = "pos">The position.</param>
   39.55 +        /// <param name = "title">The axis title.</param>
   39.56 +        /// <param name = "format">The string format for the axis values.</param>
   39.57 +        public TimeAxis(AxisPosition pos, string title = null, string format = "m:ss")
   39.58 +            : base(pos, title)
   39.59 +        {
   39.60 +            StringFormat = format;
   39.61 +        }
   39.62 +
   39.63 +        /// <summary>
   39.64 +        /// Initializes a new instance of the <see cref = "TimeAxis" /> class.
   39.65 +        /// </summary>
   39.66 +        /// <param name = "pos">The position.</param>
   39.67 +        /// <param name = "min">The min.</param>
   39.68 +        /// <param name = "max">The max.</param>
   39.69 +        /// <param name = "title">The axis title.</param>
   39.70 +        /// <param name = "format">The string format for the axis values.</param>
   39.71 +        public TimeAxis(AxisPosition pos = AxisPosition.Bottom, double min = double.NaN, double max = double.NaN,
   39.72 +                        string title = null, string format = "m:ss")
   39.73 +            : base(pos, min, max, title)
   39.74 +        {
   39.75 +            StringFormat = format;
   39.76 +        }
   39.77 +
   39.78 +        /// <summary>
   39.79 +        /// Formats the value.
   39.80 +        /// </summary>
   39.81 +        /// <param name = "x">The x.</param>
   39.82 +        /// <returns></returns>
   39.83 +        public override string FormatValue(double x)
   39.84 +        {
   39.85 +            var span = TimeSpan.FromSeconds(x);
   39.86 +            string s = ActualStringFormat ?? "h:mm:ss";
   39.87 +
   39.88 +            s = s.Replace("mm", span.Minutes.ToString("00"));
   39.89 +            s = s.Replace("ss", span.Seconds.ToString("00"));
   39.90 +            s = s.Replace("hh", span.Hours.ToString("00"));
   39.91 +            s = s.Replace("msec", span.Milliseconds.ToString("000"));
   39.92 +            s = s.Replace("m", ((int)span.TotalMinutes).ToString("0"));
   39.93 +            s = s.Replace("s", ((int)span.TotalSeconds).ToString("0"));
   39.94 +            s = s.Replace("h", ((int)span.TotalHours).ToString("0"));
   39.95 +            return s;
   39.96 +        }
   39.97 +
   39.98 +        protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
   39.99 +        {
  39.100 +            double range = Math.Abs(ActualMinimum - ActualMaximum);
  39.101 +            double interval = 1;
  39.102 +            var goodIntervals = new[] { 1.0, 5, 10, 30, 60, 120, 300, 600, 900, 1200, 1800, 3600 };
  39.103 +
  39.104 +            const int maxSteps = 20;
  39.105 +
  39.106 +            while (true)
  39.107 +            {
  39.108 +                if (range / interval < maxSteps)
  39.109 +                {
  39.110 +                    return interval;
  39.111 +                }
  39.112 +
  39.113 +                double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
  39.114 +                if (nextInterval == 0)
  39.115 +                {
  39.116 +                    nextInterval = interval * 2;
  39.117 +                }
  39.118 +
  39.119 +                interval = nextInterval;
  39.120 +            }
  39.121 +        }
  39.122 +    }
  39.123 +}
  39.124 \ No newline at end of file
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/External/OxyPlot/OxyPlot/Axes/TimeSpanAxis.cs	Sat Jun 08 16:53:22 2013 +0000
    40.3 @@ -0,0 +1,197 @@
    40.4 +// --------------------------------------------------------------------------------------------------------------------
    40.5 +// <copyright file="TimeSpanAxis.cs" company="OxyPlot">
    40.6 +//   The MIT License (MIT)
    40.7 +//
    40.8 +//   Copyright (c) 2012 Oystein Bjorke
    40.9 +//
   40.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   40.11 +//   copy of this software and associated documentation files (the
   40.12 +//   "Software"), to deal in the Software without restriction, including
   40.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   40.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   40.15 +//   permit persons to whom the Software is furnished to do so, subject to
   40.16 +//   the following conditions:
   40.17 +//
   40.18 +//   The above copyright notice and this permission notice shall be included
   40.19 +//   in all copies or substantial portions of the Software.
   40.20 +//
   40.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   40.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   40.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   40.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   40.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   40.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   40.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   40.28 +// </copyright>
   40.29 +// <summary>
   40.30 +//   Time axis.
   40.31 +// </summary>
   40.32 +// --------------------------------------------------------------------------------------------------------------------
   40.33 +namespace OxyPlot.Axes
   40.34 +{
   40.35 +    using System;
   40.36 +    using System.Linq;
   40.37 +
   40.38 +    /// <summary>
   40.39 +    /// Represents an axis presenting <see cref="System.TimeSpan"/> values.
   40.40 +    /// </summary>
   40.41 +    /// <remarks>
   40.42 +    /// The values should be in seconds.
   40.43 +    /// The StringFormat value can be used to force formatting of the axis values
   40.44 +    /// "h:mm" shows hours and minutes
   40.45 +    /// "m:ss" shows minutes and seconds
   40.46 +    /// </remarks>
   40.47 +    public class TimeSpanAxis : LinearAxis
   40.48 +    {
   40.49 +        /// <summary>
   40.50 +        /// Initializes a new instance of the <see cref = "TimeSpanAxis" /> class.
   40.51 +        /// </summary>
   40.52 +        public TimeSpanAxis()
   40.53 +        {
   40.54 +        }
   40.55 +
   40.56 +        /// <summary>
   40.57 +        /// Initializes a new instance of the <see cref="TimeSpanAxis"/> class.
   40.58 +        /// </summary>
   40.59 +        /// <param name="pos">
   40.60 +        /// The position.
   40.61 +        /// </param>
   40.62 +        /// <param name="title">
   40.63 +        /// The axis title.
   40.64 +        /// </param>
   40.65 +        /// <param name="format">
   40.66 +        /// The string format for the axis values.
   40.67 +        /// </param>
   40.68 +        public TimeSpanAxis(AxisPosition pos, string title = null, string format = "m:ss")
   40.69 +            : base(pos, title)
   40.70 +        {
   40.71 +            this.StringFormat = format;
   40.72 +        }
   40.73 +
   40.74 +        /// <summary>
   40.75 +        /// Initializes a new instance of the <see cref="TimeSpanAxis"/> class.
   40.76 +        /// </summary>
   40.77 +        /// <param name="pos">
   40.78 +        /// The position.
   40.79 +        /// </param>
   40.80 +        /// <param name="min">
   40.81 +        /// The min.
   40.82 +        /// </param>
   40.83 +        /// <param name="max">
   40.84 +        /// The max.
   40.85 +        /// </param>
   40.86 +        /// <param name="title">
   40.87 +        /// The axis title.
   40.88 +        /// </param>
   40.89 +        /// <param name="format">
   40.90 +        /// The string format for the axis values.
   40.91 +        /// </param>
   40.92 +        public TimeSpanAxis(
   40.93 +            AxisPosition pos = AxisPosition.Bottom,
   40.94 +            double min = double.NaN,
   40.95 +            double max = double.NaN,
   40.96 +            string title = null,
   40.97 +            string format = "m:ss")
   40.98 +            : base(pos, min, max, title)
   40.99 +        {
  40.100 +            this.StringFormat = format;
  40.101 +        }
  40.102 +
  40.103 +        /// <summary>
  40.104 +        /// Converts a time span to a double.
  40.105 +        /// </summary>
  40.106 +        /// <param name="s">
  40.107 +        /// The time span.
  40.108 +        /// </param>
  40.109 +        /// <returns>
  40.110 +        /// A double value.
  40.111 +        /// </returns>
  40.112 +        public static double ToDouble(TimeSpan s)
  40.113 +        {
  40.114 +            return s.TotalSeconds;
  40.115 +        }
  40.116 +
  40.117 +        /// <summary>
  40.118 +        /// Converts a double to a time span.
  40.119 +        /// </summary>
  40.120 +        /// <param name="value">
  40.121 +        /// The value.
  40.122 +        /// </param>
  40.123 +        /// <returns>
  40.124 +        /// A time span.
  40.125 +        /// </returns>
  40.126 +        public static TimeSpan ToTimeSpan(double value)
  40.127 +        {
  40.128 +            return TimeSpan.FromSeconds(value);
  40.129 +        }
  40.130 +
  40.131 +        /// <summary>
  40.132 +        /// Formats the value.
  40.133 +        /// </summary>
  40.134 +        /// <param name="x">
  40.135 +        /// The x.
  40.136 +        /// </param>
  40.137 +        /// <returns>
  40.138 +        /// The format value.
  40.139 +        /// </returns>
  40.140 +        public override string FormatValue(double x)
  40.141 +        {
  40.142 +            TimeSpan span = TimeSpan.FromSeconds(x);
  40.143 +            string s = this.ActualStringFormat ?? "h:mm:ss";
  40.144 +
  40.145 +            s = s.Replace("mm", span.Minutes.ToString("00"));
  40.146 +            s = s.Replace("ss", span.Seconds.ToString("00"));
  40.147 +            s = s.Replace("hh", span.Hours.ToString("00"));
  40.148 +            s = s.Replace("msec", span.Milliseconds.ToString("000"));
  40.149 +            s = s.Replace("m", ((int)span.TotalMinutes).ToString("0"));
  40.150 +            s = s.Replace("s", ((int)span.TotalSeconds).ToString("0"));
  40.151 +            s = s.Replace("h", ((int)span.TotalHours).ToString("0"));
  40.152 +            return s;
  40.153 +        }
  40.154 +
  40.155 +        /// <summary>
  40.156 +        /// 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.
  40.157 +        /// </summary>
  40.158 +        /// <param name="x">The coordinate.</param>
  40.159 +        /// <returns>
  40.160 +        /// The value.
  40.161 +        /// </returns>
  40.162 +        public override object GetValue(double x)
  40.163 +        {
  40.164 +            return TimeSpan.FromSeconds(x);
  40.165 +        }
  40.166 +
  40.167 +        /// <summary>
  40.168 +        /// Calculates the actual interval.
  40.169 +        /// </summary>
  40.170 +        /// <param name="availableSize">Size of the available area.</param>
  40.171 +        /// <param name="maxIntervalSize">Maximum length of the intervals.</param>
  40.172 +        /// <returns>
  40.173 +        /// The calculate actual interval.
  40.174 +        /// </returns>
  40.175 +        protected override double CalculateActualInterval(double availableSize, double maxIntervalSize)
  40.176 +        {
  40.177 +            double range = Math.Abs(this.ActualMinimum - this.ActualMaximum);
  40.178 +            double interval = 1;
  40.179 +            var goodIntervals = new[] { 1.0, 5, 10, 30, 60, 120, 300, 600, 900, 1200, 1800, 3600 };
  40.180 +
  40.181 +            int maxNumberOfIntervals = Math.Max((int)(availableSize / maxIntervalSize), 2);
  40.182 +
  40.183 +            while (true)
  40.184 +            {
  40.185 +                if (range / interval < maxNumberOfIntervals)
  40.186 +                {
  40.187 +                    return interval;
  40.188 +                }
  40.189 +
  40.190 +                double nextInterval = goodIntervals.FirstOrDefault(i => i > interval);
  40.191 +                if (Math.Abs(nextInterval) < double.Epsilon)
  40.192 +                {
  40.193 +                    nextInterval = interval * 2;
  40.194 +                }
  40.195 +
  40.196 +                interval = nextInterval;
  40.197 +            }
  40.198 +        }
  40.199 +    }
  40.200 +}
  40.201 \ No newline at end of file
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/External/OxyPlot/OxyPlot/ClassDiagrams/PlotModel.cd	Sat Jun 08 16:53:22 2013 +0000
    41.3 @@ -0,0 +1,276 @@
    41.4 +<?xml version="1.0" encoding="utf-8"?>
    41.5 +<ClassDiagram MajorVersion="1" MinorVersion="1">
    41.6 +  <Class Name="OxyPlot.PlotModel" Collapsed="true">
    41.7 +    <Position X="2.5" Y="3.25" Width="2.75" />
    41.8 +    <Compartments>
    41.9 +      <Compartment Name="Methods" Collapsed="true" />
   41.10 +    </Compartments>
   41.11 +    <TypeIdentifier>
   41.12 +      <HashCode>EBZwcA2UaBI/BUK9ZBHDJRgBY1uVERMI45sgpP2SPzE=</HashCode>
   41.13 +      <FileName>PlotModel\PlotModel.cs</FileName>
   41.14 +    </TypeIdentifier>
   41.15 +  </Class>
   41.16 +  <Class Name="OxyPlot.LineSeries" Collapsed="true">
   41.17 +    <Position X="9.75" Y="7.75" Width="1.5" />
   41.18 +    <TypeIdentifier>
   41.19 +      <HashCode>AAQCAAEIAiAAAGCAABBAAAAhRCAMEAAAADAAggACIgA=</HashCode>
   41.20 +      <FileName>Series\LineSeries.cs</FileName>
   41.21 +    </TypeIdentifier>
   41.22 +  </Class>
   41.23 +  <Class Name="OxyPlot.DataPointSeries" Collapsed="true">
   41.24 +    <Position X="9.75" Y="6.5" Width="1.5" />
   41.25 +    <TypeIdentifier>
   41.26 +      <HashCode>IAAAAAyAEAABgAAAACACAAAABAAEAAAAAAAAAgAAAAA=</HashCode>
   41.27 +      <FileName>Series\DataPointSeries.cs</FileName>
   41.28 +    </TypeIdentifier>
   41.29 +  </Class>
   41.30 +  <Class Name="OxyPlot.AreaSeries" Collapsed="true">
   41.31 +    <Position X="11" Y="9" Width="1.5" />
   41.32 +    <TypeIdentifier>
   41.33 +      <HashCode>AgAAAAEAEAAAAIAAAAAACAAAAAAECAAAABMAAgIAAAA=</HashCode>
   41.34 +      <FileName>Series\AreaSeries.cs</FileName>
   41.35 +    </TypeIdentifier>
   41.36 +  </Class>
   41.37 +  <Class Name="OxyPlot.FunctionSeries" Collapsed="true">
   41.38 +    <Position X="9.25" Y="9" Width="1.5" />
   41.39 +    <TypeIdentifier>
   41.40 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
   41.41 +      <FileName>Series\FunctionSeries.cs</FileName>
   41.42 +    </TypeIdentifier>
   41.43 +  </Class>
   41.44 +  <Class Name="OxyPlot.LinearAxis" Collapsed="true">
   41.45 +    <Position X="12" Y="2" Width="1.5" />
   41.46 +    <TypeIdentifier>
   41.47 +      <HashCode>AAQAAAAAAQAAACAAAAAAAAAAAAAAAAAAAAEAAAAAQAA=</HashCode>
   41.48 +      <FileName>Axes\LinearAxis.cs</FileName>
   41.49 +    </TypeIdentifier>
   41.50 +  </Class>
   41.51 +  <Class Name="OxyPlot.LogarithmicAxis" Collapsed="true">
   41.52 +    <Position X="14.25" Y="2" Width="1.5" />
   41.53 +    <TypeIdentifier>
   41.54 +      <HashCode>AAAAAAAAAQAAEgAAAIAAABQAAAAAQAAAAAAAABQAQAA=</HashCode>
   41.55 +      <FileName>Axes\LogarithmicAxis.cs</FileName>
   41.56 +    </TypeIdentifier>
   41.57 +  </Class>
   41.58 +  <Class Name="OxyPlot.TimeSpanAxis" Collapsed="true">
   41.59 +    <Position X="12" Y="3.5" Width="1.5" />
   41.60 +    <TypeIdentifier>
   41.61 +      <HashCode>AAAAAAAAIAAAAAEAAAAAAAAAAAEAAAAAABEAAAAAAAA=</HashCode>
   41.62 +      <FileName>Axes\TimeSpanAxis.cs</FileName>
   41.63 +    </TypeIdentifier>
   41.64 +  </Class>
   41.65 +  <Class Name="OxyPlot.CategoryAxis" Collapsed="true">
   41.66 +    <Position X="14.25" Y="3.5" Width="1.5" />
   41.67 +    <TypeIdentifier>
   41.68 +      <HashCode>AIAAEAABMAAEEAgAIBAAAFAAAAAEnAAAAAEgAJAAABE=</HashCode>
   41.69 +      <FileName>Axes\CategoryAxis.cs</FileName>
   41.70 +    </TypeIdentifier>
   41.71 +  </Class>
   41.72 +  <Class Name="OxyPlot.DateTimeAxis" Collapsed="true">
   41.73 +    <Position X="16.25" Y="3.5" Width="1.5" />
   41.74 +    <TypeIdentifier>
   41.75 +      <HashCode>gAIAAAAAIAAkGAEBAAAAIAAAggAAAAAAABEAAAAVAAA=</HashCode>
   41.76 +      <FileName>Axes\DateTimeAxis.cs</FileName>
   41.77 +    </TypeIdentifier>
   41.78 +  </Class>
   41.79 +  <Class Name="OxyPlot.Annotation" Collapsed="true">
   41.80 +    <Position X="25" Y="3.25" Width="1.5" />
   41.81 +    <TypeIdentifier>
   41.82 +      <HashCode>gAAQAAAFAAAAAAAAAEAAQAQAAAAAAAAEABAADAACAAA=</HashCode>
   41.83 +      <FileName>Annotations\Annotation.cs</FileName>
   41.84 +    </TypeIdentifier>
   41.85 +  </Class>
   41.86 +  <Class Name="OxyPlot.LineAnnotation" Collapsed="true">
   41.87 +    <Position X="25" Y="4.25" Width="1.5" />
   41.88 +    <TypeIdentifier>
   41.89 +      <HashCode>BAAQEAAAACBwAIAAABgAgAAAEAAAAAAACTAAkgAgYGA=</HashCode>
   41.90 +      <FileName>Annotations\LineAnnotation.cs</FileName>
   41.91 +    </TypeIdentifier>
   41.92 +  </Class>
   41.93 +  <Class Name="OxyPlot.BarSeries" Collapsed="true">
   41.94 +    <Position X="1.5" Y="10.25" Width="1.5" />
   41.95 +    <TypeIdentifier>
   41.96 +      <HashCode>CAAAAAgAIAQAAAAAAAAAAAAAAIAAAABAAAAAEAAAAAA=</HashCode>
   41.97 +      <FileName>Series\BarSeries\BarSeries.cs</FileName>
   41.98 +    </TypeIdentifier>
   41.99 +  </Class>
  41.100 +  <Class Name="OxyPlot.XYAxisSeries" Collapsed="true">
  41.101 +    <Position X="6.5" Y="5.25" Width="1.5" />
  41.102 +    <TypeIdentifier>
  41.103 +      <HashCode>sAAQAAE1WAAAAAAAAEAAQAQAAAAEAAAAABAUACACEAA=</HashCode>
  41.104 +      <FileName>Series\XYAxisSeries.cs</FileName>
  41.105 +    </TypeIdentifier>
  41.106 +  </Class>
  41.107 +  <Class Name="OxyPlot.CandleStickSeries" Collapsed="true">
  41.108 +    <Position X="13.5" Y="7.75" Width="1.5" />
  41.109 +    <TypeIdentifier>
  41.110 +      <HashCode>AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAABAA=</HashCode>
  41.111 +      <FileName>Series\CandleStickSeries.cs</FileName>
  41.112 +    </TypeIdentifier>
  41.113 +  </Class>
  41.114 +  <Class Name="OxyPlot.HighLowSeries" Collapsed="true">
  41.115 +    <Position X="13.5" Y="6.5" Width="1.5" />
  41.116 +    <TypeIdentifier>
  41.117 +      <HashCode>AAAAAAkBECABCAAAABgAAAQABAQEAAABAHAAggACAAA=</HashCode>
  41.118 +      <FileName>Series\HighLowSeries.cs</FileName>
  41.119 +    </TypeIdentifier>
  41.120 +  </Class>
  41.121 +  <Class Name="OxyPlot.ItemsSeries" Collapsed="true">
  41.122 +    <Position X="6.5" Y="4.25" Width="1.5" />
  41.123 +    <TypeIdentifier>
  41.124 +      <HashCode>AAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAIIAAAA=</HashCode>
  41.125 +      <FileName>Series\ItemsSeries.cs</FileName>
  41.126 +    </TypeIdentifier>
  41.127 +  </Class>
  41.128 +  <Class Name="OxyPlot.PieSeries" Collapsed="true">
  41.129 +    <Position X="8.5" Y="4.25" Width="1.5" />
  41.130 +    <TypeIdentifier>
  41.131 +      <HashCode>AQAQAAEAWGAYACAIAAAAAAAgAAgEICJAgpQFAoCCAAI=</HashCode>
  41.132 +      <FileName>Series\PieSeries.cs</FileName>
  41.133 +    </TypeIdentifier>
  41.134 +  </Class>
  41.135 +  <Class Name="OxyPlot.ScatterSeries" Collapsed="true">
  41.136 +    <Position X="11.75" Y="7.75" Width="1.5" />
  41.137 +    <TypeIdentifier>
  41.138 +      <HashCode>AARQAAEIEAAAAEgQAAAIAAAgACBEAAAEABAwAgQDAgA=</HashCode>
  41.139 +      <FileName>Series\ScatterSeries.cs</FileName>
  41.140 +    </TypeIdentifier>
  41.141 +  </Class>
  41.142 +  <Class Name="OxyPlot.StairStepSeries" Collapsed="true">
  41.143 +    <Position X="7.5" Y="9" Width="1.5" />
  41.144 +    <TypeIdentifier>
  41.145 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAAAA=</HashCode>
  41.146 +      <FileName>Series\StairStepSeries.cs</FileName>
  41.147 +    </TypeIdentifier>
  41.148 +  </Class>
  41.149 +  <Class Name="OxyPlot.StemSeries" Collapsed="true">
  41.150 +    <Position X="12.75" Y="9" Width="1.5" />
  41.151 +    <TypeIdentifier>
  41.152 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAQAA=</HashCode>
  41.153 +      <FileName>Series\StemSeries.cs</FileName>
  41.154 +    </TypeIdentifier>
  41.155 +  </Class>
  41.156 +  <Class Name="OxyPlot.AngleAxis" Collapsed="true">
  41.157 +    <Position X="18.25" Y="3.5" Width="1.5" />
  41.158 +    <TypeIdentifier>
  41.159 +      <HashCode>AAAAAAAAAQAAAAAAAAAAQAQAAAAEAAAAABAAAAAAAAA=</HashCode>
  41.160 +      <FileName>Axes\AngleAxis.cs</FileName>
  41.161 +    </TypeIdentifier>
  41.162 +  </Class>
  41.163 +  <Class Name="OxyPlot.MagnitudeAxis" Collapsed="true">
  41.164 +    <Position X="20.25" Y="3.5" Width="1.5" />
  41.165 +    <TypeIdentifier>
  41.166 +      <HashCode>AAAAAAAAAQAAAAAAAAAAQAQAAAAEAIAAABAAAAAAAAA=</HashCode>
  41.167 +      <FileName>Axes\MagnitudeAxis.cs</FileName>
  41.168 +    </TypeIdentifier>
  41.169 +  </Class>
  41.170 +  <Class Name="OxyPlot.Series" Collapsed="true">
  41.171 +    <Position X="6.5" Y="3.25" Width="1.5" />
  41.172 +    <TypeIdentifier>
  41.173 +      <HashCode>AAAQAAEAWABAEEAAAAAAAAAAAAAEAAAAABAkBgISAAA=</HashCode>
  41.174 +      <FileName>Series\Series.cs</FileName>
  41.175 +    </TypeIdentifier>
  41.176 +    <Lollipop Position="0.2" />
  41.177 +  </Class>
  41.178 +  <Class Name="OxyPlot.Axis" Collapsed="true">
  41.179 +    <Position X="13.25" Y="0.5" Width="1.5" />
  41.180 +    <TypeIdentifier>
  41.181 +      <HashCode>gEeXCAGRedQgH2V09tJAe5wCkhCEgABEG1cgxZQB4CU=</HashCode>
  41.182 +      <FileName>Axes\Axis.cs</FileName>
  41.183 +    </TypeIdentifier>
  41.184 +  </Class>
  41.185 +  <Class Name="OxyPlot.ArrowAnnotation" Collapsed="true">
  41.186 +    <Position X="26.75" Y="4.25" Width="1.5" />
  41.187 +    <TypeIdentifier>
  41.188 +      <HashCode>AAQACAAAACBAQAAAQFAAAAAAABAAAAAAgDAAgAAAAAg=</HashCode>
  41.189 +      <FileName>Annotations\ArrowAnnotation.cs</FileName>
  41.190 +    </TypeIdentifier>
  41.191 +  </Class>
  41.192 +  <Class Name="OxyPlot.PolygonAnnotation" Collapsed="true">
  41.193 +    <Position X="23.25" Y="4.25" Width="1.5" />
  41.194 +    <TypeIdentifier>
  41.195 +      <HashCode>AAAAAAAAACBggAAAABAAAAAAAAAACAAAADAAgAAAAAA=</HashCode>
  41.196 +      <FileName>Annotations\PolygonAnnotation.cs</FileName>
  41.197 +    </TypeIdentifier>
  41.198 +  </Class>
  41.199 +  <Class Name="OxyPlot.TextAnnotation" Collapsed="true">
  41.200 +    <Position X="28.5" Y="4.25" Width="1.5" />
  41.201 +    <TypeIdentifier>
  41.202 +      <HashCode>AAAAAAAgACBAAIAggAAAAAAAAAgAAAIAABIggAAAgAA=</HashCode>
  41.203 +      <FileName>Annotations\TextAnnotation.cs</FileName>
  41.204 +    </TypeIdentifier>
  41.205 +  </Class>
  41.206 +  <Class Name="OxyPlot.BarSeriesBase" Collapsed="true">
  41.207 +    <Position X="2" Y="7.75" Width="1.5" />
  41.208 +    <TypeIdentifier>
  41.209 +      <HashCode>BYQAAIEAKCSAACCQAAAAAAABAAgEIBBAAhAUAgoCAAE=</HashCode>
  41.210 +      <FileName>Series\BarSeries\BarSeriesBase.cs</FileName>
  41.211 +    </TypeIdentifier>
  41.212 +    <Lollipop Position="0.2" />
  41.213 +  </Class>
  41.214 +  <Class Name="OxyPlot.ColumnSeries" Collapsed="true">
  41.215 +    <Position X="3.25" Y="10.25" Width="1.5" />
  41.216 +    <TypeIdentifier>
  41.217 +      <HashCode>AAAAAAgAIAQAAAAAAEAAAAAAAIAAAABAAAAAEAAAAAA=</HashCode>
  41.218 +      <FileName>Series\BarSeries\ColumnSeries.cs</FileName>
  41.219 +    </TypeIdentifier>
  41.220 +  </Class>
  41.221 +  <Class Name="OxyPlot.IntervalBarSeries" Collapsed="true">
  41.222 +    <Position X="3.75" Y="7.75" Width="1.5" />
  41.223 +    <TypeIdentifier>
  41.224 +      <HashCode>DQQAAAkBGCSACECAAAAAAAABAIgEIgAAABAUEgoCAAE=</HashCode>
  41.225 +      <FileName>Series\BarSeries\IntervalBarSeries.cs</FileName>
  41.226 +    </TypeIdentifier>
  41.227 +    <Lollipop Position="0.2" />
  41.228 +  </Class>
  41.229 +  <Class Name="OxyPlot.RectangleBarSeries" Collapsed="true">
  41.230 +    <Position X="5.5" Y="6.5" Width="1.75" />
  41.231 +    <TypeIdentifier>
  41.232 +      <HashCode>AAAAAAEAECCACACAAAAAAAAAAAgEAAAAABAQAggCAAE=</HashCode>
  41.233 +      <FileName>Series\BarSeries\RectangleBarSeries.cs</FileName>
  41.234 +    </TypeIdentifier>
  41.235 +  </Class>
  41.236 +  <Class Name="OxyPlot.TornadoBarSeries" Collapsed="true">
  41.237 +    <Position X="5.5" Y="7.75" Width="1.5" />
  41.238 +    <TypeIdentifier>
  41.239 +      <HashCode>DYQAAAsBGCUACEAAAQAgAAABAKgEAoAAABAUEgICAAE=</HashCode>
  41.240 +      <FileName>Series\BarSeries\TornadoBarSeries.cs</FileName>
  41.241 +    </TypeIdentifier>
  41.242 +  </Class>
  41.243 +  <Class Name="OxyPlot.ColorAxis" Collapsed="true">
  41.244 +    <Position X="16.25" Y="2" Width="1.5" />
  41.245 +    <TypeIdentifier>
  41.246 +      <HashCode>AAAAABAAAQAAAAAAAQIAACAAAAAAAAiAABAAAQAAAAA=</HashCode>
  41.247 +      <FileName>Axes\ColorAxis.cs</FileName>
  41.248 +    </TypeIdentifier>
  41.249 +  </Class>
  41.250 +  <Class Name="OxyPlot.BarSeriesBase&lt;T&gt;" Collapsed="true">
  41.251 +    <Position X="2" Y="8.75" Width="1.5" />
  41.252 +    <TypeIdentifier>
  41.253 +      <HashCode>AAAAAAAAEAAACEAAAAAAAAAAAAAAAgAAAAAAAAAAAAA=</HashCode>
  41.254 +      <FileName>Series\BarSeries\BarSeriesBase{T}.cs</FileName>
  41.255 +    </TypeIdentifier>
  41.256 +  </Class>
  41.257 +  <Class Name="OxyPlot.CategorizedSeries" Collapsed="true">
  41.258 +    <Position X="2" Y="6.5" Width="1.5" />
  41.259 +    <TypeIdentifier>
  41.260 +      <HashCode>AAAAAAgAAAAAAAAAAAAAAAAAAIAAAgAAAAAAEAAAAAA=</HashCode>
  41.261 +      <FileName>Series\BarSeries\CategorizedSeries.cs</FileName>
  41.262 +    </TypeIdentifier>
  41.263 +  </Class>
  41.264 +  <Class Name="OxyPlot.ErrorColumnSeries" Collapsed="true">
  41.265 +    <Position X="3" Y="11.25" Width="2" />
  41.266 +    <TypeIdentifier>
  41.267 +      <HashCode>AAAIAAAAAEAAAAAAAAAAAAAAAAAEABAAAAAAAAAAAAA=</HashCode>
  41.268 +      <FileName>Series\BarSeries\ErrorColumnSeries.cs</FileName>
  41.269 +    </TypeIdentifier>
  41.270 +  </Class>
  41.271 +  <Interface Name="OxyPlot.ITrackableSeries" Collapsed="true">
  41.272 +    <Position X="6.5" Y="2" Width="1.5" />
  41.273 +    <TypeIdentifier>
  41.274 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAQAAA=</HashCode>
  41.275 +      <FileName>Series\ITrackableSeries.cs</FileName>
  41.276 +    </TypeIdentifier>
  41.277 +  </Interface>
  41.278 +  <Font Name="Segoe UI" Size="9" />
  41.279 +</ClassDiagram>
  41.280 \ No newline at end of file
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/External/OxyPlot/OxyPlot/ClassDiagrams/Reporting.cd	Sat Jun 08 16:53:22 2013 +0000
    42.3 @@ -0,0 +1,204 @@
    42.4 +<?xml version="1.0" encoding="utf-8"?>
    42.5 +<ClassDiagram MajorVersion="1" MinorVersion="1">
    42.6 +  <Class Name="OxyPlot.Reporting.TableOfContents" Collapsed="true">
    42.7 +    <Position X="7.25" Y="12" Width="1.5" />
    42.8 +    <InheritanceLine Type="OxyPlot.Reporting.ItemsTable" FixedToPoint="true">
    42.9 +      <Path>
   42.10 +        <Point X="6.75" Y="11.691" />
   42.11 +        <Point X="6.75" Y="12.312" />
   42.12 +        <Point X="7.25" Y="12.312" />
   42.13 +      </Path>
   42.14 +    </InheritanceLine>
   42.15 +    <TypeIdentifier>
   42.16 +      <HashCode>AAQAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAABgQAA=</HashCode>
   42.17 +      <FileName>Reporting\Report\TableOfContents.cs</FileName>
   42.18 +    </TypeIdentifier>
   42.19 +  </Class>
   42.20 +  <Class Name="OxyPlot.Reporting.DrawingFigure" Collapsed="true">
   42.21 +    <Position X="5.75" Y="8.5" Width="1.5" />
   42.22 +    <TypeIdentifier>
   42.23 +      <HashCode>AAAAAAAAAgAAAAAAAAAAAEAAAAgAAAAAAAAAAAAAAAA=</HashCode>
   42.24 +      <FileName>Reporting\Report\DrawingFigure.cs</FileName>
   42.25 +    </TypeIdentifier>
   42.26 +  </Class>
   42.27 +  <Class Name="OxyPlot.Reporting.Equation" Collapsed="true">
   42.28 +    <Position X="4.75" Y="5.75" Width="1.5" />
   42.29 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
   42.30 +      <Path>
   42.31 +        <Point X="3.25" Y="2.312" />
   42.32 +        <Point X="3.25" Y="6.062" />
   42.33 +        <Point X="4.75" Y="6.062" />
   42.34 +      </Path>
   42.35 +    </InheritanceLine>
   42.36 +    <TypeIdentifier>
   42.37 +      <HashCode>AAAAAAAAAgAAAAAAAAAAAEAAAAAAAAAACAAAAAAAAAA=</HashCode>
   42.38 +      <FileName>Reporting\Report\Equation.cs</FileName>
   42.39 +    </TypeIdentifier>
   42.40 +  </Class>
   42.41 +  <Class Name="OxyPlot.Reporting.Figure" Collapsed="true">
   42.42 +    <Position X="4.75" Y="7" Width="1.5" />
   42.43 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
   42.44 +      <Path>
   42.45 +        <Point X="3.25" Y="2.312" />
   42.46 +        <Point X="3.25" Y="7.312" />
   42.47 +        <Point X="4.75" Y="7.312" />
   42.48 +      </Path>
   42.49 +    </InheritanceLine>
   42.50 +    <TypeIdentifier>
   42.51 +      <HashCode>AAAAAAEgAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
   42.52 +      <FileName>Reporting\Report\Figure.cs</FileName>
   42.53 +    </TypeIdentifier>
   42.54 +  </Class>
   42.55 +  <Class Name="OxyPlot.Reporting.Header" Collapsed="true">
   42.56 +    <Position X="4.75" Y="3.75" Width="1.5" />
   42.57 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
   42.58 +      <Path>
   42.59 +        <Point X="3.25" Y="2.312" />
   42.60 +        <Point X="3.25" Y="4.062" />
   42.61 +        <Point X="4.75" Y="4.062" />
   42.62 +      </Path>
   42.63 +    </InheritanceLine>
   42.64 +    <TypeIdentifier>
   42.65 +      <HashCode>AAAAAAAAAAAAAAAEAAAAAEAAAAAAAAABAgAACAAAAAA=</HashCode>
   42.66 +      <FileName>Reporting\Report\Header.cs</FileName>
   42.67 +    </TypeIdentifier>
   42.68 +  </Class>
   42.69 +  <Class Name="OxyPlot.Reporting.Image" Collapsed="true">
   42.70 +    <Position X="4" Y="8.5" Width="1.5" />
   42.71 +    <TypeIdentifier>
   42.72 +      <HashCode>AAAAAAAAAgAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA=</HashCode>
   42.73 +      <FileName>Reporting\Report\Image.cs</FileName>
   42.74 +    </TypeIdentifier>
   42.75 +  </Class>
   42.76 +  <Class Name="OxyPlot.Reporting.Paragraph" Collapsed="true">
   42.77 +    <Position X="4.75" Y="4.75" Width="1.5" />
   42.78 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
   42.79 +      <Path>
   42.80 +        <Point X="3.25" Y="2.312" />
   42.81 +        <Point X="3.25" Y="5.062" />
   42.82 +        <Point X="4.75" Y="5.062" />
   42.83 +      </Path>
   42.84 +    </InheritanceLine>
   42.85 +    <TypeIdentifier>
   42.86 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAACAAAAAA=</HashCode>
   42.87 +      <FileName>Reporting\Report\Paragraph.cs</FileName>
   42.88 +    </TypeIdentifier>
   42.89 +  </Class>
   42.90 +  <Class Name="OxyPlot.Reporting.PlotFigure" Collapsed="true">
   42.91 +    <Position X="7.5" Y="8.5" Width="1.5" />
   42.92 +    <TypeIdentifier>
   42.93 +      <HashCode>AAAAAAAABAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAQAA=</HashCode>
   42.94 +      <FileName>Reporting\Report\PlotFigure.cs</FileName>
   42.95 +    </TypeIdentifier>
   42.96 +  </Class>
   42.97 +  <Class Name="OxyPlot.Reporting.PropertyTable" Collapsed="true">
   42.98 +    <Position X="7.25" Y="13" Width="1.5" />
   42.99 +    <InheritanceLine Type="OxyPlot.Reporting.ItemsTable" FixedToPoint="true">
  42.100 +      <Path>
  42.101 +        <Point X="6.75" Y="11.691" />
  42.102 +        <Point X="6.75" Y="13.312" />
  42.103 +        <Point X="7.25" Y="13.312" />
  42.104 +      </Path>
  42.105 +    </InheritanceLine>
  42.106 +    <TypeIdentifier>
  42.107 +      <HashCode>AICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
  42.108 +      <FileName>Reporting\Report\PropertyTable.cs</FileName>
  42.109 +    </TypeIdentifier>
  42.110 +  </Class>
  42.111 +  <Class Name="OxyPlot.Reporting.Report" Collapsed="true">
  42.112 +    <Position X="4.75" Y="1.75" Width="1.5" />
  42.113 +    <TypeIdentifier>
  42.114 +      <HashCode>AAAAAAAAAAAAAEAAgAAAAEAAAAAAAAAAAAAAAAEAAAA=</HashCode>
  42.115 +      <FileName>Reporting\Report\Report.cs</FileName>
  42.116 +    </TypeIdentifier>
  42.117 +  </Class>
  42.118 +  <Class Name="OxyPlot.Reporting.ReportItem" Collapsed="true">
  42.119 +    <Position X="2.5" Y="1.75" Width="1.5" />
  42.120 +    <TypeIdentifier>
  42.121 +      <HashCode>AAcGAAAAAACCAAAAAAAEAEAAAAAAAAAAAAAAAAELCAA=</HashCode>
  42.122 +      <FileName>Reporting\Report\ReportItem.cs</FileName>
  42.123 +    </TypeIdentifier>
  42.124 +  </Class>
  42.125 +  <Class Name="OxyPlot.Reporting.ReportSection" Collapsed="true">
  42.126 +    <Position X="4.75" Y="2.75" Width="1.5" />
  42.127 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
  42.128 +      <Path>
  42.129 +        <Point X="3.25" Y="2.312" />
  42.130 +        <Point X="3.25" Y="3.062" />
  42.131 +        <Point X="4.75" Y="3.062" />
  42.132 +      </Path>
  42.133 +    </InheritanceLine>
  42.134 +    <TypeIdentifier>
  42.135 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
  42.136 +      <FileName>Reporting\Report\ReportSection.cs</FileName>
  42.137 +    </TypeIdentifier>
  42.138 +  </Class>
  42.139 +  <Class Name="OxyPlot.Reporting.Table" Collapsed="true">
  42.140 +    <Position X="4.75" Y="10" Width="1.5" />
  42.141 +    <InheritanceLine Type="OxyPlot.Reporting.ReportItem" FixedToPoint="true">
  42.142 +      <Path>
  42.143 +        <Point X="3.25" Y="2.312" />
  42.144 +        <Point X="3.25" Y="10.312" />
  42.145 +        <Point X="4.75" Y="10.312" />
  42.146 +      </Path>
  42.147 +    </InheritanceLine>
  42.148 +    <TypeIdentifier>
  42.149 +      <HashCode>AAQAAAAgAAAAAEAgAAAAAEBAAAAAAAEACAAAAAgAAAA=</HashCode>
  42.150 +      <FileName>Reporting\Report\Table.cs</FileName>
  42.151 +    </TypeIdentifier>
  42.152 +  </Class>
  42.153 +  <Class Name="OxyPlot.Reporting.HtmlReportWriter" Collapsed="true" BaseTypeListCollapsed="true">
  42.154 +    <Position X="7.75" Y="2.75" Width="1.5" />
  42.155 +    <TypeIdentifier>
  42.156 +      <HashCode>ACAAgAAAAAAgAIQAAAAQAAAAAAoUAABAIEIkAAigAAA=</HashCode>
  42.157 +      <FileName>Reporting\ReportWriters\HtmlReportWriter.cs</FileName>
  42.158 +    </TypeIdentifier>
  42.159 +    <Lollipop Position="0.2" />
  42.160 +  </Class>
  42.161 +  <Class Name="OxyPlot.Reporting.LatexReportWriter" Collapsed="true" BaseTypeListCollapsed="true">
  42.162 +    <Position X="11.25" Y="2.75" Width="1.5" />
  42.163 +    <TypeIdentifier>
  42.164 +      <HashCode>ACABgAAAACAsAAQABAAAAAQAAAAAIAAAAEAkAAAiAAA=</HashCode>
  42.165 +      <FileName>Reporting\ReportWriters\LatexReportWriter.cs</FileName>
  42.166 +    </TypeIdentifier>
  42.167 +    <Lollipop Position="0.2" />
  42.168 +  </Class>
  42.169 +  <Class Name="OxyPlot.Reporting.TextReportWriter" Collapsed="true" BaseTypeListCollapsed="true">
  42.170 +    <Position X="9.5" Y="2.75" Width="1.5" />
  42.171 +    <TypeIdentifier>
  42.172 +      <HashCode>ICAAgABAAAAgAAQIAAAACIAEAAAAAAAAAEAkAAAgAAA=</HashCode>
  42.173 +      <FileName>Reporting\ReportWriters\TextReportWriter.cs</FileName>
  42.174 +    </TypeIdentifier>
  42.175 +    <Lollipop Position="0.2" />
  42.176 +  </Class>
  42.177 +  <Class Name="OxyPlot.Reporting.ItemsTable" Collapsed="true">
  42.178 +    <Position X="6" Y="11" Width="1.5" />
  42.179 +    <InheritanceLine Type="OxyPlot.Reporting.Table" FixedToPoint="true">
  42.180 +      <Path>
  42.181 +        <Point X="5.5" Y="10.691" />
  42.182 +        <Point X="5.5" Y="11.312" />
  42.183 +        <Point X="6" Y="11.312" />
  42.184 +      </Path>
  42.185 +    </InheritanceLine>
  42.186 +    <TypeIdentifier>
  42.187 +      <HashCode>AAAAAgAAIAAACAAAACgIAEAAAAAAAAAAAAAAAAhAgAA=</HashCode>
  42.188 +      <FileName>Reporting\Report\ItemsTable.cs</FileName>
  42.189 +    </TypeIdentifier>
  42.190 +  </Class>
  42.191 +  <Class Name="OxyPlot.Reporting.WikiReportWriter" Collapsed="true">
  42.192 +    <Position X="13" Y="2.75" Width="1.5" />
  42.193 +    <TypeIdentifier>
  42.194 +      <HashCode>ICAAkABAAAAgAAQIAAAACIAEAAAAAACEAEAkAAAgAAA=</HashCode>
  42.195 +      <FileName>Reporting\ReportWriters\WikiReportWriter.cs</FileName>
  42.196 +    </TypeIdentifier>
  42.197 +    <Lollipop Position="0.2" />
  42.198 +  </Class>
  42.199 +  <Interface Name="OxyPlot.Reporting.IReportWriter" Collapsed="true">
  42.200 +    <Position X="9.5" Y="1.75" Width="1.5" />
  42.201 +    <TypeIdentifier>
  42.202 +      <HashCode>ACAAgAAAAAAgAAQAAAAAAAAAAAAAAAAAAEAkAAAgAAA=</HashCode>
  42.203 +      <FileName>Reporting\ReportWriters\IReportWriter.cs</FileName>
  42.204 +    </TypeIdentifier>
  42.205 +  </Interface>
  42.206 +  <Font Name="Segoe UI" Size="9" />
  42.207 +</ClassDiagram>
  42.208 \ No newline at end of file
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/External/OxyPlot/OxyPlot/ClassDiagrams/Series.cd	Sat Jun 08 16:53:22 2013 +0000
    43.3 @@ -0,0 +1,161 @@
    43.4 +<?xml version="1.0" encoding="utf-8"?>
    43.5 +<ClassDiagram MajorVersion="1" MinorVersion="1">
    43.6 +  <Class Name="OxyPlot.LineSeries" Collapsed="true">
    43.7 +    <Position X="6.75" Y="5" Width="1.5" />
    43.8 +    <TypeIdentifier>
    43.9 +      <HashCode>AAQCAAEIAiAAAGCAABBAAAAhRCAMEAAAADAAggAKIgA=</HashCode>
   43.10 +      <FileName>Series\LineSeries.cs</FileName>
   43.11 +    </TypeIdentifier>
   43.12 +  </Class>
   43.13 +  <Class Name="OxyPlot.DataPointSeries" Collapsed="true">
   43.14 +    <Position X="6.75" Y="3.75" Width="1.5" />
   43.15 +    <TypeIdentifier>
   43.16 +      <HashCode>IAAAAAyAEAABgAAAACACAAAABAAEAAAAAAAAAgAAAAA=</HashCode>
   43.17 +      <FileName>Series\DataPointSeries.cs</FileName>
   43.18 +    </TypeIdentifier>
   43.19 +  </Class>
   43.20 +  <Class Name="OxyPlot.AreaSeries" Collapsed="true">
   43.21 +    <Position X="8.75" Y="6.25" Width="1.5" />
   43.22 +    <TypeIdentifier>
   43.23 +      <HashCode>AgAAAAEAEAAAAIAAAAAACAAAAAAECAAAABMAAgIAAAA=</HashCode>
   43.24 +      <FileName>Series\AreaSeries.cs</FileName>
   43.25 +    </TypeIdentifier>
   43.26 +  </Class>
   43.27 +  <Class Name="OxyPlot.FunctionSeries" Collapsed="true">
   43.28 +    <Position X="7" Y="6.25" Width="1.5" />
   43.29 +    <TypeIdentifier>
   43.30 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
   43.31 +      <FileName>Series\FunctionSeries.cs</FileName>
   43.32 +    </TypeIdentifier>
   43.33 +  </Class>
   43.34 +  <Class Name="OxyPlot.BarSeries" Collapsed="true">
   43.35 +    <Position X="0.5" Y="7.25" Width="1.5" />
   43.36 +    <TypeIdentifier>
   43.37 +      <HashCode>CAAAAAgAIAQAAAAAAAAAAAAAAIAAAABAAAAAEAAAAAA=</HashCode>
   43.38 +      <FileName>Series\BarSeries\BarSeries.cs</FileName>
   43.39 +    </TypeIdentifier>
   43.40 +  </Class>
   43.41 +  <Class Name="OxyPlot.XYAxisSeries" Collapsed="true">
   43.42 +    <Position X="5.5" Y="2.5" Width="1.5" />
   43.43 +    <TypeIdentifier>
   43.44 +      <HashCode>sAAQAAE1WAAAAAAAAEAAQAQAAAAEAAAAABAUACACEAA=</HashCode>
   43.45 +      <FileName>Series\XYAxisSeries.cs</FileName>
   43.46 +    </TypeIdentifier>
   43.47 +  </Class>
   43.48 +  <Class Name="OxyPlot.CandleStickSeries" Collapsed="true">
   43.49 +    <Position X="10.5" Y="5" Width="1.5" />
   43.50 +    <TypeIdentifier>
   43.51 +      <HashCode>AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAABAA=</HashCode>
   43.52 +      <FileName>Series\CandleStickSeries.cs</FileName>
   43.53 +    </TypeIdentifier>
   43.54 +  </Class>
   43.55 +  <Class Name="OxyPlot.HighLowSeries" Collapsed="true">
   43.56 +    <Position X="10.5" Y="3.75" Width="1.5" />
   43.57 +    <TypeIdentifier>
   43.58 +      <HashCode>AAAAAAkBECABCAAAABgAAAQABAQEAAABAHAAggAKAAA=</HashCode>
   43.59 +      <FileName>Series\HighLowSeries.cs</FileName>
   43.60 +    </TypeIdentifier>
   43.61 +  </Class>
   43.62 +  <Class Name="OxyPlot.ItemsSeries" Collapsed="true">
   43.63 +    <Position X="5.5" Y="1.5" Width="1.5" />
   43.64 +    <TypeIdentifier>
   43.65 +      <HashCode>AAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAIIAAAA=</HashCode>
   43.66 +      <FileName>Series\ItemsSeries.cs</FileName>
   43.67 +    </TypeIdentifier>
   43.68 +  </Class>
   43.69 +  <Class Name="OxyPlot.PieSeries" Collapsed="true">
   43.70 +    <Position X="7.5" Y="1.5" Width="1.5" />
   43.71 +    <TypeIdentifier>
   43.72 +      <HashCode>AQAQAAEAWGAYACAIAAAAAAAgAAgEICJAgpQFAoCCAAI=</HashCode>
   43.73 +      <FileName>Series\PieSeries.cs</FileName>
   43.74 +    </TypeIdentifier>
   43.75 +  </Class>
   43.76 +  <Class Name="OxyPlot.ScatterSeries" Collapsed="true">
   43.77 +    <Position X="8.75" Y="5" Width="1.5" />
   43.78 +    <TypeIdentifier>
   43.79 +      <HashCode>AARQAAEIEAAAAEgQAAAIAAAgACBEQAIEABAwAgQDAgA=</HashCode>
   43.80 +      <FileName>Series\ScatterSeries.cs</FileName>
   43.81 +    </TypeIdentifier>
   43.82 +  </Class>
   43.83 +  <Class Name="OxyPlot.StairStepSeries" Collapsed="true">
   43.84 +    <Position X="5.25" Y="6.25" Width="1.5" />
   43.85 +    <TypeIdentifier>
   43.86 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAAAA=</HashCode>
   43.87 +      <FileName>Series\StairStepSeries.cs</FileName>
   43.88 +    </TypeIdentifier>
   43.89 +  </Class>
   43.90 +  <Class Name="OxyPlot.StemSeries" Collapsed="true">
   43.91 +    <Position X="10.5" Y="6.25" Width="1.5" />
   43.92 +    <TypeIdentifier>
   43.93 +      <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAgAAQAA=</HashCode>
   43.94 +      <FileName>Series\StemSeries.cs</FileName>
   43.95 +    </TypeIdentifier>
   43.96 +  </Class>
   43.97 +  <Class Name="OxyPlot.Series" Collapsed="true">
   43.98 +    <Position X="5.5" Y="0.5" Width="1.5" />
   43.99 +    <TypeIdentifier>
  43.100 +      <HashCode>AAAQAAEAWABAEEAAAAAAAAAAAAAEAAAAABAkBgISAAA=</HashCode>
  43.101 +      <FileName>Series\Series.cs</FileName>
  43.102 +    </TypeIdentifier>
  43.103 +    <Lollipop Position="0.2" />
  43.104 +  </Class>
  43.105 +  <Class Name="OxyPlot.BarSeriesBase" Collapsed="true">
  43.106 +    <Position X="1" Y="5" Width="1.5" />
  43.107 +    <TypeIdentifier>
  43.108 +      <HashCode>BYQAgIEAKCSAACCQAAAAAAABAAgEIBBAAhAUEgoCAAE=</HashCode>
  43.109 +      <FileName>Series\BarSeries\BarSeriesBase.cs</FileName>
  43.110 +    </TypeIdentifier>
  43.111 +    <Lollipop Position="0.2" />
  43.112 +  </Class>
  43.113 +  <Class Name="OxyPlot.ColumnSeries" Collapsed="true">
  43.114 +    <Position X="2.25" Y="7.25" Width="1.5" />
  43.115 +    <TypeIdentifier>
  43.116 +      <HashCode>AAAAAAgAIAQAAAAAAEAAAAAAAIAAAABAAAAAEAAAAAA=</HashCode>
  43.117 +      <FileName>Series\BarSeries\ColumnSeries.cs</FileName>
  43.118 +    </TypeIdentifier>
  43.119 +  </Class>
  43.120 +  <Class Name="OxyPlot.IntervalBarSeries" Collapsed="true">
  43.121 +    <Position X="2.75" Y="5" Width="1.5" />
  43.122 +    <TypeIdentifier>
  43.123 +      <HashCode>DQQAgAkBGCSACECAAAAAAAABAIgEIgAAABAUEgoCAAE=</HashCode>
  43.124 +      <FileName>Series\BarSeries\IntervalBarSeries.cs</FileName>
  43.125 +    </TypeIdentifier>
  43.126 +    <Lollipop Position="0.2" />
  43.127 +  </Class>
  43.128 +  <Class Name="OxyPlot.RectangleBarSeries" Collapsed="true">
  43.129 +    <Position X="4.5" Y="3.75" Width="1.75" />
  43.130 +    <TypeIdentifier>
  43.131 +      <HashCode>AAAAgAEAECCACACAAAAAAAAAAAgEAAAAABAQEggCAAE=</HashCode>
  43.132 +      <FileName>Series\BarSeries\RectangleBarSeries.cs</FileName>
  43.133 +    </TypeIdentifier>
  43.134 +  </Class>
  43.135 +  <Class Name="OxyPlot.TornadoBarSeries" Collapsed="true">
  43.136 +    <Position X="4.5" Y="5" Width="1.5" />
  43.137 +    <TypeIdentifier>
  43.138 +      <HashCode>DYQAAAsBGCUICEAABQAgAAAFAKgEAoAAABA0EgICAAE=</HashCode>
  43.139 +      <FileName>Series\BarSeries\TornadoBarSeries.cs</FileName>
  43.140 +    </TypeIdentifier>
  43.141 +  </Class>
  43.142 +  <Class Name="OxyPlot.BarSeriesBase&lt;T&gt;" Collapsed="true">
  43.143 +    <Position X="1" Y="6" Width="1.5" />
  43.144 +    <TypeIdentifier>
  43.145 +      <HashCode>AAAAAAAAEAAACEAAAAAAAAAAAAAAAgAAAAAAAAAAAAA=</HashCode>
  43.146 +      <FileName>Series\BarSeries\BarSeriesBase{T}.cs</FileName>
  43.147 +    </TypeIdentifier>
  43.148 +  </Class>
  43.149 +  <Class Name="OxyPlot.CategorizedSeries" Collapsed="true">
  43.150 +    <Position X="1" Y="3.75" Width="1.5" />
  43.151 +    <TypeIdentifier>
  43.152 +      <HashCode>AAAAAAgAAAAAAAAAAAAAAAAAAIAAAgAAAAAAEAAAAAA=</HashCode>
  43.153 +      <FileName>Series\BarSeries\CategorizedSeries.cs</FileName>
  43.154 +    </TypeIdentifier>
  43.155 +  </Class>
  43.156 +  <Class Name="OxyPlot.ErrorColumnSeries" Collapsed="true">
  43.157 +    <Position X="2" Y="8.25" Width="2" />
  43.158 +    <TypeIdentifier>
  43.159 +      <HashCode>AAAIAAAAAEAAAAAAAAAAAAAAAAAEABAAAAAAAAAAAAA=</HashCode>
  43.160 +      <FileName>Series\BarSeries\ErrorColumnSeries.cs</FileName>
  43.161 +    </TypeIdentifier>
  43.162 +  </Class>
  43.163 +  <Font Name="Segoe UI" Size="9" />
  43.164 +</ClassDiagram>
  43.165 \ No newline at end of file
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ArrayHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    44.3 @@ -0,0 +1,124 @@
    44.4 +// --------------------------------------------------------------------------------------------------------------------
    44.5 +// <copyright file="ArrayHelper.cs" company="OxyPlot">
    44.6 +//   The MIT License (MIT)
    44.7 +//
    44.8 +//   Copyright (c) 2012 Oystein Bjorke
    44.9 +//
   44.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   44.11 +//   copy of this software and associated documentation files (the
   44.12 +//   "Software"), to deal in the Software without restriction, including
   44.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   44.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   44.15 +//   permit persons to whom the Software is furnished to do so, subject to
   44.16 +//   the following conditions:
   44.17 +//
   44.18 +//   The above copyright notice and this permission notice shall be included
   44.19 +//   in all copies or substantial portions of the Software.
   44.20 +//
   44.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   44.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   44.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   44.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   44.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   44.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   44.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   44.28 +// </copyright>
   44.29 +// <summary>
   44.30 +//   Array helper methods.
   44.31 +// </summary>
   44.32 +// --------------------------------------------------------------------------------------------------------------------
   44.33 +namespace OxyPlot
   44.34 +{
   44.35 +    using System;
   44.36 +
   44.37 +    /// <summary>
   44.38 +    /// Provides utility methods for vector generation.
   44.39 +    /// </summary>
   44.40 +    public static class ArrayHelper
   44.41 +    {
   44.42 +        /// <summary>
   44.43 +        /// Creates a vector.
   44.44 +        /// </summary>
   44.45 +        /// <param name="x0">
   44.46 +        /// The first value.
   44.47 +        /// </param>
   44.48 +        /// <param name="x1">
   44.49 +        /// The last value.
   44.50 +        /// </param>
   44.51 +        /// <param name="n">
   44.52 +        /// The number of steps.
   44.53 +        /// </param>
   44.54 +        /// <returns>
   44.55 +        /// A vector.
   44.56 +        /// </returns>
   44.57 +        public static double[] CreateVector(double x0, double x1, int n)
   44.58 +        {
   44.59 +            var result = new double[n];
   44.60 +            for (int i = 0; i < n; i++)
   44.61 +            {
   44.62 +                result[i] = (x0 + ((x1 - x0) * i / (n - 1))).RemoveNoise();
   44.63 +            }
   44.64 +
   44.65 +            return result;
   44.66 +        }
   44.67 +
   44.68 +        /// <summary>
   44.69 +        /// Creates a vector.
   44.70 +        /// </summary>
   44.71 +        /// <param name="x0">
   44.72 +        /// The first value.
   44.73 +        /// </param>
   44.74 +        /// <param name="x1">
   44.75 +        /// The last value.
   44.76 +        /// </param>
   44.77 +        /// <param name="dx">
   44.78 +        /// The step size.
   44.79 +        /// </param>
   44.80 +        /// <returns>
   44.81 +        /// A vector.
   44.82 +        /// </returns>
   44.83 +        public static double[] CreateVector(double x0, double x1, double dx)
   44.84 +        {
   44.85 +            var n = (int)Math.Round((x1 - x0) / dx);
   44.86 +            var result = new double[n + 1];
   44.87 +            for (int i = 0; i <= n; i++)
   44.88 +            {
   44.89 +                result[i] = (x0 + (i * dx)).RemoveNoise();
   44.90 +            }
   44.91 +
   44.92 +            return result;
   44.93 +        }
   44.94 +
   44.95 +        /// <summary>
   44.96 +        /// Evaluates the specified function.
   44.97 +        /// </summary>
   44.98 +        /// <param name="f">
   44.99 +        /// The function.
  44.100 +        /// </param>
  44.101 +        /// <param name="x">
  44.102 +        /// The x values.
  44.103 +        /// </param>
  44.104 +        /// <param name="y">
  44.105 +        /// The y values.
  44.106 +        /// </param>
  44.107 +        /// <returns>
  44.108 +        /// Array of evaluations. The value of f(x_i,y_j) will be placed at index [i, j].
  44.109 +        /// </returns>
  44.110 +        public static double[,] Evaluate(Func<double, double, double> f, double[] x, double[] y)
  44.111 +        {
  44.112 +            int m = x.Length;
  44.113 +            int n = y.Length;
  44.114 +            var result = new double[m, n];
  44.115 +            for (int i = 0; i < m; i++)
  44.116 +            {
  44.117 +                for (int j = 0; j < n; j++)
  44.118 +                {
  44.119 +                    result[i, j] = f(x[i], y[j]);
  44.120 +                }
  44.121 +            }
  44.122 +
  44.123 +            return result;
  44.124 +        }
  44.125 +
  44.126 +    }
  44.127 +}
  44.128 \ No newline at end of file
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CanonicalSplineHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    45.3 @@ -0,0 +1,252 @@
    45.4 +// --------------------------------------------------------------------------------------------------------------------
    45.5 +// <copyright file="CanonicalSplineHelper.cs" company="OxyPlot">
    45.6 +//   The MIT License (MIT)
    45.7 +//
    45.8 +//   Copyright (c) 2012 Oystein Bjorke
    45.9 +//
   45.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   45.11 +//   copy of this software and associated documentation files (the
   45.12 +//   "Software"), to deal in the Software without restriction, including
   45.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   45.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   45.15 +//   permit persons to whom the Software is furnished to do so, subject to
   45.16 +//   the following conditions:
   45.17 +//
   45.18 +//   The above copyright notice and this permission notice shall be included
   45.19 +//   in all copies or substantial portions of the Software.
   45.20 +//
   45.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   45.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   45.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   45.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   45.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   45.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   45.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   45.28 +// </copyright>
   45.29 +// <summary>
   45.30 +//   Interpolates a list of points using a canonical spline.
   45.31 +// </summary>
   45.32 +// --------------------------------------------------------------------------------------------------------------------
   45.33 +namespace OxyPlot
   45.34 +{
   45.35 +    using System;
   45.36 +    using System.Collections.Generic;
   45.37 +    using System.Linq;
   45.38 +
   45.39 +    /// <summary>
   45.40 +    /// Provides functionality to interpolate a list of points by a canonical spline.
   45.41 +    /// </summary>
   45.42 +    internal static class CanonicalSplineHelper
   45.43 +    {
   45.44 +        // CanonicalSplineHelper.cs (c) 2009 by Charles Petzold (WPF and Silverlight)
   45.45 +        // www.charlespetzold.com/blog/2009/01/Canonical-Splines-in-WPF-and-Silverlight.html
   45.46 +        /// <summary>
   45.47 +        /// Creates a spline of data points.
   45.48 +        /// </summary>
   45.49 +        /// <param name="points">
   45.50 +        /// The points.
   45.51 +        /// </param>
   45.52 +        /// <param name="tension">
   45.53 +        /// The tension.
   45.54 +        /// </param>
   45.55 +        /// <param name="tensions">
   45.56 +        /// The tensions.
   45.57 +        /// </param>
   45.58 +        /// <param name="isClosed">
   45.59 +        /// True if the spline is closed.
   45.60 +        /// </param>
   45.61 +        /// <param name="tolerance">
   45.62 +        /// The tolerance.
   45.63 +        /// </param>
   45.64 +        /// <returns>
   45.65 +        /// A list of data points.
   45.66 +        /// </returns>
   45.67 +        internal static List<IDataPoint> CreateSpline(
   45.68 +            IList<IDataPoint> points, double tension, IList<double> tensions, bool isClosed, double tolerance)
   45.69 +        {
   45.70 +            var screenPoints = points.Select(p => new ScreenPoint(p.X, p.Y)).ToList();
   45.71 +            var interpolatedScreenPoints = CreateSpline(screenPoints, tension, tensions, isClosed, tolerance);
   45.72 +            var interpolatedDataPoints = new List<IDataPoint>(interpolatedScreenPoints.Count);
   45.73 +
   45.74 +            foreach (var s in interpolatedScreenPoints)
   45.75 +            {
   45.76 +                interpolatedDataPoints.Add(new DataPoint(s.X, s.Y));
   45.77 +            }
   45.78 +
   45.79 +            return interpolatedDataPoints;
   45.80 +        }
   45.81 +
   45.82 +        /// <summary>
   45.83 +        /// Creates a spline of screen points.
   45.84 +        /// </summary>
   45.85 +        /// <param name="points">
   45.86 +        /// The points.
   45.87 +        /// </param>
   45.88 +        /// <param name="tension">
   45.89 +        /// The tension.
   45.90 +        /// </param>
   45.91 +        /// <param name="tensions">
   45.92 +        /// The tensions.
   45.93 +        /// </param>
   45.94 +        /// <param name="isClosed">
   45.95 +        /// True if the spline is closed.
   45.96 +        /// </param>
   45.97 +        /// <param name="tolerance">
   45.98 +        /// The tolerance.
   45.99 +        /// </param>
  45.100 +        /// <returns>
  45.101 +        /// A list of screen points.
  45.102 +        /// </returns>
  45.103 +        internal static List<ScreenPoint> CreateSpline(
  45.104 +            IList<ScreenPoint> points, double tension, IList<double> tensions, bool isClosed, double tolerance)
  45.105 +        {
  45.106 +            var result = new List<ScreenPoint>();
  45.107 +            if (points == null)
  45.108 +            {
  45.109 +                return result;
  45.110 +            }
  45.111 +
  45.112 +            int n = points.Count;
  45.113 +            if (n < 1)
  45.114 +            {
  45.115 +                return result;
  45.116 +            }
  45.117 +
  45.118 +            if (n < 2)
  45.119 +            {
  45.120 +                result.AddRange(points);
  45.121 +                return result;
  45.122 +            }
  45.123 +
  45.124 +            if (n == 2)
  45.125 +            {
  45.126 +                if (!isClosed)
  45.127 +                {
  45.128 +                    Segment(result, points[0], points[0], points[1], points[1], tension, tension, tolerance);
  45.129 +                }
  45.130 +                else
  45.131 +                {
  45.132 +                    Segment(result, points[1], points[0], points[1], points[0], tension, tension, tolerance);
  45.133 +                    Segment(result, points[0], points[1], points[0], points[1], tension, tension, tolerance);
  45.134 +                }
  45.135 +            }
  45.136 +            else
  45.137 +            {
  45.138 +                bool useTensionCollection = tensions != null && tensions.Count > 0;
  45.139 +
  45.140 +                for (int i = 0; i < n; i++)
  45.141 +                {
  45.142 +                    double t1 = useTensionCollection ? tensions[i % tensions.Count] : tension;
  45.143 +                    double t2 = useTensionCollection ? tensions[(i + 1) % tensions.Count] : tension;
  45.144 +
  45.145 +                    if (i == 0)
  45.146 +                    {
  45.147 +                        Segment(
  45.148 +                            result,
  45.149 +                            isClosed ? points[n - 1] : points[0],
  45.150 +                            points[0],
  45.151 +                            points[1],
  45.152 +                            points[2],
  45.153 +                            t1,
  45.154 +                            t2,
  45.155 +                            tolerance);
  45.156 +                    }
  45.157 +                    else if (i == n - 2)
  45.158 +                    {
  45.159 +                        Segment(
  45.160 +                            result,
  45.161 +                            points[i - 1],
  45.162 +                            points[i],
  45.163 +                            points[i + 1],
  45.164 +                            isClosed ? points[0] : points[i + 1],
  45.165 +                            t1,
  45.166 +                            t2,
  45.167 +                            tolerance);
  45.168 +                    }
  45.169 +                    else if (i == n - 1)
  45.170 +                    {
  45.171 +                        if (isClosed)
  45.172 +                        {
  45.173 +                            Segment(result, points[i - 1], points[i], points[0], points[1], t1, t2, tolerance);
  45.174 +                        }
  45.175 +                    }
  45.176 +                    else
  45.177 +                    {
  45.178 +                        Segment(result, points[i - 1], points[i], points[i + 1], points[i + 2], t1, t2, tolerance);
  45.179 +                    }
  45.180 +                }
  45.181 +            }
  45.182 +
  45.183 +            return result;
  45.184 +        }
  45.185 +
  45.186 +        /// <summary>
  45.187 +        /// The segment.
  45.188 +        /// </summary>
  45.189 +        /// <param name="points">
  45.190 +        /// The points.
  45.191 +        /// </param>
  45.192 +        /// <param name="pt0">
  45.193 +        /// The pt 0.
  45.194 +        /// </param>
  45.195 +        /// <param name="pt1">
  45.196 +        /// The pt 1.
  45.197 +        /// </param>
  45.198 +        /// <param name="pt2">
  45.199 +        /// The pt 2.
  45.200 +        /// </param>
  45.201 +        /// <param name="pt3">
  45.202 +        /// The pt 3.
  45.203 +        /// </param>
  45.204 +        /// <param name="t1">
  45.205 +        /// The t 1.
  45.206 +        /// </param>
  45.207 +        /// <param name="t2">
  45.208 +        /// The t 2.
  45.209 +        /// </param>
  45.210 +        /// <param name="tolerance">
  45.211 +        /// The tolerance.
  45.212 +        /// </param>
  45.213 +        private static void Segment(
  45.214 +            IList<ScreenPoint> points,
  45.215 +            ScreenPoint pt0,
  45.216 +            ScreenPoint pt1,
  45.217 +            ScreenPoint pt2,
  45.218 +            ScreenPoint pt3,
  45.219 +            double t1,
  45.220 +            double t2,
  45.221 +            double tolerance)
  45.222 +        {
  45.223 +            // See Petzold, "Programming Microsoft Windows with C#", pages 645-646 or
  45.224 +            // Petzold, "Programming Microsoft Windows with Microsoft Visual Basic .NET", pages 638-639
  45.225 +            // for derivation of the following formulas:
  45.226 +            double sx1 = t1 * (pt2.X - pt0.X);
  45.227 +            double sy1 = t1 * (pt2.Y - pt0.Y);
  45.228 +            double sx2 = t2 * (pt3.X - pt1.X);
  45.229 +            double sy2 = t2 * (pt3.Y - pt1.Y);
  45.230 +
  45.231 +            double ax = sx1 + sx2 + 2 * pt1.X - 2 * pt2.X;
  45.232 +            double ay = sy1 + sy2 + 2 * pt1.Y - 2 * pt2.Y;
  45.233 +            double bx = -2 * sx1 - sx2 - 3 * pt1.X + 3 * pt2.X;
  45.234 +            double by = -2 * sy1 - sy2 - 3 * pt1.Y + 3 * pt2.Y;
  45.235 +
  45.236 +            double cx = sx1;
  45.237 +            double cy = sy1;
  45.238 +            double dx = pt1.X;
  45.239 +            double dy = pt1.Y;
  45.240 +
  45.241 +            var num = (int)((Math.Abs(pt1.X - pt2.X) + Math.Abs(pt1.Y - pt2.Y)) / tolerance);
  45.242 +
  45.243 +            // Notice begins at 1 so excludes the first point (which is just pt1)
  45.244 +            for (int i = 1; i < num; i++)
  45.245 +            {
  45.246 +                double t = (double)i / (num - 1);
  45.247 +                var pt = new ScreenPoint(
  45.248 +                    ax * t * t * t + bx * t * t + cx * t + dx,
  45.249 +                    ay * t * t * t + by * t * t + cy * t + dy);
  45.250 +                points.Add(pt);
  45.251 +            }
  45.252 +        }
  45.253 +
  45.254 +    }
  45.255 +}
  45.256 \ No newline at end of file
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerationAttribute.cs	Sat Jun 08 16:53:22 2013 +0000
    46.3 @@ -0,0 +1,57 @@
    46.4 +// --------------------------------------------------------------------------------------------------------------------
    46.5 +// <copyright file="CodeGenerationAttribute.cs" company="OxyPlot">
    46.6 +//   The MIT License (MIT)
    46.7 +//
    46.8 +//   Copyright (c) 2012 Oystein Bjorke
    46.9 +//
   46.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   46.11 +//   copy of this software and associated documentation files (the
   46.12 +//   "Software"), to deal in the Software without restriction, including
   46.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   46.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   46.15 +//   permit persons to whom the Software is furnished to do so, subject to
   46.16 +//   the following conditions:
   46.17 +//
   46.18 +//   The above copyright notice and this permission notice shall be included
   46.19 +//   in all copies or substantial portions of the Software.
   46.20 +//
   46.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   46.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   46.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   46.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   46.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   46.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   46.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   46.28 +// </copyright>
   46.29 +// <summary>
   46.30 +//   Attribute that controls if code should be generated for the property.
   46.31 +// </summary>
   46.32 +// --------------------------------------------------------------------------------------------------------------------
   46.33 +namespace OxyPlot
   46.34 +{
   46.35 +    using System;
   46.36 +
   46.37 +    /// <summary>
   46.38 +    /// Specifies whether code should be generated for the property.
   46.39 +    /// </summary>
   46.40 +    [AttributeUsage(AttributeTargets.Property)]
   46.41 +    public class CodeGenerationAttribute : Attribute
   46.42 +    {
   46.43 +        /// <summary>
   46.44 +        /// Initializes a new instance of the <see cref="CodeGenerationAttribute"/> class.
   46.45 +        /// </summary>
   46.46 +        /// <param name="generateCode">
   46.47 +        /// The generate code.
   46.48 +        /// </param>
   46.49 +        public CodeGenerationAttribute(bool generateCode)
   46.50 +        {
   46.51 +            this.GenerateCode = generateCode;
   46.52 +        }
   46.53 +
   46.54 +        /// <summary>
   46.55 +        /// Gets or sets a value indicating whether GenerateCode.
   46.56 +        /// </summary>
   46.57 +        public bool GenerateCode { get; set; }
   46.58 +
   46.59 +    }
   46.60 +}
   46.61 \ No newline at end of file
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGenerator.cs	Sat Jun 08 16:53:22 2013 +0000
    47.3 @@ -0,0 +1,448 @@
    47.4 +// --------------------------------------------------------------------------------------------------------------------
    47.5 +// <copyright file="CodeGenerator.cs" company="OxyPlot">
    47.6 +//   The MIT License (MIT)
    47.7 +//
    47.8 +//   Copyright (c) 2012 Oystein Bjorke
    47.9 +//
   47.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   47.11 +//   copy of this software and associated documentation files (the
   47.12 +//   "Software"), to deal in the Software without restriction, including
   47.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   47.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   47.15 +//   permit persons to whom the Software is furnished to do so, subject to
   47.16 +//   the following conditions:
   47.17 +//
   47.18 +//   The above copyright notice and this permission notice shall be included
   47.19 +//   in all copies or substantial portions of the Software.
   47.20 +//
   47.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   47.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   47.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   47.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   47.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   47.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   47.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   47.28 +// </copyright>
   47.29 +// <summary>
   47.30 +//   Generates c# code for the specified PlotModel.
   47.31 +// </summary>
   47.32 +// --------------------------------------------------------------------------------------------------------------------
   47.33 +namespace OxyPlot
   47.34 +{
   47.35 +    using System;
   47.36 +    using System.Collections;
   47.37 +    using System.Collections.Generic;
   47.38 +    using System.Globalization;
   47.39 +    using System.Reflection;
   47.40 +    using System.Text;
   47.41 +    using System.Text.RegularExpressions;
   47.42 +
   47.43 +    /// <summary>
   47.44 +    /// Provides functionality to generate C# code for the specified <see cref="PlotModel"/>.
   47.45 +    /// </summary>
   47.46 +    /// <remarks>
   47.47 +    /// This is useful for creating examples or unit tests. Press Ctrl+Alt+C in a plot to copy code to the clipboard.
   47.48 +    /// Usage:
   47.49 +    /// var cg = new CodeGenerator(myPlotModel);
   47.50 +    /// Clipboard.SetText(cg.ToCode());
   47.51 +    /// </remarks>
   47.52 +    public class CodeGenerator
   47.53 +    {
   47.54 +        /// <summary>
   47.55 +        /// The sb.
   47.56 +        /// </summary>
   47.57 +        private readonly StringBuilder sb;
   47.58 +
   47.59 +        /// <summary>
   47.60 +        /// The variables.
   47.61 +        /// </summary>
   47.62 +        private readonly Dictionary<string, bool> variables;
   47.63 +
   47.64 +        /// <summary>
   47.65 +        /// The indent string.
   47.66 +        /// </summary>
   47.67 +        private string indentString;
   47.68 +
   47.69 +        /// <summary>
   47.70 +        /// The indents.
   47.71 +        /// </summary>
   47.72 +        private int indents;
   47.73 +
   47.74 +        /// <summary>
   47.75 +        /// Initializes a new instance of the <see cref="CodeGenerator"/> class.
   47.76 +        /// </summary>
   47.77 +        /// <param name="model">
   47.78 +        /// The model.
   47.79 +        /// </param>
   47.80 +        public CodeGenerator(PlotModel model)
   47.81 +        {
   47.82 +            this.variables = new Dictionary<string, bool>();
   47.83 +            this.sb = new StringBuilder();
   47.84 +            this.Indents = 8;
   47.85 +            var title = model.Title ?? "Untitled";
   47.86 +            this.AppendLine("[Example({0})]", title.ToCode());
   47.87 +            string methodName = this.MakeValidVariableName(title);
   47.88 +            this.AppendLine("public static PlotModel {0}()", methodName);
   47.89 +            this.AppendLine("{");
   47.90 +            this.Indents += 4;
   47.91 +            string modelName = this.Add(model);
   47.92 +            this.AddChildren(modelName, "Axes", model.Axes);
   47.93 +            this.AddChildren(modelName, "Series", model.Series);
   47.94 +            this.AddChildren(modelName, "Annotations", model.Annotations);
   47.95 +            this.AppendLine("return {0};", modelName);
   47.96 +            this.Indents -= 4;
   47.97 +            this.AppendLine("}");
   47.98 +        }
   47.99 +
  47.100 +        /// <summary>
  47.101 +        /// Gets or sets Indents.
  47.102 +        /// </summary>
  47.103 +        private int Indents
  47.104 +        {
  47.105 +            get
  47.106 +            {
  47.107 +                return this.indents;
  47.108 +            }
  47.109 +
  47.110 +            set
  47.111 +            {
  47.112 +                this.indents = value;
  47.113 +                this.indentString = new string(' ', value);
  47.114 +            }
  47.115 +        }
  47.116 +
  47.117 +        /// <summary>
  47.118 +        /// Formats the code.
  47.119 +        /// </summary>
  47.120 +        /// <param name="format">
  47.121 +        /// The format.
  47.122 +        /// </param>
  47.123 +        /// <param name="values">
  47.124 +        /// The values.
  47.125 +        /// </param>
  47.126 +        /// <returns>
  47.127 +        /// The format code.
  47.128 +        /// </returns>
  47.129 +        public static string FormatCode(string format, params object[] values)
  47.130 +        {
  47.131 +            var encodedValues = new object[values.Length];
  47.132 +            for (int i = 0; i < values.Length; i++)
  47.133 +            {
  47.134 +                encodedValues[i] = values[i].ToCode();
  47.135 +            }
  47.136 +
  47.137 +            return string.Format(format, encodedValues);
  47.138 +        }
  47.139 +
  47.140 +        /// <summary>
  47.141 +        /// Formats a constructor.
  47.142 +        /// </summary>
  47.143 +        /// <param name="type">
  47.144 +        /// The type.
  47.145 +        /// </param>
  47.146 +        /// <param name="format">
  47.147 +        /// The format of the constructor arguments.
  47.148 +        /// </param>
  47.149 +        /// <param name="values">
  47.150 +        /// The argument values.
  47.151 +        /// </param>
  47.152 +        /// <returns>
  47.153 +        /// The format constructor.
  47.154 +        /// </returns>
  47.155 +        public static string FormatConstructor(Type type, string format, params object[] values)
  47.156 +        {
  47.157 +            return string.Format("new {0}({1})", type.Name, FormatCode(format, values));
  47.158 +        }
  47.159 +
  47.160 +        /// <summary>
  47.161 +        /// Returns the c# code for this model.
  47.162 +        /// </summary>
  47.163 +        /// <returns>
  47.164 +        /// C# code.
  47.165 +        /// </returns>
  47.166 +        public string ToCode()
  47.167 +        {
  47.168 +            return this.sb.ToString();
  47.169 +        }
  47.170 +
  47.171 +        /// <summary>
  47.172 +        /// Adds the specified object to the generated code.
  47.173 +        /// </summary>
  47.174 +        /// <param name="obj">
  47.175 +        /// The object.
  47.176 +        /// </param>
  47.177 +        /// <returns>
  47.178 +        /// The variable name.
  47.179 +        /// </returns>
  47.180 +        private string Add(object obj)
  47.181 +        {
  47.182 +            Type type = obj.GetType();
  47.183 +            object defaultInstance = Activator.CreateInstance(type);
  47.184 +            string varName = this.GetNewVariableName(type);
  47.185 +            this.variables.Add(varName, true);
  47.186 +            this.AppendLine("var {0} = new {1}();", varName, type.Name);
  47.187 +            this.SetProperties(obj, varName, defaultInstance);
  47.188 +            return varName;
  47.189 +        }
  47.190 +
  47.191 +        /// <summary>
  47.192 +        /// Adds the children.
  47.193 +        /// </summary>
  47.194 +        /// <param name="name">
  47.195 +        /// The name.
  47.196 +        /// </param>
  47.197 +        /// <param name="collectionName">
  47.198 +        /// Name of the collection.
  47.199 +        /// </param>
  47.200 +        /// <param name="children">
  47.201 +        /// The children.
  47.202 +        /// </param>
  47.203 +        private void AddChildren(string name, string collectionName, IEnumerable children)
  47.204 +        {
  47.205 +            foreach (var child in children)
  47.206 +            {
  47.207 +                string childName = this.Add(child);
  47.208 +                this.AppendLine("{0}.{1}.Add({2});", name, collectionName, childName);
  47.209 +            }
  47.210 +        }
  47.211 +
  47.212 +        /// <summary>
  47.213 +        /// Adds the items.
  47.214 +        /// </summary>
  47.215 +        /// <param name="name">
  47.216 +        /// The name.
  47.217 +        /// </param>
  47.218 +        /// <param name="list">
  47.219 +        /// The list.
  47.220 +        /// </param>
  47.221 +        private void AddItems(string name, IList list)
  47.222 +        {
  47.223 +            foreach (var item in list)
  47.224 +            {
  47.225 +                var code = item.ToCode();
  47.226 +                if (code == null)
  47.227 +                {
  47.228 +                    continue;
  47.229 +                }
  47.230 +
  47.231 +                this.AppendLine("{0}.Add({1});", name, code);
  47.232 +            }
  47.233 +        }
  47.234 +
  47.235 +        /// <summary>
  47.236 +        /// Appends the line.
  47.237 +        /// </summary>
  47.238 +        /// <param name="format">
  47.239 +        /// The format string.
  47.240 +        /// </param>
  47.241 +        /// <param name="args">
  47.242 +        /// The args.
  47.243 +        /// </param>
  47.244 +        private void AppendLine(string format, params object[] args)
  47.245 +        {
  47.246 +            if (args.Length > 0)
  47.247 +            {
  47.248 +                this.sb.AppendLine(this.indentString + string.Format(CultureInfo.InvariantCulture, format, args));
  47.249 +            }
  47.250 +            else
  47.251 +            {
  47.252 +                this.sb.AppendLine(this.indentString + format);
  47.253 +            }
  47.254 +        }
  47.255 +
  47.256 +        /// <summary>
  47.257 +        /// Determines if the two specifed lists are equal.
  47.258 +        /// </summary>
  47.259 +        /// <param name="list1">
  47.260 +        /// The first list.
  47.261 +        /// </param>
  47.262 +        /// <param name="list2">
  47.263 +        /// The second list.
  47.264 +        /// </param>
  47.265 +        /// <returns>
  47.266 +        /// True if all items are equal.
  47.267 +        /// </returns>
  47.268 +        private bool AreListsEqual(IList list1, IList list2)
  47.269 +        {
  47.270 +            if (list1 == null || list2 == null)
  47.271 +            {
  47.272 +                return false;
  47.273 +            }
  47.274 +
  47.275 +            if (list1.Count != list2.Count)
  47.276 +            {
  47.277 +                return false;
  47.278 +            }
  47.279 +
  47.280 +            for (int i = 0; i < list1.Count; i++)
  47.281 +            {
  47.282 +                if (!list1[i].Equals(list2[i]))
  47.283 +                {
  47.284 +                    return false;
  47.285 +                }
  47.286 +            }
  47.287 +
  47.288 +            return true;
  47.289 +        }
  47.290 +
  47.291 +        /// <summary>
  47.292 +        /// Get the first attribute of the specified type.
  47.293 +        /// </summary>
  47.294 +        /// <param name="pi">
  47.295 +        /// The property info.
  47.296 +        /// </param>
  47.297 +        /// <typeparam name="T">
  47.298 +        /// The type.
  47.299 +        /// </typeparam>
  47.300 +        /// <returns>
  47.301 +        /// The attribute, or null if no attribute was found.
  47.302 +        /// </returns>
  47.303 +        private T GetFirstAttribute<T>(PropertyInfo pi) where T : Attribute
  47.304 +        {
  47.305 +            foreach (T a in pi.GetCustomAttributes(typeof(CodeGenerationAttribute), true))
  47.306 +            {
  47.307 +                return a;
  47.308 +            }
  47.309 +
  47.310 +            return null;
  47.311 +        }
  47.312 +
  47.313 +        /// <summary>
  47.314 +        /// Gets a new variable name of the specified type.
  47.315 +        /// </summary>
  47.316 +        /// <param name="type">
  47.317 +        /// The type.
  47.318 +        /// </param>
  47.319 +        /// <returns>
  47.320 +        /// The variable name.
  47.321 +        /// </returns>
  47.322 +        private string GetNewVariableName(Type type)
  47.323 +        {
  47.324 +            string prefix = type.Name;
  47.325 +            prefix = char.ToLower(prefix[0]) + prefix.Substring(1);
  47.326 +            int i = 1;
  47.327 +            while (this.variables.ContainsKey(prefix + i))
  47.328 +            {
  47.329 +                i++;
  47.330 +            }
  47.331 +
  47.332 +            return prefix + i;
  47.333 +        }
  47.334 +
  47.335 +        /// <summary>
  47.336 +        /// Makes a valid variable name of a string. Invalid characters will simply be removed.
  47.337 +        /// </summary>
  47.338 +        /// <param name="title">
  47.339 +        /// The title.
  47.340 +        /// </param>
  47.341 +        /// <returns>
  47.342 +        /// A valid variable name.
  47.343 +        /// </returns>
  47.344 +        private string MakeValidVariableName(string title)
  47.345 +        {
  47.346 +            if (title == null)
  47.347 +            {
  47.348 +                return null;
  47.349 +            }
  47.350 +
  47.351 +            var regex = new Regex("[a-zA-Z_][a-zA-Z0-9_]*");
  47.352 +            var result = new StringBuilder();
  47.353 +            foreach (var c in title)
  47.354 +            {
  47.355 +                string s = c.ToString();
  47.356 +                if (regex.Match(s).Success)
  47.357 +                {
  47.358 +                    result.Append(s);
  47.359 +                }
  47.360 +            }
  47.361 +
  47.362 +            return result.ToString();
  47.363 +        }
  47.364 +
  47.365 +        /// <summary>
  47.366 +        /// The set properties.
  47.367 +        /// </summary>
  47.368 +        /// <param name="instance">
  47.369 +        /// The instance.
  47.370 +        /// </param>
  47.371 +        /// <param name="varName">
  47.372 +        /// The var name.
  47.373 +        /// </param>
  47.374 +        /// <param name="defaultValues">
  47.375 +        /// The default values.
  47.376 +        /// </param>
  47.377 +        private void SetProperties(object instance, string varName, object defaultValues)
  47.378 +        {
  47.379 +            var instanceType = instance.GetType();
  47.380 +            var listsToAdd = new Dictionary<string, IList>();
  47.381 +            foreach (var pi in instanceType.GetProperties())
  47.382 +            {
  47.383 +                // check the [CodeGeneration] attribute
  47.384 +                var cga = this.GetFirstAttribute<CodeGenerationAttribute>(pi);
  47.385 +                if (cga != null && !cga.GenerateCode)
  47.386 +                {
  47.387 +                    continue;
  47.388 +                }
  47.389 +
  47.390 +                string name = varName + "." + pi.Name;
  47.391 +                object value = pi.GetValue(instance, null);
  47.392 +                object defaultValue = pi.GetValue(defaultValues, null);
  47.393 +
  47.394 +                // check if lists are equal
  47.395 +                if (this.AreListsEqual(value as IList, defaultValue as IList))
  47.396 +                {
  47.397 +                    continue;
  47.398 +                }
  47.399 +
  47.400 +                // add items of lists
  47.401 +                var list = value as IList;
  47.402 +                if (list != null)
  47.403 +                {
  47.404 +                    listsToAdd.Add(name, list);
  47.405 +                    continue;
  47.406 +                }
  47.407 +
  47.408 +                // only properties with public setters are used
  47.409 +                var setter = pi.GetSetMethod();
  47.410 +                if (setter == null || !setter.IsPublic)
  47.411 +                {
  47.412 +                    continue;
  47.413 +                }
  47.414 +
  47.415 +                // skip default values
  47.416 +                if ((value != null && value.Equals(defaultValue)) || value == defaultValue)
  47.417 +                {
  47.418 +                    continue;
  47.419 +                }
  47.420 +
  47.421 +                this.SetProperty(name, value);
  47.422 +            }
  47.423 +
  47.424 +            // Add the items of the lists
  47.425 +            foreach (var kvp in listsToAdd)
  47.426 +            {
  47.427 +                var name = kvp.Key;
  47.428 +                var list = kvp.Value;
  47.429 +                this.AddItems(name, list);
  47.430 +            }
  47.431 +        }
  47.432 +
  47.433 +        /// <summary>
  47.434 +        /// Sets the property.
  47.435 +        /// </summary>
  47.436 +        /// <param name="name">
  47.437 +        /// The property name.
  47.438 +        /// </param>
  47.439 +        /// <param name="value">
  47.440 +        /// The value.
  47.441 +        /// </param>
  47.442 +        private void SetProperty(string name, object value)
  47.443 +        {
  47.444 +            string code = value.ToCode();
  47.445 +            if (code != null)
  47.446 +            {
  47.447 +                this.AppendLine("{0} = {1};", name, code);
  47.448 +            }
  47.449 +        }
  47.450 +    }
  47.451 +}
  47.452 \ No newline at end of file
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/CodeGeneratorStringExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
    48.3 @@ -0,0 +1,188 @@
    48.4 +// --------------------------------------------------------------------------------------------------------------------
    48.5 +// <copyright file="CodeGeneratorStringExtensions.cs" company="OxyPlot">
    48.6 +//   The MIT License (MIT)
    48.7 +//
    48.8 +//   Copyright (c) 2012 Oystein Bjorke
    48.9 +//
   48.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   48.11 +//   copy of this software and associated documentation files (the
   48.12 +//   "Software"), to deal in the Software without restriction, including
   48.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   48.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   48.15 +//   permit persons to whom the Software is furnished to do so, subject to
   48.16 +//   the following conditions:
   48.17 +//
   48.18 +//   The above copyright notice and this permission notice shall be included
   48.19 +//   in all copies or substantial portions of the Software.
   48.20 +//
   48.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   48.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   48.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   48.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   48.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   48.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   48.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   48.28 +// </copyright>
   48.29 +// <summary>
   48.30 +//   The code generator string extensions.
   48.31 +// </summary>
   48.32 +// --------------------------------------------------------------------------------------------------------------------
   48.33 +namespace OxyPlot
   48.34 +{
   48.35 +    using System;
   48.36 +    using System.Globalization;
   48.37 +
   48.38 +    /// <summary>
   48.39 +    /// Provides extension methods for code generation.
   48.40 +    /// </summary>
   48.41 +    public static class CodeGeneratorStringExtensions
   48.42 +    {
   48.43 +        /// <summary>
   48.44 +        /// Converts the value of this instance to c# code.
   48.45 +        /// </summary>
   48.46 +        /// <param name="value">
   48.47 +        /// The instance.
   48.48 +        /// </param>
   48.49 +        /// <returns>
   48.50 +        /// C# code.
   48.51 +        /// </returns>
   48.52 +        public static string ToCode(this string value)
   48.53 +        {
   48.54 +            value = value.Replace("\"", "\\\"");
   48.55 +            value = value.Replace("\r\n", "\\n");
   48.56 +            value = value.Replace("\n", "\\n");
   48.57 +            value = value.Replace("\t", "\\t");
   48.58 +            return "\"" + value + "\"";
   48.59 +        }
   48.60 +
   48.61 +        /// <summary>
   48.62 +        /// Converts the value of this instance to c# code.
   48.63 +        /// </summary>
   48.64 +        /// <param name="value">
   48.65 +        /// The value.
   48.66 +        /// </param>
   48.67 +        /// <returns>
   48.68 +        /// C# code.
   48.69 +        /// </returns>
   48.70 +        public static string ToCode(this bool value)
   48.71 +        {
   48.72 +            return value.ToString().ToLower();
   48.73 +        }
   48.74 +
   48.75 +        /// <summary>
   48.76 +        /// Converts the value of this instance to c# code.
   48.77 +        /// </summary>
   48.78 +        /// <param name="value">
   48.79 +        /// The instance.
   48.80 +        /// </param>
   48.81 +        /// <returns>
   48.82 +        /// C# code.
   48.83 +        /// </returns>
   48.84 +        public static string ToCode(this int value)
   48.85 +        {
   48.86 +            return value.ToString(CultureInfo.InvariantCulture);
   48.87 +        }
   48.88 +
   48.89 +        /// <summary>
   48.90 +        /// Converts the value of this instance to c# code.
   48.91 +        /// </summary>
   48.92 +        /// <param name="value">
   48.93 +        /// The instance.
   48.94 +        /// </param>
   48.95 +        /// <returns>
   48.96 +        /// C# code.
   48.97 +        /// </returns>
   48.98 +        public static string ToCode(this Enum value)
   48.99 +        {
  48.100 +            return string.Format("{0}.{1}", value.GetType().Name, value);
  48.101 +        }
  48.102 +
  48.103 +        /// <summary>
  48.104 +        /// Converts the value of this instance to c# code.
  48.105 +        /// </summary>
  48.106 +        /// <param name="value">
  48.107 +        /// The instance.
  48.108 +        /// </param>
  48.109 +        /// <returns>
  48.110 +        /// C# code.
  48.111 +        /// </returns>
  48.112 +        public static string ToCode(this double value)
  48.113 +        {
  48.114 +            if (double.IsNaN(value))
  48.115 +            {
  48.116 +                return "double.NaN";
  48.117 +            }
  48.118 +
  48.119 +            if (double.IsPositiveInfinity(value))
  48.120 +            {
  48.121 +                return "double.PositiveInfinity";
  48.122 +            }
  48.123 +
  48.124 +            if (double.IsNegativeInfinity(value))
  48.125 +            {
  48.126 +                return "double.NegativeInfinity";
  48.127 +            }
  48.128 +
  48.129 +            if (value.Equals(double.MinValue))
  48.130 +            {
  48.131 +                return "double.MinValue";
  48.132 +            }
  48.133 +
  48.134 +            if (value.Equals(double.MaxValue))
  48.135 +            {
  48.136 +                return "double.MaxValue";
  48.137 +            }
  48.138 +
  48.139 +            return value.ToString(CultureInfo.InvariantCulture);
  48.140 +        }
  48.141 +
  48.142 +        /// <summary>
  48.143 +        /// Converts the value of this instance to c# code.
  48.144 +        /// </summary>
  48.145 +        /// <param name="value">
  48.146 +        /// The instance.
  48.147 +        /// </param>
  48.148 +        /// <returns>
  48.149 +        /// C# code.
  48.150 +        /// </returns>
  48.151 +        public static string ToCode(this object value)
  48.152 +        {
  48.153 +            if (value == null)
  48.154 +            {
  48.155 +                return "null";
  48.156 +            }
  48.157 +
  48.158 +            if (value is int)
  48.159 +            {
  48.160 +                return ((int)value).ToCode();
  48.161 +            }
  48.162 +
  48.163 +            if (value is double)
  48.164 +            {
  48.165 +                return ((double)value).ToCode();
  48.166 +            }
  48.167 +
  48.168 +            if (value is string)
  48.169 +            {
  48.170 +                return ((string)value).ToCode();
  48.171 +            }
  48.172 +
  48.173 +            if (value is bool)
  48.174 +            {
  48.175 +                return ((bool)value).ToCode();
  48.176 +            }
  48.177 +
  48.178 +            if (value is Enum)
  48.179 +            {
  48.180 +                return ((Enum)value).ToCode();
  48.181 +            }
  48.182 +
  48.183 +            if (value is ICodeGenerating)
  48.184 +            {
  48.185 +                return ((ICodeGenerating)value).ToCode();
  48.186 +            }
  48.187 +
  48.188 +            return null;
  48.189 +        }
  48.190 +    }
  48.191 +}
  48.192 \ No newline at end of file
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CodeGenerator/ICodeGenerating.cs	Sat Jun 08 16:53:22 2013 +0000
    49.3 @@ -0,0 +1,45 @@
    49.4 +// --------------------------------------------------------------------------------------------------------------------
    49.5 +// <copyright file="ICodeGenerating.cs" company="OxyPlot">
    49.6 +//   The MIT License (MIT)
    49.7 +//
    49.8 +//   Copyright (c) 2012 Oystein Bjorke
    49.9 +//
   49.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   49.11 +//   copy of this software and associated documentation files (the
   49.12 +//   "Software"), to deal in the Software without restriction, including
   49.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   49.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   49.15 +//   permit persons to whom the Software is furnished to do so, subject to
   49.16 +//   the following conditions:
   49.17 +//
   49.18 +//   The above copyright notice and this permission notice shall be included
   49.19 +//   in all copies or substantial portions of the Software.
   49.20 +//
   49.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   49.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   49.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   49.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   49.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   49.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   49.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   49.28 +// </copyright>
   49.29 +// <summary>
   49.30 +//   Provides functionality to generate c# code of an object.
   49.31 +// </summary>
   49.32 +// --------------------------------------------------------------------------------------------------------------------
   49.33 +namespace OxyPlot
   49.34 +{
   49.35 +    /// <summary>
   49.36 +    /// Provides functionality to generate C# code of an object.
   49.37 +    /// </summary>
   49.38 +    public interface ICodeGenerating
   49.39 +    {
   49.40 +        /// <summary>
   49.41 +        /// Returns c# code that generates this instance.
   49.42 +        /// </summary>
   49.43 +        /// <returns>
   49.44 +        /// C# code.
   49.45 +        /// </returns>
   49.46 +        string ToCode();
   49.47 +    }
   49.48 +}
   49.49 \ No newline at end of file
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/External/OxyPlot/OxyPlot/Foundation/CohenSutherlandClipping.cs	Sat Jun 08 16:53:22 2013 +0000
    50.3 @@ -0,0 +1,298 @@
    50.4 +// --------------------------------------------------------------------------------------------------------------------
    50.5 +// <copyright file="CohenSutherlandClipping.cs" company="OxyPlot">
    50.6 +//   The MIT License (MIT)
    50.7 +//
    50.8 +//   Copyright (c) 2012 Oystein Bjorke
    50.9 +//
   50.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   50.11 +//   copy of this software and associated documentation files (the
   50.12 +//   "Software"), to deal in the Software without restriction, including
   50.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   50.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   50.15 +//   permit persons to whom the Software is furnished to do so, subject to
   50.16 +//   the following conditions:
   50.17 +//
   50.18 +//   The above copyright notice and this permission notice shall be included
   50.19 +//   in all copies or substantial portions of the Software.
   50.20 +//
   50.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   50.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   50.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   50.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   50.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   50.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   50.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   50.28 +// </copyright>
   50.29 +// <summary>
   50.30 +//   Line clipping algorithm.
   50.31 +// </summary>
   50.32 +// --------------------------------------------------------------------------------------------------------------------
   50.33 +namespace OxyPlot
   50.34 +{
   50.35 +    /// <summary>
   50.36 +    /// Provides a line clipping algorithm.
   50.37 +    /// </summary>
   50.38 +    /// <remarks>
   50.39 +    /// See http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland
   50.40 +    /// </remarks>
   50.41 +    public class CohenSutherlandClipping
   50.42 +    {
   50.43 +        /// <summary>
   50.44 +        /// The bottom code.
   50.45 +        /// </summary>
   50.46 +        private const int Bottom = 4; // 0100
   50.47 +
   50.48 +        /// <summary>
   50.49 +        /// The inside code.
   50.50 +        /// </summary>
   50.51 +        private const int Inside = 0; // 0000
   50.52 +
   50.53 +        /// <summary>
   50.54 +        /// The left code.
   50.55 +        /// </summary>
   50.56 +        private const int Left = 1; // 0001
   50.57 +
   50.58 +        /// <summary>
   50.59 +        /// The right code.
   50.60 +        /// </summary>
   50.61 +        private const int Right = 2; // 0010
   50.62 +
   50.63 +        /// <summary>
   50.64 +        /// The top code.
   50.65 +        /// </summary>
   50.66 +        private const int Top = 8; // 1000
   50.67 +
   50.68 +        /// <summary>
   50.69 +        /// The x maximum.
   50.70 +        /// </summary>
   50.71 +        private readonly double xmax;
   50.72 +
   50.73 +        /// <summary>
   50.74 +        /// The x minimum.
   50.75 +        /// </summary>
   50.76 +        private readonly double xmin;
   50.77 +
   50.78 +        /// <summary>
   50.79 +        /// The y maximum.
   50.80 +        /// </summary>
   50.81 +        private readonly double ymax;
   50.82 +
   50.83 +        /// <summary>
   50.84 +        /// The y minimum.
   50.85 +        /// </summary>
   50.86 +        private readonly double ymin;
   50.87 +
   50.88 +        /// <summary>
   50.89 +        /// Initializes a new instance of the <see cref="CohenSutherlandClipping"/> class.
   50.90 +        /// </summary>
   50.91 +        /// <param name="rect">
   50.92 +        /// The clipping rectangle.
   50.93 +        /// </param>
   50.94 +        public CohenSutherlandClipping(OxyRect rect)
   50.95 +        {
   50.96 +            this.xmin = rect.Left;
   50.97 +            this.xmax = rect.Right;
   50.98 +            this.ymin = rect.Top;
   50.99 +            this.ymax = rect.Bottom;
  50.100 +        }
  50.101 +
  50.102 +        /// <summary>
  50.103 +        /// Initializes a new instance of the <see cref="CohenSutherlandClipping"/> class.
  50.104 +        /// </summary>
  50.105 +        /// <param name="xmin">
  50.106 +        /// The xmin.
  50.107 +        /// </param>
  50.108 +        /// <param name="xmax">
  50.109 +        /// The xmax.
  50.110 +        /// </param>
  50.111 +        /// <param name="ymin">
  50.112 +        /// The ymin.
  50.113 +        /// </param>
  50.114 +        /// <param name="ymax">
  50.115 +        /// The ymax.
  50.116 +        /// </param>
  50.117 +        public CohenSutherlandClipping(double xmin, double xmax, double ymin, double ymax)
  50.118 +        {
  50.119 +            this.xmin = xmin;
  50.120 +            this.ymin = ymin;
  50.121 +            this.xmax = xmax;
  50.122 +            this.ymax = ymax;
  50.123 +        }
  50.124 +
  50.125 +        /// <summary>
  50.126 +        /// Cohen–Sutherland clipping algorithm clips a line from
  50.127 +        /// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
  50.128 +        /// diagonal from (xmin, ymin) to (xmax, ymax).
  50.129 +        /// </summary>
  50.130 +        /// <param name="x0">X coordinate of the first point.</param>
  50.131 +        /// <param name="y0">Y coordinate of the first point.</param>
  50.132 +        /// <param name="x1">X coordinate of the second point.</param>
  50.133 +        /// <param name="y1">Y coordinate of the second point.</param>
  50.134 +        /// <returns>
  50.135 +        /// true if the line is inside.
  50.136 +        /// </returns>
  50.137 +        public bool ClipLine(ref double x0, ref double y0, ref double x1, ref double y1)
  50.138 +        {
  50.139 +            // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
  50.140 +            int outcode0 = this.ComputeOutCode(x0, y0);
  50.141 +            int outcode1 = this.ComputeOutCode(x1, y1);
  50.142 +            bool accept = false;
  50.143 +
  50.144 +            while (true)
  50.145 +            {
  50.146 +                if ((outcode0 | outcode1) == 0)
  50.147 +                {
  50.148 +                    // logical or is 0. Trivially accept and get out of loop
  50.149 +                    accept = true;
  50.150 +                    break;
  50.151 +                }
  50.152 +
  50.153 +                if ((outcode0 & outcode1) != 0)
  50.154 +                {
  50.155 +                    // logical and is not 0. Trivially reject and get out of loop
  50.156 +                    break;
  50.157 +                }
  50.158 +
  50.159 +                // failed both tests, so calculate the line segment to clip
  50.160 +                // from an outside point to an intersection with clip edge
  50.161 +                double x = 0, y = 0;
  50.162 +
  50.163 +                // At least one endpoint is outside the clip rectangle; pick it.
  50.164 +                int outcodeOut = outcode0 != 0 ? outcode0 : outcode1;
  50.165 +
  50.166 +                // Now find the intersection point;
  50.167 +                // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
  50.168 +                if ((outcodeOut & Top) != 0)
  50.169 +                {
  50.170 +                    // point is above the clip rectangle
  50.171 +                    x = x0 + ((x1 - x0) * (this.ymax - y0) / (y1 - y0));
  50.172 +                    y = this.ymax;
  50.173 +                }
  50.174 +                else if ((outcodeOut & Bottom) != 0)
  50.175 +                {
  50.176 +                    // point is below the clip rectangle
  50.177 +                    x = x0 + ((x1 - x0) * (this.ymin - y0) / (y1 - y0));
  50.178 +                    y = this.ymin;
  50.179 +                }
  50.180 +                else if ((outcodeOut & Right) != 0)
  50.181 +                {
  50.182 +                    // point is to the right of clip rectangle
  50.183 +                    y = y0 + ((y1 - y0) * (this.xmax - x0) / (x1 - x0));
  50.184 +                    x = this.xmax;
  50.185 +                }
  50.186 +                else if ((outcodeOut & Left) != 0)
  50.187 +                {
  50.188 +                    // point is to the left of clip rectangle
  50.189 +                    y = y0 + ((y1 - y0) * (this.xmin - x0) / (x1 - x0));
  50.190 +                    x = this.xmin;
  50.191 +                }
  50.192 +
  50.193 +                // Now we move outside point to intersection point to clip
  50.194 +                // and get ready for next pass.
  50.195 +                if (outcodeOut == outcode0)
  50.196 +                {
  50.197 +                    x0 = x;
  50.198 +                    y0 = y;
  50.199 +                    outcode0 = this.ComputeOutCode(x0, y0);
  50.200 +                }
  50.201 +                else
  50.202 +                {
  50.203 +                    x1 = x;
  50.204 +                    y1 = y;
  50.205 +                    outcode1 = this.ComputeOutCode(x1, y1);
  50.206 +                }
  50.207 +            }
  50.208 +
  50.209 +            return accept;
  50.210 +        }
  50.211 +
  50.212 +        /// <summary>
  50.213 +        /// Cohen–Sutherland clipping algorithm clips a line from
  50.214 +        /// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
  50.215 +        /// diagonal from (xmin, ymin) to (xmax, ymax).
  50.216 +        /// </summary>
  50.217 +        /// <param name="s0">
  50.218 +        /// The s 0.
  50.219 +        /// </param>
  50.220 +        /// <param name="s1">
  50.221 +        /// The s 1.
  50.222 +        /// </param>
  50.223 +        /// <returns>
  50.224 +        /// true if the line is inside
  50.225 +        /// </returns>
  50.226 +        public bool ClipLine(ref ScreenPoint s0, ref ScreenPoint s1)
  50.227 +        {
  50.228 +            return this.ClipLine(ref s0.x, ref s0.y, ref s1.x, ref s1.y);
  50.229 +        }
  50.230 +
  50.231 +        /// <summary>
  50.232 +        /// Determines whether the specified point is inside the rectangle.
  50.233 +        /// </summary>
  50.234 +        /// <param name="x">The x coordinate.</param>
  50.235 +        /// <param name="y">The y coordinate.</param>
  50.236 +        /// <returns>
  50.237 +        ///  <c>true</c> if the specified point is inside; otherwise, <c>false</c>.
  50.238 +        /// </returns>
  50.239 +        public bool IsInside(double x, double y)
  50.240 +        {
  50.241 +            return this.ComputeOutCode(x, y) == Inside;
  50.242 +        }
  50.243 +
  50.244 +        /// <summary>
  50.245 +        /// Determines whether the specified point is inside the rectangle.
  50.246 +        /// </summary>
  50.247 +        /// <param name="s">The point.</param>
  50.248 +        /// <returns>
  50.249 +        ///  <c>true</c> if the specified point is inside; otherwise, <c>false</c>.
  50.250 +        /// </returns>
  50.251 +        public bool IsInside(ScreenPoint s)
  50.252 +        {
  50.253 +            return this.ComputeOutCode(s.X, s.Y) == Inside;
  50.254 +        }
  50.255 +
  50.256 +        /// <summary>
  50.257 +        /// Computes the out code.
  50.258 +        /// </summary>
  50.259 +        /// <param name="x">
  50.260 +        /// The x.
  50.261 +        /// </param>
  50.262 +        /// <param name="y">
  50.263 +        /// The y.
  50.264 +        /// </param>
  50.265 +        /// <returns>
  50.266 +        /// The out code.
  50.267 +        /// </returns>
  50.268 +        /// <remarks>
  50.269 +        /// Compute the bit code for a point (x, y) using the clip rectangle
  50.270 +        /// bounded diagonally by (xmin, ymin), and (xmax, ymax)
  50.271 +        /// </remarks>
  50.272 +        private int ComputeOutCode(double x, double y)
  50.273 +        {
  50.274 +            int code = Inside; // initialized as being inside of clip window
  50.275 +
  50.276 +            if (x < this.xmin)
  50.277 +            {
  50.278 +                // to the left of clip window
  50.279 +                code |= Left;
  50.280 +            }
  50.281 +            else if (x > this.xmax)
  50.282 +            {
  50.283 +                // to the right of clip window
  50.284 +                code |= Right;
  50.285 +            }
  50.286 +
  50.287 +            if (y < this.ymin)
  50.288 +            {
  50.289 +                // below the clip window
  50.290 +                code |= Bottom;
  50.291 +            }
  50.292 +            else if (y > this.ymax)
  50.293 +            {
  50.294 +                // above the clip window
  50.295 +                code |= Top;
  50.296 +            }
  50.297 +
  50.298 +            return code;
  50.299 +        }
  50.300 +    }
  50.301 +}
  50.302 \ No newline at end of file
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Color.cs	Sat Jun 08 16:53:22 2013 +0000
    51.3 @@ -0,0 +1,55 @@
    51.4 +// --------------------------------------------------------------------------------------------------------------------
    51.5 +// <copyright file="Color.cs" company="OxyPlot">
    51.6 +//   The MIT License (MIT)
    51.7 +//
    51.8 +//   Copyright (c) 2012 Oystein Bjorke
    51.9 +//
   51.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   51.11 +//   copy of this software and associated documentation files (the
   51.12 +//   "Software"), to deal in the Software without restriction, including
   51.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   51.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   51.15 +//   permit persons to whom the Software is furnished to do so, subject to
   51.16 +//   the following conditions:
   51.17 +//
   51.18 +//   The above copyright notice and this permission notice shall be included
   51.19 +//   in all copies or substantial portions of the Software.
   51.20 +//
   51.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   51.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   51.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   51.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   51.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   51.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   51.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   51.28 +// </copyright>
   51.29 +// --------------------------------------------------------------------------------------------------------------------
   51.30 +namespace OxyPlot
   51.31 +{
   51.32 +    public class Color
   51.33 +    {
   51.34 +        public byte A { get; set; }
   51.35 +        public byte R { get; set; }
   51.36 +        public byte G { get; set; }
   51.37 +        public byte B { get; set; }
   51.38 +
   51.39 +        public static Color FromARGB(byte a, byte r, byte g, byte b)
   51.40 +        {
   51.41 +            return new Color { A = a, R = r, G = g, B = b };
   51.42 +        }
   51.43 +
   51.44 +        public static Color FromRGB(byte r, byte g, byte b)
   51.45 +        {
   51.46 +            return new Color { A = 255, R = r, G = g, B = b };
   51.47 +        }
   51.48 +
   51.49 +        public static Color FromAColor(byte a, Color color)
   51.50 +        {
   51.51 +            return new Color { A = a, R = color.R, G = color.G, B = color.B };
   51.52 +        }
   51.53 +        public override string ToString()
   51.54 +        {
   51.55 +            return string.Format("#{0:x2}{1:x2}{2:x2}{3:x2}", A, R, G, B);
   51.56 +        }
   51.57 +    }
   51.58 +}
   51.59 \ No newline at end of file
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Colors.cs	Sat Jun 08 16:53:22 2013 +0000
    52.3 @@ -0,0 +1,45 @@
    52.4 +// --------------------------------------------------------------------------------------------------------------------
    52.5 +// <copyright file="Colors.cs" company="OxyPlot">
    52.6 +//   The MIT License (MIT)
    52.7 +//
    52.8 +//   Copyright (c) 2012 Oystein Bjorke
    52.9 +//
   52.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   52.11 +//   copy of this software and associated documentation files (the
   52.12 +//   "Software"), to deal in the Software without restriction, including
   52.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   52.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   52.15 +//   permit persons to whom the Software is furnished to do so, subject to
   52.16 +//   the following conditions:
   52.17 +//
   52.18 +//   The above copyright notice and this permission notice shall be included
   52.19 +//   in all copies or substantial portions of the Software.
   52.20 +//
   52.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   52.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   52.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   52.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   52.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   52.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   52.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   52.28 +// </copyright>
   52.29 +// --------------------------------------------------------------------------------------------------------------------
   52.30 +namespace OxyPlot
   52.31 +{
   52.32 +    public static class Colors
   52.33 +    {
   52.34 +        public static readonly Color Transparent = Color.FromARGB(0, 0, 0, 0);
   52.35 +        public static readonly Color Black = Color.FromRGB(0, 0, 0);
   52.36 +        public static readonly Color White = Color.FromRGB(0xFF, 0xFF, 0xFF);
   52.37 +        public static readonly Color DarkGray = Color.FromRGB(0xA9, 0xA9, 0xA9);
   52.38 +        public static readonly Color Gray = Color.FromRGB(0x80, 0x80, 0x80);
   52.39 +        public static readonly Color LightGray = Color.FromRGB(0xD3, 0xD3, 0xD3);
   52.40 +        public static readonly Color Red = Color.FromRGB(0xFF, 0, 0);
   52.41 +        public static readonly Color Green = Color.FromRGB(0, 0xFF, 0);
   52.42 +        public static readonly Color Blue = Color.FromRGB(0, 0, 0xFF);
   52.43 +        public static readonly Color Orange = Color.FromRGB(0xFF, 0xA5, 0x00);
   52.44 +        public static readonly Color Indigo = Color.FromRGB(0x4B, 0x00, 0x82);
   52.45 +        public static readonly Color Violet = Color.FromRGB(0xEE, 0x82, 0xEE);
   52.46 +        public static readonly Color Yellow = Color.FromRGB(0xFF, 0xFF, 0x00);
   52.47 +    }
   52.48 +}
   52.49 \ No newline at end of file
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Conrec.cs	Sat Jun 08 16:53:22 2013 +0000
    53.3 @@ -0,0 +1,294 @@
    53.4 +// --------------------------------------------------------------------------------------------------------------------
    53.5 +// <copyright file="Conrec.cs" company="OxyPlot">
    53.6 +//   The MIT License (MIT)
    53.7 +//
    53.8 +//   Copyright (c) 2012 Oystein Bjorke
    53.9 +//
   53.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   53.11 +//   copy of this software and associated documentation files (the
   53.12 +//   "Software"), to deal in the Software without restriction, including
   53.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   53.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   53.15 +//   permit persons to whom the Software is furnished to do so, subject to
   53.16 +//   the following conditions:
   53.17 +//
   53.18 +//   The above copyright notice and this permission notice shall be included
   53.19 +//   in all copies or substantial portions of the Software.
   53.20 +//
   53.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   53.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   53.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   53.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   53.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   53.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   53.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   53.28 +// </copyright>
   53.29 +// <summary>
   53.30 +//   Creates contours from a triangular mesh.
   53.31 +// </summary>
   53.32 +// --------------------------------------------------------------------------------------------------------------------
   53.33 +namespace OxyPlot
   53.34 +{
   53.35 +    using System;
   53.36 +
   53.37 +    /// <summary>
   53.38 +    /// Provides functionality to create contours from a triangular mesh.
   53.39 +    /// </summary>
   53.40 +    /// <remarks>
   53.41 +    /// <para>
   53.42 +    /// Ported from C / Fortran code by Paul Bourke.
   53.43 +    /// See <a href="http://paulbourke.net/papers/conrec/">Conrec</a> for
   53.44 +    /// full description of code and the original source.
   53.45 +    ///  </para>
   53.46 +    /// <para>
   53.47 +    /// Contouring aids in visualizing three dimensional surfaces on a two dimensional
   53.48 +    /// medium (on paper or in this case a computer graphics screen). Two most common
   53.49 +    /// applications are displaying topological features of an area on a map or the air
   53.50 +    /// pressure on a weather map. In all cases some parameter is plotted as a function
   53.51 +    /// of two variables, the longitude and latitude or x and y axis. One problem with
   53.52 +    /// computer contouring is the process is usually CPU intensive and the algorithms
   53.53 +    /// often use advanced mathematical techniques making them susceptible to error.
   53.54 +    ///  </para>
   53.55 +    /// </remarks>
   53.56 +    public static class Conrec
   53.57 +    {
   53.58 +        /// <summary>
   53.59 +        /// Renderer delegate
   53.60 +        /// </summary>
   53.61 +        /// <param name="x1">
   53.62 +        /// Start point x-coordinate
   53.63 +        /// </param>
   53.64 +        /// <param name="y1">
   53.65 +        /// Start point y-coordinate
   53.66 +        /// </param>
   53.67 +        /// <param name="x2">
   53.68 +        /// End point x-coordinate
   53.69 +        /// </param>
   53.70 +        /// <param name="y2">
   53.71 +        /// End point y-coordinate
   53.72 +        /// </param>
   53.73 +        /// <param name="z">
   53.74 +        /// Contour level
   53.75 +        /// </param>
   53.76 +        public delegate void RendererDelegate(double x1, double y1, double x2, double y2, double z);
   53.77 +
   53.78 +        /// <summary>
   53.79 +        /// Contour is a contouring subroutine for rectangularily spaced data
   53.80 +        /// It emits calls to a line drawing subroutine supplied by the user
   53.81 +        /// which draws a contour map corresponding to data on a randomly
   53.82 +        /// spaced rectangular grid. The coordinates emitted are in the same
   53.83 +        /// units given in the x() and y() arrays.
   53.84 +        /// Any number of contour levels may be specified but they must be
   53.85 +        /// in order of increasing value.
   53.86 +        /// </summary>
   53.87 +        /// <param name="d">
   53.88 +        /// Matrix of data to contour.
   53.89 +        /// </param>
   53.90 +        /// <param name="x">
   53.91 +        /// Data matrix column coordinates.
   53.92 +        /// </param>
   53.93 +        /// <param name="y">
   53.94 +        /// Data matrix row coordinates.
   53.95 +        /// </param>
   53.96 +        /// <param name="z">
   53.97 +        /// Contour levels in increasing order.
   53.98 +        /// </param>
   53.99 +        /// <param name="renderer">
  53.100 +        /// The renderer.
  53.101 +        /// </param>
  53.102 +        public static void Contour(double[,] d, double[] x, double[] y, double[] z, RendererDelegate renderer)
  53.103 +        {
  53.104 +            double x1 = 0.0;
  53.105 +            double x2 = 0.0;
  53.106 +            double y1 = 0.0;
  53.107 +            double y2 = 0.0;
  53.108 +
  53.109 +            var h = new double[5];
  53.110 +            var sh = new int[5];
  53.111 +            var xh = new double[5];
  53.112 +            var yh = new double[5];
  53.113 +
  53.114 +            int ilb = d.GetLowerBound(0);
  53.115 +            int iub = d.GetUpperBound(0);
  53.116 +            int jlb = d.GetLowerBound(1);
  53.117 +            int jub = d.GetUpperBound(1);
  53.118 +            int nc = z.Length;
  53.119 +
  53.120 +            // The indexing of im and jm should be noted as it has to start from zero
  53.121 +            // unlike the fortran counter part
  53.122 +            int[] im = { 0, 1, 1, 0 };
  53.123 +            int[] jm = { 0, 0, 1, 1 };
  53.124 +
  53.125 +            // Note that castab is arranged differently from the FORTRAN code because
  53.126 +            // Fortran and C/C++ arrays are transposed of each other, in this case
  53.127 +            // it is more tricky as castab is in 3 dimension
  53.128 +            int[,,] castab =
  53.129 +                            {
  53.130 +                                 { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } }, { { 0, 3, 4 }, { 1, 3, 1 }, { 4, 3, 0 } },
  53.131 +                                 { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } }
  53.132 +                            };
  53.133 +
  53.134 +            Func<int, int, double> xsect = (p1, p2) => ((h[p2] * xh[p1]) - (h[p1] * xh[p2])) / (h[p2] - h[p1]);
  53.135 +            Func<int, int, double> ysect = (p1, p2) => ((h[p2] * yh[p1]) - (h[p1] * yh[p2])) / (h[p2] - h[p1]);
  53.136 +
  53.137 +            for (int j = jub - 1; j >= jlb; j--)
  53.138 +            {
  53.139 +                int i;
  53.140 +                for (i = ilb; i <= iub - 1; i++)
  53.141 +                {
  53.142 +                    double temp1 = Math.Min(d[i, j], d[i, j + 1]);
  53.143 +                    double temp2 = Math.Min(d[i + 1, j], d[i + 1, j + 1]);
  53.144 +                    double dmin = Math.Min(temp1, temp2);
  53.145 +                    temp1 = Math.Max(d[i, j], d[i, j + 1]);
  53.146 +                    temp2 = Math.Max(d[i + 1, j], d[i + 1, j + 1]);
  53.147 +                    double dmax = Math.Max(temp1, temp2);
  53.148 +
  53.149 +                    if (dmax >= z[0] && dmin <= z[nc - 1])
  53.150 +                    {
  53.151 +                        int k;
  53.152 +                        for (k = 0; k < nc; k++)
  53.153 +                        {
  53.154 +                            if (z[k] >= dmin && z[k] <= dmax)
  53.155 +                            {
  53.156 +                                int m;
  53.157 +                                for (m = 4; m >= 0; m--)
  53.158 +                                {
  53.159 +                                    if (m > 0)
  53.160 +                                    {
  53.161 +                                        // The indexing of im and jm should be noted as it has to
  53.162 +                                        // start from zero
  53.163 +                                        h[m] = d[i + im[m - 1], j + jm[m - 1]] - z[k];
  53.164 +                                        xh[m] = x[i + im[m - 1]];
  53.165 +                                        yh[m] = y[j + jm[m - 1]];
  53.166 +                                    }
  53.167 +                                    else
  53.168 +                                    {
  53.169 +                                        h[0] = 0.25 * (h[1] + h[2] + h[3] + h[4]);
  53.170 +                                        xh[0] = 0.5 * (x[i] + x[i + 1]);
  53.171 +                                        yh[0] = 0.5 * (y[j] + y[j + 1]);
  53.172 +                                    }
  53.173 +
  53.174 +                                    if (h[m] > 0.0)
  53.175 +                                    {
  53.176 +                                        sh[m] = 1;
  53.177 +                                    }
  53.178 +                                    else if (h[m] < 0.0)
  53.179 +                                    {
  53.180 +                                        sh[m] = -1;
  53.181 +                                    }
  53.182 +                                    else
  53.183 +                                    {
  53.184 +                                        sh[m] = 0;
  53.185 +                                    }
  53.186 +                                }
  53.187 +
  53.188 +                                //// Note: at this stage the relative heights of the corners and the
  53.189 +                                //// centre are in the h array, and the corresponding coordinates are
  53.190 +                                //// in the xh and yh arrays. The centre of the box is indexed by 0
  53.191 +                                //// and the 4 corners by 1 to 4 as shown below.
  53.192 +                                //// Each triangle is then indexed by the parameter m, and the 3
  53.193 +                                //// vertices of each triangle are indexed by parameters m1,m2,and
  53.194 +                                //// m3.
  53.195 +                                //// It is assumed that the centre of the box is always vertex 2
  53.196 +                                //// though this isimportant only when all 3 vertices lie exactly on
  53.197 +                                //// the same contour level, in which case only the side of the box
  53.198 +                                //// is drawn.
  53.199 +                                //// vertex 4 +-------------------+ vertex 3
  53.200 +                                //// | \               / |
  53.201 +                                //// |   \    m-3    /   |
  53.202 +                                //// |     \       /     |
  53.203 +                                //// |       \   /       |
  53.204 +                                //// |  m=2    X   m=2   |       the centre is vertex 0
  53.205 +                                //// |       /   \       |
  53.206 +                                //// |     /       \     |
  53.207 +                                //// |   /    m=1    \   |
  53.208 +                                //// | /               \ |
  53.209 +                                //// vertex 1 +-------------------+ vertex 2
  53.210 +
  53.211 +                                // Scan each triangle in the box
  53.212 +                                for (m = 1; m <= 4; m++)
  53.213 +                                {
  53.214 +                                    int m1 = m;
  53.215 +                                    int m2 = 0;
  53.216 +                                    int m3;
  53.217 +                                    if (m != 4)
  53.218 +                                    {
  53.219 +                                        m3 = m + 1;
  53.220 +                                    }
  53.221 +                                    else
  53.222 +                                    {
  53.223 +                                        m3 = 1;
  53.224 +                                    }
  53.225 +
  53.226 +                                    int caseValue = castab[sh[m1] + 1, sh[m2] + 1, sh[m3] + 1];
  53.227 +                                    if (caseValue != 0)
  53.228 +                                    {
  53.229 +                                        switch (caseValue)
  53.230 +                                        {
  53.231 +                                            case 1: // Line between vertices 1 and 2
  53.232 +                                                x1 = xh[m1];
  53.233 +                                                y1 = yh[m1];
  53.234 +                                                x2 = xh[m2];
  53.235 +                                                y2 = yh[m2];
  53.236 +                                                break;
  53.237 +                                            case 2: // Line between vertices 2 and 3
  53.238 +                                                x1 = xh[m2];
  53.239 +                                                y1 = yh[m2];
  53.240 +                                                x2 = xh[m3];
  53.241 +                                                y2 = yh[m3];
  53.242 +                                                break;
  53.243 +                                            case 3: // Line between vertices 3 and 1
  53.244 +                                                x1 = xh[m3];
  53.245 +                                                y1 = yh[m3];
  53.246 +                                                x2 = xh[m1];
  53.247 +                                                y2 = yh[m1];
  53.248 +                                                break;
  53.249 +                                            case 4: // Line between vertex 1 and side 2-3
  53.250 +                                                x1 = xh[m1];
  53.251 +                                                y1 = yh[m1];
  53.252 +                                                x2 = xsect(m2, m3);
  53.253 +                                                y2 = ysect(m2, m3);
  53.254 +                                                break;
  53.255 +                                            case 5: // Line between vertex 2 and side 3-1
  53.256 +                                                x1 = xh[m2];
  53.257 +                                                y1 = yh[m2];
  53.258 +                                                x2 = xsect(m3, m1);
  53.259 +                                                y2 = ysect(m3, m1);
  53.260 +                                                break;
  53.261 +                                            case 6: // Line between vertex 3 and side 1-2
  53.262 +                                                x1 = xh[m3];
  53.263 +                                                y1 = yh[m3];
  53.264 +                                                x2 = xsect(m1, m2);
  53.265 +                                                y2 = ysect(m1, m2);
  53.266 +                                                break;
  53.267 +                                            case 7: // Line between sides 1-2 and 2-3
  53.268 +                                                x1 = xsect(m1, m2);
  53.269 +                                                y1 = ysect(m1, m2);
  53.270 +                                                x2 = xsect(m2, m3);
  53.271 +                                                y2 = ysect(m2, m3);
  53.272 +                                                break;
  53.273 +                                            case 8: // Line between sides 2-3 and 3-1
  53.274 +                                                x1 = xsect(m2, m3);
  53.275 +                                                y1 = ysect(m2, m3);
  53.276 +                                                x2 = xsect(m3, m1);
  53.277 +                                                y2 = ysect(m3, m1);
  53.278 +                                                break;
  53.279 +                                            case 9: // Line between sides 3-1 and 1-2
  53.280 +                                                x1 = xsect(m3, m1);
  53.281 +                                                y1 = ysect(m3, m1);
  53.282 +                                                x2 = xsect(m1, m2);
  53.283 +                                                y2 = ysect(m1, m2);
  53.284 +                                                break;
  53.285 +                                        }
  53.286 +
  53.287 +                                        renderer(x1, y1, x2, y2, z[k]);
  53.288 +                                    }
  53.289 +                                }
  53.290 +                            }
  53.291 +                        }
  53.292 +                    }
  53.293 +                }
  53.294 +            }
  53.295 +        }
  53.296 +    }
  53.297 +}
  53.298 \ No newline at end of file
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/External/OxyPlot/OxyPlot/Foundation/DataPoint.cs	Sat Jun 08 16:53:22 2013 +0000
    54.3 @@ -0,0 +1,136 @@
    54.4 +// --------------------------------------------------------------------------------------------------------------------
    54.5 +// <copyright file="DataPoint.cs" company="OxyPlot">
    54.6 +//   The MIT License (MIT)
    54.7 +//
    54.8 +//   Copyright (c) 2012 Oystein Bjorke
    54.9 +//
   54.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   54.11 +//   copy of this software and associated documentation files (the
   54.12 +//   "Software"), to deal in the Software without restriction, including
   54.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   54.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   54.15 +//   permit persons to whom the Software is furnished to do so, subject to
   54.16 +//   the following conditions:
   54.17 +//
   54.18 +//   The above copyright notice and this permission notice shall be included
   54.19 +//   in all copies or substantial portions of the Software.
   54.20 +//
   54.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   54.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   54.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   54.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   54.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   54.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   54.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   54.28 +// </copyright>
   54.29 +// <summary>
   54.30 +//   DataPoint value type.
   54.31 +// </summary>
   54.32 +// --------------------------------------------------------------------------------------------------------------------
   54.33 +namespace OxyPlot
   54.34 +{
   54.35 +    using System.Diagnostics.CodeAnalysis;
   54.36 +
   54.37 +    /// <summary>
   54.38 +    /// Represents a point in the data coordinate system.
   54.39 +    /// </summary>
   54.40 +    /// <remarks>
   54.41 +    /// <see cref="DataPoint"/>s are transformed to <see cref="ScreenPoint"/>s.
   54.42 +    /// </remarks>
   54.43 +    public struct DataPoint : IDataPoint, ICodeGenerating
   54.44 +    {
   54.45 +        /// <summary>
   54.46 +        /// The undefined.
   54.47 +        /// </summary>
   54.48 +        public static readonly DataPoint Undefined = new DataPoint(double.NaN, double.NaN);
   54.49 +
   54.50 +        /// <summary>
   54.51 +        /// The x-coordinate.
   54.52 +        /// </summary>
   54.53 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
   54.54 +            Justification = "Reviewed. Suppression is OK here.")]
   54.55 +        internal double x;
   54.56 +
   54.57 +        /// <summary>
   54.58 +        /// The y-coordinate.
   54.59 +        /// </summary>
   54.60 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
   54.61 +            Justification = "Reviewed. Suppression is OK here.")]
   54.62 +        internal double y;
   54.63 +
   54.64 +        /// <summary>
   54.65 +        /// Initializes a new instance of the <see cref="DataPoint"/> struct.
   54.66 +        /// </summary>
   54.67 +        /// <param name="x">
   54.68 +        /// The x.
   54.69 +        /// </param>
   54.70 +        /// <param name="y">
   54.71 +        /// The y.
   54.72 +        /// </param>
   54.73 +        public DataPoint(double x, double y)
   54.74 +        {
   54.75 +            this.x = x;
   54.76 +            this.y = y;
   54.77 +        }
   54.78 +
   54.79 +        /// <summary>
   54.80 +        /// Gets or sets the X.
   54.81 +        /// </summary>
   54.82 +        /// <value>
   54.83 +        /// The X.
   54.84 +        /// </value>
   54.85 +        public double X
   54.86 +        {
   54.87 +            get
   54.88 +            {
   54.89 +                return this.x;
   54.90 +            }
   54.91 +
   54.92 +            set
   54.93 +            {
   54.94 +                this.x = value;
   54.95 +            }
   54.96 +        }
   54.97 +
   54.98 +        /// <summary>
   54.99 +        /// Gets or sets the Y.
  54.100 +        /// </summary>
  54.101 +        /// <value>
  54.102 +        /// The Y.
  54.103 +        /// </value>
  54.104 +        public double Y
  54.105 +        {
  54.106 +            get
  54.107 +            {
  54.108 +                return this.y;
  54.109 +            }
  54.110 +
  54.111 +            set
  54.112 +            {
  54.113 +                this.y = value;
  54.114 +            }
  54.115 +        }
  54.116 +
  54.117 +        /// <summary>
  54.118 +        /// Returns C# code that generates this instance.
  54.119 +        /// </summary>
  54.120 +        /// <returns>
  54.121 +        /// The to code.
  54.122 +        /// </returns>
  54.123 +        public string ToCode()
  54.124 +        {
  54.125 +            return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.x, this.y);
  54.126 +        }
  54.127 +
  54.128 +        /// <summary>
  54.129 +        /// Returns a <see cref="System.String"/> that represents this instance.
  54.130 +        /// </summary>
  54.131 +        /// <returns>
  54.132 +        /// A <see cref="System.String"/> that represents this instance.
  54.133 +        /// </returns>
  54.134 +        public override string ToString()
  54.135 +        {
  54.136 +            return this.x + " " + this.y;
  54.137 +        }
  54.138 +    }
  54.139 +}
  54.140 \ No newline at end of file
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/External/OxyPlot/OxyPlot/Foundation/DataPointConverter.cs	Sat Jun 08 16:53:22 2013 +0000
    55.3 @@ -0,0 +1,82 @@
    55.4 +// --------------------------------------------------------------------------------------------------------------------
    55.5 +// <copyright file="DataPointConverter.cs" company="OxyPlot">
    55.6 +//   The MIT License (MIT)
    55.7 +//
    55.8 +//   Copyright (c) 2012 Oystein Bjorke
    55.9 +//
   55.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   55.11 +//   copy of this software and associated documentation files (the
   55.12 +//   "Software"), to deal in the Software without restriction, including
   55.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   55.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   55.15 +//   permit persons to whom the Software is furnished to do so, subject to
   55.16 +//   the following conditions:
   55.17 +//
   55.18 +//   The above copyright notice and this permission notice shall be included
   55.19 +//   in all copies or substantial portions of the Software.
   55.20 +//
   55.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   55.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   55.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   55.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   55.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   55.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   55.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   55.28 +// </copyright>
   55.29 +// <summary>
   55.30 +//   The DataPoint converter.
   55.31 +// </summary>
   55.32 +// --------------------------------------------------------------------------------------------------------------------
   55.33 +namespace OxyPlot
   55.34 +{
   55.35 +    using System;
   55.36 +    using System.ComponentModel;
   55.37 +    using System.Globalization;
   55.38 +
   55.39 +    /// <summary>
   55.40 +    /// Converts a <see cref="DataPoint"/> object from one data type to another.
   55.41 +    /// </summary>
   55.42 +    public class DataPointConverter : TypeConverter
   55.43 +    {
   55.44 +        /// <summary>
   55.45 +        /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
   55.46 +        /// </summary>
   55.47 +        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
   55.48 +        /// <param name="sourceType">A <see cref="T:System.Type" /> that represents the type you want to convert from.</param>
   55.49 +        /// <returns>
   55.50 +        /// true if this converter can perform the conversion; otherwise, false.
   55.51 +        /// </returns>
   55.52 +        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
   55.53 +        {
   55.54 +            if (sourceType == typeof(string))
   55.55 +            {
   55.56 +                return true;
   55.57 +            }
   55.58 +
   55.59 +            return base.CanConvertFrom(context, sourceType);
   55.60 +        }
   55.61 +
   55.62 +        /// <summary>
   55.63 +        /// Converts the given object to the type of this converter, using the specified context and culture information.
   55.64 +        /// </summary>
   55.65 +        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
   55.66 +        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> to use as the current culture.</param>
   55.67 +        /// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
   55.68 +        /// <returns>
   55.69 +        /// An <see cref="T:System.Object" /> that represents the converted value.
   55.70 +        /// </returns>
   55.71 +        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
   55.72 +        {
   55.73 +            if (value is string)
   55.74 +            {
   55.75 +                var input = (string)value;
   55.76 +                var xy = input.Split(',');
   55.77 +                double x = double.Parse(xy[0], CultureInfo.InvariantCulture);
   55.78 +                double y = double.Parse(xy[1], CultureInfo.InvariantCulture);
   55.79 +                return new DataPoint(x, y);
   55.80 +            }
   55.81 +
   55.82 +            return base.ConvertFrom(context, culture, value);
   55.83 +        }
   55.84 +    }
   55.85 +}
   55.86 \ No newline at end of file
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/External/OxyPlot/OxyPlot/Foundation/DoubleExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
    56.3 @@ -0,0 +1,236 @@
    56.4 +// --------------------------------------------------------------------------------------------------------------------
    56.5 +// <copyright file="DoubleExtensions.cs" company="OxyPlot">
    56.6 +//   The MIT License (MIT)
    56.7 +//
    56.8 +//   Copyright (c) 2012 Oystein Bjorke
    56.9 +//
   56.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   56.11 +//   copy of this software and associated documentation files (the
   56.12 +//   "Software"), to deal in the Software without restriction, including
   56.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   56.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   56.15 +//   permit persons to whom the Software is furnished to do so, subject to
   56.16 +//   the following conditions:
   56.17 +//
   56.18 +//   The above copyright notice and this permission notice shall be included
   56.19 +//   in all copies or substantial portions of the Software.
   56.20 +//
   56.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   56.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   56.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   56.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   56.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   56.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   56.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   56.28 +// </copyright>
   56.29 +// <summary>
   56.30 +//   Extension methods for double values.
   56.31 +// </summary>
   56.32 +// --------------------------------------------------------------------------------------------------------------------
   56.33 +namespace OxyPlot
   56.34 +{
   56.35 +    using System;
   56.36 +    using System.Globalization;
   56.37 +
   56.38 +    /// <summary>
   56.39 +    /// Provides extension methods for the <see cref="Double"/> type.
   56.40 +    /// </summary>
   56.41 +    public static class DoubleExtensions
   56.42 +    {
   56.43 +        /// <summary>
   56.44 +        /// Squares the specified value.
   56.45 +        /// </summary>
   56.46 +        /// <param name="x">
   56.47 +        /// The value.
   56.48 +        /// </param>
   56.49 +        /// <returns>
   56.50 +        /// Squared value.
   56.51 +        /// </returns>
   56.52 +        public static double Squared(this double x)
   56.53 +        {
   56.54 +            return x * x;
   56.55 +        }
   56.56 +
   56.57 +        /// <summary>
   56.58 +        /// Exponent function.
   56.59 +        /// </summary>
   56.60 +        /// <param name="x">
   56.61 +        /// The value.
   56.62 +        /// </param>
   56.63 +        /// <returns>
   56.64 +        /// The exponent.
   56.65 +        /// </returns>
   56.66 +        public static double GetExponent(this double x)
   56.67 +        {
   56.68 +            return Math.Round(Math.Log(Math.Abs(x), 10));
   56.69 +        }
   56.70 +
   56.71 +        /// <summary>
   56.72 +        /// Mantissa function.
   56.73 +        /// http://en.wikipedia.org/wiki/Mantissa
   56.74 +        /// </summary>
   56.75 +        /// <param name="x">
   56.76 +        /// The value.
   56.77 +        /// </param>
   56.78 +        /// <returns>
   56.79 +        /// The mantissa.
   56.80 +        /// </returns>
   56.81 +        public static double GetMantissa(this double x)
   56.82 +        {
   56.83 +            return x / Math.Pow(10, x.GetExponent());
   56.84 +        }
   56.85 +
   56.86 +        /// <summary>
   56.87 +        /// Removes the floating point noise.
   56.88 +        /// </summary>
   56.89 +        /// <param name="value">
   56.90 +        /// The value.
   56.91 +        /// </param>
   56.92 +        /// <returns>
   56.93 +        /// A double without noise.
   56.94 +        /// </returns>
   56.95 +        public static double RemoveNoise2(this double value)
   56.96 +        {
   56.97 +            return (double)((decimal)value);
   56.98 +        }
   56.99 +
  56.100 +        /// <summary>
  56.101 +        /// Removes the floating point noise.
  56.102 +        /// </summary>
  56.103 +        /// <param name="value">
  56.104 +        /// The value.
  56.105 +        /// </param>
  56.106 +        /// <param name="maxDigits">
  56.107 +        /// The maximum number of digits.
  56.108 +        /// </param>
  56.109 +        /// <returns>
  56.110 +        /// A double without noise.
  56.111 +        /// </returns>
  56.112 +        public static double RemoveNoise(this double value, int maxDigits = 8)
  56.113 +        {
  56.114 +            return double.Parse(value.ToString("e" + maxDigits));
  56.115 +        }
  56.116 +
  56.117 +        /// <summary>
  56.118 +        /// Removes the noise from double math.
  56.119 +        /// </summary>
  56.120 +        /// <param name="value">
  56.121 +        /// The value.
  56.122 +        /// </param>
  56.123 +        /// <returns>
  56.124 +        /// A double without noise.
  56.125 +        /// </returns>
  56.126 +        public static double RemoveNoiseFromDoubleMath(this double value)
  56.127 +        {
  56.128 +            if (value.IsZero() || Math.Abs(Math.Log10(Math.Abs(value))) < 27)
  56.129 +            {
  56.130 +                return (double)((decimal)value);
  56.131 +            }
  56.132 +
  56.133 +            return double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
  56.134 +        }
  56.135 +
  56.136 +        /// <summary>
  56.137 +        /// Determines whether the specified value is zero.
  56.138 +        /// </summary>
  56.139 +        /// <param name="value">The value.</param>
  56.140 +        /// <returns>
  56.141 +        /// <c>true</c> if the specified value is zero; otherwise, <c>false</c>.
  56.142 +        /// </returns>
  56.143 +        public static bool IsZero(this double value)
  56.144 +        {
  56.145 +            return Math.Abs(value) < double.Epsilon;
  56.146 +        }
  56.147 +
  56.148 +        /// <summary>
  56.149 +        /// Calculates the nearest larger multiple of the specified value.
  56.150 +        /// </summary>
  56.151 +        /// <param name="value">
  56.152 +        /// The value.
  56.153 +        /// </param>
  56.154 +        /// <param name="step">
  56.155 +        /// The multiplier.
  56.156 +        /// </param>
  56.157 +        /// <returns>
  56.158 +        /// The multiple value.
  56.159 +        /// </returns>
  56.160 +        public static double ToUpperMultiple(this double value, double step)
  56.161 +        {
  56.162 +            var i = (int)Math.Ceiling(value / step);
  56.163 +            return (step * i).RemoveNoise();
  56.164 +        }
  56.165 +
  56.166 +        /// <summary>
  56.167 +        /// Calculates the nearest smaller multiple of the specified value.
  56.168 +        /// </summary>
  56.169 +        /// <param name="value">
  56.170 +        /// The value.
  56.171 +        /// </param>
  56.172 +        /// <param name="step">
  56.173 +        /// The multiplier.
  56.174 +        /// </param>
  56.175 +        /// <returns>
  56.176 +        /// The multiple value.
  56.177 +        /// </returns>
  56.178 +        public static double ToLowerMultiple(this double value, double step)
  56.179 +        {
  56.180 +            var i = (int)Math.Floor(value / step);
  56.181 +            return (step * i).RemoveNoise();
  56.182 +        }
  56.183 +
  56.184 +#if THISISNOTINUSE
  56.185 +
  56.186 +    // <summary>
  56.187 +    // Gets the mantissa and exponent.
  56.188 +    // </summary>
  56.189 +    /// <remarks>
  56.190 +    /// From <see cref="http://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c"/>
  56.191 +    /// </remarks>
  56.192 +    /// <param name="d">The d.</param>
  56.193 +    /// <param name="negative">if set to <c>true</c> [negative].</param>
  56.194 +    /// <param name="mantissa">The mantissa.</param>
  56.195 +    /// <param name="exponent">The exponent.</param>
  56.196 +        public static void GetMantissaAndExponent(this double d, out bool negative, out long mantissa, out int exponent)
  56.197 +        {
  56.198 +            // Translate the double into sign, exponent and mantissa.
  56.199 +            long bits = BitConverter.DoubleToInt64Bits(d);
  56.200 +
  56.201 +// Note that the shift is sign-extended, hence the test against -1 not 1
  56.202 +            negative = (bits < 0);
  56.203 +            exponent = (int)((bits >> 52) & 0x7ffL);
  56.204 +            mantissa = bits & 0xfffffffffffffL;
  56.205 +
  56.206 +            // Subnormal numbers; exponent is effectively one higher,
  56.207 +            // but there's no extra normalisation bit in the mantissa
  56.208 +            if (exponent == 0)
  56.209 +            {
  56.210 +                exponent++;
  56.211 +            }
  56.212 +
  56.213 +// Normal numbers; leave exponent as it is but add extra
  56.214 +            // bit to the front of the mantissa
  56.215 +            else
  56.216 +            {
  56.217 +                mantissa = mantissa | (1L << 52);
  56.218 +            }
  56.219 +
  56.220 +            // Bias the exponent. It's actually biased by 1023, but we're
  56.221 +            // treating the mantissa as m.0 rather than 0.m, so we need
  56.222 +            // to subtract another 52 from it.
  56.223 +            exponent -= 1075;
  56.224 +
  56.225 +            if (mantissa == 0)
  56.226 +            {
  56.227 +                return;
  56.228 +            }
  56.229 +
  56.230 +            /* Normalize */
  56.231 +            while ((mantissa & 1) == 0)
  56.232 +            {    /*  i.e., Mantissa is even */
  56.233 +                mantissa >>= 1;
  56.234 +                exponent++;
  56.235 +            }
  56.236 +        }
  56.237 +#endif
  56.238 +    }
  56.239 +}
  56.240 \ No newline at end of file
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/External/OxyPlot/OxyPlot/Foundation/FontWeights.cs	Sat Jun 08 16:53:22 2013 +0000
    57.3 @@ -0,0 +1,48 @@
    57.4 +// --------------------------------------------------------------------------------------------------------------------
    57.5 +// <copyright file="FontWeights.cs" company="OxyPlot">
    57.6 +//   The MIT License (MIT)
    57.7 +//
    57.8 +//   Copyright (c) 2012 Oystein Bjorke
    57.9 +//
   57.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   57.11 +//   copy of this software and associated documentation files (the
   57.12 +//   "Software"), to deal in the Software without restriction, including
   57.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   57.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   57.15 +//   permit persons to whom the Software is furnished to do so, subject to
   57.16 +//   the following conditions:
   57.17 +//
   57.18 +//   The above copyright notice and this permission notice shall be included
   57.19 +//   in all copies or substantial portions of the Software.
   57.20 +//
   57.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   57.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   57.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   57.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   57.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   57.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   57.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   57.28 +// </copyright>
   57.29 +// <summary>
   57.30 +//   Static font weights.
   57.31 +// </summary>
   57.32 +// --------------------------------------------------------------------------------------------------------------------
   57.33 +namespace OxyPlot
   57.34 +{
   57.35 +    /// <summary>
   57.36 +    /// Provides a set of static predefined font weight values.
   57.37 +    /// </summary>
   57.38 +    public static class FontWeights
   57.39 +    {
   57.40 +        /// <summary>
   57.41 +        /// Specifies a bold font weight.
   57.42 +        /// </summary>
   57.43 +        public const double Bold = 700;
   57.44 +
   57.45 +        /// <summary>
   57.46 +        /// Specifies a normal font weight.
   57.47 +        /// </summary>
   57.48 +        public const double Normal = 400;
   57.49 +
   57.50 +    }
   57.51 +}
   57.52 \ No newline at end of file
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/External/OxyPlot/OxyPlot/Foundation/FractionHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    58.3 @@ -0,0 +1,155 @@
    58.4 +// --------------------------------------------------------------------------------------------------------------------
    58.5 +// <copyright file="FractionHelper.cs" company="OxyPlot">
    58.6 +//   The MIT License (MIT)
    58.7 +//
    58.8 +//   Copyright (c) 2012 Oystein Bjorke
    58.9 +//
   58.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   58.11 +//   copy of this software and associated documentation files (the
   58.12 +//   "Software"), to deal in the Software without restriction, including
   58.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   58.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   58.15 +//   permit persons to whom the Software is furnished to do so, subject to
   58.16 +//   the following conditions:
   58.17 +//
   58.18 +//   The above copyright notice and this permission notice shall be included
   58.19 +//   in all copies or substantial portions of the Software.
   58.20 +//
   58.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   58.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   58.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   58.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   58.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   58.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   58.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   58.28 +// </copyright>
   58.29 +// <summary>
   58.30 +//   Generates fraction strings from double values.
   58.31 +// </summary>
   58.32 +// --------------------------------------------------------------------------------------------------------------------
   58.33 +namespace OxyPlot
   58.34 +{
   58.35 +    using System;
   58.36 +    using System.Globalization;
   58.37 +
   58.38 +    /// <summary>
   58.39 +    /// Provides functionality to generate fraction strings from double values.
   58.40 +    /// </summary>
   58.41 +    /// <remarks>
   58.42 +    /// Examples: "3/4", "PI/2"
   58.43 +    /// </remarks>
   58.44 +    public static class FractionHelper
   58.45 +    {
   58.46 +        /// <summary>
   58.47 +        /// Converts a double to a fraction string.
   58.48 +        /// </summary>
   58.49 +        /// <param name="value">
   58.50 +        /// The value.
   58.51 +        /// </param>
   58.52 +        /// <param name="unit">
   58.53 +        /// The unit.
   58.54 +        /// </param>
   58.55 +        /// <param name="unitSymbol">
   58.56 +        /// The unit symbol.
   58.57 +        /// </param>
   58.58 +        /// <param name="eps">
   58.59 +        /// The tolerance.
   58.60 +        /// </param>
   58.61 +        /// <param name="formatProvider">
   58.62 +        /// The format Provider.
   58.63 +        /// </param>
   58.64 +        /// <returns>
   58.65 +        /// The convert to fraction string.
   58.66 +        /// </returns>
   58.67 +        public static string ConvertToFractionString(
   58.68 +            double value,
   58.69 +            double unit = 1,
   58.70 +            string unitSymbol = null,
   58.71 +            double eps = 1e-6,
   58.72 +            IFormatProvider formatProvider = null)
   58.73 +        {
   58.74 +            if (Math.Abs(value) < eps)
   58.75 +            {
   58.76 +                return "0";
   58.77 +            }
   58.78 +
   58.79 +            // ½, ⅝, ¾
   58.80 +            value /= unit;
   58.81 +
   58.82 +            // int whole = (int)(value - (int) value);
   58.83 +            // int N = 10000;
   58.84 +            // int frac = (int) ((value - whole)*N);
   58.85 +            // var d = GCF(N,frac);
   58.86 +            for (int d = 1; d <= 64; d++)
   58.87 +            {
   58.88 +                double n = value * d;
   58.89 +                var ni = (int)Math.Round(n);
   58.90 +                if (Math.Abs(n - ni) < eps)
   58.91 +                {
   58.92 +                    string nis = unitSymbol == null || ni != 1 ? ni.ToString(CultureInfo.InvariantCulture) : string.Empty;
   58.93 +                    if (d == 1)
   58.94 +                    {
   58.95 +                        return string.Format("{0}{1}", nis, unitSymbol);
   58.96 +                    }
   58.97 +
   58.98 +                    return string.Format("{0}{1}/{2}", nis, unitSymbol, d);
   58.99 +                }
  58.100 +            }
  58.101 +
  58.102 +            return string.Format(formatProvider ?? CultureInfo.CurrentCulture, "{0}{1}", value, unitSymbol);
  58.103 +        }
  58.104 +
  58.105 +        /// <summary>
  58.106 +        /// Finds the greates common divisor.
  58.107 +        /// </summary>
  58.108 +        /// <param name="a">
  58.109 +        /// The a.
  58.110 +        /// </param>
  58.111 +        /// <param name="b">
  58.112 +        /// The b.
  58.113 +        /// </param>
  58.114 +        /// <returns>
  58.115 +        /// The gcd.
  58.116 +        /// </returns>
  58.117 +        public static int gcd(int a, int b)
  58.118 +        {
  58.119 +            if (b == 0)
  58.120 +            {
  58.121 +                return a;
  58.122 +            }
  58.123 +
  58.124 +            return gcd(b, a % b);
  58.125 +        }
  58.126 +
  58.127 +        /// <summary>
  58.128 +        /// Finds the greatest common factor.
  58.129 +        /// </summary>
  58.130 +        /// <param name="x">
  58.131 +        /// The x.
  58.132 +        /// </param>
  58.133 +        /// <param name="y">
  58.134 +        /// The y.
  58.135 +        /// </param>
  58.136 +        /// <returns>
  58.137 +        /// The gcf.
  58.138 +        /// </returns>
  58.139 +        private static int GCF(int x, int y)
  58.140 +        {
  58.141 +            x = Math.Abs(x);
  58.142 +            y = Math.Abs(y);
  58.143 +            int z;
  58.144 +            do
  58.145 +            {
  58.146 +                z = x % y;
  58.147 +                if (z == 0)
  58.148 +                {
  58.149 +                    return y;
  58.150 +                }
  58.151 +
  58.152 +                x = y;
  58.153 +                y = z;
  58.154 +            }
  58.155 +            while (true);
  58.156 +        }
  58.157 +    }
  58.158 +}
  58.159 \ No newline at end of file
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/External/OxyPlot/OxyPlot/Foundation/HorizontalAlignment.cs	Sat Jun 08 16:53:22 2013 +0000
    59.3 @@ -0,0 +1,52 @@
    59.4 +// --------------------------------------------------------------------------------------------------------------------
    59.5 +// <copyright file="HorizontalAlignment.cs" company="OxyPlot">
    59.6 +//   The MIT License (MIT)
    59.7 +//
    59.8 +//   Copyright (c) 2012 Oystein Bjorke
    59.9 +//
   59.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   59.11 +//   copy of this software and associated documentation files (the
   59.12 +//   "Software"), to deal in the Software without restriction, including
   59.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   59.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   59.15 +//   permit persons to whom the Software is furnished to do so, subject to
   59.16 +//   the following conditions:
   59.17 +//
   59.18 +//   The above copyright notice and this permission notice shall be included
   59.19 +//   in all copies or substantial portions of the Software.
   59.20 +//
   59.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   59.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   59.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   59.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   59.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   59.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   59.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   59.28 +// </copyright>
   59.29 +// <summary>
   59.30 +//   Horizontal text alignment.
   59.31 +// </summary>
   59.32 +// --------------------------------------------------------------------------------------------------------------------
   59.33 +namespace OxyPlot
   59.34 +{
   59.35 +    /// <summary>
   59.36 +    /// Specifies the horizontal alignment.
   59.37 +    /// </summary>
   59.38 +    public enum HorizontalAlignment
   59.39 +    {
   59.40 +        /// <summary>
   59.41 +        /// Aligned to the left.
   59.42 +        /// </summary>
   59.43 +        Left = -1,
   59.44 +
   59.45 +        /// <summary>
   59.46 +        /// Aligned in the center.
   59.47 +        /// </summary>
   59.48 +        Center = 0,
   59.49 +
   59.50 +        /// <summary>
   59.51 +        /// Aligned to the right.
   59.52 +        /// </summary>
   59.53 +        Right = 1
   59.54 +    }
   59.55 +}
   59.56 \ No newline at end of file
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/External/OxyPlot/OxyPlot/Foundation/IDataPoint.cs	Sat Jun 08 16:53:22 2013 +0000
    60.3 @@ -0,0 +1,49 @@
    60.4 +// --------------------------------------------------------------------------------------------------------------------
    60.5 +// <copyright file="IDataPoint.cs" company="OxyPlot">
    60.6 +//   The MIT License (MIT)
    60.7 +//
    60.8 +//   Copyright (c) 2012 Oystein Bjorke
    60.9 +//
   60.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   60.11 +//   copy of this software and associated documentation files (the
   60.12 +//   "Software"), to deal in the Software without restriction, including
   60.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   60.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   60.15 +//   permit persons to whom the Software is furnished to do so, subject to
   60.16 +//   the following conditions:
   60.17 +//
   60.18 +//   The above copyright notice and this permission notice shall be included
   60.19 +//   in all copies or substantial portions of the Software.
   60.20 +//
   60.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   60.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   60.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   60.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   60.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   60.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   60.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   60.28 +// </copyright>
   60.29 +// <summary>
   60.30 +//   DataPoint interface.
   60.31 +// </summary>
   60.32 +// --------------------------------------------------------------------------------------------------------------------
   60.33 +namespace OxyPlot
   60.34 +{
   60.35 +    /// <summary>
   60.36 +    /// Defines a point.
   60.37 +    /// </summary>
   60.38 +    public interface IDataPoint
   60.39 +    {
   60.40 +        /// <summary>
   60.41 +        /// Gets or sets the x-coordinate.
   60.42 +        /// </summary>
   60.43 +        /// <value>The x-coordinate.</value>
   60.44 +        double X { get; set; }
   60.45 +
   60.46 +        /// <summary>
   60.47 +        /// Gets or sets the y-coordinate.
   60.48 +        /// </summary>
   60.49 +        /// <value>The y-coordinate.</value>
   60.50 +        double Y { get; set; }
   60.51 +    }
   60.52 +}
   60.53 \ No newline at end of file
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/External/OxyPlot/OxyPlot/Foundation/IDataPointProvider.cs	Sat Jun 08 16:53:22 2013 +0000
    61.3 @@ -0,0 +1,45 @@
    61.4 +// --------------------------------------------------------------------------------------------------------------------
    61.5 +// <copyright file="IDataPointProvider.cs" company="OxyPlot">
    61.6 +//   The MIT License (MIT)
    61.7 +//
    61.8 +//   Copyright (c) 2012 Oystein Bjorke
    61.9 +//
   61.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   61.11 +//   copy of this software and associated documentation files (the
   61.12 +//   "Software"), to deal in the Software without restriction, including
   61.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   61.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   61.15 +//   permit persons to whom the Software is furnished to do so, subject to
   61.16 +//   the following conditions:
   61.17 +//
   61.18 +//   The above copyright notice and this permission notice shall be included
   61.19 +//   in all copies or substantial portions of the Software.
   61.20 +//
   61.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   61.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   61.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   61.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   61.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   61.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   61.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   61.28 +// </copyright>
   61.29 +// <summary>
   61.30 +//   Provides functionality to create data points for items in an <see cref="ItemsSeries"/>.
   61.31 +// </summary>
   61.32 +// --------------------------------------------------------------------------------------------------------------------
   61.33 +namespace OxyPlot
   61.34 +{
   61.35 +    /// <summary>
   61.36 +    /// Provides functionality to create data points.
   61.37 +    /// </summary>
   61.38 +    public interface IDataPointProvider
   61.39 +    {
   61.40 +        /// <summary>
   61.41 +        /// Gets the data point.
   61.42 +        /// </summary>
   61.43 +        /// <returns>
   61.44 +        /// The data point.
   61.45 +        /// </returns>
   61.46 +        DataPoint GetDataPoint();
   61.47 +    }
   61.48 +}
   61.49 \ No newline at end of file
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/External/OxyPlot/OxyPlot/Foundation/LineStyle.cs	Sat Jun 08 16:53:22 2013 +0000
    62.3 @@ -0,0 +1,97 @@
    62.4 +// --------------------------------------------------------------------------------------------------------------------
    62.5 +// <copyright file="LineStyle.cs" company="OxyPlot">
    62.6 +//   The MIT License (MIT)
    62.7 +//
    62.8 +//   Copyright (c) 2012 Oystein Bjorke
    62.9 +//
   62.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   62.11 +//   copy of this software and associated documentation files (the
   62.12 +//   "Software"), to deal in the Software without restriction, including
   62.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   62.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   62.15 +//   permit persons to whom the Software is furnished to do so, subject to
   62.16 +//   the following conditions:
   62.17 +//
   62.18 +//   The above copyright notice and this permission notice shall be included
   62.19 +//   in all copies or substantial portions of the Software.
   62.20 +//
   62.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   62.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   62.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   62.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   62.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   62.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   62.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   62.28 +// </copyright>
   62.29 +// <summary>
   62.30 +//   Enumeration of line styles.
   62.31 +// </summary>
   62.32 +// --------------------------------------------------------------------------------------------------------------------
   62.33 +namespace OxyPlot
   62.34 +{
   62.35 +    /// <summary>
   62.36 +    /// Specifies the style of a line.
   62.37 +    /// </summary>
   62.38 +    public enum LineStyle
   62.39 +    {
   62.40 +        /// <summary>
   62.41 +        /// The solid line style.
   62.42 +        /// </summary>
   62.43 +        Solid,
   62.44 +
   62.45 +        /// <summary>
   62.46 +        /// The dash line style.
   62.47 +        /// </summary>
   62.48 +        Dash,
   62.49 +
   62.50 +        /// <summary>
   62.51 +        /// The dot line style.
   62.52 +        /// </summary>
   62.53 +        Dot,
   62.54 +
   62.55 +        /// <summary>
   62.56 +        /// The dash dot line style.
   62.57 +        /// </summary>
   62.58 +        DashDot,
   62.59 +
   62.60 +        /// <summary>
   62.61 +        /// The dash dash dot line style.
   62.62 +        /// </summary>
   62.63 +        DashDashDot,
   62.64 +
   62.65 +        /// <summary>
   62.66 +        /// The dash dot dot line style.
   62.67 +        /// </summary>
   62.68 +        DashDotDot,
   62.69 +
   62.70 +        /// <summary>
   62.71 +        /// The dash dash dot dot line style.
   62.72 +        /// </summary>
   62.73 +        DashDashDotDot,
   62.74 +
   62.75 +        /// <summary>
   62.76 +        /// The long dash line style.
   62.77 +        /// </summary>
   62.78 +        LongDash,
   62.79 +
   62.80 +        /// <summary>
   62.81 +        /// The long dash dot line style.
   62.82 +        /// </summary>
   62.83 +        LongDashDot,
   62.84 +
   62.85 +        /// <summary>
   62.86 +        /// The long dash dot dot line style.
   62.87 +        /// </summary>
   62.88 +        LongDashDotDot,
   62.89 +
   62.90 +        /// <summary>
   62.91 +        /// The hidden line style.
   62.92 +        /// </summary>
   62.93 +        None,
   62.94 +
   62.95 +        /// <summary>
   62.96 +        /// The undefined line style.
   62.97 +        /// </summary>
   62.98 +        Undefined
   62.99 +    }
  62.100 +}
  62.101 \ No newline at end of file
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/External/OxyPlot/OxyPlot/Foundation/LineStyleHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    63.3 @@ -0,0 +1,76 @@
    63.4 +// --------------------------------------------------------------------------------------------------------------------
    63.5 +// <copyright file="LineStyleHelper.cs" company="OxyPlot">
    63.6 +//   The MIT License (MIT)
    63.7 +//
    63.8 +//   Copyright (c) 2012 Oystein Bjorke
    63.9 +//
   63.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   63.11 +//   copy of this software and associated documentation files (the
   63.12 +//   "Software"), to deal in the Software without restriction, including
   63.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   63.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   63.15 +//   permit persons to whom the Software is furnished to do so, subject to
   63.16 +//   the following conditions:
   63.17 +//
   63.18 +//   The above copyright notice and this permission notice shall be included
   63.19 +//   in all copies or substantial portions of the Software.
   63.20 +//
   63.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   63.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   63.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   63.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   63.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   63.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   63.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   63.28 +// </copyright>
   63.29 +// <summary>
   63.30 +//   Converts from LineStyle to stroke dash array.
   63.31 +// </summary>
   63.32 +// --------------------------------------------------------------------------------------------------------------------
   63.33 +namespace OxyPlot
   63.34 +{
   63.35 +    /// <summary>
   63.36 +    /// Provides functionality to convert from LineStyle to a stroke dash array.
   63.37 +    /// </summary>
   63.38 +    public static class LineStyleHelper
   63.39 +    {
   63.40 +        /// <summary>
   63.41 +        /// Gets the stroke dash array for a given <see cref="LineStyle"/>.
   63.42 +        /// </summary>
   63.43 +        /// <param name="style">
   63.44 +        /// The line style.
   63.45 +        /// </param>
   63.46 +        /// <returns>
   63.47 +        /// A dash array.
   63.48 +        /// </returns>
   63.49 +        public static double[] GetDashArray(this LineStyle style)
   63.50 +        {
   63.51 +            switch (style)
   63.52 +            {
   63.53 +                case LineStyle.Solid:
   63.54 +                    return null;
   63.55 +                case LineStyle.Dash:
   63.56 +                    return new double[] { 4, 1 };
   63.57 +                case LineStyle.Dot:
   63.58 +                    return new double[] { 1, 1 };
   63.59 +                case LineStyle.DashDot:
   63.60 +                    return new double[] { 4, 1, 1, 1 };
   63.61 +                case LineStyle.DashDashDot:
   63.62 +                    return new double[] { 4, 1, 4, 1, 1, 1 };
   63.63 +                case LineStyle.DashDotDot:
   63.64 +                    return new double[] { 4, 1, 1, 1, 1, 1 };
   63.65 +                case LineStyle.DashDashDotDot:
   63.66 +                    return new double[] { 4, 1, 4, 1, 1, 1, 1, 1 };
   63.67 +                case LineStyle.LongDash:
   63.68 +                    return new double[] { 10, 1 };
   63.69 +                case LineStyle.LongDashDot:
   63.70 +                    return new double[] { 10, 1, 1, 1 };
   63.71 +                case LineStyle.LongDashDotDot:
   63.72 +                    return new double[] { 10, 1, 1, 1, 1, 1 };
   63.73 +                default:
   63.74 +                    return null;
   63.75 +            }
   63.76 +        }
   63.77 +
   63.78 +    }
   63.79 +}
   63.80 \ No newline at end of file
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ListFiller.cs	Sat Jun 08 16:53:22 2013 +0000
    64.3 @@ -0,0 +1,145 @@
    64.4 +// --------------------------------------------------------------------------------------------------------------------
    64.5 +// <copyright file="ListFiller.cs" company="OxyPlot">
    64.6 +//   The MIT License (MIT)
    64.7 +//   
    64.8 +//   Copyright (c) 2012 Oystein Bjorke
    64.9 +//   
   64.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   64.11 +//   copy of this software and associated documentation files (the
   64.12 +//   "Software"), to deal in the Software without restriction, including
   64.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   64.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   64.15 +//   permit persons to whom the Software is furnished to do so, subject to
   64.16 +//   the following conditions:
   64.17 +//   
   64.18 +//   The above copyright notice and this permission notice shall be included
   64.19 +//   in all copies or substantial portions of the Software.
   64.20 +//   
   64.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   64.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   64.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   64.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   64.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   64.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   64.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   64.28 +// </copyright>
   64.29 +// --------------------------------------------------------------------------------------------------------------------
   64.30 +namespace OxyPlot
   64.31 +{
   64.32 +    using System;
   64.33 +    using System.Collections;
   64.34 +    using System.Collections.Generic;
   64.35 +    using System.Reflection;
   64.36 +
   64.37 +    /// <summary>
   64.38 +    ///     Provides functionality to fill a list by specified properties of another list.
   64.39 +    /// </summary>
   64.40 +    /// <remarks>
   64.41 +    ///     This class uses reflection.
   64.42 +    /// </remarks>
   64.43 +    /// <typeparam name="T">
   64.44 +    ///     The target list item type.
   64.45 +    /// </typeparam>
   64.46 +    public class ListFiller<T>
   64.47 +        where T : class, new()
   64.48 +    {
   64.49 +        /// <summary>
   64.50 +        ///     The properties.
   64.51 +        /// </summary>
   64.52 +        private readonly Dictionary<string, Action<T, object>> properties;
   64.53 +
   64.54 +        /// <summary>
   64.55 +        ///     Initializes a new instance of the <see cref="ListFiller{T}" /> class.
   64.56 +        /// </summary>
   64.57 +        public ListFiller()
   64.58 +        {
   64.59 +            this.properties = new Dictionary<string, Action<T, object>>();
   64.60 +        }
   64.61 +
   64.62 +        /// <summary>
   64.63 +        ///     Adds a setter for the specified property.
   64.64 +        /// </summary>
   64.65 +        /// <param name="propertyName">
   64.66 +        ///     Name of the property.
   64.67 +        /// </param>
   64.68 +        /// <param name="setter">
   64.69 +        ///     The setter.
   64.70 +        /// </param>
   64.71 +        public void Add(string propertyName, Action<T, object> setter)
   64.72 +        {
   64.73 +            if (string.IsNullOrEmpty(propertyName))
   64.74 +            {
   64.75 +                return;
   64.76 +            }
   64.77 +
   64.78 +            this.properties.Add(propertyName, setter);
   64.79 +        }
   64.80 +
   64.81 +        /// <summary>
   64.82 +        ///     Fills the specified target list.
   64.83 +        /// </summary>
   64.84 +        /// <param name="target">The target.</param>
   64.85 +        /// <param name="source">The source.</param>
   64.86 +        public void FillT(IList<T> target, IEnumerable source)
   64.87 +        {
   64.88 +            this.Fill((IList)target, source);
   64.89 +        }
   64.90 +
   64.91 +        /// <summary>
   64.92 +        ///     Fills the specified target list.
   64.93 +        /// </summary>
   64.94 +        /// <param name="target">
   64.95 +        ///     The target.
   64.96 +        /// </param>
   64.97 +        /// <param name="source">
   64.98 +        ///     The source list.
   64.99 +        /// </param>
  64.100 +        public void Fill(IList target, IEnumerable source)
  64.101 +        {
  64.102 +            PropertyInfo[] pi = null;
  64.103 +            Type t = null;
  64.104 +            foreach (var sourceItem in source)
  64.105 +            {
  64.106 +                if (pi == null || sourceItem.GetType() != t)
  64.107 +                {
  64.108 +                    t = sourceItem.GetType();
  64.109 +                    pi = new PropertyInfo[this.properties.Count];
  64.110 +                    int i = 0;
  64.111 +                    foreach (var p in this.properties)
  64.112 +                    {
  64.113 +                        if (string.IsNullOrEmpty(p.Key))
  64.114 +                        {
  64.115 +                            i++;
  64.116 +                            continue;
  64.117 +                        }
  64.118 +
  64.119 +                        pi[i] = t.GetProperty(p.Key);
  64.120 +                        if (pi[i] == null)
  64.121 +                        {
  64.122 +                            throw new InvalidOperationException(
  64.123 +                                string.Format("Could not find field {0} on type {1}", p.Key, t));
  64.124 +                        }
  64.125 +
  64.126 +                        i++;
  64.127 +                    }
  64.128 +                }
  64.129 +
  64.130 +                var item = new T();
  64.131 +
  64.132 +                int j = 0;
  64.133 +                foreach (var p in this.properties)
  64.134 +                {
  64.135 +                    if (pi[j] != null)
  64.136 +                    {
  64.137 +                        var value = pi[j].GetValue(sourceItem, null);
  64.138 +                        p.Value(item, value);
  64.139 +                    }
  64.140 +
  64.141 +                    j++;
  64.142 +                }
  64.143 +
  64.144 +                target.Add(item);
  64.145 +            }
  64.146 +        }       
  64.147 +    }
  64.148 +}
  64.149 \ No newline at end of file
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/External/OxyPlot/OxyPlot/Foundation/MarkerType.cs	Sat Jun 08 16:53:22 2013 +0000
    65.3 @@ -0,0 +1,91 @@
    65.4 +// --------------------------------------------------------------------------------------------------------------------
    65.5 +// <copyright file="MarkerType.cs" company="OxyPlot">
    65.6 +//   The MIT License (MIT)
    65.7 +//
    65.8 +//   Copyright (c) 2012 Oystein Bjorke
    65.9 +//
   65.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   65.11 +//   copy of this software and associated documentation files (the
   65.12 +//   "Software"), to deal in the Software without restriction, including
   65.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   65.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   65.15 +//   permit persons to whom the Software is furnished to do so, subject to
   65.16 +//   the following conditions:
   65.17 +//
   65.18 +//   The above copyright notice and this permission notice shall be included
   65.19 +//   in all copies or substantial portions of the Software.
   65.20 +//
   65.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   65.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   65.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   65.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   65.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   65.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   65.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   65.28 +// </copyright>
   65.29 +// <summary>
   65.30 +//   Enumeration of marker types.
   65.31 +// </summary>
   65.32 +// --------------------------------------------------------------------------------------------------------------------
   65.33 +namespace OxyPlot
   65.34 +{
   65.35 +    /// <summary>
   65.36 +    /// Specifies the marker type.
   65.37 +    /// </summary>
   65.38 +    public enum MarkerType
   65.39 +    {
   65.40 +        /// <summary>
   65.41 +        /// Do not render markers.
   65.42 +        /// </summary>
   65.43 +        None,
   65.44 +
   65.45 +        /// <summary>
   65.46 +        /// Render markers as circles.
   65.47 +        /// </summary>
   65.48 +        Circle,
   65.49 +
   65.50 +        /// <summary>
   65.51 +        /// Render markers as squares.
   65.52 +        /// </summary>
   65.53 +        Square,
   65.54 +
   65.55 +        /// <summary>
   65.56 +        /// Render markers as diamonds.
   65.57 +        /// </summary>
   65.58 +        Diamond,
   65.59 +
   65.60 +        /// <summary>
   65.61 +        /// Render markers as triangles.
   65.62 +        /// </summary>
   65.63 +        Triangle,
   65.64 +
   65.65 +        /// <summary>
   65.66 +        /// Render markers as crosses (note: this marker type requires the stroke color to be set).
   65.67 +        /// </summary>
   65.68 +        /// <remarks>
   65.69 +        /// This marker type requires the stroke color to be set.
   65.70 +        /// </remarks>
   65.71 +        Cross,
   65.72 +
   65.73 +        /// <summary>
   65.74 +        /// Renders markers as plus signs (note: this marker type requires the stroke color to be set).
   65.75 +        /// </summary>
   65.76 +        /// <remarks>
   65.77 +        /// This marker type requires the stroke color to be set.
   65.78 +        /// </remarks>
   65.79 +        Plus,
   65.80 +
   65.81 +        /// <summary>
   65.82 +        /// Renders markers as stars (note: this marker type requires the stroke color to be set).
   65.83 +        /// </summary>
   65.84 +        /// <remarks>
   65.85 +        /// This marker type requires the stroke color to be set.
   65.86 +        /// </remarks>
   65.87 +        Star,
   65.88 +
   65.89 +        /// <summary>
   65.90 +        /// Render markers by a custom shape (defined by outline).
   65.91 +        /// </summary>
   65.92 +        Custom
   65.93 +    }
   65.94 +}
   65.95 \ No newline at end of file
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyColor.cs	Sat Jun 08 16:53:22 2013 +0000
    66.3 @@ -0,0 +1,626 @@
    66.4 +// --------------------------------------------------------------------------------------------------------------------
    66.5 +// <copyright file="OxyColor.cs" company="OxyPlot">
    66.6 +//   The MIT License (MIT)
    66.7 +//   
    66.8 +//   Copyright (c) 2012 Oystein Bjorke
    66.9 +//   
   66.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   66.11 +//   copy of this software and associated documentation files (the
   66.12 +//   "Software"), to deal in the Software without restriction, including
   66.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   66.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   66.15 +//   permit persons to whom the Software is furnished to do so, subject to
   66.16 +//   the following conditions:
   66.17 +//   
   66.18 +//   The above copyright notice and this permission notice shall be included
   66.19 +//   in all copies or substantial portions of the Software.
   66.20 +//   
   66.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   66.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   66.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   66.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   66.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   66.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   66.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   66.28 +// </copyright>
   66.29 +// <summary>
   66.30 +//   Describes a color in terms of alpha, red, green, and blue channels.
   66.31 +// </summary>
   66.32 +// --------------------------------------------------------------------------------------------------------------------
   66.33 +namespace OxyPlot
   66.34 +{
   66.35 +    using System;
   66.36 +    using System.ComponentModel;
   66.37 +    using System.Globalization;
   66.38 +    using System.Linq;
   66.39 +    using System.Reflection;
   66.40 +
   66.41 +    /// <summary>
   66.42 +    /// Describes a color in terms of alpha, red, green, and blue channels.
   66.43 +    /// </summary>
   66.44 +    public class OxyColor : ICodeGenerating
   66.45 +    {
   66.46 +        /// <summary>
   66.47 +        /// Gets or sets the alpha value.
   66.48 +        /// </summary>
   66.49 +        /// <value> The alpha value. </value>
   66.50 +        public byte A { get; set; }
   66.51 +
   66.52 +        /// <summary>
   66.53 +        /// Gets or sets the blue value.
   66.54 +        /// </summary>
   66.55 +        /// <value> The blue value. </value>
   66.56 +        public byte B { get; set; }
   66.57 +
   66.58 +        /// <summary>
   66.59 +        /// Gets or sets the green value.
   66.60 +        /// </summary>
   66.61 +        /// <value> The green value. </value>
   66.62 +        public byte G { get; set; }
   66.63 +
   66.64 +        /// <summary>
   66.65 +        /// Gets or sets the red value.
   66.66 +        /// </summary>
   66.67 +        /// <value> The red value. </value>
   66.68 +        public byte R { get; set; }
   66.69 +
   66.70 +        /// <summary>
   66.71 +        /// Parse a string.
   66.72 +        /// </summary>
   66.73 +        /// <param name="value">
   66.74 +        /// The string in the format "#FFFFFF00" or "255,200,180,50".
   66.75 +        /// </param>
   66.76 +        /// <returns>
   66.77 +        /// The OxyColor.
   66.78 +        /// </returns>
   66.79 +        /// <exception cref="System.FormatException">
   66.80 +        /// Invalid format.
   66.81 +        /// </exception>
   66.82 +        public static OxyColor Parse(string value)
   66.83 +        {
   66.84 +            value = value.Trim();
   66.85 +            if (value.StartsWith("#"))
   66.86 +            {
   66.87 +                value = value.Trim('#');
   66.88 +                var u = uint.Parse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
   66.89 +                if (value.Length < 8)
   66.90 +                {
   66.91 +                    // alpha value was not specified
   66.92 +                    u += 0xFF000000;
   66.93 +                }
   66.94 +
   66.95 +                return FromUInt32(u);
   66.96 +            }
   66.97 +
   66.98 +            var values = value.Split(',');
   66.99 +            if (values.Length < 3 || values.Length > 4)
  66.100 +            {
  66.101 +                throw new FormatException("Invalid format.");
  66.102 +            }
  66.103 +
  66.104 +            var i = 0;
  66.105 +
  66.106 +            byte alpha = 255;
  66.107 +            if (values.Length > 3)
  66.108 +            {
  66.109 +                alpha = byte.Parse(values[i++], CultureInfo.InvariantCulture);
  66.110 +            }
  66.111 +
  66.112 +            var red = byte.Parse(values[i++], CultureInfo.InvariantCulture);
  66.113 +            var green = byte.Parse(values[i++], CultureInfo.InvariantCulture);
  66.114 +            var blue = byte.Parse(values[i], CultureInfo.InvariantCulture);
  66.115 +            return FromArgb(alpha, red, green, blue);
  66.116 +        }
  66.117 +
  66.118 +        /// <summary>
  66.119 +        /// Calculates the difference between two <see cref="OxyColor"/>s
  66.120 +        /// </summary>
  66.121 +        /// <param name="c1">
  66.122 +        /// The first color.
  66.123 +        /// </param>
  66.124 +        /// <param name="c2">
  66.125 +        /// The second color.
  66.126 +        /// </param>
  66.127 +        /// <returns>
  66.128 +        /// L2-norm in RGBA space
  66.129 +        /// </returns>
  66.130 +        public static double ColorDifference(OxyColor c1, OxyColor c2)
  66.131 +        {
  66.132 +            // http://en.wikipedia.org/wiki/OxyColor_difference
  66.133 +            // http://mathworld.wolfram.com/L2-Norm.html
  66.134 +            double dr = (c1.R - c2.R) / 255.0;
  66.135 +            double dg = (c1.G - c2.G) / 255.0;
  66.136 +            double db = (c1.B - c2.B) / 255.0;
  66.137 +            double da = (c1.A - c2.A) / 255.0;
  66.138 +            double e = (dr * dr) + (dg * dg) + (db * db) + (da * da);
  66.139 +            return Math.Sqrt(e);
  66.140 +        }
  66.141 +
  66.142 +        /// <summary>
  66.143 +        /// Convert an <see cref="uint"/> to a <see cref="OxyColor"/>.
  66.144 +        /// </summary>
  66.145 +        /// <param name="color">
  66.146 +        /// The unsigned integer color value.
  66.147 +        /// </param>
  66.148 +        /// <returns>
  66.149 +        /// The <see cref="OxyColor"/>.
  66.150 +        /// </returns>
  66.151 +        public static OxyColor FromUInt32(uint color)
  66.152 +        {
  66.153 +            var a = (byte)(color >> 24);
  66.154 +            var r = (byte)(color >> 16);
  66.155 +            var g = (byte)(color >> 8);
  66.156 +            var b = (byte)(color >> 0);
  66.157 +            return FromArgb(a, r, g, b);
  66.158 +        }
  66.159 +
  66.160 +        /// <summary>
  66.161 +        /// Creates a OxyColor from the specified HSV array.
  66.162 +        /// </summary>
  66.163 +        /// <param name="hsv">
  66.164 +        /// The HSV value array.
  66.165 +        /// </param>
  66.166 +        /// <returns>
  66.167 +        /// A OxyColor.
  66.168 +        /// </returns>
  66.169 +        public static OxyColor FromHsv(double[] hsv)
  66.170 +        {
  66.171 +            if (hsv.Length != 3)
  66.172 +            {
  66.173 +                throw new InvalidOperationException("Wrong length of hsv array.");
  66.174 +            }
  66.175 +
  66.176 +            return FromHsv(hsv[0], hsv[1], hsv[2]);
  66.177 +        }
  66.178 +
  66.179 +        /// <summary>
  66.180 +        /// Convert from HSV to <see cref="OxyColor"/>
  66.181 +        /// http://en.wikipedia.org/wiki/HSL_Color_space
  66.182 +        /// </summary>
  66.183 +        /// <param name="hue">
  66.184 +        /// The hue value [0,1]
  66.185 +        /// </param>
  66.186 +        /// <param name="sat">
  66.187 +        /// The saturation value [0,1]
  66.188 +        /// </param>
  66.189 +        /// <param name="val">
  66.190 +        /// The intensity value [0,1]
  66.191 +        /// </param>
  66.192 +        /// <returns>
  66.193 +        /// The <see cref="OxyColor"/>.
  66.194 +        /// </returns>
  66.195 +        public static OxyColor FromHsv(double hue, double sat, double val)
  66.196 +        {
  66.197 +            double g, b;
  66.198 +            double r = g = b = 0;
  66.199 +
  66.200 +            if (sat.Equals(0))
  66.201 +            {
  66.202 +                // Gray scale
  66.203 +                r = g = b = val;
  66.204 +            }
  66.205 +            else
  66.206 +            {
  66.207 +                if (hue.Equals(1))
  66.208 +                {
  66.209 +                    hue = 0;
  66.210 +                }
  66.211 +
  66.212 +                hue *= 6.0;
  66.213 +                int i = (int)Math.Floor(hue);
  66.214 +                double f = hue - i;
  66.215 +                double aa = val * (1 - sat);
  66.216 +                double bb = val * (1 - (sat * f));
  66.217 +                double cc = val * (1 - (sat * (1 - f)));
  66.218 +                switch (i)
  66.219 +                {
  66.220 +                    case 0:
  66.221 +                        r = val;
  66.222 +                        g = cc;
  66.223 +                        b = aa;
  66.224 +                        break;
  66.225 +                    case 1:
  66.226 +                        r = bb;
  66.227 +                        g = val;
  66.228 +                        b = aa;
  66.229 +                        break;
  66.230 +                    case 2:
  66.231 +                        r = aa;
  66.232 +                        g = val;
  66.233 +                        b = cc;
  66.234 +                        break;
  66.235 +                    case 3:
  66.236 +                        r = aa;
  66.237 +                        g = bb;
  66.238 +                        b = val;
  66.239 +                        break;
  66.240 +                    case 4:
  66.241 +                        r = cc;
  66.242 +                        g = aa;
  66.243 +                        b = val;
  66.244 +                        break;
  66.245 +                    case 5:
  66.246 +                        r = val;
  66.247 +                        g = aa;
  66.248 +                        b = bb;
  66.249 +                        break;
  66.250 +                }
  66.251 +            }
  66.252 +
  66.253 +            return FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
  66.254 +        }
  66.255 +
  66.256 +        /// <summary>
  66.257 +        /// Calculate the difference in hue between two <see cref="OxyColor"/>s.
  66.258 +        /// </summary>
  66.259 +        /// <param name="c1">
  66.260 +        /// The first color.
  66.261 +        /// </param>
  66.262 +        /// <param name="c2">
  66.263 +        /// The second color.
  66.264 +        /// </param>
  66.265 +        /// <returns>
  66.266 +        /// The hue difference.
  66.267 +        /// </returns>
  66.268 +        public static double HueDifference(OxyColor c1, OxyColor c2)
  66.269 +        {
  66.270 +            var hsv1 = c1.ToHsv();
  66.271 +            var hsv2 = c2.ToHsv();
  66.272 +            double dh = hsv1[0] - hsv2[0];
  66.273 +
  66.274 +            // clamp to [-0.5,0.5]
  66.275 +            if (dh > 0.5)
  66.276 +            {
  66.277 +                dh -= 1.0;
  66.278 +            }
  66.279 +
  66.280 +            if (dh < -0.5)
  66.281 +            {
  66.282 +                dh += 1.0;
  66.283 +            }
  66.284 +
  66.285 +            double e = dh * dh;
  66.286 +            return Math.Sqrt(e);
  66.287 +        }
  66.288 +
  66.289 +        /// <summary>
  66.290 +        /// Creates a color defined by an alpha value and another color.
  66.291 +        /// </summary>
  66.292 +        /// <param name="a">
  66.293 +        /// Alpha value.
  66.294 +        /// </param>
  66.295 +        /// <param name="color">
  66.296 +        /// The original color.
  66.297 +        /// </param>
  66.298 +        /// <returns>
  66.299 +        /// A color.
  66.300 +        /// </returns>
  66.301 +        public static OxyColor FromAColor(byte a, OxyColor color)
  66.302 +        {
  66.303 +            return new OxyColor { A = a, R = color.R, G = color.G, B = color.B };
  66.304 +        }
  66.305 +
  66.306 +        /// <summary>
  66.307 +        /// Creates a color from the specified ARGB values.
  66.308 +        /// </summary>
  66.309 +        /// <param name="a">
  66.310 +        /// The alpha value.
  66.311 +        /// </param>
  66.312 +        /// <param name="r">
  66.313 +        /// The red value.
  66.314 +        /// </param>
  66.315 +        /// <param name="g">
  66.316 +        /// The green value.
  66.317 +        /// </param>
  66.318 +        /// <param name="b">
  66.319 +        /// The blue value.
  66.320 +        /// </param>
  66.321 +        /// <returns>
  66.322 +        /// A color.
  66.323 +        /// </returns>
  66.324 +        public static OxyColor FromArgb(byte a, byte r, byte g, byte b)
  66.325 +        {
  66.326 +            return new OxyColor { A = a, R = r, G = g, B = b };
  66.327 +        }
  66.328 +
  66.329 +        /// <summary>
  66.330 +        /// Creates a new <see cref="OxyColor"/> structure from the specified RGB values.
  66.331 +        /// </summary>
  66.332 +        /// <param name="r">
  66.333 +        /// The red value.
  66.334 +        /// </param>
  66.335 +        /// <param name="g">
  66.336 +        /// The green value.
  66.337 +        /// </param>
  66.338 +        /// <param name="b">
  66.339 +        /// The blue value.
  66.340 +        /// </param>
  66.341 +        /// <returns>
  66.342 +        /// A <see cref="OxyColor"/> structure with the specified values and an alpha channel value of 1.
  66.343 +        /// </returns>
  66.344 +        public static OxyColor FromRgb(byte r, byte g, byte b)
  66.345 +        {
  66.346 +            // ReSharper restore InconsistentNaming
  66.347 +            return new OxyColor { A = 255, R = r, G = g, B = b };
  66.348 +        }
  66.349 +
  66.350 +        /// <summary>
  66.351 +        /// Interpolates the specified colors.
  66.352 +        /// </summary>
  66.353 +        /// <param name="color1">
  66.354 +        /// The color1.
  66.355 +        /// </param>
  66.356 +        /// <param name="color2">
  66.357 +        /// The color2.
  66.358 +        /// </param>
  66.359 +        /// <param name="t">
  66.360 +        /// The t.
  66.361 +        /// </param>
  66.362 +        /// <returns>
  66.363 +        /// The interpolated color
  66.364 +        /// </returns>
  66.365 +        public static OxyColor Interpolate(OxyColor color1, OxyColor color2, double t)
  66.366 +        {
  66.367 +            double a = (color1.A * (1 - t)) + (color2.A * t);
  66.368 +            double r = (color1.R * (1 - t)) + (color2.R * t);
  66.369 +            double g = (color1.G * (1 - t)) + (color2.G * t);
  66.370 +            double b = (color1.B * (1 - t)) + (color2.B * t);
  66.371 +            return FromArgb((byte)a, (byte)r, (byte)g, (byte)b);
  66.372 +        }
  66.373 +
  66.374 +        /// <summary>
  66.375 +        /// Convert OxyColor to double string.
  66.376 +        /// </summary>
  66.377 +        /// <returns>
  66.378 +        /// A OxyColor string, e.g. "255,200,180,50".
  66.379 +        /// </returns>
  66.380 +        public string ToByteString()
  66.381 +        {
  66.382 +            return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", this.A, this.R, this.G, this.B);
  66.383 +        }
  66.384 +
  66.385 +        /// <summary>
  66.386 +        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
  66.387 +        /// </summary>
  66.388 +        /// <param name="obj">
  66.389 +        /// The <see cref="System.Object"/> to compare with this instance.
  66.390 +        /// </param>
  66.391 +        /// <returns>
  66.392 +        /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c> .
  66.393 +        /// </returns>
  66.394 +        public override bool Equals(object obj)
  66.395 +        {
  66.396 +            if (ReferenceEquals(null, obj))
  66.397 +            {
  66.398 +                return false;
  66.399 +            }
  66.400 +
  66.401 +            if (ReferenceEquals(this, obj))
  66.402 +            {
  66.403 +                return true;
  66.404 +            }
  66.405 +
  66.406 +            if (obj.GetType() != typeof(OxyColor))
  66.407 +            {
  66.408 +                return false;
  66.409 +            }
  66.410 +
  66.411 +            return this.Equals((OxyColor)obj);
  66.412 +        }
  66.413 +
  66.414 +        /// <summary>
  66.415 +        /// Determines whether the specified <see cref="OxyColor"/> is equal to this instance.
  66.416 +        /// </summary>
  66.417 +        /// <param name="other">
  66.418 +        /// The <see cref="OxyColor"/> to compare with this instance.
  66.419 +        /// </param>
  66.420 +        /// <returns>
  66.421 +        /// <c>true</c> if the specified <see cref="OxyColor"/> is equal to this instance; otherwise, <c>false</c> .
  66.422 +        /// </returns>
  66.423 +        public bool Equals(OxyColor other)
  66.424 +        {
  66.425 +            if (ReferenceEquals(null, other))
  66.426 +            {
  66.427 +                return false;
  66.428 +            }
  66.429 +
  66.430 +            if (ReferenceEquals(this, other))
  66.431 +            {
  66.432 +                return true;
  66.433 +            }
  66.434 +
  66.435 +            return other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B;
  66.436 +        }
  66.437 +
  66.438 +        /// <summary>
  66.439 +        /// Gets the color name.
  66.440 +        /// </summary>
  66.441 +        /// <returns>
  66.442 +        /// The color name.
  66.443 +        /// </returns>
  66.444 +        public string GetColorName()
  66.445 +        {
  66.446 +            var t = typeof(OxyColors);
  66.447 +            var colors = t.GetFields(BindingFlags.Public | BindingFlags.Static);
  66.448 +            var colorField = colors.FirstOrDefault(
  66.449 +                field =>
  66.450 +                {
  66.451 +                    var color = field.GetValue(null);
  66.452 +                    return this.Equals(color);
  66.453 +                });
  66.454 +            return colorField != null ? colorField.Name : null;
  66.455 +        }
  66.456 +
  66.457 +        /// <summary>
  66.458 +        /// Returns a hash code for this instance.
  66.459 +        /// </summary>
  66.460 +        /// <returns>
  66.461 +        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
  66.462 +        /// </returns>
  66.463 +        public override int GetHashCode()
  66.464 +        {
  66.465 +            unchecked
  66.466 +            {
  66.467 +                int result = this.A.GetHashCode();
  66.468 +                result = (result * 397) ^ this.R.GetHashCode();
  66.469 +                result = (result * 397) ^ this.G.GetHashCode();
  66.470 +                result = (result * 397) ^ this.B.GetHashCode();
  66.471 +                return result;
  66.472 +            }
  66.473 +        }
  66.474 +
  66.475 +        /// <summary>
  66.476 +        /// Returns a <see cref="System.String"/> that represents this instance.
  66.477 +        /// </summary>
  66.478 +        /// <returns>
  66.479 +        /// A <see cref="System.String"/> that represents this instance.
  66.480 +        /// </returns>
  66.481 +        public override string ToString()
  66.482 +        {
  66.483 +            return string.Format(
  66.484 +                CultureInfo.InvariantCulture, "#{0:x2}{1:x2}{2:x2}{3:x2}", this.A, this.R, this.G, this.B);
  66.485 +        }
  66.486 +
  66.487 +        /// <summary>
  66.488 +        /// Changes the opacity value.
  66.489 +        /// </summary>
  66.490 +        /// <param name="newAlpha">
  66.491 +        /// The new alpha.
  66.492 +        /// </param>
  66.493 +        /// <returns>
  66.494 +        /// The new color.
  66.495 +        /// </returns>
  66.496 +        public OxyColor ChangeAlpha(byte newAlpha)
  66.497 +        {
  66.498 +            return FromArgb(newAlpha, this.R, this.G, this.B);
  66.499 +        }
  66.500 +
  66.501 +        /// <summary>
  66.502 +        /// Calculates the complementary OxyColor.
  66.503 +        /// </summary>
  66.504 +        /// <returns>
  66.505 +        /// The complementary OxyColor.
  66.506 +        /// </returns>
  66.507 +        public OxyColor Complementary()
  66.508 +        {
  66.509 +            // http://en.wikipedia.org/wiki/Complementary_Color
  66.510 +            var hsv = this.ToHsv();
  66.511 +            double newHue = hsv[0] - 0.5;
  66.512 +
  66.513 +            // clamp to [0,1]
  66.514 +            if (newHue < 0)
  66.515 +            {
  66.516 +                newHue += 1.0;
  66.517 +            }
  66.518 +
  66.519 +            return FromHsv(newHue, hsv[1], hsv[2]);
  66.520 +        }
  66.521 +
  66.522 +        /// <summary>
  66.523 +        /// Converts from a <see cref="OxyColor"/> to HSV values (double)
  66.524 +        /// </summary>
  66.525 +        /// <returns>
  66.526 +        /// Array of [Hue,Saturation,Value] in the range [0,1]
  66.527 +        /// </returns>
  66.528 +        public double[] ToHsv()
  66.529 +        {
  66.530 +            byte r = this.R;
  66.531 +            byte g = this.G;
  66.532 +            byte b = this.B;
  66.533 +
  66.534 +            byte min = Math.Min(Math.Min(r, g), b);
  66.535 +            byte v = Math.Max(Math.Max(r, g), b);
  66.536 +            double delta = v - min;
  66.537 +
  66.538 +            double s = v.Equals(0) ? 0 : delta / v;
  66.539 +            double h = 0;
  66.540 +
  66.541 +            if (s.Equals(0))
  66.542 +            {
  66.543 +                h = 0.0;
  66.544 +            }
  66.545 +            else
  66.546 +            {
  66.547 +                if (r == v)
  66.548 +                {
  66.549 +                    h = (g - b) / delta;
  66.550 +                }
  66.551 +                else if (g == v)
  66.552 +                {
  66.553 +                    h = 2 + ((b - r) / delta);
  66.554 +                }
  66.555 +                else if (b == v)
  66.556 +                {
  66.557 +                    h = 4 + ((r - g) / delta);
  66.558 +                }
  66.559 +
  66.560 +                h *= 60;
  66.561 +                if (h < 0.0)
  66.562 +                {
  66.563 +                    h += 360;
  66.564 +                }
  66.565 +            }
  66.566 +
  66.567 +            var hsv = new double[3];
  66.568 +            hsv[0] = h / 360.0;
  66.569 +            hsv[1] = s;
  66.570 +            hsv[2] = v / 255.0;
  66.571 +            return hsv;
  66.572 +        }
  66.573 +
  66.574 +        /// <summary>
  66.575 +        /// Changes the intensity.
  66.576 +        /// </summary>
  66.577 +        /// <param name="factor">
  66.578 +        /// The factor.
  66.579 +        /// </param>
  66.580 +        /// <returns>
  66.581 +        /// The new OxyColor.
  66.582 +        /// </returns>
  66.583 +        public OxyColor ChangeIntensity(double factor)
  66.584 +        {
  66.585 +            var hsv = this.ToHsv();
  66.586 +            hsv[2] *= factor;
  66.587 +            if (hsv[2] > 1.0)
  66.588 +            {
  66.589 +                hsv[2] = 1.0;
  66.590 +            }
  66.591 +
  66.592 +            return FromHsv(hsv);
  66.593 +        }
  66.594 +
  66.595 +        /// <summary>
  66.596 +        /// Converts to an unsigned integer.
  66.597 +        /// </summary>
  66.598 +        /// <returns>
  66.599 +        /// The <see cref="uint"/>.
  66.600 +        /// </returns>
  66.601 +        public uint ToUint()
  66.602 +        {
  66.603 +            uint u = (uint)this.A << 24;
  66.604 +            u += (uint)this.R << 16;
  66.605 +            u += (uint)this.G << 8;
  66.606 +            u += this.B;
  66.607 +            return u;
  66.608 +
  66.609 +            // (UInt32)((UInt32)c.A << 24 + (UInt32)c.R << 16 + (UInt32)c.G << 8 + (UInt32)c.B);
  66.610 +        }
  66.611 +
  66.612 +        /// <summary>
  66.613 +        /// Returns C# code that generates this instance.
  66.614 +        /// </summary>
  66.615 +        /// <returns>
  66.616 +        /// The to code.
  66.617 +        /// </returns>
  66.618 +        public string ToCode()
  66.619 +        {
  66.620 +            string name = this.GetColorName();
  66.621 +            if (name != null)
  66.622 +            {
  66.623 +                return string.Format("OxyColors.{0}", name);
  66.624 +            }
  66.625 +
  66.626 +            return string.Format("OxyColor.FromArgb({0}, {1}, {2}, {3})", this.A, this.R, this.G, this.B);
  66.627 +        }
  66.628 +    }
  66.629 +}
  66.630 \ No newline at end of file
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyColorConverter.cs	Sat Jun 08 16:53:22 2013 +0000
    67.3 @@ -0,0 +1,135 @@
    67.4 +// --------------------------------------------------------------------------------------------------------------------
    67.5 +// <copyright file="OxyColorConverter.cs" company="OxyPlot">
    67.6 +//   The MIT License (MIT)
    67.7 +//   
    67.8 +//   Copyright (c) 2012 Oystein Bjorke
    67.9 +//   
   67.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   67.11 +//   copy of this software and associated documentation files (the
   67.12 +//   "Software"), to deal in the Software without restriction, including
   67.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   67.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   67.15 +//   permit persons to whom the Software is furnished to do so, subject to
   67.16 +//   the following conditions:
   67.17 +//   
   67.18 +//   The above copyright notice and this permission notice shall be included
   67.19 +//   in all copies or substantial portions of the Software.
   67.20 +//   
   67.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   67.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   67.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   67.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   67.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   67.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   67.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   67.28 +// </copyright>
   67.29 +// <summary>
   67.30 +//   Converts colors from one data type to another. Access this class through the TypeDescriptor.
   67.31 +// </summary>
   67.32 +// --------------------------------------------------------------------------------------------------------------------
   67.33 +namespace OxyPlot
   67.34 +{
   67.35 +    using System;
   67.36 +    using System.ComponentModel;
   67.37 +    using System.Globalization;
   67.38 +
   67.39 +    /// <summary>
   67.40 +    /// Converts between <see cref="OxyColor"/> and <see cref="System.String"/>. Access this class through the TypeDescriptor.
   67.41 +    /// </summary>
   67.42 +    public class OxyColorConverter : TypeConverter
   67.43 +    {
   67.44 +        /// <summary>
   67.45 +        /// Determines whether an object can be converted from a given type to an instance of a <see cref="OxyColor"/>.
   67.46 +        /// </summary>
   67.47 +        /// <param name="context">
   67.48 +        /// Describes the context information of a type.
   67.49 +        /// </param>
   67.50 +        /// <param name="sourceType">
   67.51 +        /// The type of the source that is being evaluated for conversion.
   67.52 +        /// </param>
   67.53 +        /// <returns>
   67.54 +        /// True if the type can be converted to a <see cref="OxyColor"/>; otherwise, false.
   67.55 +        /// </returns>
   67.56 +        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
   67.57 +        {
   67.58 +            return (sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType);
   67.59 +        }
   67.60 +
   67.61 +        /// <summary>
   67.62 +        /// Determines whether an instance of a <see cref="OxyColor"/> can be converted to a different type.
   67.63 +        /// </summary>
   67.64 +        /// <param name="context">
   67.65 +        /// Describes the context information of a type.
   67.66 +        /// </param>
   67.67 +        /// <param name="destinationType">
   67.68 +        /// The desired type this <see cref="OxyColor"/> is being evaluated for conversion.
   67.69 +        /// </param>
   67.70 +        /// <returns>
   67.71 +        /// True if this <see cref="OxyColor"/> can be converted to destinationType; otherwise, false.
   67.72 +        /// </returns>
   67.73 +        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
   67.74 +        {
   67.75 +            return (destinationType == typeof(string)) || base.CanConvertTo(context, destinationType);
   67.76 +        }
   67.77 +
   67.78 +        /// <summary>
   67.79 +        /// Attempts to convert the specified object to a <see cref="OxyColor"/>.
   67.80 +        /// </summary>
   67.81 +        /// <param name="context">
   67.82 +        /// Describes the context information of a type.
   67.83 +        /// </param>
   67.84 +        /// <param name="culture">
   67.85 +        /// Cultural information to respect during conversion.
   67.86 +        /// </param>
   67.87 +        /// <param name="value">
   67.88 +        /// The object being converted.
   67.89 +        /// </param>
   67.90 +        /// <returns>
   67.91 +        /// The <see cref="OxyColor"/> created from converting value.
   67.92 +        /// </returns>
   67.93 +        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
   67.94 +        {
   67.95 +            var str = value as string;
   67.96 +            if (str == null)
   67.97 +            {
   67.98 +                return base.ConvertFrom(context, culture, value);
   67.99 +            }
  67.100 +
  67.101 +            return OxyColor.Parse(str);
  67.102 +        }
  67.103 +
  67.104 +        /// <summary>
  67.105 +        /// Attempts to convert a <see cref="OxyColor"/> to a specified type.
  67.106 +        /// </summary>
  67.107 +        /// <param name="context">
  67.108 +        /// Describes the context information of a type.
  67.109 +        /// </param>
  67.110 +        /// <param name="culture">
  67.111 +        /// Describes the <see cref="CultureInfo"/> of the type being converted.
  67.112 +        /// </param>
  67.113 +        /// <param name="value">
  67.114 +        /// The <see cref="OxyColor"/> to convert.
  67.115 +        /// </param>
  67.116 +        /// <param name="destinationType">
  67.117 +        /// The type to convert this <see cref="OxyColor"/> to.
  67.118 +        /// </param>
  67.119 +        /// <returns>
  67.120 +        /// The object created from converting this <see cref="OxyColor"/>.
  67.121 +        /// </returns>
  67.122 +        public override object ConvertTo(
  67.123 +            ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  67.124 +        {
  67.125 +            if (destinationType == null)
  67.126 +            {
  67.127 +                throw new ArgumentNullException("destinationType");
  67.128 +            }
  67.129 +
  67.130 +            if (destinationType == typeof(string))
  67.131 +            {
  67.132 +                return value != null ? value.ToString() : null;
  67.133 +            }
  67.134 +
  67.135 +            return base.ConvertTo(context, culture, value, destinationType);
  67.136 +        }
  67.137 +    }
  67.138 +}
  67.139 \ No newline at end of file
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyColors.cs	Sat Jun 08 16:53:22 2013 +0000
    68.3 @@ -0,0 +1,743 @@
    68.4 +// --------------------------------------------------------------------------------------------------------------------
    68.5 +// <copyright file="OxyColors.cs" company="OxyPlot">
    68.6 +//   The MIT License (MIT)
    68.7 +//
    68.8 +//   Copyright (c) 2012 Oystein Bjorke
    68.9 +//
   68.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   68.11 +//   copy of this software and associated documentation files (the
   68.12 +//   "Software"), to deal in the Software without restriction, including
   68.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   68.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   68.15 +//   permit persons to whom the Software is furnished to do so, subject to
   68.16 +//   the following conditions:
   68.17 +//
   68.18 +//   The above copyright notice and this permission notice shall be included
   68.19 +//   in all copies or substantial portions of the Software.
   68.20 +//
   68.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   68.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   68.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   68.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   68.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   68.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   68.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   68.28 +// </copyright>
   68.29 +// <summary>
   68.30 +//   Implements a set of predefined colors.
   68.31 +// </summary>
   68.32 +// --------------------------------------------------------------------------------------------------------------------
   68.33 +namespace OxyPlot
   68.34 +{
   68.35 +    /// <summary>
   68.36 +    /// Implements a set of predefined colors.
   68.37 +    /// </summary>
   68.38 +    public static class OxyColors
   68.39 +    {
   68.40 +        /// <summary>
   68.41 +        /// The alice blue.
   68.42 +        /// </summary>
   68.43 +        public static readonly OxyColor AliceBlue = OxyColor.FromUInt32(0xFFF0F8FF);
   68.44 +
   68.45 +        /// <summary>
   68.46 +        /// The antique white.
   68.47 +        /// </summary>
   68.48 +        public static readonly OxyColor AntiqueWhite = OxyColor.FromUInt32(0xFFFAEBD7);
   68.49 +
   68.50 +        /// <summary>
   68.51 +        /// The aqua.
   68.52 +        /// </summary>
   68.53 +        public static readonly OxyColor Aqua = OxyColor.FromUInt32(0xFF00FFFF);
   68.54 +
   68.55 +        /// <summary>
   68.56 +        /// The aquamarine.
   68.57 +        /// </summary>
   68.58 +        public static readonly OxyColor Aquamarine = OxyColor.FromUInt32(0xFF7FFFD4);
   68.59 +
   68.60 +        /// <summary>
   68.61 +        /// The azure.
   68.62 +        /// </summary>
   68.63 +        public static readonly OxyColor Azure = OxyColor.FromUInt32(0xFFF0FFFF);
   68.64 +
   68.65 +        /// <summary>
   68.66 +        /// The beige.
   68.67 +        /// </summary>
   68.68 +        public static readonly OxyColor Beige = OxyColor.FromUInt32(0xFFF5F5DC);
   68.69 +
   68.70 +        /// <summary>
   68.71 +        /// The bisque.
   68.72 +        /// </summary>
   68.73 +        public static readonly OxyColor Bisque = OxyColor.FromUInt32(0xFFFFE4C4);
   68.74 +
   68.75 +        /// <summary>
   68.76 +        /// The black.
   68.77 +        /// </summary>
   68.78 +        public static readonly OxyColor Black = OxyColor.FromUInt32(0xFF000000);
   68.79 +
   68.80 +        /// <summary>
   68.81 +        /// The blanched almond.
   68.82 +        /// </summary>
   68.83 +        public static readonly OxyColor BlanchedAlmond = OxyColor.FromUInt32(0xFFFFEBCD);
   68.84 +
   68.85 +        /// <summary>
   68.86 +        /// The blue.
   68.87 +        /// </summary>
   68.88 +        public static readonly OxyColor Blue = OxyColor.FromUInt32(0xFF0000FF);
   68.89 +
   68.90 +        /// <summary>
   68.91 +        /// The blue violet.
   68.92 +        /// </summary>
   68.93 +        public static readonly OxyColor BlueViolet = OxyColor.FromUInt32(0xFF8A2BE2);
   68.94 +
   68.95 +        /// <summary>
   68.96 +        /// The brown.
   68.97 +        /// </summary>
   68.98 +        public static readonly OxyColor Brown = OxyColor.FromUInt32(0xFFA52A2A);
   68.99 +
  68.100 +        /// <summary>
  68.101 +        /// The burly wood.
  68.102 +        /// </summary>
  68.103 +        public static readonly OxyColor BurlyWood = OxyColor.FromUInt32(0xFFDEB887);
  68.104 +
  68.105 +        /// <summary>
  68.106 +        /// The cadet blue.
  68.107 +        /// </summary>
  68.108 +        public static readonly OxyColor CadetBlue = OxyColor.FromUInt32(0xFF5F9EA0);
  68.109 +
  68.110 +        /// <summary>
  68.111 +        /// The chartreuse.
  68.112 +        /// </summary>
  68.113 +        public static readonly OxyColor Chartreuse = OxyColor.FromUInt32(0xFF7FFF00);
  68.114 +
  68.115 +        /// <summary>
  68.116 +        /// The chocolate.
  68.117 +        /// </summary>
  68.118 +        public static readonly OxyColor Chocolate = OxyColor.FromUInt32(0xFFD2691E);
  68.119 +
  68.120 +        /// <summary>
  68.121 +        /// The coral.
  68.122 +        /// </summary>
  68.123 +        public static readonly OxyColor Coral = OxyColor.FromUInt32(0xFFFF7F50);
  68.124 +
  68.125 +        /// <summary>
  68.126 +        /// The cornflower blue.
  68.127 +        /// </summary>
  68.128 +        public static readonly OxyColor CornflowerBlue = OxyColor.FromUInt32(0xFF6495ED);
  68.129 +
  68.130 +        /// <summary>
  68.131 +        /// The cornsilk.
  68.132 +        /// </summary>
  68.133 +        public static readonly OxyColor Cornsilk = OxyColor.FromUInt32(0xFFFFF8DC);
  68.134 +
  68.135 +        /// <summary>
  68.136 +        /// The crimson.
  68.137 +        /// </summary>
  68.138 +        public static readonly OxyColor Crimson = OxyColor.FromUInt32(0xFFDC143C);
  68.139 +
  68.140 +        /// <summary>
  68.141 +        /// The cyan.
  68.142 +        /// </summary>
  68.143 +        public static readonly OxyColor Cyan = OxyColor.FromUInt32(0xFF00FFFF);
  68.144 +
  68.145 +        /// <summary>
  68.146 +        /// The dark blue.
  68.147 +        /// </summary>
  68.148 +        public static readonly OxyColor DarkBlue = OxyColor.FromUInt32(0xFF00008B);
  68.149 +
  68.150 +        /// <summary>
  68.151 +        /// The dark cyan.
  68.152 +        /// </summary>
  68.153 +        public static readonly OxyColor DarkCyan = OxyColor.FromUInt32(0xFF008B8B);
  68.154 +
  68.155 +        /// <summary>
  68.156 +        /// The dark goldenrod.
  68.157 +        /// </summary>
  68.158 +        public static readonly OxyColor DarkGoldenrod = OxyColor.FromUInt32(0xFFB8860B);
  68.159 +
  68.160 +        /// <summary>
  68.161 +        /// The dark gray.
  68.162 +        /// </summary>
  68.163 +        public static readonly OxyColor DarkGray = OxyColor.FromUInt32(0xFFA9A9A9);
  68.164 +
  68.165 +        /// <summary>
  68.166 +        /// The dark green.
  68.167 +        /// </summary>
  68.168 +        public static readonly OxyColor DarkGreen = OxyColor.FromUInt32(0xFF006400);
  68.169 +
  68.170 +        /// <summary>
  68.171 +        /// The dark khaki.
  68.172 +        /// </summary>
  68.173 +        public static readonly OxyColor DarkKhaki = OxyColor.FromUInt32(0xFFBDB76B);
  68.174 +
  68.175 +        /// <summary>
  68.176 +        /// The dark magenta.
  68.177 +        /// </summary>
  68.178 +        public static readonly OxyColor DarkMagenta = OxyColor.FromUInt32(0xFF8B008B);
  68.179 +
  68.180 +        /// <summary>
  68.181 +        /// The dark olive green.
  68.182 +        /// </summary>
  68.183 +        public static readonly OxyColor DarkOliveGreen = OxyColor.FromUInt32(0xFF556B2F);
  68.184 +
  68.185 +        /// <summary>
  68.186 +        /// The dark orange.
  68.187 +        /// </summary>
  68.188 +        public static readonly OxyColor DarkOrange = OxyColor.FromUInt32(0xFFFF8C00);
  68.189 +
  68.190 +        /// <summary>
  68.191 +        /// The dark orchid.
  68.192 +        /// </summary>
  68.193 +        public static readonly OxyColor DarkOrchid = OxyColor.FromUInt32(0xFF9932CC);
  68.194 +
  68.195 +        /// <summary>
  68.196 +        /// The dark red.
  68.197 +        /// </summary>
  68.198 +        public static readonly OxyColor DarkRed = OxyColor.FromUInt32(0xFF8B0000);
  68.199 +
  68.200 +        /// <summary>
  68.201 +        /// The dark salmon.
  68.202 +        /// </summary>
  68.203 +        public static readonly OxyColor DarkSalmon = OxyColor.FromUInt32(0xFFE9967A);
  68.204 +
  68.205 +        /// <summary>
  68.206 +        /// The dark sea green.
  68.207 +        /// </summary>
  68.208 +        public static readonly OxyColor DarkSeaGreen = OxyColor.FromUInt32(0xFF8FBC8F);
  68.209 +
  68.210 +        /// <summary>
  68.211 +        /// The dark slate blue.
  68.212 +        /// </summary>
  68.213 +        public static readonly OxyColor DarkSlateBlue = OxyColor.FromUInt32(0xFF483D8B);
  68.214 +
  68.215 +        /// <summary>
  68.216 +        /// The dark slate gray.
  68.217 +        /// </summary>
  68.218 +        public static readonly OxyColor DarkSlateGray = OxyColor.FromUInt32(0xFF2F4F4F);
  68.219 +
  68.220 +        /// <summary>
  68.221 +        /// The dark turquoise.
  68.222 +        /// </summary>
  68.223 +        public static readonly OxyColor DarkTurquoise = OxyColor.FromUInt32(0xFF00CED1);
  68.224 +
  68.225 +        /// <summary>
  68.226 +        /// The dark violet.
  68.227 +        /// </summary>
  68.228 +        public static readonly OxyColor DarkViolet = OxyColor.FromUInt32(0xFF9400D3);
  68.229 +
  68.230 +        /// <summary>
  68.231 +        /// The deep pink.
  68.232 +        /// </summary>
  68.233 +        public static readonly OxyColor DeepPink = OxyColor.FromUInt32(0xFFFF1493);
  68.234 +
  68.235 +        /// <summary>
  68.236 +        /// The deep sky blue.
  68.237 +        /// </summary>
  68.238 +        public static readonly OxyColor DeepSkyBlue = OxyColor.FromUInt32(0xFF00BFFF);
  68.239 +
  68.240 +        /// <summary>
  68.241 +        /// The dim gray.
  68.242 +        /// </summary>
  68.243 +        public static readonly OxyColor DimGray = OxyColor.FromUInt32(0xFF696969);
  68.244 +
  68.245 +        /// <summary>
  68.246 +        /// The dodger blue.
  68.247 +        /// </summary>
  68.248 +        public static readonly OxyColor DodgerBlue = OxyColor.FromUInt32(0xFF1E90FF);
  68.249 +
  68.250 +        /// <summary>
  68.251 +        /// The firebrick.
  68.252 +        /// </summary>
  68.253 +        public static readonly OxyColor Firebrick = OxyColor.FromUInt32(0xFFB22222);
  68.254 +
  68.255 +        /// <summary>
  68.256 +        /// The floral white.
  68.257 +        /// </summary>
  68.258 +        public static readonly OxyColor FloralWhite = OxyColor.FromUInt32(0xFFFFFAF0);
  68.259 +
  68.260 +        /// <summary>
  68.261 +        /// The forest green.
  68.262 +        /// </summary>
  68.263 +        public static readonly OxyColor ForestGreen = OxyColor.FromUInt32(0xFF228B22);
  68.264 +
  68.265 +        /// <summary>
  68.266 +        /// The fuchsia.
  68.267 +        /// </summary>
  68.268 +        public static readonly OxyColor Fuchsia = OxyColor.FromUInt32(0xFFFF00FF);
  68.269 +
  68.270 +        /// <summary>
  68.271 +        /// The gainsboro.
  68.272 +        /// </summary>
  68.273 +        public static readonly OxyColor Gainsboro = OxyColor.FromUInt32(0xFFDCDCDC);
  68.274 +
  68.275 +        /// <summary>
  68.276 +        /// The ghost white.
  68.277 +        /// </summary>
  68.278 +        public static readonly OxyColor GhostWhite = OxyColor.FromUInt32(0xFFF8F8FF);
  68.279 +
  68.280 +        /// <summary>
  68.281 +        /// The gold.
  68.282 +        /// </summary>
  68.283 +        public static readonly OxyColor Gold = OxyColor.FromUInt32(0xFFFFD700);
  68.284 +
  68.285 +        /// <summary>
  68.286 +        /// The goldenrod.
  68.287 +        /// </summary>
  68.288 +        public static readonly OxyColor Goldenrod = OxyColor.FromUInt32(0xFFDAA520);
  68.289 +
  68.290 +        /// <summary>
  68.291 +        /// The gray.
  68.292 +        /// </summary>
  68.293 +        public static readonly OxyColor Gray = OxyColor.FromUInt32(0xFF808080);
  68.294 +
  68.295 +        /// <summary>
  68.296 +        /// The green.
  68.297 +        /// </summary>
  68.298 +        public static readonly OxyColor Green = OxyColor.FromUInt32(0xFF008000);
  68.299 +
  68.300 +        /// <summary>
  68.301 +        /// The green yellow.
  68.302 +        /// </summary>
  68.303 +        public static readonly OxyColor GreenYellow = OxyColor.FromUInt32(0xFFADFF2F);
  68.304 +
  68.305 +        /// <summary>
  68.306 +        /// The honeydew.
  68.307 +        /// </summary>
  68.308 +        public static readonly OxyColor Honeydew = OxyColor.FromUInt32(0xFFF0FFF0);
  68.309 +
  68.310 +        /// <summary>
  68.311 +        /// The hot pink.
  68.312 +        /// </summary>
  68.313 +        public static readonly OxyColor HotPink = OxyColor.FromUInt32(0xFFFF69B4);
  68.314 +
  68.315 +        /// <summary>
  68.316 +        /// The indian red.
  68.317 +        /// </summary>
  68.318 +        public static readonly OxyColor IndianRed = OxyColor.FromUInt32(0xFFCD5C5C);
  68.319 +
  68.320 +        /// <summary>
  68.321 +        /// The indigo.
  68.322 +        /// </summary>
  68.323 +        public static readonly OxyColor Indigo = OxyColor.FromUInt32(0xFF4B0082);
  68.324 +
  68.325 +        /// <summary>
  68.326 +        /// The ivory.
  68.327 +        /// </summary>
  68.328 +        public static readonly OxyColor Ivory = OxyColor.FromUInt32(0xFFFFFFF0);
  68.329 +
  68.330 +        /// <summary>
  68.331 +        /// The khaki.
  68.332 +        /// </summary>
  68.333 +        public static readonly OxyColor Khaki = OxyColor.FromUInt32(0xFFF0E68C);
  68.334 +
  68.335 +        /// <summary>
  68.336 +        /// The lavender.
  68.337 +        /// </summary>
  68.338 +        public static readonly OxyColor Lavender = OxyColor.FromUInt32(0xFFE6E6FA);
  68.339 +
  68.340 +        /// <summary>
  68.341 +        /// The lavender blush.
  68.342 +        /// </summary>
  68.343 +        public static readonly OxyColor LavenderBlush = OxyColor.FromUInt32(0xFFFFF0F5);
  68.344 +
  68.345 +        /// <summary>
  68.346 +        /// The lawn green.
  68.347 +        /// </summary>
  68.348 +        public static readonly OxyColor LawnGreen = OxyColor.FromUInt32(0xFF7CFC00);
  68.349 +
  68.350 +        /// <summary>
  68.351 +        /// The lemon chiffon.
  68.352 +        /// </summary>
  68.353 +        public static readonly OxyColor LemonChiffon = OxyColor.FromUInt32(0xFFFFFACD);
  68.354 +
  68.355 +        /// <summary>
  68.356 +        /// The light blue.
  68.357 +        /// </summary>
  68.358 +        public static readonly OxyColor LightBlue = OxyColor.FromUInt32(0xFFADD8E6);
  68.359 +
  68.360 +        /// <summary>
  68.361 +        /// The light coral.
  68.362 +        /// </summary>
  68.363 +        public static readonly OxyColor LightCoral = OxyColor.FromUInt32(0xFFF08080);
  68.364 +
  68.365 +        /// <summary>
  68.366 +        /// The light cyan.
  68.367 +        /// </summary>
  68.368 +        public static readonly OxyColor LightCyan = OxyColor.FromUInt32(0xFFE0FFFF);
  68.369 +
  68.370 +        /// <summary>
  68.371 +        /// The light goldenrod yellow.
  68.372 +        /// </summary>
  68.373 +        public static readonly OxyColor LightGoldenrodYellow = OxyColor.FromUInt32(0xFFFAFAD2);
  68.374 +
  68.375 +        /// <summary>
  68.376 +        /// The light gray.
  68.377 +        /// </summary>
  68.378 +        public static readonly OxyColor LightGray = OxyColor.FromUInt32(0xFFD3D3D3);
  68.379 +
  68.380 +        /// <summary>
  68.381 +        /// The light green.
  68.382 +        /// </summary>
  68.383 +        public static readonly OxyColor LightGreen = OxyColor.FromUInt32(0xFF90EE90);
  68.384 +
  68.385 +        /// <summary>
  68.386 +        /// The light pink.
  68.387 +        /// </summary>
  68.388 +        public static readonly OxyColor LightPink = OxyColor.FromUInt32(0xFFFFB6C1);
  68.389 +
  68.390 +        /// <summary>
  68.391 +        /// The light salmon.
  68.392 +        /// </summary>
  68.393 +        public static readonly OxyColor LightSalmon = OxyColor.FromUInt32(0xFFFFA07A);
  68.394 +
  68.395 +        /// <summary>
  68.396 +        /// The light sea green.
  68.397 +        /// </summary>
  68.398 +        public static readonly OxyColor LightSeaGreen = OxyColor.FromUInt32(0xFF20B2AA);
  68.399 +
  68.400 +        /// <summary>
  68.401 +        /// The light sky blue.
  68.402 +        /// </summary>
  68.403 +        public static readonly OxyColor LightSkyBlue = OxyColor.FromUInt32(0xFF87CEFA);
  68.404 +
  68.405 +        /// <summary>
  68.406 +        /// The light slate gray.
  68.407 +        /// </summary>
  68.408 +        public static readonly OxyColor LightSlateGray = OxyColor.FromUInt32(0xFF778899);
  68.409 +
  68.410 +        /// <summary>
  68.411 +        /// The light steel blue.
  68.412 +        /// </summary>
  68.413 +        public static readonly OxyColor LightSteelBlue = OxyColor.FromUInt32(0xFFB0C4DE);
  68.414 +
  68.415 +        /// <summary>
  68.416 +        /// The light yellow.
  68.417 +        /// </summary>
  68.418 +        public static readonly OxyColor LightYellow = OxyColor.FromUInt32(0xFFFFFFE0);
  68.419 +
  68.420 +        /// <summary>
  68.421 +        /// The lime.
  68.422 +        /// </summary>
  68.423 +        public static readonly OxyColor Lime = OxyColor.FromUInt32(0xFF00FF00);
  68.424 +
  68.425 +        /// <summary>
  68.426 +        /// The lime green.
  68.427 +        /// </summary>
  68.428 +        public static readonly OxyColor LimeGreen = OxyColor.FromUInt32(0xFF32CD32);
  68.429 +
  68.430 +        /// <summary>
  68.431 +        /// The linen.
  68.432 +        /// </summary>
  68.433 +        public static readonly OxyColor Linen = OxyColor.FromUInt32(0xFFFAF0E6);
  68.434 +
  68.435 +        /// <summary>
  68.436 +        /// The magenta.
  68.437 +        /// </summary>
  68.438 +        public static readonly OxyColor Magenta = OxyColor.FromUInt32(0xFFFF00FF);
  68.439 +
  68.440 +        /// <summary>
  68.441 +        /// The maroon.
  68.442 +        /// </summary>
  68.443 +        public static readonly OxyColor Maroon = OxyColor.FromUInt32(0xFF800000);
  68.444 +
  68.445 +        /// <summary>
  68.446 +        /// The medium aquamarine.
  68.447 +        /// </summary>
  68.448 +        public static readonly OxyColor MediumAquamarine = OxyColor.FromUInt32(0xFF66CDAA);
  68.449 +
  68.450 +        /// <summary>
  68.451 +        /// The medium blue.
  68.452 +        /// </summary>
  68.453 +        public static readonly OxyColor MediumBlue = OxyColor.FromUInt32(0xFF0000CD);
  68.454 +
  68.455 +        /// <summary>
  68.456 +        /// The medium orchid.
  68.457 +        /// </summary>
  68.458 +        public static readonly OxyColor MediumOrchid = OxyColor.FromUInt32(0xFFBA55D3);
  68.459 +
  68.460 +        /// <summary>
  68.461 +        /// The medium purple.
  68.462 +        /// </summary>
  68.463 +        public static readonly OxyColor MediumPurple = OxyColor.FromUInt32(0xFF9370DB);
  68.464 +
  68.465 +        /// <summary>
  68.466 +        /// The medium sea green.
  68.467 +        /// </summary>
  68.468 +        public static readonly OxyColor MediumSeaGreen = OxyColor.FromUInt32(0xFF3CB371);
  68.469 +
  68.470 +        /// <summary>
  68.471 +        /// The medium slate blue.
  68.472 +        /// </summary>
  68.473 +        public static readonly OxyColor MediumSlateBlue = OxyColor.FromUInt32(0xFF7B68EE);
  68.474 +
  68.475 +        /// <summary>
  68.476 +        /// The medium spring green.
  68.477 +        /// </summary>
  68.478 +        public static readonly OxyColor MediumSpringGreen = OxyColor.FromUInt32(0xFF00FA9A);
  68.479 +
  68.480 +        /// <summary>
  68.481 +        /// The medium turquoise.
  68.482 +        /// </summary>
  68.483 +        public static readonly OxyColor MediumTurquoise = OxyColor.FromUInt32(0xFF48D1CC);
  68.484 +
  68.485 +        /// <summary>
  68.486 +        /// The medium violet red.
  68.487 +        /// </summary>
  68.488 +        public static readonly OxyColor MediumVioletRed = OxyColor.FromUInt32(0xFFC71585);
  68.489 +
  68.490 +        /// <summary>
  68.491 +        /// The midnight blue.
  68.492 +        /// </summary>
  68.493 +        public static readonly OxyColor MidnightBlue = OxyColor.FromUInt32(0xFF191970);
  68.494 +
  68.495 +        /// <summary>
  68.496 +        /// The mint cream.
  68.497 +        /// </summary>
  68.498 +        public static readonly OxyColor MintCream = OxyColor.FromUInt32(0xFFF5FFFA);
  68.499 +
  68.500 +        /// <summary>
  68.501 +        /// The misty rose.
  68.502 +        /// </summary>
  68.503 +        public static readonly OxyColor MistyRose = OxyColor.FromUInt32(0xFFFFE4E1);
  68.504 +
  68.505 +        /// <summary>
  68.506 +        /// The moccasin.
  68.507 +        /// </summary>
  68.508 +        public static readonly OxyColor Moccasin = OxyColor.FromUInt32(0xFFFFE4B5);
  68.509 +
  68.510 +        /// <summary>
  68.511 +        /// The navajo white.
  68.512 +        /// </summary>
  68.513 +        public static readonly OxyColor NavajoWhite = OxyColor.FromUInt32(0xFFFFDEAD);
  68.514 +
  68.515 +        /// <summary>
  68.516 +        /// The navy.
  68.517 +        /// </summary>
  68.518 +        public static readonly OxyColor Navy = OxyColor.FromUInt32(0xFF000080);
  68.519 +
  68.520 +        /// <summary>
  68.521 +        /// The old lace.
  68.522 +        /// </summary>
  68.523 +        public static readonly OxyColor OldLace = OxyColor.FromUInt32(0xFFFDF5E6);
  68.524 +
  68.525 +        /// <summary>
  68.526 +        /// The olive.
  68.527 +        /// </summary>
  68.528 +        public static readonly OxyColor Olive = OxyColor.FromUInt32(0xFF808000);
  68.529 +
  68.530 +        /// <summary>
  68.531 +        /// The olive drab.
  68.532 +        /// </summary>
  68.533 +        public static readonly OxyColor OliveDrab = OxyColor.FromUInt32(0xFF6B8E23);
  68.534 +
  68.535 +        /// <summary>
  68.536 +        /// The orange.
  68.537 +        /// </summary>
  68.538 +        public static readonly OxyColor Orange = OxyColor.FromUInt32(0xFFFFA500);
  68.539 +
  68.540 +        /// <summary>
  68.541 +        /// The orange red.
  68.542 +        /// </summary>
  68.543 +        public static readonly OxyColor OrangeRed = OxyColor.FromUInt32(0xFFFF4500);
  68.544 +
  68.545 +        /// <summary>
  68.546 +        /// The orchid.
  68.547 +        /// </summary>
  68.548 +        public static readonly OxyColor Orchid = OxyColor.FromUInt32(0xFFDA70D6);
  68.549 +
  68.550 +        /// <summary>
  68.551 +        /// The pale goldenrod.
  68.552 +        /// </summary>
  68.553 +        public static readonly OxyColor PaleGoldenrod = OxyColor.FromUInt32(0xFFEEE8AA);
  68.554 +
  68.555 +        /// <summary>
  68.556 +        /// The pale green.
  68.557 +        /// </summary>
  68.558 +        public static readonly OxyColor PaleGreen = OxyColor.FromUInt32(0xFF98FB98);
  68.559 +
  68.560 +        /// <summary>
  68.561 +        /// The pale turquoise.
  68.562 +        /// </summary>
  68.563 +        public static readonly OxyColor PaleTurquoise = OxyColor.FromUInt32(0xFFAFEEEE);
  68.564 +
  68.565 +        /// <summary>
  68.566 +        /// The pale violet red.
  68.567 +        /// </summary>
  68.568 +        public static readonly OxyColor PaleVioletRed = OxyColor.FromUInt32(0xFFDB7093);
  68.569 +
  68.570 +        /// <summary>
  68.571 +        /// The papaya whip.
  68.572 +        /// </summary>
  68.573 +        public static readonly OxyColor PapayaWhip = OxyColor.FromUInt32(0xFFFFEFD5);
  68.574 +
  68.575 +        /// <summary>
  68.576 +        /// The peach puff.
  68.577 +        /// </summary>
  68.578 +        public static readonly OxyColor PeachPuff = OxyColor.FromUInt32(0xFFFFDAB9);
  68.579 +
  68.580 +        /// <summary>
  68.581 +        /// The peru.
  68.582 +        /// </summary>
  68.583 +        public static readonly OxyColor Peru = OxyColor.FromUInt32(0xFFCD853F);
  68.584 +
  68.585 +        /// <summary>
  68.586 +        /// The pink.
  68.587 +        /// </summary>
  68.588 +        public static readonly OxyColor Pink = OxyColor.FromUInt32(0xFFFFC0CB);
  68.589 +
  68.590 +        /// <summary>
  68.591 +        /// The plum.
  68.592 +        /// </summary>
  68.593 +        public static readonly OxyColor Plum = OxyColor.FromUInt32(0xFFDDA0DD);
  68.594 +
  68.595 +        /// <summary>
  68.596 +        /// The powder blue.
  68.597 +        /// </summary>
  68.598 +        public static readonly OxyColor PowderBlue = OxyColor.FromUInt32(0xFFB0E0E6);
  68.599 +
  68.600 +        /// <summary>
  68.601 +        /// The purple.
  68.602 +        /// </summary>
  68.603 +        public static readonly OxyColor Purple = OxyColor.FromUInt32(0xFF800080);
  68.604 +
  68.605 +        /// <summary>
  68.606 +        /// The red.
  68.607 +        /// </summary>
  68.608 +        public static readonly OxyColor Red = OxyColor.FromUInt32(0xFFFF0000);
  68.609 +
  68.610 +        /// <summary>
  68.611 +        /// The rosy brown.
  68.612 +        /// </summary>
  68.613 +        public static readonly OxyColor RosyBrown = OxyColor.FromUInt32(0xFFBC8F8F);
  68.614 +
  68.615 +        /// <summary>
  68.616 +        /// The royal blue.
  68.617 +        /// </summary>
  68.618 +        public static readonly OxyColor RoyalBlue = OxyColor.FromUInt32(0xFF4169E1);
  68.619 +
  68.620 +        /// <summary>
  68.621 +        /// The saddle brown.
  68.622 +        /// </summary>
  68.623 +        public static readonly OxyColor SaddleBrown = OxyColor.FromUInt32(0xFF8B4513);
  68.624 +
  68.625 +        /// <summary>
  68.626 +        /// The salmon.
  68.627 +        /// </summary>
  68.628 +        public static readonly OxyColor Salmon = OxyColor.FromUInt32(0xFFFA8072);
  68.629 +
  68.630 +        /// <summary>
  68.631 +        /// The sandy brown.
  68.632 +        /// </summary>
  68.633 +        public static readonly OxyColor SandyBrown = OxyColor.FromUInt32(0xFFF4A460);
  68.634 +
  68.635 +        /// <summary>
  68.636 +        /// The sea green.
  68.637 +        /// </summary>
  68.638 +        public static readonly OxyColor SeaGreen = OxyColor.FromUInt32(0xFF2E8B57);
  68.639 +
  68.640 +        /// <summary>
  68.641 +        /// The sea shell.
  68.642 +        /// </summary>
  68.643 +        public static readonly OxyColor SeaShell = OxyColor.FromUInt32(0xFFFFF5EE);
  68.644 +
  68.645 +        /// <summary>
  68.646 +        /// The sienna.
  68.647 +        /// </summary>
  68.648 +        public static readonly OxyColor Sienna = OxyColor.FromUInt32(0xFFA0522D);
  68.649 +
  68.650 +        /// <summary>
  68.651 +        /// The silver.
  68.652 +        /// </summary>
  68.653 +        public static readonly OxyColor Silver = OxyColor.FromUInt32(0xFFC0C0C0);
  68.654 +
  68.655 +        /// <summary>
  68.656 +        /// The sky blue.
  68.657 +        /// </summary>
  68.658 +        public static readonly OxyColor SkyBlue = OxyColor.FromUInt32(0xFF87CEEB);
  68.659 +
  68.660 +        /// <summary>
  68.661 +        /// The slate blue.
  68.662 +        /// </summary>
  68.663 +        public static readonly OxyColor SlateBlue = OxyColor.FromUInt32(0xFF6A5ACD);
  68.664 +
  68.665 +        /// <summary>
  68.666 +        /// The slate gray.
  68.667 +        /// </summary>
  68.668 +        public static readonly OxyColor SlateGray = OxyColor.FromUInt32(0xFF708090);
  68.669 +
  68.670 +        /// <summary>
  68.671 +        /// The snow.
  68.672 +        /// </summary>
  68.673 +        public static readonly OxyColor Snow = OxyColor.FromUInt32(0xFFFFFAFA);
  68.674 +
  68.675 +        /// <summary>
  68.676 +        /// The spring green.
  68.677 +        /// </summary>
  68.678 +        public static readonly OxyColor SpringGreen = OxyColor.FromUInt32(0xFF00FF7F);
  68.679 +
  68.680 +        /// <summary>
  68.681 +        /// The steel blue.
  68.682 +        /// </summary>
  68.683 +        public static readonly OxyColor SteelBlue = OxyColor.FromUInt32(0xFF4682B4);
  68.684 +
  68.685 +        /// <summary>
  68.686 +        /// The tan.
  68.687 +        /// </summary>
  68.688 +        public static readonly OxyColor Tan = OxyColor.FromUInt32(0xFFD2B48C);
  68.689 +
  68.690 +        /// <summary>
  68.691 +        /// The teal.
  68.692 +        /// </summary>
  68.693 +        public static readonly OxyColor Teal = OxyColor.FromUInt32(0xFF008080);
  68.694 +
  68.695 +        /// <summary>
  68.696 +        /// The thistle.
  68.697 +        /// </summary>
  68.698 +        public static readonly OxyColor Thistle = OxyColor.FromUInt32(0xFFD8BFD8);
  68.699 +
  68.700 +        /// <summary>
  68.701 +        /// The tomato.
  68.702 +        /// </summary>
  68.703 +        public static readonly OxyColor Tomato = OxyColor.FromUInt32(0xFFFF6347);
  68.704 +
  68.705 +        /// <summary>
  68.706 +        /// The transparent.
  68.707 +        /// </summary>
  68.708 +        public static readonly OxyColor Transparent = OxyColor.FromUInt32(0x00FFFFFF);
  68.709 +
  68.710 +        /// <summary>
  68.711 +        /// The turquoise.
  68.712 +        /// </summary>
  68.713 +        public static readonly OxyColor Turquoise = OxyColor.FromUInt32(0xFF40E0D0);
  68.714 +
  68.715 +        /// <summary>
  68.716 +        /// The violet.
  68.717 +        /// </summary>
  68.718 +        public static readonly OxyColor Violet = OxyColor.FromUInt32(0xFFEE82EE);
  68.719 +
  68.720 +        /// <summary>
  68.721 +        /// The wheat.
  68.722 +        /// </summary>
  68.723 +        public static readonly OxyColor Wheat = OxyColor.FromUInt32(0xFFF5DEB3);
  68.724 +
  68.725 +        /// <summary>
  68.726 +        /// The white.
  68.727 +        /// </summary>
  68.728 +        public static readonly OxyColor White = OxyColor.FromUInt32(0xFFFFFFFF);
  68.729 +
  68.730 +        /// <summary>
  68.731 +        /// The white smoke.
  68.732 +        /// </summary>
  68.733 +        public static readonly OxyColor WhiteSmoke = OxyColor.FromUInt32(0xFFF5F5F5);
  68.734 +
  68.735 +        /// <summary>
  68.736 +        /// The yellow.
  68.737 +        /// </summary>
  68.738 +        public static readonly OxyColor Yellow = OxyColor.FromUInt32(0xFFFFFF00);
  68.739 +
  68.740 +        /// <summary>
  68.741 +        /// The yellow green.
  68.742 +        /// </summary>
  68.743 +        public static readonly OxyColor YellowGreen = OxyColor.FromUInt32(0xFF9ACD32);
  68.744 +
  68.745 +    }
  68.746 +}
  68.747 \ No newline at end of file
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyImage.cs	Sat Jun 08 16:53:22 2013 +0000
    69.3 @@ -0,0 +1,444 @@
    69.4 +// --------------------------------------------------------------------------------------------------------------------
    69.5 +// <copyright file="OxyImage.cs" company="OxyPlot">
    69.6 +//   The MIT License (MIT)
    69.7 +//   
    69.8 +//   Copyright (c) 2012 Oystein Bjorke
    69.9 +//   
   69.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   69.11 +//   copy of this software and associated documentation files (the
   69.12 +//   "Software"), to deal in the Software without restriction, including
   69.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   69.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   69.15 +//   permit persons to whom the Software is furnished to do so, subject to
   69.16 +//   the following conditions:
   69.17 +//   
   69.18 +//   The above copyright notice and this permission notice shall be included
   69.19 +//   in all copies or substantial portions of the Software.
   69.20 +//   
   69.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   69.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   69.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   69.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   69.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   69.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   69.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   69.28 +// </copyright>
   69.29 +// <summary>
   69.30 +//   Represents an image, encoded as DIB, JPEG or PNG.
   69.31 +// </summary>
   69.32 +// --------------------------------------------------------------------------------------------------------------------
   69.33 +namespace OxyPlot
   69.34 +{
   69.35 +    using System;
   69.36 +    using System.IO;
   69.37 +    using System.Linq;
   69.38 +
   69.39 +    /// <summary>
   69.40 +    /// Represents an image, encoded as DIB, JPEG or PNG.
   69.41 +    /// </summary>
   69.42 +    public class OxyImage
   69.43 +    {
   69.44 +        /// <summary>
   69.45 +        /// The image data.
   69.46 +        /// </summary>
   69.47 +        private readonly byte[] data;
   69.48 +
   69.49 +        /// <summary>
   69.50 +        /// Initializes a new instance of the <see cref="OxyImage"/> class from the specified stream.
   69.51 +        /// </summary>
   69.52 +        /// <param name="s">
   69.53 +        /// A stream that provides the image data.
   69.54 +        /// </param>
   69.55 +        public OxyImage(Stream s)
   69.56 +        {
   69.57 +            using (var ms = new MemoryStream())
   69.58 +            {
   69.59 +                s.CopyTo(ms);
   69.60 +                this.data = ms.ToArray();
   69.61 +            }
   69.62 +        }
   69.63 +
   69.64 +        /// <summary>
   69.65 +        /// Initializes a new instance of the <see cref="OxyImage"/> class from a byte array.
   69.66 +        /// </summary>
   69.67 +        /// <param name="bytes">
   69.68 +        /// The image bytes.
   69.69 +        /// </param>
   69.70 +        public OxyImage(byte[] bytes)
   69.71 +        {
   69.72 +            this.data = bytes;
   69.73 +        }
   69.74 +
   69.75 +        /// <summary>
   69.76 +        /// Creates an <see cref="OxyImage"/> from the specified <see cref="OxyColor"/> array.
   69.77 +        /// </summary>
   69.78 +        /// <param name="data">
   69.79 +        /// The pixel data, indexed as [row,column] (from bottom-left).
   69.80 +        /// </param>
   69.81 +        /// <param name="dpi">
   69.82 +        /// The resolution.
   69.83 +        /// </param>
   69.84 +        /// <returns>
   69.85 +        /// An <see cref="OxyImage"/>.
   69.86 +        /// </returns>
   69.87 +        /// <remarks>
   69.88 +        /// This method is creating a simple BitmapInfoHeader.
   69.89 +        /// </remarks>
   69.90 +        public static OxyImage FromArgbX(OxyColor[,] data, int dpi = 96)
   69.91 +        {
   69.92 +            int height = data.GetLength(0);
   69.93 +            int width = data.GetLength(1);
   69.94 +            var bytes = new byte[width * height * 4];
   69.95 +            int k = 0;
   69.96 +            for (int i = 0; i < height; i++)
   69.97 +            {
   69.98 +                for (int j = 0; j < width; j++)
   69.99 +                {
  69.100 +                    bytes[k++] = data[i, j].B;
  69.101 +                    bytes[k++] = data[i, j].G;
  69.102 +                    bytes[k++] = data[i, j].R;
  69.103 +                    bytes[k++] = data[i, j].A;
  69.104 +                }
  69.105 +            }
  69.106 +
  69.107 +            return FromArgbX(width, height, bytes, dpi);
  69.108 +        }
  69.109 +
  69.110 +        /// <summary>
  69.111 +        /// Creates an <see cref="OxyImage"/> from the specified <see cref="OxyColor"/> array.
  69.112 +        /// </summary>
  69.113 +        /// <param name="data">
  69.114 +        /// The pixel data, indexed as [row,column] (from bottom-left).
  69.115 +        /// </param>
  69.116 +        /// <param name="dpi">
  69.117 +        /// The resolution.
  69.118 +        /// </param>
  69.119 +        /// <returns>
  69.120 +        /// An <see cref="OxyImage"/>.
  69.121 +        /// </returns>
  69.122 +        /// <remarks>
  69.123 +        /// This method is creating a Bitmap V4 info header, including channel bit masks and color space information.
  69.124 +        /// </remarks>
  69.125 +        public static OxyImage FromArgb(OxyColor[,] data, int dpi = 96)
  69.126 +        {
  69.127 +            int height = data.GetLength(0);
  69.128 +            int width = data.GetLength(1);
  69.129 +            var bytes = new byte[width * height * 4];
  69.130 +            int k = 0;
  69.131 +            for (int i = 0; i < height; i++)
  69.132 +            {
  69.133 +                for (int j = 0; j < width; j++)
  69.134 +                {
  69.135 +                    bytes[k++] = data[i, j].B;
  69.136 +                    bytes[k++] = data[i, j].G;
  69.137 +                    bytes[k++] = data[i, j].R;
  69.138 +                    bytes[k++] = data[i, j].A;
  69.139 +                }
  69.140 +            }
  69.141 +
  69.142 +            return FromArgb(width, height, bytes, dpi);
  69.143 +        }
  69.144 +
  69.145 +        /// <summary>
  69.146 +        /// Creates an <see cref="OxyImage"/> from the specified pixel data.
  69.147 +        /// </summary>
  69.148 +        /// <param name="width">
  69.149 +        /// The width.
  69.150 +        /// </param>
  69.151 +        /// <param name="height">
  69.152 +        /// The height.
  69.153 +        /// </param>
  69.154 +        /// <param name="pixelData">
  69.155 +        /// The pixel data (BGRA from bottom-left).
  69.156 +        /// </param>
  69.157 +        /// <param name="dpi">
  69.158 +        /// The resolution.
  69.159 +        /// </param>
  69.160 +        /// <returns>
  69.161 +        /// An <see cref="OxyImage"/>.
  69.162 +        /// </returns>
  69.163 +        /// <remarks>
  69.164 +        /// This method is creating a Bitmap V4 info header, including channel bit masks and color space information.
  69.165 +        /// </remarks>
  69.166 +        public static OxyImage FromArgb(int width, int height, byte[] pixelData, int dpi = 96)
  69.167 +        {
  69.168 +            var ms = new MemoryStream();
  69.169 +            var w = new BinaryWriter(ms);
  69.170 +
  69.171 +            const int OffBits = 14 + 108;
  69.172 +            var size = OffBits + pixelData.Length;
  69.173 +
  69.174 +            // Bitmap file header (14 bytes)
  69.175 +            w.Write((byte)'B');
  69.176 +            w.Write((byte)'M');
  69.177 +            w.Write((uint)size);
  69.178 +            w.Write((ushort)0);
  69.179 +            w.Write((ushort)0);
  69.180 +            w.Write((uint)OffBits);
  69.181 +
  69.182 +            // Bitmap V4 info header (108 bytes)
  69.183 +            WriteBitmapV4Header(w, width, height, 32, pixelData.Length, dpi);
  69.184 +
  69.185 +            // Pixel array (from bottom-left corner)
  69.186 +            w.Write(pixelData);
  69.187 +
  69.188 +            return new OxyImage(ms.ToArray());
  69.189 +        }
  69.190 +
  69.191 +        /// <summary>
  69.192 +        /// Creates an <see cref="OxyImage"/> from the specified 8-bit indexed pixel data.
  69.193 +        /// </summary>
  69.194 +        /// <param name="indexedData">
  69.195 +        /// The indexed pixel data (from bottom-left).
  69.196 +        /// </param>
  69.197 +        /// <param name="palette">
  69.198 +        /// The palette.
  69.199 +        /// </param>
  69.200 +        /// <param name="dpi">
  69.201 +        /// The resolution.
  69.202 +        /// </param>
  69.203 +        /// <returns>
  69.204 +        /// An <see cref="OxyImage"/>.
  69.205 +        /// </returns>
  69.206 +        public static OxyImage FromIndexed8(byte[,] indexedData, OxyColor[] palette, int dpi = 96)
  69.207 +        {
  69.208 +            int height = indexedData.GetLength(0);
  69.209 +            int width = indexedData.GetLength(1);
  69.210 +            return FromIndexed8(width, height, indexedData.Cast<byte>().ToArray(), palette, dpi);
  69.211 +        }
  69.212 +
  69.213 +        /// <summary>
  69.214 +        /// Creates an <see cref="OxyImage"/> from the specified 8-bit indexed pixel data.
  69.215 +        /// </summary>
  69.216 +        /// <param name="width">
  69.217 +        /// The width.
  69.218 +        /// </param>
  69.219 +        /// <param name="height">
  69.220 +        /// The height.
  69.221 +        /// </param>
  69.222 +        /// <param name="indexedPixelData">
  69.223 +        /// The indexed pixel data (from bottom-left).
  69.224 +        /// </param>
  69.225 +        /// <param name="palette">
  69.226 +        /// The palette.
  69.227 +        /// </param>
  69.228 +        /// <param name="dpi">
  69.229 +        /// The resolution.
  69.230 +        /// </param>
  69.231 +        /// <returns>
  69.232 +        /// An <see cref="OxyImage"/>.
  69.233 +        /// </returns>
  69.234 +        public static OxyImage FromIndexed8(
  69.235 +            int width, int height, byte[] indexedPixelData, OxyColor[] palette, int dpi = 96)
  69.236 +        {
  69.237 +            if (indexedPixelData.Length != width * height)
  69.238 +            {
  69.239 +                throw new ArgumentException("Length of data is not correct.", "indexedPixelData");
  69.240 +            }
  69.241 +
  69.242 +            if (palette.Length == 0)
  69.243 +            {
  69.244 +                throw new ArgumentException("Palette not defined.", "palette");
  69.245 +            }
  69.246 +
  69.247 +            var ms = new MemoryStream();
  69.248 +            var w = new BinaryWriter(ms);
  69.249 +
  69.250 +            var offBits = 14 + 40 + (4 * palette.Length);
  69.251 +            var size = offBits + indexedPixelData.Length;
  69.252 +
  69.253 +            // Bitmap file header (14 bytes)
  69.254 +            w.Write((byte)'B');
  69.255 +            w.Write((byte)'M');
  69.256 +            w.Write((uint)size);
  69.257 +            w.Write((ushort)0);
  69.258 +            w.Write((ushort)0);
  69.259 +            w.Write((uint)offBits);
  69.260 +
  69.261 +            // Bitmap info header
  69.262 +            WriteBitmapInfoHeader(w, width, height, 8, indexedPixelData.Length, dpi, palette.Length);
  69.263 +
  69.264 +            // Color table
  69.265 +            foreach (var color in palette)
  69.266 +            {
  69.267 +                w.Write(color.B);
  69.268 +                w.Write(color.G);
  69.269 +                w.Write(color.R);
  69.270 +                w.Write(color.A);
  69.271 +            }
  69.272 +
  69.273 +            // Pixel array (from bottom-left corner)
  69.274 +            w.Write(indexedPixelData);
  69.275 +
  69.276 +            return new OxyImage(ms.ToArray());
  69.277 +        }
  69.278 +
  69.279 +        /// <summary>
  69.280 +        /// Creates an <see cref="OxyImage"/> from the specified pixel data.
  69.281 +        /// </summary>
  69.282 +        /// <param name="width">
  69.283 +        /// The width.
  69.284 +        /// </param>
  69.285 +        /// <param name="height">
  69.286 +        /// The height.
  69.287 +        /// </param>
  69.288 +        /// <param name="pixelData">
  69.289 +        /// The pixel data (BGRA from bottom-left).
  69.290 +        /// </param>
  69.291 +        /// <param name="dpi">
  69.292 +        /// The resolution.
  69.293 +        /// </param>
  69.294 +        /// <returns>
  69.295 +        /// An <see cref="OxyImage"/>.
  69.296 +        /// </returns>
  69.297 +        /// <remarks>
  69.298 +        /// This method is creating a simple BitmapInfoHeader.
  69.299 +        /// </remarks>
  69.300 +        public static OxyImage FromArgbX(int width, int height, byte[] pixelData, int dpi = 96)
  69.301 +        {
  69.302 +            var ms = new MemoryStream();
  69.303 +            var w = new BinaryWriter(ms);
  69.304 +
  69.305 +            const int OffBits = 14 + 40;
  69.306 +            var size = OffBits + pixelData.Length;
  69.307 +
  69.308 +            // Bitmap file header (14 bytes)
  69.309 +            w.Write((byte)'B');
  69.310 +            w.Write((byte)'M');
  69.311 +            w.Write((uint)size);
  69.312 +            w.Write((ushort)0);
  69.313 +            w.Write((ushort)0);
  69.314 +            w.Write((uint)OffBits);
  69.315 +
  69.316 +            // Bitmap info header
  69.317 +            WriteBitmapInfoHeader(w, width, height, 32, pixelData.Length, dpi);
  69.318 +
  69.319 +            // Pixel array (from bottom-left corner)
  69.320 +            w.Write(pixelData);
  69.321 +
  69.322 +            return new OxyImage(ms.ToArray());
  69.323 +        }
  69.324 +
  69.325 +        /// <summary>
  69.326 +        /// Gets the image data.
  69.327 +        /// </summary>
  69.328 +        /// <returns>
  69.329 +        /// The image data as a byte array.
  69.330 +        /// </returns>
  69.331 +        public byte[] GetData()
  69.332 +        {
  69.333 +            return this.data;
  69.334 +        }
  69.335 +
  69.336 +        /// <summary>
  69.337 +        /// Writes the bitmap info header.
  69.338 +        /// </summary>
  69.339 +        /// <param name="w">
  69.340 +        /// The writer.
  69.341 +        /// </param>
  69.342 +        /// <param name="width">
  69.343 +        /// The width.
  69.344 +        /// </param>
  69.345 +        /// <param name="height">
  69.346 +        /// The height.
  69.347 +        /// </param>
  69.348 +        /// <param name="bitsPerPixel">
  69.349 +        /// The number of bits per pixel.
  69.350 +        /// </param>
  69.351 +        /// <param name="length">
  69.352 +        /// The length of the pixel data.
  69.353 +        /// </param>
  69.354 +        /// <param name="dpi">
  69.355 +        /// The dpi.
  69.356 +        /// </param>
  69.357 +        /// <param name="colors">
  69.358 +        /// The number of colors.
  69.359 +        /// </param>
  69.360 +        private static void WriteBitmapInfoHeader(
  69.361 +            BinaryWriter w, int width, int height, int bitsPerPixel, int length, int dpi, int colors = 0)
  69.362 +        {
  69.363 +            // Convert resolution to pixels per meter
  69.364 +            var ppm = (uint)(dpi / 0.0254);
  69.365 +
  69.366 +            w.Write((uint)40);
  69.367 +            w.Write((uint)width);
  69.368 +            w.Write((uint)height);
  69.369 +            w.Write((ushort)1);
  69.370 +            w.Write((ushort)bitsPerPixel);
  69.371 +            w.Write((uint)0);
  69.372 +            w.Write((uint)length);
  69.373 +            w.Write(ppm);
  69.374 +            w.Write(ppm);
  69.375 +            w.Write((uint)colors);
  69.376 +            w.Write((uint)colors);
  69.377 +        }
  69.378 +
  69.379 +        /// <summary>
  69.380 +        /// Writes the bitmap V4 header.
  69.381 +        /// </summary>
  69.382 +        /// <param name="w">
  69.383 +        /// The writer.
  69.384 +        /// </param>
  69.385 +        /// <param name="width">
  69.386 +        /// The width.
  69.387 +        /// </param>
  69.388 +        /// <param name="height">
  69.389 +        /// The height.
  69.390 +        /// </param>
  69.391 +        /// <param name="bitsPerPixel">
  69.392 +        /// The number of bits per pixel.
  69.393 +        /// </param>
  69.394 +        /// <param name="length">
  69.395 +        /// The length.
  69.396 +        /// </param>
  69.397 +        /// <param name="dpi">
  69.398 +        /// The resolution.
  69.399 +        /// </param>
  69.400 +        /// <param name="colors">
  69.401 +        /// The number of colors.
  69.402 +        /// </param>
  69.403 +        private static void WriteBitmapV4Header(
  69.404 +            BinaryWriter w, int width, int height, int bitsPerPixel, int length, int dpi, int colors = 0)
  69.405 +        {
  69.406 +            // Convert resolution to pixels per meter
  69.407 +            var ppm = (uint)(dpi / 0.0254);
  69.408 +
  69.409 +            w.Write((uint)108);
  69.410 +            w.Write((uint)width);
  69.411 +            w.Write((uint)height);
  69.412 +            w.Write((ushort)1);
  69.413 +            w.Write((ushort)bitsPerPixel);
  69.414 +            w.Write((uint)3);
  69.415 +            w.Write((uint)length);
  69.416 +            w.Write(ppm);
  69.417 +            w.Write(ppm);
  69.418 +            w.Write((uint)colors);
  69.419 +            w.Write((uint)colors);
  69.420 +
  69.421 +            // Write the channel bit masks
  69.422 +            w.Write(0x00FF0000);
  69.423 +            w.Write(0x0000FF00);
  69.424 +            w.Write(0x000000FF);
  69.425 +            w.Write(0xFF000000);
  69.426 +
  69.427 +            // Write the color space
  69.428 +            w.Write((uint)0x206E6957);
  69.429 +            w.Write(new byte[3 * 3 * 4]);
  69.430 +
  69.431 +            // Write the gamma RGB
  69.432 +            w.Write((uint)0);
  69.433 +            w.Write((uint)0);
  69.434 +            w.Write((uint)0);
  69.435 +        }
  69.436 +
  69.437 +        /// <summary>
  69.438 +        /// Creates a PNG image from the specified pixels.
  69.439 +        /// </summary>
  69.440 +        /// <param name="pixels">The pixels (bottom line first).</param>
  69.441 +        /// <returns>An OxyImage.</returns>
  69.442 +        public static OxyImage PngFromArgb(OxyColor[,] pixels)
  69.443 +        {
  69.444 +            return new OxyImage(PngEncoder.Encode(pixels));
  69.445 +        }
  69.446 +    }
  69.447 +}
  69.448 \ No newline at end of file
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyPalette.cs	Sat Jun 08 16:53:22 2013 +0000
    70.3 @@ -0,0 +1,102 @@
    70.4 +// --------------------------------------------------------------------------------------------------------------------
    70.5 +// <copyright file="OxyPalette.cs" company="OxyPlot">
    70.6 +//   The MIT License (MIT)
    70.7 +//
    70.8 +//   Copyright (c) 2012 Oystein Bjorke
    70.9 +//
   70.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   70.11 +//   copy of this software and associated documentation files (the
   70.12 +//   "Software"), to deal in the Software without restriction, including
   70.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   70.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   70.15 +//   permit persons to whom the Software is furnished to do so, subject to
   70.16 +//   the following conditions:
   70.17 +//
   70.18 +//   The above copyright notice and this permission notice shall be included
   70.19 +//   in all copies or substantial portions of the Software.
   70.20 +//
   70.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   70.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   70.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   70.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   70.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   70.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   70.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   70.28 +// </copyright>
   70.29 +// <summary>
   70.30 +//   Represents a palette of colors.
   70.31 +// </summary>
   70.32 +// --------------------------------------------------------------------------------------------------------------------
   70.33 +namespace OxyPlot
   70.34 +{
   70.35 +    using System.Collections.Generic;
   70.36 +
   70.37 +    /// <summary>
   70.38 +    /// Represents a palette of colors.
   70.39 +    /// </summary>
   70.40 +    public class OxyPalette
   70.41 +    {
   70.42 +        /// <summary>
   70.43 +        /// Initializes a new instance of the <see cref="OxyPalette"/> class.
   70.44 +        /// </summary>
   70.45 +        public OxyPalette()
   70.46 +        {
   70.47 +            this.Colors = new List<OxyColor>();
   70.48 +        }
   70.49 +
   70.50 +        /// <summary>
   70.51 +        /// Initializes a new instance of the <see cref="OxyPalette"/> class.
   70.52 +        /// </summary>
   70.53 +        /// <param name="colors">
   70.54 +        /// The colors.
   70.55 +        /// </param>
   70.56 +        public OxyPalette(params OxyColor[] colors)
   70.57 +        {
   70.58 +            this.Colors = new List<OxyColor>(colors);
   70.59 +        }
   70.60 +
   70.61 +        /// <summary>
   70.62 +        /// Initializes a new instance of the <see cref="OxyPalette"/> class.
   70.63 +        /// </summary>
   70.64 +        /// <param name="colors">
   70.65 +        /// The colors.
   70.66 +        /// </param>
   70.67 +        public OxyPalette(IEnumerable<OxyColor> colors)
   70.68 +        {
   70.69 +            this.Colors = new List<OxyColor>(colors);
   70.70 +        }
   70.71 +
   70.72 +        /// <summary>
   70.73 +        /// Gets or sets the colors.
   70.74 +        /// </summary>
   70.75 +        /// <value> The colors. </value>
   70.76 +        public IList<OxyColor> Colors { get; set; }
   70.77 +
   70.78 +        /// <summary>
   70.79 +        /// Interpolates the specified colors to a palette of the specified size.
   70.80 +        /// </summary>
   70.81 +        /// <param name="paletteSize">
   70.82 +        /// The size of the palette.
   70.83 +        /// </param>
   70.84 +        /// <param name="colors">
   70.85 +        /// The colors.
   70.86 +        /// </param>
   70.87 +        /// <returns>
   70.88 +        /// A palette.
   70.89 +        /// </returns>
   70.90 +        public static OxyPalette Interpolate(int paletteSize, params OxyColor[] colors)
   70.91 +        {
   70.92 +            var palette = new OxyColor[paletteSize];
   70.93 +            for (int i = 0; i < paletteSize; i++)
   70.94 +            {
   70.95 +                double y = (double)i / (paletteSize - 1);
   70.96 +                double x = y * (colors.Length - 1);
   70.97 +                int i0 = (int)x;
   70.98 +                int i1 = i0 + 1 < colors.Length ? i0 + 1 : i0;
   70.99 +                palette[i] = OxyColor.Interpolate(colors[i0], colors[i1], x - i0);
  70.100 +            }
  70.101 +
  70.102 +            return new OxyPalette(palette);
  70.103 +        }
  70.104 +    }
  70.105 +}
  70.106 \ No newline at end of file
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyPalettes.cs	Sat Jun 08 16:53:22 2013 +0000
    71.3 @@ -0,0 +1,208 @@
    71.4 +// --------------------------------------------------------------------------------------------------------------------
    71.5 +// <copyright file="OxyPalettes.cs" company="OxyPlot">
    71.6 +//   The MIT License (MIT)
    71.7 +//
    71.8 +//   Copyright (c) 2012 Oystein Bjorke
    71.9 +//
   71.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   71.11 +//   copy of this software and associated documentation files (the
   71.12 +//   "Software"), to deal in the Software without restriction, including
   71.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   71.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   71.15 +//   permit persons to whom the Software is furnished to do so, subject to
   71.16 +//   the following conditions:
   71.17 +//
   71.18 +//   The above copyright notice and this permission notice shall be included
   71.19 +//   in all copies or substantial portions of the Software.
   71.20 +//
   71.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   71.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   71.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   71.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   71.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   71.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   71.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   71.28 +// </copyright>
   71.29 +// <summary>
   71.30 +//   Provides predefined palettes.
   71.31 +// </summary>
   71.32 +// --------------------------------------------------------------------------------------------------------------------
   71.33 +namespace OxyPlot
   71.34 +{
   71.35 +    /// <summary>
   71.36 +    /// Provides predefined palettes.
   71.37 +    /// </summary>
   71.38 +    public static class OxyPalettes
   71.39 +    {
   71.40 +        /// <summary>
   71.41 +        /// Initializes static members of the <see cref="OxyPalettes"/> class.
   71.42 +        /// </summary>
   71.43 +        static OxyPalettes()
   71.44 +        {
   71.45 +            BlueWhiteRed31 = BlueWhiteRed(31);
   71.46 +            Hot64 = Hot(64);
   71.47 +            Hue64 = Hue(64);
   71.48 +        }
   71.49 +
   71.50 +        /// <summary>
   71.51 +        /// Gets the blue white red (31) palette.
   71.52 +        /// </summary>
   71.53 +        public static OxyPalette BlueWhiteRed31 { get; private set; }
   71.54 +
   71.55 +        /// <summary>
   71.56 +        /// Gets the hot (64) palette.
   71.57 +        /// </summary>
   71.58 +        public static OxyPalette Hot64 { get; private set; }
   71.59 +
   71.60 +        /// <summary>
   71.61 +        /// Gets the hue64 palette.
   71.62 +        /// </summary>
   71.63 +        public static OxyPalette Hue64 { get; private set; }
   71.64 +
   71.65 +        /// <summary>
   71.66 +        /// Creates a black/white/red palette with the specified number of colors.
   71.67 +        /// </summary>
   71.68 +        /// <param name="numberOfColors">
   71.69 +        /// The number of colors to create for the palette.
   71.70 +        /// </param>
   71.71 +        /// <returns>
   71.72 +        /// A palette.
   71.73 +        /// </returns>
   71.74 +        public static OxyPalette BlackWhiteRed(int numberOfColors)
   71.75 +        {
   71.76 +            return OxyPalette.Interpolate(numberOfColors, OxyColors.Black, OxyColors.White, OxyColors.Red);
   71.77 +        }
   71.78 +
   71.79 +        /// <summary>
   71.80 +        /// Creates a blue/white/red palette with the specified number of colors.
   71.81 +        /// </summary>
   71.82 +        /// <param name="numberOfColors">
   71.83 +        /// The number of colors to create for the palette.
   71.84 +        /// </param>
   71.85 +        /// <returns>
   71.86 +        /// A palette.
   71.87 +        /// </returns>
   71.88 +        public static OxyPalette BlueWhiteRed(int numberOfColors)
   71.89 +        {
   71.90 +            return OxyPalette.Interpolate(numberOfColors, OxyColors.Blue, OxyColors.White, OxyColors.Red);
   71.91 +        }
   71.92 +
   71.93 +        /// <summary>
   71.94 +        /// Creates a 'cool' palette with the specified number of colors.
   71.95 +        /// </summary>
   71.96 +        /// <param name="numberOfColors">
   71.97 +        /// The number of colors to create for the palette.
   71.98 +        /// </param>
   71.99 +        /// <returns>
  71.100 +        /// A palette.
  71.101 +        /// </returns>
  71.102 +        public static OxyPalette Cool(int numberOfColors)
  71.103 +        {
  71.104 +            return OxyPalette.Interpolate(numberOfColors, OxyColors.Cyan, OxyColors.Magenta);
  71.105 +        }
  71.106 +
  71.107 +        /// <summary>
  71.108 +        /// Creates a gray-scale palette with the specified number of colors.
  71.109 +        /// </summary>
  71.110 +        /// <param name="numberOfColors">
  71.111 +        /// The number of colors to create for the palette.
  71.112 +        /// </param>
  71.113 +        /// <returns>
  71.114 +        /// A palette.
  71.115 +        /// </returns>
  71.116 +        public static OxyPalette Gray(int numberOfColors)
  71.117 +        {
  71.118 +            return OxyPalette.Interpolate(numberOfColors, OxyColors.Black, OxyColors.White);
  71.119 +        }
  71.120 +
  71.121 +        /// <summary>
  71.122 +        /// Creates a 'hot' palette with the specified number of colors.
  71.123 +        /// </summary>
  71.124 +        /// <param name="numberOfColors">
  71.125 +        /// The number of colors to create for the palette.
  71.126 +        /// </param>
  71.127 +        /// <returns>
  71.128 +        /// A palette.
  71.129 +        /// </returns>
  71.130 +        public static OxyPalette Hot(int numberOfColors)
  71.131 +        {
  71.132 +            return OxyPalette.Interpolate(
  71.133 +                numberOfColors,
  71.134 +                OxyColors.Black,
  71.135 +                OxyColor.FromRgb(127, 0, 0),
  71.136 +                OxyColor.FromRgb(255, 127, 0),
  71.137 +                OxyColor.FromRgb(255, 255, 127),
  71.138 +                OxyColors.White);
  71.139 +        }
  71.140 +
  71.141 +        /// <summary>
  71.142 +        /// Creates a palette from the hue component of the HSV color model.
  71.143 +        /// </summary>
  71.144 +        /// <param name="numberOfColors">
  71.145 +        /// The number of colors.
  71.146 +        /// </param>
  71.147 +        /// <returns>
  71.148 +        /// The palette.
  71.149 +        /// </returns>
  71.150 +        /// <remarks>
  71.151 +        /// This palette is particularly appropriate for displaying periodic functions.
  71.152 +        /// </remarks>
  71.153 +        public static OxyPalette Hue(int numberOfColors)
  71.154 +        {
  71.155 +            return OxyPalette.Interpolate(
  71.156 +                numberOfColors,
  71.157 +                OxyColors.Red,
  71.158 +                OxyColors.Yellow,
  71.159 +                OxyColors.Green,
  71.160 +                OxyColors.Cyan,
  71.161 +                OxyColors.Blue,
  71.162 +                OxyColors.Magenta,
  71.163 +                OxyColors.Red);
  71.164 +        }
  71.165 +
  71.166 +        /// <summary>
  71.167 +        /// Creates a 'jet' palette with the specified number of colors.
  71.168 +        /// </summary>
  71.169 +        /// <param name="numberOfColors">
  71.170 +        /// The number of colors to create for the palette.
  71.171 +        /// </param>
  71.172 +        /// <returns>
  71.173 +        /// A palette.
  71.174 +        /// </returns>
  71.175 +        /// <remarks>
  71.176 +        /// See http://www.mathworks.se/help/techdoc/ref/colormap.html.
  71.177 +        /// </remarks>
  71.178 +        public static OxyPalette Jet(int numberOfColors)
  71.179 +        {
  71.180 +            return OxyPalette.Interpolate(
  71.181 +                numberOfColors,
  71.182 +                OxyColors.DarkBlue,
  71.183 +                OxyColors.Cyan,
  71.184 +                OxyColors.Yellow,
  71.185 +                OxyColors.Orange,
  71.186 +                OxyColors.DarkRed);
  71.187 +        }
  71.188 +
  71.189 +        /// <summary>
  71.190 +        /// Creates a rainbow palette with the specified number of colors.
  71.191 +        /// </summary>
  71.192 +        /// <param name="numberOfColors">
  71.193 +        /// The number of colors to create for the palette.
  71.194 +        /// </param>
  71.195 +        /// <returns>
  71.196 +        /// A palette.
  71.197 +        /// </returns>
  71.198 +        public static OxyPalette Rainbow(int numberOfColors)
  71.199 +        {
  71.200 +            return OxyPalette.Interpolate(
  71.201 +                numberOfColors,
  71.202 +                OxyColors.Violet,
  71.203 +                OxyColors.Indigo,
  71.204 +                OxyColors.Blue,
  71.205 +                OxyColors.Green,
  71.206 +                OxyColors.Yellow,
  71.207 +                OxyColors.Orange,
  71.208 +                OxyColors.Red);
  71.209 +        }
  71.210 +    }
  71.211 +}
  71.212 \ No newline at end of file
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyPen.cs	Sat Jun 08 16:53:22 2013 +0000
    72.3 @@ -0,0 +1,138 @@
    72.4 +// --------------------------------------------------------------------------------------------------------------------
    72.5 +// <copyright file="OxyPen.cs" company="OxyPlot">
    72.6 +//   The MIT License (MIT)
    72.7 +//
    72.8 +//   Copyright (c) 2012 Oystein Bjorke
    72.9 +//
   72.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   72.11 +//   copy of this software and associated documentation files (the
   72.12 +//   "Software"), to deal in the Software without restriction, including
   72.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   72.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   72.15 +//   permit persons to whom the Software is furnished to do so, subject to
   72.16 +//   the following conditions:
   72.17 +//
   72.18 +//   The above copyright notice and this permission notice shall be included
   72.19 +//   in all copies or substantial portions of the Software.
   72.20 +//
   72.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   72.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   72.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   72.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   72.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   72.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   72.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   72.28 +// </copyright>
   72.29 +// <summary>
   72.30 +//   Describes a pen in terms of color, thickness, line style and line join type.
   72.31 +// </summary>
   72.32 +// --------------------------------------------------------------------------------------------------------------------
   72.33 +namespace OxyPlot
   72.34 +{
   72.35 +    using System;
   72.36 +
   72.37 +    /// <summary>
   72.38 +    /// Describes a pen in terms of color, thickness, line style and line join type.
   72.39 +    /// </summary>
   72.40 +    public class OxyPen
   72.41 +    {
   72.42 +        /// <summary>
   72.43 +        /// Initializes a new instance of the <see cref="OxyPen"/> class.
   72.44 +        /// </summary>
   72.45 +        /// <param name="color">
   72.46 +        /// The color.
   72.47 +        /// </param>
   72.48 +        /// <param name="thickness">
   72.49 +        /// The thickness.
   72.50 +        /// </param>
   72.51 +        /// <param name="lineStyle">
   72.52 +        /// The line style.
   72.53 +        /// </param>
   72.54 +        /// <param name="lineJoin">
   72.55 +        /// The line join.
   72.56 +        /// </param>
   72.57 +        public OxyPen(
   72.58 +            OxyColor color,
   72.59 +            double thickness = 1.0,
   72.60 +            LineStyle lineStyle = LineStyle.Solid,
   72.61 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
   72.62 +        {
   72.63 +            this.Color = color;
   72.64 +            this.Thickness = thickness;
   72.65 +            this.DashArray = LineStyleHelper.GetDashArray(lineStyle);
   72.66 +            this.LineStyle = lineStyle;
   72.67 +            this.LineJoin = lineJoin;
   72.68 +        }
   72.69 +
   72.70 +        /// <summary>
   72.71 +        /// Gets or sets the color.
   72.72 +        /// </summary>
   72.73 +        /// <value>The color.</value>
   72.74 +        public OxyColor Color { get; set; }
   72.75 +
   72.76 +        /// <summary>
   72.77 +        /// Gets or sets the dash array.
   72.78 +        /// </summary>
   72.79 +        /// <value>The dash array.</value>
   72.80 +        public double[] DashArray { get; set; }
   72.81 +
   72.82 +        /// <summary>
   72.83 +        /// Gets or sets the line join.
   72.84 +        /// </summary>
   72.85 +        /// <value>The line join.</value>
   72.86 +        public OxyPenLineJoin LineJoin { get; set; }
   72.87 +
   72.88 +        /// <summary>
   72.89 +        /// Gets or sets the line style.
   72.90 +        /// </summary>
   72.91 +        /// <value>The line style.</value>
   72.92 +        public LineStyle LineStyle { get; set; }
   72.93 +
   72.94 +        /// <summary>
   72.95 +        /// Gets or sets the thickness.
   72.96 +        /// </summary>
   72.97 +        /// <value>The thickness.</value>
   72.98 +        public double Thickness { get; set; }
   72.99 +
  72.100 +        /// <summary>
  72.101 +        /// Creates the specified pen.
  72.102 +        /// </summary>
  72.103 +        /// <param name="color">The color.</param>
  72.104 +        /// <param name="thickness">The thickness.</param>
  72.105 +        /// <param name="lineStyle">The line style.</param>
  72.106 +        /// <param name="lineJoin">The line join.</param>
  72.107 +        /// <returns>A pen.</returns>
  72.108 +        public static OxyPen Create(
  72.109 +            OxyColor color,
  72.110 +            double thickness,
  72.111 +            LineStyle lineStyle = LineStyle.Solid,
  72.112 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
  72.113 +        {
  72.114 +            if (color == null || lineStyle == LineStyle.None || Math.Abs(thickness) < double.Epsilon)
  72.115 +            {
  72.116 +                return null;
  72.117 +            }
  72.118 +
  72.119 +            return new OxyPen(color, thickness, lineStyle, lineJoin);
  72.120 +        }
  72.121 +
  72.122 +        /// <summary>
  72.123 +        /// Returns a hash code for this instance.
  72.124 +        /// </summary>
  72.125 +        /// <returns>
  72.126 +        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
  72.127 +        /// </returns>
  72.128 +        public override int GetHashCode()
  72.129 +        {
  72.130 +            unchecked
  72.131 +            {
  72.132 +                int result = this.Color.GetHashCode();
  72.133 +                result = (result * 397) ^ this.Thickness.GetHashCode();
  72.134 +                result = (result * 397) ^ this.LineStyle.GetHashCode();
  72.135 +                result = (result * 397) ^ this.LineJoin.GetHashCode();
  72.136 +                return result;
  72.137 +            }
  72.138 +        }
  72.139 +
  72.140 +    }
  72.141 +}
  72.142 \ No newline at end of file
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyPenLineJoin.cs	Sat Jun 08 16:53:22 2013 +0000
    73.3 @@ -0,0 +1,52 @@
    73.4 +// --------------------------------------------------------------------------------------------------------------------
    73.5 +// <copyright file="OxyPenLineJoin.cs" company="OxyPlot">
    73.6 +//   The MIT License (MIT)
    73.7 +//
    73.8 +//   Copyright (c) 2012 Oystein Bjorke
    73.9 +//
   73.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   73.11 +//   copy of this software and associated documentation files (the
   73.12 +//   "Software"), to deal in the Software without restriction, including
   73.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   73.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   73.15 +//   permit persons to whom the Software is furnished to do so, subject to
   73.16 +//   the following conditions:
   73.17 +//
   73.18 +//   The above copyright notice and this permission notice shall be included
   73.19 +//   in all copies or substantial portions of the Software.
   73.20 +//
   73.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   73.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   73.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   73.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   73.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   73.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   73.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   73.28 +// </copyright>
   73.29 +// <summary>
   73.30 +//   Pen line join.
   73.31 +// </summary>
   73.32 +// --------------------------------------------------------------------------------------------------------------------
   73.33 +namespace OxyPlot
   73.34 +{
   73.35 +    /// <summary>
   73.36 +    /// Specifies how to join line segments.
   73.37 +    /// </summary>
   73.38 +    public enum OxyPenLineJoin
   73.39 +    {
   73.40 +        /// <summary>
   73.41 +        /// Line joins use regular angular vertices.
   73.42 +        /// </summary>
   73.43 +        Miter,
   73.44 +
   73.45 +        /// <summary>
   73.46 +        /// Line joins use rounded vertices.
   73.47 +        /// </summary>
   73.48 +        Round,
   73.49 +
   73.50 +        /// <summary>
   73.51 +        /// Line joins use beveled vertices.
   73.52 +        /// </summary>
   73.53 +        Bevel
   73.54 +    }
   73.55 +}
   73.56 \ No newline at end of file
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyRect.cs	Sat Jun 08 16:53:22 2013 +0000
    74.3 @@ -0,0 +1,287 @@
    74.4 +// --------------------------------------------------------------------------------------------------------------------
    74.5 +// <copyright file="OxyRect.cs" company="OxyPlot">
    74.6 +//   The MIT License (MIT)
    74.7 +//
    74.8 +//   Copyright (c) 2012 Oystein Bjorke
    74.9 +//
   74.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   74.11 +//   copy of this software and associated documentation files (the
   74.12 +//   "Software"), to deal in the Software without restriction, including
   74.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   74.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   74.15 +//   permit persons to whom the Software is furnished to do so, subject to
   74.16 +//   the following conditions:
   74.17 +//
   74.18 +//   The above copyright notice and this permission notice shall be included
   74.19 +//   in all copies or substantial portions of the Software.
   74.20 +//
   74.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   74.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   74.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   74.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   74.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   74.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   74.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   74.28 +// </copyright>
   74.29 +// <summary>
   74.30 +//   Describes the width, height, and point origin of a rectangle.
   74.31 +// </summary>
   74.32 +// --------------------------------------------------------------------------------------------------------------------
   74.33 +namespace OxyPlot
   74.34 +{
   74.35 +    using System;
   74.36 +    using System.Diagnostics;
   74.37 +    using System.Globalization;
   74.38 +
   74.39 +    /// <summary>
   74.40 +    /// Describes the width, height, and point origin of a rectangle.
   74.41 +    /// </summary>
   74.42 +    public struct OxyRect
   74.43 +    {
   74.44 +        /// <summary>
   74.45 +        /// The height of the rectangle.
   74.46 +        /// </summary>
   74.47 +        private double height;
   74.48 +
   74.49 +        /// <summary>
   74.50 +        /// The x-coordinate location of the left side of the rectangle.
   74.51 +        /// </summary>
   74.52 +        private double left;
   74.53 +
   74.54 +        /// <summary>
   74.55 +        /// The y-coordinate location of the top side of the rectangle.
   74.56 +        /// </summary>
   74.57 +        private double top;
   74.58 +
   74.59 +        /// <summary>
   74.60 +        /// The width of the rectangle.
   74.61 +        /// </summary>
   74.62 +        private double width;
   74.63 +
   74.64 +        /// <summary>
   74.65 +        /// Initializes a new instance of the <see cref="OxyRect"/> structure that has the specified x-coordinate, y-coordinate, width, and height.
   74.66 +        /// </summary>
   74.67 +        /// <param name="left">
   74.68 +        /// The x-coordinate location of the left side of the rectangle.
   74.69 +        /// </param>
   74.70 +        /// <param name="top">
   74.71 +        /// The y-coordinate location of the top side of the rectangle.
   74.72 +        /// </param>
   74.73 +        /// <param name="width">
   74.74 +        /// The width of the rectangle.
   74.75 +        /// </param>
   74.76 +        /// <param name="height">
   74.77 +        /// The height of the rectangle.
   74.78 +        /// </param>
   74.79 +        public OxyRect(double left, double top, double width, double height)
   74.80 +        {
   74.81 +            this.left = left;
   74.82 +            this.top = top;
   74.83 +            this.width = width;
   74.84 +            this.height = height;
   74.85 +            Debug.Assert(width >= 0, "Width should be larger than 0.");
   74.86 +            Debug.Assert(height >= 0, "Height should be larger than 0.");
   74.87 +        }
   74.88 +
   74.89 +        /// <summary>
   74.90 +        /// Gets or sets the y-axis value of the bottom of the rectangle.
   74.91 +        /// </summary>
   74.92 +        /// <value>
   74.93 +        /// The bottom.
   74.94 +        /// </value>
   74.95 +        public double Bottom
   74.96 +        {
   74.97 +            get
   74.98 +            {
   74.99 +                return this.top + this.height;
  74.100 +            }
  74.101 +
  74.102 +            set
  74.103 +            {
  74.104 +                this.height = value - this.top;
  74.105 +            }
  74.106 +        }
  74.107 +
  74.108 +        /// <summary>
  74.109 +        /// Gets or sets the height of the rectangle.
  74.110 +        /// </summary>
  74.111 +        /// <value>
  74.112 +        /// The height.
  74.113 +        /// </value>
  74.114 +        public double Height
  74.115 +        {
  74.116 +            get
  74.117 +            {
  74.118 +                return this.height;
  74.119 +            }
  74.120 +
  74.121 +            set
  74.122 +            {
  74.123 +                this.height = value;
  74.124 +            }
  74.125 +        }
  74.126 +
  74.127 +        /// <summary>
  74.128 +        /// Gets or sets the x-axis value of the left side of the rectangle.
  74.129 +        /// </summary>
  74.130 +        /// <value>
  74.131 +        /// The left.
  74.132 +        /// </value>
  74.133 +        public double Left
  74.134 +        {
  74.135 +            get
  74.136 +            {
  74.137 +                return this.left;
  74.138 +            }
  74.139 +
  74.140 +            set
  74.141 +            {
  74.142 +                this.left = value;
  74.143 +            }
  74.144 +        }
  74.145 +
  74.146 +        /// <summary>
  74.147 +        /// Gets or sets the x-axis value of the right side of the rectangle.
  74.148 +        /// </summary>
  74.149 +        /// <value>
  74.150 +        /// The right.
  74.151 +        /// </value>
  74.152 +        public double Right
  74.153 +        {
  74.154 +            get
  74.155 +            {
  74.156 +                return this.left + this.width;
  74.157 +            }
  74.158 +
  74.159 +            set
  74.160 +            {
  74.161 +                this.width = value - this.left;
  74.162 +            }
  74.163 +        }
  74.164 +
  74.165 +        /// <summary>
  74.166 +        /// Gets or sets the y-axis position of the top of the rectangle.
  74.167 +        /// </summary>
  74.168 +        /// <value>
  74.169 +        /// The top.
  74.170 +        /// </value>
  74.171 +        public double Top
  74.172 +        {
  74.173 +            get
  74.174 +            {
  74.175 +                return this.top;
  74.176 +            }
  74.177 +
  74.178 +            set
  74.179 +            {
  74.180 +                this.top = value;
  74.181 +            }
  74.182 +        }
  74.183 +
  74.184 +        /// <summary>
  74.185 +        /// Gets or sets the width of the rectangle.
  74.186 +        /// </summary>
  74.187 +        /// <value>
  74.188 +        /// The width.
  74.189 +        /// </value>
  74.190 +        public double Width
  74.191 +        {
  74.192 +            get
  74.193 +            {
  74.194 +                return this.width;
  74.195 +            }
  74.196 +
  74.197 +            set
  74.198 +            {
  74.199 +                this.width = value;
  74.200 +            }
  74.201 +        }
  74.202 +
  74.203 +        /// <summary>
  74.204 +        /// Gets the center point of the rectangle.
  74.205 +        /// </summary>
  74.206 +        /// <value>The center.</value>
  74.207 +        public ScreenPoint Center
  74.208 +        {
  74.209 +            get
  74.210 +            {
  74.211 +                return new ScreenPoint(this.left + (this.width * 0.5), this.top + (this.height * 0.5));
  74.212 +            }
  74.213 +        }
  74.214 +
  74.215 +        /// <summary>
  74.216 +        /// Creates a rectangle from the specified corner coordinates.
  74.217 +        /// </summary>
  74.218 +        /// <param name="x0">
  74.219 +        /// The x0.
  74.220 +        /// </param>
  74.221 +        /// <param name="y0">
  74.222 +        /// The y0.
  74.223 +        /// </param>
  74.224 +        /// <param name="x1">
  74.225 +        /// The x1.
  74.226 +        /// </param>
  74.227 +        /// <param name="y1">
  74.228 +        /// The y1.
  74.229 +        /// </param>
  74.230 +        /// <returns>
  74.231 +        /// A rectangle.
  74.232 +        /// </returns>
  74.233 +        public static OxyRect Create(double x0, double y0, double x1, double y1)
  74.234 +        {
  74.235 +            return new OxyRect(Math.Min(x0, x1), Math.Min(y0, y1), Math.Abs(x1 - x0), Math.Abs(y1 - y0));
  74.236 +        }
  74.237 +
  74.238 +        /// <summary>
  74.239 +        /// Creates a rectangle from the specified corner coordinates.
  74.240 +        /// </summary>
  74.241 +        /// <param name="p0">The first corner.</param>
  74.242 +        /// <param name="p1">The second corner.</param>
  74.243 +        /// <returns>A rectangle.</returns>
  74.244 +        public static OxyRect Create(ScreenPoint p0, ScreenPoint p1)
  74.245 +        {
  74.246 +            return Create(p0.X, p0.Y, p1.X, p1.Y);
  74.247 +        }
  74.248 +
  74.249 +        /// <summary>
  74.250 +        /// Determines whether the specified point is inside the rectangle.
  74.251 +        /// </summary>
  74.252 +        /// <param name="x">
  74.253 +        /// The x coordinate.
  74.254 +        /// </param>
  74.255 +        /// <param name="y">
  74.256 +        /// The y coordinate.
  74.257 +        /// </param>
  74.258 +        /// <returns>
  74.259 +        /// <c>true</c> if the rectangle contains the specified point; otherwise, <c>false</c>.
  74.260 +        /// </returns>
  74.261 +        public bool Contains(double x, double y)
  74.262 +        {
  74.263 +            return x >= this.Left && x <= this.Right && y >= this.Top && y <= this.Bottom;
  74.264 +        }
  74.265 +
  74.266 +        /// <summary>
  74.267 +        /// Determines whether the specified point is inside the rectangle.
  74.268 +        /// </summary>
  74.269 +        /// <param name="p">The point.</param>
  74.270 +        /// <returns>
  74.271 +        /// <c>true</c> if the rectangle contains the specified point; otherwise, <c>false</c>.
  74.272 +        /// </returns>
  74.273 +        public bool Contains(ScreenPoint p)
  74.274 +        {
  74.275 +            return this.Contains(p.x, p.y);
  74.276 +        }
  74.277 +
  74.278 +        /// <summary>
  74.279 +        /// Returns a <see cref="System.String"/> that represents this instance.
  74.280 +        /// </summary>
  74.281 +        /// <returns>
  74.282 +        /// A <see cref="System.String"/> that represents this instance.
  74.283 +        /// </returns>
  74.284 +        public override string ToString()
  74.285 +        {
  74.286 +            return string.Format(
  74.287 +                CultureInfo.InvariantCulture, "({0}, {1}, {2}, {3})", this.left, this.top, this.width, this.height);
  74.288 +        }
  74.289 +    }
  74.290 +}
  74.291 \ No newline at end of file
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxySize.cs	Sat Jun 08 16:53:22 2013 +0000
    75.3 @@ -0,0 +1,87 @@
    75.4 +// --------------------------------------------------------------------------------------------------------------------
    75.5 +// <copyright file="OxySize.cs" company="OxyPlot">
    75.6 +//   The MIT License (MIT)
    75.7 +//   
    75.8 +//   Copyright (c) 2012 Oystein Bjorke
    75.9 +//   
   75.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   75.11 +//   copy of this software and associated documentation files (the
   75.12 +//   "Software"), to deal in the Software without restriction, including
   75.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   75.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   75.15 +//   permit persons to whom the Software is furnished to do so, subject to
   75.16 +//   the following conditions:
   75.17 +//   
   75.18 +//   The above copyright notice and this permission notice shall be included
   75.19 +//   in all copies or substantial portions of the Software.
   75.20 +//   
   75.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   75.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   75.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   75.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   75.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   75.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   75.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   75.28 +// </copyright>
   75.29 +// <summary>
   75.30 +//   Implements a structure that is used to describe the Size of an object.
   75.31 +// </summary>
   75.32 +// --------------------------------------------------------------------------------------------------------------------
   75.33 +namespace OxyPlot
   75.34 +{
   75.35 +    using System.Globalization;
   75.36 +
   75.37 +    /// <summary>
   75.38 +    /// Implements a structure that is used to describe the size of an object.
   75.39 +    /// </summary>
   75.40 +    public struct OxySize
   75.41 +    {
   75.42 +        /// <summary>
   75.43 +        /// Empty Size.
   75.44 +        /// </summary>
   75.45 +        public static OxySize Empty = new OxySize(0, 0);
   75.46 +
   75.47 +        /// <summary>
   75.48 +        /// Initializes a new instance of the <see cref="OxySize"/> struct.
   75.49 +        /// </summary>
   75.50 +        /// <param name="width">
   75.51 +        /// The width.
   75.52 +        /// </param>
   75.53 +        /// <param name="height">
   75.54 +        /// The height.
   75.55 +        /// </param>
   75.56 +        public OxySize(double width, double height)
   75.57 +            : this()
   75.58 +        {
   75.59 +            this.Width = width;
   75.60 +            this.Height = height;
   75.61 +        }
   75.62 +
   75.63 +        /// <summary>
   75.64 +        /// Gets or sets the height.
   75.65 +        /// </summary>
   75.66 +        /// <value>
   75.67 +        /// The height.
   75.68 +        /// </value>
   75.69 +        public double Height { get; set; }
   75.70 +
   75.71 +        /// <summary>
   75.72 +        /// Gets or sets the width.
   75.73 +        /// </summary>
   75.74 +        /// <value>
   75.75 +        /// The width.
   75.76 +        /// </value>
   75.77 +        public double Width { get; set; }
   75.78 +
   75.79 +        /// <summary>
   75.80 +        /// Returns a <see cref="System.String"/> that represents this instance.
   75.81 +        /// </summary>
   75.82 +        /// <returns>
   75.83 +        /// A <see cref="System.String"/> that represents this instance.
   75.84 +        /// </returns>
   75.85 +        public override string ToString()
   75.86 +        {
   75.87 +            return string.Format(CultureInfo.InvariantCulture, "({0}, {1})", this.Width, this.Height);
   75.88 +        }
   75.89 +    }
   75.90 +}
   75.91 \ No newline at end of file
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/External/OxyPlot/OxyPlot/Foundation/OxyThickness.cs	Sat Jun 08 16:53:22 2013 +0000
    76.3 @@ -0,0 +1,220 @@
    76.4 +// --------------------------------------------------------------------------------------------------------------------
    76.5 +// <copyright file="OxyThickness.cs" company="OxyPlot">
    76.6 +//   The MIT License (MIT)
    76.7 +//
    76.8 +//   Copyright (c) 2012 Oystein Bjorke
    76.9 +//
   76.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   76.11 +//   copy of this software and associated documentation files (the
   76.12 +//   "Software"), to deal in the Software without restriction, including
   76.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   76.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   76.15 +//   permit persons to whom the Software is furnished to do so, subject to
   76.16 +//   the following conditions:
   76.17 +//
   76.18 +//   The above copyright notice and this permission notice shall be included
   76.19 +//   in all copies or substantial portions of the Software.
   76.20 +//
   76.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   76.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   76.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   76.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   76.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   76.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   76.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   76.28 +// </copyright>
   76.29 +// <summary>
   76.30 +//   Describes the thickness of a frame around a rectangle. Four Double values describe the Left, Top, Right, and Bottom sides of the rectangle, respectively.
   76.31 +// </summary>
   76.32 +// --------------------------------------------------------------------------------------------------------------------
   76.33 +namespace OxyPlot
   76.34 +{
   76.35 +    using System.Globalization;
   76.36 +
   76.37 +    /// <summary>
   76.38 +    /// Describes the thickness of a frame around a rectangle. Four <see cref="System.Double"/> values describe the left, top, right, and bottom sides of the rectangle, respectively.
   76.39 +    /// </summary>
   76.40 +    public struct OxyThickness : ICodeGenerating
   76.41 +    {
   76.42 +        /// <summary>
   76.43 +        /// The bottom.
   76.44 +        /// </summary>
   76.45 +        private double bottom;
   76.46 +
   76.47 +        /// <summary>
   76.48 +        /// The left.
   76.49 +        /// </summary>
   76.50 +        private double left;
   76.51 +
   76.52 +        /// <summary>
   76.53 +        /// The right.
   76.54 +        /// </summary>
   76.55 +        private double right;
   76.56 +
   76.57 +        /// <summary>
   76.58 +        /// The top.
   76.59 +        /// </summary>
   76.60 +        private double top;
   76.61 +
   76.62 +        /// <summary>
   76.63 +        /// Initializes a new instance of the <see cref="OxyThickness"/> struct.
   76.64 +        /// </summary>
   76.65 +        /// <param name="thickness">
   76.66 +        /// The thickness.
   76.67 +        /// </param>
   76.68 +        public OxyThickness(double thickness)
   76.69 +            : this(thickness, thickness, thickness, thickness)
   76.70 +        {
   76.71 +        }
   76.72 +
   76.73 +        /// <summary>
   76.74 +        /// Initializes a new instance of the <see cref="OxyThickness"/> struct.
   76.75 +        /// </summary>
   76.76 +        /// <param name="left">
   76.77 +        /// The left.
   76.78 +        /// </param>
   76.79 +        /// <param name="top">
   76.80 +        /// The top.
   76.81 +        /// </param>
   76.82 +        /// <param name="right">
   76.83 +        /// The right.
   76.84 +        /// </param>
   76.85 +        /// <param name="bottom">
   76.86 +        /// The bottom.
   76.87 +        /// </param>
   76.88 +        public OxyThickness(double left, double top, double right, double bottom)
   76.89 +        {
   76.90 +            this.left = left;
   76.91 +            this.top = top;
   76.92 +            this.right = right;
   76.93 +            this.bottom = bottom;
   76.94 +        }
   76.95 +
   76.96 +        /// <summary>
   76.97 +        /// Gets or sets the bottom thickness.
   76.98 +        /// </summary>
   76.99 +        /// <value>
  76.100 +        /// The bottom thickness.
  76.101 +        /// </value>
  76.102 +        public double Bottom
  76.103 +        {
  76.104 +            get
  76.105 +            {
  76.106 +                return this.bottom;
  76.107 +            }
  76.108 +
  76.109 +            set
  76.110 +            {
  76.111 +                this.bottom = value;
  76.112 +            }
  76.113 +        }
  76.114 +
  76.115 +        /// <summary>
  76.116 +        /// Gets the height.
  76.117 +        /// </summary>
  76.118 +        public double Height
  76.119 +        {
  76.120 +            get
  76.121 +            {
  76.122 +                return this.Bottom - this.Top;
  76.123 +            }
  76.124 +        }
  76.125 +
  76.126 +        /// <summary>
  76.127 +        /// Gets or sets the left thickness.
  76.128 +        /// </summary>
  76.129 +        /// <value>
  76.130 +        /// The left thickness.
  76.131 +        /// </value>
  76.132 +        public double Left
  76.133 +        {
  76.134 +            get
  76.135 +            {
  76.136 +                return this.left;
  76.137 +            }
  76.138 +
  76.139 +            set
  76.140 +            {
  76.141 +                this.left = value;
  76.142 +            }
  76.143 +        }
  76.144 +
  76.145 +        /// <summary>
  76.146 +        /// Gets or sets the right thickness.
  76.147 +        /// </summary>
  76.148 +        /// <value>
  76.149 +        /// The right thickness.
  76.150 +        /// </value>
  76.151 +        public double Right
  76.152 +        {
  76.153 +            get
  76.154 +            {
  76.155 +                return this.right;
  76.156 +            }
  76.157 +
  76.158 +            set
  76.159 +            {
  76.160 +                this.right = value;
  76.161 +            }
  76.162 +        }
  76.163 +
  76.164 +        /// <summary>
  76.165 +        /// Gets or sets the top thickness.
  76.166 +        /// </summary>
  76.167 +        /// <value>
  76.168 +        /// The top thickness.
  76.169 +        /// </value>
  76.170 +        public double Top
  76.171 +        {
  76.172 +            get
  76.173 +            {
  76.174 +                return this.top;
  76.175 +            }
  76.176 +
  76.177 +            set
  76.178 +            {
  76.179 +                this.top = value;
  76.180 +            }
  76.181 +        }
  76.182 +
  76.183 +        /// <summary>
  76.184 +        /// Gets the width.
  76.185 +        /// </summary>
  76.186 +        public double Width
  76.187 +        {
  76.188 +            get
  76.189 +            {
  76.190 +                return this.Right - this.Left;
  76.191 +            }
  76.192 +        }
  76.193 +
  76.194 +        /// <summary>
  76.195 +        /// Returns C# code that generates this instance.
  76.196 +        /// </summary>
  76.197 +        /// <returns>
  76.198 +        /// The to code.
  76.199 +        /// </returns>
  76.200 +        public string ToCode()
  76.201 +        {
  76.202 +            return string.Format(
  76.203 +                CultureInfo.InvariantCulture,
  76.204 +                "new OxyThickness({0},{1},{2},{3})",
  76.205 +                this.Left,
  76.206 +                this.Top,
  76.207 +                this.Right,
  76.208 +                this.Bottom);
  76.209 +        }
  76.210 +
  76.211 +        /// <summary>
  76.212 +        /// Returns a <see cref="System.String"/> that represents this instance.
  76.213 +        /// </summary>
  76.214 +        /// <returns>
  76.215 +        /// A <see cref="System.String"/> that represents this instance.
  76.216 +        /// </returns>
  76.217 +        public override string ToString()
  76.218 +        {
  76.219 +            return string.Format(
  76.220 +                CultureInfo.InvariantCulture, "({0}, {1}, {2}, {3})", this.left, this.top, this.right, this.bottom);
  76.221 +        }
  76.222 +    }
  76.223 +}
  76.224 \ No newline at end of file
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Pen.cs	Sat Jun 08 16:53:22 2013 +0000
    77.3 @@ -0,0 +1,42 @@
    77.4 +// --------------------------------------------------------------------------------------------------------------------
    77.5 +// <copyright file="Pen.cs" company="OxyPlot">
    77.6 +//   The MIT License (MIT)
    77.7 +//
    77.8 +//   Copyright (c) 2012 Oystein Bjorke
    77.9 +//
   77.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   77.11 +//   copy of this software and associated documentation files (the
   77.12 +//   "Software"), to deal in the Software without restriction, including
   77.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   77.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   77.15 +//   permit persons to whom the Software is furnished to do so, subject to
   77.16 +//   the following conditions:
   77.17 +//
   77.18 +//   The above copyright notice and this permission notice shall be included
   77.19 +//   in all copies or substantial portions of the Software.
   77.20 +//
   77.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   77.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   77.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   77.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   77.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   77.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   77.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   77.28 +// </copyright>
   77.29 +// --------------------------------------------------------------------------------------------------------------------
   77.30 +namespace OxyPlot
   77.31 +{
   77.32 +    public class Pen
   77.33 +    {
   77.34 +        public Pen(Color c, double th, LineStyle ls)
   77.35 +        {
   77.36 +            Color = c;
   77.37 +            Thickness = th;
   77.38 +            DashArray = LineStyleHelper.GetDashArray(ls);
   77.39 +        }
   77.40 +
   77.41 +        public Color Color { get; set; }
   77.42 +        public double Thickness { get; set; }
   77.43 +        public double[] DashArray { get; set; }
   77.44 +    }
   77.45 +}
   77.46 \ No newline at end of file
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/External/OxyPlot/OxyPlot/Foundation/PlotLength.cs	Sat Jun 08 16:53:22 2013 +0000
    78.3 @@ -0,0 +1,91 @@
    78.4 +// --------------------------------------------------------------------------------------------------------------------
    78.5 +// <copyright file="PlotLength.cs" company="OxyPlot">
    78.6 +//   The MIT License (MIT)
    78.7 +//   
    78.8 +//   Copyright (c) 2012 Oystein Bjorke
    78.9 +//   
   78.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   78.11 +//   copy of this software and associated documentation files (the
   78.12 +//   "Software"), to deal in the Software without restriction, including
   78.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   78.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   78.15 +//   permit persons to whom the Software is furnished to do so, subject to
   78.16 +//   the following conditions:
   78.17 +//   
   78.18 +//   The above copyright notice and this permission notice shall be included
   78.19 +//   in all copies or substantial portions of the Software.
   78.20 +//   
   78.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   78.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   78.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   78.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   78.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   78.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   78.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   78.28 +// </copyright>
   78.29 +// <summary>
   78.30 +//   Represents lengths in the plot.
   78.31 +// </summary>
   78.32 +// --------------------------------------------------------------------------------------------------------------------
   78.33 +
   78.34 +namespace OxyPlot
   78.35 +{
   78.36 +    /// <summary>
   78.37 +    /// Represents lengths in the plot. 
   78.38 +    /// </summary>
   78.39 +    public struct PlotLength
   78.40 +    {
   78.41 +        /// <summary>
   78.42 +        /// The unit type
   78.43 +        /// </summary>
   78.44 +        private readonly PlotLengthUnit unit;
   78.45 +
   78.46 +        /// <summary>
   78.47 +        /// The value
   78.48 +        /// </summary>
   78.49 +        private readonly double value;
   78.50 +
   78.51 +        /// <summary>
   78.52 +        /// Initializes a new instance of the <see cref="PlotLength"/> struct.
   78.53 +        /// </summary>
   78.54 +        /// <param name="value">
   78.55 +        /// The value.
   78.56 +        /// </param>
   78.57 +        /// <param name="unit">
   78.58 +        /// The unit.
   78.59 +        /// </param>
   78.60 +        public PlotLength(double value, PlotLengthUnit unit)
   78.61 +        {
   78.62 +            this.value = value;
   78.63 +            this.unit = unit;
   78.64 +        }
   78.65 +
   78.66 +        /// <summary>
   78.67 +        /// Gets the value.
   78.68 +        /// </summary>
   78.69 +        /// <value>
   78.70 +        /// The value.
   78.71 +        /// </value>
   78.72 +        public double Value
   78.73 +        {
   78.74 +            get
   78.75 +            {
   78.76 +                return this.value;
   78.77 +            }
   78.78 +        }
   78.79 +
   78.80 +        /// <summary>
   78.81 +        /// Gets the type of the unit.
   78.82 +        /// </summary>
   78.83 +        /// <value>
   78.84 +        /// The type of the unit.
   78.85 +        /// </value>
   78.86 +        public PlotLengthUnit Unit
   78.87 +        {
   78.88 +            get
   78.89 +            {
   78.90 +                return this.unit;
   78.91 +            }
   78.92 +        }
   78.93 +    }
   78.94 +}
   78.95 \ No newline at end of file
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/External/OxyPlot/OxyPlot/Foundation/PlotLengthUnit.cs	Sat Jun 08 16:53:22 2013 +0000
    79.3 @@ -0,0 +1,58 @@
    79.4 +// --------------------------------------------------------------------------------------------------------------------
    79.5 +// <copyright file="PlotLengthUnit.cs" company="OxyPlot">
    79.6 +//   The MIT License (MIT)
    79.7 +//   
    79.8 +//   Copyright (c) 2012 Oystein Bjorke
    79.9 +//   
   79.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   79.11 +//   copy of this software and associated documentation files (the
   79.12 +//   "Software"), to deal in the Software without restriction, including
   79.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   79.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   79.15 +//   permit persons to whom the Software is furnished to do so, subject to
   79.16 +//   the following conditions:
   79.17 +//   
   79.18 +//   The above copyright notice and this permission notice shall be included
   79.19 +//   in all copies or substantial portions of the Software.
   79.20 +//   
   79.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   79.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   79.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   79.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   79.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   79.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   79.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   79.28 +// </copyright>
   79.29 +// <summary>
   79.30 +//   Describes the kind of value that a <see cref="PlotLength" /> object is holding.
   79.31 +// </summary>
   79.32 +// --------------------------------------------------------------------------------------------------------------------
   79.33 +
   79.34 +namespace OxyPlot
   79.35 +{
   79.36 +    /// <summary>
   79.37 +    /// Describes the kind of value that a <see cref="PlotLength"/> object is holding.
   79.38 +    /// </summary>
   79.39 +    public enum PlotLengthUnit
   79.40 +    {
   79.41 +        /// <summary>
   79.42 +        /// The value is in data space (transformed by x/y axis)
   79.43 +        /// </summary>
   79.44 +        Data = 0, 
   79.45 +
   79.46 +        /// <summary>
   79.47 +        /// The value is in screen units
   79.48 +        /// </summary>
   79.49 +        ScreenUnits = 1, 
   79.50 +
   79.51 +        /// <summary>
   79.52 +        /// The value is relative to the plot viewport (0-1)
   79.53 +        /// </summary>
   79.54 +        RelativeToViewport = 2, 
   79.55 +
   79.56 +        /// <summary>
   79.57 +        /// The value is relative to the plot area (0-1)
   79.58 +        /// </summary>
   79.59 +        RelativeToPlotArea = 3
   79.60 +    }
   79.61 +}
   79.62 \ No newline at end of file
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/External/OxyPlot/OxyPlot/Foundation/PngEncoder.cs	Sat Jun 08 16:53:22 2013 +0000
    80.3 @@ -0,0 +1,323 @@
    80.4 +// --------------------------------------------------------------------------------------------------------------------
    80.5 +// <copyright file="PngEncoder.cs" company="OxyPlot">
    80.6 +//   The MIT License (MIT)
    80.7 +//   
    80.8 +//   Copyright (c) 2012 Oystein Bjorke
    80.9 +//   
   80.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   80.11 +//   copy of this software and associated documentation files (the
   80.12 +//   "Software"), to deal in the Software without restriction, including
   80.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   80.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   80.15 +//   permit persons to whom the Software is furnished to do so, subject to
   80.16 +//   the following conditions:
   80.17 +//   
   80.18 +//   The above copyright notice and this permission notice shall be included
   80.19 +//   in all copies or substantial portions of the Software.
   80.20 +//   
   80.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   80.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   80.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   80.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   80.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   80.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   80.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   80.28 +// </copyright>
   80.29 +// --------------------------------------------------------------------------------------------------------------------
   80.30 +
   80.31 +namespace OxyPlot
   80.32 +{
   80.33 +    using System;
   80.34 +    using System.Collections.Generic;
   80.35 +    using System.IO;
   80.36 +    using System.Linq;
   80.37 +
   80.38 +    /// <summary>
   80.39 +    /// Provides encoding of uncompressed png images.
   80.40 +    /// </summary>
   80.41 +    public class PngEncoder
   80.42 +    {
   80.43 +        /// <summary>
   80.44 +        /// The CRC table
   80.45 +        /// </summary>
   80.46 +        private static readonly ulong[] CrcTable;
   80.47 +
   80.48 +        /// <summary>
   80.49 +        /// Initializes static members of the <see cref="PngEncoder" /> class.
   80.50 +        /// </summary>
   80.51 +        static PngEncoder()
   80.52 +        {
   80.53 +            CrcTable = new ulong[256];
   80.54 +            for (int n = 0; n < 256; n++)
   80.55 +            {
   80.56 +                var c = (ulong)n;
   80.57 +                for (int k = 0; k < 8; k++)
   80.58 +                {
   80.59 +                    if ((c & 1) != 0)
   80.60 +                    {
   80.61 +                        c = 0xedb88320L ^ (c >> 1);
   80.62 +                    }
   80.63 +                    else
   80.64 +                    {
   80.65 +                        c = c >> 1;
   80.66 +                    }
   80.67 +                }
   80.68 +
   80.69 +                CrcTable[n] = c;
   80.70 +            }
   80.71 +        }
   80.72 +
   80.73 +        /// <summary>
   80.74 +        /// Encodes the specified image data to png.
   80.75 +        /// </summary>
   80.76 +        /// <param name="pixels">
   80.77 +        /// The pixel data (bottom line first).
   80.78 +        /// </param>
   80.79 +        /// <param name="dpi">
   80.80 +        /// The image resolution in dots per inch.
   80.81 +        /// </param>
   80.82 +        /// <returns>
   80.83 +        /// The png image data.
   80.84 +        /// </returns>
   80.85 +        public static byte[] Encode(OxyColor[,] pixels, int dpi = 96)
   80.86 +        {
   80.87 +            int height = pixels.GetLength(0);
   80.88 +            int width = pixels.GetLength(1);
   80.89 +            var bytes = new byte[(width * height * 4) + height];
   80.90 +
   80.91 +            int k = 0;
   80.92 +            for (int i = height - 1; i >= 0; i--)
   80.93 +            {
   80.94 +                bytes[k++] = 0; // Filter
   80.95 +                for (int j = 0; j < width; j++)
   80.96 +                {
   80.97 +                    bytes[k++] = pixels[i, j].R;
   80.98 +                    bytes[k++] = pixels[i, j].G;
   80.99 +                    bytes[k++] = pixels[i, j].B;
  80.100 +                    bytes[k++] = pixels[i, j].A;
  80.101 +                }
  80.102 +            }
  80.103 +
  80.104 +            var w = new MemoryWriter();
  80.105 +            w.Write((byte)0x89);
  80.106 +            w.Write("PNG\r\n\x1a\n".ToCharArray());
  80.107 +            WriteChunk(w, "IHDR", CreateHeaderData(width, height));
  80.108 +            WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi));
  80.109 +            WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes));
  80.110 +            WriteChunk(w, "IEND", new byte[0]);
  80.111 +            return w.ToArray();
  80.112 +        }
  80.113 +
  80.114 +        /// <summary>
  80.115 +        /// Calculates the Adler-32 check sum.
  80.116 +        /// </summary>
  80.117 +        /// <param name="data">
  80.118 +        /// The data.
  80.119 +        /// </param>
  80.120 +        /// <returns>
  80.121 +        /// The check sum.
  80.122 +        /// </returns>
  80.123 +        private static uint Adler32(IEnumerable<byte> data)
  80.124 +        {
  80.125 +            // http://en.wikipedia.org/wiki/Adler-32
  80.126 +            uint a = 1;
  80.127 +            uint b = 0;
  80.128 +            const uint ModAdler = 65521;
  80.129 +            foreach (var x in data)
  80.130 +            {
  80.131 +                a = (a + x) % ModAdler;
  80.132 +                b = (b + a) % ModAdler;
  80.133 +            }
  80.134 +
  80.135 +            return (b << 16) | a;
  80.136 +        }
  80.137 +
  80.138 +        /// <summary>
  80.139 +        /// Creates the header data.
  80.140 +        /// </summary>
  80.141 +        /// <param name="width">
  80.142 +        /// The width.
  80.143 +        /// </param>
  80.144 +        /// <param name="height">
  80.145 +        /// The height.
  80.146 +        /// </param>
  80.147 +        /// <returns>
  80.148 +        /// The header.
  80.149 +        /// </returns>
  80.150 +        private static byte[] CreateHeaderData(int width, int height)
  80.151 +        {
  80.152 +            // http://www.w3.org/TR/PNG-Chunks.html
  80.153 +            var w = new MemoryWriter();
  80.154 +            WriteBigEndian(w, width);
  80.155 +            WriteBigEndian(w, height);
  80.156 +            w.Write((byte)8); // bit depth
  80.157 +            w.Write((byte)6); // color type RGBA
  80.158 +            w.Write((byte)0); // compression method
  80.159 +            w.Write((byte)0); // filter method
  80.160 +            w.Write((byte)0); // interlace method
  80.161 +            return w.ToArray();
  80.162 +        }
  80.163 +
  80.164 +        /// <summary>
  80.165 +        /// Creates the physical dimensions data.
  80.166 +        /// </summary>
  80.167 +        /// <param name="dpix">
  80.168 +        /// The horizontal resolution.
  80.169 +        /// </param>
  80.170 +        /// <param name="dpiy">
  80.171 +        /// The vertical resolution.
  80.172 +        /// </param>
  80.173 +        /// <returns>
  80.174 +        /// The data.
  80.175 +        /// </returns>
  80.176 +        private static byte[] CreatePhysicalDimensionsData(int dpix, int dpiy)
  80.177 +        {
  80.178 +            var ppux = (int)(dpix / 0.0254);
  80.179 +            var ppuy = (int)(dpiy / 0.0254);
  80.180 +            var w = new MemoryWriter();
  80.181 +            WriteBigEndian(w, ppux);
  80.182 +            WriteBigEndian(w, ppuy);
  80.183 +            w.Write((byte)1); // Unit: metre
  80.184 +            return w.ToArray();
  80.185 +        }
  80.186 +
  80.187 +        /// <summary>
  80.188 +        /// Creates the uncompressed blocks.
  80.189 +        /// </summary>
  80.190 +        /// <param name="bytes">
  80.191 +        /// The data.
  80.192 +        /// </param>
  80.193 +        /// <returns>
  80.194 +        /// The output data.
  80.195 +        /// </returns>
  80.196 +        private static byte[] CreateUncompressedBlocks(byte[] bytes)
  80.197 +        {
  80.198 +            // http://www.w3.org/TR/PNG-Compression.html
  80.199 +            const int MaxDeflate = 0xFFFF;
  80.200 +            var w = new MemoryWriter();
  80.201 +            const uint CompressionMethod = 8;
  80.202 +            const uint Check = (31 - ((CompressionMethod << 8) % 31)) % 31;
  80.203 +            w.Write((byte)CompressionMethod);
  80.204 +            w.Write((byte)Check);
  80.205 +            for (int i = 0; i < bytes.Length; i += MaxDeflate)
  80.206 +            {
  80.207 +                var n = (ushort)Math.Min(bytes.Length - i, MaxDeflate);
  80.208 +                var last = (byte)(i + n < bytes.Length ? 0 : 1);
  80.209 +                w.Write(last);
  80.210 +                w.Write((byte)(n & 0xFF));
  80.211 +                w.Write((byte)((n >> 8) & 0xFF));
  80.212 +                var n2 = ~n;
  80.213 +                w.Write((byte)(n2 & 0xFF));
  80.214 +                w.Write((byte)((n2 >> 8) & 0xFF));
  80.215 +                w.Write(bytes, i, n);
  80.216 +            }
  80.217 +
  80.218 +            WriteBigEndian(w, Adler32(bytes));
  80.219 +            return w.ToArray();
  80.220 +        }
  80.221 +
  80.222 +        /// <summary>
  80.223 +        /// Updates the CRC check sum.
  80.224 +        /// </summary>
  80.225 +        /// <param name="crc">
  80.226 +        /// The input CRC.
  80.227 +        /// </param>
  80.228 +        /// <param name="data">
  80.229 +        /// The data.
  80.230 +        /// </param>
  80.231 +        /// <returns>
  80.232 +        /// The updated CRC.
  80.233 +        /// </returns>
  80.234 +        private static ulong UpdateCrc(ulong crc, IEnumerable<byte> data)
  80.235 +        {
  80.236 +            return data.Aggregate(crc, (current, x) => CrcTable[(current ^ x) & 0xff] ^ (current >> 8));
  80.237 +        }
  80.238 +
  80.239 +        /// <summary>
  80.240 +        /// Writes the integer value with big endian byte order.
  80.241 +        /// </summary>
  80.242 +        /// <param name="w">
  80.243 +        /// The writer.
  80.244 +        /// </param>
  80.245 +        /// <param name="value">
  80.246 +        /// The value.
  80.247 +        /// </param>
  80.248 +        private static void WriteBigEndian(BinaryWriter w, int value)
  80.249 +        {
  80.250 +            var bytes = BitConverter.GetBytes(value);
  80.251 +            w.Write(bytes[3]);
  80.252 +            w.Write(bytes[2]);
  80.253 +            w.Write(bytes[1]);
  80.254 +            w.Write(bytes[0]);
  80.255 +        }
  80.256 +
  80.257 +        /// <summary>
  80.258 +        /// Writes the unsigned integer value with big endian byte order.
  80.259 +        /// </summary>
  80.260 +        /// <param name="w">
  80.261 +        /// The writer.
  80.262 +        /// </param>
  80.263 +        /// <param name="value">
  80.264 +        /// The value.
  80.265 +        /// </param>
  80.266 +        private static void WriteBigEndian(BinaryWriter w, uint value)
  80.267 +        {
  80.268 +            var bytes = BitConverter.GetBytes(value);
  80.269 +            w.Write(bytes[3]);
  80.270 +            w.Write(bytes[2]);
  80.271 +            w.Write(bytes[1]);
  80.272 +            w.Write(bytes[0]);
  80.273 +        }
  80.274 +
  80.275 +        /// <summary>
  80.276 +        /// Writes a png chunk.
  80.277 +        /// </summary>
  80.278 +        /// <param name="w">
  80.279 +        /// The writer.
  80.280 +        /// </param>
  80.281 +        /// <param name="type">
  80.282 +        /// The chunk type.
  80.283 +        /// </param>
  80.284 +        /// <param name="data">
  80.285 +        /// The chunk data.
  80.286 +        /// </param>
  80.287 +        private static void WriteChunk(BinaryWriter w, string type, byte[] data)
  80.288 +        {
  80.289 +            var ty = type.ToCharArray().Select(ch => (byte)ch).ToArray();
  80.290 +            WriteBigEndian(w, data.Length);
  80.291 +            w.Write(ty);
  80.292 +            w.Write(data);
  80.293 +
  80.294 +            var c = 0xffffffff;
  80.295 +            c = (uint)UpdateCrc(c, ty);
  80.296 +            c = (uint)UpdateCrc(c, data);
  80.297 +            var crc = c ^ 0xffffffff;
  80.298 +
  80.299 +            WriteBigEndian(w, crc);
  80.300 +        }
  80.301 +
  80.302 +        /// <summary>
  80.303 +        /// Provides a binary writer that writes to memory.
  80.304 +        /// </summary>
  80.305 +        private class MemoryWriter : BinaryWriter
  80.306 +        {
  80.307 +            /// <summary>
  80.308 +            /// Initializes a new instance of the <see cref="MemoryWriter" /> class.
  80.309 +            /// </summary>
  80.310 +            public MemoryWriter()
  80.311 +                : base(new MemoryStream())
  80.312 +            {
  80.313 +            }
  80.314 +
  80.315 +            /// <summary>
  80.316 +            /// Gets the content as a byte array.
  80.317 +            /// </summary>
  80.318 +            /// <returns>The byte array.</returns>
  80.319 +            public byte[] ToArray()
  80.320 +            {
  80.321 +                this.BaseStream.Flush();
  80.322 +                return ((MemoryStream)this.BaseStream).ToArray();
  80.323 +            }
  80.324 +        }
  80.325 +    }
  80.326 +}
  80.327 \ No newline at end of file
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Point.cs	Sat Jun 08 16:53:22 2013 +0000
    81.3 @@ -0,0 +1,58 @@
    81.4 +// --------------------------------------------------------------------------------------------------------------------
    81.5 +// <copyright file="Point.cs" company="OxyPlot">
    81.6 +//   The MIT License (MIT)
    81.7 +//
    81.8 +//   Copyright (c) 2012 Oystein Bjorke
    81.9 +//
   81.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   81.11 +//   copy of this software and associated documentation files (the
   81.12 +//   "Software"), to deal in the Software without restriction, including
   81.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   81.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   81.15 +//   permit persons to whom the Software is furnished to do so, subject to
   81.16 +//   the following conditions:
   81.17 +//
   81.18 +//   The above copyright notice and this permission notice shall be included
   81.19 +//   in all copies or substantial portions of the Software.
   81.20 +//
   81.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   81.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   81.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   81.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   81.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   81.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   81.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   81.28 +// </copyright>
   81.29 +// --------------------------------------------------------------------------------------------------------------------
   81.30 +namespace OxyPlot
   81.31 +{
   81.32 +    public struct Point
   81.33 +    {
   81.34 +        internal double x;
   81.35 +
   81.36 +        internal double y;
   81.37 +
   81.38 +        public Point(double x, double y)
   81.39 +        {
   81.40 +            this.x = x;
   81.41 +            this.y = y;
   81.42 +        }
   81.43 +
   81.44 +        public double X
   81.45 +        {
   81.46 +            get { return x; }
   81.47 +            set { x = value; }
   81.48 +        }
   81.49 +
   81.50 +        public double Y
   81.51 +        {
   81.52 +            get { return y; }
   81.53 +            set { y = value; }
   81.54 +        }
   81.55 +
   81.56 +        public override string ToString()
   81.57 +        {
   81.58 +            return x + " " + y;
   81.59 +        }
   81.60 +    }
   81.61 +}
   81.62 \ No newline at end of file
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Rectangle.cs	Sat Jun 08 16:53:22 2013 +0000
    82.3 @@ -0,0 +1,36 @@
    82.4 +// --------------------------------------------------------------------------------------------------------------------
    82.5 +// <copyright file="Rectangle.cs" company="OxyPlot">
    82.6 +//   The MIT License (MIT)
    82.7 +//
    82.8 +//   Copyright (c) 2012 Oystein Bjorke
    82.9 +//
   82.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   82.11 +//   copy of this software and associated documentation files (the
   82.12 +//   "Software"), to deal in the Software without restriction, including
   82.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   82.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   82.15 +//   permit persons to whom the Software is furnished to do so, subject to
   82.16 +//   the following conditions:
   82.17 +//
   82.18 +//   The above copyright notice and this permission notice shall be included
   82.19 +//   in all copies or substantial portions of the Software.
   82.20 +//
   82.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   82.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   82.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   82.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   82.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   82.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   82.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   82.28 +// </copyright>
   82.29 +// --------------------------------------------------------------------------------------------------------------------
   82.30 +namespace OxyPlot
   82.31 +{
   82.32 +    public struct Rectangle
   82.33 +    {
   82.34 +        public double Top { get; set; }
   82.35 +        public double Bottom { get; set; }
   82.36 +        public double Left { get; set; }
   82.37 +        public double Right { get; set; }
   82.38 +    }
   82.39 +}
   82.40 \ No newline at end of file
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ReflectionHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    83.3 @@ -0,0 +1,81 @@
    83.4 +// --------------------------------------------------------------------------------------------------------------------
    83.5 +// <copyright file="ReflectionHelper.cs" company="OxyPlot">
    83.6 +//   The MIT License (MIT)
    83.7 +//
    83.8 +//   Copyright (c) 2012 Oystein Bjorke
    83.9 +//
   83.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   83.11 +//   copy of this software and associated documentation files (the
   83.12 +//   "Software"), to deal in the Software without restriction, including
   83.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   83.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   83.15 +//   permit persons to whom the Software is furnished to do so, subject to
   83.16 +//   the following conditions:
   83.17 +//
   83.18 +//   The above copyright notice and this permission notice shall be included
   83.19 +//   in all copies or substantial portions of the Software.
   83.20 +//
   83.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   83.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   83.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   83.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   83.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   83.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   83.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   83.28 +// </copyright>
   83.29 +// <summary>
   83.30 +//   Provides reflection based support methods.
   83.31 +// </summary>
   83.32 +// --------------------------------------------------------------------------------------------------------------------
   83.33 +namespace OxyPlot
   83.34 +{
   83.35 +    using System;
   83.36 +    using System.Collections;
   83.37 +    using System.Collections.Generic;
   83.38 +    using System.Globalization;
   83.39 +    using System.Reflection;
   83.40 +
   83.41 +    /// <summary>
   83.42 +    /// Provides utility methods reflection based support methods.
   83.43 +    /// </summary>
   83.44 +    public static class ReflectionHelper
   83.45 +    {
   83.46 +        /// <summary>
   83.47 +        /// Fills a list by the specified property of a source list/enumerable.
   83.48 +        /// </summary>
   83.49 +        /// <param name="source">
   83.50 +        /// The source list.
   83.51 +        /// </param>
   83.52 +        /// <param name="propertyName">
   83.53 +        /// The property name.
   83.54 +        /// </param>
   83.55 +        /// <param name="list">
   83.56 +        /// The list to be filled.
   83.57 +        /// </param>
   83.58 +        /// <typeparam name="T">
   83.59 +        /// The type of the destination list items (and the source property).
   83.60 +        /// </typeparam>
   83.61 +        public static void FillList<T>(IEnumerable source, string propertyName, IList<T> list)
   83.62 +        {
   83.63 +            PropertyInfo pi = null;
   83.64 +            Type t = null;
   83.65 +            foreach (var o in source)
   83.66 +            {
   83.67 +                if (pi == null || o.GetType() != t)
   83.68 +                {
   83.69 +                    t = o.GetType();
   83.70 +                    pi = t.GetProperty(propertyName);
   83.71 +                    if (pi == null)
   83.72 +                    {
   83.73 +                        throw new InvalidOperationException(
   83.74 +                            string.Format("Could not find field {0} on type {1}", propertyName, t));
   83.75 +                    }
   83.76 +                }
   83.77 +
   83.78 +                var v = pi.GetValue(o, null);
   83.79 +                var value = (T)Convert.ChangeType(v, typeof(T), CultureInfo.InvariantCulture);
   83.80 +                list.Add(value);
   83.81 +            }
   83.82 +        }
   83.83 +    }
   83.84 +}
   83.85 \ No newline at end of file
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ScreenPoint.cs	Sat Jun 08 16:53:22 2013 +0000
    84.3 @@ -0,0 +1,198 @@
    84.4 +// --------------------------------------------------------------------------------------------------------------------
    84.5 +// <copyright file="ScreenPoint.cs" company="OxyPlot">
    84.6 +//   The MIT License (MIT)
    84.7 +//
    84.8 +//   Copyright (c) 2012 Oystein Bjorke
    84.9 +//
   84.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   84.11 +//   copy of this software and associated documentation files (the
   84.12 +//   "Software"), to deal in the Software without restriction, including
   84.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   84.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   84.15 +//   permit persons to whom the Software is furnished to do so, subject to
   84.16 +//   the following conditions:
   84.17 +//
   84.18 +//   The above copyright notice and this permission notice shall be included
   84.19 +//   in all copies or substantial portions of the Software.
   84.20 +//
   84.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   84.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   84.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   84.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   84.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   84.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   84.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   84.28 +// </copyright>
   84.29 +// <summary>
   84.30 +//   Describes a point defined in the screen coordinate system.
   84.31 +// </summary>
   84.32 +// --------------------------------------------------------------------------------------------------------------------
   84.33 +namespace OxyPlot
   84.34 +{
   84.35 +    using System;
   84.36 +
   84.37 +    /// <summary>
   84.38 +    /// Represents a point defined in the screen coordinate system.
   84.39 +    /// </summary>
   84.40 +    /// <remarks>
   84.41 +    /// The rendering methods transforms <see cref="DataPoint"/>s to <see cref="ScreenPoint"/>s.
   84.42 +    /// </remarks>
   84.43 +    public struct ScreenPoint
   84.44 +    {
   84.45 +        /// <summary>
   84.46 +        /// The undefined point.
   84.47 +        /// </summary>
   84.48 +        public static readonly ScreenPoint Undefined = new ScreenPoint(double.NaN, double.NaN);
   84.49 +
   84.50 +        /// <summary>
   84.51 +        /// The x-coordinate.
   84.52 +        /// </summary>
   84.53 +        internal double x;
   84.54 +
   84.55 +        /// <summary>
   84.56 +        /// The y-coordinate.
   84.57 +        /// </summary>
   84.58 +        internal double y;
   84.59 +
   84.60 +        /// <summary>
   84.61 +        /// Initializes a new instance of the <see cref="ScreenPoint"/> struct.
   84.62 +        /// </summary>
   84.63 +        /// <param name="x">
   84.64 +        /// The x-coordinate.
   84.65 +        /// </param>
   84.66 +        /// <param name="y">
   84.67 +        /// The y-coordinate.
   84.68 +        /// </param>
   84.69 +        public ScreenPoint(double x, double y)
   84.70 +        {
   84.71 +            this.x = x;
   84.72 +            this.y = y;
   84.73 +        }
   84.74 +
   84.75 +        /// <summary>
   84.76 +        /// Gets or sets the x-coordinate.
   84.77 +        /// </summary>
   84.78 +        /// <value> The x-coordinate. </value>
   84.79 +        public double X
   84.80 +        {
   84.81 +            get
   84.82 +            {
   84.83 +                return this.x;
   84.84 +            }
   84.85 +
   84.86 +            set
   84.87 +            {
   84.88 +                this.x = value;
   84.89 +            }
   84.90 +        }
   84.91 +
   84.92 +        /// <summary>
   84.93 +        /// Gets or sets the y-coordinate.
   84.94 +        /// </summary>
   84.95 +        /// <value> The y-coordinate. </value>
   84.96 +        public double Y
   84.97 +        {
   84.98 +            get
   84.99 +            {
  84.100 +                return this.y;
  84.101 +            }
  84.102 +
  84.103 +            set
  84.104 +            {
  84.105 +                this.y = value;
  84.106 +            }
  84.107 +        }
  84.108 +
  84.109 +        /// <summary>
  84.110 +        /// Determines whether the specified point is undefined.
  84.111 +        /// </summary>
  84.112 +        /// <param name="point">
  84.113 +        /// The point.
  84.114 +        /// </param>
  84.115 +        /// <returns>
  84.116 +        /// <c>true</c> if the specified point is undefined; otherwise, <c>false</c> .
  84.117 +        /// </returns>
  84.118 +        public static bool IsUndefined(ScreenPoint point)
  84.119 +        {
  84.120 +            return double.IsNaN(point.X) && double.IsNaN(point.Y);
  84.121 +        }
  84.122 +
  84.123 +        /// <summary>
  84.124 +        /// Gets the distance to the specified point.
  84.125 +        /// </summary>
  84.126 +        /// <param name="point">
  84.127 +        /// The point.
  84.128 +        /// </param>
  84.129 +        /// <returns>
  84.130 +        /// The distance.
  84.131 +        /// </returns>
  84.132 +        public double DistanceTo(ScreenPoint point)
  84.133 +        {
  84.134 +            double dx = point.x - this.x;
  84.135 +            double dy = point.y - this.y;
  84.136 +            return Math.Sqrt((dx * dx) + (dy * dy));
  84.137 +        }
  84.138 +
  84.139 +        /// <summary>
  84.140 +        /// Gets the squared distance to the specified point.
  84.141 +        /// </summary>
  84.142 +        /// <param name="point">
  84.143 +        /// The point.
  84.144 +        /// </param>
  84.145 +        /// <returns>
  84.146 +        /// The squared distance.
  84.147 +        /// </returns>
  84.148 +        public double DistanceToSquared(ScreenPoint point)
  84.149 +        {
  84.150 +            double dx = point.x - this.x;
  84.151 +            double dy = point.y - this.y;
  84.152 +            return (dx * dx) + (dy * dy);
  84.153 +        }
  84.154 +
  84.155 +        /// <summary>
  84.156 +        /// Returns a <see cref="System.String"/> that represents this instance.
  84.157 +        /// </summary>
  84.158 +        /// <returns>
  84.159 +        /// A <see cref="System.String"/> that represents this instance.
  84.160 +        /// </returns>
  84.161 +        public override string ToString()
  84.162 +        {
  84.163 +            return this.x + " " + this.y;
  84.164 +        }
  84.165 +
  84.166 +        /// <summary>
  84.167 +        /// Translates a <see cref="ScreenPoint"/> by a <see cref="ScreenVector"/>.
  84.168 +        /// </summary>
  84.169 +        /// <param name="p1"> The point. </param>
  84.170 +        /// <param name="p2"> The vector. </param>
  84.171 +        /// <returns> The translated point. </returns>
  84.172 +        public static ScreenPoint operator +(ScreenPoint p1, ScreenVector p2)
  84.173 +        {
  84.174 +            return new ScreenPoint(p1.x + p2.x, p1.y + p2.y);
  84.175 +        }
  84.176 +
  84.177 +        /// <summary>
  84.178 +        /// Subtracts a <see cref="ScreenPoint"/> from a <see cref="ScreenPoint"/>
  84.179 +        /// and returns the result as a <see cref="ScreenVector"/>.
  84.180 +        /// </summary>
  84.181 +        /// <param name="p1"> The point on which to perform the subtraction. </param>
  84.182 +        /// <param name="p2"> The point to subtract from p1. </param>
  84.183 +        /// <returns> A <see cref="ScreenVector"/> structure that represents the difference between p1 and p2. </returns>
  84.184 +        public static ScreenVector operator -(ScreenPoint p1, ScreenPoint p2)
  84.185 +        {
  84.186 +            return new ScreenVector(p1.x - p2.x, p1.y - p2.y);
  84.187 +        }
  84.188 +
  84.189 +        /// <summary>
  84.190 +        /// Subtracts a <see cref="ScreenVector"/> from a <see cref="ScreenPoint"/> 
  84.191 +        /// and returns the result as a <see cref="ScreenPoint"/>.
  84.192 +        /// </summary>
  84.193 +        /// <param name="point"> The point on which to perform the subtraction. </param>
  84.194 +        /// <param name="vector"> The vector to subtract from p1. </param>
  84.195 +        /// <returns> A <see cref="ScreenPoint"/> that represents point translated by the negative vector. </returns>
  84.196 +        public static ScreenPoint operator -(ScreenPoint point, ScreenVector vector)
  84.197 +        {
  84.198 +            return new ScreenPoint(point.x - vector.x, point.y - vector.y);
  84.199 +        }
  84.200 +    }
  84.201 +}
  84.202 \ No newline at end of file
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ScreenPointHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    85.3 @@ -0,0 +1,255 @@
    85.4 +// --------------------------------------------------------------------------------------------------------------------
    85.5 +// <copyright file="ScreenPointHelper.cs" company="OxyPlot">
    85.6 +//   The MIT License (MIT)
    85.7 +//   
    85.8 +//   Copyright (c) 2012 Oystein Bjorke
    85.9 +//   
   85.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   85.11 +//   copy of this software and associated documentation files (the
   85.12 +//   "Software"), to deal in the Software without restriction, including
   85.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   85.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   85.15 +//   permit persons to whom the Software is furnished to do so, subject to
   85.16 +//   the following conditions:
   85.17 +//   
   85.18 +//   The above copyright notice and this permission notice shall be included
   85.19 +//   in all copies or substantial portions of the Software.
   85.20 +//   
   85.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   85.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   85.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   85.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   85.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   85.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   85.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   85.28 +// </copyright>
   85.29 +// <summary>
   85.30 +//   Provides various algorithms for polygons and lines of ScreenPoint.
   85.31 +// </summary>
   85.32 +// --------------------------------------------------------------------------------------------------------------------
   85.33 +namespace OxyPlot
   85.34 +{
   85.35 +    using System.Collections.Generic;
   85.36 +
   85.37 +    /// <summary>
   85.38 +    /// Provides algorithms for polygons and lines of <see cref="ScreenPoint"/>.
   85.39 +    /// </summary>
   85.40 +    public static class ScreenPointHelper
   85.41 +    {
   85.42 +        /// <summary>
   85.43 +        /// Finds the nearest point on the specified polyline.
   85.44 +        /// </summary>
   85.45 +        /// <param name="point">
   85.46 +        /// The point.
   85.47 +        /// </param>
   85.48 +        /// <param name="points">
   85.49 +        /// The points.
   85.50 +        /// </param>
   85.51 +        /// <returns>
   85.52 +        /// The nearest point.
   85.53 +        /// </returns>
   85.54 +        public static ScreenPoint FindNearestPointOnPolyline(ScreenPoint point, IList<ScreenPoint> points)
   85.55 +        {
   85.56 +            double minimumDistance = double.MaxValue;
   85.57 +            var nearestPoint = default(ScreenPoint);
   85.58 +
   85.59 +            for (int i = 0; i + 1 < points.Count; i++)
   85.60 +            {
   85.61 +                var p1 = points[i];
   85.62 +                var p2 = points[i + 1];
   85.63 +                if (ScreenPoint.IsUndefined(p1) || ScreenPoint.IsUndefined(p2))
   85.64 +                {
   85.65 +                    continue;
   85.66 +                }
   85.67 +
   85.68 +                // Find the nearest point on the line segment.
   85.69 +                var nearestPointOnSegment = FindPointOnLine(point, p1, p2);
   85.70 +
   85.71 +                if (ScreenPoint.IsUndefined(nearestPointOnSegment))
   85.72 +                {
   85.73 +                    continue;
   85.74 +                }
   85.75 +
   85.76 +                double l2 = (point - nearestPointOnSegment).LengthSquared;
   85.77 +
   85.78 +                if (l2 < minimumDistance)
   85.79 +                {
   85.80 +                    nearestPoint = nearestPointOnSegment;
   85.81 +                    minimumDistance = l2;
   85.82 +                }
   85.83 +            }
   85.84 +
   85.85 +            return nearestPoint;
   85.86 +        }
   85.87 +
   85.88 +        /// <summary>
   85.89 +        /// Finds the point on line.
   85.90 +        /// </summary>
   85.91 +        /// <param name="p">
   85.92 +        /// The point.
   85.93 +        /// </param>
   85.94 +        /// <param name="p1">
   85.95 +        /// The first point on the line.
   85.96 +        /// </param>
   85.97 +        /// <param name="p2">
   85.98 +        /// The second point on the line.
   85.99 +        /// </param>
  85.100 +        /// <returns>
  85.101 +        /// The nearest point on the line.
  85.102 +        /// </returns>
  85.103 +        /// <remarks>
  85.104 +        /// See <a href="http://paulbourke.net/geometry/pointlineplane/">Bourke</a>.
  85.105 +        /// </remarks>
  85.106 +        public static ScreenPoint FindPointOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
  85.107 +        {
  85.108 +            double dx = p2.x - p1.x;
  85.109 +            double dy = p2.y - p1.y;
  85.110 +            double u = FindPositionOnLine(p, p1, p2);
  85.111 +
  85.112 +            if (double.IsNaN(u))
  85.113 +            {
  85.114 +                u = 0;
  85.115 +            }
  85.116 +
  85.117 +            if (u < 0)
  85.118 +            {
  85.119 +                u = 0;
  85.120 +            }
  85.121 +
  85.122 +            if (u > 1)
  85.123 +            {
  85.124 +                u = 1;
  85.125 +            }
  85.126 +
  85.127 +            return new ScreenPoint(p1.x + (u * dx), p1.y + (u * dy));
  85.128 +        }
  85.129 +
  85.130 +        /// <summary>
  85.131 +        /// Finds the nearest point on line.
  85.132 +        /// </summary>
  85.133 +        /// <param name="p">
  85.134 +        /// The point.
  85.135 +        /// </param>
  85.136 +        /// <param name="p1">
  85.137 +        /// The start point on the line.
  85.138 +        /// </param>
  85.139 +        /// <param name="p2">
  85.140 +        /// The end point on the line.
  85.141 +        /// </param>
  85.142 +        /// <returns>
  85.143 +        /// The relative position of the nearest point.
  85.144 +        /// </returns>
  85.145 +        /// <remarks>
  85.146 +        /// See <a href="http://paulbourke.net/geometry/pointlineplane/">Bourke</a>.
  85.147 +        /// </remarks>
  85.148 +        public static double FindPositionOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
  85.149 +        {
  85.150 +            double dx = p2.x - p1.x;
  85.151 +            double dy = p2.y - p1.y;
  85.152 +            double u1 = ((p.x - p1.x) * dx) + ((p.y - p1.y) * dy);
  85.153 +            double u2 = (dx * dx) + (dy * dy);
  85.154 +
  85.155 +            if (u2 < 1e-6)
  85.156 +            {
  85.157 +                return double.NaN;
  85.158 +            }
  85.159 +
  85.160 +            return u1 / u2;
  85.161 +        }
  85.162 +
  85.163 +        /// <summary>
  85.164 +        /// Determines whether the specified point is in the specified polygon.
  85.165 +        /// </summary>
  85.166 +        /// <param name="p">
  85.167 +        /// The point.
  85.168 +        /// </param>
  85.169 +        /// <param name="pts">
  85.170 +        /// The polygon points.
  85.171 +        /// </param>
  85.172 +        /// <returns>
  85.173 +        /// <c>true</c> if the point is in the polygon; otherwise, <c>false</c>.
  85.174 +        /// </returns>
  85.175 +        public static bool IsPointInPolygon(ScreenPoint p, IList<ScreenPoint> pts)
  85.176 +        {
  85.177 +            int nvert = pts.Count;
  85.178 +            bool c = false;
  85.179 +            for (int i = 0, j = nvert - 1; i < nvert; j = i++)
  85.180 +            {
  85.181 +                if (((pts[i].Y > p.Y) != (pts[j].Y > p.Y))
  85.182 +                    && (p.X < ((pts[j].X - pts[i].X) * ((p.Y - pts[i].Y) / (pts[j].Y - pts[i].Y))) + pts[i].X))
  85.183 +                {
  85.184 +                    c = !c;
  85.185 +                }
  85.186 +            }
  85.187 +
  85.188 +            return c;
  85.189 +        }
  85.190 +
  85.191 +        /// <summary>
  85.192 +        /// Resamples the points with the specified point distance limit.
  85.193 +        /// </summary>
  85.194 +        /// <param name="allPoints">
  85.195 +        /// All points.
  85.196 +        /// </param>
  85.197 +        /// <param name="minimumDistance">
  85.198 +        /// The minimum squared distance.
  85.199 +        /// </param>
  85.200 +        /// <returns>
  85.201 +        /// List of resampled points.
  85.202 +        /// </returns>
  85.203 +        public static IList<ScreenPoint> ResamplePoints(IList<ScreenPoint> allPoints, double minimumDistance)
  85.204 +        {
  85.205 +            double minimumSquaredDistance = minimumDistance * minimumDistance;
  85.206 +            int n = allPoints.Count;
  85.207 +            var result = new List<ScreenPoint>(n);
  85.208 +            if (n > 0)
  85.209 +            {
  85.210 +                result.Add(allPoints[0]);
  85.211 +                int i0 = 0;
  85.212 +                for (int i = 1; i < n; i++)
  85.213 +                {
  85.214 +                    double distSquared = allPoints[i0].DistanceToSquared(allPoints[i]);
  85.215 +                    if (distSquared < minimumSquaredDistance && i != n - 1)
  85.216 +                    {
  85.217 +                        continue;
  85.218 +                    }
  85.219 +
  85.220 +                    i0 = i;
  85.221 +                    result.Add(allPoints[i]);
  85.222 +                }
  85.223 +            }
  85.224 +
  85.225 +            return result;
  85.226 +        }
  85.227 +
  85.228 +        /// <summary>
  85.229 +        /// Gets the centroid of the specified polygon.
  85.230 +        /// </summary>
  85.231 +        /// <param name="points">
  85.232 +        /// The points.
  85.233 +        /// </param>
  85.234 +        /// <returns>
  85.235 +        /// The centroid.
  85.236 +        /// </returns>
  85.237 +        public static ScreenPoint GetCentroid(IList<ScreenPoint> points)
  85.238 +        {
  85.239 +            double cx = 0;
  85.240 +            double cy = 0;
  85.241 +            double a = 0;
  85.242 +
  85.243 +            for (int i = 0; i < points.Count; i++)
  85.244 +            {
  85.245 +                int i1 = (i + 1) % points.Count;
  85.246 +                double da = (points[i].x * points[i1].y) - (points[i1].x * points[i].y);
  85.247 +                cx += (points[i].x + points[i1].x) * da;
  85.248 +                cy += (points[i].y + points[i1].y) * da;
  85.249 +                a += da;
  85.250 +            }
  85.251 +
  85.252 +            a *= 0.5;
  85.253 +            cx /= 6 * a;
  85.254 +            cy /= 6 * a;
  85.255 +            return new ScreenPoint(cx, cy);
  85.256 +        }
  85.257 +    }
  85.258 +}
  85.259 \ No newline at end of file
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/External/OxyPlot/OxyPlot/Foundation/ScreenVector.cs	Sat Jun 08 16:53:22 2013 +0000
    86.3 @@ -0,0 +1,155 @@
    86.4 +// --------------------------------------------------------------------------------------------------------------------
    86.5 +// <copyright file="ScreenVector.cs" company="OxyPlot">
    86.6 +//   The MIT License (MIT)
    86.7 +//
    86.8 +//   Copyright (c) 2012 Oystein Bjorke
    86.9 +//
   86.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   86.11 +//   copy of this software and associated documentation files (the
   86.12 +//   "Software"), to deal in the Software without restriction, including
   86.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   86.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   86.15 +//   permit persons to whom the Software is furnished to do so, subject to
   86.16 +//   the following conditions:
   86.17 +//
   86.18 +//   The above copyright notice and this permission notice shall be included
   86.19 +//   in all copies or substantial portions of the Software.
   86.20 +//
   86.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   86.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   86.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   86.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   86.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   86.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   86.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   86.28 +// </copyright>
   86.29 +// <summary>
   86.30 +//   Represents a vector defined in the screen coordinate system.
   86.31 +// </summary>
   86.32 +// --------------------------------------------------------------------------------------------------------------------
   86.33 +namespace OxyPlot
   86.34 +{
   86.35 +    using System;
   86.36 +
   86.37 +    /// <summary>
   86.38 +    /// Represents a vector defined in the screen coordinate system.
   86.39 +    /// </summary>
   86.40 +    public struct ScreenVector
   86.41 +    {
   86.42 +        /// <summary>
   86.43 +        /// The x-coordinate.
   86.44 +        /// </summary>
   86.45 +        internal double x;
   86.46 +
   86.47 +        /// <summary>
   86.48 +        /// The y-coordinate.
   86.49 +        /// </summary>
   86.50 +        internal double y;
   86.51 +
   86.52 +        /// <summary>
   86.53 +        /// Initializes a new instance of the <see cref="ScreenVector"/> structure.
   86.54 +        /// </summary>
   86.55 +        /// <param name="x">
   86.56 +        /// The x-coordinate.
   86.57 +        /// </param>
   86.58 +        /// <param name="y">
   86.59 +        /// The y-coordinate.
   86.60 +        /// </param>
   86.61 +        public ScreenVector(double x, double y)
   86.62 +        {
   86.63 +            this.x = x;
   86.64 +            this.y = y;
   86.65 +        }
   86.66 +
   86.67 +        /// <summary>
   86.68 +        /// Gets the length.
   86.69 +        /// </summary>
   86.70 +        public double Length
   86.71 +        {
   86.72 +            get
   86.73 +            {
   86.74 +                return Math.Sqrt((this.x * this.x) + (this.y * this.y));
   86.75 +            }
   86.76 +        }
   86.77 +
   86.78 +        /// <summary>
   86.79 +        /// Gets the length squared.
   86.80 +        /// </summary>
   86.81 +        public double LengthSquared
   86.82 +        {
   86.83 +            get
   86.84 +            {
   86.85 +                return (this.x * this.x) + (this.y * this.y);
   86.86 +            }
   86.87 +        }
   86.88 +
   86.89 +        /// <summary>
   86.90 +        /// Gets or sets the x-coordinate.
   86.91 +        /// </summary>
   86.92 +        /// <value> The x-coordinate. </value>
   86.93 +        public double X
   86.94 +        {
   86.95 +            get
   86.96 +            {
   86.97 +                return this.x;
   86.98 +            }
   86.99 +
  86.100 +            set
  86.101 +            {
  86.102 +                this.x = value;
  86.103 +            }
  86.104 +        }
  86.105 +
  86.106 +        /// <summary>
  86.107 +        /// Gets or sets the y-coordinate.
  86.108 +        /// </summary>
  86.109 +        /// <value> The y-coordinate. </value>
  86.110 +        public double Y
  86.111 +        {
  86.112 +            get
  86.113 +            {
  86.114 +                return this.y;
  86.115 +            }
  86.116 +
  86.117 +            set
  86.118 +            {
  86.119 +                this.y = value;
  86.120 +            }
  86.121 +        }
  86.122 +
  86.123 +        /// <summary>
  86.124 +        /// Normalizes this vector.
  86.125 +        /// </summary>
  86.126 +        public void Normalize()
  86.127 +        {
  86.128 +            double l = Math.Sqrt((this.x * this.x) + (this.y * this.y));
  86.129 +            if (l > 0)
  86.130 +            {
  86.131 +                this.x /= l;
  86.132 +                this.y /= l;
  86.133 +            }
  86.134 +        }
  86.135 +
  86.136 +        /// <summary>
  86.137 +        /// Returns a <see cref="System.String"/> that represents this instance.
  86.138 +        /// </summary>
  86.139 +        /// <returns>
  86.140 +        /// A <see cref="System.String"/> that represents this instance.
  86.141 +        /// </returns>
  86.142 +        public override string ToString()
  86.143 +        {
  86.144 +            return this.x + " " + this.y;
  86.145 +        }
  86.146 +
  86.147 +        /// <summary>
  86.148 +        /// Implements the operator *.
  86.149 +        /// </summary>
  86.150 +        /// <param name="v"> The vector. </param>
  86.151 +        /// <param name="d"> The multiplication factor. </param>
  86.152 +        /// <returns> The result of the operator. </returns>
  86.153 +        public static ScreenVector operator *(ScreenVector v, double d)
  86.154 +        {
  86.155 +            return new ScreenVector(v.x * d, v.y * d);
  86.156 +        }
  86.157 +    }
  86.158 +}
  86.159 \ No newline at end of file
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/External/OxyPlot/OxyPlot/Foundation/Size.cs	Sat Jun 08 16:53:22 2013 +0000
    87.3 @@ -0,0 +1,43 @@
    87.4 +// --------------------------------------------------------------------------------------------------------------------
    87.5 +// <copyright file="Size.cs" company="OxyPlot">
    87.6 +//   The MIT License (MIT)
    87.7 +//
    87.8 +//   Copyright (c) 2012 Oystein Bjorke
    87.9 +//
   87.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   87.11 +//   copy of this software and associated documentation files (the
   87.12 +//   "Software"), to deal in the Software without restriction, including
   87.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   87.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   87.15 +//   permit persons to whom the Software is furnished to do so, subject to
   87.16 +//   the following conditions:
   87.17 +//
   87.18 +//   The above copyright notice and this permission notice shall be included
   87.19 +//   in all copies or substantial portions of the Software.
   87.20 +//
   87.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   87.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   87.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   87.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   87.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   87.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   87.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   87.28 +// </copyright>
   87.29 +// --------------------------------------------------------------------------------------------------------------------
   87.30 +namespace OxyPlot
   87.31 +{
   87.32 +    public struct Size
   87.33 +    {
   87.34 +        public double Width { get; set; }
   87.35 +        public double Height { get; set; }
   87.36 +
   87.37 +        public static Size Empty = new Size(0,0);
   87.38 +
   87.39 +        public Size(double width, double height)
   87.40 +            : this()
   87.41 +        {
   87.42 +            this.Width = width;
   87.43 +            this.Height = height;
   87.44 +        }
   87.45 +    }
   87.46 +}
   87.47 \ No newline at end of file
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/External/OxyPlot/OxyPlot/Foundation/StreamExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
    88.3 @@ -0,0 +1,25 @@
    88.4 +namespace OxyPlot
    88.5 +{
    88.6 +    using System.IO;
    88.7 +
    88.8 +    /// <summary>
    88.9 +    /// Implements <see cref="Stream"/> extension methods.
   88.10 +    /// </summary>
   88.11 +    public static class StreamExtensions
   88.12 +    {
   88.13 +        /// <summary>
   88.14 +        /// Copies to the specified stream.
   88.15 +        /// </summary>
   88.16 +        /// <param name="input">The input stream.</param>
   88.17 +        /// <param name="output">The output stream.</param>
   88.18 +        public static void CopyTo(this Stream input, Stream output)
   88.19 +        {
   88.20 +            var buffer = new byte[32768];
   88.21 +            int read;
   88.22 +            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
   88.23 +            {
   88.24 +                output.Write(buffer, 0, read);
   88.25 +            }
   88.26 +        }
   88.27 +    }
   88.28 +}
   88.29 \ No newline at end of file
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/External/OxyPlot/OxyPlot/Foundation/StringHelper.cs	Sat Jun 08 16:53:22 2013 +0000
    89.3 @@ -0,0 +1,169 @@
    89.4 +// --------------------------------------------------------------------------------------------------------------------
    89.5 +// <copyright file="StringHelper.cs" company="OxyPlot">
    89.6 +//   The MIT License (MIT)
    89.7 +//
    89.8 +//   Copyright (c) 2012 Oystein Bjorke
    89.9 +//
   89.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   89.11 +//   copy of this software and associated documentation files (the
   89.12 +//   "Software"), to deal in the Software without restriction, including
   89.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   89.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   89.15 +//   permit persons to whom the Software is furnished to do so, subject to
   89.16 +//   the following conditions:
   89.17 +//
   89.18 +//   The above copyright notice and this permission notice shall be included
   89.19 +//   in all copies or substantial portions of the Software.
   89.20 +//
   89.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   89.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   89.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   89.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   89.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   89.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   89.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   89.28 +// </copyright>
   89.29 +// <summary>
   89.30 +//   Provides support for string formatting.
   89.31 +// </summary>
   89.32 +// --------------------------------------------------------------------------------------------------------------------
   89.33 +namespace OxyPlot
   89.34 +{
   89.35 +    using System;
   89.36 +    using System.Collections;
   89.37 +    using System.Text;
   89.38 +    using System.Text.RegularExpressions;
   89.39 +
   89.40 +    /// <summary>
   89.41 +    /// Provides extended string formatting functionality.
   89.42 +    /// </summary>
   89.43 +    public static class StringHelper
   89.44 +    {
   89.45 +        /// <summary>
   89.46 +        /// The formatting expression.
   89.47 +        /// </summary>
   89.48 +        private static readonly Regex FormattingExpression = new Regex("{(?<Property>.+?)(?<Format>\\:.*?)?}");
   89.49 +
   89.50 +        /// <summary>
   89.51 +        /// Replaces the format items in the specified string.
   89.52 +        /// </summary>
   89.53 +        /// <param name="provider">
   89.54 +        /// The culture specific format provider.
   89.55 +        /// </param>
   89.56 +        /// <param name="formatString">
   89.57 +        /// The format string.
   89.58 +        /// </param>
   89.59 +        /// <param name="item">
   89.60 +        /// The item.
   89.61 +        /// </param>
   89.62 +        /// <param name="values">
   89.63 +        /// The values.
   89.64 +        /// </param>
   89.65 +        /// <remarks>
   89.66 +        /// 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.
   89.67 +        /// </remarks>
   89.68 +        /// <returns>
   89.69 +        /// The formatted string.
   89.70 +        /// </returns>
   89.71 +        public static string Format(IFormatProvider provider, string formatString, object item, params object[] values)
   89.72 +        {
   89.73 +            // Replace items on the format {Property[:Formatstring]}
   89.74 +            var s = FormattingExpression.Replace(
   89.75 +                formatString,
   89.76 +                delegate(Match match)
   89.77 +                    {
   89.78 +                        var property = match.Groups["Property"].Value;
   89.79 +                        if (property.Length > 0 && char.IsDigit(property[0]))
   89.80 +                        {
   89.81 +                            return match.Value;
   89.82 +                        }
   89.83 +
   89.84 +                        var pi = item.GetType().GetProperty(property);
   89.85 +                        if (pi == null)
   89.86 +                        {
   89.87 +                            return string.Empty;
   89.88 +                        }
   89.89 +
   89.90 +                        var v = pi.GetValue(item, null);
   89.91 +                        var format = match.Groups["Format"].Value;
   89.92 +
   89.93 +                        var fs = "{0" + format + "}";
   89.94 +                        return string.Format(provider, fs, v);
   89.95 +                    });
   89.96 +
   89.97 +            // Also apply the standard formatting
   89.98 +            s = string.Format(provider, s, values);
   89.99 +            return s;
  89.100 +        }
  89.101 +
  89.102 +        /// <summary>
  89.103 +        /// Creates a valid file name.
  89.104 +        /// </summary>
  89.105 +        /// <param name="title">
  89.106 +        /// The title.
  89.107 +        /// </param>
  89.108 +        /// <param name="extension">
  89.109 +        /// The extension.
  89.110 +        /// </param>
  89.111 +        /// <returns>
  89.112 +        /// A file name.
  89.113 +        /// </returns>
  89.114 +        public static string CreateValidFileName(string title, string extension)
  89.115 +        {
  89.116 +            string validFileName = title.Trim();
  89.117 +            var invalidFileNameChars = "/?<>\\:*|\0\t\r\n".ToCharArray();
  89.118 +            foreach (char invalChar in invalidFileNameChars)
  89.119 +            {
  89.120 +                validFileName = validFileName.Replace(invalChar.ToString(), string.Empty);
  89.121 +            }
  89.122 +
  89.123 +            foreach (char invalChar in invalidFileNameChars)
  89.124 +            {
  89.125 +                validFileName = validFileName.Replace(invalChar.ToString(), string.Empty);
  89.126 +            }
  89.127 +
  89.128 +            if (validFileName.Length > 160)
  89.129 +            {
  89.130 +                // safe value threshold is 260
  89.131 +                validFileName = validFileName.Remove(156) + "...";
  89.132 +            }
  89.133 +
  89.134 +            return validFileName + extension;
  89.135 +        }
  89.136 +
  89.137 +        /// <summary>
  89.138 +        /// Creates a string from a collection of items.
  89.139 +        /// </summary>
  89.140 +        /// <param name="provider">
  89.141 +        /// The provider.
  89.142 +        /// </param>
  89.143 +        /// <param name="items">
  89.144 +        /// The items.
  89.145 +        /// </param>
  89.146 +        /// <param name="formatstring">
  89.147 +        /// The format string to apply to each item.
  89.148 +        /// </param>
  89.149 +        /// <param name="separator">
  89.150 +        /// The separator.
  89.151 +        /// </param>
  89.152 +        /// <returns>
  89.153 +        /// The collection as a string.
  89.154 +        /// </returns>
  89.155 +        public static object CreateList(
  89.156 +            IFormatProvider provider, IEnumerable items, string formatstring, string separator = ", ")
  89.157 +        {
  89.158 +            var sb = new StringBuilder();
  89.159 +            foreach (var item in items)
  89.160 +            {
  89.161 +                if (sb.Length > 0)
  89.162 +                {
  89.163 +                    sb.Append(separator);
  89.164 +                }
  89.165 +
  89.166 +                sb.Append(string.Format(provider, formatstring, item));
  89.167 +            }
  89.168 +
  89.169 +            return sb.ToString();
  89.170 +        }
  89.171 +    }
  89.172 +}
  89.173 \ No newline at end of file
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/External/OxyPlot/OxyPlot/Foundation/SutherlandHodgmanClipping.cs	Sat Jun 08 16:53:22 2013 +0000
    90.3 @@ -0,0 +1,233 @@
    90.4 +// --------------------------------------------------------------------------------------------------------------------
    90.5 +// <copyright file="SutherlandHodgmanClipping.cs" company="OxyPlot">
    90.6 +//   The MIT License (MIT)
    90.7 +//
    90.8 +//   Copyright (c) 2012 Oystein Bjorke
    90.9 +//
   90.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   90.11 +//   copy of this software and associated documentation files (the
   90.12 +//   "Software"), to deal in the Software without restriction, including
   90.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   90.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   90.15 +//   permit persons to whom the Software is furnished to do so, subject to
   90.16 +//   the following conditions:
   90.17 +//
   90.18 +//   The above copyright notice and this permission notice shall be included
   90.19 +//   in all copies or substantial portions of the Software.
   90.20 +//
   90.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   90.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   90.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   90.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   90.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   90.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   90.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   90.28 +// </copyright>
   90.29 +// <summary>
   90.30 +//   Polygon clipping by the sutherland-hodgman algortihm.
   90.31 +// </summary>
   90.32 +// --------------------------------------------------------------------------------------------------------------------
   90.33 +namespace OxyPlot
   90.34 +{
   90.35 +    using System;
   90.36 +    using System.Collections.Generic;
   90.37 +
   90.38 +    /// <summary>
   90.39 +    /// Provides polygon clipping by the Sutherland-Hodgman algortihm.
   90.40 +    /// </summary>
   90.41 +    public static class SutherlandHodgmanClipping
   90.42 +    {
   90.43 +        /// <summary>
   90.44 +        /// The rectangle edge.
   90.45 +        /// </summary>
   90.46 +        private enum RectangleEdge
   90.47 +        {
   90.48 +            /// <summary>
   90.49 +            /// The left.
   90.50 +            /// </summary>
   90.51 +            Left,
   90.52 +
   90.53 +            /// <summary>
   90.54 +            /// The right.
   90.55 +            /// </summary>
   90.56 +            Right,
   90.57 +
   90.58 +            /// <summary>
   90.59 +            /// The top.
   90.60 +            /// </summary>
   90.61 +            Top,
   90.62 +
   90.63 +            /// <summary>
   90.64 +            /// The bottom.
   90.65 +            /// </summary>
   90.66 +            Bottom
   90.67 +        }
   90.68 +
   90.69 +        /// <summary>
   90.70 +        /// The Sutherland-Hodgman polygon clipping algorithm.
   90.71 +        /// </summary>
   90.72 +        /// <remarks>
   90.73 +        /// See http://ezekiel.vancouver.wsu.edu/~cs442/lectures/clip/clip/index.html
   90.74 +        /// </remarks>
   90.75 +        /// <param name="bounds">
   90.76 +        /// The bounds.
   90.77 +        /// </param>
   90.78 +        /// <param name="v">
   90.79 +        /// The polygon points.
   90.80 +        /// </param>
   90.81 +        /// <returns>
   90.82 +        /// The clipped points.
   90.83 +        /// </returns>
   90.84 +        public static List<ScreenPoint> ClipPolygon(OxyRect bounds, IList<ScreenPoint> v)
   90.85 +        {
   90.86 +            List<ScreenPoint> p1 = ClipOneAxis(bounds, RectangleEdge.Left, v);
   90.87 +            List<ScreenPoint> p2 = ClipOneAxis(bounds, RectangleEdge.Right, p1);
   90.88 +            List<ScreenPoint> p3 = ClipOneAxis(bounds, RectangleEdge.Top, p2);
   90.89 +            return ClipOneAxis(bounds, RectangleEdge.Bottom, p3);
   90.90 +        }
   90.91 +
   90.92 +        /// <summary>
   90.93 +        /// Clips to one axis.
   90.94 +        /// </summary>
   90.95 +        /// <param name="bounds">
   90.96 +        /// The bounds.
   90.97 +        /// </param>
   90.98 +        /// <param name="edge">
   90.99 +        /// The edge.
  90.100 +        /// </param>
  90.101 +        /// <param name="v">
  90.102 +        /// The points of the polygon.
  90.103 +        /// </param>
  90.104 +        /// <returns>
  90.105 +        /// The clipped points.
  90.106 +        /// </returns>
  90.107 +        private static List<ScreenPoint> ClipOneAxis(OxyRect bounds, RectangleEdge edge, IList<ScreenPoint> v)
  90.108 +        {
  90.109 +            if (v.Count == 0)
  90.110 +            {
  90.111 +                return new List<ScreenPoint>();
  90.112 +            }
  90.113 +
  90.114 +            var polygon = new List<ScreenPoint>(v.Count);
  90.115 +
  90.116 +            var s = v[v.Count - 1];
  90.117 +
  90.118 +            for (int i = 0; i < v.Count; ++i)
  90.119 +            {
  90.120 +                var p = v[i];
  90.121 +                bool pin = IsInside(bounds, edge, p);
  90.122 +                bool sin = IsInside(bounds, edge, s);
  90.123 +
  90.124 +                if (sin && pin)
  90.125 +                {
  90.126 +                    // case 1: inside -> inside
  90.127 +                    polygon.Add(p);
  90.128 +                }
  90.129 +                else if (sin)
  90.130 +                {
  90.131 +                    // case 2: inside -> outside
  90.132 +                    polygon.Add(LineIntercept(bounds, edge, s, p));
  90.133 +                }
  90.134 +                else if (!pin)
  90.135 +                {
  90.136 +                    // case 3: outside -> outside
  90.137 +                    // emit nothing
  90.138 +                }
  90.139 +                else
  90.140 +                {
  90.141 +                    // case 4: outside -> inside
  90.142 +                    polygon.Add(LineIntercept(bounds, edge, s, p));
  90.143 +                    polygon.Add(p);
  90.144 +                }
  90.145 +
  90.146 +                s = p;
  90.147 +            }
  90.148 +
  90.149 +            return polygon;
  90.150 +        }
  90.151 +
  90.152 +        /// <summary>
  90.153 +        /// Determines whether the specified point is inside the edge/bounds.
  90.154 +        /// </summary>
  90.155 +        /// <param name="bounds">The bounds.</param>
  90.156 +        /// <param name="edge">The edge to test.</param>
  90.157 +        /// <param name="p">The point.</param>
  90.158 +        /// <returns>
  90.159 +        ///  <c>true</c> if the specified point is inside; otherwise, <c>false</c>.
  90.160 +        /// </returns>
  90.161 +        private static bool IsInside(OxyRect bounds, RectangleEdge edge, ScreenPoint p)
  90.162 +        {
  90.163 +            switch (edge)
  90.164 +            {
  90.165 +                case RectangleEdge.Left:
  90.166 +                    return !(p.X < bounds.Left);
  90.167 +
  90.168 +                case RectangleEdge.Right:
  90.169 +                    return !(p.X >= bounds.Right);
  90.170 +
  90.171 +                case RectangleEdge.Top:
  90.172 +                    return !(p.Y < bounds.Top);
  90.173 +
  90.174 +                case RectangleEdge.Bottom:
  90.175 +                    return !(p.Y >= bounds.Bottom);
  90.176 +
  90.177 +                default:
  90.178 +                    throw new ArgumentException("edge");
  90.179 +            }
  90.180 +        }
  90.181 +
  90.182 +        /// <summary>
  90.183 +        /// Fines the edge interception.
  90.184 +        /// </summary>
  90.185 +        /// <param name="bounds">The bounds.</param>
  90.186 +        /// <param name="edge">The edge.</param>
  90.187 +        /// <param name="a">The first point.</param>
  90.188 +        /// <param name="b">The second point.</param>
  90.189 +        /// <returns>The interception.</returns>
  90.190 +        private static ScreenPoint LineIntercept(OxyRect bounds, RectangleEdge edge, ScreenPoint a, ScreenPoint b)
  90.191 +        {
  90.192 +            if (a.x == b.x && a.y == b.y)
  90.193 +            {
  90.194 +                return a;
  90.195 +            }
  90.196 +
  90.197 +            switch (edge)
  90.198 +            {
  90.199 +                case RectangleEdge.Bottom:
  90.200 +                    if (b.Y == a.Y)
  90.201 +                    {
  90.202 +                        throw new ArgumentException("no intercept found");
  90.203 +                    }
  90.204 +
  90.205 +                    return new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Bottom - a.Y)) / (b.Y - a.Y)), bounds.Bottom);
  90.206 +
  90.207 +                case RectangleEdge.Left:
  90.208 +                    if (b.X == a.X)
  90.209 +                    {
  90.210 +                        throw new ArgumentException("no intercept found");
  90.211 +                    }
  90.212 +
  90.213 +                    return new ScreenPoint(bounds.Left, a.Y + (((b.Y - a.Y) * (bounds.Left - a.X)) / (b.X - a.X)));
  90.214 +
  90.215 +                case RectangleEdge.Right:
  90.216 +                    if (b.X == a.X)
  90.217 +                    {
  90.218 +                        throw new ArgumentException("no intercept found");
  90.219 +                    }
  90.220 +
  90.221 +                    return new ScreenPoint(bounds.Right, a.Y + (((b.Y - a.Y) * (bounds.Right - a.X)) / (b.X - a.X)));
  90.222 +
  90.223 +                case RectangleEdge.Top:
  90.224 +                    if (b.Y == a.Y)
  90.225 +                    {
  90.226 +                        throw new ArgumentException("no intercept found");
  90.227 +                    }
  90.228 +
  90.229 +                    return new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Top - a.Y)) / (b.Y - a.Y)), bounds.Top);
  90.230 +            }
  90.231 +
  90.232 +            throw new ArgumentException("no intercept found");
  90.233 +        }
  90.234 +
  90.235 +    }
  90.236 +}
  90.237 \ No newline at end of file
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/External/OxyPlot/OxyPlot/Foundation/VerticalAlignment.cs	Sat Jun 08 16:53:22 2013 +0000
    91.3 @@ -0,0 +1,52 @@
    91.4 +// --------------------------------------------------------------------------------------------------------------------
    91.5 +// <copyright file="VerticalAlignment.cs" company="OxyPlot">
    91.6 +//   The MIT License (MIT)
    91.7 +//
    91.8 +//   Copyright (c) 2012 Oystein Bjorke
    91.9 +//
   91.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   91.11 +//   copy of this software and associated documentation files (the
   91.12 +//   "Software"), to deal in the Software without restriction, including
   91.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   91.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   91.15 +//   permit persons to whom the Software is furnished to do so, subject to
   91.16 +//   the following conditions:
   91.17 +//
   91.18 +//   The above copyright notice and this permission notice shall be included
   91.19 +//   in all copies or substantial portions of the Software.
   91.20 +//
   91.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   91.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   91.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   91.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   91.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   91.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   91.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   91.28 +// </copyright>
   91.29 +// <summary>
   91.30 +//   Vertical text alignment.
   91.31 +// </summary>
   91.32 +// --------------------------------------------------------------------------------------------------------------------
   91.33 +namespace OxyPlot
   91.34 +{
   91.35 +    /// <summary>
   91.36 +    /// Specifies the vertical alignment.
   91.37 +    /// </summary>
   91.38 +    public enum VerticalAlignment
   91.39 +    {
   91.40 +        /// <summary>
   91.41 +        /// Aligned at the top.
   91.42 +        /// </summary>
   91.43 +        Top = -1,
   91.44 +
   91.45 +        /// <summary>
   91.46 +        /// Aligned in the middle.
   91.47 +        /// </summary>
   91.48 +        Middle = 0,
   91.49 +
   91.50 +        /// <summary>
   91.51 +        /// Aligned at the bottom.
   91.52 +        /// </summary>
   91.53 +        Bottom = 1
   91.54 +    }
   91.55 +}
   91.56 \ No newline at end of file
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/External/OxyPlot/OxyPlot/Foundation/XmlWriterBase.cs	Sat Jun 08 16:53:22 2013 +0000
    92.3 @@ -0,0 +1,233 @@
    92.4 +// --------------------------------------------------------------------------------------------------------------------
    92.5 +// <copyright file="XmlWriterBase.cs" company="OxyPlot">
    92.6 +//   The MIT License (MIT)
    92.7 +//
    92.8 +//   Copyright (c) 2012 Oystein Bjorke
    92.9 +//
   92.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   92.11 +//   copy of this software and associated documentation files (the
   92.12 +//   "Software"), to deal in the Software without restriction, including
   92.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   92.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   92.15 +//   permit persons to whom the Software is furnished to do so, subject to
   92.16 +//   the following conditions:
   92.17 +//
   92.18 +//   The above copyright notice and this permission notice shall be included
   92.19 +//   in all copies or substantial portions of the Software.
   92.20 +//
   92.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   92.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   92.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   92.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   92.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   92.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   92.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   92.28 +// </copyright>
   92.29 +// <summary>
   92.30 +//   Abstract base class for exporters that write xml.
   92.31 +// </summary>
   92.32 +// --------------------------------------------------------------------------------------------------------------------
   92.33 +namespace OxyPlot
   92.34 +{
   92.35 +    using System;
   92.36 +    using System.IO;
   92.37 +    using System.Text;
   92.38 +    using System.Xml;
   92.39 +
   92.40 +    /// <summary>
   92.41 +    /// Provides an abstract base class for exporters that write xml.
   92.42 +    /// </summary>
   92.43 +    public abstract class XmlWriterBase : IDisposable
   92.44 +    {
   92.45 +        /// <summary>
   92.46 +        /// The xml writer.
   92.47 +        /// </summary>
   92.48 +        private XmlWriter w;
   92.49 +
   92.50 +        /// <summary>
   92.51 +        /// The disposed flag.
   92.52 +        /// </summary>
   92.53 +        private bool disposed;
   92.54 +
   92.55 +        /// <summary>
   92.56 +        /// Initializes a new instance of the <see cref = "XmlWriterBase" /> class.
   92.57 +        /// </summary>
   92.58 +        protected XmlWriterBase()
   92.59 +        {
   92.60 +        }
   92.61 +
   92.62 +        /// <summary>
   92.63 +        /// Initializes a new instance of the <see cref="XmlWriterBase"/> class.
   92.64 +        /// </summary>
   92.65 +        /// <param name="stream">
   92.66 +        /// The stream.
   92.67 +        /// </param>
   92.68 +        protected XmlWriterBase(Stream stream)
   92.69 +        {
   92.70 +            this.w = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 });
   92.71 +        }
   92.72 +
   92.73 +        /// <summary>
   92.74 +        /// Closes this instance.
   92.75 +        /// </summary>
   92.76 +        public virtual void Close()
   92.77 +        {
   92.78 +        }
   92.79 +
   92.80 +        /// <summary>
   92.81 +        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
   92.82 +        /// </summary>
   92.83 +        public void Dispose()
   92.84 +        {
   92.85 +            this.Dispose(true);
   92.86 +            GC.SuppressFinalize(this);
   92.87 +        }
   92.88 +
   92.89 +        /// <summary>
   92.90 +        /// Flushes this instance.
   92.91 +        /// </summary>
   92.92 +        public void Flush()
   92.93 +        {
   92.94 +            this.w.Flush();
   92.95 +        }
   92.96 +
   92.97 +        /// <summary>
   92.98 +        /// The write attribute string.
   92.99 +        /// </summary>
  92.100 +        /// <param name="name">
  92.101 +        /// The name.
  92.102 +        /// </param>
  92.103 +        /// <param name="value">
  92.104 +        /// The value.
  92.105 +        /// </param>
  92.106 +        protected void WriteAttributeString(string name, string value)
  92.107 +        {
  92.108 +            this.w.WriteAttributeString(name, value);
  92.109 +        }
  92.110 +
  92.111 +        /// <summary>
  92.112 +        /// The write doc type.
  92.113 +        /// </summary>
  92.114 +        /// <param name="name">
  92.115 +        /// The name.
  92.116 +        /// </param>
  92.117 +        /// <param name="pubid">
  92.118 +        /// The pubid.
  92.119 +        /// </param>
  92.120 +        /// <param name="sysid">
  92.121 +        /// The sysid.
  92.122 +        /// </param>
  92.123 +        /// <param name="subset">
  92.124 +        /// The subset.
  92.125 +        /// </param>
  92.126 +        protected void WriteDocType(string name, string pubid, string sysid, string subset)
  92.127 +        {
  92.128 +            this.w.WriteDocType(name, pubid, sysid, subset);
  92.129 +        }
  92.130 +
  92.131 +        /// <summary>
  92.132 +        /// The write element string.
  92.133 +        /// </summary>
  92.134 +        /// <param name="name">
  92.135 +        /// The name.
  92.136 +        /// </param>
  92.137 +        /// <param name="text">
  92.138 +        /// The text.
  92.139 +        /// </param>
  92.140 +        protected void WriteElementString(string name, string text)
  92.141 +        {
  92.142 +            this.w.WriteElementString(name, text);
  92.143 +        }
  92.144 +
  92.145 +        /// <summary>
  92.146 +        /// The write end document.
  92.147 +        /// </summary>
  92.148 +        protected void WriteEndDocument()
  92.149 +        {
  92.150 +            this.w.WriteEndDocument();
  92.151 +        }
  92.152 +
  92.153 +        /// <summary>
  92.154 +        /// The write end element.
  92.155 +        /// </summary>
  92.156 +        protected void WriteEndElement()
  92.157 +        {
  92.158 +            this.w.WriteEndElement();
  92.159 +        }
  92.160 +
  92.161 +        /// <summary>
  92.162 +        /// The write raw.
  92.163 +        /// </summary>
  92.164 +        /// <param name="text">
  92.165 +        /// The text.
  92.166 +        /// </param>
  92.167 +        protected void WriteRaw(string text)
  92.168 +        {
  92.169 +            this.w.WriteRaw(text);
  92.170 +        }
  92.171 +
  92.172 +        /// <summary>
  92.173 +        /// The write start document.
  92.174 +        /// </summary>
  92.175 +        /// <param name="standalone">
  92.176 +        /// The standalone.
  92.177 +        /// </param>
  92.178 +        protected void WriteStartDocument(bool standalone)
  92.179 +        {
  92.180 +            this.w.WriteStartDocument(standalone);
  92.181 +        }
  92.182 +
  92.183 +        /// <summary>
  92.184 +        /// The write start element.
  92.185 +        /// </summary>
  92.186 +        /// <param name="name">
  92.187 +        /// The name.
  92.188 +        /// </param>
  92.189 +        protected void WriteStartElement(string name)
  92.190 +        {
  92.191 +            this.w.WriteStartElement(name);
  92.192 +        }
  92.193 +
  92.194 +        /// <summary>
  92.195 +        /// The write start element.
  92.196 +        /// </summary>
  92.197 +        /// <param name="name">
  92.198 +        /// The name.
  92.199 +        /// </param>
  92.200 +        /// <param name="ns">
  92.201 +        /// The ns.
  92.202 +        /// </param>
  92.203 +        protected void WriteStartElement(string name, string ns)
  92.204 +        {
  92.205 +            this.w.WriteStartElement(name, ns);
  92.206 +        }
  92.207 +
  92.208 +        /// <summary>
  92.209 +        /// The write string.
  92.210 +        /// </summary>
  92.211 +        /// <param name="text">
  92.212 +        /// The text.
  92.213 +        /// </param>
  92.214 +        protected void WriteString(string text)
  92.215 +        {
  92.216 +            this.w.WriteString(text);
  92.217 +        }
  92.218 +
  92.219 +        /// <summary>
  92.220 +        /// Releases unmanaged and - optionally - managed resources
  92.221 +        /// </summary>
  92.222 +        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  92.223 +        private void Dispose(bool disposing)
  92.224 +        {
  92.225 +            if (!this.disposed)
  92.226 +            {
  92.227 +                if (disposing)
  92.228 +                {
  92.229 +                    this.Close();
  92.230 +                }
  92.231 +            }
  92.232 +
  92.233 +            this.disposed = true;
  92.234 +        }
  92.235 +    }
  92.236 +}
  92.237 \ No newline at end of file
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/External/OxyPlot/OxyPlot/LibraryDoc.cs	Sat Jun 08 16:53:22 2013 +0000
    93.3 @@ -0,0 +1,37 @@
    93.4 +// --------------------------------------------------------------------------------------------------------------------
    93.5 +// <copyright file="LibraryDoc.cs" company="OxyPlot">
    93.6 +//   The MIT License (MIT)
    93.7 +//   
    93.8 +//   Copyright (c) 2012 Oystein Bjorke
    93.9 +//   
   93.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   93.11 +//   copy of this software and associated documentation files (the
   93.12 +//   "Software"), to deal in the Software without restriction, including
   93.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   93.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   93.15 +//   permit persons to whom the Software is furnished to do so, subject to
   93.16 +//   the following conditions:
   93.17 +//   
   93.18 +//   The above copyright notice and this permission notice shall be included
   93.19 +//   in all copies or substantial portions of the Software.
   93.20 +//   
   93.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   93.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   93.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   93.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   93.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   93.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   93.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   93.28 +// </copyright>
   93.29 +// --------------------------------------------------------------------------------------------------------------------
   93.30 +
   93.31 +namespace OxyPlot
   93.32 +{
   93.33 +    /// <summary>
   93.34 +    /// The OxyPlot solution provides plotting functionality on many platforms.
   93.35 +    /// </summary>
   93.36 +    [System.Runtime.CompilerServices.CompilerGenerated]
   93.37 +    internal class LibraryDoc
   93.38 +    {
   93.39 +    }
   93.40 +}
   93.41 \ No newline at end of file
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/CursorType.cs	Sat Jun 08 16:53:22 2013 +0000
    94.3 @@ -0,0 +1,62 @@
    94.4 +// --------------------------------------------------------------------------------------------------------------------
    94.5 +// <copyright file="CursorType.cs" company="OxyPlot">
    94.6 +//   The MIT License (MIT)
    94.7 +//
    94.8 +//   Copyright (c) 2012 Oystein Bjorke
    94.9 +//
   94.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   94.11 +//   copy of this software and associated documentation files (the
   94.12 +//   "Software"), to deal in the Software without restriction, including
   94.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   94.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   94.15 +//   permit persons to whom the Software is furnished to do so, subject to
   94.16 +//   the following conditions:
   94.17 +//
   94.18 +//   The above copyright notice and this permission notice shall be included
   94.19 +//   in all copies or substantial portions of the Software.
   94.20 +//
   94.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   94.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   94.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   94.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   94.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   94.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   94.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   94.28 +// </copyright>
   94.29 +// <summary>
   94.30 +//   Specifies the cursor type.
   94.31 +// </summary>
   94.32 +// --------------------------------------------------------------------------------------------------------------------
   94.33 +namespace OxyPlot
   94.34 +{
   94.35 +    /// <summary>
   94.36 +    /// Specifies the cursor type.
   94.37 +    /// </summary>
   94.38 +    public enum CursorType
   94.39 +    {
   94.40 +        /// <summary>
   94.41 +        /// The default cursor
   94.42 +        /// </summary>
   94.43 +        Default = 0,
   94.44 +
   94.45 +        /// <summary>
   94.46 +        /// The pan cursor
   94.47 +        /// </summary>
   94.48 +        Pan,
   94.49 +
   94.50 +        /// <summary>
   94.51 +        /// The zoom rectangle cursor
   94.52 +        /// </summary>
   94.53 +        ZoomRectangle,
   94.54 +
   94.55 +        /// <summary>
   94.56 +        /// The horizontal zoom cursor
   94.57 +        /// </summary>
   94.58 +        ZoomHorizontal,
   94.59 +
   94.60 +        /// <summary>
   94.61 +        /// The vertical zoom cursor
   94.62 +        /// </summary>
   94.63 +        ZoomVertical
   94.64 +    }
   94.65 +}
   94.66 \ No newline at end of file
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/IPlotControl.cs	Sat Jun 08 16:53:22 2013 +0000
    95.3 @@ -0,0 +1,176 @@
    95.4 +// --------------------------------------------------------------------------------------------------------------------
    95.5 +// <copyright file="IPlotControl.cs" company="OxyPlot">
    95.6 +//   The MIT License (MIT)
    95.7 +//
    95.8 +//   Copyright (c) 2012 Oystein Bjorke
    95.9 +//
   95.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   95.11 +//   copy of this software and associated documentation files (the
   95.12 +//   "Software"), to deal in the Software without restriction, including
   95.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   95.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   95.15 +//   permit persons to whom the Software is furnished to do so, subject to
   95.16 +//   the following conditions:
   95.17 +//
   95.18 +//   The above copyright notice and this permission notice shall be included
   95.19 +//   in all copies or substantial portions of the Software.
   95.20 +//
   95.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   95.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   95.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   95.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   95.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   95.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   95.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   95.28 +// </copyright>
   95.29 +// <summary>
   95.30 +//   Interface for Plot controls.
   95.31 +// </summary>
   95.32 +// --------------------------------------------------------------------------------------------------------------------
   95.33 +namespace OxyPlot
   95.34 +{
   95.35 +    using OxyPlot.Annotations;
   95.36 +    using OxyPlot.Axes;
   95.37 +    using OxyPlot.Series;
   95.38 +
   95.39 +    /// <summary>
   95.40 +    /// Defines functionality in the Plot controls.
   95.41 +    /// </summary>
   95.42 +    public interface IPlotControl
   95.43 +    {
   95.44 +        /// <summary>
   95.45 +        /// Gets the actual model.
   95.46 +        /// </summary>
   95.47 +        /// <value>The actual model.</value>
   95.48 +        PlotModel ActualModel { get; }
   95.49 +
   95.50 +        /// <summary>
   95.51 +        /// Gets the axes from a point.
   95.52 +        /// </summary>
   95.53 +        /// <param name="pt">
   95.54 +        /// The point.
   95.55 +        /// </param>
   95.56 +        /// <param name="xaxis">
   95.57 +        /// The x-axis.
   95.58 +        /// </param>
   95.59 +        /// <param name="yaxis">
   95.60 +        /// The y-axis.
   95.61 +        /// </param>
   95.62 +        void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis);
   95.63 +
   95.64 +        /// <summary>
   95.65 +        /// Gets the series from point.
   95.66 +        /// </summary>
   95.67 +        /// <param name="pt">
   95.68 +        /// The point (screen coordinates).
   95.69 +        /// </param>
   95.70 +        /// <param name="limit">
   95.71 +        /// The maximum allowed distance.
   95.72 +        /// </param>
   95.73 +        /// <returns>
   95.74 +        /// The series.
   95.75 +        /// </returns>
   95.76 +        Series.Series GetSeriesFromPoint(ScreenPoint pt, double limit = 100);
   95.77 +
   95.78 +        /// <summary>
   95.79 +        /// Hides the tracker.
   95.80 +        /// </summary>
   95.81 +        void HideTracker();
   95.82 +
   95.83 +        /// <summary>
   95.84 +        /// Hides the zoom rectangle.
   95.85 +        /// </summary>
   95.86 +        void HideZoomRectangle();
   95.87 +
   95.88 +        /// <summary>
   95.89 +        /// Invalidate the plot (not blocking the UI thread)
   95.90 +        /// </summary>
   95.91 +        /// <param name="updateData">
   95.92 +        /// if set to <c>true</c>, all data collections will be updated.
   95.93 +        /// </param>
   95.94 +        void InvalidatePlot(bool updateData = true);
   95.95 +
   95.96 +        /// <summary>
   95.97 +        /// Pans the specified axis.
   95.98 +        /// </summary>
   95.99 +        /// <param name="axis">
  95.100 +        /// The axis.
  95.101 +        /// </param>
  95.102 +        /// <param name="ppt">
  95.103 +        /// The previous point (screen coordinates).
  95.104 +        /// </param>
  95.105 +        /// <param name="cpt">
  95.106 +        /// The current point (screen coordinates).
  95.107 +        /// </param>
  95.108 +        void Pan(Axis axis, ScreenPoint ppt, ScreenPoint cpt);
  95.109 +
  95.110 +        /// <summary>
  95.111 +        /// Refresh the plot immediately (blocking UI thread)
  95.112 +        /// </summary>
  95.113 +        /// <param name="updateData">
  95.114 +        /// if set to <c>true</c>, all data collections will be updated.
  95.115 +        /// </param>
  95.116 +        void RefreshPlot(bool updateData = true);
  95.117 +
  95.118 +        /// <summary>
  95.119 +        /// Resets the specified axis.
  95.120 +        /// </summary>
  95.121 +        /// <param name="axis">
  95.122 +        /// The axis.
  95.123 +        /// </param>
  95.124 +        void Reset(Axis axis);
  95.125 +
  95.126 +        /// <summary>
  95.127 +        /// Sets the cursor type.
  95.128 +        /// </summary>
  95.129 +        /// <param name="cursorType">
  95.130 +        /// The cursor type.
  95.131 +        /// </param>
  95.132 +        void SetCursorType(CursorType cursorType);
  95.133 +
  95.134 +        /// <summary>
  95.135 +        /// Shows the tracker.
  95.136 +        /// </summary>
  95.137 +        /// <param name="trackerHitResult">
  95.138 +        /// The tracker data.
  95.139 +        /// </param>
  95.140 +        void ShowTracker(TrackerHitResult trackerHitResult);
  95.141 +
  95.142 +        /// <summary>
  95.143 +        /// Shows the zoom rectangle.
  95.144 +        /// </summary>
  95.145 +        /// <param name="r">
  95.146 +        /// The rectangle.
  95.147 +        /// </param>
  95.148 +        void ShowZoomRectangle(OxyRect r);
  95.149 +
  95.150 +        /// <summary>
  95.151 +        /// Zooms the specified axis to the specified values.
  95.152 +        /// </summary>
  95.153 +        /// <param name="axis">
  95.154 +        /// The axis.
  95.155 +        /// </param>
  95.156 +        /// <param name="p1">
  95.157 +        /// The new minimum value.
  95.158 +        /// </param>
  95.159 +        /// <param name="p2">
  95.160 +        /// The new maximum value.
  95.161 +        /// </param>
  95.162 +        void Zoom(Axis axis, double p1, double p2);
  95.163 +
  95.164 +        /// <summary>
  95.165 +        /// Zooms at the specified position.
  95.166 +        /// </summary>
  95.167 +        /// <param name="axis">
  95.168 +        /// The axis.
  95.169 +        /// </param>
  95.170 +        /// <param name="factor">
  95.171 +        /// The zoom factor.
  95.172 +        /// </param>
  95.173 +        /// <param name="x">
  95.174 +        /// The position to zoom at.
  95.175 +        /// </param>
  95.176 +        void ZoomAt(Axis axis, double factor, double x);
  95.177 +
  95.178 +    }
  95.179 +}
  95.180 \ No newline at end of file
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ManipulationEventArgs.cs	Sat Jun 08 16:53:22 2013 +0000
    96.3 @@ -0,0 +1,67 @@
    96.4 +// --------------------------------------------------------------------------------------------------------------------
    96.5 +// <copyright file="ManipulationEventArgs.cs" company="OxyPlot">
    96.6 +//   The MIT License (MIT)
    96.7 +//
    96.8 +//   Copyright (c) 2012 Oystein Bjorke
    96.9 +//
   96.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   96.11 +//   copy of this software and associated documentation files (the
   96.12 +//   "Software"), to deal in the Software without restriction, including
   96.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   96.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   96.15 +//   permit persons to whom the Software is furnished to do so, subject to
   96.16 +//   the following conditions:
   96.17 +//
   96.18 +//   The above copyright notice and this permission notice shall be included
   96.19 +//   in all copies or substantial portions of the Software.
   96.20 +//
   96.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   96.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   96.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   96.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   96.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   96.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   96.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   96.28 +// </copyright>
   96.29 +// <summary>
   96.30 +//   Provides data for the manipulation events.
   96.31 +// </summary>
   96.32 +// --------------------------------------------------------------------------------------------------------------------
   96.33 +namespace OxyPlot
   96.34 +{
   96.35 +    /// <summary>
   96.36 +    /// Provides data for the manipulation events.
   96.37 +    /// </summary>
   96.38 +    public class ManipulationEventArgs
   96.39 +    {
   96.40 +        /// <summary>
   96.41 +        /// Initializes a new instance of the <see cref="ManipulationEventArgs"/> class.
   96.42 +        /// </summary>
   96.43 +        /// <param name="currentPosition">
   96.44 +        /// The current position.
   96.45 +        /// </param>
   96.46 +        public ManipulationEventArgs(ScreenPoint currentPosition)
   96.47 +        {
   96.48 +            this.CurrentPosition = currentPosition;
   96.49 +        }
   96.50 +
   96.51 +        /// <summary>
   96.52 +        /// Gets the current position.
   96.53 +        /// </summary>
   96.54 +        /// <value>The current position.</value>
   96.55 +        public ScreenPoint CurrentPosition { get; private set; }
   96.56 +
   96.57 +        /// <summary>
   96.58 +        /// Gets or sets the X scaling factor.
   96.59 +        /// </summary>
   96.60 +        /// <value>The scale value.</value>
   96.61 +        public double ScaleX { get; set; }
   96.62 +
   96.63 +        /// <summary>
   96.64 +        /// Gets or sets the Y scaling factor.
   96.65 +        /// </summary>
   96.66 +        /// <value>The scale value.</value>
   96.67 +        public double ScaleY { get; set; }
   96.68 +
   96.69 +    }
   96.70 +}
   96.71 \ No newline at end of file
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ManipulatorBase.cs	Sat Jun 08 16:53:22 2013 +0000
    97.3 @@ -0,0 +1,151 @@
    97.4 +// --------------------------------------------------------------------------------------------------------------------
    97.5 +// <copyright file="ManipulatorBase.cs" company="OxyPlot">
    97.6 +//   The MIT License (MIT)
    97.7 +//
    97.8 +//   Copyright (c) 2012 Oystein Bjorke
    97.9 +//
   97.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   97.11 +//   copy of this software and associated documentation files (the
   97.12 +//   "Software"), to deal in the Software without restriction, including
   97.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   97.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   97.15 +//   permit persons to whom the Software is furnished to do so, subject to
   97.16 +//   the following conditions:
   97.17 +//
   97.18 +//   The above copyright notice and this permission notice shall be included
   97.19 +//   in all copies or substantial portions of the Software.
   97.20 +//
   97.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   97.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   97.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   97.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   97.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   97.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   97.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   97.28 +// </copyright>
   97.29 +// <summary>
   97.30 +//   The manipulator base.
   97.31 +// </summary>
   97.32 +// --------------------------------------------------------------------------------------------------------------------
   97.33 +namespace OxyPlot
   97.34 +{
   97.35 +    using OxyPlot.Axes;
   97.36 +
   97.37 +    /// <summary>
   97.38 +    /// Provides an absract base class for plot control manipulators.
   97.39 +    /// </summary>
   97.40 +    public class ManipulatorBase
   97.41 +    {
   97.42 +        /// <summary>
   97.43 +        /// Initializes a new instance of the <see cref="ManipulatorBase"/> class.
   97.44 +        /// </summary>
   97.45 +        /// <param name="plotControl">
   97.46 +        /// The plot control.
   97.47 +        /// </param>
   97.48 +        protected ManipulatorBase(IPlotControl plotControl)
   97.49 +        {
   97.50 +            this.PlotControl = plotControl;
   97.51 +        }
   97.52 +
   97.53 +        /// <summary>
   97.54 +        /// Gets the first position of the manipulation.
   97.55 +        /// </summary>
   97.56 +        public ScreenPoint StartPosition { get; private set; }
   97.57 +
   97.58 +        /// <summary>
   97.59 +        /// Gets the plot control.
   97.60 +        /// </summary>
   97.61 +        protected IPlotControl PlotControl { get; private set; }
   97.62 +
   97.63 +        /// <summary>
   97.64 +        /// Gets or sets the X axis.
   97.65 +        /// </summary>
   97.66 +        /// <value>The X axis.</value>
   97.67 +        protected Axis XAxis { get; set; }
   97.68 +
   97.69 +        /// <summary>
   97.70 +        /// Gets or sets the Y axis.
   97.71 +        /// </summary>
   97.72 +        /// <value>The Y axis.</value>
   97.73 +        protected Axis YAxis { get; set; }
   97.74 +
   97.75 +        /// <summary>
   97.76 +        /// Occurs when a manipulation is complete.
   97.77 +        /// </summary>
   97.78 +        /// <param name="e">
   97.79 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
   97.80 +        /// </param>
   97.81 +        public virtual void Completed(ManipulationEventArgs e)
   97.82 +        {
   97.83 +            this.PlotControl.SetCursorType(CursorType.Default);
   97.84 +        }
   97.85 +
   97.86 +        /// <summary>
   97.87 +        /// Occurs when the input device changes position during a manipulation.
   97.88 +        /// </summary>
   97.89 +        /// <param name="e">
   97.90 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
   97.91 +        /// </param>
   97.92 +        public virtual void Delta(ManipulationEventArgs e)
   97.93 +        {
   97.94 +        }
   97.95 +
   97.96 +        /// <summary>
   97.97 +        /// Gets the cursor for the manipulation.
   97.98 +        /// </summary>
   97.99 +        /// <returns>
  97.100 +        /// The cursor.
  97.101 +        /// </returns>
  97.102 +        public virtual CursorType GetCursorType()
  97.103 +        {
  97.104 +            return CursorType.Default;
  97.105 +        }
  97.106 +
  97.107 +        /// <summary>
  97.108 +        /// Occurs when an input device begins a manipulation on the plot.
  97.109 +        /// </summary>
  97.110 +        /// <param name="e">
  97.111 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
  97.112 +        /// </param>
  97.113 +        public virtual void Started(ManipulationEventArgs e)
  97.114 +        {
  97.115 +            Axis xaxis;
  97.116 +            Axis yaxis;
  97.117 +            this.PlotControl.GetAxesFromPoint(e.CurrentPosition, out xaxis, out yaxis);
  97.118 +            this.StartPosition = e.CurrentPosition;
  97.119 +
  97.120 +            this.XAxis = xaxis;
  97.121 +            this.YAxis = yaxis;
  97.122 +
  97.123 +            this.PlotControl.SetCursorType(this.GetCursorType());
  97.124 +        }
  97.125 +
  97.126 +        /// <summary>
  97.127 +        /// Transforms a point from screen coordinates to data coordinates.
  97.128 +        /// </summary>
  97.129 +        /// <param name="x">
  97.130 +        /// The x coordinate.
  97.131 +        /// </param>
  97.132 +        /// <param name="y">
  97.133 +        /// The y coordinate.
  97.134 +        /// </param>
  97.135 +        /// <returns>
  97.136 +        /// A data point.
  97.137 +        /// </returns>
  97.138 +        protected DataPoint InverseTransform(double x, double y)
  97.139 +        {
  97.140 +            if (this.XAxis != null)
  97.141 +            {
  97.142 +                return this.XAxis.InverseTransform(x, y, this.YAxis);
  97.143 +            }
  97.144 +
  97.145 +            if (this.YAxis != null)
  97.146 +            {
  97.147 +                return new DataPoint(0, this.YAxis.InverseTransform(y));
  97.148 +            }
  97.149 +
  97.150 +            return new DataPoint();
  97.151 +        }
  97.152 +
  97.153 +    }
  97.154 +}
  97.155 \ No newline at end of file
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/PanManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
    98.3 @@ -0,0 +1,100 @@
    98.4 +// --------------------------------------------------------------------------------------------------------------------
    98.5 +// <copyright file="PanManipulator.cs" company="OxyPlot">
    98.6 +//   The MIT License (MIT)
    98.7 +//
    98.8 +//   Copyright (c) 2012 Oystein Bjorke
    98.9 +//
   98.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   98.11 +//   copy of this software and associated documentation files (the
   98.12 +//   "Software"), to deal in the Software without restriction, including
   98.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   98.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   98.15 +//   permit persons to whom the Software is furnished to do so, subject to
   98.16 +//   the following conditions:
   98.17 +//
   98.18 +//   The above copyright notice and this permission notice shall be included
   98.19 +//   in all copies or substantial portions of the Software.
   98.20 +//
   98.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   98.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   98.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   98.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   98.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   98.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   98.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   98.28 +// </copyright>
   98.29 +// <summary>
   98.30 +//   The pan manipulator.
   98.31 +// </summary>
   98.32 +// --------------------------------------------------------------------------------------------------------------------
   98.33 +namespace OxyPlot
   98.34 +{
   98.35 +    /// <summary>
   98.36 +    /// Provides a plot control manipulator for panning functionality.
   98.37 +    /// </summary>
   98.38 +    public class PanManipulator : ManipulatorBase
   98.39 +    {
   98.40 +        /// <summary>
   98.41 +        /// Initializes a new instance of the <see cref="PanManipulator"/> class.
   98.42 +        /// </summary>
   98.43 +        /// <param name="plotControl">
   98.44 +        /// The plot control.
   98.45 +        /// </param>
   98.46 +        public PanManipulator(IPlotControl plotControl)
   98.47 +            : base(plotControl)
   98.48 +        {
   98.49 +        }
   98.50 +
   98.51 +        /// <summary>
   98.52 +        /// Gets or sets the previous position.
   98.53 +        /// </summary>
   98.54 +        private ScreenPoint PreviousPosition { get; set; }
   98.55 +
   98.56 +        /// <summary>
   98.57 +        /// Occurs when the input device changes position during a manipulation.
   98.58 +        /// </summary>
   98.59 +        /// <param name="e">
   98.60 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
   98.61 +        /// </param>
   98.62 +        public override void Delta(ManipulationEventArgs e)
   98.63 +        {
   98.64 +            base.Delta(e);
   98.65 +            if (this.XAxis != null)
   98.66 +            {
   98.67 +                this.PlotControl.Pan(this.XAxis, this.PreviousPosition, e.CurrentPosition);
   98.68 +            }
   98.69 +
   98.70 +            if (this.YAxis != null)
   98.71 +            {
   98.72 +                this.PlotControl.Pan(this.YAxis, this.PreviousPosition, e.CurrentPosition);
   98.73 +            }
   98.74 +
   98.75 +            this.PlotControl.RefreshPlot(false);
   98.76 +            this.PreviousPosition = e.CurrentPosition;
   98.77 +        }
   98.78 +
   98.79 +        /// <summary>
   98.80 +        /// Gets the cursor for the manipulation.
   98.81 +        /// </summary>
   98.82 +        /// <returns>
   98.83 +        /// The cursor.
   98.84 +        /// </returns>
   98.85 +        public override CursorType GetCursorType()
   98.86 +        {
   98.87 +            return CursorType.Pan;
   98.88 +        }
   98.89 +
   98.90 +        /// <summary>
   98.91 +        /// Occurs when an input device begins a manipulation on the plot.
   98.92 +        /// </summary>
   98.93 +        /// <param name="e">
   98.94 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
   98.95 +        /// </param>
   98.96 +        public override void Started(ManipulationEventArgs e)
   98.97 +        {
   98.98 +            base.Started(e);
   98.99 +            this.PreviousPosition = e.CurrentPosition;
  98.100 +        }
  98.101 +
  98.102 +    }
  98.103 +}
  98.104 \ No newline at end of file
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ResetManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
    99.3 @@ -0,0 +1,71 @@
    99.4 +// --------------------------------------------------------------------------------------------------------------------
    99.5 +// <copyright file="ResetManipulator.cs" company="OxyPlot">
    99.6 +//   The MIT License (MIT)
    99.7 +//
    99.8 +//   Copyright (c) 2012 Oystein Bjorke
    99.9 +//
   99.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
   99.11 +//   copy of this software and associated documentation files (the
   99.12 +//   "Software"), to deal in the Software without restriction, including
   99.13 +//   without limitation the rights to use, copy, modify, merge, publish,
   99.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
   99.15 +//   permit persons to whom the Software is furnished to do so, subject to
   99.16 +//   the following conditions:
   99.17 +//
   99.18 +//   The above copyright notice and this permission notice shall be included
   99.19 +//   in all copies or substantial portions of the Software.
   99.20 +//
   99.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   99.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   99.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   99.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   99.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   99.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   99.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   99.28 +// </copyright>
   99.29 +// <summary>
   99.30 +//   The reset manipulator.
   99.31 +// </summary>
   99.32 +// --------------------------------------------------------------------------------------------------------------------
   99.33 +namespace OxyPlot
   99.34 +{
   99.35 +    /// <summary>
   99.36 +    /// Provides a plot control manipulator for reset functionality.
   99.37 +    /// </summary>
   99.38 +    public class ResetManipulator : ManipulatorBase
   99.39 +    {
   99.40 +        /// <summary>
   99.41 +        /// Initializes a new instance of the <see cref="ResetManipulator"/> class.
   99.42 +        /// </summary>
   99.43 +        /// <param name="plotControl">
   99.44 +        /// The plot control.
   99.45 +        /// </param>
   99.46 +        public ResetManipulator(IPlotControl plotControl)
   99.47 +            : base(plotControl)
   99.48 +        {
   99.49 +        }
   99.50 +
   99.51 +        /// <summary>
   99.52 +        /// Occurs when an input device begins a manipulation on the plot.
   99.53 +        /// </summary>
   99.54 +        /// <param name="e">
   99.55 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
   99.56 +        /// </param>
   99.57 +        public override void Started(ManipulationEventArgs e)
   99.58 +        {
   99.59 +            base.Started(e);
   99.60 +            if (this.XAxis != null)
   99.61 +            {
   99.62 +                this.PlotControl.Reset(this.XAxis);
   99.63 +            }
   99.64 +
   99.65 +            if (this.YAxis != null)
   99.66 +            {
   99.67 +                this.PlotControl.Reset(this.YAxis);
   99.68 +            }
   99.69 +
   99.70 +            this.PlotControl.InvalidatePlot();
   99.71 +        }
   99.72 +
   99.73 +    }
   99.74 +}
   99.75 \ No newline at end of file
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/TrackerHitResult.cs	Sat Jun 08 16:53:22 2013 +0000
   100.3 @@ -0,0 +1,162 @@
   100.4 +// --------------------------------------------------------------------------------------------------------------------
   100.5 +// <copyright file="TrackerHitResult.cs" company="OxyPlot">
   100.6 +//   The MIT License (MIT)
   100.7 +//
   100.8 +//   Copyright (c) 2012 Oystein Bjorke
   100.9 +//
  100.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  100.11 +//   copy of this software and associated documentation files (the
  100.12 +//   "Software"), to deal in the Software without restriction, including
  100.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  100.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  100.15 +//   permit persons to whom the Software is furnished to do so, subject to
  100.16 +//   the following conditions:
  100.17 +//
  100.18 +//   The above copyright notice and this permission notice shall be included
  100.19 +//   in all copies or substantial portions of the Software.
  100.20 +//
  100.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  100.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  100.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  100.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  100.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  100.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  100.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  100.28 +// </copyright>
  100.29 +// <summary>
  100.30 +//   Provides a data container for a tracker hit result.
  100.31 +// </summary>
  100.32 +// --------------------------------------------------------------------------------------------------------------------
  100.33 +namespace OxyPlot
  100.34 +{
  100.35 +    using OxyPlot.Series;
  100.36 +
  100.37 +    /// <summary>
  100.38 +    /// Provides a data container for a tracker hit result.
  100.39 +    /// </summary>
  100.40 +    /// <remarks>
  100.41 +    /// This is used as DataContext for the TrackerControl.
  100.42 +    /// The TrackerControl is visible when the user use the left mouse button to "track" points on the series.
  100.43 +    /// </remarks>
  100.44 +    public class TrackerHitResult
  100.45 +    {
  100.46 +        /// <summary>
  100.47 +        /// The default format string.
  100.48 +        /// </summary>
  100.49 +        private const string DefaultFormatString = "{0}\n{1}: {2}\n{3}: {4}";
  100.50 +
  100.51 +        /// <summary>
  100.52 +        /// Initializes a new instance of the <see cref="TrackerHitResult"/> class.
  100.53 +        /// </summary>
  100.54 +        /// <param name="series">The series.</param>
  100.55 +        /// <param name="dp">The data point.</param>
  100.56 +        /// <param name="sp">The screen point.</param>
  100.57 +        /// <param name="item">The item.</param>
  100.58 +        /// <param name="index">The index.</param>
  100.59 +        /// <param name="text">The text.</param>
  100.60 +        public TrackerHitResult(OxyPlot.Series.Series series, IDataPoint dp, ScreenPoint sp, object item = null, double index = -1, string text = null)
  100.61 +        {
  100.62 +            this.DataPoint = dp;
  100.63 +            this.Position = sp;
  100.64 +            this.Item = item;
  100.65 +            this.Index = index;
  100.66 +            this.Series = series;
  100.67 +            this.Text = text;
  100.68 +            var ds = series as DataPointSeries;
  100.69 +            if (ds != null)
  100.70 +            {
  100.71 +                this.XAxis = ds.XAxis;
  100.72 +                this.YAxis = ds.YAxis;
  100.73 +            }
  100.74 +        }
  100.75 +
  100.76 +        /// <summary>
  100.77 +        /// Gets or sets the nearest or interpolated data point.
  100.78 +        /// </summary>
  100.79 +        public IDataPoint DataPoint { get; set; }
  100.80 +
  100.81 +        /// <summary>
  100.82 +        /// Gets or sets the source item of the point.
  100.83 +        /// If the current point is from an ItemsSource and is not interpolated, this property will contain the item.
  100.84 +        /// </summary>
  100.85 +        public object Item { get; set; }
  100.86 +
  100.87 +        /// <summary>
  100.88 +        /// Gets or sets the index for the Item.
  100.89 +        /// </summary>
  100.90 +        public double Index { get; set; }
  100.91 +
  100.92 +        /// <summary>
  100.93 +        /// Gets or sets the horizontal/vertical line extents.
  100.94 +        /// </summary>
  100.95 +        public OxyRect LineExtents { get; set; }
  100.96 +
  100.97 +        /// <summary>
  100.98 +        /// Gets or sets the plot model.
  100.99 +        /// </summary>
 100.100 +        public PlotModel PlotModel { get; set; }
 100.101 +
 100.102 +        /// <summary>
 100.103 +        /// Gets or sets the position in screen coordinates.
 100.104 +        /// </summary>
 100.105 +        public ScreenPoint Position { get; set; }
 100.106 +
 100.107 +        /// <summary>
 100.108 +        /// Gets or sets the series that is being tracked.
 100.109 +        /// </summary>
 100.110 +        public Series.Series Series { get; set; }
 100.111 +
 100.112 +        /// <summary>
 100.113 +        /// Gets or sets the text shown in the tracker.
 100.114 +        /// </summary>
 100.115 +        public string Text { get; set; }
 100.116 +
 100.117 +        /// <summary>
 100.118 +        /// Gets or sets the X axis.
 100.119 +        /// </summary>
 100.120 +        public Axes.Axis XAxis { get; set; }
 100.121 +
 100.122 +        /// <summary>
 100.123 +        /// Gets or sets the Y axis.
 100.124 +        /// </summary>
 100.125 +        public Axes.Axis YAxis { get; set; }
 100.126 +
 100.127 +        /// <summary>
 100.128 +        /// Returns a <see cref="System.String"/> that represents this instance.
 100.129 +        /// </summary>
 100.130 +        /// <returns>
 100.131 +        /// A <see cref="System.String"/> that represents this instance.
 100.132 +        /// </returns>
 100.133 +        public override string ToString()
 100.134 +        {
 100.135 +            if (this.Text != null)
 100.136 +            {
 100.137 +                return this.Text;
 100.138 +            }
 100.139 +
 100.140 +            var ts = this.Series as ITrackableSeries;
 100.141 +            string formatString = DefaultFormatString;
 100.142 +            if (ts != null && !string.IsNullOrEmpty(ts.TrackerFormatString))
 100.143 +            {
 100.144 +                formatString = ts.TrackerFormatString;
 100.145 +            }
 100.146 +
 100.147 +            string xaxisTitle = (this.XAxis != null ? this.XAxis.Title : null) ?? "X";
 100.148 +            string yaxisTitle = (this.YAxis != null ? this.YAxis.Title : null) ?? "Y";
 100.149 +            object xvalue = this.XAxis != null ? this.XAxis.GetValue(this.DataPoint.X) : this.DataPoint.X;
 100.150 +            object yvalue = this.YAxis != null ? this.YAxis.GetValue(this.DataPoint.Y) : this.DataPoint.Y;
 100.151 +
 100.152 +            return StringHelper.Format(
 100.153 +                this.Series.ActualCulture,
 100.154 +                formatString,
 100.155 +                this.Item,
 100.156 +                this.Series.Title,
 100.157 +                xaxisTitle,
 100.158 +                xvalue,
 100.159 +                yaxisTitle,
 100.160 +                yvalue,
 100.161 +                this.Item).Trim();
 100.162 +        }
 100.163 +
 100.164 +    }
 100.165 +}
 100.166 \ No newline at end of file
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/TrackerManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
   101.3 @@ -0,0 +1,186 @@
   101.4 +// --------------------------------------------------------------------------------------------------------------------
   101.5 +// <copyright file="TrackerManipulator.cs" company="OxyPlot">
   101.6 +//   The MIT License (MIT)
   101.7 +//
   101.8 +//   Copyright (c) 2012 Oystein Bjorke
   101.9 +//
  101.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  101.11 +//   copy of this software and associated documentation files (the
  101.12 +//   "Software"), to deal in the Software without restriction, including
  101.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  101.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  101.15 +//   permit persons to whom the Software is furnished to do so, subject to
  101.16 +//   the following conditions:
  101.17 +//
  101.18 +//   The above copyright notice and this permission notice shall be included
  101.19 +//   in all copies or substantial portions of the Software.
  101.20 +//
  101.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  101.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  101.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  101.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  101.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  101.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  101.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  101.28 +// </copyright>
  101.29 +// <summary>
  101.30 +//   The tracker manipulator.
  101.31 +// </summary>
  101.32 +// --------------------------------------------------------------------------------------------------------------------
  101.33 +namespace OxyPlot
  101.34 +{
  101.35 +    using OxyPlot.Series;
  101.36 +
  101.37 +    /// <summary>
  101.38 +    /// Provides a plot control manipulator for tracker functionality.
  101.39 +    /// </summary>
  101.40 +    public class TrackerManipulator : ManipulatorBase
  101.41 +    {
  101.42 +        /// <summary>
  101.43 +        /// The current series.
  101.44 +        /// </summary>
  101.45 +        private ITrackableSeries currentSeries;
  101.46 +
  101.47 +        /// <summary>
  101.48 +        /// Initializes a new instance of the <see cref="TrackerManipulator"/> class.
  101.49 +        /// </summary>
  101.50 +        /// <param name="plotControl">
  101.51 +        /// The plot control.
  101.52 +        /// </param>
  101.53 +        public TrackerManipulator(IPlotControl plotControl)
  101.54 +            : base(plotControl)
  101.55 +        {
  101.56 +            this.Snap = true;
  101.57 +            this.PointsOnly = false;
  101.58 +        }
  101.59 +
  101.60 +        /// <summary>
  101.61 +        /// Gets or sets a value indicating whether to show tracker on points only (not interpolating).
  101.62 +        /// </summary>
  101.63 +        public bool PointsOnly { get; set; }
  101.64 +
  101.65 +        /// <summary>
  101.66 +        /// Gets or sets a value indicating whether to snap to the nearest point.
  101.67 +        /// </summary>
  101.68 +        public bool Snap { get; set; }
  101.69 +
  101.70 +        /// <summary>
  101.71 +        /// Occurs when a manipulation is complete.
  101.72 +        /// </summary>
  101.73 +        /// <param name="e">
  101.74 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
  101.75 +        /// </param>
  101.76 +        public override void Completed(ManipulationEventArgs e)
  101.77 +        {
  101.78 +            base.Completed(e);
  101.79 +
  101.80 +            if (this.currentSeries == null)
  101.81 +            {
  101.82 +                return;
  101.83 +            }
  101.84 +
  101.85 +            this.currentSeries = null;
  101.86 +            this.PlotControl.HideTracker();
  101.87 +        }
  101.88 +
  101.89 +        /// <summary>
  101.90 +        /// Occurs when the input device changes position during a manipulation.
  101.91 +        /// </summary>
  101.92 +        /// <param name="e">
  101.93 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
  101.94 +        /// </param>
  101.95 +        public override void Delta(ManipulationEventArgs e)
  101.96 +        {
  101.97 +            base.Delta(e);
  101.98 +            if (this.currentSeries == null)
  101.99 +            {
 101.100 +                return;
 101.101 +            }
 101.102 +
 101.103 +            if (!this.PlotControl.ActualModel.PlotArea.Contains(e.CurrentPosition.X, e.CurrentPosition.Y))
 101.104 +            {
 101.105 +                return;
 101.106 +            }
 101.107 +
 101.108 +            TrackerHitResult result = GetNearestHit(this.currentSeries, e.CurrentPosition, this.Snap, this.PointsOnly);
 101.109 +            if (result != null)
 101.110 +            {
 101.111 +                result.PlotModel = this.PlotControl.ActualModel;
 101.112 +                this.PlotControl.ShowTracker(result);
 101.113 +            }
 101.114 +        }
 101.115 +
 101.116 +        /// <summary>
 101.117 +        /// Gets the cursor for the manipulation.
 101.118 +        /// </summary>
 101.119 +        /// <returns>
 101.120 +        /// The cursor.
 101.121 +        /// </returns>
 101.122 +        public override CursorType GetCursorType()
 101.123 +        {
 101.124 +            return CursorType.Default;
 101.125 +        }
 101.126 +
 101.127 +        /// <summary>
 101.128 +        /// Occurs when an input device begins a manipulation on the plot.
 101.129 +        /// </summary>
 101.130 +        /// <param name="e">
 101.131 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
 101.132 +        /// </param>
 101.133 +        public override void Started(ManipulationEventArgs e)
 101.134 +        {
 101.135 +            base.Started(e);
 101.136 +            this.currentSeries = this.PlotControl.GetSeriesFromPoint(e.CurrentPosition);
 101.137 +            this.Delta(e);
 101.138 +        }
 101.139 +
 101.140 +        /// <summary>
 101.141 +        /// Gets the nearest tracker hit.
 101.142 +        /// </summary>
 101.143 +        /// <param name="s">
 101.144 +        /// The series.
 101.145 +        /// </param>
 101.146 +        /// <param name="point">
 101.147 +        /// The point.
 101.148 +        /// </param>
 101.149 +        /// <param name="snap">
 101.150 +        /// Snap to points.
 101.151 +        /// </param>
 101.152 +        /// <param name="pointsOnly">
 101.153 +        /// Check points only (no interpolation).
 101.154 +        /// </param>
 101.155 +        /// <returns>
 101.156 +        /// A tracker hit result.
 101.157 +        /// </returns>
 101.158 +        private static TrackerHitResult GetNearestHit(ITrackableSeries s, ScreenPoint point, bool snap, bool pointsOnly)
 101.159 +        {
 101.160 +            if (s == null)
 101.161 +            {
 101.162 +                return null;
 101.163 +            }
 101.164 +
 101.165 +            // Check data points only
 101.166 +            if (snap || pointsOnly)
 101.167 +            {
 101.168 +                TrackerHitResult result = s.GetNearestPoint(point, false);
 101.169 +                if (result != null)
 101.170 +                {
 101.171 +                    if (result.Position.DistanceTo(point) < 20)
 101.172 +                    {
 101.173 +                        return result;
 101.174 +                    }
 101.175 +                }
 101.176 +            }
 101.177 +
 101.178 +            // Check between data points (if possible)
 101.179 +            if (!pointsOnly)
 101.180 +            {
 101.181 +                TrackerHitResult result = s.GetNearestPoint(point, true);
 101.182 +                return result;
 101.183 +            }
 101.184 +
 101.185 +            return null;
 101.186 +        }
 101.187 +
 101.188 +    }
 101.189 +}
 101.190 \ No newline at end of file
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
   102.3 @@ -0,0 +1,72 @@
   102.4 +// --------------------------------------------------------------------------------------------------------------------
   102.5 +// <copyright file="ZoomManipulator.cs" company="OxyPlot">
   102.6 +//   The MIT License (MIT)
   102.7 +//
   102.8 +//   Copyright (c) 2012 Oystein Bjorke
   102.9 +//
  102.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  102.11 +//   copy of this software and associated documentation files (the
  102.12 +//   "Software"), to deal in the Software without restriction, including
  102.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  102.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  102.15 +//   permit persons to whom the Software is furnished to do so, subject to
  102.16 +//   the following conditions:
  102.17 +//
  102.18 +//   The above copyright notice and this permission notice shall be included
  102.19 +//   in all copies or substantial portions of the Software.
  102.20 +//
  102.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  102.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  102.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  102.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  102.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  102.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  102.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  102.28 +// </copyright>
  102.29 +// <summary>
  102.30 +//   The zoom manipulator.
  102.31 +// </summary>
  102.32 +// --------------------------------------------------------------------------------------------------------------------
  102.33 +namespace OxyPlot
  102.34 +{
  102.35 +    /// <summary>
  102.36 +    /// Provides a plot control manipulator for zoom functionality.
  102.37 +    /// </summary>
  102.38 +    public class ZoomManipulator : ManipulatorBase
  102.39 +    {
  102.40 +        /// <summary>
  102.41 +        /// Initializes a new instance of the <see cref="ZoomManipulator"/> class.
  102.42 +        /// </summary>
  102.43 +        /// <param name="plotControl">
  102.44 +        /// The plot control.
  102.45 +        /// </param>
  102.46 +        public ZoomManipulator(IPlotControl plotControl)
  102.47 +            : base(plotControl)
  102.48 +        {
  102.49 +        }
  102.50 +
  102.51 +        /// <summary>
  102.52 +        /// Occurs when the input device changes position during a manipulation.
  102.53 +        /// </summary>
  102.54 +        /// <param name="e">The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.</param>
  102.55 +        public override void Delta(ManipulationEventArgs e)
  102.56 +        {
  102.57 +            base.Delta(e);
  102.58 +
  102.59 +            DataPoint current = this.InverseTransform(e.CurrentPosition.X, e.CurrentPosition.Y);
  102.60 +
  102.61 +            if (this.XAxis != null)
  102.62 +            {
  102.63 +                this.PlotControl.ZoomAt(this.XAxis, e.ScaleX, current.X);
  102.64 +            }
  102.65 +
  102.66 +            if (this.YAxis != null)
  102.67 +            {
  102.68 +                this.PlotControl.ZoomAt(this.YAxis, e.ScaleY, current.Y);
  102.69 +            }
  102.70 +
  102.71 +            this.PlotControl.InvalidatePlot();
  102.72 +        }
  102.73 +
  102.74 +    }
  102.75 +}
  102.76 \ No newline at end of file
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomRectangleManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
   103.3 @@ -0,0 +1,154 @@
   103.4 +// --------------------------------------------------------------------------------------------------------------------
   103.5 +// <copyright file="ZoomRectangleManipulator.cs" company="OxyPlot">
   103.6 +//   The MIT License (MIT)
   103.7 +//
   103.8 +//   Copyright (c) 2012 Oystein Bjorke
   103.9 +//
  103.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  103.11 +//   copy of this software and associated documentation files (the
  103.12 +//   "Software"), to deal in the Software without restriction, including
  103.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  103.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  103.15 +//   permit persons to whom the Software is furnished to do so, subject to
  103.16 +//   the following conditions:
  103.17 +//
  103.18 +//   The above copyright notice and this permission notice shall be included
  103.19 +//   in all copies or substantial portions of the Software.
  103.20 +//
  103.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  103.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  103.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  103.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  103.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  103.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  103.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  103.28 +// </copyright>
  103.29 +// <summary>
  103.30 +//   The zoom manipulator.
  103.31 +// </summary>
  103.32 +// --------------------------------------------------------------------------------------------------------------------
  103.33 +namespace OxyPlot
  103.34 +{
  103.35 +    using System;
  103.36 +
  103.37 +    /// <summary>
  103.38 +    /// Provides a plot control manipulator for zoom by rectangle functionality.
  103.39 +    /// </summary>
  103.40 +    public class ZoomRectangleManipulator : ManipulatorBase
  103.41 +    {
  103.42 +        /// <summary>
  103.43 +        /// Initializes a new instance of the <see cref="ZoomRectangleManipulator"/> class.
  103.44 +        /// </summary>
  103.45 +        /// <param name="plotControl">
  103.46 +        /// The plot control.
  103.47 +        /// </param>
  103.48 +        public ZoomRectangleManipulator(IPlotControl plotControl)
  103.49 +            : base(plotControl)
  103.50 +        {
  103.51 +        }
  103.52 +
  103.53 +        /// <summary>
  103.54 +        /// Gets or sets the zoom rectangle.
  103.55 +        /// </summary>
  103.56 +        private OxyRect ZoomRectangle { get; set; }
  103.57 +
  103.58 +        /// <summary>
  103.59 +        /// Occurs when a manipulation is complete.
  103.60 +        /// </summary>
  103.61 +        /// <param name="e">
  103.62 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
  103.63 +        /// </param>
  103.64 +        public override void Completed(ManipulationEventArgs e)
  103.65 +        {
  103.66 +            base.Completed(e);
  103.67 +
  103.68 +            this.PlotControl.HideZoomRectangle();
  103.69 +
  103.70 +            if (this.ZoomRectangle.Width > 10 && this.ZoomRectangle.Height > 10)
  103.71 +            {
  103.72 +                DataPoint p0 = this.InverseTransform(this.ZoomRectangle.Left, this.ZoomRectangle.Top);
  103.73 +                DataPoint p1 = this.InverseTransform(this.ZoomRectangle.Right, this.ZoomRectangle.Bottom);
  103.74 +
  103.75 +                if (this.XAxis != null)
  103.76 +                {
  103.77 +                    this.PlotControl.Zoom(this.XAxis, p0.X, p1.X);
  103.78 +                }
  103.79 +
  103.80 +                if (this.YAxis != null)
  103.81 +                {
  103.82 +                    this.PlotControl.Zoom(this.YAxis, p0.Y, p1.Y);
  103.83 +                }
  103.84 +
  103.85 +                this.PlotControl.InvalidatePlot();
  103.86 +            }
  103.87 +        }
  103.88 +
  103.89 +        /// <summary>
  103.90 +        /// Occurs when the input device changes position during a manipulation.
  103.91 +        /// </summary>
  103.92 +        /// <param name="e">
  103.93 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
  103.94 +        /// </param>
  103.95 +        public override void Delta(ManipulationEventArgs e)
  103.96 +        {
  103.97 +            base.Delta(e);
  103.98 +
  103.99 +            OxyRect plotArea = this.PlotControl.ActualModel.PlotArea;
 103.100 +
 103.101 +            double x = Math.Min(this.StartPosition.X, e.CurrentPosition.X);
 103.102 +            double w = Math.Abs(this.StartPosition.X - e.CurrentPosition.X);
 103.103 +            double y = Math.Min(this.StartPosition.Y, e.CurrentPosition.Y);
 103.104 +            double h = Math.Abs(this.StartPosition.Y - e.CurrentPosition.Y);
 103.105 +
 103.106 +            if (this.XAxis == null)
 103.107 +            {
 103.108 +                x = plotArea.Left;
 103.109 +                w = plotArea.Width;
 103.110 +            }
 103.111 +
 103.112 +            if (this.YAxis == null)
 103.113 +            {
 103.114 +                y = plotArea.Top;
 103.115 +                h = plotArea.Height;
 103.116 +            }
 103.117 +
 103.118 +            this.ZoomRectangle = new OxyRect(x, y, w, h);
 103.119 +            this.PlotControl.ShowZoomRectangle(this.ZoomRectangle);
 103.120 +        }
 103.121 +
 103.122 +        /// <summary>
 103.123 +        /// Gets the cursor for the manipulation.
 103.124 +        /// </summary>
 103.125 +        /// <returns>
 103.126 +        /// The cursor.
 103.127 +        /// </returns>
 103.128 +        public override CursorType GetCursorType()
 103.129 +        {
 103.130 +            if (this.XAxis == null)
 103.131 +            {
 103.132 +                return CursorType.ZoomVertical;
 103.133 +            }
 103.134 +
 103.135 +            if (this.YAxis == null)
 103.136 +            {
 103.137 +                return CursorType.ZoomHorizontal;
 103.138 +            }
 103.139 +
 103.140 +            return CursorType.ZoomRectangle;
 103.141 +        }
 103.142 +
 103.143 +        /// <summary>
 103.144 +        /// Occurs when an input device begins a manipulation on the plot.
 103.145 +        /// </summary>
 103.146 +        /// <param name="e">
 103.147 +        /// The <see cref="OxyPlot.ManipulationEventArgs"/> instance containing the event data.
 103.148 +        /// </param>
 103.149 +        public override void Started(ManipulationEventArgs e)
 103.150 +        {
 103.151 +            base.Started(e);
 103.152 +            this.ZoomRectangle = new OxyRect(this.StartPosition.X, this.StartPosition.Y, 0, 0);
 103.153 +            this.PlotControl.ShowZoomRectangle(this.ZoomRectangle);
 103.154 +        }
 103.155 +
 103.156 +    }
 103.157 +}
 103.158 \ No newline at end of file
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/External/OxyPlot/OxyPlot/Manipulators/ZoomStepManipulator.cs	Sat Jun 08 16:53:22 2013 +0000
   104.3 @@ -0,0 +1,106 @@
   104.4 +// --------------------------------------------------------------------------------------------------------------------
   104.5 +// <copyright file="ZoomStepManipulator.cs" company="OxyPlot">
   104.6 +//   The MIT License (MIT)
   104.7 +//
   104.8 +//   Copyright (c) 2012 Oystein Bjorke
   104.9 +//
  104.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  104.11 +//   copy of this software and associated documentation files (the
  104.12 +//   "Software"), to deal in the Software without restriction, including
  104.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  104.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  104.15 +//   permit persons to whom the Software is furnished to do so, subject to
  104.16 +//   the following conditions:
  104.17 +//
  104.18 +//   The above copyright notice and this permission notice shall be included
  104.19 +//   in all copies or substantial portions of the Software.
  104.20 +//
  104.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  104.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  104.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  104.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  104.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  104.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  104.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  104.28 +// </copyright>
  104.29 +// <summary>
  104.30 +//   The step manipulator.
  104.31 +// </summary>
  104.32 +// --------------------------------------------------------------------------------------------------------------------
  104.33 +namespace OxyPlot
  104.34 +{
  104.35 +    /// <summary>
  104.36 +    /// Provides a plot control manipulator for stepwise zoom functionality.
  104.37 +    /// </summary>
  104.38 +    public class ZoomStepManipulator : ManipulatorBase
  104.39 +    {
  104.40 +        /// <summary>
  104.41 +        /// Initializes a new instance of the <see cref="ZoomStepManipulator"/> class.
  104.42 +        /// </summary>
  104.43 +        /// <param name="plotControl">
  104.44 +        /// The plot control.
  104.45 +        /// </param>
  104.46 +        /// <param name="step">
  104.47 +        /// The step.
  104.48 +        /// </param>
  104.49 +        /// <param name="fineControl">
  104.50 +        /// The fine Control.
  104.51 +        /// </param>
  104.52 +        public ZoomStepManipulator(IPlotControl plotControl, double step, bool fineControl)
  104.53 +            : base(plotControl)
  104.54 +        {
  104.55 +            this.Step = step;
  104.56 +            this.FineControl = fineControl;
  104.57 +        }
  104.58 +
  104.59 +        /// <summary>
  104.60 +        /// Gets or sets a value indicating whether FineControl.
  104.61 +        /// </summary>
  104.62 +        public bool FineControl { get; set; }
  104.63 +
  104.64 +        /// <summary>
  104.65 +        /// Gets or sets Step.
  104.66 +        /// </summary>
  104.67 +        public double Step { get; set; }
  104.68 +
  104.69 +        /// <summary>
  104.70 +        /// The started.
  104.71 +        /// </summary>
  104.72 +        /// <param name="e">
  104.73 +        /// The e.
  104.74 +        /// </param>
  104.75 +        public override void Started(ManipulationEventArgs e)
  104.76 +        {
  104.77 +            base.Started(e);
  104.78 +
  104.79 +            DataPoint current = this.InverseTransform(e.CurrentPosition.X, e.CurrentPosition.Y);
  104.80 +
  104.81 +            double scale = this.Step;
  104.82 +            if (this.FineControl)
  104.83 +            {
  104.84 +                scale *= 3;
  104.85 +            }
  104.86 +
  104.87 +            scale = 1 + scale;
  104.88 +
  104.89 +            // make sure the zoom factor is not negative
  104.90 +            if (scale < 0.1)
  104.91 +            {
  104.92 +                scale = 0.1;
  104.93 +            }
  104.94 +
  104.95 +            if (this.XAxis != null)
  104.96 +            {
  104.97 +                this.PlotControl.ZoomAt(this.XAxis, scale, current.X);
  104.98 +            }
  104.99 +
 104.100 +            if (this.YAxis != null)
 104.101 +            {
 104.102 +                this.PlotControl.ZoomAt(this.YAxis, scale, current.Y);
 104.103 +            }
 104.104 +
 104.105 +            this.PlotControl.InvalidatePlot();
 104.106 +        }
 104.107 +
 104.108 +    }
 104.109 +}
 104.110 \ No newline at end of file
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/External/OxyPlot/OxyPlot/MouseActions/MouseAction.cs	Sat Jun 08 16:53:22 2013 +0000
   105.3 @@ -0,0 +1,54 @@
   105.4 +// --------------------------------------------------------------------------------------------------------------------
   105.5 +// <copyright file="MouseAction.cs" company="OxyPlot">
   105.6 +//   The MIT License (MIT)
   105.7 +//
   105.8 +//   Copyright (c) 2012 Oystein Bjorke
   105.9 +//
  105.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  105.11 +//   copy of this software and associated documentation files (the
  105.12 +//   "Software"), to deal in the Software without restriction, including
  105.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  105.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  105.15 +//   permit persons to whom the Software is furnished to do so, subject to
  105.16 +//   the following conditions:
  105.17 +//
  105.18 +//   The above copyright notice and this permission notice shall be included
  105.19 +//   in all copies or substantial portions of the Software.
  105.20 +//
  105.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  105.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  105.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  105.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  105.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  105.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  105.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  105.28 +// </copyright>
  105.29 +// --------------------------------------------------------------------------------------------------------------------
  105.30 +namespace OxyPlot
  105.31 +{
  105.32 +    public abstract class MouseAction : IMouseAction
  105.33 +    {
  105.34 +        protected IPlotControl pc;
  105.35 +
  105.36 +        protected MouseAction(IPlotControl pc)
  105.37 +        {
  105.38 +            this.pc = pc;
  105.39 +        }
  105.40 +
  105.41 +        public virtual void OnMouseDown(ScreenPoint pt, OxyMouseButton button, int clickCount, bool control, bool shift, bool alt)
  105.42 +        {
  105.43 +        }
  105.44 +
  105.45 +        public virtual void OnMouseMove(ScreenPoint pt, bool control, bool shift, bool alt)
  105.46 +        {
  105.47 +        }
  105.48 +
  105.49 +        public virtual void OnMouseUp()
  105.50 +        {
  105.51 +        }
  105.52 +
  105.53 +        public virtual void OnMouseWheel(ScreenPoint pt, double delta, bool control, bool shift, bool alt)
  105.54 +        {
  105.55 +        }
  105.56 +    }
  105.57 +}
  105.58 \ No newline at end of file
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/External/OxyPlot/OxyPlot/MouseActions/SliderAction.cs	Sat Jun 08 16:53:22 2013 +0000
   106.3 @@ -0,0 +1,106 @@
   106.4 +// --------------------------------------------------------------------------------------------------------------------
   106.5 +// <copyright file="SliderAction.cs" company="OxyPlot">
   106.6 +//   The MIT License (MIT)
   106.7 +//
   106.8 +//   Copyright (c) 2012 Oystein Bjorke
   106.9 +//
  106.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  106.11 +//   copy of this software and associated documentation files (the
  106.12 +//   "Software"), to deal in the Software without restriction, including
  106.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  106.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  106.15 +//   permit persons to whom the Software is furnished to do so, subject to
  106.16 +//   the following conditions:
  106.17 +//
  106.18 +//   The above copyright notice and this permission notice shall be included
  106.19 +//   in all copies or substantial portions of the Software.
  106.20 +//
  106.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  106.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  106.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  106.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  106.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  106.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  106.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  106.28 +// </copyright>
  106.29 +// --------------------------------------------------------------------------------------------------------------------
  106.30 +namespace OxyPlot
  106.31 +{
  106.32 +    // todo: use screen coordinates instead of original points (problem on log axes)
  106.33 +    public class SliderAction : MouseAction
  106.34 +    {
  106.35 +        public SliderAction(IPlot pc)
  106.36 +            : base(pc)
  106.37 +        {
  106.38 +        }
  106.39 +
  106.40 +        private DataSeries currentSeries;
  106.41 +
  106.42 +        public override void OnMouseDown(ScreenPoint pt, OxyMouseButton button, int clickCount, bool control, bool shift)
  106.43 +        {
  106.44 +            base.OnMouseDown(pt, button, clickCount, control, shift);
  106.45 +
  106.46 +            if (button != OxyMouseButton.Left)
  106.47 +                return;
  106.48 +
  106.49 +            // Middle button double click adds an annotation
  106.50 +            if (clickCount == 2)
  106.51 +            {
  106.52 +                // pc.Annotations.
  106.53 +                pc.Refresh();
  106.54 +            }
  106.55 +
  106.56 +            currentSeries = pc.GetSeriesFromPoint(pt) as DataSeries;
  106.57 +
  106.58 +            OnMouseMove(pt, control, shift);
  106.59 +
  106.60 +            //pc.CaptureMouse();
  106.61 +            // pc.Cursor = Cursors.Cross;
  106.62 +        }
  106.63 +
  106.64 +        public override void OnMouseMove(ScreenPoint pt, bool control, bool shift)
  106.65 +        {
  106.66 +            if (currentSeries == null)
  106.67 +                return;
  106.68 +
  106.69 +            var current = GetNearestPoint(currentSeries, pt, !control, shift);
  106.70 +            if (current != null)
  106.71 +                pc.ShowSlider(currentSeries, current.Value);
  106.72 +        }
  106.73 +
  106.74 +        private static DataPoint? GetNearestPoint(ISeries s, ScreenPoint point, bool snap, bool pointsOnly)
  106.75 +        {
  106.76 +            if (s == null)
  106.77 +                return null;
  106.78 +
  106.79 +            if (snap || pointsOnly)
  106.80 +            {
  106.81 +                ScreenPoint spn;
  106.82 +                DataPoint dpn;
  106.83 +                if (s.GetNearestPoint(point, out dpn, out spn) && snap)
  106.84 +                {
  106.85 +                    if (spn.DistanceTo(point) < 20)
  106.86 +                        return dpn;
  106.87 +                }
  106.88 +            }
  106.89 +
  106.90 +            ScreenPoint sp;
  106.91 +            DataPoint dp;
  106.92 +
  106.93 +            if (!pointsOnly)
  106.94 +                if (s.GetNearestInterpolatedPoint(point, out dp, out sp))
  106.95 +                    return dp;
  106.96 +
  106.97 +            return null;
  106.98 +        }
  106.99 +
 106.100 +        public override void OnMouseUp()
 106.101 +        {
 106.102 +            base.OnMouseUp();
 106.103 +            if (currentSeries == null)
 106.104 +                return;
 106.105 +            currentSeries = null;
 106.106 +            pc.HideSlider();
 106.107 +        }
 106.108 +    }
 106.109 +}
 106.110 \ No newline at end of file
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/External/OxyPlot/OxyPlot/NamespaceDoc.cs	Sat Jun 08 16:53:22 2013 +0000
   107.3 @@ -0,0 +1,37 @@
   107.4 +// --------------------------------------------------------------------------------------------------------------------
   107.5 +// <copyright file="NamespaceDoc.cs" company="OxyPlot">
   107.6 +//   The MIT License (MIT)
   107.7 +//   
   107.8 +//   Copyright (c) 2012 Oystein Bjorke
   107.9 +//   
  107.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  107.11 +//   copy of this software and associated documentation files (the
  107.12 +//   "Software"), to deal in the Software without restriction, including
  107.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  107.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  107.15 +//   permit persons to whom the Software is furnished to do so, subject to
  107.16 +//   the following conditions:
  107.17 +//   
  107.18 +//   The above copyright notice and this permission notice shall be included
  107.19 +//   in all copies or substantial portions of the Software.
  107.20 +//   
  107.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  107.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  107.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  107.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  107.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  107.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  107.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  107.28 +// </copyright>
  107.29 +// --------------------------------------------------------------------------------------------------------------------
  107.30 +
  107.31 +namespace OxyPlot
  107.32 +{
  107.33 +    /// <summary>
  107.34 +    /// The OxyPlot namespace contains the platform independent classes of the library.
  107.35 +    /// </summary>
  107.36 +    [System.Runtime.CompilerServices.CompilerGenerated]
  107.37 +    internal class NamespaceDoc
  107.38 +    {
  107.39 +    }
  107.40 +}
  107.41 \ No newline at end of file
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj	Sat Jun 08 16:53:22 2013 +0000
   108.3 @@ -0,0 +1,237 @@
   108.4 +<?xml version="1.0" encoding="utf-8"?>
   108.5 +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   108.6 +  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   108.7 +  <PropertyGroup>
   108.8 +    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
   108.9 +    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
  108.10 +    <ProjectGuid>{BCC43E58-E473-403E-A84D-63FEDC723040}</ProjectGuid>
  108.11 +    <OutputType>Library</OutputType>
  108.12 +    <AppDesignerFolder>Properties</AppDesignerFolder>
  108.13 +    <RootNamespace>OxyPlot</RootNamespace>
  108.14 +    <AssemblyName>OxyPlot</AssemblyName>
  108.15 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
  108.16 +    <FileAlignment>512</FileAlignment>
  108.17 +    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
  108.18 +  </PropertyGroup>
  108.19 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  108.20 +    <DebugSymbols>true</DebugSymbols>
  108.21 +    <DebugType>full</DebugType>
  108.22 +    <Optimize>false</Optimize>
  108.23 +    <OutputPath>bin\Debug\</OutputPath>
  108.24 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
  108.25 +    <ErrorReport>prompt</ErrorReport>
  108.26 +    <WarningLevel>4</WarningLevel>
  108.27 +  </PropertyGroup>
  108.28 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  108.29 +    <DebugType>pdbonly</DebugType>
  108.30 +    <Optimize>true</Optimize>
  108.31 +    <OutputPath>..\..\Output\NET40x\</OutputPath>
  108.32 +    <DefineConstants>TRACE</DefineConstants>
  108.33 +    <ErrorReport>prompt</ErrorReport>
  108.34 +    <WarningLevel>4</WarningLevel>
  108.35 +    <DocumentationFile>..\..\Output\NET40x\OxyPlot.XML</DocumentationFile>
  108.36 +  </PropertyGroup>
  108.37 +  <PropertyGroup>
  108.38 +    <SignAssembly>true</SignAssembly>
  108.39 +  </PropertyGroup>
  108.40 +  <PropertyGroup>
  108.41 +    <AssemblyOriginatorKeyFile>OxyPlot.snk</AssemblyOriginatorKeyFile>
  108.42 +  </PropertyGroup>
  108.43 +  <ItemGroup>
  108.44 +    <Reference Include="System" />
  108.45 +    <Reference Include="System.Core" />
  108.46 +    <Reference Include="System.Xml.Linq" />
  108.47 +    <Reference Include="System.Data.DataSetExtensions" />
  108.48 +    <Reference Include="Microsoft.CSharp" />
  108.49 +    <Reference Include="System.Data" />
  108.50 +    <Reference Include="System.Xml" />
  108.51 +  </ItemGroup>
  108.52 +  <ItemGroup>
  108.53 +    <Compile Include="..\GlobalAssemblyInfo.cs">
  108.54 +      <Link>Properties\GlobalAssemblyInfo.cs</Link>
  108.55 +    </Compile>
  108.56 +    <Compile Include="Annotations\Annotation.cs" />
  108.57 +    <Compile Include="Annotations\AnnotationLayer.cs" />
  108.58 +    <Compile Include="Annotations\ArrowAnnotation.cs" />
  108.59 +    <Compile Include="Annotations\EllipseAnnotation.cs" />
  108.60 +    <Compile Include="Annotations\ImageAnnotation.cs" />
  108.61 +    <Compile Include="Annotations\TileMapAnnotation.cs" />
  108.62 +    <Compile Include="Foundation\PlotLength.cs" />
  108.63 +    <Compile Include="Foundation\PlotLengthUnit.cs" />
  108.64 +    <Compile Include="Annotations\RectangleAnnotation.cs" />
  108.65 +    <Compile Include="Annotations\TextAnnotation.cs" />
  108.66 +    <Compile Include="Annotations\PolygonAnnotation.cs" />
  108.67 +    <Compile Include="Annotations\LineAnnotation.cs" />
  108.68 +    <Compile Include="Annotations\LineAnnotationType.cs" />
  108.69 +    <Compile Include="Annotations\TextualAnnotation.cs" />
  108.70 +    <Compile Include="Axes\AngleAxis.cs" />
  108.71 +    <Compile Include="Axes\Axis.cs" />
  108.72 +    <Compile Include="Axes\AxisChangedEventArgs.cs" />
  108.73 +    <Compile Include="Axes\AxisChangeTypes.cs" />
  108.74 +    <Compile Include="Axes\AxisLayer.cs" />
  108.75 +    <Compile Include="Axes\AxisPosition.cs" />
  108.76 +    <Compile Include="Axes\CategoryAxis.cs" />
  108.77 +    <Compile Include="Axes\ColorAxis.cs" />
  108.78 +    <Compile Include="Axes\DateTimeAxis.cs" />
  108.79 +    <Compile Include="Axes\DateTimeIntervalType.cs" />
  108.80 +    <Compile Include="Axes\LinearAxis.cs" />
  108.81 +    <Compile Include="Axes\MagnitudeAxis.cs" />
  108.82 +    <Compile Include="Axes\TickStyle.cs" />
  108.83 +    <Compile Include="Axes\TimeSpanAxis.cs" />
  108.84 +    <Compile Include="Foundation\CodeGenerator\CodeGenerationAttribute.cs" />
  108.85 +    <Compile Include="Foundation\CodeGenerator\CodeGenerator.cs" />
  108.86 +    <Compile Include="Foundation\CodeGenerator\CodeGeneratorStringExtensions.cs" />
  108.87 +    <Compile Include="Foundation\CodeGenerator\ICodeGenerating.cs" />
  108.88 +    <Compile Include="Foundation\ListFiller.cs" />
  108.89 +    <Compile Include="Foundation\OxyPalette.cs" />
  108.90 +    <Compile Include="Foundation\OxyPalettes.cs" />
  108.91 +    <Compile Include="Foundation\PngEncoder.cs" />
  108.92 +    <Compile Include="Foundation\ScreenVector.cs" />
  108.93 +    <Compile Include="Foundation\StreamExtensions.cs" />
  108.94 +    <Compile Include="Foundation\StringHelper.cs" />
  108.95 +    <Compile Include="Foundation\DoubleExtensions.cs" />
  108.96 +    <Compile Include="Foundation\FractionHelper.cs" />
  108.97 +    <Compile Include="Foundation\ArrayHelper.cs" />
  108.98 +    <Compile Include="Foundation\IDataPoint.cs" />
  108.99 +    <Compile Include="Foundation\ReflectionHelper.cs" />
 108.100 +    <Compile Include="Foundation\ScreenPointHelper.cs" />
 108.101 +    <Compile Include="Manipulators\ZoomManipulator.cs" />
 108.102 +    <Compile Include="Manipulators\ZoomStepManipulator.cs" />
 108.103 +    <Compile Include="Manipulators\ResetManipulator.cs" />
 108.104 +    <Compile Include="Manipulators\ManipulationEventArgs.cs" />
 108.105 +    <Compile Include="Manipulators\TrackerManipulator.cs" />
 108.106 +    <Compile Include="Manipulators\ZoomRectangleManipulator.cs" />
 108.107 +    <Compile Include="Manipulators\ManipulatorBase.cs" />
 108.108 +    <Compile Include="Manipulators\CursorType.cs" />
 108.109 +    <Compile Include="Manipulators\PanManipulator.cs" />
 108.110 +    <Compile Include="Manipulators\TrackerHitResult.cs" />
 108.111 +    <Compile Include="LibraryDoc.cs" />
 108.112 +    <Compile Include="NamespaceDoc.cs" />
 108.113 +    <Compile Include="PlotModel\HitTestResult.cs" />
 108.114 +    <Compile Include="Foundation\OxyImage.cs" />
 108.115 +    <Compile Include="Reporting\NamespaceDoc.cs" />
 108.116 +    <Compile Include="Series\BarSeries\BarItem.cs" />
 108.117 +    <Compile Include="Series\BarSeries\BarItemBase.cs" />
 108.118 +    <Compile Include="Series\BarSeries\BarSeriesBase{T}.cs" />
 108.119 +    <Compile Include="Series\BarSeries\CategorizedItem.cs" />
 108.120 +    <Compile Include="Series\BarSeries\CategorizedSeries.cs" />
 108.121 +    <Compile Include="Series\BarSeries\ErrorColumnItem.cs" />
 108.122 +    <Compile Include="Series\BarSeries\ColumnItem.cs" />
 108.123 +    <Compile Include="Series\BarSeries\ErrorColumnSeries.cs" />
 108.124 +    <Compile Include="Series\BarSeries\IStackableSeries.cs" />
 108.125 +    <Compile Include="Series\BoxPlotItem.cs" />
 108.126 +    <Compile Include="Series\BoxPlotSeries.cs" />
 108.127 +    <Compile Include="Foundation\IDataPointProvider.cs" />
 108.128 +    <Compile Include="Series\HeatMapSeries.cs" />
 108.129 +    <Compile Include="Series\LineLegendPosition.cs" />
 108.130 +    <Compile Include="Svg\SvgExporter.cs" />
 108.131 +    <Compile Include="PlotModel\PlotModel.MouseEvents.cs" />
 108.132 +    <Compile Include="PlotModel\OxyMouseButton.cs" />
 108.133 +    <Compile Include="PlotModel\OxyMouseEventArgs.cs" />
 108.134 +    <Compile Include="PlotModel\PlotElement.cs" />
 108.135 +    <Compile Include="PlotModel\PlotModel.Legends.cs" />
 108.136 +    <Compile Include="Foundation\CanonicalSplineHelper.cs" />
 108.137 +    <Compile Include="Foundation\FontWeights.cs" />
 108.138 +    <Compile Include="Foundation\OxyThickness.cs" />
 108.139 +    <Compile Include="Foundation\ScreenPoint.cs" />
 108.140 +    <Compile Include="Foundation\OxyRect.cs" />
 108.141 +    <Compile Include="Foundation\OxySize.cs" />
 108.142 +    <Compile Include="Foundation\SutherlandHodgmanClipping.cs" />
 108.143 +    <Compile Include="Manipulators\IPlotControl.cs" />
 108.144 +    <Compile Include="PlotModel\PlotModel.Rendering.cs" />
 108.145 +    <Compile Include="PlotModel\SelectablePlotElement.cs" />
 108.146 +    <Compile Include="PlotModel\UIPlotElement.cs" />
 108.147 +    <Compile Include="Render\AxisRendererBase.cs" />
 108.148 +    <Compile Include="Foundation\CohenSutherlandClipping.cs" />
 108.149 +    <Compile Include="Render\AngleAxisRenderer.cs" />
 108.150 +    <Compile Include="Foundation\HorizontalAlignment.cs" />
 108.151 +    <Compile Include="Render\MagnitudeAxisRenderer.cs" />
 108.152 +    <Compile Include="Render\MathRenderingExtensions.cs" />
 108.153 +    <Compile Include="Foundation\OxyPenLineJoin.cs" />
 108.154 +    <Compile Include="Render\RenderContextBase.cs" />
 108.155 +    <Compile Include="Render\RenderingExtensions.cs" />
 108.156 +    <Compile Include="Render\HorizontalAndVerticalAxisRenderer.cs" />
 108.157 +    <Compile Include="Render\IRenderContext.cs" />
 108.158 +    <Compile Include="Foundation\VerticalAlignment.cs" />
 108.159 +    <Compile Include="Reporting\ReportWriters\WikiReportWriter.cs" />
 108.160 +    <Compile Include="Reporting\ReportWriters\HtmlReportWriter.cs" />
 108.161 +    <Compile Include="Reporting\ReportWriters\IReportWriter.cs" />
 108.162 +    <Compile Include="Reporting\ReportWriters\StringExtensions.cs" />
 108.163 +    <Compile Include="Reporting\ReportWriters\TextReportWriter.cs" />
 108.164 +    <Compile Include="Reporting\Report\ItemsTable.cs" />
 108.165 +    <Compile Include="Reporting\Report\ParagraphStyle.cs" />
 108.166 +    <Compile Include="Reporting\Report\ReportStyle.cs" />
 108.167 +    <Compile Include="Reporting\Report\TableOfContents.cs" />
 108.168 +    <Compile Include="Reporting\Report\DrawingFigure.cs" />
 108.169 +    <Compile Include="Reporting\Report\Equation.cs" />
 108.170 +    <Compile Include="Reporting\Report\Figure.cs" />
 108.171 +    <Compile Include="Reporting\Report\Header.cs" />
 108.172 +    <Compile Include="Reporting\Report\HeaderHelper.cs" />
 108.173 +    <Compile Include="Reporting\Report\Image.cs" />
 108.174 +    <Compile Include="Reporting\Report\Paragraph.cs" />
 108.175 +    <Compile Include="Reporting\Report\PlotFigure.cs" />
 108.176 +    <Compile Include="Reporting\Report\PropertyTable.cs" />
 108.177 +    <Compile Include="Reporting\Report\Report.cs" />
 108.178 +    <Compile Include="Reporting\Report\ReportItem.cs" />
 108.179 +    <Compile Include="Reporting\Report\ReportSection.cs" />
 108.180 +    <Compile Include="Reporting\Report\Table.cs" />
 108.181 +    <Compile Include="Reporting\Report\ItemsTableField.cs" />
 108.182 +    <Compile Include="Series\AreaSeries.cs" />
 108.183 +    <Compile Include="Foundation\OxyPen.cs" />
 108.184 +    <Compile Include="Foundation\LineStyleHelper.cs" />
 108.185 +    <Compile Include="Foundation\DataPoint.cs" />
 108.186 +    <Compile Include="Series\BarSeries\LabelPlacement.cs" />
 108.187 +    <Compile Include="Series\CandleStickSeries.cs" />
 108.188 +    <Compile Include="Foundation\Conrec.cs" />
 108.189 +    <Compile Include="Series\ContourSeries.cs" />
 108.190 +    <Compile Include="Series\BarSeries\ColumnSeries.cs" />
 108.191 +    <Compile Include="Series\BarSeries\BarSeries.cs" />
 108.192 +    <Compile Include="Series\BarSeries\BarSeriesBase.cs" />
 108.193 +    <Compile Include="Series\BarSeries\IntervalBarItem.cs" />
 108.194 +    <Compile Include="Series\BarSeries\RectangleBarItem.cs" />
 108.195 +    <Compile Include="Series\BarSeries\RectangleBarSeries.cs" />
 108.196 +    <Compile Include="Series\BarSeries\IntervalBarSeries.cs" />
 108.197 +    <Compile Include="Series\BarSeries\TornadoBarItem.cs" />
 108.198 +    <Compile Include="Series\BarSeries\TornadoBarSeries.cs" />
 108.199 +    <Compile Include="Series\ItemsSeries.cs" />
 108.200 +    <Compile Include="Series\DataPointSeries.cs" />
 108.201 +    <Compile Include="Series\HighLowItem.cs" />
 108.202 +    <Compile Include="Series\HighLowSeries.cs" />
 108.203 +    <Compile Include="Series\ScatterPoint.cs" />
 108.204 +    <Compile Include="Series\Series.cs" />
 108.205 +    <Compile Include="Series\StemSeries.cs" />
 108.206 +    <Compile Include="Series\StairStepSeries.cs" />
 108.207 +    <Compile Include="Series\ITrackableSeries.cs" />
 108.208 +    <Compile Include="Series\ScatterSeries.cs" />
 108.209 +    <Compile Include="Series\TwoColorLineSeries.cs" />
 108.210 +    <Compile Include="Series\XYAxisSeries.cs" />
 108.211 +    <Compile Include="Series\PieSeries.cs" />
 108.212 +    <Compile Include="Series\FunctionSeries.cs" />
 108.213 +    <Compile Include="Series\PieSlice.cs" />
 108.214 +    <Compile Include="Svg\SvgRenderContext.cs" />
 108.215 +    <Compile Include="Svg\SvgWriter.cs" />
 108.216 +    <Compile Include="Foundation\OxyColor.cs" />
 108.217 +    <Compile Include="Foundation\OxyColors.cs" />
 108.218 +    <Compile Include="Series\LineSeries.cs" />
 108.219 +    <Compile Include="Foundation\LineStyle.cs" />
 108.220 +    <Compile Include="Axes\LogarithmicAxis.cs" />
 108.221 +    <Compile Include="Foundation\MarkerType.cs" />
 108.222 +    <Compile Include="PlotModel\PlotModel.cs" />
 108.223 +    <Compile Include="Properties\AssemblyInfo.cs" />
 108.224 +    <Compile Include="Foundation\XmlWriterBase.cs" />
 108.225 +  </ItemGroup>
 108.226 +  <ItemGroup>
 108.227 +    <None Include="ClassDiagrams\Series.cd" />
 108.228 +    <None Include="ClassDiagrams\PlotModel.cd" />
 108.229 +    <None Include="ClassDiagrams\Reporting.cd" />
 108.230 +    <None Include="OxyPlot.snk" />
 108.231 +  </ItemGroup>
 108.232 +  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 108.233 +  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
 108.234 +       Other similar extension points exist, see Microsoft.Common.targets.
 108.235 +  <Target Name="BeforeBuild">
 108.236 +  </Target>
 108.237 +  <Target Name="AfterBuild">
 108.238 +  </Target>
 108.239 +  -->
 108.240 +</Project>
 108.241 \ No newline at end of file
   109.1 Binary file External/OxyPlot/OxyPlot/OxyPlot.snk has changed
   110.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/HitTestResult.cs	Sat Jun 08 16:53:22 2013 +0000
   110.3 @@ -0,0 +1,79 @@
   110.4 +// --------------------------------------------------------------------------------------------------------------------
   110.5 +// <copyright file="HitTestResult.cs" company="OxyPlot">
   110.6 +//   The MIT License (MIT)
   110.7 +//
   110.8 +//   Copyright (c) 2012 Oystein Bjorke
   110.9 +//
  110.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  110.11 +//   copy of this software and associated documentation files (the
  110.12 +//   "Software"), to deal in the Software without restriction, including
  110.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  110.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  110.15 +//   permit persons to whom the Software is furnished to do so, subject to
  110.16 +//   the following conditions:
  110.17 +//
  110.18 +//   The above copyright notice and this permission notice shall be included
  110.19 +//   in all copies or substantial portions of the Software.
  110.20 +//
  110.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  110.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  110.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  110.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  110.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  110.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  110.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  110.28 +// </copyright>
  110.29 +// <summary>
  110.30 +//   Represents a hit test result.
  110.31 +// </summary>
  110.32 +// --------------------------------------------------------------------------------------------------------------------
  110.33 +namespace OxyPlot
  110.34 +{
  110.35 +    /// <summary>
  110.36 +    /// Represents a hit test result.
  110.37 +    /// </summary>
  110.38 +    public class HitTestResult
  110.39 +    {
  110.40 +        /// <summary>
  110.41 +        /// Initializes a new instance of the <see cref="HitTestResult"/> class.
  110.42 +        /// </summary>
  110.43 +        public HitTestResult()
  110.44 +        {
  110.45 +        }
  110.46 +
  110.47 +        /// <summary>
  110.48 +        /// Initializes a new instance of the <see cref="HitTestResult"/> class.
  110.49 +        /// </summary>
  110.50 +        /// <param name="nhp">The nearest hit point.</param>
  110.51 +        /// <param name="item">The item.</param>
  110.52 +        /// <param name="index">The index.</param>
  110.53 +        public HitTestResult(ScreenPoint nhp, object item = null, double index = 0)
  110.54 +        {
  110.55 +            this.NearestHitPoint = nhp;
  110.56 +            this.Item = item;
  110.57 +            this.Index = index;
  110.58 +        }
  110.59 +
  110.60 +        /// <summary>
  110.61 +        /// Gets or sets the index of the hit (if available).
  110.62 +        /// </summary>
  110.63 +        /// <value> The index. </value>
  110.64 +        /// <remarks>
  110.65 +        /// If the hit was in the middle between point 1 and 2, index = 1.5.
  110.66 +        /// </remarks>
  110.67 +        public double Index { get; set; }
  110.68 +
  110.69 +        /// <summary>
  110.70 +        /// Gets or sets the item of the hit.
  110.71 +        /// </summary>
  110.72 +        /// <value> The item. </value>
  110.73 +        public object Item { get; set; }
  110.74 +
  110.75 +        /// <summary>
  110.76 +        /// Gets or sets the position of the nearest hit point.
  110.77 +        /// </summary>
  110.78 +        /// <value> The nearest hit point. </value>
  110.79 +        public ScreenPoint NearestHitPoint { get; set; }
  110.80 +
  110.81 +    }
  110.82 +}
  110.83 \ No newline at end of file
   111.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/OxyMouseButton.cs	Sat Jun 08 16:53:22 2013 +0000
   111.3 @@ -0,0 +1,67 @@
   111.4 +// --------------------------------------------------------------------------------------------------------------------
   111.5 +// <copyright file="OxyMouseButton.cs" company="OxyPlot">
   111.6 +//   The MIT License (MIT)
   111.7 +//
   111.8 +//   Copyright (c) 2012 Oystein Bjorke
   111.9 +//
  111.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  111.11 +//   copy of this software and associated documentation files (the
  111.12 +//   "Software"), to deal in the Software without restriction, including
  111.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  111.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  111.15 +//   permit persons to whom the Software is furnished to do so, subject to
  111.16 +//   the following conditions:
  111.17 +//
  111.18 +//   The above copyright notice and this permission notice shall be included
  111.19 +//   in all copies or substantial portions of the Software.
  111.20 +//
  111.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  111.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  111.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  111.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  111.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  111.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  111.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  111.28 +// </copyright>
  111.29 +// <summary>
  111.30 +//   The mouse buttons.
  111.31 +// </summary>
  111.32 +// --------------------------------------------------------------------------------------------------------------------
  111.33 +namespace OxyPlot
  111.34 +{
  111.35 +    /// <summary>
  111.36 +    /// Specifies constants that define which mouse button was pressed.
  111.37 +    /// </summary>
  111.38 +    public enum OxyMouseButton
  111.39 +    {
  111.40 +        /// <summary>
  111.41 +        /// No mouse button.
  111.42 +        /// </summary>
  111.43 +        None = 0,
  111.44 +
  111.45 +        /// <summary>
  111.46 +        /// The left mouse button.
  111.47 +        /// </summary>
  111.48 +        Left = 1,
  111.49 +
  111.50 +        /// <summary>
  111.51 +        /// The middle mouse button.
  111.52 +        /// </summary>
  111.53 +        Middle = 2,
  111.54 +
  111.55 +        /// <summary>
  111.56 +        /// The right mouse button.
  111.57 +        /// </summary>
  111.58 +        Right = 3,
  111.59 +
  111.60 +        /// <summary>
  111.61 +        /// The first extended mouse button.
  111.62 +        /// </summary>
  111.63 +        XButton1 = 4,
  111.64 +
  111.65 +        /// <summary>
  111.66 +        /// The second extended mouse button.
  111.67 +        /// </summary>
  111.68 +        XButton2 = 5,
  111.69 +    }
  111.70 +}
  111.71 \ No newline at end of file
   112.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/OxyMouseEventArgs.cs	Sat Jun 08 16:53:22 2013 +0000
   112.3 @@ -0,0 +1,87 @@
   112.4 +// --------------------------------------------------------------------------------------------------------------------
   112.5 +// <copyright file="OxyMouseEventArgs.cs" company="OxyPlot">
   112.6 +//   The MIT License (MIT)
   112.7 +//
   112.8 +//   Copyright (c) 2012 Oystein Bjorke
   112.9 +//
  112.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  112.11 +//   copy of this software and associated documentation files (the
  112.12 +//   "Software"), to deal in the Software without restriction, including
  112.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  112.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  112.15 +//   permit persons to whom the Software is furnished to do so, subject to
  112.16 +//   the following conditions:
  112.17 +//
  112.18 +//   The above copyright notice and this permission notice shall be included
  112.19 +//   in all copies or substantial portions of the Software.
  112.20 +//
  112.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  112.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  112.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  112.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  112.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  112.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  112.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  112.28 +// </copyright>
  112.29 +// <summary>
  112.30 +//   Represents event arguments for 3D mouse events events.
  112.31 +// </summary>
  112.32 +// --------------------------------------------------------------------------------------------------------------------
  112.33 +namespace OxyPlot
  112.34 +{
  112.35 +    using System;
  112.36 +
  112.37 +    /// <summary>
  112.38 +    /// Provides data for the mouse events.
  112.39 +    /// </summary>
  112.40 +    public class OxyMouseEventArgs : EventArgs
  112.41 +    {
  112.42 +        /// <summary>
  112.43 +        /// Gets or sets the mouse button that has changed.
  112.44 +        /// </summary>
  112.45 +        public OxyMouseButton ChangedButton { get; set; }
  112.46 +
  112.47 +        /// <summary>
  112.48 +        /// Gets or sets the click count.
  112.49 +        /// </summary>
  112.50 +        /// <value> The click count. </value>
  112.51 +        public int ClickCount { get; set; }
  112.52 +
  112.53 +        /// <summary>
  112.54 +        /// Gets or sets a value indicating whether Handled.
  112.55 +        /// </summary>
  112.56 +        public bool Handled { get; set; }
  112.57 +
  112.58 +        /// <summary>
  112.59 +        /// Gets or sets a value indicating whether the alt key was pressed when the event was raised.
  112.60 +        /// </summary>
  112.61 +        public bool IsAltDown { get; set; }
  112.62 +
  112.63 +        /// <summary>
  112.64 +        /// Gets or sets a value indicating whether the control key was pressed when the event was raised.
  112.65 +        /// </summary>
  112.66 +        public bool IsControlDown { get; set; }
  112.67 +
  112.68 +        /// <summary>
  112.69 +        /// Gets or sets a value indicating whether the shift key was pressed when the event was raised.
  112.70 +        /// </summary>
  112.71 +        public bool IsShiftDown { get; set; }
  112.72 +
  112.73 +        /// <summary>
  112.74 +        /// Gets or sets the hit test result.
  112.75 +        /// </summary>
  112.76 +        public HitTestResult HitTestResult { get; set; }
  112.77 +
  112.78 +        /// <summary>
  112.79 +        /// Gets or sets the plot control.
  112.80 +        /// </summary>
  112.81 +        /// <value> The plot control. </value>
  112.82 +        public IPlotControl PlotControl { get; set; }
  112.83 +
  112.84 +        /// <summary>
  112.85 +        /// Gets or sets the position.
  112.86 +        /// </summary>
  112.87 +        public ScreenPoint Position { get; set; }
  112.88 +
  112.89 +    }
  112.90 +}
  112.91 \ No newline at end of file
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/PlotElement.cs	Sat Jun 08 16:53:22 2013 +0000
   113.3 @@ -0,0 +1,142 @@
   113.4 +// --------------------------------------------------------------------------------------------------------------------
   113.5 +// <copyright file="PlotElement.cs" company="OxyPlot">
   113.6 +//   The MIT License (MIT)
   113.7 +//
   113.8 +//   Copyright (c) 2012 Oystein Bjorke
   113.9 +//
  113.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  113.11 +//   copy of this software and associated documentation files (the
  113.12 +//   "Software"), to deal in the Software without restriction, including
  113.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  113.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  113.15 +//   permit persons to whom the Software is furnished to do so, subject to
  113.16 +//   the following conditions:
  113.17 +//
  113.18 +//   The above copyright notice and this permission notice shall be included
  113.19 +//   in all copies or substantial portions of the Software.
  113.20 +//
  113.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  113.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  113.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  113.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  113.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  113.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  113.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  113.28 +// </copyright>
  113.29 +// <summary>
  113.30 +//   Abstract base class for all plottable elements (Axes, Annotations, Series).
  113.31 +// </summary>
  113.32 +// --------------------------------------------------------------------------------------------------------------------
  113.33 +namespace OxyPlot
  113.34 +{
  113.35 +    using System;
  113.36 +
  113.37 +    /// <summary>
  113.38 +    /// Provides an abstract base class for elements contained in a <see cref="PlotModel"/>.
  113.39 +    /// </summary>
  113.40 +    public abstract class PlotElement
  113.41 +    {
  113.42 +        /// <summary>
  113.43 +        /// Initializes a new instance of the <see cref="PlotElement"/> class.
  113.44 +        /// </summary>
  113.45 +        protected PlotElement()
  113.46 +        {
  113.47 +            this.Font = null;
  113.48 +            this.FontSize = double.NaN;
  113.49 +            this.FontWeight = FontWeights.Normal;
  113.50 +        }
  113.51 +
  113.52 +        /// <summary>
  113.53 +        /// Gets or sets the font.
  113.54 +        /// </summary>
  113.55 +        /// <value> The font. </value>
  113.56 +        /// <remarks>
  113.57 +        /// If the value is null, the parent PlotModel's DefaultFont will be used.
  113.58 +        /// </remarks>
  113.59 +        public string Font { get; set; }
  113.60 +
  113.61 +        /// <summary>
  113.62 +        /// Gets or sets the size of the font.
  113.63 +        /// </summary>
  113.64 +        /// <value> The size of the font. </value>
  113.65 +        /// <remarks>
  113.66 +        /// If the value is NaN, the parent PlotModel's DefaultFontSize will be used.
  113.67 +        /// </remarks>
  113.68 +        public double FontSize { get; set; }
  113.69 +
  113.70 +        /// <summary>
  113.71 +        /// Gets or sets the font weight.
  113.72 +        /// </summary>
  113.73 +        /// <value> The font weight. </value>
  113.74 +        public double FontWeight { get; set; }
  113.75 +
  113.76 +        /// <summary>
  113.77 +        /// Gets the parent plot model.
  113.78 +        /// </summary>
  113.79 +        public PlotModel PlotModel { get; internal set; }
  113.80 +
  113.81 +        /// <summary>
  113.82 +        /// Gets or sets an arbitrary object value that can be used to store custom information about this plot element.
  113.83 +        /// </summary>
  113.84 +        /// <value> The intended value. This property has no default value. </value>
  113.85 +        /// <remarks>
  113.86 +        /// 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.
  113.87 +        /// </remarks>
  113.88 +        public object Tag { get; set; }
  113.89 +
  113.90 +        /// <summary>
  113.91 +        /// Gets or sets the color of the text.
  113.92 +        /// </summary>
  113.93 +        /// <value> The color of the text. </value>
  113.94 +        /// <remarks>
  113.95 +        /// If the value is null, the TextColor of the parent PlotModel will be used.
  113.96 +        /// </remarks>
  113.97 +        public OxyColor TextColor { get; set; }
  113.98 +
  113.99 +        /// <summary>
 113.100 +        /// Gets the actual font.
 113.101 +        /// </summary>
 113.102 +        protected internal string ActualFont
 113.103 +        {
 113.104 +            get
 113.105 +            {
 113.106 +                return this.Font ?? this.PlotModel.DefaultFont;
 113.107 +            }
 113.108 +        }
 113.109 +
 113.110 +        /// <summary>
 113.111 +        /// Gets the actual size of the font.
 113.112 +        /// </summary>
 113.113 +        /// <value> The actual size of the font. </value>
 113.114 +        protected internal double ActualFontSize
 113.115 +        {
 113.116 +            get
 113.117 +            {
 113.118 +                return !double.IsNaN(this.FontSize) ? this.FontSize : this.PlotModel.DefaultFontSize;
 113.119 +            }
 113.120 +        }
 113.121 +
 113.122 +        /// <summary>
 113.123 +        /// Gets the actual font weight.
 113.124 +        /// </summary>
 113.125 +        protected internal double ActualFontWeight
 113.126 +        {
 113.127 +            get
 113.128 +            {
 113.129 +                return this.FontWeight;
 113.130 +            }
 113.131 +        }
 113.132 +
 113.133 +        /// <summary>
 113.134 +        /// Gets the actual color of the text.
 113.135 +        /// </summary>
 113.136 +        /// <value> The actual color of the text. </value>
 113.137 +        protected internal OxyColor ActualTextColor
 113.138 +        {
 113.139 +            get
 113.140 +            {
 113.141 +                return this.TextColor ?? this.PlotModel.TextColor;
 113.142 +            }
 113.143 +        }
 113.144 +    }
 113.145 +}
 113.146 \ No newline at end of file
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.Legends.cs	Sat Jun 08 16:53:22 2013 +0000
   114.3 @@ -0,0 +1,507 @@
   114.4 +// --------------------------------------------------------------------------------------------------------------------
   114.5 +// <copyright file="PlotModel.Legends.cs" company="OxyPlot">
   114.6 +//   The MIT License (MIT)
   114.7 +//
   114.8 +//   Copyright (c) 2012 Oystein Bjorke
   114.9 +//
  114.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  114.11 +//   copy of this software and associated documentation files (the
  114.12 +//   "Software"), to deal in the Software without restriction, including
  114.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  114.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  114.15 +//   permit persons to whom the Software is furnished to do so, subject to
  114.16 +//   the following conditions:
  114.17 +//
  114.18 +//   The above copyright notice and this permission notice shall be included
  114.19 +//   in all copies or substantial portions of the Software.
  114.20 +//
  114.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  114.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  114.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  114.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  114.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  114.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  114.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  114.28 +// </copyright>
  114.29 +// <summary>
  114.30 +//   Partial PlotModel class - this file contains methods related to the series legends.
  114.31 +// </summary>
  114.32 +// --------------------------------------------------------------------------------------------------------------------
  114.33 +namespace OxyPlot
  114.34 +{
  114.35 +    using System;
  114.36 +    using System.Collections.Generic;
  114.37 +    using System.Linq;
  114.38 +
  114.39 +    using OxyPlot.Series;
  114.40 +
  114.41 +    public partial class PlotModel
  114.42 +    {
  114.43 +        /// <summary>
  114.44 +        /// Makes the LegendOrientation property safe.
  114.45 +        /// </summary>
  114.46 +        /// <remarks>
  114.47 +        /// If Legend is positioned left or right, force it to vertical orientation
  114.48 +        /// </remarks>
  114.49 +        private void EnsureLegendProperties()
  114.50 +        {
  114.51 +            switch (this.LegendPosition)
  114.52 +            {
  114.53 +                case LegendPosition.LeftTop:
  114.54 +                case LegendPosition.LeftMiddle:
  114.55 +                case LegendPosition.LeftBottom:
  114.56 +                case LegendPosition.RightTop:
  114.57 +                case LegendPosition.RightMiddle:
  114.58 +                case LegendPosition.RightBottom:
  114.59 +                    if (this.LegendOrientation == LegendOrientation.Horizontal)
  114.60 +                    {
  114.61 +                        this.LegendOrientation = LegendOrientation.Vertical;
  114.62 +                    }
  114.63 +
  114.64 +                    break;
  114.65 +            }
  114.66 +        }
  114.67 +
  114.68 +        /// <summary>
  114.69 +        /// Gets the rectangle of the legend box.
  114.70 +        /// </summary>
  114.71 +        /// <param name="legendSize">Size of the legend box.</param>
  114.72 +        /// <returns>A rectangle.</returns>
  114.73 +        private OxyRect GetLegendRectangle(OxySize legendSize)
  114.74 +        {
  114.75 +            double top = 0;
  114.76 +            double left = 0;
  114.77 +            if (this.LegendPlacement == LegendPlacement.Outside)
  114.78 +            {
  114.79 +                switch (this.LegendPosition)
  114.80 +                {
  114.81 +                    case LegendPosition.LeftTop:
  114.82 +                    case LegendPosition.LeftMiddle:
  114.83 +                    case LegendPosition.LeftBottom:
  114.84 +                        left = this.PlotAndAxisArea.Left - legendSize.Width - this.LegendMargin;
  114.85 +                        break;
  114.86 +                    case LegendPosition.RightTop:
  114.87 +                    case LegendPosition.RightMiddle:
  114.88 +                    case LegendPosition.RightBottom:
  114.89 +                        left = this.PlotAndAxisArea.Right + this.LegendMargin;
  114.90 +                        break;
  114.91 +                    case LegendPosition.TopLeft:
  114.92 +                    case LegendPosition.TopCenter:
  114.93 +                    case LegendPosition.TopRight:
  114.94 +                        top = this.PlotAndAxisArea.Top - legendSize.Height - this.LegendMargin;
  114.95 +                        break;
  114.96 +                    case LegendPosition.BottomLeft:
  114.97 +                    case LegendPosition.BottomCenter:
  114.98 +                    case LegendPosition.BottomRight:
  114.99 +                        top = this.PlotAndAxisArea.Bottom + this.LegendMargin;
 114.100 +                        break;
 114.101 +                }
 114.102 +
 114.103 +                switch (this.LegendPosition)
 114.104 +                {
 114.105 +                    case LegendPosition.TopLeft:
 114.106 +                    case LegendPosition.BottomLeft:
 114.107 +                        left = this.PlotArea.Left;
 114.108 +                        break;
 114.109 +                    case LegendPosition.TopRight:
 114.110 +                    case LegendPosition.BottomRight:
 114.111 +                        left = this.PlotArea.Right - legendSize.Width;
 114.112 +                        break;
 114.113 +                    case LegendPosition.LeftTop:
 114.114 +                    case LegendPosition.RightTop:
 114.115 +                        top = this.PlotArea.Top;
 114.116 +                        break;
 114.117 +                    case LegendPosition.LeftBottom:
 114.118 +                    case LegendPosition.RightBottom:
 114.119 +                        top = this.PlotArea.Bottom - legendSize.Height;
 114.120 +                        break;
 114.121 +                    case LegendPosition.LeftMiddle:
 114.122 +                    case LegendPosition.RightMiddle:
 114.123 +                        top = (this.PlotArea.Top + this.PlotArea.Bottom - legendSize.Height) * 0.5;
 114.124 +                        break;
 114.125 +                    case LegendPosition.TopCenter:
 114.126 +                    case LegendPosition.BottomCenter:
 114.127 +                        left = (this.PlotArea.Left + this.PlotArea.Right - legendSize.Width) * 0.5;
 114.128 +                        break;
 114.129 +                }
 114.130 +            }
 114.131 +            else
 114.132 +            {
 114.133 +                switch (this.LegendPosition)
 114.134 +                {
 114.135 +                    case LegendPosition.LeftTop:
 114.136 +                    case LegendPosition.LeftMiddle:
 114.137 +                    case LegendPosition.LeftBottom:
 114.138 +                        left = this.PlotArea.Left + this.LegendMargin;
 114.139 +                        break;
 114.140 +                    case LegendPosition.RightTop:
 114.141 +                    case LegendPosition.RightMiddle:
 114.142 +                    case LegendPosition.RightBottom:
 114.143 +                        left = this.PlotArea.Right - legendSize.Width - this.LegendMargin;
 114.144 +                        break;
 114.145 +                    case LegendPosition.TopLeft:
 114.146 +                    case LegendPosition.TopCenter:
 114.147 +                    case LegendPosition.TopRight:
 114.148 +                        top = this.PlotArea.Top + this.LegendMargin;
 114.149 +                        break;
 114.150 +                    case LegendPosition.BottomLeft:
 114.151 +                    case LegendPosition.BottomCenter:
 114.152 +                    case LegendPosition.BottomRight:
 114.153 +                        top = this.PlotArea.Bottom - legendSize.Height - this.LegendMargin;
 114.154 +                        break;
 114.155 +                }
 114.156 +
 114.157 +                switch (this.LegendPosition)
 114.158 +                {
 114.159 +                    case LegendPosition.TopLeft:
 114.160 +                    case LegendPosition.BottomLeft:
 114.161 +                        left = this.PlotArea.Left + this.LegendMargin;
 114.162 +                        break;
 114.163 +                    case LegendPosition.TopRight:
 114.164 +                    case LegendPosition.BottomRight:
 114.165 +                        left = this.PlotArea.Right - legendSize.Width - this.LegendMargin;
 114.166 +                        break;
 114.167 +                    case LegendPosition.LeftTop:
 114.168 +                    case LegendPosition.RightTop:
 114.169 +                        top = this.PlotArea.Top + this.LegendMargin;
 114.170 +                        break;
 114.171 +                    case LegendPosition.LeftBottom:
 114.172 +                    case LegendPosition.RightBottom:
 114.173 +                        top = this.PlotArea.Bottom - legendSize.Height - this.LegendMargin;
 114.174 +                        break;
 114.175 +
 114.176 +                    case LegendPosition.LeftMiddle:
 114.177 +                    case LegendPosition.RightMiddle:
 114.178 +                        top = (this.PlotArea.Top + this.PlotArea.Bottom - legendSize.Height) * 0.5;
 114.179 +                        break;
 114.180 +                    case LegendPosition.TopCenter:
 114.181 +                    case LegendPosition.BottomCenter:
 114.182 +                        left = (this.PlotArea.Left + this.PlotArea.Right - legendSize.Width) * 0.5;
 114.183 +                        break;
 114.184 +                }
 114.185 +            }
 114.186 +
 114.187 +            return new OxyRect(left, top, legendSize.Width, legendSize.Height);
 114.188 +        }
 114.189 +
 114.190 +        /// <summary>
 114.191 +        /// Renders the legend for the specified series.
 114.192 +        /// </summary>
 114.193 +        /// <param name="rc">
 114.194 +        /// The render context.
 114.195 +        /// </param>
 114.196 +        /// <param name="s">
 114.197 +        /// The series.
 114.198 +        /// </param>
 114.199 +        /// <param name="rect">
 114.200 +        /// The position and size of the legend.
 114.201 +        /// </param>
 114.202 +        private void RenderLegend(IRenderContext rc, Series.Series s, OxyRect rect)
 114.203 +        {
 114.204 +            double x = rect.Left;
 114.205 +            switch (this.LegendItemAlignment)
 114.206 +            {
 114.207 +                case HorizontalAlignment.Center:
 114.208 +                    x = (rect.Left + rect.Right) / 2;
 114.209 +                    if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
 114.210 +                    {
 114.211 +                        x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
 114.212 +                    }
 114.213 +                    else
 114.214 +                    {
 114.215 +                        x -= (this.LegendSymbolLength + this.LegendSymbolMargin) / 2;
 114.216 +                    }
 114.217 +
 114.218 +                    break;
 114.219 +                case HorizontalAlignment.Right:
 114.220 +                    x = rect.Right;
 114.221 +
 114.222 +                    // if (LegendSymbolPlacement == LegendSymbolPlacement.Right)
 114.223 +                    x -= this.LegendSymbolLength + this.LegendSymbolMargin;
 114.224 +                    break;
 114.225 +            }
 114.226 +
 114.227 +            if (this.LegendSymbolPlacement == LegendSymbolPlacement.Left)
 114.228 +            {
 114.229 +                x += this.LegendSymbolLength + this.LegendSymbolMargin;
 114.230 +            }
 114.231 +
 114.232 +            double y = rect.Top;
 114.233 +            var maxsize = new OxySize(Math.Max(rect.Right - x, 0), Math.Max(rect.Bottom - y, 0));
 114.234 +
 114.235 +            var textSize = rc.DrawMathText(
 114.236 +                new ScreenPoint(x, y),
 114.237 +                s.Title,
 114.238 +                this.LegendTextColor ?? this.TextColor,
 114.239 +                this.LegendFont ?? this.DefaultFont,
 114.240 +                this.LegendFontSize,
 114.241 +                this.LegendFontWeight,
 114.242 +                0,
 114.243 +                this.LegendItemAlignment,
 114.244 +                VerticalAlignment.Top,
 114.245 +                maxsize,
 114.246 +                true);
 114.247 +            double x0 = x;
 114.248 +            switch (this.LegendItemAlignment)
 114.249 +            {
 114.250 +                case HorizontalAlignment.Center:
 114.251 +                    x0 = x - (textSize.Width * 0.5);
 114.252 +                    break;
 114.253 +                case HorizontalAlignment.Right:
 114.254 +                    x0 = x - textSize.Width;
 114.255 +                    break;
 114.256 +            }
 114.257 +
 114.258 +            var symbolRect =
 114.259 +                new OxyRect(
 114.260 +                    this.LegendSymbolPlacement == LegendSymbolPlacement.Right
 114.261 +                        ? x0 + textSize.Width + this.LegendSymbolMargin
 114.262 +                        : x0 - this.LegendSymbolMargin - this.LegendSymbolLength,
 114.263 +                    rect.Top,
 114.264 +                    this.LegendSymbolLength,
 114.265 +                    textSize.Height);
 114.266 +
 114.267 +            s.RenderLegend(rc, symbolRect);
 114.268 +        }
 114.269 +
 114.270 +        /// <summary>
 114.271 +        /// Measures the legends.
 114.272 +        /// </summary>
 114.273 +        /// <param name="rc">
 114.274 +        /// The render context.
 114.275 +        /// </param>
 114.276 +        /// <param name="availableSize">
 114.277 +        /// The available size for the legend box.
 114.278 +        /// </param>
 114.279 +        /// <returns>
 114.280 +        /// The size of the legend box.
 114.281 +        /// </returns>
 114.282 +        private OxySize MeasureLegends(IRenderContext rc, OxySize availableSize)
 114.283 +        {
 114.284 +            return this.RenderOrMeasureLegends(rc, new OxyRect(0, 0, availableSize.Width, availableSize.Height), true);
 114.285 +        }
 114.286 +
 114.287 +        /// <summary>
 114.288 +        /// Renders or measures the legends.
 114.289 +        /// </summary>
 114.290 +        /// <param name="rc">
 114.291 +        /// The render context.
 114.292 +        /// </param>
 114.293 +        /// <param name="rect">
 114.294 +        /// The rectangle.
 114.295 +        /// </param>
 114.296 +        private void RenderLegends(IRenderContext rc, OxyRect rect)
 114.297 +        {
 114.298 +            this.RenderOrMeasureLegends(rc, rect);
 114.299 +        }
 114.300 +
 114.301 +        /// <summary>
 114.302 +        /// Renders or measures the legends.
 114.303 +        /// </summary>
 114.304 +        /// <param name="rc">
 114.305 +        /// The render context.
 114.306 +        /// </param>
 114.307 +        /// <param name="rect">
 114.308 +        /// Provides the available size if measuring, otherwise it provides the position and size of the legend.
 114.309 +        /// </param>
 114.310 +        /// <param name="measureOnly">
 114.311 +        /// Specify if the size of the legend box should be measured only (not rendered).
 114.312 +        /// </param>
 114.313 +        /// <returns>
 114.314 +        /// The size of the legend box.
 114.315 +        /// </returns>
 114.316 +        private OxySize RenderOrMeasureLegends(IRenderContext rc, OxyRect rect, bool measureOnly = false)
 114.317 +        {
 114.318 +            // Render background and border around legend
 114.319 +            if (!measureOnly && rect.Width > 0 && rect.Height > 0)
 114.320 +            {
 114.321 +                rc.DrawRectangleAsPolygon(rect, this.LegendBackground, this.LegendBorder, this.LegendBorderThickness);
 114.322 +            }
 114.323 +
 114.324 +            double availableWidth = rect.Width;
 114.325 +            double availableHeight = rect.Height;
 114.326 +
 114.327 +            double x = this.LegendPadding;
 114.328 +            double top = this.LegendPadding;
 114.329 +
 114.330 +            var size = new OxySize();
 114.331 +
 114.332 +            // Render/measure the legend title
 114.333 +            if (!string.IsNullOrEmpty(this.LegendTitle))
 114.334 +            {
 114.335 +                OxySize titleSize;
 114.336 +                if (measureOnly)
 114.337 +                {
 114.338 +                    titleSize = rc.MeasureMathText(
 114.339 +                        this.LegendTitle,
 114.340 +                        this.LegendTitleFont ?? DefaultFont,
 114.341 +                        this.LegendTitleFontSize,
 114.342 +                        this.LegendTitleFontWeight);
 114.343 +                }
 114.344 +                else
 114.345 +                {
 114.346 +                    titleSize = rc.DrawMathText(
 114.347 +                        new ScreenPoint(rect.Left + x, rect.Top + top),
 114.348 +                        this.LegendTitle,
 114.349 +                        this.LegendTitleColor ?? this.TextColor,
 114.350 +                        this.LegendTitleFont ?? this.DefaultFont,
 114.351 +                        this.LegendTitleFontSize,
 114.352 +                        this.LegendTitleFontWeight,
 114.353 +                        0,
 114.354 +                        HorizontalAlignment.Left,
 114.355 +                        VerticalAlignment.Top,
 114.356 +                        null,
 114.357 +                        true);
 114.358 +                }
 114.359 +
 114.360 +                top += titleSize.Height;
 114.361 +                size.Width = x + titleSize.Width + this.LegendPadding;
 114.362 +                size.Height = top + titleSize.Height;
 114.363 +            }
 114.364 +
 114.365 +            double y = top;
 114.366 +
 114.367 +            double lineHeight = 0;
 114.368 +
 114.369 +            // tolerance for floating-point number comparisons
 114.370 +            const double Epsilon = 1e-3;
 114.371 +
 114.372 +            // the maximum item with in the column being rendered (only used for vertical orientation)
 114.373 +            double maxItemWidth = 0;
 114.374 +
 114.375 +            var items = this.LegendItemOrder == LegendItemOrder.Reverse ? this.VisibleSeries.Reverse() : this.VisibleSeries;
 114.376 +
 114.377 +            // When orientation is vertical and alignment is center or right, the items cannot be rendered before
 114.378 +            // the max item width has been calculated. Render the items for each column, and at the end.
 114.379 +            var seriesToRender = new Dictionary<Series.Series, OxyRect>();
 114.380 +            Action renderItems = () =>
 114.381 +                {
 114.382 +                    foreach (var sr in seriesToRender)
 114.383 +                    {
 114.384 +                        var itemRect = sr.Value;
 114.385 +                        var itemSeries = sr.Key;
 114.386 +
 114.387 +                        double rwidth = itemRect.Width;
 114.388 +                        if (itemRect.Left + rwidth + this.LegendPadding > rect.Left + availableWidth)
 114.389 +                        {
 114.390 +                            rwidth = rect.Left + availableWidth - itemRect.Left - this.LegendPadding;
 114.391 +                        }
 114.392 +
 114.393 +                        double rheight = itemRect.Height;
 114.394 +                        if (rect.Top + rheight + this.LegendPadding > rect.Top + availableHeight)
 114.395 +                        {
 114.396 +                            rheight = rect.Top + availableHeight - rect.Top - this.LegendPadding;
 114.397 +                        }
 114.398 +
 114.399 +                        var r = new OxyRect(itemRect.Left, itemRect.Top, Math.Max(rwidth, 0), Math.Max(rheight, 0));
 114.400 +                        this.RenderLegend(rc, itemSeries, r);
 114.401 +                    }
 114.402 +
 114.403 +                    seriesToRender.Clear();
 114.404 +                };
 114.405 +
 114.406 +            foreach (var s in items)
 114.407 +            {
 114.408 +                // Skip series with empty title
 114.409 +                if (string.IsNullOrEmpty(s.Title))
 114.410 +                {
 114.411 +                    continue;
 114.412 +                }
 114.413 +
 114.414 +                var textSize = rc.MeasureMathText(s.Title, this.LegendFont ?? DefaultFont, this.LegendFontSize, this.LegendFontWeight);
 114.415 +                double itemWidth = this.LegendSymbolLength + this.LegendSymbolMargin + textSize.Width;
 114.416 +                double itemHeight = textSize.Height;
 114.417 +
 114.418 +                if (this.LegendOrientation == LegendOrientation.Horizontal)
 114.419 +                {
 114.420 +                    // Add spacing between items
 114.421 +                    if (x > this.LegendPadding)
 114.422 +                    {
 114.423 +                        x += this.LegendItemSpacing;
 114.424 +                    }
 114.425 +
 114.426 +                    // Check if the item is too large to fit within the available width
 114.427 +                    if (x + itemWidth > availableWidth - this.LegendPadding + Epsilon)
 114.428 +                    {
 114.429 +                        // new line
 114.430 +                        x = this.LegendPadding;
 114.431 +                        y += lineHeight;
 114.432 +                        lineHeight = 0;
 114.433 +                    }
 114.434 +
 114.435 +                    // Update the max size of the current line
 114.436 +                    lineHeight = Math.Max(lineHeight, textSize.Height);
 114.437 +
 114.438 +                    if (!measureOnly)
 114.439 +                    {
 114.440 +                        seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight));
 114.441 +                    }
 114.442 +
 114.443 +                    x += itemWidth;
 114.444 +
 114.445 +                    // Update the max width of the legend box
 114.446 +                    size.Width = Math.Max(size.Width, x);
 114.447 +
 114.448 +                    // Update the max height of the legend box
 114.449 +                    size.Height = Math.Max(size.Height, y + textSize.Height);
 114.450 +                }
 114.451 +                else
 114.452 +                {
 114.453 +                    if (y + itemHeight > availableHeight - this.LegendPadding + Epsilon)
 114.454 +                    {
 114.455 +                        renderItems();
 114.456 +
 114.457 +                        y = top;
 114.458 +                        x += maxItemWidth + this.LegendColumnSpacing;
 114.459 +                        maxItemWidth = 0;
 114.460 +                    }
 114.461 +
 114.462 +                    if (!measureOnly)
 114.463 +                    {
 114.464 +                        seriesToRender.Add(s, new OxyRect(rect.Left + x, rect.Top + y, itemWidth, itemHeight));
 114.465 +                    }
 114.466 +
 114.467 +                    y += itemHeight;
 114.468 +
 114.469 +                    // Update the max size of the items in the current column
 114.470 +                    maxItemWidth = Math.Max(maxItemWidth, itemWidth);
 114.471 +
 114.472 +                    // Update the max width of the legend box
 114.473 +                    size.Width = Math.Max(size.Width, x + itemWidth);
 114.474 +
 114.475 +                    // Update the max height of the legend box
 114.476 +                    size.Height = Math.Max(size.Height, y);
 114.477 +                }
 114.478 +            }
 114.479 +
 114.480 +            renderItems();
 114.481 +
 114.482 +            if (size.Width > 0)
 114.483 +            {
 114.484 +                size.Width += this.LegendPadding;
 114.485 +            }
 114.486 +
 114.487 +            if (size.Height > 0)
 114.488 +            {
 114.489 +                size.Height += this.LegendPadding;
 114.490 +            }
 114.491 +
 114.492 +            if (size.Width > availableWidth)
 114.493 +            {
 114.494 +                size.Width = availableWidth;
 114.495 +            }
 114.496 +
 114.497 +            if (size.Height > availableHeight)
 114.498 +            {
 114.499 +                size.Height = availableHeight;
 114.500 +            }
 114.501 +
 114.502 +            if (!double.IsNaN(LegendMaxWidth) && size.Width > this.LegendMaxWidth)
 114.503 +            {
 114.504 +                size.Width = this.LegendMaxWidth;
 114.505 +            }
 114.506 +
 114.507 +            return size;
 114.508 +        }
 114.509 +    }
 114.510 +}
 114.511 \ No newline at end of file
   115.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.MouseEvents.cs	Sat Jun 08 16:53:22 2013 +0000
   115.3 @@ -0,0 +1,202 @@
   115.4 +// --------------------------------------------------------------------------------------------------------------------
   115.5 +// <copyright file="PlotModel.MouseEvents.cs" company="OxyPlot">
   115.6 +//   The MIT License (MIT)
   115.7 +//
   115.8 +//   Copyright (c) 2012 Oystein Bjorke
   115.9 +//
  115.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  115.11 +//   copy of this software and associated documentation files (the
  115.12 +//   "Software"), to deal in the Software without restriction, including
  115.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  115.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  115.15 +//   permit persons to whom the Software is furnished to do so, subject to
  115.16 +//   the following conditions:
  115.17 +//
  115.18 +//   The above copyright notice and this permission notice shall be included
  115.19 +//   in all copies or substantial portions of the Software.
  115.20 +//
  115.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  115.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  115.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  115.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  115.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  115.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  115.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  115.28 +// </copyright>
  115.29 +// <summary>
  115.30 +//   Partial PlotModel class - this file contains mouse events and handlers.
  115.31 +// </summary>
  115.32 +// --------------------------------------------------------------------------------------------------------------------
  115.33 +namespace OxyPlot
  115.34 +{
  115.35 +    using System;
  115.36 +    using System.Linq;
  115.37 +
  115.38 +    public partial class PlotModel
  115.39 +    {
  115.40 +        /// <summary>
  115.41 +        /// The mouse hit tolerance.
  115.42 +        /// </summary>
  115.43 +        private const double MouseHitTolerance = 10;
  115.44 +
  115.45 +        /// <summary>
  115.46 +        /// The current mouse events element.
  115.47 +        /// </summary>
  115.48 +        private UIPlotElement currentMouseEventElement;
  115.49 +
  115.50 +        /// <summary>
  115.51 +        /// Occurs when a mouse button is pressed down on the model.
  115.52 +        /// </summary>
  115.53 +        public event EventHandler<OxyMouseEventArgs> MouseDown;
  115.54 +
  115.55 +        /// <summary>
  115.56 +        /// Occurs when the mouse is moved on the plot element (only occurs after MouseDown).
  115.57 +        /// </summary>
  115.58 +        public event EventHandler<OxyMouseEventArgs> MouseMove;
  115.59 +
  115.60 +        /// <summary>
  115.61 +        /// Occurs when the mouse button is released on the plot element.
  115.62 +        /// </summary>
  115.63 +        public event EventHandler<OxyMouseEventArgs> MouseUp;
  115.64 +
  115.65 +        /// <summary>
  115.66 +        /// Handles the mouse down event.
  115.67 +        /// </summary>
  115.68 +        /// <param name="sender">
  115.69 +        /// The sender.
  115.70 +        /// </param>
  115.71 +        /// <param name="e">
  115.72 +        /// The <see cref="OxyPlot.OxyMouseEventArgs"/> instance containing the event data.
  115.73 +        /// </param>
  115.74 +        public void HandleMouseDown(object sender, OxyMouseEventArgs e)
  115.75 +        {
  115.76 +            // Revert the order to handle the top-level elements first
  115.77 +            foreach (var element in this.GetElements().Reverse())
  115.78 +            {
  115.79 +                var uiElement = element as UIPlotElement;
  115.80 +                if (uiElement == null)
  115.81 +                {
  115.82 +                    continue;
  115.83 +                }
  115.84 +
  115.85 +                var result = uiElement.HitTest(e.Position, MouseHitTolerance);
  115.86 +                if (result != null)
  115.87 +                {
  115.88 +                    e.HitTestResult = result;
  115.89 +                    uiElement.OnMouseDown(sender, e);
  115.90 +                    if (e.Handled)
  115.91 +                    {
  115.92 +                        this.currentMouseEventElement = uiElement;
  115.93 +                    }
  115.94 +                }
  115.95 +
  115.96 +                if (e.Handled)
  115.97 +                {
  115.98 +                    break;
  115.99 +                }
 115.100 +            }
 115.101 +
 115.102 +            if (!e.Handled)
 115.103 +            {
 115.104 +                this.OnMouseDown(sender, e);
 115.105 +            }
 115.106 +        }
 115.107 +
 115.108 +        /// <summary>
 115.109 +        /// Handles the mouse move event.
 115.110 +        /// </summary>
 115.111 +        /// <param name="sender">
 115.112 +        /// The sender.
 115.113 +        /// </param>
 115.114 +        /// <param name="e">
 115.115 +        /// The <see cref="OxyPlot.OxyMouseEventArgs"/> instance containing the event data.
 115.116 +        /// </param>
 115.117 +        public void HandleMouseMove(object sender, OxyMouseEventArgs e)
 115.118 +        {
 115.119 +            if (this.currentMouseEventElement != null)
 115.120 +            {
 115.121 +                this.currentMouseEventElement.OnMouseMove(sender, e);
 115.122 +            }
 115.123 +
 115.124 +            if (!e.Handled)
 115.125 +            {
 115.126 +                this.OnMouseMove(sender, e);
 115.127 +            }
 115.128 +        }
 115.129 +
 115.130 +        /// <summary>
 115.131 +        /// Handles the mouse up event.
 115.132 +        /// </summary>
 115.133 +        /// <param name="sender">
 115.134 +        /// The sender.
 115.135 +        /// </param>
 115.136 +        /// <param name="e">
 115.137 +        /// The <see cref="OxyPlot.OxyMouseEventArgs"/> instance containing the event data.
 115.138 +        /// </param>
 115.139 +        public void HandleMouseUp(object sender, OxyMouseEventArgs e)
 115.140 +        {
 115.141 +            if (this.currentMouseEventElement != null)
 115.142 +            {
 115.143 +                this.currentMouseEventElement.OnMouseUp(sender, e);
 115.144 +                this.currentMouseEventElement = null;
 115.145 +            }
 115.146 +
 115.147 +            if (!e.Handled)
 115.148 +            {
 115.149 +                this.OnMouseUp(sender, e);
 115.150 +            }
 115.151 +        }
 115.152 +
 115.153 +        /// <summary>
 115.154 +        /// Raises the <see cref="MouseDown"/> event.
 115.155 +        /// </summary>
 115.156 +        /// <param name="sender">
 115.157 +        /// The sender.
 115.158 +        /// </param>
 115.159 +        /// <param name="e">
 115.160 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
 115.161 +        /// </param>
 115.162 +        protected virtual void OnMouseDown(object sender, OxyMouseEventArgs e)
 115.163 +        {
 115.164 +            if (this.MouseDown != null && !e.Handled)
 115.165 +            {
 115.166 +                this.MouseDown(sender, e);
 115.167 +            }
 115.168 +        }
 115.169 +
 115.170 +        /// <summary>
 115.171 +        /// Raises the <see cref="MouseMove"/> event.
 115.172 +        /// </summary>
 115.173 +        /// <param name="sender">
 115.174 +        /// The sender.
 115.175 +        /// </param>
 115.176 +        /// <param name="e">
 115.177 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
 115.178 +        /// </param>
 115.179 +        protected virtual void OnMouseMove(object sender, OxyMouseEventArgs e)
 115.180 +        {
 115.181 +            if (this.MouseMove != null)
 115.182 +            {
 115.183 +                this.MouseMove(sender, e);
 115.184 +            }
 115.185 +        }
 115.186 +
 115.187 +        /// <summary>
 115.188 +        /// Raises the <see cref="MouseUp"/> event.
 115.189 +        /// </summary>
 115.190 +        /// <param name="sender">
 115.191 +        /// The sender.
 115.192 +        /// </param>
 115.193 +        /// <param name="e">
 115.194 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
 115.195 +        /// </param>
 115.196 +        protected virtual void OnMouseUp(object sender, OxyMouseEventArgs e)
 115.197 +        {
 115.198 +            if (this.MouseUp != null)
 115.199 +            {
 115.200 +                this.MouseUp(sender, e);
 115.201 +            }
 115.202 +        }
 115.203 +
 115.204 +    }
 115.205 +}
 115.206 \ No newline at end of file
   116.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.Rendering.cs	Sat Jun 08 16:53:22 2013 +0000
   116.3 @@ -0,0 +1,481 @@
   116.4 +// --------------------------------------------------------------------------------------------------------------------
   116.5 +// <copyright file="PlotModel.Rendering.cs" company="OxyPlot">
   116.6 +//   The MIT License (MIT)
   116.7 +//
   116.8 +//   Copyright (c) 2012 Oystein Bjorke
   116.9 +//
  116.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  116.11 +//   copy of this software and associated documentation files (the
  116.12 +//   "Software"), to deal in the Software without restriction, including
  116.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  116.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  116.15 +//   permit persons to whom the Software is furnished to do so, subject to
  116.16 +//   the following conditions:
  116.17 +//
  116.18 +//   The above copyright notice and this permission notice shall be included
  116.19 +//   in all copies or substantial portions of the Software.
  116.20 +//
  116.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  116.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  116.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  116.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  116.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  116.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  116.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  116.28 +// </copyright>
  116.29 +// <summary>
  116.30 +//   Partial PlotModel class - this file contains rendering methods.
  116.31 +// </summary>
  116.32 +// --------------------------------------------------------------------------------------------------------------------
  116.33 +namespace OxyPlot
  116.34 +{
  116.35 +    using System;
  116.36 +    using System.Collections.Generic;
  116.37 +    using System.Linq;
  116.38 +
  116.39 +    using OxyPlot.Annotations;
  116.40 +    using OxyPlot.Axes;
  116.41 +    using OxyPlot.Series;
  116.42 +
  116.43 +    public partial class PlotModel
  116.44 +    {
  116.45 +        /// <summary>
  116.46 +        /// Renders the plot with the specified rendering context.
  116.47 +        /// </summary>
  116.48 +        /// <param name="rc">The rendering context.</param>
  116.49 +        /// <param name="width">The width.</param>
  116.50 +        /// <param name="height">The height.</param>
  116.51 +        public void Render(IRenderContext rc, double width, double height)
  116.52 +        {
  116.53 +            lock (this.syncRoot)
  116.54 +            {
  116.55 +                if (width <= 0 || height <= 0)
  116.56 +                {
  116.57 +                    return;
  116.58 +                }
  116.59 +                
  116.60 +                this.Width = width;
  116.61 +                this.Height = height;
  116.62 +
  116.63 +                this.ActualPlotMargins = this.PlotMargins;
  116.64 +                this.EnsureLegendProperties();
  116.65 +
  116.66 +                while (true)
  116.67 +                {
  116.68 +                    this.UpdatePlotArea(rc);
  116.69 +                    this.UpdateAxisTransforms();
  116.70 +                    this.UpdateIntervals();
  116.71 +                    if (!this.AutoAdjustPlotMargins)
  116.72 +                    {
  116.73 +                        break;
  116.74 +                    }
  116.75 +
  116.76 +                    if (!this.AdjustPlotMargins(rc))
  116.77 +                    {
  116.78 +                        break;
  116.79 +                    }
  116.80 +                }
  116.81 +
  116.82 +                if (this.PlotType == PlotType.Cartesian)
  116.83 +                {
  116.84 +                    this.EnforceCartesianTransforms();
  116.85 +                    this.UpdateIntervals();
  116.86 +                }
  116.87 +
  116.88 +                this.RenderBackgrounds(rc);
  116.89 +                this.RenderAnnotations(rc, AnnotationLayer.BelowAxes);
  116.90 +                this.RenderAxes(rc, AxisLayer.BelowSeries);
  116.91 +                this.RenderAnnotations(rc, AnnotationLayer.BelowSeries);
  116.92 +                this.RenderSeries(rc);
  116.93 +                this.RenderAnnotations(rc, AnnotationLayer.AboveSeries);
  116.94 +                this.RenderTitle(rc);
  116.95 +                this.RenderBox(rc);
  116.96 +                this.RenderAxes(rc, AxisLayer.AboveSeries);
  116.97 +
  116.98 +                if (this.IsLegendVisible)
  116.99 +                {
 116.100 +                    this.RenderLegends(rc, this.LegendArea);
 116.101 +                }
 116.102 +            }
 116.103 +        }
 116.104 +
 116.105 +        /// <summary>
 116.106 +        /// Calculates the maximum size of the specified axes.
 116.107 +        /// </summary>
 116.108 +        /// <param name="rc">
 116.109 +        /// The render context.
 116.110 +        /// </param>
 116.111 +        /// <param name="axesOfPositionTier">
 116.112 +        /// The axes of position tier.
 116.113 +        /// </param>
 116.114 +        /// <returns>
 116.115 +        /// The maximum size.
 116.116 +        /// </returns>
 116.117 +        private static double MaxSizeOfPositionTier(IRenderContext rc, IEnumerable<Axis> axesOfPositionTier)
 116.118 +        {
 116.119 +            double maxSizeOfPositionTier = 0;
 116.120 +            foreach (var axis in axesOfPositionTier)
 116.121 +            {
 116.122 +                OxySize size = axis.Measure(rc);
 116.123 +                if (axis.IsHorizontal())
 116.124 +                {
 116.125 +                    if (size.Height > maxSizeOfPositionTier)
 116.126 +                    {
 116.127 +                        maxSizeOfPositionTier = size.Height;
 116.128 +                    }
 116.129 +                }
 116.130 +                else
 116.131 +                {
 116.132 +                    if (size.Width > maxSizeOfPositionTier)
 116.133 +                    {
 116.134 +                        maxSizeOfPositionTier = size.Width;
 116.135 +                    }
 116.136 +                }
 116.137 +            }
 116.138 +
 116.139 +            return maxSizeOfPositionTier;
 116.140 +        }
 116.141 +
 116.142 +        /// <summary>
 116.143 +        /// Adjust the plot margins.
 116.144 +        /// </summary>
 116.145 +        /// <param name="rc">
 116.146 +        /// The render context.
 116.147 +        /// </param>
 116.148 +        /// <returns>
 116.149 +        /// The adjust plot margins.
 116.150 +        /// </returns>
 116.151 +        private bool AdjustPlotMargins(IRenderContext rc)
 116.152 +        {
 116.153 +            bool isAdjusted = false;
 116.154 +            var newPlotMargins = new Dictionary<AxisPosition, double>
 116.155 +                {
 116.156 +                    { AxisPosition.Left, this.ActualPlotMargins.Left },
 116.157 +                    { AxisPosition.Top, this.ActualPlotMargins.Top },
 116.158 +                    { AxisPosition.Right, this.ActualPlotMargins.Right },
 116.159 +                    { AxisPosition.Bottom, this.ActualPlotMargins.Bottom }
 116.160 +                };
 116.161 +
 116.162 +            for (var position = AxisPosition.Left; position <= AxisPosition.Bottom; position++)
 116.163 +            {
 116.164 +                double maxValueOfPositionTier = 0;
 116.165 +                var axesOfPosition = this.Axes.Where(a => a.Position == position).ToList();
 116.166 +                foreach (var positionTier in axesOfPosition.Select(a => a.PositionTier).Distinct().OrderBy(l => l))
 116.167 +                {
 116.168 +                    var axesOfPositionTier = axesOfPosition.Where(a => a.PositionTier == positionTier).ToList();
 116.169 +                    double maxSizeOfPositionTier = MaxSizeOfPositionTier(rc, axesOfPositionTier);
 116.170 +                    double minValueOfPositionTier = maxValueOfPositionTier;
 116.171 +
 116.172 +                    if (Math.Abs(maxValueOfPositionTier) > 1e-5)
 116.173 +                    {
 116.174 +                        maxValueOfPositionTier += this.AxisTierDistance;
 116.175 +                    }
 116.176 +
 116.177 +                    maxValueOfPositionTier += maxSizeOfPositionTier;
 116.178 +
 116.179 +                    foreach (Axis axis in axesOfPositionTier)
 116.180 +                    {
 116.181 +                        axis.PositionTierSize = maxSizeOfPositionTier;
 116.182 +                        axis.PositionTierMinShift = minValueOfPositionTier;
 116.183 +                        axis.PositionTierMaxShift = maxValueOfPositionTier;
 116.184 +                    }
 116.185 +                }
 116.186 +
 116.187 +                if (maxValueOfPositionTier > newPlotMargins[position])
 116.188 +                {
 116.189 +                    newPlotMargins[position] = maxValueOfPositionTier;
 116.190 +                    isAdjusted = true;
 116.191 +                }
 116.192 +            }
 116.193 +
 116.194 +            if (isAdjusted)
 116.195 +            {
 116.196 +                this.ActualPlotMargins = new OxyThickness(
 116.197 +                    newPlotMargins[AxisPosition.Left],
 116.198 +                    newPlotMargins[AxisPosition.Top],
 116.199 +                    newPlotMargins[AxisPosition.Right],
 116.200 +                    newPlotMargins[AxisPosition.Bottom]);
 116.201 +            }
 116.202 +
 116.203 +            return isAdjusted;
 116.204 +        }
 116.205 +
 116.206 +        /// <summary>
 116.207 +        /// Measures the size of the title and subtitle.
 116.208 +        /// </summary>
 116.209 +        /// <param name="rc">
 116.210 +        /// The rendering context.
 116.211 +        /// </param>
 116.212 +        /// <returns>
 116.213 +        /// Size of the titles.
 116.214 +        /// </returns>
 116.215 +        private OxySize MeasureTitles(IRenderContext rc)
 116.216 +        {
 116.217 +            OxySize size1 = rc.MeasureText(this.Title, this.ActualTitleFont, this.TitleFontSize, this.TitleFontWeight);
 116.218 +            OxySize size2 = rc.MeasureText(
 116.219 +                this.Subtitle, this.SubtitleFont ?? this.ActualSubtitleFont, this.SubtitleFontSize, this.SubtitleFontWeight);
 116.220 +            double height = size1.Height + size2.Height;
 116.221 +            double width = Math.Max(size1.Width, size2.Width);
 116.222 +            return new OxySize(width, height);
 116.223 +        }
 116.224 +
 116.225 +        /// <summary>
 116.226 +        /// Renders the annotations.
 116.227 +        /// </summary>
 116.228 +        /// <param name="rc">
 116.229 +        /// The render context.
 116.230 +        /// </param>
 116.231 +        /// <param name="layer">
 116.232 +        /// The layer.
 116.233 +        /// </param>
 116.234 +        private void RenderAnnotations(IRenderContext rc, AnnotationLayer layer)
 116.235 +        {
 116.236 +            foreach (var a in this.Annotations.Where(a => a.Layer == layer))
 116.237 +            {
 116.238 +                a.Render(rc, this);
 116.239 +            }
 116.240 +        }
 116.241 +
 116.242 +        /// <summary>
 116.243 +        /// Renders the axes.
 116.244 +        /// </summary>
 116.245 +        /// <param name="rc">
 116.246 +        /// The render context.
 116.247 +        /// </param>
 116.248 +        /// <param name="layer">
 116.249 +        /// The layer.
 116.250 +        /// </param>
 116.251 +        private void RenderAxes(IRenderContext rc, AxisLayer layer)
 116.252 +        {
 116.253 +            for (int i = 0; i < 2; i++)
 116.254 +            {
 116.255 +                foreach (var a in this.Axes)
 116.256 +                {
 116.257 +                    if (a.IsAxisVisible && a.Layer == layer)
 116.258 +                    {
 116.259 +                        a.Render(rc, this, layer, i);
 116.260 +                    }
 116.261 +                }
 116.262 +            }
 116.263 +        }
 116.264 +
 116.265 +        /// <summary>
 116.266 +        /// Renders the series backgrounds.
 116.267 +        /// </summary>
 116.268 +        /// <param name="rc">
 116.269 +        /// The render context.
 116.270 +        /// </param>
 116.271 +        private void RenderBackgrounds(IRenderContext rc)
 116.272 +        {
 116.273 +            // Render the main background of the plot area (only if there are axes)
 116.274 +            // The border is rendered by DrawRectangleAsPolygon to ensure that it is pixel aligned with the tick marks.
 116.275 +            if (this.Axes.Count > 0 && this.PlotAreaBackground != null)
 116.276 +            {
 116.277 +                rc.DrawRectangleAsPolygon(this.PlotArea, this.PlotAreaBackground, null, 0);
 116.278 +            }
 116.279 +
 116.280 +            foreach (var s in this.VisibleSeries)
 116.281 +            {
 116.282 +                var s2 = s as XYAxisSeries;
 116.283 +                if (s2 == null || s2.Background == null)
 116.284 +                {
 116.285 +                    continue;
 116.286 +                }
 116.287 +
 116.288 +                rc.DrawRectangle(s2.GetScreenRectangle(), s2.Background, null, 0);
 116.289 +            }
 116.290 +        }
 116.291 +
 116.292 +        /// <summary>
 116.293 +        /// Renders the border around the plot area.
 116.294 +        /// </summary>
 116.295 +        /// <remarks>
 116.296 +        /// The border will only by rendered if there are axes in the plot.
 116.297 +        /// </remarks>
 116.298 +        /// <param name="rc">
 116.299 +        /// The render context.
 116.300 +        /// </param>
 116.301 +        private void RenderBox(IRenderContext rc)
 116.302 +        {
 116.303 +            // The border is rendered by DrawBox to ensure that it is pixel aligned with the tick marks (cannot use DrawRectangle here).
 116.304 +            if (this.Axes.Count > 0)
 116.305 +            {
 116.306 +                rc.DrawRectangleAsPolygon(this.PlotArea, null, this.PlotAreaBorderColor, this.PlotAreaBorderThickness);
 116.307 +            }
 116.308 +        }
 116.309 +
 116.310 +        /// <summary>
 116.311 +        /// Renders the series.
 116.312 +        /// </summary>
 116.313 +        /// <param name="rc">
 116.314 +        /// The render context.
 116.315 +        /// </param>
 116.316 +        private void RenderSeries(IRenderContext rc)
 116.317 +        {
 116.318 +            // Update undefined colors
 116.319 +            this.ResetDefaultColor();
 116.320 +            foreach (var s in this.VisibleSeries)
 116.321 +            {
 116.322 +                s.SetDefaultValues(this);
 116.323 +            }
 116.324 +
 116.325 +            foreach (var s in this.VisibleSeries)
 116.326 +            {
 116.327 +                s.Render(rc, this);
 116.328 +            }
 116.329 +        }
 116.330 +
 116.331 +        /// <summary>
 116.332 +        /// Renders the title and subtitle.
 116.333 +        /// </summary>
 116.334 +        /// <param name="rc">
 116.335 +        /// The render context.
 116.336 +        /// </param>
 116.337 +        private void RenderTitle(IRenderContext rc)
 116.338 +        {
 116.339 +            OxySize size1 = rc.MeasureText(this.Title, this.ActualTitleFont, this.TitleFontSize, this.TitleFontWeight);
 116.340 +            rc.MeasureText(
 116.341 +                this.Subtitle, this.SubtitleFont ?? this.ActualSubtitleFont, this.SubtitleFontSize, this.SubtitleFontWeight);
 116.342 +
 116.343 +            // double height = size1.Height + size2.Height;
 116.344 +            // double dy = (TitleArea.Top+TitleArea.Bottom-height)*0.5;
 116.345 +            double dy = this.TitleArea.Top;
 116.346 +            double dx = (this.TitleArea.Left + this.TitleArea.Right) * 0.5;
 116.347 +
 116.348 +            if (!string.IsNullOrEmpty(this.Title))
 116.349 +            {
 116.350 +                rc.DrawMathText(
 116.351 +                    new ScreenPoint(dx, dy),
 116.352 +                    this.Title,
 116.353 +                    this.TitleColor ?? this.TextColor,
 116.354 +                    this.ActualTitleFont,
 116.355 +                    this.TitleFontSize,
 116.356 +                    this.TitleFontWeight,
 116.357 +                    0,
 116.358 +                    HorizontalAlignment.Center,
 116.359 +                    VerticalAlignment.Top);
 116.360 +                dy += size1.Height;
 116.361 +            }
 116.362 +
 116.363 +            if (!string.IsNullOrEmpty(this.Subtitle))
 116.364 +            {
 116.365 +                rc.DrawMathText(
 116.366 +                    new ScreenPoint(dx, dy),
 116.367 +                    this.Subtitle,
 116.368 +                    this.SubtitleColor ?? this.TextColor,
 116.369 +                    this.ActualSubtitleFont,
 116.370 +                    this.SubtitleFontSize,
 116.371 +                    this.SubtitleFontWeight,
 116.372 +                    0,
 116.373 +                    HorizontalAlignment.Center,
 116.374 +                    VerticalAlignment.Top);
 116.375 +            }
 116.376 +        }
 116.377 +
 116.378 +        /// <summary>
 116.379 +        /// Calculates the plot area (subtract padding, title size and outside legends)
 116.380 +        /// </summary>
 116.381 +        /// <param name="rc">
 116.382 +        /// The rendering context.
 116.383 +        /// </param>
 116.384 +        private void UpdatePlotArea(IRenderContext rc)
 116.385 +        {
 116.386 +            var plotArea = new OxyRect(
 116.387 +                this.Padding.Left,
 116.388 +                this.Padding.Top,
 116.389 +                this.Width - this.Padding.Left - this.Padding.Right,
 116.390 +                this.Height - this.Padding.Top - this.Padding.Bottom);
 116.391 +
 116.392 +            var titleSize = this.MeasureTitles(rc);
 116.393 +
 116.394 +            if (titleSize.Height > 0)
 116.395 +            {
 116.396 +                double titleHeight = titleSize.Height + this.TitlePadding;
 116.397 +                plotArea.Height -= titleHeight;
 116.398 +                plotArea.Top += titleHeight;
 116.399 +            }
 116.400 +
 116.401 +            plotArea.Top += this.ActualPlotMargins.Top;
 116.402 +            plotArea.Height -= this.ActualPlotMargins.Top;
 116.403 +
 116.404 +            plotArea.Height -= this.ActualPlotMargins.Bottom;
 116.405 +
 116.406 +            plotArea.Left += this.ActualPlotMargins.Left;
 116.407 +            plotArea.Width -= this.ActualPlotMargins.Left;
 116.408 +
 116.409 +            plotArea.Width -= this.ActualPlotMargins.Right;
 116.410 +
 116.411 +            // Find the available size for the legend box
 116.412 +            double availableLegendWidth = plotArea.Width;
 116.413 +            double availableLegendHeight = plotArea.Height;
 116.414 +            if (this.LegendPlacement == LegendPlacement.Inside)
 116.415 +            {
 116.416 +                availableLegendWidth -= this.LegendMargin * 2;
 116.417 +                availableLegendHeight -= this.LegendMargin * 2;
 116.418 +            }
 116.419 +
 116.420 +            if (availableLegendWidth < 0)
 116.421 +            {
 116.422 +                availableLegendWidth = 0;
 116.423 +            }
 116.424 +
 116.425 +            if (availableLegendHeight < 0)
 116.426 +            {
 116.427 +                availableLegendHeight = 0;
 116.428 +            }
 116.429 +
 116.430 +            // Calculate the size of the legend box
 116.431 +            var legendSize = this.MeasureLegends(rc, new OxySize(availableLegendWidth, availableLegendHeight));
 116.432 +
 116.433 +            // Adjust the plot area after the size of the legend box has been calculated
 116.434 +            if (this.IsLegendVisible && this.LegendPlacement == LegendPlacement.Outside)
 116.435 +            {
 116.436 +                switch (this.LegendPosition)
 116.437 +                {
 116.438 +                    case LegendPosition.LeftTop:
 116.439 +                    case LegendPosition.LeftMiddle:
 116.440 +                    case LegendPosition.LeftBottom:
 116.441 +                        plotArea.Left += legendSize.Width + this.LegendMargin;
 116.442 +                        plotArea.Width -= legendSize.Width + this.LegendMargin;
 116.443 +                        break;
 116.444 +                    case LegendPosition.RightTop:
 116.445 +                    case LegendPosition.RightMiddle:
 116.446 +                    case LegendPosition.RightBottom:
 116.447 +                        plotArea.Width -= legendSize.Width + this.LegendMargin;
 116.448 +                        break;
 116.449 +                    case LegendPosition.TopLeft:
 116.450 +                    case LegendPosition.TopCenter:
 116.451 +                    case LegendPosition.TopRight:
 116.452 +                        plotArea.Top += legendSize.Height + this.LegendMargin;
 116.453 +                        plotArea.Height -= legendSize.Height + this.LegendMargin;
 116.454 +                        break;
 116.455 +                    case LegendPosition.BottomLeft:
 116.456 +                    case LegendPosition.BottomCenter:
 116.457 +                    case LegendPosition.BottomRight:
 116.458 +                        plotArea.Height -= legendSize.Height + this.LegendMargin;
 116.459 +                        break;
 116.460 +                }
 116.461 +            }
 116.462 +
 116.463 +            // Ensure the plot area is valid
 116.464 +            if (plotArea.Height < 0)
 116.465 +            {
 116.466 +                plotArea.Bottom = plotArea.Top + 1;
 116.467 +            }
 116.468 +
 116.469 +            if (plotArea.Width < 0)
 116.470 +            {
 116.471 +                plotArea.Right = plotArea.Left + 1;
 116.472 +            }
 116.473 +
 116.474 +            this.PlotArea = plotArea;
 116.475 +            this.PlotAndAxisArea = new OxyRect(
 116.476 +                plotArea.Left - this.ActualPlotMargins.Left,
 116.477 +                plotArea.Top - this.ActualPlotMargins.Top,
 116.478 +                plotArea.Width + this.ActualPlotMargins.Left + this.ActualPlotMargins.Right,
 116.479 +                plotArea.Height + this.ActualPlotMargins.Top + this.ActualPlotMargins.Bottom);
 116.480 +            this.TitleArea = new OxyRect(this.PlotArea.Left, this.Padding.Top, this.PlotArea.Width, titleSize.Height + (this.TitlePadding * 2));
 116.481 +            this.LegendArea = this.GetLegendRectangle(legendSize);
 116.482 +        }
 116.483 +    }
 116.484 +}
 116.485 \ No newline at end of file
   117.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/PlotModel.cs	Sat Jun 08 16:53:22 2013 +0000
   117.3 @@ -0,0 +1,1485 @@
   117.4 +// --------------------------------------------------------------------------------------------------------------------
   117.5 +// <copyright file="PlotModel.cs" company="OxyPlot">
   117.6 +//   The MIT License (MIT)
   117.7 +//
   117.8 +//   Copyright (c) 2012 Oystein Bjorke
   117.9 +//
  117.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  117.11 +//   copy of this software and associated documentation files (the
  117.12 +//   "Software"), to deal in the Software without restriction, including
  117.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  117.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  117.15 +//   permit persons to whom the Software is furnished to do so, subject to
  117.16 +//   the following conditions:
  117.17 +//
  117.18 +//   The above copyright notice and this permission notice shall be included
  117.19 +//   in all copies or substantial portions of the Software.
  117.20 +//
  117.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  117.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  117.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  117.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  117.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  117.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  117.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  117.28 +// </copyright>
  117.29 +// <summary>
  117.30 +//   Plot coordinate system type
  117.31 +// </summary>
  117.32 +// --------------------------------------------------------------------------------------------------------------------
  117.33 +namespace OxyPlot
  117.34 +{
  117.35 +    using System;
  117.36 +    using System.Collections.Generic;
  117.37 +    using System.Collections.ObjectModel;
  117.38 +    using System.Diagnostics;
  117.39 +    using System.Globalization;
  117.40 +    using System.IO;
  117.41 +    using System.Linq;
  117.42 +    using System.Reflection;
  117.43 +
  117.44 +    using OxyPlot.Annotations;
  117.45 +    using OxyPlot.Axes;
  117.46 +    using OxyPlot.Reporting;
  117.47 +    using OxyPlot.Series;
  117.48 +
  117.49 +    /// <summary>
  117.50 +    /// Specifies the coordinate system type.
  117.51 +    /// </summary>
  117.52 +    public enum PlotType
  117.53 +    {
  117.54 +        /// <summary>
  117.55 +        /// XY coordinate system - two perpendicular axes
  117.56 +        /// </summary>
  117.57 +        XY,
  117.58 +
  117.59 +        /// <summary>
  117.60 +        /// Cartesian coordinate system - perpendicular axes with the same scaling.
  117.61 +        /// </summary>
  117.62 +        /// <remarks>
  117.63 +        /// See http://en.wikipedia.org/wiki/Cartesian_coordinate_system
  117.64 +        /// </remarks>
  117.65 +        Cartesian,
  117.66 +
  117.67 +        /// <summary>
  117.68 +        /// Polar coordinate system - with radial and angular axes 
  117.69 +        /// </summary>
  117.70 +        /// <remarks>
  117.71 +        /// See http://en.wikipedia.org/wiki/Polar_coordinate_system
  117.72 +        /// </remarks>
  117.73 +        Polar
  117.74 +    }
  117.75 +
  117.76 +    /// <summary>
  117.77 +    /// Specifies the placement of the legend box.
  117.78 +    /// </summary>
  117.79 +    public enum LegendPlacement
  117.80 +    {
  117.81 +        /// <summary>
  117.82 +        /// Place the legends inside the plot area.
  117.83 +        /// </summary>
  117.84 +        Inside,
  117.85 +
  117.86 +        /// <summary>
  117.87 +        /// Place the legends outside the plot area.
  117.88 +        /// </summary>
  117.89 +        Outside
  117.90 +    }
  117.91 +
  117.92 +    /// <summary>
  117.93 +    /// Specifies the position of the legend box.
  117.94 +    /// </summary>
  117.95 +    public enum LegendPosition
  117.96 +    {
  117.97 +        /// <summary>
  117.98 +        /// Place the legend box in the top-left corner.
  117.99 +        /// </summary>
 117.100 +        TopLeft,
 117.101 +
 117.102 +        /// <summary>
 117.103 +        /// Place the legend box centered at the top.
 117.104 +        /// </summary>
 117.105 +        TopCenter,
 117.106 +
 117.107 +        /// <summary>
 117.108 +        ///  Place the legend box in the top-right corner.
 117.109 +        /// </summary>
 117.110 +        TopRight,
 117.111 +
 117.112 +        /// <summary>
 117.113 +        ///  Place the legend box in the bottom-left corner.
 117.114 +        /// </summary>
 117.115 +        BottomLeft,
 117.116 +
 117.117 +        /// <summary>
 117.118 +        /// Place the legend box centered at the bottom.
 117.119 +        /// </summary>
 117.120 +        BottomCenter,
 117.121 +
 117.122 +        /// <summary>
 117.123 +        ///  Place the legend box in the bottom-right corner.
 117.124 +        /// </summary>
 117.125 +        BottomRight,
 117.126 +
 117.127 +        /// <summary>
 117.128 +        /// Place the legend box in the left-top corner.
 117.129 +        /// </summary>
 117.130 +        LeftTop,
 117.131 +
 117.132 +        /// <summary>
 117.133 +        /// Place the legend box centered at the left.
 117.134 +        /// </summary>
 117.135 +        LeftMiddle,
 117.136 +
 117.137 +        /// <summary>
 117.138 +        /// Place the legend box in the left-bottom corner.
 117.139 +        /// </summary>
 117.140 +        LeftBottom,
 117.141 +
 117.142 +        /// <summary>
 117.143 +        /// Place the legend box in the right-top corner.
 117.144 +        /// </summary>
 117.145 +        RightTop,
 117.146 +
 117.147 +        /// <summary>
 117.148 +        /// Place the legend box centered at the right.
 117.149 +        /// </summary>
 117.150 +        RightMiddle,
 117.151 +
 117.152 +        /// <summary>
 117.153 +        /// Place the legend box in the right-bottom corner.
 117.154 +        /// </summary>
 117.155 +        RightBottom
 117.156 +    }
 117.157 +
 117.158 +    /// <summary>
 117.159 +    /// Specifies the orientation of the items in the legend box.
 117.160 +    /// </summary>
 117.161 +    public enum LegendOrientation
 117.162 +    {
 117.163 +        /// <summary>
 117.164 +        /// Orient the items horizontally.
 117.165 +        /// </summary>
 117.166 +        Horizontal,
 117.167 +
 117.168 +        /// <summary>
 117.169 +        /// Orient the items vertically.
 117.170 +        /// </summary>
 117.171 +        Vertical
 117.172 +    }
 117.173 +
 117.174 +    /// <summary>
 117.175 +    /// Specifies the item order of the legends.
 117.176 +    /// </summary>
 117.177 +    public enum LegendItemOrder
 117.178 +    {
 117.179 +        /// <summary>
 117.180 +        /// Render the items in the normal order.
 117.181 +        /// </summary>
 117.182 +        Normal,
 117.183 +
 117.184 +        /// <summary>
 117.185 +        /// Render the items in the reverse order.
 117.186 +        /// </summary>
 117.187 +        Reverse
 117.188 +    }
 117.189 +
 117.190 +    /// <summary>
 117.191 +    /// Specifies the placement of the legend symbols.
 117.192 +    /// </summary>
 117.193 +    public enum LegendSymbolPlacement
 117.194 +    {
 117.195 +        /// <summary>
 117.196 +        /// Render symbols to the left of the labels.
 117.197 +        /// </summary>
 117.198 +        Left,
 117.199 +
 117.200 +        /// <summary>
 117.201 +        /// Render symbols to the right of the labels.
 117.202 +        /// </summary>
 117.203 +        Right
 117.204 +    }
 117.205 +
 117.206 +    /// <summary>
 117.207 +    /// Represents a plot (including axes, series and annotations).
 117.208 +    /// </summary>
 117.209 +    public partial class PlotModel
 117.210 +    {
 117.211 +        /// <summary>
 117.212 +        /// The default selection color.
 117.213 +        /// </summary>
 117.214 +        internal static readonly OxyColor DefaultSelectionColor = OxyColors.Yellow;
 117.215 +
 117.216 +        /// <summary>
 117.217 +        /// The default font.
 117.218 +        /// </summary>
 117.219 +        private const string PrivateDefaultFont = "Segoe UI";
 117.220 +
 117.221 +        /// <summary>
 117.222 +        /// The current color index.
 117.223 +        /// </summary>
 117.224 +        private int currentColorIndex;
 117.225 +
 117.226 +        /// <summary>
 117.227 +        /// Initializes a new instance of the <see cref="PlotModel" /> class.
 117.228 +        /// </summary>
 117.229 +        public PlotModel()
 117.230 +        {
 117.231 +            this.Axes = new Collection<Axis>();
 117.232 +            this.Series = new Collection<OxyPlot.Series.Series>();
 117.233 +            this.Annotations = new Collection<Annotation>();
 117.234 +
 117.235 +            this.PlotType = PlotType.XY;
 117.236 +
 117.237 +            this.PlotMargins = new OxyThickness(60, 4, 4, 40);
 117.238 +            this.Padding = new OxyThickness(8, 8, 16, 8);
 117.239 +            this.AutoAdjustPlotMargins = true;
 117.240 +
 117.241 +            this.DefaultFont = PrivateDefaultFont;
 117.242 +            this.DefaultFontSize = 12;
 117.243 +
 117.244 +            this.TitleFont = null;
 117.245 +            this.TitleFontSize = 18;
 117.246 +            this.TitleFontWeight = FontWeights.Bold;
 117.247 +            this.SubtitleFont = null;
 117.248 +            this.SubtitleFontSize = 14;
 117.249 +            this.SubtitleFontWeight = FontWeights.Normal;
 117.250 +            this.TitlePadding = 6;
 117.251 +
 117.252 +            this.TextColor = OxyColors.Black;
 117.253 +            this.PlotAreaBorderColor = OxyColors.Black;
 117.254 +            this.PlotAreaBorderThickness = 1;
 117.255 +
 117.256 +            this.IsLegendVisible = true;
 117.257 +            this.LegendTitleFont = null;
 117.258 +            this.LegendTitleFontSize = 12;
 117.259 +            this.LegendTitleFontWeight = FontWeights.Bold;
 117.260 +            this.LegendFont = null;
 117.261 +            this.LegendFontSize = 12;
 117.262 +            this.LegendFontWeight = FontWeights.Normal;
 117.263 +            this.LegendSymbolLength = 16;
 117.264 +            this.LegendSymbolMargin = 4;
 117.265 +            this.LegendPadding = 8;
 117.266 +            this.LegendColumnSpacing = 8;
 117.267 +            this.LegendItemSpacing = 24;
 117.268 +            this.LegendMargin = 8;
 117.269 +
 117.270 +            this.LegendBackground = null;
 117.271 +            this.LegendBorder = null;
 117.272 +            this.LegendBorderThickness = 1;
 117.273 +
 117.274 +            this.LegendMaxWidth = double.NaN;
 117.275 +            this.LegendPlacement = LegendPlacement.Inside;
 117.276 +            this.LegendPosition = LegendPosition.RightTop;
 117.277 +            this.LegendOrientation = LegendOrientation.Vertical;
 117.278 +            this.LegendItemOrder = LegendItemOrder.Normal;
 117.279 +            this.LegendItemAlignment = HorizontalAlignment.Left;
 117.280 +            this.LegendSymbolPlacement = LegendSymbolPlacement.Left;
 117.281 +
 117.282 +            this.DefaultColors = new List<OxyColor>
 117.283 +            {
 117.284 +                    OxyColor.FromRgb(0x4E, 0x9A, 0x06),
 117.285 +                    OxyColor.FromRgb(0xC8, 0x8D, 0x00),
 117.286 +                    OxyColor.FromRgb(0xCC, 0x00, 0x00),
 117.287 +                    OxyColor.FromRgb(0x20, 0x4A, 0x87),
 117.288 +                    OxyColors.Red,
 117.289 +                    OxyColors.Orange,
 117.290 +                    OxyColors.Yellow,
 117.291 +                    OxyColors.Green,
 117.292 +                    OxyColors.Blue,
 117.293 +                    OxyColors.Indigo,
 117.294 +                    OxyColors.Violet
 117.295 +                };
 117.296 +
 117.297 +            this.AxisTierDistance = 4.0;
 117.298 +        }
 117.299 +
 117.300 +        /// <summary>
 117.301 +        /// Initializes a new instance of the <see cref="PlotModel"/> class.
 117.302 +        /// </summary>
 117.303 +        /// <param name="title">
 117.304 +        /// The title.
 117.305 +        /// </param>
 117.306 +        /// <param name="subtitle">
 117.307 +        /// The subtitle.
 117.308 +        /// </param>
 117.309 +        public PlotModel(string title, string subtitle = null)
 117.310 +            : this()
 117.311 +        {
 117.312 +            this.Title = title;
 117.313 +            this.Subtitle = subtitle;
 117.314 +        }
 117.315 +
 117.316 +        /// <summary>
 117.317 +        /// The synchronization root object.
 117.318 +        /// </summary>
 117.319 +        private object syncRoot = new object();
 117.320 +
 117.321 +        /// <summary>
 117.322 +        /// Gets an object that can be used to synchronize access to the PlotModel.
 117.323 +        /// </summary>
 117.324 +        /// <value>The sync root.</value>
 117.325 +        public object SyncRoot { get { return this.syncRoot; } }
 117.326 +
 117.327 +        /// <summary>
 117.328 +        /// Occurs when the plot has been updated.
 117.329 +        /// </summary>
 117.330 +        public event EventHandler Updated;
 117.331 +
 117.332 +        /// <summary>
 117.333 +        /// Occurs when the plot is about to be updated.
 117.334 +        /// </summary>
 117.335 +        public event EventHandler Updating;
 117.336 +
 117.337 +        /// <summary>
 117.338 +        /// Gets or sets the default font.
 117.339 +        /// </summary>
 117.340 +        /// <value> The default font. </value>
 117.341 +        /// <remarks>
 117.342 +        /// This font is used for text on axes, series, legends and plot titles unless other fonts are specified.
 117.343 +        /// </remarks>
 117.344 +        public string DefaultFont { get; set; }
 117.345 +
 117.346 +        /// <summary>
 117.347 +        /// Gets or sets the default size of the fonts.
 117.348 +        /// </summary>
 117.349 +        /// <value>
 117.350 +        /// The default size of the font.
 117.351 +        /// </value>
 117.352 +        public double DefaultFontSize { get; set; }
 117.353 +
 117.354 +        /// <summary>
 117.355 +        /// Gets the actual culture.
 117.356 +        /// </summary>
 117.357 +        public CultureInfo ActualCulture
 117.358 +        {
 117.359 +            get
 117.360 +            {
 117.361 +                return this.Culture ?? CultureInfo.CurrentCulture;
 117.362 +            }
 117.363 +        }
 117.364 +
 117.365 +        /// <summary>
 117.366 +        /// Gets the actual plot margins.
 117.367 +        /// </summary>
 117.368 +        /// <value> The actual plot margins. </value>
 117.369 +        public OxyThickness ActualPlotMargins { get; private set; }
 117.370 +
 117.371 +        /// <summary>
 117.372 +        /// Gets the plot control that renders this plot.
 117.373 +        /// </summary>
 117.374 +        /// <remarks>
 117.375 +        /// Only one PlotControl can render the plot at the same time.
 117.376 +        /// </remarks>
 117.377 +        /// <value>The plot control.</value>
 117.378 +        public IPlotControl PlotControl { get; private set; }
 117.379 +
 117.380 +        /// <summary>
 117.381 +        /// Gets or sets the annotations.
 117.382 +        /// </summary>
 117.383 +        /// <value> The annotations. </value>
 117.384 +        public Collection<Annotation> Annotations { get; set; }
 117.385 +
 117.386 +        /// <summary>
 117.387 +        /// Gets or sets a value indicating whether to auto adjust plot margins.
 117.388 +        /// </summary>
 117.389 +        public bool AutoAdjustPlotMargins { get; set; }
 117.390 +
 117.391 +        /// <summary>
 117.392 +        /// Gets or sets the axes.
 117.393 +        /// </summary>
 117.394 +        /// <value> The axes. </value>
 117.395 +        public Collection<Axis> Axes { get; set; }
 117.396 +
 117.397 +        /// <summary>
 117.398 +        /// Gets or sets the color of the background of the plot.
 117.399 +        /// </summary>
 117.400 +        public OxyColor Background { get; set; }
 117.401 +
 117.402 +        /// <summary>
 117.403 +        /// Gets or sets the culture.
 117.404 +        /// </summary>
 117.405 +        /// <value> The culture. </value>
 117.406 +        public CultureInfo Culture { get; set; }
 117.407 +
 117.408 +        /// <summary>
 117.409 +        /// Gets or sets the default colors.
 117.410 +        /// </summary>
 117.411 +        /// <value> The default colors. </value>
 117.412 +        public IList<OxyColor> DefaultColors { get; set; }
 117.413 +
 117.414 +        /// <summary>
 117.415 +        /// Gets or sets a value indicating whether the legend is visible. The titles of the series must be set to use the legend.
 117.416 +        /// </summary>
 117.417 +        public bool IsLegendVisible { get; set; }
 117.418 +
 117.419 +        /// <summary>
 117.420 +        /// Gets the legend area.
 117.421 +        /// </summary>
 117.422 +        /// <value> The legend area. </value>
 117.423 +        public OxyRect LegendArea { get; private set; }
 117.424 +
 117.425 +        /// <summary>
 117.426 +        /// Gets or sets the background color of the legend. Use null for no background.
 117.427 +        /// </summary>
 117.428 +        /// <value> The legend background. </value>
 117.429 +        public OxyColor LegendBackground { get; set; }
 117.430 +
 117.431 +        /// <summary>
 117.432 +        /// Gets or sets the border color of the legend.
 117.433 +        /// </summary>
 117.434 +        /// <value> The legend border. </value>
 117.435 +        public OxyColor LegendBorder { get; set; }
 117.436 +
 117.437 +        /// <summary>
 117.438 +        /// Gets or sets the thickness of the legend border. Use 0 for no border.
 117.439 +        /// </summary>
 117.440 +        /// <value> The legend border thickness. </value>
 117.441 +        public double LegendBorderThickness { get; set; }
 117.442 +
 117.443 +        /// <summary>
 117.444 +        /// Gets or sets the legend column spacing.
 117.445 +        /// </summary>
 117.446 +        /// <value> The legend column spacing. </value>
 117.447 +        public double LegendColumnSpacing { get; set; }
 117.448 +
 117.449 +        /// <summary>
 117.450 +        /// Gets or sets the legend font.
 117.451 +        /// </summary>
 117.452 +        /// <value> The legend font. </value>
 117.453 +        public string LegendFont { get; set; }
 117.454 +
 117.455 +        /// <summary>
 117.456 +        /// Gets or sets the size of the legend font.
 117.457 +        /// </summary>
 117.458 +        /// <value> The size of the legend font. </value>
 117.459 +        public double LegendFontSize { get; set; }
 117.460 +
 117.461 +        /// <summary>
 117.462 +        /// Gets or sets the color of the legend text.
 117.463 +        /// </summary>
 117.464 +        /// <value>
 117.465 +        /// The color of the legend text.
 117.466 +        /// </value>
 117.467 +        /// <remarks>
 117.468 +        /// If this value is null, the TextColor will be used.
 117.469 +        /// </remarks>
 117.470 +        public OxyColor LegendTextColor { get; set; }
 117.471 +
 117.472 +        /// <summary>
 117.473 +        /// Gets or sets the legend font weight.
 117.474 +        /// </summary>
 117.475 +        /// <value> The legend font weight. </value>
 117.476 +        public double LegendFontWeight { get; set; }
 117.477 +
 117.478 +        /// <summary>
 117.479 +        /// Gets or sets the legend item alignment.
 117.480 +        /// </summary>
 117.481 +        /// <value> The legend item alignment. </value>
 117.482 +        public HorizontalAlignment LegendItemAlignment { get; set; }
 117.483 +
 117.484 +        /// <summary>
 117.485 +        /// Gets or sets the legend item order.
 117.486 +        /// </summary>
 117.487 +        /// <value> The legend item order. </value>
 117.488 +        public LegendItemOrder LegendItemOrder { get; set; }
 117.489 +
 117.490 +        /// <summary>
 117.491 +        /// Gets or sets the legend spacing.
 117.492 +        /// </summary>
 117.493 +        /// <value> The legend spacing. </value>
 117.494 +        public double LegendItemSpacing { get; set; }
 117.495 +
 117.496 +        /// <summary>
 117.497 +        /// Gets or sets the legend margin.
 117.498 +        /// </summary>
 117.499 +        /// <value> The legend margin. </value>
 117.500 +        public double LegendMargin { get; set; }
 117.501 +
 117.502 +        /// <summary>
 117.503 +        /// Gets or sets the max width of the legend.
 117.504 +        /// </summary>
 117.505 +        /// <value>The max width of the legend.</value>
 117.506 +        public double LegendMaxWidth { get; set; }
 117.507 +
 117.508 +        /// <summary>
 117.509 +        /// Gets or sets the legend orientation.
 117.510 +        /// </summary>
 117.511 +        /// <value> The legend orientation. </value>
 117.512 +        public LegendOrientation LegendOrientation { get; set; }
 117.513 +
 117.514 +        /// <summary>
 117.515 +        /// Gets or sets the legend padding.
 117.516 +        /// </summary>
 117.517 +        /// <value> The legend padding. </value>
 117.518 +        public double LegendPadding { get; set; }
 117.519 +
 117.520 +        /// <summary>
 117.521 +        /// Gets or sets the legend placement.
 117.522 +        /// </summary>
 117.523 +        /// <value> The legend placement. </value>
 117.524 +        public LegendPlacement LegendPlacement { get; set; }
 117.525 +
 117.526 +        /// <summary>
 117.527 +        /// Gets or sets the legend position.
 117.528 +        /// </summary>
 117.529 +        /// <value> The legend position. </value>
 117.530 +        public LegendPosition LegendPosition { get; set; }
 117.531 +
 117.532 +        /// <summary>
 117.533 +        /// Gets or sets the length of the legend symbols (the default value is 16).
 117.534 +        /// </summary>
 117.535 +        public double LegendSymbolLength { get; set; }
 117.536 +
 117.537 +        /// <summary>
 117.538 +        /// Gets or sets the legend symbol margins (distance between the symbol and the text).
 117.539 +        /// </summary>
 117.540 +        /// <value> The legend symbol margin. </value>
 117.541 +        public double LegendSymbolMargin { get; set; }
 117.542 +
 117.543 +        /// <summary>
 117.544 +        /// Gets or sets the legend symbol placement.
 117.545 +        /// </summary>
 117.546 +        /// <value> The legend symbol placement. </value>
 117.547 +        public LegendSymbolPlacement LegendSymbolPlacement { get; set; }
 117.548 +
 117.549 +        /// <summary>
 117.550 +        /// Gets or sets the legend title.
 117.551 +        /// </summary>
 117.552 +        /// <value> The legend title. </value>
 117.553 +        public string LegendTitle { get; set; }
 117.554 +
 117.555 +        /// <summary>
 117.556 +        /// Gets or sets the color of the legend title.
 117.557 +        /// </summary>
 117.558 +        /// <value>
 117.559 +        /// The color of the legend title.
 117.560 +        /// </value>
 117.561 +        /// <remarks>
 117.562 +        /// If this value is null, the TextColor will be used.
 117.563 +        /// </remarks>
 117.564 +        public OxyColor LegendTitleColor { get; set; }
 117.565 +
 117.566 +        /// <summary>
 117.567 +        /// Gets or sets the legend title font.
 117.568 +        /// </summary>
 117.569 +        /// <value> The legend title font. </value>
 117.570 +        public string LegendTitleFont { get; set; }
 117.571 +
 117.572 +        /// <summary>
 117.573 +        /// Gets or sets the size of the legend title font.
 117.574 +        /// </summary>
 117.575 +        /// <value> The size of the legend title font. </value>
 117.576 +        public double LegendTitleFontSize { get; set; }
 117.577 +
 117.578 +        /// <summary>
 117.579 +        /// Gets or sets the legend title font weight.
 117.580 +        /// </summary>
 117.581 +        /// <value> The legend title font weight. </value>
 117.582 +        public double LegendTitleFontWeight { get; set; }
 117.583 +
 117.584 +        /// <summary>
 117.585 +        /// Gets or sets the padding around the plot.
 117.586 +        /// </summary>
 117.587 +        /// <value> The padding. </value>
 117.588 +        public OxyThickness Padding { get; set; }
 117.589 +
 117.590 +        /// <summary>
 117.591 +        /// Gets the total width of the plot (in device units).
 117.592 +        /// </summary>
 117.593 +        public double Width { get; private set; }
 117.594 +
 117.595 +        /// <summary>
 117.596 +        /// Gets the total height of the plot (in device units).
 117.597 +        /// </summary>
 117.598 +        public double Height { get; private set; }
 117.599 +
 117.600 +        /// <summary>
 117.601 +        /// Gets the area including both the plot and the axes. Outside legends are rendered outside this rectangle.
 117.602 +        /// </summary>
 117.603 +        /// <value> The plot and axis area. </value>
 117.604 +        public OxyRect PlotAndAxisArea { get; private set; }
 117.605 +
 117.606 +        /// <summary>
 117.607 +        /// Gets the plot area. This area is used to draw the series (not including axes or legends).
 117.608 +        /// </summary>
 117.609 +        /// <value> The plot area. </value>
 117.610 +        public OxyRect PlotArea { get; private set; }
 117.611 +
 117.612 +        /// <summary>
 117.613 +        /// Gets or sets the distance between two neighbourhood tiers of the same AxisPosition.
 117.614 +        /// </summary>
 117.615 +        public double AxisTierDistance { get; set; }
 117.616 +
 117.617 +        /// <summary>
 117.618 +        /// Gets or sets the color of the background of the plot area.
 117.619 +        /// </summary>
 117.620 +        public OxyColor PlotAreaBackground { get; set; }
 117.621 +
 117.622 +        /// <summary>
 117.623 +        /// Gets or sets the color of the border around the plot area.
 117.624 +        /// </summary>
 117.625 +        /// <value> The color of the box. </value>
 117.626 +        public OxyColor PlotAreaBorderColor { get; set; }
 117.627 +
 117.628 +        /// <summary>
 117.629 +        /// Gets or sets the thickness of the border around the plot area.
 117.630 +        /// </summary>
 117.631 +        /// <value> The box thickness. </value>
 117.632 +        public double PlotAreaBorderThickness { get; set; }
 117.633 +
 117.634 +        /// <summary>
 117.635 +        /// 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.
 117.636 +        /// </summary>
 117.637 +        public OxyThickness PlotMargins { get; set; }
 117.638 +
 117.639 +        /// <summary>
 117.640 +        /// Gets or sets the type of the coordinate system.
 117.641 +        /// </summary>
 117.642 +        /// <value> The type of the plot. </value>
 117.643 +        public PlotType PlotType { get; set; }
 117.644 +
 117.645 +        /// <summary>
 117.646 +        /// Gets or sets the color of the selection.
 117.647 +        /// </summary>
 117.648 +        /// <value>
 117.649 +        /// The color of the selection.
 117.650 +        /// </value>
 117.651 +        public OxyColor SelectionColor { get; set; }
 117.652 +
 117.653 +        /// <summary>
 117.654 +        /// Gets or sets the series.
 117.655 +        /// </summary>
 117.656 +        /// <value> The series. </value>
 117.657 +        public Collection<Series.Series> Series { get; set; }
 117.658 +
 117.659 +        /// <summary>
 117.660 +        /// Gets or sets the subtitle.
 117.661 +        /// </summary>
 117.662 +        /// <value> The subtitle. </value>
 117.663 +        public string Subtitle { get; set; }
 117.664 +
 117.665 +        /// <summary>
 117.666 +        /// Gets or sets the subtitle font. If this property is null, the Title font will be used.
 117.667 +        /// </summary>
 117.668 +        /// <value> The subtitle font. </value>
 117.669 +        public string SubtitleFont { get; set; }
 117.670 +
 117.671 +        /// <summary>
 117.672 +        /// Gets or sets the size of the subtitle font.
 117.673 +        /// </summary>
 117.674 +        /// <value> The size of the subtitle font. </value>
 117.675 +        public double SubtitleFontSize { get; set; }
 117.676 +
 117.677 +        /// <summary>
 117.678 +        /// Gets or sets the subtitle font weight.
 117.679 +        /// </summary>
 117.680 +        /// <value> The subtitle font weight. </value>
 117.681 +        public double SubtitleFontWeight { get; set; }
 117.682 +
 117.683 +        /// <summary>
 117.684 +        /// Gets or sets the default color of the text in the plot (titles, legends, annotations, axes).
 117.685 +        /// </summary>
 117.686 +        /// <value> The color of the text. </value>
 117.687 +        public OxyColor TextColor { get; set; }
 117.688 +
 117.689 +        /// <summary>
 117.690 +        /// Gets or sets the title.
 117.691 +        /// </summary>
 117.692 +        /// <value> The title. </value>
 117.693 +        public string Title { get; set; }
 117.694 +
 117.695 +        /// <summary>
 117.696 +        /// Gets or sets the color of the title.
 117.697 +        /// </summary>
 117.698 +        /// <value>
 117.699 +        /// The color of the title.
 117.700 +        /// </value>
 117.701 +        /// <remarks>
 117.702 +        /// If the value is null, the TextColor will be used.
 117.703 +        /// </remarks>
 117.704 +        public OxyColor TitleColor { get; set; }
 117.705 +
 117.706 +        /// <summary>
 117.707 +        /// Gets or sets the color of the subtitle.
 117.708 +        /// </summary>
 117.709 +        /// <value>
 117.710 +        /// The color of the subtitle.
 117.711 +        /// </value>
 117.712 +        public OxyColor SubtitleColor { get; set; }
 117.713 +
 117.714 +        /// <summary>
 117.715 +        /// Gets the title area.
 117.716 +        /// </summary>
 117.717 +        /// <value> The title area. </value>
 117.718 +        public OxyRect TitleArea { get; private set; }
 117.719 +
 117.720 +        /// <summary>
 117.721 +        /// Gets or sets the title font.
 117.722 +        /// </summary>
 117.723 +        /// <value> The title font. </value>
 117.724 +        public string TitleFont { get; set; }
 117.725 +
 117.726 +        /// <summary>
 117.727 +        /// Gets or sets the size of the title font.
 117.728 +        /// </summary>
 117.729 +        /// <value> The size of the title font. </value>
 117.730 +        public double TitleFontSize { get; set; }
 117.731 +
 117.732 +        /// <summary>
 117.733 +        /// Gets or sets the title font weight.
 117.734 +        /// </summary>
 117.735 +        /// <value> The title font weight. </value>
 117.736 +        public double TitleFontWeight { get; set; }
 117.737 +
 117.738 +        /// <summary>
 117.739 +        /// Gets or sets the padding around the title.
 117.740 +        /// </summary>
 117.741 +        /// <value> The title padding. </value>
 117.742 +        public double TitlePadding { get; set; }
 117.743 +
 117.744 +        /// <summary>
 117.745 +        /// Gets the default angle axis.
 117.746 +        /// </summary>
 117.747 +        /// <value> The default angle axis. </value>
 117.748 +        public AngleAxis DefaultAngleAxis { get; private set; }
 117.749 +
 117.750 +        /// <summary>
 117.751 +        /// Gets the default magnitude axis.
 117.752 +        /// </summary>
 117.753 +        /// <value> The default magnitude axis. </value>
 117.754 +        public MagnitudeAxis DefaultMagnitudeAxis { get; private set; }
 117.755 +
 117.756 +        /// <summary>
 117.757 +        /// Gets the default X axis.
 117.758 +        /// </summary>
 117.759 +        /// <value> The default X axis. </value>
 117.760 +        public Axis DefaultXAxis { get; private set; }
 117.761 +
 117.762 +        /// <summary>
 117.763 +        /// Gets the default Y axis.
 117.764 +        /// </summary>
 117.765 +        /// <value> The default Y axis. </value>
 117.766 +        public Axis DefaultYAxis { get; private set; }
 117.767 +
 117.768 +        /// <summary>
 117.769 +        /// Gets the default color axis.
 117.770 +        /// </summary>
 117.771 +        /// <value> The default color axis. </value>
 117.772 +        public ColorAxis DefaultColorAxis { get; private set; }
 117.773 +
 117.774 +        /// <summary>
 117.775 +        /// Gets the actual title font.
 117.776 +        /// </summary>
 117.777 +        protected string ActualTitleFont
 117.778 +        {
 117.779 +            get
 117.780 +            {
 117.781 +                return this.TitleFont ?? this.DefaultFont;
 117.782 +            }
 117.783 +        }
 117.784 +
 117.785 +        /// <summary>
 117.786 +        /// Gets the actual subtitle font.
 117.787 +        /// </summary>
 117.788 +        protected string ActualSubtitleFont
 117.789 +        {
 117.790 +            get
 117.791 +            {
 117.792 +                return this.SubtitleFont ?? this.DefaultFont;
 117.793 +            }
 117.794 +        }
 117.795 +
 117.796 +        /// <summary>
 117.797 +        /// Gets the visible series.
 117.798 +        /// </summary>
 117.799 +        /// <value> The visible series. </value>
 117.800 +        private IEnumerable<Series.Series> VisibleSeries
 117.801 +        {
 117.802 +            get
 117.803 +            {
 117.804 +                return this.Series.Where(s => s.IsVisible);
 117.805 +            }
 117.806 +        }
 117.807 +
 117.808 +        /// <summary>
 117.809 +        /// Attaches this model to the specified plot control.
 117.810 +        /// </summary>
 117.811 +        /// <param name="plotControl">The plot control.</param>
 117.812 +        /// <remarks>
 117.813 +        /// Only one plot control can be attached to the plot model.
 117.814 +        /// The plot model contains data (e.g. axis scaling) that is only relevant to the current plot control.
 117.815 +        /// </remarks>
 117.816 +        public void AttachPlotControl(IPlotControl plotControl)
 117.817 +        {
 117.818 +            this.PlotControl = plotControl;
 117.819 +        }
 117.820 +
 117.821 +        /// <summary>
 117.822 +        /// Creates a report for the plot.
 117.823 +        /// </summary>
 117.824 +        /// <returns>
 117.825 +        /// A report.
 117.826 +        /// </returns>
 117.827 +        public Report CreateReport()
 117.828 +        {
 117.829 +            var r = new Report { Culture = CultureInfo.InvariantCulture };
 117.830 +
 117.831 +            r.AddHeader(1, "P L O T   R E P O R T");
 117.832 +            r.AddHeader(2, "=== PlotModel ===");
 117.833 +            r.AddPropertyTable("PlotModel", this);
 117.834 +
 117.835 +            r.AddHeader(2, "=== Axes ===");
 117.836 +            foreach (Axis a in this.Axes)
 117.837 +            {
 117.838 +                r.AddPropertyTable(a.GetType().Name, a);
 117.839 +            }
 117.840 +
 117.841 +            r.AddHeader(2, "=== Annotations ===");
 117.842 +            foreach (var a in this.Annotations)
 117.843 +            {
 117.844 +                r.AddPropertyTable(a.GetType().Name, a);
 117.845 +            }
 117.846 +
 117.847 +            r.AddHeader(2, "=== Series ===");
 117.848 +            foreach (var s in this.Series)
 117.849 +            {
 117.850 +                r.AddPropertyTable(s.GetType().Name, s);
 117.851 +                var ds = s as DataPointSeries;
 117.852 +                if (ds != null)
 117.853 +                {
 117.854 +                    var fields = new List<ItemsTableField> { new ItemsTableField("X", "X"), new ItemsTableField("Y", "Y") };
 117.855 +                    r.AddItemsTable("Data", ds.Points, fields);
 117.856 +                }
 117.857 +            }
 117.858 +
 117.859 +            var assemblyName = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
 117.860 +            r.AddParagraph(string.Format("Report generated by OxyPlot {0}", assemblyName.Version.ToString(3)));
 117.861 +
 117.862 +            return r;
 117.863 +        }
 117.864 +
 117.865 +        /// <summary>
 117.866 +        /// Creates a text report for the plot.
 117.867 +        /// </summary>
 117.868 +        /// <returns>
 117.869 +        /// The create text report.
 117.870 +        /// </returns>
 117.871 +        public string CreateTextReport()
 117.872 +        {
 117.873 +            using (var ms = new MemoryStream())
 117.874 +            {
 117.875 +                var trw = new TextReportWriter(ms);
 117.876 +                Report report = this.CreateReport();
 117.877 +                report.Write(trw);
 117.878 +                trw.Flush();
 117.879 +                ms.Position = 0;
 117.880 +                var r = new StreamReader(ms);
 117.881 +                return r.ReadToEnd();
 117.882 +            }
 117.883 +        }
 117.884 +
 117.885 +        /// <summary>
 117.886 +        /// Refreshes the plot.
 117.887 +        /// </summary>
 117.888 +        /// <param name="updateData">Updates all data sources if set to <c>true</c>.</param>
 117.889 +        public void RefreshPlot(bool updateData)
 117.890 +        {
 117.891 +            if (this.PlotControl == null)
 117.892 +            {
 117.893 +                return;
 117.894 +            }
 117.895 +
 117.896 +            this.PlotControl.RefreshPlot(updateData);
 117.897 +        }
 117.898 +
 117.899 +        /// <summary>
 117.900 +        /// Invalidates the plot.
 117.901 +        /// </summary>
 117.902 +        /// <param name="updateData">Updates all data sources if set to <c>true</c>.</param>
 117.903 +        public void InvalidatePlot(bool updateData)
 117.904 +        {
 117.905 +            if (this.PlotControl == null)
 117.906 +            {
 117.907 +                return;
 117.908 +            }
 117.909 +
 117.910 +            this.PlotControl.InvalidatePlot(updateData);
 117.911 +        }
 117.912 +
 117.913 +        /// <summary>
 117.914 +        /// Gets the first axes that covers the area of the specified point.
 117.915 +        /// </summary>
 117.916 +        /// <param name="pt">
 117.917 +        /// The point.
 117.918 +        /// </param>
 117.919 +        /// <param name="xaxis">
 117.920 +        /// The xaxis.
 117.921 +        /// </param>
 117.922 +        /// <param name="yaxis">
 117.923 +        /// The yaxis.
 117.924 +        /// </param>
 117.925 +        public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
 117.926 +        {
 117.927 +            xaxis = yaxis = null;
 117.928 +
 117.929 +            // Get the axis position of the given point. Using null if the point is inside the plot area.
 117.930 +            AxisPosition? position = null;
 117.931 +            double plotAreaValue = 0;
 117.932 +            if (pt.X < this.PlotArea.Left)
 117.933 +            {
 117.934 +                position = AxisPosition.Left;
 117.935 +                plotAreaValue = this.PlotArea.Left;
 117.936 +            }
 117.937 +
 117.938 +            if (pt.X > this.PlotArea.Right)
 117.939 +            {
 117.940 +                position = AxisPosition.Right;
 117.941 +                plotAreaValue = this.PlotArea.Right;
 117.942 +            }
 117.943 +
 117.944 +            if (pt.Y < this.PlotArea.Top)
 117.945 +            {
 117.946 +                position = AxisPosition.Top;
 117.947 +                plotAreaValue = this.PlotArea.Top;
 117.948 +            }
 117.949 +
 117.950 +            if (pt.Y > this.PlotArea.Bottom)
 117.951 +            {
 117.952 +                position = AxisPosition.Bottom;
 117.953 +                plotAreaValue = this.PlotArea.Bottom;
 117.954 +            }
 117.955 +
 117.956 +            foreach (var axis in this.Axes)
 117.957 +            {
 117.958 +                if (axis is ColorAxis)
 117.959 +                {
 117.960 +                    continue;
 117.961 +                }
 117.962 +
 117.963 +                if (axis is MagnitudeAxis)
 117.964 +                {
 117.965 +                    xaxis = axis;
 117.966 +                    continue;
 117.967 +                }
 117.968 +
 117.969 +                if (axis is AngleAxis)
 117.970 +                {
 117.971 +                    yaxis = axis;
 117.972 +                    continue;
 117.973 +                }
 117.974 +
 117.975 +                double x = double.NaN;
 117.976 +                if (axis.IsHorizontal())
 117.977 +                {
 117.978 +                    x = axis.InverseTransform(pt.X);
 117.979 +                }
 117.980 +
 117.981 +                if (axis.IsVertical())
 117.982 +                {
 117.983 +                    x = axis.InverseTransform(pt.Y);
 117.984 +                }
 117.985 +
 117.986 +                if (x >= axis.ActualMinimum && x <= axis.ActualMaximum)
 117.987 +                {
 117.988 +                    if (position == null)
 117.989 +                    {
 117.990 +                        if (axis.IsHorizontal())
 117.991 +                        {
 117.992 +                            if (xaxis == null)
 117.993 +                            {
 117.994 +                                xaxis = axis;
 117.995 +                            }
 117.996 +                        }
 117.997 +                        else if (axis.IsVertical())
 117.998 +                        {
 117.999 +                            if (yaxis == null)
117.1000 +                            {
117.1001 +                                yaxis = axis;
117.1002 +                            }
117.1003 +                        }
117.1004 +                    }
117.1005 +                    else if (position == axis.Position)
117.1006 +                    {
117.1007 +                        // Choose right tier
117.1008 +                        double positionTierMinShift = axis.PositionTierMinShift;
117.1009 +                        double positionTierMaxShift = axis.PositionTierMaxShift;
117.1010 +
117.1011 +                        double posValue = axis.IsHorizontal() ? pt.Y : pt.X;
117.1012 +                        bool isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left;
117.1013 +                        if ((posValue >= plotAreaValue + positionTierMinShift
117.1014 +                             && posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop)
117.1015 +                            ||
117.1016 +                            (posValue <= plotAreaValue - positionTierMinShift
117.1017 +                             && posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop))
117.1018 +                        {
117.1019 +                            if (axis.IsHorizontal())
117.1020 +                            {
117.1021 +                                if (xaxis == null)
117.1022 +                                {
117.1023 +                                    xaxis = axis;
117.1024 +                                }
117.1025 +                            }
117.1026 +                            else if (axis.IsVertical())
117.1027 +                            {
117.1028 +                                if (yaxis == null)
117.1029 +                                {
117.1030 +                                    yaxis = axis;
117.1031 +                                }
117.1032 +                            }
117.1033 +                        }
117.1034 +                    }
117.1035 +                }
117.1036 +            }
117.1037 +        }
117.1038 +
117.1039 +        /// <summary>
117.1040 +        /// Gets the default color from the DefaultColors palette.
117.1041 +        /// </summary>
117.1042 +        /// <returns>
117.1043 +        /// The next default color.
117.1044 +        /// </returns>
117.1045 +        public OxyColor GetDefaultColor()
117.1046 +        {
117.1047 +            return this.DefaultColors[this.currentColorIndex++ % this.DefaultColors.Count];
117.1048 +        }
117.1049 +
117.1050 +        /// <summary>
117.1051 +        /// Gets the default line style.
117.1052 +        /// </summary>
117.1053 +        /// <returns>
117.1054 +        /// The next default line style.
117.1055 +        /// </returns>
117.1056 +        public LineStyle GetDefaultLineStyle()
117.1057 +        {
117.1058 +            return (LineStyle)((this.currentColorIndex / this.DefaultColors.Count) % (int)LineStyle.None);
117.1059 +        }
117.1060 +
117.1061 +        /// <summary>
117.1062 +        /// Gets a series from the specified point.
117.1063 +        /// </summary>
117.1064 +        /// <param name="point">
117.1065 +        /// The point.
117.1066 +        /// </param>
117.1067 +        /// <param name="limit">
117.1068 +        /// The limit.
117.1069 +        /// </param>
117.1070 +        /// <returns>
117.1071 +        /// The nearest series.
117.1072 +        /// </returns>
117.1073 +        public Series.Series GetSeriesFromPoint(ScreenPoint point, double limit)
117.1074 +        {
117.1075 +            double mindist = double.MaxValue;
117.1076 +            Series.Series closest = null;
117.1077 +            foreach (var s in this.VisibleSeries.Reverse())
117.1078 +            {
117.1079 +                var ts = s as ITrackableSeries;
117.1080 +                if (ts == null)
117.1081 +                {
117.1082 +                    continue;
117.1083 +                }
117.1084 +
117.1085 +                var thr = ts.GetNearestPoint(point, true) ?? ts.GetNearestPoint(point, false);
117.1086 +
117.1087 +                if (thr == null)
117.1088 +                {
117.1089 +                    continue;
117.1090 +                }
117.1091 +
117.1092 +                // find distance to this point on the screen
117.1093 +                double dist = point.DistanceTo(thr.Position);
117.1094 +                if (dist < mindist)
117.1095 +                {
117.1096 +                    closest = s;
117.1097 +                    mindist = dist;
117.1098 +                }
117.1099 +            }
117.1100 +
117.1101 +            if (mindist < limit)
117.1102 +            {
117.1103 +                return closest;
117.1104 +            }
117.1105 +
117.1106 +            return null;
117.1107 +        }
117.1108 +
117.1109 +        /// <summary>
117.1110 +        /// Generates C# code of the model.
117.1111 +        /// </summary>
117.1112 +        /// <returns>
117.1113 +        /// C# code.
117.1114 +        /// </returns>
117.1115 +        public string ToCode()
117.1116 +        {
117.1117 +            var cg = new CodeGenerator(this);
117.1118 +            return cg.ToCode();
117.1119 +        }
117.1120 +
117.1121 +        /// <summary>
117.1122 +        /// Returns a <see cref="System.String"/> that represents this instance.
117.1123 +        /// </summary>
117.1124 +        /// <returns>
117.1125 +        /// A <see cref="System.String"/> that represents this instance.
117.1126 +        /// </returns>
117.1127 +        public override string ToString()
117.1128 +        {
117.1129 +            return this.Title;
117.1130 +        }
117.1131 +
117.1132 +        /// <summary>
117.1133 +        /// Create an svg model and return it as a string.
117.1134 +        /// </summary>
117.1135 +        /// <param name="width">The width (points).</param>
117.1136 +        /// <param name="height">The height (points).</param>
117.1137 +        /// <param name="isDocument">if set to <c>true</c>, the xml headers will be included (?xml and !DOCTYPE).</param>
117.1138 +        /// <param name="textMeasurer">The text measurer.</param>
117.1139 +        /// <returns>The svg string.</returns>
117.1140 +        public string ToSvg(double width, double height, bool isDocument, IRenderContext textMeasurer)
117.1141 +        {
117.1142 +            return SvgExporter.ExportToString(this, width, height, isDocument, textMeasurer);
117.1143 +        }
117.1144 +
117.1145 +        /// <summary>
117.1146 +        /// Gets all elements of the plot model.
117.1147 +        /// </summary>
117.1148 +        /// <returns>An enumerator of the plot elements.</returns>
117.1149 +        public IEnumerable<PlotElement> GetElements()
117.1150 +        {
117.1151 +            foreach (var axis in this.Axes)
117.1152 +            {
117.1153 +                yield return axis;
117.1154 +            }
117.1155 +
117.1156 +            foreach (var annotation in this.Annotations)
117.1157 +            {
117.1158 +                yield return annotation;
117.1159 +            }
117.1160 +
117.1161 +            foreach (var s in this.Series)
117.1162 +            {
117.1163 +                yield return s;
117.1164 +            }
117.1165 +        }
117.1166 +
117.1167 +        /// <summary>
117.1168 +        /// Updates all axes and series. 0. Updates the owner PlotModel of all plot items (axes, series and annotations)
117.1169 +        /// 1. Updates the data of each Series (only if updateData==true).
117.1170 +        /// 2. Ensure that all series have axes assigned.
117.1171 +        /// 3. Updates the max and min of the axes.
117.1172 +        /// </summary>
117.1173 +        /// <param name="updateData">
117.1174 +        /// if set to <c>true</c> , all data collections will be updated.
117.1175 +        /// </param>
117.1176 +        public void Update(bool updateData = true)
117.1177 +        {
117.1178 +            lock (this.syncRoot)
117.1179 +            {
117.1180 +                this.OnUpdating();
117.1181 +
117.1182 +                // update the owner PlotModel
117.1183 +                foreach (var s in this.VisibleSeries)
117.1184 +                {
117.1185 +                    s.PlotModel = this;
117.1186 +                }
117.1187 +
117.1188 +                foreach (var a in this.Annotations)
117.1189 +                {
117.1190 +                    a.PlotModel = this;
117.1191 +                }
117.1192 +
117.1193 +                // Updates the default axes
117.1194 +                this.EnsureDefaultAxes();
117.1195 +
117.1196 +                // Update data of the series
117.1197 +                if (updateData)
117.1198 +                {
117.1199 +                    foreach (var s in this.VisibleSeries)
117.1200 +                    {
117.1201 +                        s.UpdateData();
117.1202 +                    }
117.1203 +                }
117.1204 +
117.1205 +                foreach (var a in this.Axes)
117.1206 +                {
117.1207 +                    a.PlotModel = this;
117.1208 +                }
117.1209 +
117.1210 +                foreach (var c in this.Axes.OfType<CategoryAxis>())
117.1211 +                {
117.1212 +                    c.UpdateLabels(this.VisibleSeries);
117.1213 +                }
117.1214 +
117.1215 +                // Update valid data of the series
117.1216 +                if (updateData)
117.1217 +                {
117.1218 +                    foreach (var s in this.VisibleSeries)
117.1219 +                    {
117.1220 +                        s.UpdateValidData();
117.1221 +                    }
117.1222 +                }
117.1223 +
117.1224 +                // Updates axes with information from the series
117.1225 +                // This is used by the category axis that need to know the number of series using the axis.
117.1226 +                foreach (var a in this.Axes)
117.1227 +                {
117.1228 +                    a.UpdateFromSeries(this.VisibleSeries);
117.1229 +                }
117.1230 +
117.1231 +                // Update the max and min of the axes
117.1232 +                this.UpdateMaxMin(updateData);
117.1233 +                this.OnUpdated();
117.1234 +            }
117.1235 +        }
117.1236 +
117.1237 +        /// <summary>
117.1238 +        /// Updates the axis transforms.
117.1239 +        /// </summary>
117.1240 +        public void UpdateAxisTransforms()
117.1241 +        {
117.1242 +            // Update the axis transforms
117.1243 +            foreach (var a in this.Axes)
117.1244 +            {
117.1245 +                a.UpdateTransform(this.PlotArea);
117.1246 +            }
117.1247 +        }
117.1248 +
117.1249 +        /// <summary>
117.1250 +        /// Gets the axis for the specified key.
117.1251 +        /// </summary>
117.1252 +        /// <param name="key">The key.</param>
117.1253 +        /// <param name="defaultAxis">The default axis.</param>
117.1254 +        /// <returns>The axis, or the defaultAxis if the key is not found.</returns>
117.1255 +        public Axis GetAxisOrDefault(string key, Axis defaultAxis)
117.1256 +        {
117.1257 +            if (key != null)
117.1258 +            {
117.1259 +                return this.Axes.FirstOrDefault(a => a.Key == key) ?? defaultAxis;
117.1260 +            }
117.1261 +
117.1262 +            return defaultAxis;
117.1263 +        }
117.1264 +
117.1265 +        /// <summary>
117.1266 +        /// Raises the Updated event.
117.1267 +        /// </summary>
117.1268 +        protected virtual void OnUpdated()
117.1269 +        {
117.1270 +            var handler = this.Updated;
117.1271 +            if (handler != null)
117.1272 +            {
117.1273 +                var args = new EventArgs();
117.1274 +                handler(this, args);
117.1275 +            }
117.1276 +        }
117.1277 +
117.1278 +        /// <summary>
117.1279 +        /// Raises the Updating event.
117.1280 +        /// </summary>
117.1281 +        protected virtual void OnUpdating()
117.1282 +        {
117.1283 +            var handler = this.Updating;
117.1284 +            if (handler != null)
117.1285 +            {
117.1286 +                var args = new EventArgs();
117.1287 +                handler(this, args);
117.1288 +            }
117.1289 +        }
117.1290 +
117.1291 +        /// <summary>
117.1292 +        /// Enforces the same scale on all axes.
117.1293 +        /// </summary>
117.1294 +        private void EnforceCartesianTransforms()
117.1295 +        {
117.1296 +            // Set the same scaling on all axes
117.1297 +            double sharedScale = this.Axes.Min(a => Math.Abs(a.Scale));
117.1298 +            foreach (var a in this.Axes)
117.1299 +            {
117.1300 +                a.Zoom(sharedScale);
117.1301 +            }
117.1302 +
117.1303 +            sharedScale = this.Axes.Max(a => Math.Abs(a.Scale));
117.1304 +            foreach (var a in this.Axes)
117.1305 +            {
117.1306 +                a.Zoom(sharedScale);
117.1307 +            }
117.1308 +
117.1309 +            foreach (var a in this.Axes)
117.1310 +            {
117.1311 +                a.UpdateTransform(this.PlotArea);
117.1312 +            }
117.1313 +        }
117.1314 +
117.1315 +        /// <summary>
117.1316 +        /// Updates the intervals (major and minor step values).
117.1317 +        /// </summary>
117.1318 +        private void UpdateIntervals()
117.1319 +        {
117.1320 +            // Update the intervals for all axes
117.1321 +            foreach (var a in this.Axes)
117.1322 +            {
117.1323 +                a.UpdateIntervals(this.PlotArea);
117.1324 +            }
117.1325 +        }
117.1326 +
117.1327 +        /// <summary>
117.1328 +        /// Finds and sets the default horizontal and vertical axes (the first horizontal/vertical axes in the Axes collection).
117.1329 +        /// </summary>
117.1330 +        private void EnsureDefaultAxes()
117.1331 +        {
117.1332 +            this.DefaultXAxis = this.Axes.FirstOrDefault(a => a.IsHorizontal() && a.IsXyAxis());
117.1333 +            this.DefaultYAxis = this.Axes.FirstOrDefault(a => a.IsVertical() && a.IsXyAxis());
117.1334 +            this.DefaultMagnitudeAxis = this.Axes.FirstOrDefault(a => a is MagnitudeAxis) as MagnitudeAxis;
117.1335 +            this.DefaultAngleAxis = this.Axes.FirstOrDefault(a => a is AngleAxis) as AngleAxis;
117.1336 +            this.DefaultColorAxis = this.Axes.FirstOrDefault(a => a is ColorAxis) as ColorAxis;
117.1337 +
117.1338 +            if (this.DefaultXAxis == null)
117.1339 +            {
117.1340 +                this.DefaultXAxis = this.DefaultMagnitudeAxis;
117.1341 +            }
117.1342 +
117.1343 +            if (this.DefaultYAxis == null)
117.1344 +            {
117.1345 +                this.DefaultYAxis = this.DefaultAngleAxis;
117.1346 +            }
117.1347 +
117.1348 +            if (this.PlotType == PlotType.Polar)
117.1349 +            {
117.1350 +                if (this.DefaultXAxis == null)
117.1351 +                {
117.1352 +                    this.DefaultXAxis = this.DefaultMagnitudeAxis = new MagnitudeAxis();
117.1353 +                }
117.1354 +
117.1355 +                if (this.DefaultYAxis == null)
117.1356 +                {
117.1357 +                    this.DefaultYAxis = this.DefaultAngleAxis = new AngleAxis();
117.1358 +                }
117.1359 +            }
117.1360 +            else
117.1361 +            {
117.1362 +                bool createdlinearxaxis = false;
117.1363 +                bool createdlinearyaxis = false;
117.1364 +                if (this.DefaultXAxis == null)
117.1365 +                {
117.1366 +                    if (this.Series.Any(series => series is ColumnSeries))
117.1367 +                    {
117.1368 +                        this.DefaultXAxis = new CategoryAxis { Position = AxisPosition.Bottom };
117.1369 +                    }
117.1370 +                    else
117.1371 +                    {
117.1372 +                        this.DefaultXAxis = new LinearAxis { Position = AxisPosition.Bottom };
117.1373 +                        createdlinearxaxis = true;
117.1374 +                    }
117.1375 +                }
117.1376 +
117.1377 +                if (this.DefaultYAxis == null)
117.1378 +                {
117.1379 +                    if (this.Series.Any(series => series is BarSeries))
117.1380 +                    {
117.1381 +                        this.DefaultYAxis = new CategoryAxis { Position = AxisPosition.Left };
117.1382 +                    }
117.1383 +                    else
117.1384 +                    {
117.1385 +                        this.DefaultYAxis = new LinearAxis { Position = AxisPosition.Left };
117.1386 +                        createdlinearyaxis = true;
117.1387 +                    }
117.1388 +                }
117.1389 +
117.1390 +                if (createdlinearxaxis && this.DefaultYAxis is CategoryAxis)
117.1391 +                {
117.1392 +                    this.DefaultXAxis.MinimumPadding = 0;
117.1393 +                }
117.1394 +
117.1395 +                if (createdlinearyaxis && this.DefaultXAxis is CategoryAxis)
117.1396 +                {
117.1397 +                    this.DefaultYAxis.MinimumPadding = 0;
117.1398 +                }
117.1399 +            }
117.1400 +
117.1401 +            bool areAxesRequired = false;
117.1402 +            foreach (var s in this.VisibleSeries)
117.1403 +            {
117.1404 +                if (s.AreAxesRequired())
117.1405 +                {
117.1406 +                    areAxesRequired = true;
117.1407 +                }
117.1408 +            }
117.1409 +
117.1410 +            if (areAxesRequired)
117.1411 +            {
117.1412 +                if (!this.Axes.Contains(this.DefaultXAxis))
117.1413 +                {
117.1414 +                    Debug.Assert(this.DefaultXAxis != null, "Default x-axis not created.");
117.1415 +                    if (this.DefaultXAxis != null)
117.1416 +                    {
117.1417 +                        this.Axes.Add(this.DefaultXAxis);
117.1418 +                    }
117.1419 +                }
117.1420 +
117.1421 +                if (!this.Axes.Contains(this.DefaultYAxis))
117.1422 +                {
117.1423 +                    Debug.Assert(this.DefaultYAxis != null, "Default y-axis not created.");
117.1424 +                    if (this.DefaultYAxis != null)
117.1425 +                    {
117.1426 +                        this.Axes.Add(this.DefaultYAxis);
117.1427 +                    }
117.1428 +                }
117.1429 +            }
117.1430 +
117.1431 +            // Update the x/index axes of series without axes defined
117.1432 +            foreach (var s in this.VisibleSeries)
117.1433 +            {
117.1434 +                if (s.AreAxesRequired())
117.1435 +                {
117.1436 +                    s.EnsureAxes();
117.1437 +                }
117.1438 +            }
117.1439 +
117.1440 +            // Update the x/index axes of annotations without axes defined
117.1441 +            foreach (var a in this.Annotations)
117.1442 +            {
117.1443 +                a.EnsureAxes();
117.1444 +            }
117.1445 +        }
117.1446 +
117.1447 +        /// <summary>
117.1448 +        /// Resets the default color index.
117.1449 +        /// </summary>
117.1450 +        private void ResetDefaultColor()
117.1451 +        {
117.1452 +            this.currentColorIndex = 0;
117.1453 +        }
117.1454 +
117.1455 +        /// <summary>
117.1456 +        /// Updates maximum and minimum values of the axes from values of all data series.
117.1457 +        /// </summary>
117.1458 +        /// <param name="isDataUpdated">
117.1459 +        /// if set to <c>true</c> , the data has been updated.
117.1460 +        /// </param>
117.1461 +        private void UpdateMaxMin(bool isDataUpdated)
117.1462 +        {
117.1463 +            if (isDataUpdated)
117.1464 +            {
117.1465 +                foreach (var a in this.Axes)
117.1466 +                {
117.1467 +                    a.ResetDataMaxMin();
117.1468 +                }
117.1469 +
117.1470 +                // data has been updated, so we need to calculate the max/min of the series again
117.1471 +                foreach (var s in this.VisibleSeries)
117.1472 +                {
117.1473 +                    s.UpdateMaxMin();
117.1474 +                }
117.1475 +            }
117.1476 +
117.1477 +            foreach (var s in this.VisibleSeries)
117.1478 +            {
117.1479 +                s.UpdateAxisMaxMin();
117.1480 +            }
117.1481 +
117.1482 +            foreach (var a in this.Axes)
117.1483 +            {
117.1484 +                a.UpdateActualMaxMin();
117.1485 +            }
117.1486 +        }
117.1487 +    }
117.1488 +}
117.1489 \ No newline at end of file
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/SelectablePlotElement.cs	Sat Jun 08 16:53:22 2013 +0000
   118.3 @@ -0,0 +1,159 @@
   118.4 +// --------------------------------------------------------------------------------------------------------------------
   118.5 +// <copyright file="SelectablePlotElement.cs" company="OxyPlot">
   118.6 +//   The MIT License (MIT)
   118.7 +//
   118.8 +//   Copyright (c) 2012 Oystein Bjorke
   118.9 +//
  118.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  118.11 +//   copy of this software and associated documentation files (the
  118.12 +//   "Software"), to deal in the Software without restriction, including
  118.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  118.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  118.15 +//   permit persons to whom the Software is furnished to do so, subject to
  118.16 +//   the following conditions:
  118.17 +//
  118.18 +//   The above copyright notice and this permission notice shall be included
  118.19 +//   in all copies or substantial portions of the Software.
  118.20 +//
  118.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  118.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  118.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  118.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  118.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  118.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  118.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  118.28 +// </copyright>
  118.29 +// <summary>
  118.30 +//   Represents a plot element that supports selection.
  118.31 +// </summary>
  118.32 +// --------------------------------------------------------------------------------------------------------------------
  118.33 +namespace OxyPlot
  118.34 +{
  118.35 +    using System;
  118.36 +
  118.37 +    /// <summary>
  118.38 +    /// Provides an abstract base class for plot elements that support selection.
  118.39 +    /// </summary>
  118.40 +    public abstract class SelectablePlotElement : PlotElement
  118.41 +    {
  118.42 +        /// <summary>
  118.43 +        /// The is selected.
  118.44 +        /// </summary>
  118.45 +        private bool isSelected;
  118.46 +
  118.47 +        /// <summary>
  118.48 +        /// Initializes a new instance of the <see cref="SelectablePlotElement"/> class.
  118.49 +        /// </summary>
  118.50 +        protected SelectablePlotElement()
  118.51 +        {
  118.52 +            this.Selectable = true;
  118.53 +            this.IsSelected = false;
  118.54 +        }
  118.55 +
  118.56 +        /// <summary>
  118.57 +        /// Occurs when the IsSelected property is changed.
  118.58 +        /// </summary>
  118.59 +        public event EventHandler Selected;
  118.60 +
  118.61 +        /// <summary>
  118.62 +        /// Gets or sets the index of the selected item (or -1 if all items are selected).
  118.63 +        /// </summary>
  118.64 +        /// <value>
  118.65 +        /// The index of the selected.
  118.66 +        /// </value>
  118.67 +        public int SelectedIndex { get; set; }
  118.68 +
  118.69 +        /// <summary>
  118.70 +        /// Gets or sets a value indicating whether this plot element is selected.
  118.71 +        /// </summary>
  118.72 +        public bool IsSelected
  118.73 +        {
  118.74 +            get
  118.75 +            {
  118.76 +                return this.isSelected;
  118.77 +            }
  118.78 +
  118.79 +            set
  118.80 +            {
  118.81 +                if (value == this.isSelected)
  118.82 +                {
  118.83 +                    return;
  118.84 +                }
  118.85 +
  118.86 +                this.isSelected = value;
  118.87 +                this.OnIsSelectedChanged();
  118.88 +            }
  118.89 +        }
  118.90 +
  118.91 +        /// <summary>
  118.92 +        /// Gets or sets a value indicating whether this plot element can be selected.
  118.93 +        /// </summary>
  118.94 +        public bool Selectable { get; set; }
  118.95 +
  118.96 +        /// <summary>
  118.97 +        /// Gets the actual selection color.
  118.98 +        /// </summary>
  118.99 +        /// <value> The actual selection color. </value>
 118.100 +        protected OxyColor ActualSelectedColor
 118.101 +        {
 118.102 +            get
 118.103 +            {
 118.104 +                if (this.PlotModel != null)
 118.105 +                {
 118.106 +                    return this.PlotModel.SelectionColor ?? PlotModel.DefaultSelectionColor;
 118.107 +                }
 118.108 +
 118.109 +                return PlotModel.DefaultSelectionColor;
 118.110 +            }
 118.111 +        }
 118.112 +
 118.113 +        /// <summary>
 118.114 +        /// Gets the selection color it the element is selected, or the specified color if it is not.
 118.115 +        /// </summary>
 118.116 +        /// <param name="originalColor">The unselected color of the element.</param>
 118.117 +        /// <param name="index">The index of the item to check (use -1 for all items).</param>
 118.118 +        /// <returns>
 118.119 +        /// A color.
 118.120 +        /// </returns>
 118.121 +        protected OxyColor GetSelectableColor(OxyColor originalColor, int index = -1)
 118.122 +        {
 118.123 +            if (originalColor == null)
 118.124 +            {
 118.125 +                return null;
 118.126 +            }
 118.127 +
 118.128 +            if (this.IsSelected && (index == -1 || index == this.SelectedIndex))
 118.129 +            {
 118.130 +                return this.ActualSelectedColor;
 118.131 +            }
 118.132 +
 118.133 +            return originalColor;
 118.134 +        }
 118.135 +
 118.136 +        /// <summary>
 118.137 +        /// Gets the selection fill color it the element is selected, or the specified fill color if it is not.
 118.138 +        /// </summary>
 118.139 +        /// <param name="originalColor">The unselected fill color of the element.</param>
 118.140 +        /// <param name="index">The index of the item to check (use -1 for all items).</param>
 118.141 +        /// <returns>
 118.142 +        /// A fill color.
 118.143 +        /// </returns>
 118.144 +        protected OxyColor GetSelectableFillColor(OxyColor originalColor, int index = -1)
 118.145 +        {
 118.146 +            return this.GetSelectableColor(originalColor, index);
 118.147 +        }
 118.148 +
 118.149 +        /// <summary>
 118.150 +        /// Raises the Selected event.
 118.151 +        /// </summary>
 118.152 +        protected void OnIsSelectedChanged()
 118.153 +        {
 118.154 +            var eh = this.Selected;
 118.155 +            if (eh != null)
 118.156 +            {
 118.157 +                eh(this, new EventArgs());
 118.158 +            }
 118.159 +        }
 118.160 +
 118.161 +    }
 118.162 +}
 118.163 \ No newline at end of file
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/External/OxyPlot/OxyPlot/PlotModel/UIPlotElement.cs	Sat Jun 08 16:53:22 2013 +0000
   119.3 @@ -0,0 +1,116 @@
   119.4 +// --------------------------------------------------------------------------------------------------------------------
   119.5 +// <copyright file="UIPlotElement.cs" company="OxyPlot">
   119.6 +//   The MIT License (MIT)
   119.7 +//
   119.8 +//   Copyright (c) 2012 Oystein Bjorke
   119.9 +//
  119.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  119.11 +//   copy of this software and associated documentation files (the
  119.12 +//   "Software"), to deal in the Software without restriction, including
  119.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  119.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  119.15 +//   permit persons to whom the Software is furnished to do so, subject to
  119.16 +//   the following conditions:
  119.17 +//
  119.18 +//   The above copyright notice and this permission notice shall be included
  119.19 +//   in all copies or substantial portions of the Software.
  119.20 +//
  119.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  119.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  119.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  119.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  119.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  119.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  119.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  119.28 +// </copyright>
  119.29 +// <summary>
  119.30 +//   Represents a plot element that handles mouse events.
  119.31 +// </summary>
  119.32 +// --------------------------------------------------------------------------------------------------------------------
  119.33 +namespace OxyPlot
  119.34 +{
  119.35 +    using System;
  119.36 +
  119.37 +    /// <summary>
  119.38 +    /// Provides an abstract base class for plot elements that handle mouse events.
  119.39 +    /// </summary>
  119.40 +    public abstract class UIPlotElement : SelectablePlotElement
  119.41 +    {
  119.42 +        /// <summary>
  119.43 +        /// Occurs when a mouse button is pressed down on the model.
  119.44 +        /// </summary>
  119.45 +        public event EventHandler<OxyMouseEventArgs> MouseDown;
  119.46 +
  119.47 +        /// <summary>
  119.48 +        /// Occurs when the mouse is moved on the plot element (only occurs after MouseDown).
  119.49 +        /// </summary>
  119.50 +        public event EventHandler<OxyMouseEventArgs> MouseMove;
  119.51 +
  119.52 +        /// <summary>
  119.53 +        /// Occurs when the mouse button is released on the plot element.
  119.54 +        /// </summary>
  119.55 +        public event EventHandler<OxyMouseEventArgs> MouseUp;
  119.56 +
  119.57 +        /// <summary>
  119.58 +        /// Raises the <see cref="MouseDown"/> event.
  119.59 +        /// </summary>
  119.60 +        /// <param name="sender">
  119.61 +        /// The sender.
  119.62 +        /// </param>
  119.63 +        /// <param name="e">
  119.64 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
  119.65 +        /// </param>
  119.66 +        protected internal virtual void OnMouseDown(object sender, OxyMouseEventArgs e)
  119.67 +        {
  119.68 +            if (this.MouseDown != null)
  119.69 +            {
  119.70 +                this.MouseDown(sender, e);
  119.71 +            }
  119.72 +        }
  119.73 +
  119.74 +        /// <summary>
  119.75 +        /// Raises the <see cref="MouseMove"/> event.
  119.76 +        /// </summary>
  119.77 +        /// <param name="sender">
  119.78 +        /// The sender.
  119.79 +        /// </param>
  119.80 +        /// <param name="e">
  119.81 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
  119.82 +        /// </param>
  119.83 +        protected internal virtual void OnMouseMove(object sender, OxyMouseEventArgs e)
  119.84 +        {
  119.85 +            if (this.MouseMove != null)
  119.86 +            {
  119.87 +                this.MouseMove(sender, e);
  119.88 +            }
  119.89 +        }
  119.90 +
  119.91 +        /// <summary>
  119.92 +        /// Raises the <see cref="MouseUp"/> event.
  119.93 +        /// </summary>
  119.94 +        /// <param name="sender">
  119.95 +        /// The sender.
  119.96 +        /// </param>
  119.97 +        /// <param name="e">
  119.98 +        /// The <see cref="OxyMouseEventArgs"/> instance containing the event data.
  119.99 +        /// </param>
 119.100 +        protected internal virtual void OnMouseUp(object sender, OxyMouseEventArgs e)
 119.101 +        {
 119.102 +            if (this.MouseUp != null)
 119.103 +            {
 119.104 +                this.MouseUp(sender, e);
 119.105 +            }
 119.106 +        }
 119.107 +
 119.108 +        /// <summary>
 119.109 +        /// Tests if the plot element is hit by the specified point.
 119.110 +        /// </summary>
 119.111 +        /// <param name="point">The point.</param>
 119.112 +        /// <param name="tolerance">The tolerance.</param>
 119.113 +        /// <returns>
 119.114 +        /// A hit test result.
 119.115 +        /// </returns>
 119.116 +        protected internal abstract HitTestResult HitTest(ScreenPoint point, double tolerance);
 119.117 +
 119.118 +    }
 119.119 +}
 119.120 \ No newline at end of file
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/External/OxyPlot/OxyPlot/Properties/AssemblyInfo.cs	Sat Jun 08 16:53:22 2013 +0000
   120.3 @@ -0,0 +1,10 @@
   120.4 +// --------------------------------------------------------------------------------------------------------------------
   120.5 +// <copyright file="AssemblyInfo.cs" company="OxyPlot">
   120.6 +//   http://oxyplot.codeplex.com, license: MIT
   120.7 +// </copyright>
   120.8 +// --------------------------------------------------------------------------------------------------------------------
   120.9 +
  120.10 +using System.Reflection;
  120.11 +
  120.12 +[assembly: AssemblyTitle("OxyPlot")]
  120.13 +[assembly: AssemblyDescription("OxyPlot core library")]
  120.14 \ No newline at end of file
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/External/OxyPlot/OxyPlot/Render/AngleAxisRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   121.3 @@ -0,0 +1,166 @@
   121.4 +// --------------------------------------------------------------------------------------------------------------------
   121.5 +// <copyright file="AngleAxisRenderer.cs" company="OxyPlot">
   121.6 +//   The MIT License (MIT)
   121.7 +//
   121.8 +//   Copyright (c) 2012 Oystein Bjorke
   121.9 +//
  121.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  121.11 +//   copy of this software and associated documentation files (the
  121.12 +//   "Software"), to deal in the Software without restriction, including
  121.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  121.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  121.15 +//   permit persons to whom the Software is furnished to do so, subject to
  121.16 +//   the following conditions:
  121.17 +//
  121.18 +//   The above copyright notice and this permission notice shall be included
  121.19 +//   in all copies or substantial portions of the Software.
  121.20 +//
  121.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  121.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  121.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  121.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  121.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  121.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  121.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  121.28 +// </copyright>
  121.29 +// <summary>
  121.30 +//   The angle axis renderer.
  121.31 +// </summary>
  121.32 +// --------------------------------------------------------------------------------------------------------------------
  121.33 +namespace OxyPlot
  121.34 +{
  121.35 +    using System;
  121.36 +
  121.37 +    using OxyPlot.Axes;
  121.38 +
  121.39 +    /// <summary>
  121.40 +    /// Provides functionality to render <see cref="AngleAxis"/>.
  121.41 +    /// </summary>
  121.42 +    public class AngleAxisRenderer : AxisRendererBase
  121.43 +    {
  121.44 +        /// <summary>
  121.45 +        /// Initializes a new instance of the <see cref="AngleAxisRenderer"/> class.
  121.46 +        /// </summary>
  121.47 +        /// <param name="rc">
  121.48 +        /// The render context.
  121.49 +        /// </param>
  121.50 +        /// <param name="plot">
  121.51 +        /// The plot.
  121.52 +        /// </param>
  121.53 +        public AngleAxisRenderer(IRenderContext rc, PlotModel plot)
  121.54 +            : base(rc, plot)
  121.55 +        {
  121.56 +        }
  121.57 +
  121.58 +        /// <summary>
  121.59 +        /// Renders the specified axis.
  121.60 +        /// </summary>
  121.61 +        /// <param name="axis">The axis.</param>
  121.62 +        /// <param name="pass">The render pass.</param>
  121.63 +        /// <exception cref="System.InvalidOperationException">Magnitude axis not defined.</exception>
  121.64 +        public override void Render(Axis axis, int pass)
  121.65 +        {
  121.66 +            base.Render(axis, pass);
  121.67 +
  121.68 +            var magnitudeAxis = this.Plot.DefaultMagnitudeAxis;
  121.69 +
  121.70 +            if (axis.RelatedAxis != null)
  121.71 +            {
  121.72 +                magnitudeAxis = axis.RelatedAxis as MagnitudeAxis;
  121.73 +            }
  121.74 +
  121.75 +            if (magnitudeAxis == null)
  121.76 +            {
  121.77 +                throw new InvalidOperationException("Magnitude axis not defined.");
  121.78 +            }
  121.79 +
  121.80 +            double eps = axis.MinorStep * 1e-3;
  121.81 +
  121.82 +            if (axis.ShowMinorTicks)
  121.83 +            {
  121.84 +                foreach (double value in this.MinorTickValues)
  121.85 +                {
  121.86 +                    if (value < axis.ActualMinimum - eps || value > axis.ActualMaximum + eps)
  121.87 +                    {
  121.88 +                        continue;
  121.89 +                    }
  121.90 +
  121.91 +                    if (this.MajorTickValues.Contains(value))
  121.92 +                    {
  121.93 +                        continue;
  121.94 +                    }
  121.95 +
  121.96 +                    var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
  121.97 +
  121.98 +                    if (this.MinorPen != null)
  121.99 +                    {
 121.100 +                        this.rc.DrawLine(magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, pt.x, pt.y, this.MinorPen, false);
 121.101 +                    }
 121.102 +                }
 121.103 +            }
 121.104 +
 121.105 +            var angleAxis = (AngleAxis)axis;
 121.106 +            bool isFullCircle = Math.Abs(Math.Abs(angleAxis.EndAngle - angleAxis.StartAngle) - 360) < 1e-6;
 121.107 +
 121.108 +            foreach (double value in this.MajorTickValues)
 121.109 +            {
 121.110 +                // skip the last value (overlapping with the first)
 121.111 +                if (isFullCircle && value > axis.ActualMaximum - eps)
 121.112 +                {
 121.113 +                    continue;
 121.114 +                }
 121.115 +
 121.116 +                if (value < axis.ActualMinimum - eps || value > axis.ActualMaximum + eps)
 121.117 +                {
 121.118 +                    continue;
 121.119 +                }
 121.120 +
 121.121 +                ScreenPoint pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
 121.122 +                if (this.MajorPen != null)
 121.123 +                {
 121.124 +                    this.rc.DrawLine(
 121.125 +                        magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, pt.x, pt.y, this.MajorPen, false);
 121.126 +                }
 121.127 +            }
 121.128 +
 121.129 +            foreach (double value in this.MajorLabelValues)
 121.130 +            {
 121.131 +                // skip the last value (overlapping with the first)
 121.132 +                if (isFullCircle && value > axis.ActualMaximum - eps)
 121.133 +                {
 121.134 +                    continue;
 121.135 +                }
 121.136 +
 121.137 +                var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis);
 121.138 +                double angle = Math.Atan2(pt.y - magnitudeAxis.MidPoint.y, pt.x - magnitudeAxis.MidPoint.x);
 121.139 +
 121.140 +                // add some margin
 121.141 +                pt.x += Math.Cos(angle) * axis.AxisTickToLabelDistance;
 121.142 +                pt.y += Math.Sin(angle) * axis.AxisTickToLabelDistance;
 121.143 +
 121.144 +                // Convert to degrees
 121.145 +                angle *= 180 / Math.PI;
 121.146 +
 121.147 +                string text = axis.FormatValue(value);
 121.148 +
 121.149 +                var ha = HorizontalAlignment.Left;
 121.150 +                var va = VerticalAlignment.Middle;
 121.151 +
 121.152 +                if (Math.Abs(Math.Abs(angle) - 90) < 10)
 121.153 +                {
 121.154 +                    ha = HorizontalAlignment.Center;
 121.155 +                    va = angle > 90 ? VerticalAlignment.Top : VerticalAlignment.Bottom;
 121.156 +                    angle = 0;
 121.157 +                }
 121.158 +                else if (angle > 90 || angle < -90)
 121.159 +                {
 121.160 +                    angle -= 180;
 121.161 +                    ha = HorizontalAlignment.Right;
 121.162 +                }
 121.163 +
 121.164 +                this.rc.DrawMathText(
 121.165 +                    pt, text, axis.ActualTextColor, axis.ActualFont, axis.ActualFontSize, axis.ActualFontWeight, angle, ha, va);
 121.166 +            }
 121.167 +        }
 121.168 +    }
 121.169 +}
 121.170 \ No newline at end of file
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/External/OxyPlot/OxyPlot/Render/AxisRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   122.3 @@ -0,0 +1,532 @@
   122.4 +// --------------------------------------------------------------------------------------------------------------------
   122.5 +// <copyright file="AxisRenderer.cs" company="OxyPlot">
   122.6 +//   The MIT License (MIT)
   122.7 +//
   122.8 +//   Copyright (c) 2012 Oystein Bjorke
   122.9 +//
  122.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  122.11 +//   copy of this software and associated documentation files (the
  122.12 +//   "Software"), to deal in the Software without restriction, including
  122.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  122.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  122.15 +//   permit persons to whom the Software is furnished to do so, subject to
  122.16 +//   the following conditions:
  122.17 +//
  122.18 +//   The above copyright notice and this permission notice shall be included
  122.19 +//   in all copies or substantial portions of the Software.
  122.20 +//
  122.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  122.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  122.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  122.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  122.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  122.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  122.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  122.28 +// </copyright>
  122.29 +// --------------------------------------------------------------------------------------------------------------------
  122.30 +using System;
  122.31 +using System.Collections.Generic;
  122.32 +
  122.33 +namespace OxyPlot
  122.34 +{
  122.35 +    public class AxisRenderer
  122.36 +    {
  122.37 +        private const double AXIS_LEGEND_DIST = 4; // distance from axis number to axis legend
  122.38 +        private const double TICK_DIST = 8; // distance from axis tick to number
  122.39 +
  122.40 +        private OxyPen extraPen;
  122.41 +        private OxyPen majorPen;
  122.42 +        private OxyPen majorTickPen;
  122.43 +
  122.44 +        private ICollection<double> majorTickValues;
  122.45 +        private OxyPen minorPen;
  122.46 +        private OxyPen minorTickPen;
  122.47 +        private ICollection<double> minorTickValues;
  122.48 +        private OxyPen zeroPen;
  122.49 +
  122.50 +        protected readonly PlotModel Plot;
  122.51 +        protected readonly IRenderContext rc;
  122.52 +
  122.53 +        public AxisRenderer(IRenderContext rc, PlotModel plot)
  122.54 +        {
  122.55 +            this.Plot = plot;
  122.56 +            this.rc = rc;
  122.57 +        }
  122.58 +
  122.59 +        public void Render(Axis axis)
  122.60 +        {
  122.61 +            if (axis == null)
  122.62 +                return;
  122.63 +
  122.64 +            axis.GetTickValues(out majorTickValues, out minorTickValues);
  122.65 +
  122.66 +            CreatePens(axis);
  122.67 +
  122.68 +            if (axis.IsHorizontal())
  122.69 +            {
  122.70 +                RenderHorizontalAxis(axis, Plot.DefaultYAxis);
  122.71 +            }
  122.72 +            if (axis.IsVertical())
  122.73 +            {
  122.74 +                RenderVerticalAxis(axis, Plot.DefaultXAxis);
  122.75 +            }
  122.76 +            if (axis.Position == AxisPosition.Angle)
  122.77 +            {
  122.78 +                RenderAngleAxis(axis, Plot.DefaultMagnitudeAxis);
  122.79 +            }
  122.80 +            if (axis.Position == AxisPosition.Magnitude)
  122.81 +            {
  122.82 +                RenderMagnitudeAxis(axis, Plot.DefaultAngleAxis);
  122.83 +            }
  122.84 +        }
  122.85 +
  122.86 +        private void RenderMagnitudeAxis(Axis axis, Axis angleAxis)
  122.87 +        {
  122.88 +            if (axis.RelatedAxis != null)
  122.89 +                angleAxis = axis.RelatedAxis;
  122.90 +
  122.91 +            if (axis.ShowMinorTicks)
  122.92 +            {
  122.93 +                //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
  122.94 +
  122.95 +                foreach (double xValue in minorTickValues)
  122.96 +                {
  122.97 +                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
  122.98 +                    {
  122.99 +                        continue;
 122.100 +                    }
 122.101 +
 122.102 +                    if (majorTickValues.Contains(xValue))
 122.103 +                    {
 122.104 +                        continue;
 122.105 +                    }
 122.106 +
 122.107 +                    var pts = new List<ScreenPoint>();
 122.108 +                    for (double th = angleAxis.ActualMinimum;
 122.109 +                         th <= angleAxis.ActualMaximum;
 122.110 +                         th += angleAxis.MinorStep*0.1)
 122.111 +                    {
 122.112 +                        pts.Add(axis.Transform(xValue, th, angleAxis));
 122.113 +                    }
 122.114 +
 122.115 +                    if (minorPen != null)
 122.116 +                    {
 122.117 +                        rc.DrawLine(pts, minorPen.Color, minorPen.Thickness, minorPen.DashArray);
 122.118 +                    }
 122.119 +                    // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
 122.120 +                }
 122.121 +            }
 122.122 +
 122.123 +            //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
 122.124 +
 122.125 +            foreach (double xValue in majorTickValues)
 122.126 +            {
 122.127 +                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 122.128 +                {
 122.129 +                    continue;
 122.130 +                }
 122.131 +
 122.132 +                var pts = new List<ScreenPoint>();
 122.133 +                for (double th = angleAxis.ActualMinimum; th <= angleAxis.ActualMaximum; th += angleAxis.MinorStep*0.1)
 122.134 +                {
 122.135 +                    pts.Add(axis.Transform(xValue, th, angleAxis));
 122.136 +                }
 122.137 +
 122.138 +                if (majorPen != null)
 122.139 +                {
 122.140 +                    rc.DrawLine(pts, majorPen.Color, majorPen.Thickness, majorPen.DashArray);
 122.141 +                }
 122.142 +
 122.143 +                // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
 122.144 +
 122.145 +                //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
 122.146 +                //string text = axis.FormatValue(xValue);
 122.147 +                //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
 122.148 +
 122.149 +                //rc.DrawText(pt, text, plot.TextColor,
 122.150 +                //            axis.FontFamily, axis.FontSize, axis.FontWeight,
 122.151 +                //            axis.Angle,
 122.152 +                //            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
 122.153 +
 122.154 +                //maxh = Math.Max(maxh, h);
 122.155 +            }
 122.156 +        }
 122.157 +
 122.158 +        private void RenderAngleAxis(Axis axis, Axis magnitudeAxis)
 122.159 +        {
 122.160 +            if (axis.RelatedAxis != null)
 122.161 +                magnitudeAxis = axis.RelatedAxis;
 122.162 +
 122.163 +            if (axis.ShowMinorTicks)
 122.164 +            {
 122.165 +                //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
 122.166 +
 122.167 +                foreach (double xValue in minorTickValues)
 122.168 +                {
 122.169 +                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 122.170 +                    {
 122.171 +                        continue;
 122.172 +                    }
 122.173 +
 122.174 +                    if (majorTickValues.Contains(xValue))
 122.175 +                    {
 122.176 +                        continue;
 122.177 +                    }
 122.178 +
 122.179 +                    var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);
 122.180 +
 122.181 +                    if (minorPen != null)
 122.182 +                    {
 122.183 +                        RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, minorPen, false);
 122.184 +                    }
 122.185 +                    // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
 122.186 +                }
 122.187 +            }
 122.188 +
 122.189 +            //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
 122.190 +
 122.191 +            foreach (double xValue in majorTickValues)
 122.192 +            {
 122.193 +                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 122.194 +                {
 122.195 +                    continue;
 122.196 +                }
 122.197 +
 122.198 +                var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);
 122.199 +
 122.200 +                if (majorPen != null)
 122.201 +                {
 122.202 +                    RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, majorPen, false);
 122.203 +                }
 122.204 +                // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
 122.205 +
 122.206 +                //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
 122.207 +                //string text = axis.FormatValue(xValue);
 122.208 +                //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
 122.209 +
 122.210 +                //rc.DrawText(pt, text, plot.TextColor,
 122.211 +                //            axis.FontFamily, axis.FontSize, axis.FontWeight,
 122.212 +                //            axis.Angle,
 122.213 +                //            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
 122.214 +
 122.215 +                //maxh = Math.Max(maxh, h);
 122.216 +            }
 122.217 +        }
 122.218 +
 122.219 +        private void RenderLine(double x0, double y0, double x1, double y1, OxyPen pen, bool aliased = true)
 122.220 +        {
 122.221 +            if (pen == null)
 122.222 +                return;
 122.223 +
 122.224 +            rc.DrawLine(new[]
 122.225 +                            {
 122.226 +                                new ScreenPoint(x0, y0),
 122.227 +                                new ScreenPoint(x1, y1)
 122.228 +                            }, pen.Color, pen.Thickness, pen.DashArray, aliased);
 122.229 +        }
 122.230 +
 122.231 +        private void GetVerticalTickPositions(Axis axis, TickStyle glt, double ticksize,
 122.232 +                                              out double y0, out double y1)
 122.233 +        {
 122.234 +            y0 = 0;
 122.235 +            y1 = 0;
 122.236 +            bool istop = axis.Position == AxisPosition.Top;
 122.237 +            double topsign = istop ? -1 : 1;
 122.238 +            switch (glt)
 122.239 +            {
 122.240 +                case TickStyle.Crossing:
 122.241 +                    y0 = -ticksize*topsign;
 122.242 +                    y1 = ticksize*topsign;
 122.243 +                    break;
 122.244 +                case TickStyle.Inside:
 122.245 +                    y0 = -ticksize*topsign;
 122.246 +                    break;
 122.247 +                case TickStyle.Outside:
 122.248 +                    y1 = ticksize*topsign;
 122.249 +                    break;
 122.250 +            }
 122.251 +        }
 122.252 +
 122.253 +        private void GetHorizontalTickPositions(Axis axis, TickStyle glt, double ticksize, out double x0,
 122.254 +                                                out double x1)
 122.255 +        {
 122.256 +            x0 = 0;
 122.257 +            x1 = 0;
 122.258 +            bool isLeft = axis.Position == AxisPosition.Left;
 122.259 +            double leftSign = isLeft ? -1 : 1;
 122.260 +            switch (glt)
 122.261 +            {
 122.262 +                case TickStyle.Crossing:
 122.263 +                    x0 = -ticksize*leftSign;
 122.264 +                    x1 = ticksize*leftSign;
 122.265 +                    break;
 122.266 +                case TickStyle.Inside:
 122.267 +                    x0 = -ticksize*leftSign;
 122.268 +                    break;
 122.269 +                case TickStyle.Outside:
 122.270 +                    x1 = ticksize*leftSign;
 122.271 +                    break;
 122.272 +            }
 122.273 +        }
 122.274 +
 122.275 +        public void CreatePens(Axis axis)
 122.276 +        {
 122.277 +            minorPen = CreatePen(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
 122.278 +            majorPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
 122.279 +            minorTickPen = CreatePen(axis.TicklineColor, axis.MinorGridlineThickness, LineStyle.Solid);
 122.280 +            majorTickPen = CreatePen(axis.TicklineColor, axis.MajorGridlineThickness, LineStyle.Solid);
 122.281 +            zeroPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
 122.282 +            extraPen = CreatePen(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
 122.283 +        }
 122.284 +
 122.285 +        private void RenderHorizontalAxis(Axis axis, Axis perpendicularAxis)
 122.286 +        {
 122.287 +            double y = Plot.Bounds.Bottom;
 122.288 +            switch (axis.Position)
 122.289 +            {
 122.290 +                case AxisPosition.Top:
 122.291 +                    y = Plot.Bounds.Top;
 122.292 +                    break;
 122.293 +                case AxisPosition.Bottom:
 122.294 +                    y = Plot.Bounds.Bottom;
 122.295 +                    break;
 122.296 +            }
 122.297 +            if (axis.PositionAtZeroCrossing)
 122.298 +            {
 122.299 +                y = perpendicularAxis.TransformX(0);
 122.300 +            }
 122.301 +
 122.302 +            double y0, y1;
 122.303 +
 122.304 +            if (axis.ShowMinorTicks)
 122.305 +            {
 122.306 +                GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
 122.307 +
 122.308 +                foreach (double xValue in minorTickValues)
 122.309 +                {
 122.310 +                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 122.311 +                    {
 122.312 +                        continue;
 122.313 +                    }
 122.314 +
 122.315 +                    if (majorTickValues.Contains(xValue))
 122.316 +                    {
 122.317 +                        continue;
 122.318 +                    }
 122.319 +
 122.320 +                    double x = axis.TransformX(xValue);
 122.321 +                    if (minorPen != null)
 122.322 +                    {
 122.323 +                        RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, minorPen);
 122.324 +                    }
 122.325 +                    RenderLine(x, y + y0, x, y + y1, minorTickPen);
 122.326 +                }
 122.327 +            }
 122.328 +
 122.329 +            GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
 122.330 +
 122.331 +            double maxh = 0;
 122.332 +            bool istop = axis.Position == AxisPosition.Top;
 122.333 +            foreach (double xValue in majorTickValues)
 122.334 +            {
 122.335 +                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 122.336 +                {
 122.337 +                    continue;
 122.338 +                }
 122.339 +
 122.340 +                double x = axis.TransformX(xValue);
 122.341 +
 122.342 +                if (majorPen != null)
 122.343 +                {
 122.344 +                    RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);
 122.345 +                }
 122.346 +                RenderLine(x, y + y0, x, y + y1, majorTickPen);
 122.347 +
 122.348 +                if (xValue == 0 && axis.PositionAtZeroCrossing)
 122.349 +                    continue;
 122.350 +
 122.351 +                var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
 122.352 +                string text = axis.FormatValue(xValue);
 122.353 +                double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
 122.354 +
 122.355 +                rc.DrawText(pt, text, Plot.TextColor,
 122.356 +                            axis.FontFamily, axis.FontSize, axis.FontWeight,
 122.357 +                            axis.Angle,
 122.358 +                            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);
 122.359 +
 122.360 +                maxh = Math.Max(maxh, h);
 122.361 +            }
 122.362 +
 122.363 +            if (axis.PositionAtZeroCrossing)
 122.364 +            {
 122.365 +                double x = axis.TransformX(0);
 122.366 +                RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, zeroPen);
 122.367 +            }
 122.368 +
 122.369 +            if (axis.ExtraGridlines != null)
 122.370 +            {
 122.371 +                foreach (double x in axis.ExtraGridlines)
 122.372 +                {
 122.373 +                    if (!IsWithin(x, axis.ActualMinimum, axis.ActualMaximum))
 122.374 +                        continue;
 122.375 +                    double sx = axis.TransformX(x);
 122.376 +                    RenderLine(sx, Plot.Bounds.Top, sx, Plot.Bounds.Bottom, extraPen);
 122.377 +                }
 122.378 +            }
 122.379 +
 122.380 +            // The horizontal axis line
 122.381 +            RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);
 122.382 +
 122.383 +            // The horizontal axis legend (centered horizontally)
 122.384 +            double legendX = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);
 122.385 +            HorizontalTextAlign halign = HorizontalTextAlign.Center;
 122.386 +            VerticalTextAlign valign = VerticalTextAlign.Bottom;
 122.387 +
 122.388 +            if (axis.PositionAtZeroCrossing)
 122.389 +            {
 122.390 +                legendX = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
 122.391 +            }
 122.392 +
 122.393 +            double legendY = rc.Height - AXIS_LEGEND_DIST;
 122.394 +            if (istop)
 122.395 +            {
 122.396 +                legendY = AXIS_LEGEND_DIST;
 122.397 +                valign = VerticalTextAlign.Top;
 122.398 +            }
 122.399 +            rc.DrawText(new ScreenPoint(legendX, legendY),
 122.400 +                        axis.Title, Plot.TextColor,
 122.401 +                        axis.FontFamily, axis.FontSize, axis.FontWeight, 0, halign, valign);
 122.402 +        }
 122.403 +
 122.404 +        private OxyPen CreatePen(OxyColor c, double th, LineStyle ls)
 122.405 +        {
 122.406 +            if (ls == LineStyle.None || th == 0)
 122.407 +                return null;
 122.408 +            return new OxyPen(c, th, ls);
 122.409 +        }
 122.410 +
 122.411 +        private void RenderVerticalAxis(Axis axis, Axis perpendicularAxis)
 122.412 +        {
 122.413 +            double x = Plot.Bounds.Left;
 122.414 +            switch (axis.Position)
 122.415 +            {
 122.416 +                case AxisPosition.Left:
 122.417 +                    x = Plot.Bounds.Left;
 122.418 +                    break;
 122.419 +                case AxisPosition.Right:
 122.420 +                    x = Plot.Bounds.Right;
 122.421 +                    break;
 122.422 +            }
 122.423 +            if (axis.PositionAtZeroCrossing)
 122.424 +                x = perpendicularAxis.TransformX(0);
 122.425 +
 122.426 +            double x0, x1;
 122.427 +
 122.428 +            if (axis.ShowMinorTicks)
 122.429 +            {
 122.430 +                GetHorizontalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out x0, out x1);
 122.431 +                foreach (double yValue in minorTickValues)
 122.432 +                {
 122.433 +                    if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
 122.434 +                    {
 122.435 +                        continue;
 122.436 +                    }
 122.437 +
 122.438 +                    if (majorTickValues.Contains(yValue))
 122.439 +                    {
 122.440 +                        continue;
 122.441 +                    }
 122.442 +                    double y = axis.TransformX(yValue);
 122.443 +
 122.444 +                    if (minorPen != null)
 122.445 +                    {
 122.446 +                        RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, minorPen);
 122.447 +                    }
 122.448 +
 122.449 +                    RenderLine(x + x0, y, x + x1, y, minorTickPen);
 122.450 +                }
 122.451 +            }
 122.452 +
 122.453 +            GetHorizontalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out x0, out x1);
 122.454 +            double maxw = 0;
 122.455 +
 122.456 +            bool isleft = axis.Position == AxisPosition.Left;
 122.457 +
 122.458 +            foreach (double yValue in majorTickValues)
 122.459 +            {
 122.460 +                if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
 122.461 +                    continue;
 122.462 +
 122.463 +                double y = axis.TransformX(yValue);
 122.464 +
 122.465 +                if (majorPen != null)
 122.466 +                {
 122.467 +                    RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);
 122.468 +                }
 122.469 +
 122.470 +                RenderLine(x + x0, y, x + x1, y, majorTickPen);
 122.471 +
 122.472 +                if (yValue == 0 && axis.PositionAtZeroCrossing)
 122.473 +                    continue;
 122.474 +
 122.475 +                var pt = new ScreenPoint(isleft ? x + x1 - TICK_DIST : x + x1 + TICK_DIST, y);
 122.476 +                string text = axis.FormatValue(yValue);
 122.477 +                double w = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
 122.478 +                rc.DrawText(pt, text, Plot.TextColor,
 122.479 +                            axis.FontFamily, axis.FontSize, axis.FontWeight,
 122.480 +                            axis.Angle,
 122.481 +                            isleft ? HorizontalTextAlign.Right : HorizontalTextAlign.Left, VerticalTextAlign.Middle);
 122.482 +                maxw = Math.Max(maxw, w);
 122.483 +            }
 122.484 +
 122.485 +            if (axis.PositionAtZeroCrossing)
 122.486 +            {
 122.487 +                double y = axis.TransformX(0);
 122.488 +                RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, zeroPen);
 122.489 +            }
 122.490 +
 122.491 +            if (axis.ExtraGridlines != null)
 122.492 +                foreach (double y in axis.ExtraGridlines)
 122.493 +                {
 122.494 +                    if (!IsWithin(y, axis.ActualMinimum, axis.ActualMaximum))
 122.495 +                        continue;
 122.496 +                    double sy = axis.TransformX(y);
 122.497 +                    RenderLine(Plot.Bounds.Left, sy, Plot.Bounds.Right, sy, extraPen);
 122.498 +                }
 122.499 +
 122.500 +            RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);
 122.501 +
 122.502 +            double ymid = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);
 122.503 +
 122.504 +            HorizontalTextAlign halign = HorizontalTextAlign.Center;
 122.505 +            VerticalTextAlign valign = VerticalTextAlign.Top;
 122.506 +
 122.507 +            if (axis.PositionAtZeroCrossing)
 122.508 +            {
 122.509 +                ymid = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
 122.510 +                // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
 122.511 +            }
 122.512 +
 122.513 +            if (isleft)
 122.514 +            {
 122.515 +                x = AXIS_LEGEND_DIST;
 122.516 +            }
 122.517 +            else
 122.518 +            {
 122.519 +                x = rc.Width - AXIS_LEGEND_DIST;
 122.520 +                valign = VerticalTextAlign.Bottom;
 122.521 +            }
 122.522 +
 122.523 +            rc.DrawText(new ScreenPoint(x, ymid), axis.Title, Plot.TextColor,
 122.524 +                        axis.FontFamily, axis.FontSize, axis.FontWeight,
 122.525 +                        -90, halign, valign);
 122.526 +        }
 122.527 +
 122.528 +        private bool IsWithin(double d, double min, double max)
 122.529 +        {
 122.530 +            if (d < min) return false;
 122.531 +            if (d > max) return false;
 122.532 +            return true;
 122.533 +        }
 122.534 +    }
 122.535 +}
 122.536 \ No newline at end of file
   123.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.2 +++ b/External/OxyPlot/OxyPlot/Render/AxisRendererBase.cs	Sat Jun 08 16:53:22 2013 +0000
   123.3 @@ -0,0 +1,217 @@
   123.4 +// --------------------------------------------------------------------------------------------------------------------
   123.5 +// <copyright file="AxisRendererBase.cs" company="OxyPlot">
   123.6 +//   The MIT License (MIT)
   123.7 +//
   123.8 +//   Copyright (c) 2012 Oystein Bjorke
   123.9 +//
  123.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  123.11 +//   copy of this software and associated documentation files (the
  123.12 +//   "Software"), to deal in the Software without restriction, including
  123.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  123.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  123.15 +//   permit persons to whom the Software is furnished to do so, subject to
  123.16 +//   the following conditions:
  123.17 +//
  123.18 +//   The above copyright notice and this permission notice shall be included
  123.19 +//   in all copies or substantial portions of the Software.
  123.20 +//
  123.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  123.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  123.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  123.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  123.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  123.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  123.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  123.28 +// </copyright>
  123.29 +// <summary>
  123.30 +//   The axis renderer base.
  123.31 +// </summary>
  123.32 +// --------------------------------------------------------------------------------------------------------------------
  123.33 +namespace OxyPlot
  123.34 +{
  123.35 +    using System.Collections.Generic;
  123.36 +
  123.37 +    using OxyPlot.Axes;
  123.38 +
  123.39 +    /// <summary>
  123.40 +    /// Provides an abstract base class for axis renderers.
  123.41 +    /// </summary>
  123.42 +    public abstract class AxisRendererBase
  123.43 +    {
  123.44 +        /// <summary>
  123.45 +        /// The plot.
  123.46 +        /// </summary>
  123.47 +        protected readonly PlotModel Plot;
  123.48 +
  123.49 +        /// <summary>
  123.50 +        /// The render context.
  123.51 +        /// </summary>
  123.52 +        protected readonly IRenderContext rc;
  123.53 +
  123.54 +        /// <summary>
  123.55 +        /// The axis lines pen.
  123.56 +        /// </summary>
  123.57 +        protected OxyPen AxislinePen;
  123.58 +
  123.59 +        /// <summary>
  123.60 +        /// The extra grid lines pen.
  123.61 +        /// </summary>
  123.62 +        protected OxyPen ExtraPen;
  123.63 +
  123.64 +        /// <summary>
  123.65 +        /// The major label values.
  123.66 +        /// </summary>
  123.67 +        protected IList<double> MajorLabelValues;
  123.68 +
  123.69 +        /// <summary>
  123.70 +        /// The major grid lines pen.
  123.71 +        /// </summary>
  123.72 +        protected OxyPen MajorPen;
  123.73 +
  123.74 +        /// <summary>
  123.75 +        /// The major tick pen.
  123.76 +        /// </summary>
  123.77 +        protected OxyPen MajorTickPen;
  123.78 +
  123.79 +        /// <summary>
  123.80 +        /// The major tick values.
  123.81 +        /// </summary>
  123.82 +        protected IList<double> MajorTickValues;
  123.83 +
  123.84 +        /// <summary>
  123.85 +        /// The minor grid lines pen.
  123.86 +        /// </summary>
  123.87 +        protected OxyPen MinorPen;
  123.88 +
  123.89 +        /// <summary>
  123.90 +        /// The minor tick pen.
  123.91 +        /// </summary>
  123.92 +        protected OxyPen MinorTickPen;
  123.93 +
  123.94 +        /// <summary>
  123.95 +        /// The minor tick values.
  123.96 +        /// </summary>
  123.97 +        protected IList<double> MinorTickValues;
  123.98 +
  123.99 +        /// <summary>
 123.100 +        /// The zero grid line pen.
 123.101 +        /// </summary>
 123.102 +        protected OxyPen ZeroPen;
 123.103 +
 123.104 +        /// <summary>
 123.105 +        /// Initializes a new instance of the <see cref="AxisRendererBase"/> class.
 123.106 +        /// </summary>
 123.107 +        /// <param name="rc">
 123.108 +        /// The render context.
 123.109 +        /// </param>
 123.110 +        /// <param name="plot">
 123.111 +        /// The plot.
 123.112 +        /// </param>
 123.113 +        protected AxisRendererBase(IRenderContext rc, PlotModel plot)
 123.114 +        {
 123.115 +            this.Plot = plot;
 123.116 +            this.rc = rc;
 123.117 +        }
 123.118 +
 123.119 +        /// <summary>
 123.120 +        /// Renders the specified axis.
 123.121 +        /// </summary>
 123.122 +        /// <param name="axis">The axis.</param>
 123.123 +        /// <param name="pass">The pass.</param>
 123.124 +        public virtual void Render(Axis axis, int pass)
 123.125 +        {
 123.126 +            if (axis == null)
 123.127 +            {
 123.128 +                return;
 123.129 +            }
 123.130 +
 123.131 +            axis.GetTickValues(out this.MajorLabelValues, out this.MajorTickValues, out this.MinorTickValues);
 123.132 +            this.CreatePens(axis);
 123.133 +        }
 123.134 +
 123.135 +        /// <summary>
 123.136 +        /// The create pens.
 123.137 +        /// </summary>
 123.138 +        /// <param name="axis">
 123.139 +        /// The axis.
 123.140 +        /// </param>
 123.141 +        protected void CreatePens(Axis axis)
 123.142 +        {
 123.143 +            this.MinorPen = OxyPen.Create(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
 123.144 +            this.MajorPen = OxyPen.Create(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
 123.145 +            this.MinorTickPen = OxyPen.Create(axis.TicklineColor, axis.MinorGridlineThickness);
 123.146 +            this.MajorTickPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
 123.147 +            this.ZeroPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
 123.148 +            this.ExtraPen = OxyPen.Create(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
 123.149 +            this.AxislinePen = OxyPen.Create(axis.AxislineColor, axis.AxislineThickness, axis.AxislineStyle);
 123.150 +        }
 123.151 +
 123.152 +        /// <summary>
 123.153 +        /// The get tick positions.
 123.154 +        /// </summary>
 123.155 +        /// <param name="axis">
 123.156 +        /// The axis.
 123.157 +        /// </param>
 123.158 +        /// <param name="glt">
 123.159 +        /// The glt.
 123.160 +        /// </param>
 123.161 +        /// <param name="ticksize">
 123.162 +        /// The ticksize.
 123.163 +        /// </param>
 123.164 +        /// <param name="position">
 123.165 +        /// The position.
 123.166 +        /// </param>
 123.167 +        /// <param name="x0">
 123.168 +        /// The x 0.
 123.169 +        /// </param>
 123.170 +        /// <param name="x1">
 123.171 +        /// The x 1.
 123.172 +        /// </param>
 123.173 +        protected void GetTickPositions(
 123.174 +            Axis axis, TickStyle glt, double ticksize, AxisPosition position, out double x0, out double x1)
 123.175 +        {
 123.176 +            x0 = 0;
 123.177 +            x1 = 0;
 123.178 +            bool isTopOrLeft = position == AxisPosition.Top || position == AxisPosition.Left;
 123.179 +            double sign = isTopOrLeft ? -1 : 1;
 123.180 +            switch (glt)
 123.181 +            {
 123.182 +                case TickStyle.Crossing:
 123.183 +                    x0 = -ticksize * sign * 0.75;
 123.184 +                    x1 = ticksize * sign * 0.75;
 123.185 +                    break;
 123.186 +                case TickStyle.Inside:
 123.187 +                    x0 = -ticksize * sign;
 123.188 +                    break;
 123.189 +                case TickStyle.Outside:
 123.190 +                    x1 = ticksize * sign;
 123.191 +                    break;
 123.192 +            }
 123.193 +        }
 123.194 +
 123.195 +        /// <summary>
 123.196 +        /// Determines whether the specified value is within the specified range.
 123.197 +        /// </summary>
 123.198 +        /// <param name="d">The value to check.</param>
 123.199 +        /// <param name="min">The minium value of the range.</param>
 123.200 +        /// <param name="max">The maximum value of the range.</param>
 123.201 +        /// <returns>
 123.202 +        ///  <c>true</c> if the specified value is within the range; otherwise, <c>false</c>.
 123.203 +        /// </returns>
 123.204 +        protected bool IsWithin(double d, double min, double max)
 123.205 +        {
 123.206 +            if (d < min)
 123.207 +            {
 123.208 +                return false;
 123.209 +            }
 123.210 +
 123.211 +            if (d > max)
 123.212 +            {
 123.213 +                return false;
 123.214 +            }
 123.215 +
 123.216 +            return true;
 123.217 +        }
 123.218 +
 123.219 +    }
 123.220 +}
 123.221 \ No newline at end of file
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/External/OxyPlot/OxyPlot/Render/HorizontalAndVerticalAxisRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   124.3 @@ -0,0 +1,642 @@
   124.4 +// --------------------------------------------------------------------------------------------------------------------
   124.5 +// <copyright file="HorizontalAndVerticalAxisRenderer.cs" company="OxyPlot">
   124.6 +//   The MIT License (MIT)
   124.7 +//   
   124.8 +//   Copyright (c) 2012 Oystein Bjorke
   124.9 +//   
  124.10 +//   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
  124.11 +//   associated documentation files (the "Software"), to deal in the Software without restriction,
  124.12 +//   including without limitation the rights to use, copy, modify, merge, publish, distribute,
  124.13 +//   sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
  124.14 +//   furnished to do so, subject to the following conditions:
  124.15 +//   
  124.16 +//   The above copyright notice and this permission notice shall be included in all copies or substantial
  124.17 +//   portions of the Software.
  124.18 +//   
  124.19 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
  124.20 +//   NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  124.21 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  124.22 +//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  124.23 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  124.24 +// </copyright>
  124.25 +// <summary>
  124.26 +//   Rendering helper class for horizontal and vertical axes (both linear and logarithmic)
  124.27 +// </summary>
  124.28 +// --------------------------------------------------------------------------------------------------------------------
  124.29 +namespace OxyPlot
  124.30 +{
  124.31 +    using System;
  124.32 +    using System.Collections.Generic;
  124.33 +    using System.Diagnostics;
  124.34 +
  124.35 +    using OxyPlot.Axes;
  124.36 +
  124.37 +    /// <summary>
  124.38 +    /// Preovides functionality to render horizontal and vertical axes.
  124.39 +    /// </summary>
  124.40 +    public class HorizontalAndVerticalAxisRenderer : AxisRendererBase
  124.41 +    {
  124.42 +        /// <summary>
  124.43 +        /// Initializes a new instance of the <see cref="HorizontalAndVerticalAxisRenderer"/> class.
  124.44 +        /// </summary>
  124.45 +        /// <param name="rc">
  124.46 +        /// The render context.
  124.47 +        /// </param>
  124.48 +        /// <param name="plot">
  124.49 +        /// The plot.
  124.50 +        /// </param>
  124.51 +        public HorizontalAndVerticalAxisRenderer(IRenderContext rc, PlotModel plot)
  124.52 +            : base(rc, plot)
  124.53 +        {
  124.54 +        }
  124.55 +
  124.56 +        /// <summary>
  124.57 +        /// Renders the specified axis.
  124.58 +        /// </summary>
  124.59 +        /// <param name="axis">The axis.</param>
  124.60 +        /// <param name="pass">The pass.</param>
  124.61 +        public override void Render(Axis axis, int pass)
  124.62 +        {
  124.63 +            base.Render(axis, pass);
  124.64 +
  124.65 +            double totalShift = axis.PositionTierMinShift;
  124.66 +            double tierSize = axis.PositionTierSize - this.Plot.AxisTierDistance;
  124.67 +
  124.68 +            // store properties locally for performance
  124.69 +            double plotAreaLeft = this.Plot.PlotArea.Left;
  124.70 +            double plotAreaRight = this.Plot.PlotArea.Right;
  124.71 +            double plotAreaTop = this.Plot.PlotArea.Top;
  124.72 +            double plotAreaBottom = this.Plot.PlotArea.Bottom;
  124.73 +
  124.74 +            // Axis position (x or y screen coordinate)
  124.75 +            double axisPosition = 0;
  124.76 +            double titlePosition = 0;
  124.77 +
  124.78 +            switch (axis.Position)
  124.79 +            {
  124.80 +                case AxisPosition.Left:
  124.81 +                    axisPosition = plotAreaLeft - totalShift;
  124.82 +                    titlePosition = axisPosition - tierSize;
  124.83 +                    break;
  124.84 +                case AxisPosition.Right:
  124.85 +                    axisPosition = plotAreaRight + totalShift;
  124.86 +                    titlePosition = axisPosition + tierSize;
  124.87 +                    break;
  124.88 +                case AxisPosition.Top:
  124.89 +                    axisPosition = plotAreaTop - totalShift;
  124.90 +                    titlePosition = axisPosition - tierSize;
  124.91 +                    break;
  124.92 +                case AxisPosition.Bottom:
  124.93 +                    axisPosition = plotAreaBottom + totalShift;
  124.94 +                    titlePosition = axisPosition + tierSize;
  124.95 +                    break;
  124.96 +            }
  124.97 +
  124.98 +            if (axis.PositionAtZeroCrossing)
  124.99 +            {
 124.100 +                var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
 124.101 +                axisPosition = perpendicularAxis.Transform(0);
 124.102 +            }
 124.103 +
 124.104 +            if (pass == 0)
 124.105 +            {
 124.106 +                this.RenderMinorItems(axis, axisPosition);
 124.107 +            }
 124.108 +
 124.109 +            if (pass == 1)
 124.110 +            {
 124.111 +                this.RenderMajorItems(axis, axisPosition, titlePosition);
 124.112 +            }
 124.113 +        }
 124.114 +
 124.115 +        /// <summary>
 124.116 +        /// Gets the axis title position, rotation and alignment.
 124.117 +        /// </summary>
 124.118 +        /// <param name="axis">
 124.119 +        /// The axis.
 124.120 +        /// </param>
 124.121 +        /// <param name="titlePosition">
 124.122 +        /// The title position.
 124.123 +        /// </param>
 124.124 +        /// <param name="angle">
 124.125 +        /// The angle.
 124.126 +        /// </param>
 124.127 +        /// <param name="halign">
 124.128 +        /// The horizontal alignment.
 124.129 +        /// </param>
 124.130 +        /// <param name="valign">
 124.131 +        /// The vertical alignment.
 124.132 +        /// </param>
 124.133 +        /// <returns>
 124.134 +        /// The <see cref="ScreenPoint"/>.
 124.135 +        /// </returns>
 124.136 +        protected virtual ScreenPoint GetAxisTitlePositionAndAlignment(
 124.137 +            Axis axis, 
 124.138 +            double titlePosition, 
 124.139 +            ref double angle, 
 124.140 +            ref HorizontalAlignment halign, 
 124.141 +            ref VerticalAlignment valign)
 124.142 +        {
 124.143 +            double middle = axis.IsHorizontal()
 124.144 +                                ? Lerp(axis.ScreenMin.X, axis.ScreenMax.X, axis.TitlePosition)
 124.145 +                                : Lerp(axis.ScreenMax.Y, axis.ScreenMin.Y, axis.TitlePosition);
 124.146 +
 124.147 +            if (axis.PositionAtZeroCrossing)
 124.148 +            {
 124.149 +                var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
 124.150 +                middle = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
 124.151 +            }
 124.152 +
 124.153 +            switch (axis.Position)
 124.154 +            {
 124.155 +                case AxisPosition.Left:
 124.156 +                    return new ScreenPoint(titlePosition, middle);
 124.157 +                case AxisPosition.Right:
 124.158 +                    valign = VerticalAlignment.Bottom;
 124.159 +                    return new ScreenPoint(titlePosition, middle);
 124.160 +                case AxisPosition.Top:
 124.161 +                    halign = HorizontalAlignment.Center;
 124.162 +                    valign = VerticalAlignment.Top;
 124.163 +                    angle = 0;
 124.164 +                    return new ScreenPoint(middle, titlePosition);
 124.165 +                case AxisPosition.Bottom:
 124.166 +                    halign = HorizontalAlignment.Center;
 124.167 +                    valign = VerticalAlignment.Bottom;
 124.168 +                    angle = 0;
 124.169 +                    return new ScreenPoint(middle, titlePosition);
 124.170 +                default:
 124.171 +                    throw new ArgumentOutOfRangeException("axis");
 124.172 +            }
 124.173 +        }
 124.174 +
 124.175 +        /// <summary>
 124.176 +        /// Gets the alignments given the specified rotation angle.
 124.177 +        /// </summary>
 124.178 +        /// <param name="angle">
 124.179 +        /// The angle.
 124.180 +        /// </param>
 124.181 +        /// <param name="defaultHorizontalAlignment">
 124.182 +        /// The default horizontal alignment.
 124.183 +        /// </param>
 124.184 +        /// <param name="defaultVerticalAlignment">
 124.185 +        /// The default vertical alignment.
 124.186 +        /// </param>
 124.187 +        /// <param name="ha">
 124.188 +        /// The rotated horizontal alignment.
 124.189 +        /// </param>
 124.190 +        /// <param name="va">
 124.191 +        /// The rotated vertical alignment.
 124.192 +        /// </param>
 124.193 +        protected virtual void GetRotatedAlignments(
 124.194 +            double angle, 
 124.195 +            HorizontalAlignment defaultHorizontalAlignment, 
 124.196 +            VerticalAlignment defaultVerticalAlignment, 
 124.197 +            out HorizontalAlignment ha, 
 124.198 +            out VerticalAlignment va)
 124.199 +        {
 124.200 +            ha = defaultHorizontalAlignment;
 124.201 +            va = defaultVerticalAlignment;
 124.202 +
 124.203 +            Debug.Assert(angle <= 180 && angle >= -180, "Axis angle should be in the interval [-180,180] degrees.");
 124.204 +
 124.205 +            if (angle > -45 && angle < 45)
 124.206 +            {
 124.207 +                return;
 124.208 +            }
 124.209 +
 124.210 +            if (angle > 135 || angle < -135)
 124.211 +            {
 124.212 +                ha = (HorizontalAlignment)(-(int)defaultHorizontalAlignment);
 124.213 +                va = (VerticalAlignment)(-(int)defaultVerticalAlignment);
 124.214 +                return;
 124.215 +            }
 124.216 +
 124.217 +            if (angle > 45)
 124.218 +            {
 124.219 +                ha = (HorizontalAlignment)((int)defaultVerticalAlignment);
 124.220 +                va = (VerticalAlignment)(-(int)defaultHorizontalAlignment);
 124.221 +                return;
 124.222 +            }
 124.223 +
 124.224 +            if (angle < -45)
 124.225 +            {
 124.226 +                ha = (HorizontalAlignment)(-(int)defaultVerticalAlignment);
 124.227 +                va = (VerticalAlignment)((int)defaultHorizontalAlignment);
 124.228 +            }
 124.229 +        }
 124.230 +
 124.231 +        /// <summary>
 124.232 +        /// Linear interpolation
 124.233 +        /// http://en.wikipedia.org/wiki/Linear_interpolation
 124.234 +        /// </summary>
 124.235 +        /// <param name="x0">
 124.236 +        /// The x0.
 124.237 +        /// </param>
 124.238 +        /// <param name="x1">
 124.239 +        /// The x1.
 124.240 +        /// </param>
 124.241 +        /// <param name="f">
 124.242 +        /// The interpolation factor.
 124.243 +        /// </param>
 124.244 +        /// <returns>
 124.245 +        /// The interpolated value.
 124.246 +        /// </returns>
 124.247 +        private static double Lerp(double x0, double x1, double f)
 124.248 +        {
 124.249 +            return (x0 * (1 - f)) + (x1 * f);
 124.250 +        }
 124.251 +
 124.252 +        /// <summary>
 124.253 +        /// Snaps v to value if it is within the the specified distance.
 124.254 +        /// </summary>
 124.255 +        /// <param name="target">
 124.256 +        /// The target value.
 124.257 +        /// </param>
 124.258 +        /// <param name="v">
 124.259 +        /// The value to snap.
 124.260 +        /// </param>
 124.261 +        /// <param name="eps">
 124.262 +        /// The distance tolerance.
 124.263 +        /// </param>
 124.264 +        private static void SnapTo(double target, ref double v, double eps = 0.5)
 124.265 +        {
 124.266 +            if (v > target - eps && v < target + eps)
 124.267 +            {
 124.268 +                v = target;
 124.269 +            }
 124.270 +        }
 124.271 +
 124.272 +        /// <summary>
 124.273 +        /// Renders the axis title.
 124.274 +        /// </summary>
 124.275 +        /// <param name="axis">
 124.276 +        /// The axis.
 124.277 +        /// </param>
 124.278 +        /// <param name="titlePosition">
 124.279 +        /// The title position.
 124.280 +        /// </param>
 124.281 +        private void RenderAxisTitle(Axis axis, double titlePosition)
 124.282 +        {
 124.283 +            bool isHorizontal = axis.IsHorizontal();
 124.284 +
 124.285 +            OxySize? maxSize = null;
 124.286 +
 124.287 +            if (axis.ClipTitle)
 124.288 +            {
 124.289 +                // Calculate the title clipping dimensions
 124.290 +                double screenLength = isHorizontal
 124.291 +                                          ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X)
 124.292 +                                          : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y);
 124.293 +
 124.294 +                maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue);
 124.295 +            }
 124.296 +
 124.297 +            double angle = -90;
 124.298 +
 124.299 +            var halign = HorizontalAlignment.Center;
 124.300 +            var valign = VerticalAlignment.Top;
 124.301 +
 124.302 +            var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign);
 124.303 +
 124.304 +            this.rc.SetToolTip(axis.ToolTip);
 124.305 +            this.rc.DrawMathText(
 124.306 +                lpt, 
 124.307 +                axis.ActualTitle, 
 124.308 +                axis.ActualTitleColor, 
 124.309 +                axis.ActualTitleFont, 
 124.310 +                axis.ActualTitleFontSize, 
 124.311 +                axis.ActualTitleFontWeight, 
 124.312 +                angle, 
 124.313 +                halign, 
 124.314 +                valign, 
 124.315 +                maxSize);
 124.316 +            this.rc.SetToolTip(null);
 124.317 +        }
 124.318 +
 124.319 +        /// <summary>
 124.320 +        /// Renders the major items.
 124.321 +        /// </summary>
 124.322 +        /// <param name="axis">
 124.323 +        /// The axis.
 124.324 +        /// </param>
 124.325 +        /// <param name="axisPosition">
 124.326 +        /// The axis position.
 124.327 +        /// </param>
 124.328 +        /// <param name="titlePosition">
 124.329 +        /// The title position.
 124.330 +        /// </param>
 124.331 +        private void RenderMajorItems(Axis axis, double axisPosition, double titlePosition)
 124.332 +        {
 124.333 +            double eps = axis.ActualMinorStep * 1e-3;
 124.334 +
 124.335 +            double actualMinimum = axis.ActualMinimum;
 124.336 +            double actualMaximum = axis.ActualMaximum;
 124.337 +
 124.338 +            double plotAreaLeft = this.Plot.PlotArea.Left;
 124.339 +            double plotAreaRight = this.Plot.PlotArea.Right;
 124.340 +            double plotAreaTop = this.Plot.PlotArea.Top;
 124.341 +            double plotAreaBottom = this.Plot.PlotArea.Bottom;
 124.342 +            bool isHorizontal = axis.IsHorizontal();
 124.343 +
 124.344 +            double a0;
 124.345 +            double a1;
 124.346 +            var majorSegments = new List<ScreenPoint>();
 124.347 +            var majorTickSegments = new List<ScreenPoint>();
 124.348 +            this.GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);
 124.349 +
 124.350 +            foreach (double value in this.MajorTickValues)
 124.351 +            {
 124.352 +                if (value < actualMinimum - eps || value > actualMaximum + eps)
 124.353 +                {
 124.354 +                    continue;
 124.355 +                }
 124.356 +
 124.357 +                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
 124.358 +                {
 124.359 +                    continue;
 124.360 +                }
 124.361 +
 124.362 +                double transformedValue = axis.Transform(value);
 124.363 +                if (isHorizontal)
 124.364 +                {
 124.365 +                    SnapTo(plotAreaLeft, ref transformedValue);
 124.366 +                    SnapTo(plotAreaRight, ref transformedValue);
 124.367 +                }
 124.368 +                else
 124.369 +                {
 124.370 +                    SnapTo(plotAreaTop, ref transformedValue);
 124.371 +                    SnapTo(plotAreaBottom, ref transformedValue);
 124.372 +                }
 124.373 +
 124.374 +                if (this.MajorPen != null)
 124.375 +                {
 124.376 +                    if (isHorizontal)
 124.377 +                    {
 124.378 +                        majorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
 124.379 +                        majorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
 124.380 +                    }
 124.381 +                    else
 124.382 +                    {
 124.383 +                        majorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
 124.384 +                        majorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
 124.385 +                    }
 124.386 +                }
 124.387 +
 124.388 +                if (axis.TickStyle != TickStyle.None)
 124.389 +                {
 124.390 +                    if (isHorizontal)
 124.391 +                    {
 124.392 +                        majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
 124.393 +                        majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
 124.394 +                    }
 124.395 +                    else
 124.396 +                    {
 124.397 +                        majorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
 124.398 +                        majorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
 124.399 +                    }
 124.400 +                }
 124.401 +            }
 124.402 +
 124.403 +            // Render the axis labels (numbers or category names)
 124.404 +            foreach (double value in this.MajorLabelValues)
 124.405 +            {
 124.406 +                if (value < actualMinimum - eps || value > actualMaximum + eps)
 124.407 +                {
 124.408 +                    continue;
 124.409 +                }
 124.410 +
 124.411 +                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
 124.412 +                {
 124.413 +                    continue;
 124.414 +                }
 124.415 +
 124.416 +                double transformedValue = axis.Transform(value);
 124.417 +                if (isHorizontal)
 124.418 +                {
 124.419 +                    SnapTo(plotAreaLeft, ref transformedValue);
 124.420 +                    SnapTo(plotAreaRight, ref transformedValue);
 124.421 +                }
 124.422 +                else
 124.423 +                {
 124.424 +                    SnapTo(plotAreaTop, ref transformedValue);
 124.425 +                    SnapTo(plotAreaBottom, ref transformedValue);
 124.426 +                }
 124.427 +
 124.428 +                var pt = new ScreenPoint();
 124.429 +                var ha = HorizontalAlignment.Right;
 124.430 +                var va = VerticalAlignment.Middle;
 124.431 +                switch (axis.Position)
 124.432 +                {
 124.433 +                    case AxisPosition.Left:
 124.434 +                        pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue);
 124.435 +                        this.GetRotatedAlignments(
 124.436 +                            axis.Angle, HorizontalAlignment.Right, VerticalAlignment.Middle, out ha, out va);
 124.437 +                        break;
 124.438 +                    case AxisPosition.Right:
 124.439 +                        pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue);
 124.440 +                        this.GetRotatedAlignments(
 124.441 +                            axis.Angle, HorizontalAlignment.Left, VerticalAlignment.Middle, out ha, out va);
 124.442 +                        break;
 124.443 +                    case AxisPosition.Top:
 124.444 +                        pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance);
 124.445 +                        this.GetRotatedAlignments(
 124.446 +                            axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Bottom, out ha, out va);
 124.447 +                        break;
 124.448 +                    case AxisPosition.Bottom:
 124.449 +                        pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance);
 124.450 +                        this.GetRotatedAlignments(
 124.451 +                            axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Top, out ha, out va);
 124.452 +                        break;
 124.453 +                }
 124.454 +
 124.455 +                string text = axis.FormatValue(value);
 124.456 +                this.rc.DrawMathText(
 124.457 +                    pt, 
 124.458 +                    text, 
 124.459 +                    axis.ActualTextColor, 
 124.460 +                    axis.ActualFont, 
 124.461 +                    axis.ActualFontSize, 
 124.462 +                    axis.ActualFontWeight, 
 124.463 +                    axis.Angle, 
 124.464 +                    ha, 
 124.465 +                    va);
 124.466 +            }
 124.467 +
 124.468 +            // Draw the zero crossing line
 124.469 +            if (axis.PositionAtZeroCrossing && this.ZeroPen != null)
 124.470 +            {
 124.471 +                double t0 = axis.Transform(0);
 124.472 +                if (isHorizontal)
 124.473 +                {
 124.474 +                    this.rc.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen);
 124.475 +                }
 124.476 +                else
 124.477 +                {
 124.478 +                    this.rc.DrawLine(plotAreaLeft, t0, plotAreaRight, t0, this.ZeroPen);
 124.479 +                }
 124.480 +            }
 124.481 +
 124.482 +            // Draw extra grid lines
 124.483 +            if (axis.ExtraGridlines != null && this.ExtraPen != null)
 124.484 +            {
 124.485 +                foreach (double value in axis.ExtraGridlines)
 124.486 +                {
 124.487 +                    if (!this.IsWithin(value, actualMinimum, actualMaximum))
 124.488 +                    {
 124.489 +                        continue;
 124.490 +                    }
 124.491 +
 124.492 +                    double transformedValue = axis.Transform(value);
 124.493 +                    if (isHorizontal)
 124.494 +                    {
 124.495 +                        this.rc.DrawLine(transformedValue, plotAreaTop, transformedValue, plotAreaBottom, this.ExtraPen);
 124.496 +                    }
 124.497 +                    else
 124.498 +                    {
 124.499 +                        this.rc.DrawLine(plotAreaLeft, transformedValue, plotAreaRight, transformedValue, this.ExtraPen);
 124.500 +                    }
 124.501 +                }
 124.502 +            }
 124.503 +
 124.504 +            // Draw the axis line (across the tick marks)
 124.505 +            if (isHorizontal)
 124.506 +            {
 124.507 +                this.rc.DrawLine(
 124.508 +                    axis.Transform(actualMinimum), 
 124.509 +                    axisPosition, 
 124.510 +                    axis.Transform(actualMaximum), 
 124.511 +                    axisPosition, 
 124.512 +                    this.AxislinePen);
 124.513 +            }
 124.514 +            else
 124.515 +            {
 124.516 +                this.rc.DrawLine(
 124.517 +                    axisPosition, 
 124.518 +                    axis.Transform(actualMinimum), 
 124.519 +                    axisPosition, 
 124.520 +                    axis.Transform(actualMaximum), 
 124.521 +                    this.AxislinePen);
 124.522 +            }
 124.523 +
 124.524 +            // Draw the axis title
 124.525 +            if (!string.IsNullOrEmpty(axis.ActualTitle))
 124.526 +            {
 124.527 +                this.RenderAxisTitle(axis, titlePosition);
 124.528 +            }
 124.529 +
 124.530 +            if (this.MajorPen != null)
 124.531 +            {
 124.532 +                this.rc.DrawLineSegments(majorSegments, this.MajorPen);
 124.533 +            }
 124.534 +
 124.535 +            if (this.MajorTickPen != null)
 124.536 +            {
 124.537 +                this.rc.DrawLineSegments(majorTickSegments, this.MajorTickPen);
 124.538 +            }
 124.539 +        }
 124.540 +
 124.541 +        /// <summary>
 124.542 +        /// Renders the minor items.
 124.543 +        /// </summary>
 124.544 +        /// <param name="axis">
 124.545 +        /// The axis.
 124.546 +        /// </param>
 124.547 +        /// <param name="axisPosition">
 124.548 +        /// The axis position.
 124.549 +        /// </param>
 124.550 +        private void RenderMinorItems(Axis axis, double axisPosition)
 124.551 +        {
 124.552 +            double eps = axis.ActualMinorStep * 1e-3;
 124.553 +            double actualMinimum = axis.ActualMinimum;
 124.554 +            double actualMaximum = axis.ActualMaximum;
 124.555 +
 124.556 +            double plotAreaLeft = this.Plot.PlotArea.Left;
 124.557 +            double plotAreaRight = this.Plot.PlotArea.Right;
 124.558 +            double plotAreaTop = this.Plot.PlotArea.Top;
 124.559 +            double plotAreaBottom = this.Plot.PlotArea.Bottom;
 124.560 +            bool isHorizontal = axis.IsHorizontal();
 124.561 +
 124.562 +            double a0;
 124.563 +            double a1;
 124.564 +            var minorSegments = new List<ScreenPoint>();
 124.565 +            var minorTickSegments = new List<ScreenPoint>();
 124.566 +            this.GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);
 124.567 +
 124.568 +            foreach (double value in this.MinorTickValues)
 124.569 +            {
 124.570 +                if (value < actualMinimum - eps || value > actualMaximum + eps)
 124.571 +                {
 124.572 +                    continue;
 124.573 +                }
 124.574 +
 124.575 +                if (this.MajorTickValues.Contains(value))
 124.576 +                {
 124.577 +                    continue;
 124.578 +                }
 124.579 +
 124.580 +                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
 124.581 +                {
 124.582 +                    continue;
 124.583 +                }
 124.584 +
 124.585 +                double transformedValue = axis.Transform(value);
 124.586 +
 124.587 +                if (isHorizontal)
 124.588 +                {
 124.589 +                    SnapTo(plotAreaLeft, ref transformedValue);
 124.590 +                    SnapTo(plotAreaRight, ref transformedValue);
 124.591 +                }
 124.592 +                else
 124.593 +                {
 124.594 +                    SnapTo(plotAreaTop, ref transformedValue);
 124.595 +                    SnapTo(plotAreaBottom, ref transformedValue);
 124.596 +                }
 124.597 +
 124.598 +                // Draw the minor grid line
 124.599 +                if (this.MinorPen != null)
 124.600 +                {
 124.601 +                    if (isHorizontal)
 124.602 +                    {
 124.603 +                        minorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
 124.604 +                        minorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
 124.605 +                    }
 124.606 +                    else
 124.607 +                    {
 124.608 +                        if (transformedValue < plotAreaTop || transformedValue > plotAreaBottom)
 124.609 +                        {
 124.610 +                        }
 124.611 +
 124.612 +                        minorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
 124.613 +                        minorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
 124.614 +                    }
 124.615 +                }
 124.616 +
 124.617 +                // Draw the minor tick
 124.618 +                if (axis.TickStyle != TickStyle.None)
 124.619 +                {
 124.620 +                    if (isHorizontal)
 124.621 +                    {
 124.622 +                        minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
 124.623 +                        minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
 124.624 +                    }
 124.625 +                    else
 124.626 +                    {
 124.627 +                        minorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
 124.628 +                        minorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
 124.629 +                    }
 124.630 +                }
 124.631 +            }
 124.632 +
 124.633 +            // Draw all the line segments);
 124.634 +            if (this.MinorPen != null)
 124.635 +            {
 124.636 +                this.rc.DrawLineSegments(minorSegments, this.MinorPen);
 124.637 +            }
 124.638 +
 124.639 +            if (this.MinorTickPen != null)
 124.640 +            {
 124.641 +                this.rc.DrawLineSegments(minorTickSegments, this.MinorTickPen);
 124.642 +            }
 124.643 +        }
 124.644 +    }
 124.645 +}
 124.646 \ No newline at end of file
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/External/OxyPlot/OxyPlot/Render/IRenderContext.cs	Sat Jun 08 16:53:22 2013 +0000
   125.3 @@ -0,0 +1,400 @@
   125.4 +// --------------------------------------------------------------------------------------------------------------------
   125.5 +// <copyright file="IRenderContext.cs" company="OxyPlot">
   125.6 +//   The MIT License (MIT)
   125.7 +//
   125.8 +//   Copyright (c) 2012 Oystein Bjorke
   125.9 +//
  125.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  125.11 +//   copy of this software and associated documentation files (the
  125.12 +//   "Software"), to deal in the Software without restriction, including
  125.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  125.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  125.15 +//   permit persons to whom the Software is furnished to do so, subject to
  125.16 +//   the following conditions:
  125.17 +//
  125.18 +//   The above copyright notice and this permission notice shall be included
  125.19 +//   in all copies or substantial portions of the Software.
  125.20 +//
  125.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  125.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  125.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  125.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  125.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  125.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  125.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  125.28 +// </copyright>
  125.29 +// <summary>
  125.30 +//   Render context interface.
  125.31 +// </summary>
  125.32 +// --------------------------------------------------------------------------------------------------------------------
  125.33 +namespace OxyPlot
  125.34 +{
  125.35 +    using System.Collections.Generic;
  125.36 +
  125.37 +    /// <summary>
  125.38 +    /// Defines rendering functionality.
  125.39 +    /// </summary>
  125.40 +    public interface IRenderContext
  125.41 +    {
  125.42 +        /// <summary>
  125.43 +        /// Gets a value indicating whether the context renders to screen.
  125.44 +        /// </summary>
  125.45 +        /// <value>
  125.46 +        ///   <c>true</c> if the context renders to screen; otherwise, <c>false</c>.
  125.47 +        /// </value>
  125.48 +        bool RendersToScreen { get; }
  125.49 +
  125.50 +        /// <summary>
  125.51 +        /// Draws an ellipse.
  125.52 +        /// </summary>
  125.53 +        /// <param name="rect">
  125.54 +        /// The rectangle.
  125.55 +        /// </param>
  125.56 +        /// <param name="fill">
  125.57 +        /// The fill color.
  125.58 +        /// </param>
  125.59 +        /// <param name="stroke">
  125.60 +        /// The stroke color.
  125.61 +        /// </param>
  125.62 +        /// <param name="thickness">
  125.63 +        /// The thickness.
  125.64 +        /// </param>
  125.65 +        void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1.0);
  125.66 +
  125.67 +        /// <summary>
  125.68 +        /// Draws the collection of ellipses, where all have the same stroke and fill.
  125.69 +        /// This performs better than calling DrawEllipse multiple times.
  125.70 +        /// </summary>
  125.71 +        /// <param name="rectangles">
  125.72 +        /// The rectangles.
  125.73 +        /// </param>
  125.74 +        /// <param name="fill">
  125.75 +        /// The fill color.
  125.76 +        /// </param>
  125.77 +        /// <param name="stroke">
  125.78 +        /// The stroke color.
  125.79 +        /// </param>
  125.80 +        /// <param name="thickness">
  125.81 +        /// The stroke thickness.
  125.82 +        /// </param>
  125.83 +        void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness = 1.0);
  125.84 +
  125.85 +        /// <summary>
  125.86 +        /// Draws the polyline from the specified points.
  125.87 +        /// </summary>
  125.88 +        /// <param name="points">
  125.89 +        /// The points.
  125.90 +        /// </param>
  125.91 +        /// <param name="stroke">
  125.92 +        /// The stroke color.
  125.93 +        /// </param>
  125.94 +        /// <param name="thickness">
  125.95 +        /// The stroke thickness.
  125.96 +        /// </param>
  125.97 +        /// <param name="dashArray">
  125.98 +        /// The dash array.
  125.99 +        /// </param>
 125.100 +        /// <param name="lineJoin">
 125.101 +        /// The line join type.
 125.102 +        /// </param>
 125.103 +        /// <param name="aliased">
 125.104 +        /// if set to <c>true</c> the shape will be aliased.
 125.105 +        /// </param>
 125.106 +        void DrawLine(
 125.107 +            IList<ScreenPoint> points,
 125.108 +            OxyColor stroke,
 125.109 +            double thickness = 1.0,
 125.110 +            double[] dashArray = null,
 125.111 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
 125.112 +            bool aliased = false);
 125.113 +
 125.114 +        /// <summary>
 125.115 +        /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc.
 125.116 +        /// This should have better performance than calling DrawLine for each segment.
 125.117 +        /// </summary>
 125.118 +        /// <param name="points">
 125.119 +        /// The points.
 125.120 +        /// </param>
 125.121 +        /// <param name="stroke">
 125.122 +        /// The stroke color.
 125.123 +        /// </param>
 125.124 +        /// <param name="thickness">
 125.125 +        /// The stroke thickness.
 125.126 +        /// </param>
 125.127 +        /// <param name="dashArray">
 125.128 +        /// The dash array.
 125.129 +        /// </param>
 125.130 +        /// <param name="lineJoin">
 125.131 +        /// The line join type.
 125.132 +        /// </param>
 125.133 +        /// <param name="aliased">
 125.134 +        /// if set to <c>true</c> the shape will be aliased.
 125.135 +        /// </param>
 125.136 +        void DrawLineSegments(
 125.137 +            IList<ScreenPoint> points,
 125.138 +            OxyColor stroke,
 125.139 +            double thickness = 1.0,
 125.140 +            double[] dashArray = null,
 125.141 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
 125.142 +            bool aliased = false);
 125.143 +
 125.144 +        /// <summary>
 125.145 +        /// Draws the polygon from the specified points. The polygon can have stroke and/or fill.
 125.146 +        /// </summary>
 125.147 +        /// <param name="points">
 125.148 +        /// The points.
 125.149 +        /// </param>
 125.150 +        /// <param name="fill">
 125.151 +        /// The fill color.
 125.152 +        /// </param>
 125.153 +        /// <param name="stroke">
 125.154 +        /// The stroke color.
 125.155 +        /// </param>
 125.156 +        /// <param name="thickness">
 125.157 +        /// The stroke thickness.
 125.158 +        /// </param>
 125.159 +        /// <param name="dashArray">
 125.160 +        /// The dash array.
 125.161 +        /// </param>
 125.162 +        /// <param name="lineJoin">
 125.163 +        /// The line join type.
 125.164 +        /// </param>
 125.165 +        /// <param name="aliased">
 125.166 +        /// if set to <c>true</c> the shape will be aliased.
 125.167 +        /// </param>
 125.168 +        void DrawPolygon(
 125.169 +            IList<ScreenPoint> points,
 125.170 +            OxyColor fill,
 125.171 +            OxyColor stroke,
 125.172 +            double thickness = 1.0,
 125.173 +            double[] dashArray = null,
 125.174 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
 125.175 +            bool aliased = false);
 125.176 +
 125.177 +        /// <summary>
 125.178 +        /// Draws a collection of polygons, where all polygons have the same stroke and fill.
 125.179 +        /// This performs better than calling DrawPolygon multiple times.
 125.180 +        /// </summary>
 125.181 +        /// <param name="polygons">
 125.182 +        /// The polygons.
 125.183 +        /// </param>
 125.184 +        /// <param name="fill">
 125.185 +        /// The fill color.
 125.186 +        /// </param>
 125.187 +        /// <param name="stroke">
 125.188 +        /// The stroke color.
 125.189 +        /// </param>
 125.190 +        /// <param name="thickness">
 125.191 +        /// The stroke thickness.
 125.192 +        /// </param>
 125.193 +        /// <param name="dashArray">
 125.194 +        /// The dash array.
 125.195 +        /// </param>
 125.196 +        /// <param name="lineJoin">
 125.197 +        /// The line join type.
 125.198 +        /// </param>
 125.199 +        /// <param name="aliased">
 125.200 +        /// if set to <c>true</c> the shape will be aliased.
 125.201 +        /// </param>
 125.202 +        void DrawPolygons(
 125.203 +            IList<IList<ScreenPoint>> polygons,
 125.204 +            OxyColor fill,
 125.205 +            OxyColor stroke,
 125.206 +            double thickness = 1.0,
 125.207 +            double[] dashArray = null,
 125.208 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
 125.209 +            bool aliased = false);
 125.210 +
 125.211 +        /// <summary>
 125.212 +        /// Draws the rectangle.
 125.213 +        /// </summary>
 125.214 +        /// <param name="rect">
 125.215 +        /// The rectangle.
 125.216 +        /// </param>
 125.217 +        /// <param name="fill">
 125.218 +        /// The fill color.
 125.219 +        /// </param>
 125.220 +        /// <param name="stroke">
 125.221 +        /// The stroke color.
 125.222 +        /// </param>
 125.223 +        /// <param name="thickness">
 125.224 +        /// The stroke thickness.
 125.225 +        /// </param>
 125.226 +        void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1.0);
 125.227 +
 125.228 +        /// <summary>
 125.229 +        /// Draws a collection of rectangles, where all have the same stroke and fill.
 125.230 +        /// This performs better than calling DrawRectangle multiple times.
 125.231 +        /// </summary>
 125.232 +        /// <param name="rectangles">
 125.233 +        /// The rectangles.
 125.234 +        /// </param>
 125.235 +        /// <param name="fill">
 125.236 +        /// The fill color.
 125.237 +        /// </param>
 125.238 +        /// <param name="stroke">
 125.239 +        /// The stroke color.
 125.240 +        /// </param>
 125.241 +        /// <param name="thickness">
 125.242 +        /// The stroke thickness.
 125.243 +        /// </param>
 125.244 +        void DrawRectangles(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness = 1.0);
 125.245 +
 125.246 +        /// <summary>
 125.247 +        /// Draws the text.
 125.248 +        /// </summary>
 125.249 +        /// <param name="p">
 125.250 +        /// The position.
 125.251 +        /// </param>
 125.252 +        /// <param name="text">
 125.253 +        /// The text.
 125.254 +        /// </param>
 125.255 +        /// <param name="fill">
 125.256 +        /// The fill color.
 125.257 +        /// </param>
 125.258 +        /// <param name="fontFamily">
 125.259 +        /// The font family.
 125.260 +        /// </param>
 125.261 +        /// <param name="fontSize">
 125.262 +        /// Size of the font.
 125.263 +        /// </param>
 125.264 +        /// <param name="fontWeight">
 125.265 +        /// The font weight.
 125.266 +        /// </param>
 125.267 +        /// <param name="rotate">
 125.268 +        /// The rotation angle.
 125.269 +        /// </param>
 125.270 +        /// <param name="halign">
 125.271 +        /// The horizontal alignment.
 125.272 +        /// </param>
 125.273 +        /// <param name="valign">
 125.274 +        /// The vertical alignment.
 125.275 +        /// </param>
 125.276 +        /// <param name="maxSize">
 125.277 +        /// The maximum size of the text.
 125.278 +        /// </param>
 125.279 +        void DrawText(
 125.280 +            ScreenPoint p,
 125.281 +            string text,
 125.282 +            OxyColor fill,
 125.283 +            string fontFamily = null,
 125.284 +            double fontSize = 10,
 125.285 +            double fontWeight = 500,
 125.286 +            double rotate = 0,
 125.287 +            HorizontalAlignment halign = HorizontalAlignment.Left,
 125.288 +            VerticalAlignment valign = VerticalAlignment.Top,
 125.289 +            OxySize? maxSize = null);
 125.290 +
 125.291 +        /// <summary>
 125.292 +        /// Measures the text.
 125.293 +        /// </summary>
 125.294 +        /// <param name="text">
 125.295 +        /// The text.
 125.296 +        /// </param>
 125.297 +        /// <param name="fontFamily">
 125.298 +        /// The font family.
 125.299 +        /// </param>
 125.300 +        /// <param name="fontSize">
 125.301 +        /// Size of the font.
 125.302 +        /// </param>
 125.303 +        /// <param name="fontWeight">
 125.304 +        /// The font weight.
 125.305 +        /// </param>
 125.306 +        /// <returns>
 125.307 +        /// The text size.
 125.308 +        /// </returns>
 125.309 +        OxySize MeasureText(string text, string fontFamily = null, double fontSize = 10, double fontWeight = 500);
 125.310 +
 125.311 +        /// <summary>
 125.312 +        /// Sets the tool tip for the following items.
 125.313 +        /// </summary>
 125.314 +        /// <params>
 125.315 +        /// This is only used in the plot controls.
 125.316 +        /// </params>
 125.317 +        /// <param name="text">
 125.318 +        /// The text in the tooltip.
 125.319 +        /// </param>
 125.320 +        void SetToolTip(string text);
 125.321 +
 125.322 +        /// <summary>
 125.323 +        /// Cleans up resources not in use.
 125.324 +        /// </summary>
 125.325 +        /// <remarks>
 125.326 +        /// This method is called at the end of each rendering.
 125.327 +        /// </remarks>
 125.328 +        void CleanUp();
 125.329 +
 125.330 +        /// <summary>
 125.331 +        /// Gets the size of the specified image.
 125.332 +        /// </summary>
 125.333 +        /// <param name="source">The image source.</param>
 125.334 +        /// <returns>The image info.</returns>
 125.335 +        OxyImageInfo GetImageInfo(OxyImage source);
 125.336 +
 125.337 +        /// <summary>
 125.338 +        /// Draws the specified portion of the specified <see cref="OxyImage"/> at the specified location and with the specified size.
 125.339 +        /// </summary>
 125.340 +        /// <param name="source">The source.</param>
 125.341 +        /// <param name="srcX">The x-coordinate of the upper-left corner of the portion of the source image to draw.</param>
 125.342 +        /// <param name="srcY">The y-coordinate of the upper-left corner of the portion of the source image to draw.</param>
 125.343 +        /// <param name="srcWidth">Width of the portion of the source image to draw.</param>
 125.344 +        /// <param name="srcHeight">Height of the portion of the source image to draw.</param>
 125.345 +        /// <param name="destX">The x-coordinate of the upper-left corner of drawn image.</param>
 125.346 +        /// <param name="destY">The y-coordinate of the upper-left corner of drawn image.</param>
 125.347 +        /// <param name="destWidth">The width of the drawn image.</param>
 125.348 +        /// <param name="destHeight">The height of the drawn image.</param>
 125.349 +        /// <param name="opacity">The opacity.</param>
 125.350 +        /// <param name="interpolate">interpolate if set to <c>true</c>.</param>
 125.351 +        void DrawImage(OxyImage source, uint srcX, uint srcY, uint srcWidth, uint srcHeight, double destX, double destY, double destWidth, double destHeight, double opacity, bool interpolate);
 125.352 +
 125.353 +        /// <summary>
 125.354 +        /// Sets the clip rectangle.
 125.355 +        /// </summary>
 125.356 +        /// <param name="rect">The clip rectangle.</param>
 125.357 +        /// <returns>True if the clip rectangle was set.</returns>
 125.358 +        bool SetClip(OxyRect rect);
 125.359 +
 125.360 +        /// <summary>
 125.361 +        /// Resets the clip rectangle.
 125.362 +        /// </summary>
 125.363 +        void ResetClip();
 125.364 +    }
 125.365 +
 125.366 +    /// <summary>
 125.367 +    /// Provides information about the size of an image.
 125.368 +    /// </summary>
 125.369 +    public class OxyImageInfo
 125.370 +    {
 125.371 +        /// <summary>
 125.372 +        /// Gets or sets the width in pixels.
 125.373 +        /// </summary>
 125.374 +        /// <value>
 125.375 +        /// The width.
 125.376 +        /// </value>
 125.377 +        public uint Width { get; set; }
 125.378 +
 125.379 +        /// <summary>
 125.380 +        /// Gets or sets the height in pixels.
 125.381 +        /// </summary>
 125.382 +        /// <value>
 125.383 +        /// The height.
 125.384 +        /// </value>
 125.385 +        public uint Height { get; set; }
 125.386 +
 125.387 +        /// <summary>
 125.388 +        /// Gets or sets the horizontal resolution in dpi.
 125.389 +        /// </summary>
 125.390 +        /// <value>
 125.391 +        /// The dpi X.
 125.392 +        /// </value>
 125.393 +        public double DpiX { get; set; }
 125.394 +
 125.395 +        /// <summary>
 125.396 +        /// Gets or sets the vertical resolution in dpi.
 125.397 +        /// </summary>
 125.398 +        /// <value>
 125.399 +        /// The dpi Y.
 125.400 +        /// </value>
 125.401 +        public double DpiY { get; set; }
 125.402 +    }
 125.403 +}
 125.404 \ No newline at end of file
   126.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.2 +++ b/External/OxyPlot/OxyPlot/Render/MagnitudeAxisRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   126.3 @@ -0,0 +1,145 @@
   126.4 +// --------------------------------------------------------------------------------------------------------------------
   126.5 +// <copyright file="MagnitudeAxisRenderer.cs" company="OxyPlot">
   126.6 +//   The MIT License (MIT)
   126.7 +//
   126.8 +//   Copyright (c) 2012 Oystein Bjorke
   126.9 +//
  126.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  126.11 +//   copy of this software and associated documentation files (the
  126.12 +//   "Software"), to deal in the Software without restriction, including
  126.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  126.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  126.15 +//   permit persons to whom the Software is furnished to do so, subject to
  126.16 +//   the following conditions:
  126.17 +//
  126.18 +//   The above copyright notice and this permission notice shall be included
  126.19 +//   in all copies or substantial portions of the Software.
  126.20 +//
  126.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  126.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  126.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  126.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  126.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  126.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  126.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  126.28 +// </copyright>
  126.29 +// <summary>
  126.30 +//   The magnitude axis renderer.
  126.31 +// </summary>
  126.32 +// --------------------------------------------------------------------------------------------------------------------
  126.33 +namespace OxyPlot
  126.34 +{
  126.35 +    using System;
  126.36 +    using System.Collections.Generic;
  126.37 +
  126.38 +    using OxyPlot.Axes;
  126.39 +
  126.40 +    /// <summary>
  126.41 +    /// Provides functionality to render <see cref="MagnitudeAxis"/>.
  126.42 +    /// </summary>
  126.43 +    public class MagnitudeAxisRenderer : AxisRendererBase
  126.44 +    {
  126.45 +        /// <summary>
  126.46 +        /// Initializes a new instance of the <see cref="MagnitudeAxisRenderer"/> class.
  126.47 +        /// </summary>
  126.48 +        /// <param name="rc">
  126.49 +        /// The render context.
  126.50 +        /// </param>
  126.51 +        /// <param name="plot">
  126.52 +        /// The plot.
  126.53 +        /// </param>
  126.54 +        public MagnitudeAxisRenderer(IRenderContext rc, PlotModel plot)
  126.55 +            : base(rc, plot)
  126.56 +        {
  126.57 +        }
  126.58 +
  126.59 +        /// <summary>
  126.60 +        /// Renders the specified axis.
  126.61 +        /// </summary>
  126.62 +        /// <param name="axis">The axis.</param>
  126.63 +        /// <param name="pass">The pass.</param>
  126.64 +        /// <exception cref="System.NullReferenceException">Angle axis should not be null.</exception>
  126.65 +        public override void Render(Axis axis, int pass)
  126.66 +        {
  126.67 +            base.Render(axis, pass);
  126.68 +
  126.69 +            var angleAxis = this.Plot.DefaultAngleAxis as Axis;
  126.70 +            if (axis.RelatedAxis != null)
  126.71 +            {
  126.72 +                angleAxis = axis.RelatedAxis;
  126.73 +            }
  126.74 +
  126.75 +            if (angleAxis == null)
  126.76 +            {
  126.77 +                throw new NullReferenceException("Angle axis should not be null.");
  126.78 +            }
  126.79 +
  126.80 +            if (axis.ShowMinorTicks)
  126.81 +            {
  126.82 +                // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);
  126.83 +
  126.84 +                foreach (double xValue in this.MinorTickValues)
  126.85 +                {
  126.86 +                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
  126.87 +                    {
  126.88 +                        continue;
  126.89 +                    }
  126.90 +
  126.91 +                    if (this.MajorTickValues.Contains(xValue))
  126.92 +                    {
  126.93 +                        continue;
  126.94 +                    }
  126.95 +
  126.96 +                    var pts = new List<ScreenPoint>();
  126.97 +                    for (double th = angleAxis.ActualMinimum;
  126.98 +                         th <= angleAxis.ActualMaximum + angleAxis.MinorStep * 0.01;
  126.99 +                         th += angleAxis.MinorStep * 0.1)
 126.100 +                    {
 126.101 +                        pts.Add(axis.Transform(xValue, th, angleAxis));
 126.102 +                    }
 126.103 +
 126.104 +                    if (this.MinorPen != null)
 126.105 +                    {
 126.106 +                        this.rc.DrawLine(pts, this.MinorPen.Color, this.MinorPen.Thickness, this.MinorPen.DashArray);
 126.107 +                    }
 126.108 +
 126.109 +                    // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
 126.110 +                }
 126.111 +            }
 126.112 +
 126.113 +            // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);
 126.114 +
 126.115 +            foreach (double xValue in this.MajorTickValues)
 126.116 +            {
 126.117 +                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
 126.118 +                {
 126.119 +                    continue;
 126.120 +                }
 126.121 +
 126.122 +                var pts = new List<ScreenPoint>();
 126.123 +                for (double th = angleAxis.ActualMinimum;
 126.124 +                     th <= angleAxis.ActualMaximum + angleAxis.MinorStep * 0.01;
 126.125 +                     th += angleAxis.MinorStep * 0.1)
 126.126 +                {
 126.127 +                    pts.Add(axis.Transform(xValue, th, angleAxis));
 126.128 +                }
 126.129 +
 126.130 +                if (this.MajorPen != null)
 126.131 +                {
 126.132 +                    this.rc.DrawLine(pts, this.MajorPen.Color, this.MajorPen.Thickness, this.MajorPen.DashArray);
 126.133 +                }
 126.134 +
 126.135 +                // RenderGridline(x, y + y0, x, y + y1, majorTickPen);
 126.136 +                // var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
 126.137 +                // string text = axis.FormatValue(xValue);
 126.138 +                // double h = rc.MeasureText(text, axis.Font, axis.FontSize, axis.FontWeight).Height;
 126.139 +                // rc.DrawText(pt, text, axis.LabelColor ?? plot.TextColor,
 126.140 +                // axis.Font, axis.FontSize, axis.FontWeight,
 126.141 +                // axis.Angle,
 126.142 +                // HorizontalAlignment.Center, istop ? VerticalAlignment.Bottom : VerticalAlignment.Top);
 126.143 +                // maxh = Math.Max(maxh, h);
 126.144 +            }
 126.145 +        }
 126.146 +
 126.147 +    }
 126.148 +}
 126.149 \ No newline at end of file
   127.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.2 +++ b/External/OxyPlot/OxyPlot/Render/MathRenderingExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
   127.3 @@ -0,0 +1,347 @@
   127.4 +// --------------------------------------------------------------------------------------------------------------------
   127.5 +// <copyright file="MathRenderingExtensions.cs" company="OxyPlot">
   127.6 +//   The MIT License (MIT)
   127.7 +//
   127.8 +//   Copyright (c) 2012 Oystein Bjorke
   127.9 +//
  127.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  127.11 +//   copy of this software and associated documentation files (the
  127.12 +//   "Software"), to deal in the Software without restriction, including
  127.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  127.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  127.15 +//   permit persons to whom the Software is furnished to do so, subject to
  127.16 +//   the following conditions:
  127.17 +//
  127.18 +//   The above copyright notice and this permission notice shall be included
  127.19 +//   in all copies or substantial portions of the Software.
  127.20 +//
  127.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  127.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  127.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  127.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  127.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  127.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  127.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  127.28 +// </copyright>
  127.29 +// <summary>
  127.30 +//   The math rendering extensions.
  127.31 +// </summary>
  127.32 +// --------------------------------------------------------------------------------------------------------------------
  127.33 +namespace OxyPlot
  127.34 +{
  127.35 +    using System;
  127.36 +
  127.37 +    /// <summary>
  127.38 +    /// Provides functionality to render mathematic expressions (TeX syntax).
  127.39 +    /// </summary>
  127.40 +    public static class MathRenderingExtensions
  127.41 +    {
  127.42 +        /// <summary>
  127.43 +        /// Initializes static members of the <see cref = "MathRenderingExtensions" /> class.
  127.44 +        /// </summary>
  127.45 +        static MathRenderingExtensions()
  127.46 +        {
  127.47 +            SubAlignment = 0.6;
  127.48 +            SubSize = 0.62;
  127.49 +            SuperAlignment = 0;
  127.50 +            SuperSize = 0.62;
  127.51 +        }
  127.52 +
  127.53 +        /// <summary>
  127.54 +        /// Gets or sets the subscript alignment.
  127.55 +        /// </summary>
  127.56 +        private static double SubAlignment { get; set; }
  127.57 +
  127.58 +        /// <summary>
  127.59 +        /// Gets or sets the subscript size.
  127.60 +        /// </summary>
  127.61 +        private static double SubSize { get; set; }
  127.62 +
  127.63 +        /// <summary>
  127.64 +        /// Gets or sets the superscript alignment.
  127.65 +        /// </summary>
  127.66 +        private static double SuperAlignment { get; set; }
  127.67 +
  127.68 +        /// <summary>
  127.69 +        /// Gets or sets the superscript size.
  127.70 +        /// </summary>
  127.71 +        private static double SuperSize { get; set; }
  127.72 +
  127.73 +        /// <summary>
  127.74 +        /// Draws or measures text containing sub- and superscript.
  127.75 +        /// </summary>
  127.76 +        /// <param name="rc">The render context.</param>
  127.77 +        /// <param name="pt">The point.</param>
  127.78 +        /// <param name="text">The text.</param>
  127.79 +        /// <param name="textColor">Color of the text.</param>
  127.80 +        /// <param name="fontFamily">The font family.</param>
  127.81 +        /// <param name="fontSize">The font size.</param>
  127.82 +        /// <param name="fontWeight">The font weight.</param>
  127.83 +        /// <param name="angle">The angle.</param>
  127.84 +        /// <param name="ha">The horizontal alignment.</param>
  127.85 +        /// <param name="va">The vertical alignment.</param>
  127.86 +        /// <param name="maxsize">The maximum size of the text.</param>
  127.87 +        /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param>
  127.88 +        /// <returns>The size of the text.</returns>
  127.89 +        /// <example>
  127.90 +        /// Subscript: H_{2}O
  127.91 +        /// Superscript: E=mc^{2}
  127.92 +        /// Both: A^{2}_{i,j}
  127.93 +        /// </example>
  127.94 +        public static OxySize DrawMathText(
  127.95 +            this IRenderContext rc,
  127.96 +            ScreenPoint pt,
  127.97 +            string text,
  127.98 +            OxyColor textColor,
  127.99 +            string fontFamily,
 127.100 +            double fontSize,
 127.101 +            double fontWeight,
 127.102 +            double angle,
 127.103 +            HorizontalAlignment ha,
 127.104 +            VerticalAlignment va,
 127.105 +            OxySize? maxsize,
 127.106 +            bool measure)
 127.107 +        {
 127.108 +            if (string.IsNullOrEmpty(text))
 127.109 +            {
 127.110 +                return OxySize.Empty;
 127.111 +            }
 127.112 +
 127.113 +            if (angle.Equals(0) && (text.Contains("^{") || text.Contains("_{")))
 127.114 +            {
 127.115 +                double x = pt.X;
 127.116 +                double y = pt.Y;
 127.117 +
 127.118 +                // Measure
 127.119 +                var size = InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, true);
 127.120 +
 127.121 +                switch (ha)
 127.122 +                {
 127.123 +                    case HorizontalAlignment.Right:
 127.124 +                        x -= size.Width;
 127.125 +                        break;
 127.126 +                    case HorizontalAlignment.Center:
 127.127 +                        x -= size.Width * 0.5;
 127.128 +                        break;
 127.129 +                }
 127.130 +
 127.131 +                switch (va)
 127.132 +                {
 127.133 +                    case VerticalAlignment.Bottom:
 127.134 +                        y -= size.Height;
 127.135 +                        break;
 127.136 +                    case VerticalAlignment.Middle:
 127.137 +                        y -= size.Height * 0.5;
 127.138 +                        break;
 127.139 +                }
 127.140 +
 127.141 +                InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, false);
 127.142 +                return measure ? size : OxySize.Empty;
 127.143 +            }
 127.144 +
 127.145 +            rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize);
 127.146 +            if (measure)
 127.147 +            {
 127.148 +                return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
 127.149 +            }
 127.150 +
 127.151 +            return OxySize.Empty;
 127.152 +        }
 127.153 +
 127.154 +        /// <summary>
 127.155 +        /// Draws text containing sub- and superscript.
 127.156 +        /// </summary>
 127.157 +        /// <param name="rc">The render context.</param>
 127.158 +        /// <param name="pt">The point.</param>
 127.159 +        /// <param name="text">The text.</param>
 127.160 +        /// <param name="textColor">Color of the text.</param>
 127.161 +        /// <param name="fontFamily">The font family.</param>
 127.162 +        /// <param name="fontSize">The font size.</param>
 127.163 +        /// <param name="fontWeight">The font weight.</param>
 127.164 +        /// <param name="angle">The angle.</param>
 127.165 +        /// <param name="ha">The horizontal alignment.</param>
 127.166 +        /// <param name="va">The vertical alignment.</param>
 127.167 +        /// <param name="maxsize">The maximum size of the text.</param>
 127.168 +        /// <example>
 127.169 +        /// Subscript: H_{2}O
 127.170 +        /// Superscript: E=mc^{2}
 127.171 +        /// Both: A^{2}_{i,j}
 127.172 +        /// </example>
 127.173 +        public static void DrawMathText(
 127.174 +            this IRenderContext rc,
 127.175 +            ScreenPoint pt,
 127.176 +            string text,
 127.177 +            OxyColor textColor,
 127.178 +            string fontFamily,
 127.179 +            double fontSize,
 127.180 +            double fontWeight,
 127.181 +            double angle,
 127.182 +            HorizontalAlignment ha,
 127.183 +            VerticalAlignment va,
 127.184 +            OxySize? maxsize = null)
 127.185 +        {
 127.186 +            DrawMathText(rc, pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize, false);
 127.187 +        }
 127.188 +
 127.189 +        /// <summary>
 127.190 +        /// The measure math text.
 127.191 +        /// </summary>
 127.192 +        /// <param name="rc">
 127.193 +        /// The render context.
 127.194 +        /// </param>
 127.195 +        /// <param name="text">
 127.196 +        /// The text.
 127.197 +        /// </param>
 127.198 +        /// <param name="fontFamily">
 127.199 +        /// The font family.
 127.200 +        /// </param>
 127.201 +        /// <param name="fontSize">
 127.202 +        /// The font size.
 127.203 +        /// </param>
 127.204 +        /// <param name="fontWeight">
 127.205 +        /// The font weight.
 127.206 +        /// </param>
 127.207 +        /// <returns>
 127.208 +        /// The size of the text.
 127.209 +        /// </returns>
 127.210 +        public static OxySize MeasureMathText(
 127.211 +            this IRenderContext rc, string text, string fontFamily, double fontSize, double fontWeight)
 127.212 +        {
 127.213 +            if (text.Contains("^{") || text.Contains("_{"))
 127.214 +            {
 127.215 +                return InternalDrawMathText(rc, 0, 0, text, null, fontFamily, fontSize, fontWeight, true);
 127.216 +            }
 127.217 +
 127.218 +            return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
 127.219 +        }
 127.220 +
 127.221 +        /// <summary>
 127.222 +        /// The internal draw math text.
 127.223 +        /// </summary>
 127.224 +        /// <param name="rc">
 127.225 +        /// The render context.
 127.226 +        /// </param>
 127.227 +        /// <param name="x">
 127.228 +        /// The x.
 127.229 +        /// </param>
 127.230 +        /// <param name="y">
 127.231 +        /// The y.
 127.232 +        /// </param>
 127.233 +        /// <param name="s">
 127.234 +        /// The s.
 127.235 +        /// </param>
 127.236 +        /// <param name="textColor">
 127.237 +        /// The text color.
 127.238 +        /// </param>
 127.239 +        /// <param name="fontFamily">
 127.240 +        /// The font family.
 127.241 +        /// </param>
 127.242 +        /// <param name="fontSize">
 127.243 +        /// The font size.
 127.244 +        /// </param>
 127.245 +        /// <param name="fontWeight">
 127.246 +        /// The font weight.
 127.247 +        /// </param>
 127.248 +        /// <param name="measureOnly">
 127.249 +        /// The measure only.
 127.250 +        /// </param>
 127.251 +        /// <returns>
 127.252 +        /// The size of the text.
 127.253 +        /// </returns>
 127.254 +        private static OxySize InternalDrawMathText(
 127.255 +            IRenderContext rc,
 127.256 +            double x,
 127.257 +            double y,
 127.258 +            string s,
 127.259 +            OxyColor textColor,
 127.260 +            string fontFamily,
 127.261 +            double fontSize,
 127.262 +            double fontWeight,
 127.263 +            bool measureOnly)
 127.264 +        {
 127.265 +            int i = 0;
 127.266 +
 127.267 +            double currentX = x;
 127.268 +            double maximumX = x;
 127.269 +            double maxHeight = 0;
 127.270 +
 127.271 +            // http://en.wikipedia.org/wiki/Subscript_and_superscript
 127.272 +            double superscriptY = y + fontSize * SuperAlignment;
 127.273 +            double superscriptFontSize = fontSize * SuperSize;
 127.274 +            double subscriptY = y + fontSize * SubAlignment;
 127.275 +            double subscriptFontSize = fontSize * SubSize;
 127.276 +
 127.277 +            Func<double, double, string, double, OxySize> drawText = (xb, yb, text, fSize) =>
 127.278 +                {
 127.279 +                    if (!measureOnly)
 127.280 +                    {
 127.281 +                        rc.DrawText(new ScreenPoint(xb, yb), text, textColor, fontFamily, fSize, fontWeight);
 127.282 +                    }
 127.283 +
 127.284 +                    return rc.MeasureText(text, fontFamily, fSize, fontWeight);
 127.285 +                };
 127.286 +
 127.287 +            while (i < s.Length)
 127.288 +            {
 127.289 +                // Superscript
 127.290 +                if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{')
 127.291 +                {
 127.292 +                    int i1 = s.IndexOf('}', i);
 127.293 +                    if (i1 != -1)
 127.294 +                    {
 127.295 +                        string supString = s.Substring(i + 2, i1 - i - 2);
 127.296 +                        i = i1 + 1;
 127.297 +                        OxySize size = drawText(currentX, superscriptY, supString, superscriptFontSize);
 127.298 +                        if (currentX + size.Width > maximumX)
 127.299 +                        {
 127.300 +                            maximumX = currentX + size.Width;
 127.301 +                        }
 127.302 +
 127.303 +                        continue;
 127.304 +                    }
 127.305 +                }
 127.306 +
 127.307 +                // Subscript
 127.308 +                if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{')
 127.309 +                {
 127.310 +                    int i1 = s.IndexOf('}', i);
 127.311 +                    if (i1 != -1)
 127.312 +                    {
 127.313 +                        string subString = s.Substring(i + 2, i1 - i - 2);
 127.314 +                        i = i1 + 1;
 127.315 +                        OxySize size = drawText(currentX, subscriptY, subString, subscriptFontSize);
 127.316 +                        if (currentX + size.Width > maximumX)
 127.317 +                        {
 127.318 +                            maximumX = currentX + size.Width;
 127.319 +                        }
 127.320 +
 127.321 +                        continue;
 127.322 +                    }
 127.323 +                }
 127.324 +
 127.325 +                // Regular text
 127.326 +                int i2 = s.IndexOfAny("^_".ToCharArray(), i);
 127.327 +                string regularString;
 127.328 +                if (i2 == -1)
 127.329 +                {
 127.330 +                    regularString = s.Substring(i);
 127.331 +                    i = s.Length;
 127.332 +                }
 127.333 +                else
 127.334 +                {
 127.335 +                    regularString = s.Substring(i, i2 - i);
 127.336 +                    i = i2;
 127.337 +                }
 127.338 +
 127.339 +                currentX = maximumX + 2;
 127.340 +                OxySize size2 = drawText(currentX, y, regularString, fontSize);
 127.341 +                currentX += size2.Width + 2;
 127.342 +                maxHeight = Math.Max(maxHeight, size2.Height);
 127.343 +                maximumX = currentX;
 127.344 +            }
 127.345 +
 127.346 +            return new OxySize(maximumX - x, maxHeight);
 127.347 +        }
 127.348 +
 127.349 +    }
 127.350 +}
 127.351 \ No newline at end of file
   128.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.2 +++ b/External/OxyPlot/OxyPlot/Render/PlotRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   128.3 @@ -0,0 +1,159 @@
   128.4 +// --------------------------------------------------------------------------------------------------------------------
   128.5 +// <copyright file="PlotRenderer.cs" company="OxyPlot">
   128.6 +//   The MIT License (MIT)
   128.7 +//
   128.8 +//   Copyright (c) 2012 Oystein Bjorke
   128.9 +//
  128.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  128.11 +//   copy of this software and associated documentation files (the
  128.12 +//   "Software"), to deal in the Software without restriction, including
  128.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  128.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  128.15 +//   permit persons to whom the Software is furnished to do so, subject to
  128.16 +//   the following conditions:
  128.17 +//
  128.18 +//   The above copyright notice and this permission notice shall be included
  128.19 +//   in all copies or substantial portions of the Software.
  128.20 +//
  128.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  128.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  128.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  128.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  128.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  128.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  128.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  128.28 +// </copyright>
  128.29 +// --------------------------------------------------------------------------------------------------------------------
  128.30 +using System;
  128.31 +
  128.32 +namespace OxyPlot
  128.33 +{
  128.34 +    public class PlotRenderer
  128.35 +    {
  128.36 +        protected readonly PlotModel plot;
  128.37 +        protected readonly IRenderContext rc;
  128.38 +
  128.39 +        public PlotRenderer(IRenderContext rc, PlotModel p)
  128.40 +        {
  128.41 +            this.rc = rc;
  128.42 +            plot = p;
  128.43 +        }
  128.44 +
  128.45 +        public void RenderTitle(string title, string subtitle)
  128.46 +        {
  128.47 +            OxySize size1 = rc.MeasureText(title, plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight);
  128.48 +            OxySize size2 = rc.MeasureText(subtitle, plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight);
  128.49 +            double height = size1.Height + size2.Height;
  128.50 +            double dy = (plot.AxisMargins.Top - height) * 0.5;
  128.51 +            double dx = (plot.Bounds.Left + plot.Bounds.Right) * 0.5;
  128.52 +
  128.53 +            if (!String.IsNullOrEmpty(title))
  128.54 +                rc.DrawText(
  128.55 +                    new ScreenPoint(dx, dy), title, plot.TextColor,
  128.56 +                    plot.TitleFont, plot.TitleFontSize, plot.TitleFontWeight,
  128.57 +                    0,
  128.58 +                    HorizontalTextAlign.Center, VerticalTextAlign.Top);
  128.59 +            if (!String.IsNullOrEmpty(subtitle))
  128.60 +                rc.DrawText(new ScreenPoint(dx, dy + size1.Height), subtitle, plot.TextColor,
  128.61 +                            plot.TitleFont, plot.SubtitleFontSize, plot.SubtitleFontWeight, 0,
  128.62 +                            HorizontalTextAlign.Center, VerticalTextAlign.Top);
  128.63 +        }
  128.64 +
  128.65 +        public void RenderRect(OxyRect bounds, OxyColor fill, OxyColor borderColor, double borderThickness)
  128.66 +        {
  128.67 +            var border = new[]
  128.68 +                             {
  128.69 +                                 new ScreenPoint(bounds.Left, bounds.Top), new ScreenPoint(bounds.Right, bounds.Top),
  128.70 +                                 new ScreenPoint(bounds.Right, bounds.Bottom), new ScreenPoint(bounds.Left, bounds.Bottom),
  128.71 +                                 new ScreenPoint(bounds.Left, bounds.Top)
  128.72 +                             };
  128.73 +
  128.74 +            rc.DrawPolygon(border, fill, borderColor, borderThickness, null, true);
  128.75 +        }
  128.76 +
  128.77 +        private static readonly double LEGEND_PADDING = 8;
  128.78 +
  128.79 +        public void RenderLegends()
  128.80 +        {
  128.81 +            double maxWidth = 0;
  128.82 +            double maxHeight = 0;
  128.83 +            double totalHeight = 0;
  128.84 +
  128.85 +            // Measure
  128.86 +            foreach (var s in plot.Series)
  128.87 +            {
  128.88 +                if (String.IsNullOrEmpty(s.Title))
  128.89 +                    continue;
  128.90 +                var oxySize = rc.MeasureText(s.Title, plot.LegendFont, plot.LegendFontSize);
  128.91 +                if (oxySize.Width > maxWidth) maxWidth = oxySize.Width;
  128.92 +                if (oxySize.Height > maxHeight) maxHeight = oxySize.Height;
  128.93 +                totalHeight += oxySize.Height;
  128.94 +            }
  128.95 +
  128.96 +            double lineLength = plot.LegendSymbolLength;
  128.97 +
  128.98 +            // Arrange
  128.99 +            double x0 = double.NaN, x1 = double.NaN, y0 = double.NaN;
 128.100 +
 128.101 +            //   padding          padding
 128.102 +            //          lineLength
 128.103 +            // y0       -----o----       seriesName
 128.104 +            //          x0               x1
 128.105 +
 128.106 +            double sign = 1;
 128.107 +            if (plot.IsLegendOutsidePlotArea)
 128.108 +                sign = -1;
 128.109 +
 128.110 +            // Horizontal alignment
 128.111 +            HorizontalTextAlign ha = HorizontalTextAlign.Left;
 128.112 +            switch (plot.LegendPosition)
 128.113 +            {
 128.114 +                case LegendPosition.TopRight:
 128.115 +                case LegendPosition.BottomRight:
 128.116 +                    x0 = plot.Bounds.Right - LEGEND_PADDING * sign;
 128.117 +                    x1 = x0 - lineLength * sign - LEGEND_PADDING * sign;
 128.118 +                    ha = sign == 1 ? HorizontalTextAlign.Right : HorizontalTextAlign.Left;
 128.119 +                    break;
 128.120 +                case LegendPosition.TopLeft:
 128.121 +                case LegendPosition.BottomLeft:
 128.122 +                    x0 = plot.Bounds.Left + LEGEND_PADDING * sign;
 128.123 +                    x1 = x0 + lineLength * sign + LEGEND_PADDING * sign;
 128.124 +                    ha = sign == 1 ? HorizontalTextAlign.Left : HorizontalTextAlign.Right;
 128.125 +                    break;
 128.126 +            }
 128.127 +
 128.128 +            // Vertical alignment
 128.129 +            VerticalTextAlign va = VerticalTextAlign.Middle;
 128.130 +            switch (plot.LegendPosition)
 128.131 +            {
 128.132 +                case LegendPosition.TopRight:
 128.133 +                case LegendPosition.TopLeft:
 128.134 +                    y0 = plot.Bounds.Top + LEGEND_PADDING + maxHeight / 2;
 128.135 +                    break;
 128.136 +                case LegendPosition.BottomRight:
 128.137 +                case LegendPosition.BottomLeft:
 128.138 +                    y0 = plot.Bounds.Bottom - maxHeight + LEGEND_PADDING;
 128.139 +                    break;
 128.140 +            }
 128.141 +
 128.142 +            foreach (var s in plot.Series)
 128.143 +            {
 128.144 +                if (String.IsNullOrEmpty(s.Title))
 128.145 +                    continue;
 128.146 +                rc.DrawText(new ScreenPoint(x1, y0),
 128.147 +                            s.Title, plot.TextColor,
 128.148 +                            plot.LegendFont, plot.LegendFontSize, 500, 0,
 128.149 +                            ha, va);
 128.150 +                OxyRect rect = new OxyRect(x0 - lineLength, y0 - maxHeight / 2, lineLength, maxHeight);
 128.151 +                if (ha == HorizontalTextAlign.Left)
 128.152 +                    rect = new OxyRect(x0, y0 - maxHeight / 2, lineLength, maxHeight);
 128.153 +
 128.154 +                s.RenderLegend(rc, rect);
 128.155 +                if (plot.LegendPosition == LegendPosition.TopLeft || plot.LegendPosition == LegendPosition.TopRight)
 128.156 +                    y0 += maxHeight;
 128.157 +                else
 128.158 +                    y0 -= maxHeight;
 128.159 +            }
 128.160 +        }
 128.161 +    }
 128.162 +}
 128.163 \ No newline at end of file
   129.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.2 +++ b/External/OxyPlot/OxyPlot/Render/RenderContextBase.cs	Sat Jun 08 16:53:22 2013 +0000
   129.3 @@ -0,0 +1,423 @@
   129.4 +// --------------------------------------------------------------------------------------------------------------------
   129.5 +// <copyright file="RenderContextBase.cs" company="OxyPlot">
   129.6 +//   The MIT License (MIT)
   129.7 +//
   129.8 +//   Copyright (c) 2012 Oystein Bjorke
   129.9 +//
  129.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  129.11 +//   copy of this software and associated documentation files (the
  129.12 +//   "Software"), to deal in the Software without restriction, including
  129.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  129.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  129.15 +//   permit persons to whom the Software is furnished to do so, subject to
  129.16 +//   the following conditions:
  129.17 +//
  129.18 +//   The above copyright notice and this permission notice shall be included
  129.19 +//   in all copies or substantial portions of the Software.
  129.20 +//
  129.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  129.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  129.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  129.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  129.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  129.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  129.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  129.28 +// </copyright>
  129.29 +// <summary>
  129.30 +//   The abstract render context base class.
  129.31 +// </summary>
  129.32 +// --------------------------------------------------------------------------------------------------------------------
  129.33 +namespace OxyPlot
  129.34 +{
  129.35 +    using System.Collections.Generic;
  129.36 +
  129.37 +    /// <summary>
  129.38 +    /// Provides an abstract base class for rendering contexts.
  129.39 +    /// </summary>
  129.40 +    public abstract class RenderContextBase : IRenderContext
  129.41 +    {
  129.42 +        /// <summary>
  129.43 +        /// Initializes a new instance of the <see cref="RenderContextBase" /> class.
  129.44 +        /// </summary>
  129.45 +        protected RenderContextBase()
  129.46 +        {
  129.47 +            this.RendersToScreen = true;
  129.48 +        }
  129.49 +
  129.50 +        /// <summary>
  129.51 +        /// Gets or sets a value indicating whether the context renders to screen.
  129.52 +        /// </summary>
  129.53 +        /// <value>
  129.54 +        /// <c>true</c> if the context renders to screen; otherwise, <c>false</c>.
  129.55 +        /// </value>
  129.56 +        public bool RendersToScreen { get; set; }
  129.57 +
  129.58 +        /// <summary>
  129.59 +        /// Draws an ellipse.
  129.60 +        /// </summary>
  129.61 +        /// <param name="rect">
  129.62 +        /// The rectangle.
  129.63 +        /// </param>
  129.64 +        /// <param name="fill">
  129.65 +        /// The fill color.
  129.66 +        /// </param>
  129.67 +        /// <param name="stroke">
  129.68 +        /// The stroke color.
  129.69 +        /// </param>
  129.70 +        /// <param name="thickness">
  129.71 +        /// The thickness.
  129.72 +        /// </param>
  129.73 +        public abstract void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
  129.74 +
  129.75 +        /// <summary>
  129.76 +        /// Draws the collection of ellipses, where all have the same stroke and fill.
  129.77 +        /// This performs better than calling DrawEllipse multiple times.
  129.78 +        /// </summary>
  129.79 +        /// <param name="rectangles">
  129.80 +        /// The rectangles.
  129.81 +        /// </param>
  129.82 +        /// <param name="fill">
  129.83 +        /// The fill color.
  129.84 +        /// </param>
  129.85 +        /// <param name="stroke">
  129.86 +        /// The stroke color.
  129.87 +        /// </param>
  129.88 +        /// <param name="thickness">
  129.89 +        /// The stroke thickness.
  129.90 +        /// </param>
  129.91 +        public virtual void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness)
  129.92 +        {
  129.93 +            foreach (var r in rectangles)
  129.94 +            {
  129.95 +                this.DrawEllipse(r, fill, stroke, thickness);
  129.96 +            }
  129.97 +        }
  129.98 +
  129.99 +        /// <summary>
 129.100 +        /// Draws the polyline from the specified points.
 129.101 +        /// </summary>
 129.102 +        /// <param name="points">
 129.103 +        /// The points.
 129.104 +        /// </param>
 129.105 +        /// <param name="stroke">
 129.106 +        /// The stroke color.
 129.107 +        /// </param>
 129.108 +        /// <param name="thickness">
 129.109 +        /// The stroke thickness.
 129.110 +        /// </param>
 129.111 +        /// <param name="dashArray">
 129.112 +        /// The dash array.
 129.113 +        /// </param>
 129.114 +        /// <param name="lineJoin">
 129.115 +        /// The line join type.
 129.116 +        /// </param>
 129.117 +        /// <param name="aliased">
 129.118 +        /// if set to <c>true</c> the shape will be aliased.
 129.119 +        /// </param>
 129.120 +        public abstract void DrawLine(
 129.121 +            IList<ScreenPoint> points,
 129.122 +            OxyColor stroke,
 129.123 +            double thickness,
 129.124 +            double[] dashArray,
 129.125 +            OxyPenLineJoin lineJoin,
 129.126 +            bool aliased);
 129.127 +
 129.128 +        /// <summary>
 129.129 +        /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc.
 129.130 +        /// This should have better performance than calling DrawLine for each segment.
 129.131 +        /// </summary>
 129.132 +        /// <param name="points">
 129.133 +        /// The points.
 129.134 +        /// </param>
 129.135 +        /// <param name="stroke">
 129.136 +        /// The stroke color.
 129.137 +        /// </param>
 129.138 +        /// <param name="thickness">
 129.139 +        /// The stroke thickness.
 129.140 +        /// </param>
 129.141 +        /// <param name="dashArray">
 129.142 +        /// The dash array.
 129.143 +        /// </param>
 129.144 +        /// <param name="lineJoin">
 129.145 +        /// The line join type.
 129.146 +        /// </param>
 129.147 +        /// <param name="aliased">
 129.148 +        /// if set to <c>true</c> the shape will be aliased.
 129.149 +        /// </param>
 129.150 +        public virtual void DrawLineSegments(
 129.151 +            IList<ScreenPoint> points,
 129.152 +            OxyColor stroke,
 129.153 +            double thickness,
 129.154 +            double[] dashArray,
 129.155 +            OxyPenLineJoin lineJoin,
 129.156 +            bool aliased)
 129.157 +        {
 129.158 +            for (int i = 0; i + 1 < points.Count; i += 2)
 129.159 +            {
 129.160 +                this.DrawLine(new[] { points[i], points[i + 1] }, stroke, thickness, dashArray, lineJoin, aliased);
 129.161 +            }
 129.162 +        }
 129.163 +
 129.164 +        /// <summary>
 129.165 +        /// Draws the polygon from the specified points. The polygon can have stroke and/or fill.
 129.166 +        /// </summary>
 129.167 +        /// <param name="points">
 129.168 +        /// The points.
 129.169 +        /// </param>
 129.170 +        /// <param name="fill">
 129.171 +        /// The fill color.
 129.172 +        /// </param>
 129.173 +        /// <param name="stroke">
 129.174 +        /// The stroke color.
 129.175 +        /// </param>
 129.176 +        /// <param name="thickness">
 129.177 +        /// The stroke thickness.
 129.178 +        /// </param>
 129.179 +        /// <param name="dashArray">
 129.180 +        /// The dash array.
 129.181 +        /// </param>
 129.182 +        /// <param name="lineJoin">
 129.183 +        /// The line join type.
 129.184 +        /// </param>
 129.185 +        /// <param name="aliased">
 129.186 +        /// if set to <c>true</c> the shape will be aliased.
 129.187 +        /// </param>
 129.188 +        public abstract void DrawPolygon(
 129.189 +            IList<ScreenPoint> points,
 129.190 +            OxyColor fill,
 129.191 +            OxyColor stroke,
 129.192 +            double thickness,
 129.193 +            double[] dashArray,
 129.194 +            OxyPenLineJoin lineJoin,
 129.195 +            bool aliased);
 129.196 +
 129.197 +        /// <summary>
 129.198 +        /// Draws a collection of polygons, where all polygons have the same stroke and fill.
 129.199 +        /// This performs better than calling DrawPolygon multiple times.
 129.200 +        /// </summary>
 129.201 +        /// <param name="polygons">
 129.202 +        /// The polygons.
 129.203 +        /// </param>
 129.204 +        /// <param name="fill">
 129.205 +        /// The fill color.
 129.206 +        /// </param>
 129.207 +        /// <param name="stroke">
 129.208 +        /// The stroke color.
 129.209 +        /// </param>
 129.210 +        /// <param name="thickness">
 129.211 +        /// The stroke thickness.
 129.212 +        /// </param>
 129.213 +        /// <param name="dashArray">
 129.214 +        /// The dash array.
 129.215 +        /// </param>
 129.216 +        /// <param name="lineJoin">
 129.217 +        /// The line join type.
 129.218 +        /// </param>
 129.219 +        /// <param name="aliased">
 129.220 +        /// if set to <c>true</c> the shape will be aliased.
 129.221 +        /// </param>
 129.222 +        public virtual void DrawPolygons(
 129.223 +            IList<IList<ScreenPoint>> polygons,
 129.224 +            OxyColor fill,
 129.225 +            OxyColor stroke,
 129.226 +            double thickness,
 129.227 +            double[] dashArray,
 129.228 +            OxyPenLineJoin lineJoin,
 129.229 +            bool aliased)
 129.230 +        {
 129.231 +            foreach (var polygon in polygons)
 129.232 +            {
 129.233 +                this.DrawPolygon(polygon, fill, stroke, thickness, dashArray, lineJoin, aliased);
 129.234 +            }
 129.235 +        }
 129.236 +
 129.237 +        /// <summary>
 129.238 +        /// Draws the rectangle.
 129.239 +        /// </summary>
 129.240 +        /// <param name="rect">
 129.241 +        /// The rectangle.
 129.242 +        /// </param>
 129.243 +        /// <param name="fill">
 129.244 +        /// The fill color.
 129.245 +        /// </param>
 129.246 +        /// <param name="stroke">
 129.247 +        /// The stroke color.
 129.248 +        /// </param>
 129.249 +        /// <param name="thickness">
 129.250 +        /// The stroke thickness.
 129.251 +        /// </param>
 129.252 +        public abstract void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
 129.253 +
 129.254 +        /// <summary>
 129.255 +        /// Draws a collection of rectangles, where all have the same stroke and fill.
 129.256 +        /// This performs better than calling DrawRectangle multiple times.
 129.257 +        /// </summary>
 129.258 +        /// <param name="rectangles">
 129.259 +        /// The rectangles.
 129.260 +        /// </param>
 129.261 +        /// <param name="fill">
 129.262 +        /// The fill color.
 129.263 +        /// </param>
 129.264 +        /// <param name="stroke">
 129.265 +        /// The stroke color.
 129.266 +        /// </param>
 129.267 +        /// <param name="thickness">
 129.268 +        /// The stroke thickness.
 129.269 +        /// </param>
 129.270 +        public virtual void DrawRectangles(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness)
 129.271 +        {
 129.272 +            foreach (var r in rectangles)
 129.273 +            {
 129.274 +                this.DrawRectangle(r, fill, stroke, thickness);
 129.275 +            }
 129.276 +        }
 129.277 +
 129.278 +        /// <summary>
 129.279 +        /// Draws the text.
 129.280 +        /// </summary>
 129.281 +        /// <param name="p">
 129.282 +        /// The p.
 129.283 +        /// </param>
 129.284 +        /// <param name="text">
 129.285 +        /// The text.
 129.286 +        /// </param>
 129.287 +        /// <param name="fill">
 129.288 +        /// The fill color.
 129.289 +        /// </param>
 129.290 +        /// <param name="fontFamily">
 129.291 +        /// The font family.
 129.292 +        /// </param>
 129.293 +        /// <param name="fontSize">
 129.294 +        /// Size of the font.
 129.295 +        /// </param>
 129.296 +        /// <param name="fontWeight">
 129.297 +        /// The font weight.
 129.298 +        /// </param>
 129.299 +        /// <param name="rotate">
 129.300 +        /// The rotation angle.
 129.301 +        /// </param>
 129.302 +        /// <param name="halign">
 129.303 +        /// The horizontal alignment.
 129.304 +        /// </param>
 129.305 +        /// <param name="valign">
 129.306 +        /// The vertical alignment.
 129.307 +        /// </param>
 129.308 +        /// <param name="maxSize">
 129.309 +        /// The maximum size of the text.
 129.310 +        /// </param>
 129.311 +        public abstract void DrawText(
 129.312 +            ScreenPoint p,
 129.313 +            string text,
 129.314 +            OxyColor fill,
 129.315 +            string fontFamily,
 129.316 +            double fontSize,
 129.317 +            double fontWeight,
 129.318 +            double rotate,
 129.319 +            HorizontalAlignment halign,
 129.320 +            VerticalAlignment valign,
 129.321 +            OxySize? maxSize);
 129.322 +
 129.323 +        /// <summary>
 129.324 +        /// Measures the text.
 129.325 +        /// </summary>
 129.326 +        /// <param name="text">
 129.327 +        /// The text.
 129.328 +        /// </param>
 129.329 +        /// <param name="fontFamily">
 129.330 +        /// The font family.
 129.331 +        /// </param>
 129.332 +        /// <param name="fontSize">
 129.333 +        /// Size of the font.
 129.334 +        /// </param>
 129.335 +        /// <param name="fontWeight">
 129.336 +        /// The font weight.
 129.337 +        /// </param>
 129.338 +        /// <returns>
 129.339 +        /// The text size.
 129.340 +        /// </returns>
 129.341 +        public abstract OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight);
 129.342 +
 129.343 +        /// <summary>
 129.344 +        /// Sets the tool tip for the following items.
 129.345 +        /// </summary>
 129.346 +        /// <param name="text">
 129.347 +        /// The text in the tooltip.
 129.348 +        /// </param>
 129.349 +        /// <params>
 129.350 +        /// This is only used in the plot controls.
 129.351 +        /// </params>
 129.352 +        public virtual void SetToolTip(string text)
 129.353 +        {
 129.354 +        }
 129.355 +
 129.356 +        /// <summary>
 129.357 +        /// Cleans up resources not in use.
 129.358 +        /// </summary>
 129.359 +        /// <remarks>
 129.360 +        /// This method is called at the end of each rendering.
 129.361 +        /// </remarks>
 129.362 +        public virtual void CleanUp()
 129.363 +        {
 129.364 +        }
 129.365 +
 129.366 +        /// <summary>
 129.367 +        /// Gets the size of the specified image.
 129.368 +        /// </summary>
 129.369 +        /// <param name="source">The image source.</param>
 129.370 +        /// <returns>
 129.371 +        /// The image info.
 129.372 +        /// </returns>
 129.373 +        public virtual OxyImageInfo GetImageInfo(OxyImage source)
 129.374 +        {
 129.375 +            return null;
 129.376 +        }
 129.377 +
 129.378 +        /// <summary>
 129.379 +        /// Draws the image.
 129.380 +        /// </summary>
 129.381 +        /// <param name="source">The source.</param>
 129.382 +        /// <param name="srcX">The SRC X.</param>
 129.383 +        /// <param name="srcY">The SRC Y.</param>
 129.384 +        /// <param name="srcWidth">Width of the SRC.</param>
 129.385 +        /// <param name="srcHeight">Height of the SRC.</param>
 129.386 +        /// <param name="x">The x.</param>
 129.387 +        /// <param name="y">The y.</param>
 129.388 +        /// <param name="w">The w.</param>
 129.389 +        /// <param name="h">The h.</param>
 129.390 +        /// <param name="opacity">The opacity.</param>
 129.391 +        /// <param name="interpolate">interpolate if set to <c>true</c>.</param>
 129.392 +        public virtual void DrawImage(
 129.393 +            OxyImage source,
 129.394 +            uint srcX,
 129.395 +            uint srcY,
 129.396 +            uint srcWidth,
 129.397 +            uint srcHeight,
 129.398 +            double x,
 129.399 +            double y,
 129.400 +            double w,
 129.401 +            double h,
 129.402 +            double opacity,
 129.403 +            bool interpolate)
 129.404 +        {
 129.405 +        }
 129.406 +
 129.407 +        /// <summary>
 129.408 +        /// Sets the clip rectangle.
 129.409 +        /// </summary>
 129.410 +        /// <param name="rect">The clip rectangle.</param>
 129.411 +        /// <returns>
 129.412 +        /// True if the clip rectangle was set.
 129.413 +        /// </returns>
 129.414 +        public virtual bool SetClip(OxyRect rect)
 129.415 +        {
 129.416 +            return false;
 129.417 +        }
 129.418 +
 129.419 +        /// <summary>
 129.420 +        /// Resets the clip rectangle.
 129.421 +        /// </summary>
 129.422 +        public virtual void ResetClip()
 129.423 +        {
 129.424 +        }
 129.425 +    }
 129.426 +}
 129.427 \ No newline at end of file
   130.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.2 +++ b/External/OxyPlot/OxyPlot/Render/RenderingExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
   130.3 @@ -0,0 +1,1109 @@
   130.4 +// --------------------------------------------------------------------------------------------------------------------
   130.5 +// <copyright file="RenderingExtensions.cs" company="OxyPlot">
   130.6 +//   The MIT License (MIT)
   130.7 +//   
   130.8 +//   Copyright (c) 2012 Oystein Bjorke
   130.9 +//   
  130.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  130.11 +//   copy of this software and associated documentation files (the
  130.12 +//   "Software"), to deal in the Software without restriction, including
  130.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  130.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  130.15 +//   permit persons to whom the Software is furnished to do so, subject to
  130.16 +//   the following conditions:
  130.17 +//   
  130.18 +//   The above copyright notice and this permission notice shall be included
  130.19 +//   in all copies or substantial portions of the Software.
  130.20 +//   
  130.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  130.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  130.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  130.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  130.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  130.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  130.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  130.28 +// </copyright>
  130.29 +// <summary>
  130.30 +//   The rendering extensions.
  130.31 +// </summary>
  130.32 +// --------------------------------------------------------------------------------------------------------------------
  130.33 +
  130.34 +namespace OxyPlot
  130.35 +{
  130.36 +    using System;
  130.37 +    using System.Collections.Generic;
  130.38 +    using System.Linq;
  130.39 +
  130.40 +    /// <summary>
  130.41 +    /// Provides extension methods for <see cref="IRenderContext"/>.
  130.42 +    /// </summary>
  130.43 +    public static class RenderingExtensions
  130.44 +    {
  130.45 +        /* Length constants used to draw triangles and stars
  130.46 +                             ___
  130.47 +         /\                   |
  130.48 +         /  \                 |
  130.49 +         /    \               | M2
  130.50 +         /      \             |
  130.51 +         /        \           |
  130.52 +         /     +    \        ---
  130.53 +         /            \       |
  130.54 +         /              \     | M1
  130.55 +         /________________\  _|_
  130.56 +         |--------|-------|
  130.57 +              1       1
  130.58 +        
  130.59 +                  |
  130.60 +            \     |     /     ---
  130.61 +              \   |   /        | M3
  130.62 +                \ | /          |
  130.63 +         ---------+--------   ---
  130.64 +                / | \          | M3
  130.65 +              /   |   \        |
  130.66 +            /     |     \     ---
  130.67 +                  |
  130.68 +            |-----|-----|
  130.69 +               M3    M3
  130.70 +        */
  130.71 +
  130.72 +        /// <summary>
  130.73 +        /// The vertical distance to the bottom points of the triangles.
  130.74 +        /// </summary>
  130.75 +        private static readonly double M1 = Math.Tan(Math.PI / 6);
  130.76 +
  130.77 +        /// <summary>
  130.78 +        /// The vertical distance to the top points of the triangles .
  130.79 +        /// </summary>
  130.80 +        private static readonly double M2 = Math.Sqrt(1 + (M1 * M1));
  130.81 +
  130.82 +        /// <summary>
  130.83 +        /// The horizontal/vertical distance to the end points of the stars.
  130.84 +        /// </summary>
  130.85 +        private static readonly double M3 = Math.Tan(Math.PI / 4);
  130.86 +
  130.87 +        /// <summary>
  130.88 +        /// Draws the clipped line.
  130.89 +        /// </summary>
  130.90 +        /// <param name="rc">The render context.</param>
  130.91 +        /// <param name="points">The points.</param>
  130.92 +        /// <param name="clippingRectangle">The clipping rectangle.</param>
  130.93 +        /// <param name="minDistSquared">The squared minimum distance.</param>
  130.94 +        /// <param name="stroke">The stroke.</param>
  130.95 +        /// <param name="strokeThickness">The stroke thickness.</param>
  130.96 +        /// <param name="lineStyle">The line style.</param>
  130.97 +        /// <param name="lineJoin">The line join.</param>
  130.98 +        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
  130.99 +        /// <param name="pointsRendered">The points rendered callback.</param>
 130.100 +        public static void DrawClippedLine(
 130.101 +            this IRenderContext rc,
 130.102 +            IList<ScreenPoint> points,
 130.103 +            OxyRect clippingRectangle,
 130.104 +            double minDistSquared,
 130.105 +            OxyColor stroke,
 130.106 +            double strokeThickness,
 130.107 +            LineStyle lineStyle,
 130.108 +            OxyPenLineJoin lineJoin,
 130.109 +            bool aliased,
 130.110 +            Action<IList<ScreenPoint>> pointsRendered = null)
 130.111 +        {
 130.112 +            var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom);
 130.113 +
 130.114 +            var pts = new List<ScreenPoint>();
 130.115 +            int n = points.Count;
 130.116 +            if (n > 0)
 130.117 +            {
 130.118 +                if (n == 1)
 130.119 +                {
 130.120 +                    pts.Add(points[0]);
 130.121 +                }
 130.122 +
 130.123 +                var last = points[0];
 130.124 +                for (int i = 1; i < n; i++)
 130.125 +                {
 130.126 +                    var s0 = points[i - 1];
 130.127 +                    var s1 = points[i];
 130.128 +
 130.129 +                    // Clipped version of this and next point.
 130.130 +                    var sc0 = s0;
 130.131 +                    var sc1 = s1;
 130.132 +                    bool isInside = clipping.ClipLine(ref sc0, ref sc1);
 130.133 +
 130.134 +                    if (!isInside)
 130.135 +                    {
 130.136 +                        // keep the previous coordinate
 130.137 +                        continue;
 130.138 +                    }
 130.139 +
 130.140 +                    // render from s0c-s1c
 130.141 +                    double dx = sc1.x - last.x;
 130.142 +                    double dy = sc1.y - last.y;
 130.143 +
 130.144 +                    if ((dx * dx) + (dy * dy) > minDistSquared || i == 1 || i == n - 1)
 130.145 +                    {
 130.146 +                        if (!sc0.Equals(last) || i == 1)
 130.147 +                        {
 130.148 +                            pts.Add(sc0);
 130.149 +                        }
 130.150 +
 130.151 +                        pts.Add(sc1);
 130.152 +                        last = sc1;
 130.153 +                    }
 130.154 +
 130.155 +                    // render the line if we are leaving the clipping region););
 130.156 +                    if (!clipping.IsInside(s1))
 130.157 +                    {
 130.158 +                        if (pts.Count > 0)
 130.159 +                        {
 130.160 +                            EnsureNonEmptyLineIsVisible(pts);
 130.161 +                            rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.162 +                            if (pointsRendered != null)
 130.163 +                            {
 130.164 +                                pointsRendered(pts);
 130.165 +                            }
 130.166 +
 130.167 +                            pts = new List<ScreenPoint>();
 130.168 +                        }
 130.169 +                    }
 130.170 +                }
 130.171 +
 130.172 +                if (pts.Count > 0)
 130.173 +                {
 130.174 +                    EnsureNonEmptyLineIsVisible(pts);
 130.175 +                    rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.176 +
 130.177 +                    // Execute the 'callback'.
 130.178 +                    if (pointsRendered != null)
 130.179 +                    {
 130.180 +                        pointsRendered(pts);
 130.181 +                    }
 130.182 +                }
 130.183 +            }
 130.184 +        }
 130.185 +
 130.186 +        /// <summary>
 130.187 +        /// Draws the clipped line segments.
 130.188 +        /// </summary>
 130.189 +        /// <param name="rc">The render context.</param>
 130.190 +        /// <param name="points">The points.</param>
 130.191 +        /// <param name="clippingRectangle">The clipping rectangle.</param>
 130.192 +        /// <param name="stroke">The stroke.</param>
 130.193 +        /// <param name="strokeThickness">The stroke thickness.</param>
 130.194 +        /// <param name="lineStyle">The line style.</param>
 130.195 +        /// <param name="lineJoin">The line join.</param>
 130.196 +        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
 130.197 +        public static void DrawClippedLineSegments(
 130.198 +            this IRenderContext rc,
 130.199 +            IList<ScreenPoint> points,
 130.200 +            OxyRect clippingRectangle,
 130.201 +            OxyColor stroke,
 130.202 +            double strokeThickness,
 130.203 +            LineStyle lineStyle,
 130.204 +            OxyPenLineJoin lineJoin,
 130.205 +            bool aliased)
 130.206 +        {
 130.207 +            if (rc.SetClip(clippingRectangle))
 130.208 +            {
 130.209 +                rc.DrawLineSegments(points, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.210 +                rc.ResetClip();
 130.211 +                return;
 130.212 +            }
 130.213 +
 130.214 +            var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom);
 130.215 +
 130.216 +            var clippedPoints = new List<ScreenPoint>(points.Count);
 130.217 +            for (int i = 0; i + 1 < points.Count; i += 2)
 130.218 +            {
 130.219 +                var s0 = points[i];
 130.220 +                var s1 = points[i + 1];
 130.221 +                if (clipping.ClipLine(ref s0, ref s1))
 130.222 +                {
 130.223 +                    clippedPoints.Add(s0);
 130.224 +                    clippedPoints.Add(s1);
 130.225 +                }
 130.226 +            }
 130.227 +
 130.228 +            rc.DrawLineSegments(clippedPoints, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.229 +        }
 130.230 +
 130.231 +        /// <summary>
 130.232 +        /// Draws the specified image.
 130.233 +        /// </summary>
 130.234 +        /// <param name="rc">The render context.</param>
 130.235 +        /// <param name="image">The image.</param>
 130.236 +        /// <param name="x">The destination X position.</param>
 130.237 +        /// <param name="y">The destination Y position.</param>
 130.238 +        /// <param name="w">The width.</param>
 130.239 +        /// <param name="h">The height.</param>
 130.240 +        /// <param name="opacity">The opacity.</param>
 130.241 +        /// <param name="interpolate">Interpolate the image if set to <c>true</c>.</param>
 130.242 +        public static void DrawImage(
 130.243 +            this IRenderContext rc,
 130.244 +            OxyImage image,
 130.245 +            double x,
 130.246 +            double y,
 130.247 +            double w,
 130.248 +            double h,
 130.249 +            double opacity,
 130.250 +            bool interpolate)
 130.251 +        {
 130.252 +            var info = rc.GetImageInfo(image);
 130.253 +            if (info == null)
 130.254 +            {
 130.255 +                return;
 130.256 +            }
 130.257 +
 130.258 +            rc.DrawImage(image, 0, 0, info.Width, info.Height, x, y, w, h, opacity, interpolate);
 130.259 +        }
 130.260 +
 130.261 +        /// <summary>
 130.262 +        /// Draws the clipped image.
 130.263 +        /// </summary>
 130.264 +        /// <param name="rc">The render context.</param>
 130.265 +        /// <param name="clippingRect">The clipping rectangle.</param>
 130.266 +        /// <param name="source">The source.</param>
 130.267 +        /// <param name="x">The destination X position.</param>
 130.268 +        /// <param name="y">The destination Y position.</param>
 130.269 +        /// <param name="w">The width.</param>
 130.270 +        /// <param name="h">The height.</param>
 130.271 +        /// <param name="opacity">The opacity.</param>
 130.272 +        /// <param name="interpolate">interpolate if set to <c>true</c>.</param>
 130.273 +        public static void DrawClippedImage(
 130.274 +            this IRenderContext rc,
 130.275 +            OxyRect clippingRect,
 130.276 +            OxyImage source,
 130.277 +            double x,
 130.278 +            double y,
 130.279 +            double w,
 130.280 +            double h,
 130.281 +            double opacity,
 130.282 +            bool interpolate)
 130.283 +        {
 130.284 +            if (x > clippingRect.Right || x + w < clippingRect.Left || y > clippingRect.Bottom || y + h < clippingRect.Top)
 130.285 +            {
 130.286 +                return;
 130.287 +            }
 130.288 +
 130.289 +            if (rc.SetClip(clippingRect))
 130.290 +            {
 130.291 +                // The render context supports clipping, then we can draw the whole image
 130.292 +                rc.DrawImage(source, x, y, w, h, opacity, interpolate);
 130.293 +                rc.ResetClip();
 130.294 +                return;
 130.295 +            }
 130.296 +
 130.297 +            // The render context does not support clipping, we must calculate the rectangle
 130.298 +            var info = rc.GetImageInfo(source);
 130.299 +            if (info == null)
 130.300 +            {
 130.301 +                return;
 130.302 +            }
 130.303 +
 130.304 +            // Fint the positions of the clipping rectangle normalized to image coordinates (0,1)
 130.305 +            var i0 = (clippingRect.Left - x) / w;
 130.306 +            var i1 = (clippingRect.Right - x) / w;
 130.307 +            var j0 = (clippingRect.Top - y) / h;
 130.308 +            var j1 = (clippingRect.Bottom - y) / h;
 130.309 +
 130.310 +            // Find the origin of the clipped source rectangle
 130.311 +            var srcx = i0 < 0 ? 0u : i0 * info.Width;
 130.312 +            var srcy = j0 < 0 ? 0u : j0 * info.Height;
 130.313 +            srcx = (int)Math.Ceiling(srcx);
 130.314 +            srcy = (int)Math.Ceiling(srcy);
 130.315 +
 130.316 +            // Find the size of the clipped source rectangle
 130.317 +            var srcw = i1 > 1 ? info.Width - srcx : (i1 * info.Width) - srcx;
 130.318 +            var srch = j1 > 1 ? info.Height - srcy : (j1 * info.Height) - srcy;
 130.319 +            srcw = (int)srcw;
 130.320 +            srch = (int)srch;
 130.321 +
 130.322 +            if ((int)srcw <= 0 || (int)srch <= 0)
 130.323 +            {
 130.324 +                return;
 130.325 +            }
 130.326 +
 130.327 +            // The clipped destination rectangle
 130.328 +            var destx = i0 < 0 ? x : x + (srcx / info.Width * w);
 130.329 +            var desty = j0 < 0 ? y : y + (srcy / info.Height * h);
 130.330 +            var destw = w * srcw / info.Width;
 130.331 +            var desth = h * srch / info.Height;
 130.332 +
 130.333 +            rc.DrawImage(source, (uint)srcx, (uint)srcy, (uint)srcw, (uint)srch, destx, desty, destw, desth, opacity, interpolate);
 130.334 +        }
 130.335 +
 130.336 +        /// <summary>
 130.337 +        /// Draws the polygon within the specified clipping rectangle.
 130.338 +        /// </summary>
 130.339 +        /// <param name="rc">
 130.340 +        /// The render context.
 130.341 +        /// </param>
 130.342 +        /// <param name="points">
 130.343 +        /// The points.
 130.344 +        /// </param>
 130.345 +        /// <param name="clippingRectangle">
 130.346 +        /// The clipping rectangle.
 130.347 +        /// </param>
 130.348 +        /// <param name="minDistSquared">
 130.349 +        /// The squared minimum distance between points.
 130.350 +        /// </param>
 130.351 +        /// <param name="fill">
 130.352 +        /// The fill.
 130.353 +        /// </param>
 130.354 +        /// <param name="stroke">
 130.355 +        /// The stroke.
 130.356 +        /// </param>
 130.357 +        /// <param name="strokeThickness">
 130.358 +        /// The stroke thickness.
 130.359 +        /// </param>
 130.360 +        /// <param name="lineStyle">
 130.361 +        /// The line style.
 130.362 +        /// </param>
 130.363 +        /// <param name="lineJoin">
 130.364 +        /// The line join.
 130.365 +        /// </param>
 130.366 +        /// <param name="aliased">
 130.367 +        /// The aliased.
 130.368 +        /// </param>
 130.369 +        public static void DrawClippedPolygon(
 130.370 +            this IRenderContext rc,
 130.371 +            IList<ScreenPoint> points,
 130.372 +            OxyRect clippingRectangle,
 130.373 +            double minDistSquared,
 130.374 +            OxyColor fill,
 130.375 +            OxyColor stroke,
 130.376 +            double strokeThickness = 1.0,
 130.377 +            LineStyle lineStyle = LineStyle.Solid,
 130.378 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter,
 130.379 +            bool aliased = false)
 130.380 +        {
 130.381 +            if (rc.SetClip(clippingRectangle))
 130.382 +            {
 130.383 +                rc.DrawPolygon(points, fill, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.384 +                rc.ResetClip();
 130.385 +                return;
 130.386 +            }
 130.387 +
 130.388 +            var clippedPoints = SutherlandHodgmanClipping.ClipPolygon(clippingRectangle, points);
 130.389 +
 130.390 +            rc.DrawPolygon(
 130.391 +                clippedPoints, fill, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
 130.392 +        }
 130.393 +
 130.394 +        /// <summary>
 130.395 +        /// Draws the clipped rectangle.
 130.396 +        /// </summary>
 130.397 +        /// <param name="rc">
 130.398 +        /// The render context.
 130.399 +        /// </param>
 130.400 +        /// <param name="rect">
 130.401 +        /// The rectangle to draw.
 130.402 +        /// </param>
 130.403 +        /// <param name="clippingRectangle">
 130.404 +        /// The clipping rectangle.
 130.405 +        /// </param>
 130.406 +        /// <param name="fill">
 130.407 +        /// The fill color.
 130.408 +        /// </param>
 130.409 +        /// <param name="stroke">
 130.410 +        /// The stroke color.
 130.411 +        /// </param>
 130.412 +        /// <param name="thickness">
 130.413 +        /// The stroke thickness.
 130.414 +        /// </param>
 130.415 +        public static void DrawClippedRectangle(
 130.416 +            this IRenderContext rc,
 130.417 +            OxyRect rect,
 130.418 +            OxyRect clippingRectangle,
 130.419 +            OxyColor fill,
 130.420 +            OxyColor stroke,
 130.421 +            double thickness)
 130.422 +        {
 130.423 +            if (rc.SetClip(clippingRectangle))
 130.424 +            {
 130.425 +                rc.DrawRectangle(rect, fill, stroke, thickness);
 130.426 +                rc.ResetClip();
 130.427 +                return;
 130.428 +            }
 130.429 +
 130.430 +            var clippedRect = ClipRect(rect, clippingRectangle);
 130.431 +            if (clippedRect == null)
 130.432 +            {
 130.433 +                return;
 130.434 +            }
 130.435 +
 130.436 +            rc.DrawRectangle(clippedRect.Value, fill, stroke, thickness);
 130.437 +        }
 130.438 +
 130.439 +        /// <summary>
 130.440 +        /// Draws the clipped rectangle as a polygon.
 130.441 +        /// </summary>
 130.442 +        /// <param name="rc">
 130.443 +        /// The render context.
 130.444 +        /// </param>
 130.445 +        /// <param name="rect">
 130.446 +        /// The rectangle to draw.
 130.447 +        /// </param>
 130.448 +        /// <param name="clippingRectangle">
 130.449 +        /// The clipping rectangle.
 130.450 +        /// </param>
 130.451 +        /// <param name="fill">
 130.452 +        /// The fill color.
 130.453 +        /// </param>
 130.454 +        /// <param name="stroke">
 130.455 +        /// The stroke color.
 130.456 +        /// </param>
 130.457 +        /// <param name="thickness">
 130.458 +        /// The stroke thickness.
 130.459 +        /// </param>
 130.460 +        public static void DrawClippedRectangleAsPolygon(
 130.461 +            this IRenderContext rc,
 130.462 +            OxyRect rect,
 130.463 +            OxyRect clippingRectangle,
 130.464 +            OxyColor fill,
 130.465 +            OxyColor stroke,
 130.466 +            double thickness)
 130.467 +        {
 130.468 +            if (rc.SetClip(clippingRectangle))
 130.469 +            {
 130.470 +                rc.DrawRectangleAsPolygon(rect, fill, stroke, thickness);
 130.471 +                rc.ResetClip();
 130.472 +                return;
 130.473 +            }
 130.474 +
 130.475 +            var clippedRect = ClipRect(rect, clippingRectangle);
 130.476 +            if (clippedRect == null)
 130.477 +            {
 130.478 +                return;
 130.479 +            }
 130.480 +
 130.481 +            rc.DrawRectangleAsPolygon(clippedRect.Value, fill, stroke, thickness);
 130.482 +        }
 130.483 +
 130.484 +        /// <summary>
 130.485 +        /// Draws a clipped ellipse.
 130.486 +        /// </summary>
 130.487 +        /// <param name="rc">The render context.</param>
 130.488 +        /// <param name="clippingRectangle">The clipping rectangle.</param>
 130.489 +        /// <param name="rect">The rectangle.</param>
 130.490 +        /// <param name="fill">The fill color.</param>
 130.491 +        /// <param name="stroke">The stroke color.</param>
 130.492 +        /// <param name="thickness">The stroke thickness.</param>
 130.493 +        /// <param name="n">The number of points around the ellipse.</param>
 130.494 +        public static void DrawClippedEllipse(
 130.495 +            this IRenderContext rc,
 130.496 +            OxyRect clippingRectangle,
 130.497 +            OxyRect rect,
 130.498 +            OxyColor fill,
 130.499 +            OxyColor stroke,
 130.500 +            double thickness,
 130.501 +            int n = 100)
 130.502 +        {
 130.503 +            if (rc.SetClip(clippingRectangle))
 130.504 +            {
 130.505 +                rc.DrawEllipse(rect, fill, stroke, thickness);
 130.506 +                rc.ResetClip();
 130.507 +                return;
 130.508 +            }
 130.509 +
 130.510 +            var points = new ScreenPoint[n];
 130.511 +            double cx = (rect.Left + rect.Right) / 2;
 130.512 +            double cy = (rect.Top + rect.Bottom) / 2;
 130.513 +            double rx = (rect.Right - rect.Left) / 2;
 130.514 +            double ry = (rect.Bottom - rect.Top) / 2;
 130.515 +            for (int i = 0; i < n; i++)
 130.516 +            {
 130.517 +                double a = Math.PI * 2 * i / (n - 1);
 130.518 +                points[i] = new ScreenPoint(cx + (rx * Math.Cos(a)), cy + (ry * Math.Sin(a)));
 130.519 +            }
 130.520 +
 130.521 +            rc.DrawClippedPolygon(points, clippingRectangle, 4, fill, stroke, thickness);
 130.522 +        }
 130.523 +
 130.524 +        /// <summary>
 130.525 +        /// Draws the clipped text.
 130.526 +        /// </summary>
 130.527 +        /// <param name="rc">The rendering context.</param>
 130.528 +        /// <param name="clippingRectangle">The clipping rectangle.</param>
 130.529 +        /// <param name="p">The position.</param>
 130.530 +        /// <param name="text">The text.</param>
 130.531 +        /// <param name="fill">The fill color.</param>
 130.532 +        /// <param name="fontFamily">The font family.</param>
 130.533 +        /// <param name="fontSize">Size of the font.</param>
 130.534 +        /// <param name="fontWeight">The font weight.</param>
 130.535 +        /// <param name="rotate">The rotation angle.</param>
 130.536 +        /// <param name="horizontalAlignment">The horizontal align.</param>
 130.537 +        /// <param name="verticalAlignment">The vertical align.</param>
 130.538 +        /// <param name="maxSize">Size of the max.</param>
 130.539 +        public static void DrawClippedText(
 130.540 +            this IRenderContext rc,
 130.541 +            OxyRect clippingRectangle,
 130.542 +            ScreenPoint p,
 130.543 +            string text,
 130.544 +            OxyColor fill,
 130.545 +            string fontFamily = null,
 130.546 +            double fontSize = 10,
 130.547 +            double fontWeight = 500,
 130.548 +            double rotate = 0,
 130.549 +            HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left,
 130.550 +            VerticalAlignment verticalAlignment = VerticalAlignment.Top,
 130.551 +            OxySize? maxSize = null)
 130.552 +        {
 130.553 +            if (rc.SetClip(clippingRectangle))
 130.554 +            {
 130.555 +                rc.DrawText(p, text, fill, fontFamily, fontSize, fontWeight, rotate, horizontalAlignment, verticalAlignment, maxSize);
 130.556 +                rc.ResetClip();
 130.557 +                return;
 130.558 +            }
 130.559 +
 130.560 +            // fall back simply check position
 130.561 +            if (clippingRectangle.Contains(p.X, p.Y))
 130.562 +            {
 130.563 +                rc.DrawText(p, text, fill, fontFamily, fontSize, fontWeight, rotate, horizontalAlignment, verticalAlignment, maxSize);
 130.564 +            }
 130.565 +        }
 130.566 +
 130.567 +        /// <summary>
 130.568 +        /// Draws a line specified by coordinates.
 130.569 +        /// </summary>
 130.570 +        /// <param name="rc">
 130.571 +        /// The render context.
 130.572 +        /// </param>
 130.573 +        /// <param name="x0">
 130.574 +        /// The x0.
 130.575 +        /// </param>
 130.576 +        /// <param name="y0">
 130.577 +        /// The y0.
 130.578 +        /// </param>
 130.579 +        /// <param name="x1">
 130.580 +        /// The x1.
 130.581 +        /// </param>
 130.582 +        /// <param name="y1">
 130.583 +        /// The y1.
 130.584 +        /// </param>
 130.585 +        /// <param name="pen">
 130.586 +        /// The pen.
 130.587 +        /// </param>
 130.588 +        /// <param name="aliased">
 130.589 +        /// Aliased line if set to <c>true</c>.
 130.590 +        /// </param>
 130.591 +        public static void DrawLine(
 130.592 +            this IRenderContext rc, double x0, double y0, double x1, double y1, OxyPen pen, bool aliased = true)
 130.593 +        {
 130.594 +            if (pen == null)
 130.595 +            {
 130.596 +                return;
 130.597 +            }
 130.598 +
 130.599 +            rc.DrawLine(
 130.600 +                new[] { new ScreenPoint(x0, y0), new ScreenPoint(x1, y1) },
 130.601 +                pen.Color,
 130.602 +                pen.Thickness,
 130.603 +                pen.DashArray,
 130.604 +                pen.LineJoin,
 130.605 +                aliased);
 130.606 +        }
 130.607 +
 130.608 +        /// <summary>
 130.609 +        /// Draws the line segments.
 130.610 +        /// </summary>
 130.611 +        /// <param name="rc">
 130.612 +        /// The render context.
 130.613 +        /// </param>
 130.614 +        /// <param name="points">
 130.615 +        /// The points.
 130.616 +        /// </param>
 130.617 +        /// <param name="pen">
 130.618 +        /// The pen.
 130.619 +        /// </param>
 130.620 +        /// <param name="aliased">
 130.621 +        /// if set to <c>true</c> [aliased].
 130.622 +        /// </param>
 130.623 +        public static void DrawLineSegments(
 130.624 +            this IRenderContext rc, IList<ScreenPoint> points, OxyPen pen, bool aliased = true)
 130.625 +        {
 130.626 +            if (pen == null)
 130.627 +            {
 130.628 +                return;
 130.629 +            }
 130.630 +
 130.631 +            rc.DrawLineSegments(points, pen.Color, pen.Thickness, pen.DashArray, pen.LineJoin, aliased);
 130.632 +        }
 130.633 +
 130.634 +        /// <summary>
 130.635 +        /// Renders the marker.
 130.636 +        /// </summary>
 130.637 +        /// <param name="rc">The render context.</param>
 130.638 +        /// <param name="p">The center point of the marker.</param>
 130.639 +        /// <param name="clippingRect">The clipping rectangle.</param>
 130.640 +        /// <param name="type">The marker type.</param>
 130.641 +        /// <param name="outline">The outline.</param>
 130.642 +        /// <param name="size">The size of the marker.</param>
 130.643 +        /// <param name="fill">The fill color.</param>
 130.644 +        /// <param name="stroke">The stroke color.</param>
 130.645 +        /// <param name="strokeThickness">The stroke thickness.</param>
 130.646 +        public static void DrawMarker(
 130.647 +            this IRenderContext rc,
 130.648 +            ScreenPoint p,
 130.649 +            OxyRect clippingRect,
 130.650 +            MarkerType type,
 130.651 +            IList<ScreenPoint> outline,
 130.652 +            double size,
 130.653 +            OxyColor fill,
 130.654 +            OxyColor stroke,
 130.655 +            double strokeThickness)
 130.656 +        {
 130.657 +            rc.DrawMarkers(new[] { p }, clippingRect, type, outline, new[] { size }, fill, stroke, strokeThickness);
 130.658 +        }
 130.659 +
 130.660 +        /// <summary>
 130.661 +        /// Draws a list of markers.
 130.662 +        /// </summary>
 130.663 +        /// <param name="rc">
 130.664 +        /// The render context.
 130.665 +        /// </param>
 130.666 +        /// <param name="markerPoints">
 130.667 +        /// The marker points.
 130.668 +        /// </param>
 130.669 +        /// <param name="clippingRect">
 130.670 +        /// The clipping rectangle.
 130.671 +        /// </param>
 130.672 +        /// <param name="markerType">
 130.673 +        /// Type of the marker.
 130.674 +        /// </param>
 130.675 +        /// <param name="markerOutline">
 130.676 +        /// The marker outline.
 130.677 +        /// </param>
 130.678 +        /// <param name="markerSize">
 130.679 +        /// Size of the marker.
 130.680 +        /// </param>
 130.681 +        /// <param name="markerFill">
 130.682 +        /// The marker fill.
 130.683 +        /// </param>
 130.684 +        /// <param name="markerStroke">
 130.685 +        /// The marker stroke.
 130.686 +        /// </param>
 130.687 +        /// <param name="markerStrokeThickness">
 130.688 +        /// The marker stroke thickness.
 130.689 +        /// </param>
 130.690 +        /// <param name="resolution">
 130.691 +        /// The resolution.
 130.692 +        /// </param>
 130.693 +        /// <param name="binOffset">
 130.694 +        /// The bin Offset.
 130.695 +        /// </param>
 130.696 +        public static void DrawMarkers(
 130.697 +            this IRenderContext rc,
 130.698 +            IList<ScreenPoint> markerPoints,
 130.699 +            OxyRect clippingRect,
 130.700 +            MarkerType markerType,
 130.701 +            IList<ScreenPoint> markerOutline,
 130.702 +            double markerSize,
 130.703 +            OxyColor markerFill,
 130.704 +            OxyColor markerStroke,
 130.705 +            double markerStrokeThickness,
 130.706 +            int resolution = 0,
 130.707 +            ScreenPoint binOffset = new ScreenPoint())
 130.708 +        {
 130.709 +            DrawMarkers(
 130.710 +                rc,
 130.711 +                markerPoints,
 130.712 +                clippingRect,
 130.713 +                markerType,
 130.714 +                markerOutline,
 130.715 +                new[] { markerSize },
 130.716 +                markerFill,
 130.717 +                markerStroke,
 130.718 +                markerStrokeThickness,
 130.719 +                resolution,
 130.720 +                binOffset);
 130.721 +        }
 130.722 +
 130.723 +        /// <summary>
 130.724 +        /// Draws a list of markers.
 130.725 +        /// </summary>
 130.726 +        /// <param name="rc">
 130.727 +        /// The render context.
 130.728 +        /// </param>
 130.729 +        /// <param name="markerPoints">
 130.730 +        /// The marker points.
 130.731 +        /// </param>
 130.732 +        /// <param name="clippingRect">
 130.733 +        /// The clipping rectangle.
 130.734 +        /// </param>
 130.735 +        /// <param name="markerType">
 130.736 +        /// Type of the marker.
 130.737 +        /// </param>
 130.738 +        /// <param name="markerOutline">
 130.739 +        /// The marker outline.
 130.740 +        /// </param>
 130.741 +        /// <param name="markerSize">
 130.742 +        /// Size of the markers.
 130.743 +        /// </param>
 130.744 +        /// <param name="markerFill">
 130.745 +        /// The marker fill.
 130.746 +        /// </param>
 130.747 +        /// <param name="markerStroke">
 130.748 +        /// The marker stroke.
 130.749 +        /// </param>
 130.750 +        /// <param name="markerStrokeThickness">
 130.751 +        /// The marker stroke thickness.
 130.752 +        /// </param>
 130.753 +        /// <param name="resolution">
 130.754 +        /// The resolution.
 130.755 +        /// </param>
 130.756 +        /// <param name="binOffset">
 130.757 +        /// The bin Offset.
 130.758 +        /// </param>
 130.759 +        public static void DrawMarkers(
 130.760 +            this IRenderContext rc,
 130.761 +            IList<ScreenPoint> markerPoints,
 130.762 +            OxyRect clippingRect,
 130.763 +            MarkerType markerType,
 130.764 +            IList<ScreenPoint> markerOutline,
 130.765 +            IList<double> markerSize,
 130.766 +            OxyColor markerFill,
 130.767 +            OxyColor markerStroke,
 130.768 +            double markerStrokeThickness,
 130.769 +            int resolution = 0,
 130.770 +            ScreenPoint binOffset = new ScreenPoint())
 130.771 +        {
 130.772 +            if (markerType == MarkerType.None)
 130.773 +            {
 130.774 +                return;
 130.775 +            }
 130.776 +
 130.777 +            int n = markerPoints.Count;
 130.778 +            var ellipses = new List<OxyRect>(n);
 130.779 +            var rects = new List<OxyRect>(n);
 130.780 +            var polygons = new List<IList<ScreenPoint>>(n);
 130.781 +            var lines = new List<ScreenPoint>(n);
 130.782 +
 130.783 +            var hashset = new Dictionary<uint, bool>();
 130.784 +
 130.785 +            int i = 0;
 130.786 +
 130.787 +            double minx = clippingRect.Left;
 130.788 +            double maxx = clippingRect.Right;
 130.789 +            double miny = clippingRect.Top;
 130.790 +            double maxy = clippingRect.Bottom;
 130.791 +
 130.792 +            foreach (var p in markerPoints)
 130.793 +            {
 130.794 +                if (resolution > 1)
 130.795 +                {
 130.796 +                    var x = (int)((p.X - binOffset.X) / resolution);
 130.797 +                    var y = (int)((p.Y - binOffset.Y) / resolution);
 130.798 +                    uint hash = (uint)(x << 16) + (uint)y;
 130.799 +                    if (hashset.ContainsKey(hash))
 130.800 +                    {
 130.801 +                        i++;
 130.802 +                        continue;
 130.803 +                    }
 130.804 +
 130.805 +                    hashset.Add(hash, true);
 130.806 +                }
 130.807 +
 130.808 +                bool outside = p.x < minx || p.x > maxx || p.y < miny || p.y > maxy;
 130.809 +                if (!outside)
 130.810 +                {
 130.811 +                    int j = i < markerSize.Count ? i : 0;
 130.812 +                    AddMarkerGeometry(p, markerType, markerOutline, markerSize[j], ellipses, rects, polygons, lines);
 130.813 +                }
 130.814 +
 130.815 +                i++;
 130.816 +            }
 130.817 +
 130.818 +            if (ellipses.Count > 0)
 130.819 +            {
 130.820 +                rc.DrawEllipses(ellipses, markerFill, markerStroke, markerStrokeThickness);
 130.821 +            }
 130.822 +
 130.823 +            if (rects.Count > 0)
 130.824 +            {
 130.825 +                rc.DrawRectangles(rects, markerFill, markerStroke, markerStrokeThickness);
 130.826 +            }
 130.827 +
 130.828 +            if (polygons.Count > 0)
 130.829 +            {
 130.830 +                rc.DrawPolygons(polygons, markerFill, markerStroke, markerStrokeThickness);
 130.831 +            }
 130.832 +
 130.833 +            if (lines.Count > 0)
 130.834 +            {
 130.835 +                rc.DrawLineSegments(lines, markerStroke, markerStrokeThickness);
 130.836 +            }
 130.837 +        }
 130.838 +
 130.839 +        /// <summary>
 130.840 +        /// Draws the rectangle as an aliased polygon.
 130.841 +        /// (makes sure pixel alignment is the same as for lines)
 130.842 +        /// </summary>
 130.843 +        /// <param name="rc">
 130.844 +        /// The render context.
 130.845 +        /// </param>
 130.846 +        /// <param name="rect">
 130.847 +        /// The rectangle.
 130.848 +        /// </param>
 130.849 +        /// <param name="fill">
 130.850 +        /// The fill.
 130.851 +        /// </param>
 130.852 +        /// <param name="stroke">
 130.853 +        /// The stroke.
 130.854 +        /// </param>
 130.855 +        /// <param name="thickness">
 130.856 +        /// The thickness.
 130.857 +        /// </param>
 130.858 +        public static void DrawRectangleAsPolygon(
 130.859 +            this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
 130.860 +        {
 130.861 +            var sp0 = new ScreenPoint(rect.Left, rect.Top);
 130.862 +            var sp1 = new ScreenPoint(rect.Right, rect.Top);
 130.863 +            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
 130.864 +            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);
 130.865 +            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, stroke, thickness, null, OxyPenLineJoin.Miter, true);
 130.866 +        }
 130.867 +
 130.868 +        /// <summary>
 130.869 +        /// Draws the rectangle as an aliased polygon.
 130.870 +        /// (makes sure pixel alignment is the same as for lines)
 130.871 +        /// </summary>
 130.872 +        /// <param name="rc">
 130.873 +        /// The render context.
 130.874 +        /// </param>
 130.875 +        /// <param name="rect">
 130.876 +        /// The rectangle.
 130.877 +        /// </param>
 130.878 +        /// <param name="fill">
 130.879 +        /// The fill.
 130.880 +        /// </param>
 130.881 +        /// <param name="stroke">
 130.882 +        /// The stroke.
 130.883 +        /// </param>
 130.884 +        /// <param name="thickness">
 130.885 +        /// The thickness.
 130.886 +        /// </param>
 130.887 +        public static void DrawRectangleAsPolygon(
 130.888 +            this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness)
 130.889 +        {
 130.890 +            if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top)
 130.891 +                && thickness.Left.Equals(thickness.Bottom))
 130.892 +            {
 130.893 +                DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left);
 130.894 +                return;
 130.895 +            }
 130.896 +
 130.897 +            var sp0 = new ScreenPoint(rect.Left, rect.Top);
 130.898 +            var sp1 = new ScreenPoint(rect.Right, rect.Top);
 130.899 +            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
 130.900 +            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);
 130.901 +            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, null, 0, null, OxyPenLineJoin.Miter, true);
 130.902 +            rc.DrawPolygon(new[] { sp0, sp1 }, null, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true);
 130.903 +            rc.DrawPolygon(new[] { sp1, sp2 }, null, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true);
 130.904 +            rc.DrawPolygon(new[] { sp2, sp3 }, null, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true);
 130.905 +            rc.DrawPolygon(new[] { sp3, sp0 }, null, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true);
 130.906 +        }
 130.907 +
 130.908 +        /// <summary>
 130.909 +        /// Adds a marker geometry.
 130.910 +        /// </summary>
 130.911 +        /// <param name="p">
 130.912 +        /// The position of the marker.
 130.913 +        /// </param>
 130.914 +        /// <param name="type">
 130.915 +        /// The type.
 130.916 +        /// </param>
 130.917 +        /// <param name="outline">
 130.918 +        /// The outline.
 130.919 +        /// </param>
 130.920 +        /// <param name="size">
 130.921 +        /// The size.
 130.922 +        /// </param>
 130.923 +        /// <param name="ellipses">
 130.924 +        /// The ellipse collection.
 130.925 +        /// </param>
 130.926 +        /// <param name="rects">
 130.927 +        /// The rectangle collection.
 130.928 +        /// </param>
 130.929 +        /// <param name="polygons">
 130.930 +        /// The polygon collection.
 130.931 +        /// </param>
 130.932 +        /// <param name="lines">
 130.933 +        /// The line collection.
 130.934 +        /// </param>
 130.935 +        private static void AddMarkerGeometry(
 130.936 +            ScreenPoint p,
 130.937 +            MarkerType type,
 130.938 +            IEnumerable<ScreenPoint> outline,
 130.939 +            double size,
 130.940 +            IList<OxyRect> ellipses,
 130.941 +            IList<OxyRect> rects,
 130.942 +            IList<IList<ScreenPoint>> polygons,
 130.943 +            IList<ScreenPoint> lines)
 130.944 +        {
 130.945 +            if (type == MarkerType.Custom)
 130.946 +            {
 130.947 +                if (outline == null)
 130.948 +                {
 130.949 +                    throw new ArgumentNullException("outline", "The outline should be set when MarkerType is 'Custom'.");
 130.950 +                }
 130.951 +
 130.952 +                var poly = outline.Select(o => new ScreenPoint(p.X + (o.x * size), p.Y + (o.y * size))).ToList();
 130.953 +                polygons.Add(poly);
 130.954 +                return;
 130.955 +            }
 130.956 +
 130.957 +            switch (type)
 130.958 +            {
 130.959 +                case MarkerType.Circle:
 130.960 +                    {
 130.961 +                        ellipses.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
 130.962 +                        break;
 130.963 +                    }
 130.964 +
 130.965 +                case MarkerType.Square:
 130.966 +                    {
 130.967 +                        rects.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
 130.968 +                        break;
 130.969 +                    }
 130.970 +
 130.971 +                case MarkerType.Diamond:
 130.972 +                    {
 130.973 +                        polygons.Add(
 130.974 +                            new[]
 130.975 +                                {
 130.976 +                                    new ScreenPoint(p.x, p.y - (M2 * size)), new ScreenPoint(p.x + (M2 * size), p.y),
 130.977 +                                    new ScreenPoint(p.x, p.y + (M2 * size)), new ScreenPoint(p.x - (M2 * size), p.y)
 130.978 +                                });
 130.979 +                        break;
 130.980 +                    }
 130.981 +
 130.982 +                case MarkerType.Triangle:
 130.983 +                    {
 130.984 +                        polygons.Add(
 130.985 +                            new[]
 130.986 +                                {
 130.987 +                                    new ScreenPoint(p.x - size, p.y + (M1 * size)),
 130.988 +                                    new ScreenPoint(p.x + size, p.y + (M1 * size)), new ScreenPoint(p.x, p.y - (M2 * size))
 130.989 +                                });
 130.990 +                        break;
 130.991 +                    }
 130.992 +
 130.993 +                case MarkerType.Plus:
 130.994 +                case MarkerType.Star:
 130.995 +                    {
 130.996 +                        lines.Add(new ScreenPoint(p.x - size, p.y));
 130.997 +                        lines.Add(new ScreenPoint(p.x + size, p.y));
 130.998 +                        lines.Add(new ScreenPoint(p.x, p.y - size));
 130.999 +                        lines.Add(new ScreenPoint(p.x, p.y + size));
130.1000 +                        break;
130.1001 +                    }
130.1002 +            }
130.1003 +
130.1004 +            switch (type)
130.1005 +            {
130.1006 +                case MarkerType.Cross:
130.1007 +                case MarkerType.Star:
130.1008 +                    {
130.1009 +                        lines.Add(new ScreenPoint(p.x - (size * M3), p.y - (size * M3)));
130.1010 +                        lines.Add(new ScreenPoint(p.x + (size * M3), p.y + (size * M3)));
130.1011 +                        lines.Add(new ScreenPoint(p.x - (size * M3), p.y + (size * M3)));
130.1012 +                        lines.Add(new ScreenPoint(p.x + (size * M3), p.y - (size * M3)));
130.1013 +                        break;
130.1014 +                    }
130.1015 +            }
130.1016 +        }
130.1017 +
130.1018 +        /// <summary>
130.1019 +        /// Calculates the clipped version of a rectangle.
130.1020 +        /// </summary>
130.1021 +        /// <param name="rect">
130.1022 +        /// The rectangle to clip.
130.1023 +        /// </param>
130.1024 +        /// <param name="clippingRectangle">
130.1025 +        /// The clipping rectangle.
130.1026 +        /// </param>
130.1027 +        /// <returns>
130.1028 +        /// The clipped rectangle, or null if the rectangle is outside the clipping area.
130.1029 +        /// </returns>
130.1030 +        private static OxyRect? ClipRect(OxyRect rect, OxyRect clippingRectangle)
130.1031 +        {
130.1032 +            if (rect.Right < clippingRectangle.Left)
130.1033 +            {
130.1034 +                return null;
130.1035 +            }
130.1036 +
130.1037 +            if (rect.Left > clippingRectangle.Right)
130.1038 +            {
130.1039 +                return null;
130.1040 +            }
130.1041 +
130.1042 +            if (rect.Top > clippingRectangle.Bottom)
130.1043 +            {
130.1044 +                return null;
130.1045 +            }
130.1046 +
130.1047 +            if (rect.Bottom < clippingRectangle.Top)
130.1048 +            {
130.1049 +                return null;
130.1050 +            }
130.1051 +
130.1052 +            if (rect.Right > clippingRectangle.Right)
130.1053 +            {
130.1054 +                rect.Right = clippingRectangle.Right;
130.1055 +            }
130.1056 +
130.1057 +            if (rect.Left < clippingRectangle.Left)
130.1058 +            {
130.1059 +                rect.Width = rect.Right - clippingRectangle.Left;
130.1060 +                rect.Left = clippingRectangle.Left;
130.1061 +            }
130.1062 +
130.1063 +            if (rect.Top < clippingRectangle.Top)
130.1064 +            {
130.1065 +                rect.Height = rect.Bottom - clippingRectangle.Top;
130.1066 +                rect.Top = clippingRectangle.Top;
130.1067 +            }
130.1068 +
130.1069 +            if (rect.Bottom > clippingRectangle.Bottom)
130.1070 +            {
130.1071 +                rect.Bottom = clippingRectangle.Bottom;
130.1072 +            }
130.1073 +
130.1074 +            if (rect.Width <= 0 || rect.Height <= 0)
130.1075 +            {
130.1076 +                return null;
130.1077 +            }
130.1078 +
130.1079 +            return rect;
130.1080 +        }
130.1081 +
130.1082 +        /// <summary>
130.1083 +        /// Makes sure that a non empty line is visible.
130.1084 +        /// </summary>
130.1085 +        /// <param name="pts">The points (screen coordinates).</param>
130.1086 +        /// <remarks>
130.1087 +        /// If the line contains one point, another point is added.
130.1088 +        /// If the line contains two points at the same position, the points are moved 2 pixels apart.
130.1089 +        /// </remarks>
130.1090 +        private static void EnsureNonEmptyLineIsVisible(IList<ScreenPoint> pts)
130.1091 +        {
130.1092 +            // Check if the line contains two points and they are at the same point
130.1093 +            if (pts.Count == 2)
130.1094 +            {
130.1095 +                if (pts[0].DistanceTo(pts[1]) < 1)
130.1096 +                {
130.1097 +                    // Modify to a small horizontal line to make sure it is being rendered
130.1098 +                    pts[1] = new ScreenPoint(pts[0].X + 1, pts[0].Y);
130.1099 +                    pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
130.1100 +                }
130.1101 +            }
130.1102 +
130.1103 +            // Check if the line contains a single point
130.1104 +            if (pts.Count == 1)
130.1105 +            {
130.1106 +                // Add a second point to make sure the line is being rendered as a small dot
130.1107 +                pts.Add(new ScreenPoint(pts[0].X + 1, pts[0].Y));
130.1108 +                pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
130.1109 +            }
130.1110 +        }
130.1111 +    }
130.1112 +}
130.1113 \ No newline at end of file
   131.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.2 +++ b/External/OxyPlot/OxyPlot/Render/VerticalAxisRenderer.cs	Sat Jun 08 16:53:22 2013 +0000
   131.3 @@ -0,0 +1,318 @@
   131.4 +// --------------------------------------------------------------------------------------------------------------------
   131.5 +// <copyright file="VerticalAxisRenderer.cs" company="OxyPlot">
   131.6 +//   The MIT License (MIT)
   131.7 +//
   131.8 +//   Copyright (c) 2012 Oystein Bjorke
   131.9 +//
  131.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  131.11 +//   copy of this software and associated documentation files (the
  131.12 +//   "Software"), to deal in the Software without restriction, including
  131.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  131.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  131.15 +//   permit persons to whom the Software is furnished to do so, subject to
  131.16 +//   the following conditions:
  131.17 +//
  131.18 +//   The above copyright notice and this permission notice shall be included
  131.19 +//   in all copies or substantial portions of the Software.
  131.20 +//
  131.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  131.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  131.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  131.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  131.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  131.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  131.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  131.28 +// </copyright>
  131.29 +// <summary>
  131.30 +//   Gets the rotated alignments given the specified angle.
  131.31 +// </summary>
  131.32 +// --------------------------------------------------------------------------------------------------------------------
  131.33 +using System;
  131.34 +using System.Diagnostics;
  131.35 +
  131.36 +namespace OxyPlot
  131.37 +{
  131.38 +    public class VerticalAxisRendererBase : AxisRendererBase
  131.39 +    {
  131.40 +        public VerticalAxisRendererBase(IRenderContext rc, PlotModel plot)
  131.41 +            : base(rc, plot)
  131.42 +        {
  131.43 +        }
  131.44 +
  131.45 +        public override void Render(Axis axis)
  131.46 +        {
  131.47 +            base.Render(axis);
  131.48 +
  131.49 +            var perpendicularAxis = Plot.DefaultXAxis;
  131.50 +            bool isHorizontal = true;
  131.51 +
  131.52 +            // Axis position (x or y screen coordinate)
  131.53 +            double apos = 0;
  131.54 +
  131.55 +            switch (axis.Position)
  131.56 +            {
  131.57 +                case AxisPosition.Left:
  131.58 +                    apos = Plot.PlotArea.Left;
  131.59 +                    isHorizontal = false;
  131.60 +                    break;
  131.61 +                case AxisPosition.Right:
  131.62 +                    apos = Plot.PlotArea.Right;
  131.63 +                    isHorizontal = false;
  131.64 +                    break;
  131.65 +                case AxisPosition.Top:
  131.66 +                    apos = Plot.PlotArea.Top;
  131.67 +                    perpendicularAxis = Plot.DefaultYAxis;
  131.68 +                    break;
  131.69 +                case AxisPosition.Bottom:
  131.70 +                    apos = Plot.PlotArea.Bottom;
  131.71 +                    perpendicularAxis = Plot.DefaultYAxis;
  131.72 +                    break;
  131.73 +            }
  131.74 +
  131.75 +            if (axis.PositionAtZeroCrossing)
  131.76 +            {
  131.77 +                apos = perpendicularAxis.Transform(0);
  131.78 +            }
  131.79 +
  131.80 +            double a0, a1;
  131.81 +
  131.82 +            if (axis.ShowMinorTicks)
  131.83 +            {
  131.84 +                GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);
  131.85 +
  131.86 +                foreach (double value in MinorTickValues)
  131.87 +                {
  131.88 +                    if (value < axis.ActualMinimum || value > axis.ActualMaximum)
  131.89 +                    {
  131.90 +                        continue;
  131.91 +                    }
  131.92 +
  131.93 +                    if (MajorTickValues.Contains(value))
  131.94 +                    {
  131.95 +                        continue;
  131.96 +                    }
  131.97 +
  131.98 +                    double transformedValue = axis.Transform(value);
  131.99 +
 131.100 +                    if (MinorPen != null)
 131.101 +                    {
 131.102 +                        if (isHorizontal)
 131.103 +                        {
 131.104 +                            rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MinorPen);
 131.105 +
 131.106 +                        }
 131.107 +                        else
 131.108 +                        {
 131.109 +                            rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MinorPen);
 131.110 +                        }
 131.111 +                    }
 131.112 +                    if (isHorizontal)
 131.113 +                    {
 131.114 +                        rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MinorTickPen);
 131.115 +
 131.116 +                    }
 131.117 +                    else
 131.118 +                    {
 131.119 +                        rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MinorTickPen);
 131.120 +                    }
 131.121 +                }
 131.122 +            }
 131.123 +
 131.124 +            GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);
 131.125 +
 131.126 +            double maxWidth = 0;
 131.127 +            double maxHeight = 0;
 131.128 +
 131.129 +            foreach (double value in MajorTickValues)
 131.130 +            {
 131.131 +                if (value < axis.ActualMinimum || value > axis.ActualMaximum)
 131.132 +                    continue;
 131.133 +
 131.134 +                double transformedValue = axis.Transform(value);
 131.135 +
 131.136 +                if (MajorPen != null)
 131.137 +                {
 131.138 +                    if (isHorizontal)
 131.139 +                    {
 131.140 +                        rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MajorPen);
 131.141 +
 131.142 +                    }
 131.143 +                    else
 131.144 +                    {
 131.145 +                        rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MajorPen);
 131.146 +                    }
 131.147 +                }
 131.148 +
 131.149 +                if (isHorizontal)
 131.150 +                {
 131.151 +                    rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MajorTickPen);
 131.152 +
 131.153 +                }
 131.154 +                else
 131.155 +                {
 131.156 +                    rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MajorTickPen);
 131.157 +                }
 131.158 +
 131.159 +                if (value == 0 && axis.PositionAtZeroCrossing)
 131.160 +                    continue;
 131.161 +
 131.162 +                var pt = new ScreenPoint();
 131.163 +                var ha = HorizontalTextAlign.Right;
 131.164 +                var va = VerticalTextAlign.Middle;
 131.165 +                switch (axis.Position)
 131.166 +                {
 131.167 +                    case AxisPosition.Left:
 131.168 +                        pt = new ScreenPoint(apos + a1 - TICK_DIST, transformedValue);
 131.169 +                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va);
 131.170 +                        break;
 131.171 +                    case AxisPosition.Right:
 131.172 +                        pt = new ScreenPoint(apos + a1 + TICK_DIST, transformedValue);
 131.173 +                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va);
 131.174 +                        break;
 131.175 +                    case AxisPosition.Top:
 131.176 +                        pt = new ScreenPoint(transformedValue, apos + a1 - TICK_DIST);
 131.177 +                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va);
 131.178 +                        break;
 131.179 +                    case AxisPosition.Bottom:
 131.180 +                        pt = new ScreenPoint(transformedValue, apos + a1 + TICK_DIST);
 131.181 +                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va);
 131.182 +                        break;
 131.183 +
 131.184 +                }
 131.185 +
 131.186 +                string text = axis.FormatValue(value);
 131.187 +                var size = rc.DrawMathText(pt, text, Plot.TextColor,
 131.188 +                             axis.FontFamily, axis.FontSize, axis.FontWeight,
 131.189 +                             axis.Angle, ha, va);
 131.190 +
 131.191 +                maxWidth = Math.Max(maxWidth, size.Width);
 131.192 +                maxHeight = Math.Max(maxHeight, size.Height);
 131.193 +            }
 131.194 +
 131.195 +            if (axis.PositionAtZeroCrossing)
 131.196 +            {
 131.197 +                double t0 = axis.Transform(0);
 131.198 +                if (isHorizontal)
 131.199 +                {
 131.200 +                    rc.DrawLine(t0, Plot.PlotArea.Top, t0, Plot.PlotArea.Bottom, ZeroPen);
 131.201 +
 131.202 +                }
 131.203 +                else
 131.204 +                {
 131.205 +                    rc.DrawLine(Plot.PlotArea.Left, t0, Plot.PlotArea.Right, t0, ZeroPen);
 131.206 +                }
 131.207 +            }
 131.208 +
 131.209 +            if (axis.ExtraGridlines != null)
 131.210 +            {
 131.211 +                foreach (double value in axis.ExtraGridlines)
 131.212 +                {
 131.213 +                    if (!IsWithin(value, axis.ActualMinimum, axis.ActualMaximum))
 131.214 +                        continue;
 131.215 +
 131.216 +                    double transformedValue = axis.Transform(value);
 131.217 +                    if (isHorizontal)
 131.218 +                    {
 131.219 +                        rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, ExtraPen);
 131.220 +
 131.221 +                    }
 131.222 +                    else
 131.223 +                    {
 131.224 +                        rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, ExtraPen);
 131.225 +                    }
 131.226 +                }
 131.227 +            }
 131.228 +            if (isHorizontal)
 131.229 +            {
 131.230 +                rc.DrawLine(Plot.PlotArea.Left, apos, Plot.PlotArea.Right, apos, MajorPen);
 131.231 +
 131.232 +            }
 131.233 +            else
 131.234 +            {
 131.235 +                rc.DrawLine(apos, Plot.PlotArea.Top, apos, Plot.PlotArea.Bottom, MajorPen);
 131.236 +            }
 131.237 +
 131.238 +            if (!String.IsNullOrWhiteSpace(axis.Title))
 131.239 +            {
 131.240 +                // Axis legend
 131.241 +                double ymid = axis.Transform((axis.ActualMinimum + axis.ActualMaximum) / 2);
 131.242 +                double angle = -90;
 131.243 +                var lpt = new ScreenPoint();
 131.244 +
 131.245 +                var halign = HorizontalTextAlign.Center;
 131.246 +                var valign = VerticalTextAlign.Top;
 131.247 +
 131.248 +                if (axis.PositionAtZeroCrossing)
 131.249 +                {
 131.250 +                    ymid = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
 131.251 +                    // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
 131.252 +                }
 131.253 +
 131.254 +                switch (axis.Position)
 131.255 +                {
 131.256 +                    case AxisPosition.Left:
 131.257 +                        lpt = new ScreenPoint(AXIS_LEGEND_DIST, ymid);
 131.258 +                        break;
 131.259 +                    case AxisPosition.Right:
 131.260 +                        lpt = new ScreenPoint(rc.Width - AXIS_LEGEND_DIST, ymid);
 131.261 +                        valign = VerticalTextAlign.Bottom;
 131.262 +                        break;
 131.263 +                    case AxisPosition.Top:
 131.264 +                        lpt = new ScreenPoint(ymid, AXIS_LEGEND_DIST);
 131.265 +                        halign = HorizontalTextAlign.Center;
 131.266 +                        valign = VerticalTextAlign.Top;
 131.267 +                        angle = 0;
 131.268 +                        break;
 131.269 +                    case AxisPosition.Bottom:
 131.270 +                        lpt = new ScreenPoint(ymid, rc.Height - AXIS_LEGEND_DIST);
 131.271 +                        halign = HorizontalTextAlign.Center;
 131.272 +                        valign = VerticalTextAlign.Bottom;
 131.273 +                        angle = 0;
 131.274 +                        break;
 131.275 +                }
 131.276 +
 131.277 +                rc.DrawText(lpt, axis.Title, Plot.TextColor,
 131.278 +                            axis.FontFamily, axis.FontSize, axis.FontWeight,
 131.279 +                            angle, halign, valign);
 131.280 +            }
 131.281 +        }
 131.282 +
 131.283 +        /// <summary>
 131.284 +        /// Gets the rotated alignments given the specified angle.
 131.285 +        /// </summary>
 131.286 +        /// <param name="angle">The angle.</param>
 131.287 +        /// <param name="defaultHorizontalAlignment">The default horizontal alignment.</param>
 131.288 +        /// <param name="defaultVerticalAlignment">The default vertical alignment.</param>
 131.289 +        /// <param name="ha">The rotated horizontal alignment.</param>
 131.290 +        /// <param name="va">The rotated vertical alignment.</param>
 131.291 +        private static void GetRotatedAlignments(double angle, HorizontalTextAlign defaultHorizontalAlignment, VerticalTextAlign defaultVerticalAlignment,
 131.292 +            out HorizontalTextAlign ha, out VerticalTextAlign va)
 131.293 +        {
 131.294 +            ha = defaultHorizontalAlignment;
 131.295 +            va = defaultVerticalAlignment;
 131.296 +
 131.297 +            Debug.Assert(angle <= 180 && angle >= -180, "Axis angle should be in the interval [-180,180] degrees.");
 131.298 +
 131.299 +            if (angle > -45 && angle < 45)
 131.300 +                return;
 131.301 +            if (angle > 135 || angle < -135)
 131.302 +            {
 131.303 +                ha = (HorizontalTextAlign)(-(int)defaultHorizontalAlignment);
 131.304 +                va = (VerticalTextAlign)(-(int)defaultVerticalAlignment);
 131.305 +                return;
 131.306 +            }
 131.307 +            if (angle > 45)
 131.308 +            {
 131.309 +                ha = (HorizontalTextAlign)((int)defaultVerticalAlignment);
 131.310 +                va = (VerticalTextAlign)(-(int)defaultHorizontalAlignment);
 131.311 +                return;
 131.312 +            }
 131.313 +            if (angle < -45)
 131.314 +            {
 131.315 +                ha = (HorizontalTextAlign)(-(int)defaultVerticalAlignment);
 131.316 +                va = (VerticalTextAlign)((int)defaultHorizontalAlignment);
 131.317 +                return;
 131.318 +            }
 131.319 +        }
 131.320 +    }
 131.321 +}
 131.322 \ No newline at end of file
   132.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.2 +++ b/External/OxyPlot/OxyPlot/Reporting/NamespaceDoc.cs	Sat Jun 08 16:53:22 2013 +0000
   132.3 @@ -0,0 +1,39 @@
   132.4 +// --------------------------------------------------------------------------------------------------------------------
   132.5 +// <copyright file="NamespaceDoc.cs" company="OxyPlot">
   132.6 +//   The MIT License (MIT)
   132.7 +//   
   132.8 +//   Copyright (c) 2012 Oystein Bjorke
   132.9 +//   
  132.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  132.11 +//   copy of this software and associated documentation files (the
  132.12 +//   "Software"), to deal in the Software without restriction, including
  132.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  132.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  132.15 +//   permit persons to whom the Software is furnished to do so, subject to
  132.16 +//   the following conditions:
  132.17 +//   
  132.18 +//   The above copyright notice and this permission notice shall be included
  132.19 +//   in all copies or substantial portions of the Software.
  132.20 +//   
  132.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  132.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  132.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  132.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  132.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  132.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  132.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  132.28 +// </copyright>
  132.29 +// --------------------------------------------------------------------------------------------------------------------
  132.30 +
  132.31 +namespace OxyPlot.Reporting
  132.32 +{
  132.33 +    using System.Runtime.CompilerServices;
  132.34 +
  132.35 +    /// <summary>
  132.36 +    ///     The OxyPlot.Reporting namespace contains a simple report model.
  132.37 +    /// </summary>
  132.38 +    [CompilerGenerated]
  132.39 +    internal class NamespaceDoc
  132.40 +    {
  132.41 +    }
  132.42 +}
  132.43 \ No newline at end of file
   133.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   133.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Content.cs	Sat Jun 08 16:53:22 2013 +0000
   133.3 @@ -0,0 +1,75 @@
   133.4 +// --------------------------------------------------------------------------------------------------------------------
   133.5 +// <copyright file="Content.cs" company="OxyPlot">
   133.6 +//   The MIT License (MIT)
   133.7 +//
   133.8 +//   Copyright (c) 2012 Oystein Bjorke
   133.9 +//
  133.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  133.11 +//   copy of this software and associated documentation files (the
  133.12 +//   "Software"), to deal in the Software without restriction, including
  133.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  133.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  133.15 +//   permit persons to whom the Software is furnished to do so, subject to
  133.16 +//   the following conditions:
  133.17 +//
  133.18 +//   The above copyright notice and this permission notice shall be included
  133.19 +//   in all copies or substantial portions of the Software.
  133.20 +//
  133.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  133.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  133.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  133.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  133.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  133.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  133.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  133.28 +// </copyright>
  133.29 +// --------------------------------------------------------------------------------------------------------------------
  133.30 +using System.Collections.Generic;
  133.31 +
  133.32 +namespace OxyPlot.Reporting
  133.33 +{
  133.34 +    public class Content : Table
  133.35 +    {
  133.36 +        public List<ContentItem> Contents { get; set; }
  133.37 +        public ReportItem Base { get; set; }
  133.38 +
  133.39 +        public Content(ReportItem b)
  133.40 +        {
  133.41 +            this.Base = b;
  133.42 +            Class = "content";
  133.43 +            Contents = new List<ContentItem>();
  133.44 +            Columns.Add(new TableColumn(null, "Chapter"));
  133.45 +            Columns.Add(new TableColumn(null, "Title"));
  133.46 +            Items = Contents;
  133.47 +        }
  133.48 +
  133.49 +        public class ContentItem
  133.50 +        {
  133.51 +            public string Chapter { get; set; }
  133.52 +            public string Title { get; set; }
  133.53 +        }
  133.54 +
  133.55 +        public override void Update()
  133.56 +        {
  133.57 +            Contents.Clear();
  133.58 +            var hh = new HeaderHelper();
  133.59 +            Search(Base, hh);
  133.60 +            base.Update();
  133.61 +        }
  133.62 +
  133.63 +        private void Search(ReportItem item, HeaderHelper hh)
  133.64 +        {
  133.65 +            var h = item as Header;
  133.66 +            if (h != null)
  133.67 +            {
  133.68 +                h.Chapter = hh.GetHeader(h.Level);
  133.69 +                Contents.Add(new ContentItem() { Chapter = h.Chapter, Title = h.Text });
  133.70 +            }
  133.71 +            foreach (var c in item.Children)
  133.72 +                Search(c,hh);
  133.73 +        }
  133.74 +        public override void WriteContent(IReportWriter w)
  133.75 +        {
  133.76 +        }
  133.77 +    }
  133.78 +}
  133.79 \ No newline at end of file
   134.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Drawing.cs	Sat Jun 08 16:53:22 2013 +0000
   134.3 @@ -0,0 +1,46 @@
   134.4 +// --------------------------------------------------------------------------------------------------------------------
   134.5 +// <copyright file="Drawing.cs" company="OxyPlot">
   134.6 +//   The MIT License (MIT)
   134.7 +//
   134.8 +//   Copyright (c) 2012 Oystein Bjorke
   134.9 +//
  134.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  134.11 +//   copy of this software and associated documentation files (the
  134.12 +//   "Software"), to deal in the Software without restriction, including
  134.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  134.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  134.15 +//   permit persons to whom the Software is furnished to do so, subject to
  134.16 +//   the following conditions:
  134.17 +//
  134.18 +//   The above copyright notice and this permission notice shall be included
  134.19 +//   in all copies or substantial portions of the Software.
  134.20 +//
  134.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  134.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  134.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  134.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  134.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  134.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  134.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  134.28 +// </copyright>
  134.29 +// <summary>
  134.30 +//   Drawing currently only supports SVG format.
  134.31 +// </summary>
  134.32 +// --------------------------------------------------------------------------------------------------------------------
  134.33 +namespace OxyPlot.Reporting
  134.34 +{
  134.35 +    /// <summary>
  134.36 +    /// Drawing currently only supports SVG format.
  134.37 +    /// </summary>
  134.38 +    public class Drawing : Figure
  134.39 +    {
  134.40 +        public enum DrawingFormat { Svg }
  134.41 +        public DrawingFormat Format { get; set; }
  134.42 +        public string Content { get; set; }
  134.43 +
  134.44 +        public override void WriteContent(IReportWriter w)
  134.45 +        {
  134.46 +            w.WriteDrawing(this);
  134.47 +        }
  134.48 +    }
  134.49 +}
  134.50 \ No newline at end of file
   135.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/DrawingFigure.cs	Sat Jun 08 16:53:22 2013 +0000
   135.3 @@ -0,0 +1,73 @@
   135.4 +// --------------------------------------------------------------------------------------------------------------------
   135.5 +// <copyright file="DrawingFigure.cs" company="OxyPlot">
   135.6 +//   The MIT License (MIT)
   135.7 +//
   135.8 +//   Copyright (c) 2012 Oystein Bjorke
   135.9 +//
  135.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  135.11 +//   copy of this software and associated documentation files (the
  135.12 +//   "Software"), to deal in the Software without restriction, including
  135.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  135.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  135.15 +//   permit persons to whom the Software is furnished to do so, subject to
  135.16 +//   the following conditions:
  135.17 +//
  135.18 +//   The above copyright notice and this permission notice shall be included
  135.19 +//   in all copies or substantial portions of the Software.
  135.20 +//
  135.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  135.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  135.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  135.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  135.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  135.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  135.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  135.28 +// </copyright>
  135.29 +// <summary>
  135.30 +//   Represents a drawing report item.
  135.31 +// </summary>
  135.32 +// --------------------------------------------------------------------------------------------------------------------
  135.33 +namespace OxyPlot.Reporting
  135.34 +{
  135.35 +    /// <summary>
  135.36 +    /// Represents a drawing report item.
  135.37 +    /// </summary>
  135.38 +    /// <remarks>
  135.39 +    /// Drawing currently only supports SVG format.
  135.40 +    /// </remarks>
  135.41 +    public class DrawingFigure : Figure
  135.42 +    {
  135.43 +        /// <summary>
  135.44 +        /// The drawing format.
  135.45 +        /// </summary>
  135.46 +        public enum DrawingFormat
  135.47 +        {
  135.48 +            /// <summary>
  135.49 +            /// The svg.
  135.50 +            /// </summary>
  135.51 +            Svg
  135.52 +        }
  135.53 +
  135.54 +        /// <summary>
  135.55 +        /// Gets or sets Content.
  135.56 +        /// </summary>
  135.57 +        public string Content { get; set; }
  135.58 +
  135.59 +        /// <summary>
  135.60 +        /// Gets or sets Format.
  135.61 +        /// </summary>
  135.62 +        public DrawingFormat Format { get; set; }
  135.63 +
  135.64 +        /// <summary>
  135.65 +        /// The write content.
  135.66 +        /// </summary>
  135.67 +        /// <param name="w">
  135.68 +        /// The w.
  135.69 +        /// </param>
  135.70 +        public override void WriteContent(IReportWriter w)
  135.71 +        {
  135.72 +            w.WriteDrawing(this);
  135.73 +        }
  135.74 +
  135.75 +    }
  135.76 +}
  135.77 \ No newline at end of file
   136.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   136.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Equation.cs	Sat Jun 08 16:53:22 2013 +0000
   136.3 @@ -0,0 +1,59 @@
   136.4 +// --------------------------------------------------------------------------------------------------------------------
   136.5 +// <copyright file="Equation.cs" company="OxyPlot">
   136.6 +//   The MIT License (MIT)
   136.7 +//
   136.8 +//   Copyright (c) 2012 Oystein Bjorke
   136.9 +//
  136.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  136.11 +//   copy of this software and associated documentation files (the
  136.12 +//   "Software"), to deal in the Software without restriction, including
  136.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  136.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  136.15 +//   permit persons to whom the Software is furnished to do so, subject to
  136.16 +//   the following conditions:
  136.17 +//
  136.18 +//   The above copyright notice and this permission notice shall be included
  136.19 +//   in all copies or substantial portions of the Software.
  136.20 +//
  136.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  136.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  136.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  136.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  136.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  136.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  136.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  136.28 +// </copyright>
  136.29 +// <summary>
  136.30 +//   Represents an equation.
  136.31 +// </summary>
  136.32 +// --------------------------------------------------------------------------------------------------------------------
  136.33 +namespace OxyPlot.Reporting
  136.34 +{
  136.35 +    /// <summary>
  136.36 +    /// Represents an equation.
  136.37 +    /// </summary>
  136.38 +    public class Equation : ReportItem
  136.39 +    {
  136.40 +        /// <summary>
  136.41 +        /// Gets or sets Caption.
  136.42 +        /// </summary>
  136.43 +        public string Caption { get; set; }
  136.44 +
  136.45 +        /// <summary>
  136.46 +        /// Gets or sets Content.
  136.47 +        /// </summary>
  136.48 +        public string Content { get; set; }
  136.49 +
  136.50 +        /// <summary>
  136.51 +        /// The write content.
  136.52 +        /// </summary>
  136.53 +        /// <param name="w">
  136.54 +        /// The w.
  136.55 +        /// </param>
  136.56 +        public override void WriteContent(IReportWriter w)
  136.57 +        {
  136.58 +            w.WriteEquation(this);
  136.59 +        }
  136.60 +
  136.61 +    }
  136.62 +}
  136.63 \ No newline at end of file
   137.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Figure.cs	Sat Jun 08 16:53:22 2013 +0000
   137.3 @@ -0,0 +1,62 @@
   137.4 +// --------------------------------------------------------------------------------------------------------------------
   137.5 +// <copyright file="Figure.cs" company="OxyPlot">
   137.6 +//   The MIT License (MIT)
   137.7 +//
   137.8 +//   Copyright (c) 2012 Oystein Bjorke
   137.9 +//
  137.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  137.11 +//   copy of this software and associated documentation files (the
  137.12 +//   "Software"), to deal in the Software without restriction, including
  137.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  137.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  137.15 +//   permit persons to whom the Software is furnished to do so, subject to
  137.16 +//   the following conditions:
  137.17 +//
  137.18 +//   The above copyright notice and this permission notice shall be included
  137.19 +//   in all copies or substantial portions of the Software.
  137.20 +//
  137.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  137.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  137.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  137.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  137.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  137.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  137.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  137.28 +// </copyright>
  137.29 +// <summary>
  137.30 +//   Represents a figure (abstract base class for DrawingFigure, Image and PlotFigure).
  137.31 +// </summary>
  137.32 +// --------------------------------------------------------------------------------------------------------------------
  137.33 +namespace OxyPlot.Reporting
  137.34 +{
  137.35 +    /// <summary>
  137.36 +    /// Represents a figure (abstract base class for DrawingFigure, Image and PlotFigure).
  137.37 +    /// </summary>
  137.38 +    public abstract class Figure : ReportItem
  137.39 +    {
  137.40 +        /// <summary>
  137.41 +        /// Gets or sets FigureNumber.
  137.42 +        /// </summary>
  137.43 +        public int FigureNumber { get; set; }
  137.44 +
  137.45 +        /// <summary>
  137.46 +        /// Gets or sets FigureText.
  137.47 +        /// </summary>
  137.48 +        public string FigureText { get; set; }
  137.49 +
  137.50 +        /// <summary>
  137.51 +        /// The get full caption.
  137.52 +        /// </summary>
  137.53 +        /// <param name="style">
  137.54 +        /// The style.
  137.55 +        /// </param>
  137.56 +        /// <returns>
  137.57 +        /// The get full caption.
  137.58 +        /// </returns>
  137.59 +        public string GetFullCaption(ReportStyle style)
  137.60 +        {
  137.61 +            return string.Format(style.FigureTextFormatString, this.FigureNumber, this.FigureText);
  137.62 +        }
  137.63 +
  137.64 +    }
  137.65 +}
  137.66 \ No newline at end of file
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Header.cs	Sat Jun 08 16:53:22 2013 +0000
   138.3 @@ -0,0 +1,82 @@
   138.4 +// --------------------------------------------------------------------------------------------------------------------
   138.5 +// <copyright file="Header.cs" company="OxyPlot">
   138.6 +//   The MIT License (MIT)
   138.7 +//
   138.8 +//   Copyright (c) 2012 Oystein Bjorke
   138.9 +//
  138.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  138.11 +//   copy of this software and associated documentation files (the
  138.12 +//   "Software"), to deal in the Software without restriction, including
  138.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  138.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  138.15 +//   permit persons to whom the Software is furnished to do so, subject to
  138.16 +//   the following conditions:
  138.17 +//
  138.18 +//   The above copyright notice and this permission notice shall be included
  138.19 +//   in all copies or substantial portions of the Software.
  138.20 +//
  138.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  138.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  138.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  138.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  138.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  138.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  138.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  138.28 +// </copyright>
  138.29 +// <summary>
  138.30 +//   Represents a header.
  138.31 +// </summary>
  138.32 +// --------------------------------------------------------------------------------------------------------------------
  138.33 +namespace OxyPlot.Reporting
  138.34 +{
  138.35 +    /// <summary>
  138.36 +    /// Represents a header.
  138.37 +    /// </summary>
  138.38 +    public class Header : ReportItem
  138.39 +    {
  138.40 +        /// <summary>
  138.41 +        /// Gets or sets the chapter number(s).
  138.42 +        /// </summary>
  138.43 +        public string Chapter { get; set; }
  138.44 +
  138.45 +        /// <summary>
  138.46 +        /// Gets or sets the level of the header (1-5).
  138.47 +        /// </summary>
  138.48 +        public int Level { get; set; }
  138.49 +
  138.50 +        /// <summary>
  138.51 +        /// Gets or sets the header text.
  138.52 +        /// </summary>
  138.53 +        public string Text { get; set; }
  138.54 +
  138.55 +        /// <summary>
  138.56 +        /// The to string.
  138.57 +        /// </summary>
  138.58 +        /// <returns>
  138.59 +        /// The to string.
  138.60 +        /// </returns>
  138.61 +        public override string ToString()
  138.62 +        {
  138.63 +            string h = string.Empty;
  138.64 +            if (this.Chapter != null)
  138.65 +            {
  138.66 +                h += this.Chapter + " ";
  138.67 +            }
  138.68 +
  138.69 +            h += this.Text;
  138.70 +            return h;
  138.71 +        }
  138.72 +
  138.73 +        /// <summary>
  138.74 +        /// The write content.
  138.75 +        /// </summary>
  138.76 +        /// <param name="w">
  138.77 +        /// The w.
  138.78 +        /// </param>
  138.79 +        public override void WriteContent(IReportWriter w)
  138.80 +        {
  138.81 +            w.WriteHeader(this);
  138.82 +        }
  138.83 +
  138.84 +    }
  138.85 +}
  138.86 \ No newline at end of file
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/HeaderHelper.cs	Sat Jun 08 16:53:22 2013 +0000
   139.3 @@ -0,0 +1,82 @@
   139.4 +// --------------------------------------------------------------------------------------------------------------------
   139.5 +// <copyright file="HeaderHelper.cs" company="OxyPlot">
   139.6 +//   The MIT License (MIT)
   139.7 +//
   139.8 +//   Copyright (c) 2012 Oystein Bjorke
   139.9 +//
  139.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  139.11 +//   copy of this software and associated documentation files (the
  139.12 +//   "Software"), to deal in the Software without restriction, including
  139.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  139.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  139.15 +//   permit persons to whom the Software is furnished to do so, subject to
  139.16 +//   the following conditions:
  139.17 +//
  139.18 +//   The above copyright notice and this permission notice shall be included
  139.19 +//   in all copies or substantial portions of the Software.
  139.20 +//
  139.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  139.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  139.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  139.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  139.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  139.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  139.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  139.28 +// </copyright>
  139.29 +// <summary>
  139.30 +//   The header helper.
  139.31 +// </summary>
  139.32 +// --------------------------------------------------------------------------------------------------------------------
  139.33 +namespace OxyPlot.Reporting
  139.34 +{
  139.35 +    /// <summary>
  139.36 +    /// The header helper.
  139.37 +    /// </summary>
  139.38 +    public class HeaderHelper
  139.39 +    {
  139.40 +        /// <summary>
  139.41 +        /// The header level.
  139.42 +        /// </summary>
  139.43 +        private readonly int[] headerLevel = new int[10];
  139.44 +
  139.45 +        /// <summary>
  139.46 +        /// The get header.
  139.47 +        /// </summary>
  139.48 +        /// <param name="level">
  139.49 +        /// The level.
  139.50 +        /// </param>
  139.51 +        /// <returns>
  139.52 +        /// The get header.
  139.53 +        /// </returns>
  139.54 +        public string GetHeader(int level)
  139.55 +        {
  139.56 +            for (int i = level - 1; i > 0; i--)
  139.57 +            {
  139.58 +                if (this.headerLevel[i] == 0)
  139.59 +                {
  139.60 +                    this.headerLevel[i] = 1;
  139.61 +                }
  139.62 +            }
  139.63 +
  139.64 +            this.headerLevel[level]++;
  139.65 +            for (int i = level + 1; i < 10; i++)
  139.66 +            {
  139.67 +                this.headerLevel[i] = 0;
  139.68 +            }
  139.69 +
  139.70 +            string levelString = string.Empty;
  139.71 +            for (int i = 1; i <= level; i++)
  139.72 +            {
  139.73 +                if (i > 1)
  139.74 +                {
  139.75 +                    levelString += ".";
  139.76 +                }
  139.77 +
  139.78 +                levelString += this.headerLevel[i];
  139.79 +            }
  139.80 +
  139.81 +            return levelString;
  139.82 +        }
  139.83 +
  139.84 +    }
  139.85 +}
  139.86 \ No newline at end of file
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Image.cs	Sat Jun 08 16:53:22 2013 +0000
   140.3 @@ -0,0 +1,54 @@
   140.4 +// --------------------------------------------------------------------------------------------------------------------
   140.5 +// <copyright file="Image.cs" company="OxyPlot">
   140.6 +//   The MIT License (MIT)
   140.7 +//
   140.8 +//   Copyright (c) 2012 Oystein Bjorke
   140.9 +//
  140.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  140.11 +//   copy of this software and associated documentation files (the
  140.12 +//   "Software"), to deal in the Software without restriction, including
  140.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  140.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  140.15 +//   permit persons to whom the Software is furnished to do so, subject to
  140.16 +//   the following conditions:
  140.17 +//
  140.18 +//   The above copyright notice and this permission notice shall be included
  140.19 +//   in all copies or substantial portions of the Software.
  140.20 +//
  140.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  140.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  140.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  140.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  140.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  140.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  140.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  140.28 +// </copyright>
  140.29 +// <summary>
  140.30 +//   Represents an image report item.
  140.31 +// </summary>
  140.32 +// --------------------------------------------------------------------------------------------------------------------
  140.33 +namespace OxyPlot.Reporting
  140.34 +{
  140.35 +    /// <summary>
  140.36 +    /// Represents an image report item.
  140.37 +    /// </summary>
  140.38 +    public class Image : Figure
  140.39 +    {
  140.40 +        /// <summary>
  140.41 +        /// Gets or sets Source.
  140.42 +        /// </summary>
  140.43 +        public string Source { get; set; }
  140.44 +
  140.45 +        /// <summary>
  140.46 +        /// The write content.
  140.47 +        /// </summary>
  140.48 +        /// <param name="w">
  140.49 +        /// The w.
  140.50 +        /// </param>
  140.51 +        public override void WriteContent(IReportWriter w)
  140.52 +        {
  140.53 +            w.WriteImage(this);
  140.54 +        }
  140.55 +
  140.56 +    }
  140.57 +}
  140.58 \ No newline at end of file
   141.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ItemsTable.cs	Sat Jun 08 16:53:22 2013 +0000
   141.3 @@ -0,0 +1,243 @@
   141.4 +// --------------------------------------------------------------------------------------------------------------------
   141.5 +// <copyright file="ItemsTable.cs" company="OxyPlot">
   141.6 +//   The MIT License (MIT)
   141.7 +//
   141.8 +//   Copyright (c) 2012 Oystein Bjorke
   141.9 +//
  141.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  141.11 +//   copy of this software and associated documentation files (the
  141.12 +//   "Software"), to deal in the Software without restriction, including
  141.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  141.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  141.15 +//   permit persons to whom the Software is furnished to do so, subject to
  141.16 +//   the following conditions:
  141.17 +//
  141.18 +//   The above copyright notice and this permission notice shall be included
  141.19 +//   in all copies or substantial portions of the Software.
  141.20 +//
  141.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  141.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  141.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  141.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  141.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  141.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  141.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  141.28 +// </copyright>
  141.29 +// <summary>
  141.30 +//   Represents a table of items.
  141.31 +// </summary>
  141.32 +// --------------------------------------------------------------------------------------------------------------------
  141.33 +namespace OxyPlot.Reporting
  141.34 +{
  141.35 +    using System.Collections;
  141.36 +    using System.Collections.Generic;
  141.37 +    using System.Diagnostics;
  141.38 +    using System.Linq;
  141.39 +
  141.40 +    /// <summary>
  141.41 +    /// Represents a table of items.
  141.42 +    /// </summary>
  141.43 +    public class ItemsTable : Table
  141.44 +    {
  141.45 +        /// <summary>
  141.46 +        /// Initializes a new instance of the <see cref="ItemsTable"/> class.
  141.47 +        /// </summary>
  141.48 +        /// <param name="itemsInRows">
  141.49 +        /// The items in rows.
  141.50 +        /// </param>
  141.51 +        public ItemsTable(bool itemsInRows = true)
  141.52 +        {
  141.53 +            this.Fields = new List<ItemsTableField>();
  141.54 +            this.ItemsInRows = itemsInRows;
  141.55 +            this.Alignment = Alignment.Center;
  141.56 +        }
  141.57 +
  141.58 +        /// <summary>
  141.59 +        /// Gets or sets Alignment.
  141.60 +        /// </summary>
  141.61 +        public Alignment Alignment { get; set; }
  141.62 +
  141.63 +        /// <summary>
  141.64 +        /// Gets or sets Fields.
  141.65 +        /// </summary>
  141.66 +        public IList<ItemsTableField> Fields { get; set; }
  141.67 +
  141.68 +        /// <summary>
  141.69 +        /// Gets or sets the items.
  141.70 +        /// The table will be filled when this property is set.
  141.71 +        /// </summary>
  141.72 +        /// <value>The items.</value>
  141.73 +        public IEnumerable Items { get; set; }
  141.74 +
  141.75 +        /// <summary>
  141.76 +        /// Gets a value indicating whether ItemsInRows.
  141.77 +        /// </summary>
  141.78 +        public bool ItemsInRows { get; private set; }
  141.79 +
  141.80 +        /// <summary>
  141.81 +        /// The has header.
  141.82 +        /// </summary>
  141.83 +        /// <returns>
  141.84 +        /// The has header.
  141.85 +        /// </returns>
  141.86 +        public bool HasHeader()
  141.87 +        {
  141.88 +            foreach (var c in this.Fields)
  141.89 +            {
  141.90 +                if (c.Header != null)
  141.91 +                {
  141.92 +                    return true;
  141.93 +                }
  141.94 +            }
  141.95 +
  141.96 +            return false;
  141.97 +        }
  141.98 +
  141.99 +        /// <summary>
 141.100 +        /// The to array.
 141.101 +        /// </summary>
 141.102 +        /// <returns>
 141.103 +        /// </returns>
 141.104 +        public string[,] ToArray()
 141.105 +        {
 141.106 +            List<object> items = this.Items.Cast<object>().ToList();
 141.107 +            int nrows = items.Count;
 141.108 +
 141.109 +            bool hasHeader = this.HasHeader();
 141.110 +            if (hasHeader)
 141.111 +            {
 141.112 +                nrows++;
 141.113 +            }
 141.114 +
 141.115 +            var result = new string[nrows, this.Fields.Count];
 141.116 +
 141.117 +            int row = 0;
 141.118 +            if (hasHeader)
 141.119 +            {
 141.120 +                for (int i = 0; i < this.Fields.Count; i++)
 141.121 +                {
 141.122 +                    ItemsTableField c = this.Fields[i];
 141.123 +                    result[row, i] = c.Header;
 141.124 +                }
 141.125 +
 141.126 +                row++;
 141.127 +            }
 141.128 +
 141.129 +            foreach (var item in items)
 141.130 +            {
 141.131 +                for (int i = 0; i < this.Fields.Count; i++)
 141.132 +                {
 141.133 +                    ItemsTableField c = this.Fields[i];
 141.134 +                    string text = c.GetText(item, this.Report.ActualCulture);
 141.135 +                    result[row, i] = text;
 141.136 +                }
 141.137 +
 141.138 +                row++;
 141.139 +            }
 141.140 +
 141.141 +            if (!this.ItemsInRows)
 141.142 +            {
 141.143 +                result = Transpose(result);
 141.144 +            }
 141.145 +
 141.146 +            return result;
 141.147 +        }
 141.148 +
 141.149 +        /// <summary>
 141.150 +        /// The update.
 141.151 +        /// </summary>
 141.152 +        public override void Update()
 141.153 +        {
 141.154 +            base.Update();
 141.155 +            this.UpdateItems();
 141.156 +        }
 141.157 +
 141.158 +        /// <summary>
 141.159 +        /// The update items.
 141.160 +        /// </summary>
 141.161 +        public void UpdateItems()
 141.162 +        {
 141.163 +            this.Rows.Clear();
 141.164 +            this.Columns.Clear();
 141.165 +            if (this.Fields == null || this.Fields.Count == 0)
 141.166 +            {
 141.167 +                return;
 141.168 +            }
 141.169 +
 141.170 +            string[,] cells = this.ToArray();
 141.171 +
 141.172 +            int rows = cells.GetUpperBound(0) + 1;
 141.173 +            int columns = cells.GetUpperBound(1) + 1;
 141.174 +            for (int i = 0; i < rows; i++)
 141.175 +            {
 141.176 +                var tr = new TableRow();
 141.177 +                if (this.ItemsInRows)
 141.178 +                {
 141.179 +                    tr.IsHeader = i == 0;
 141.180 +                }
 141.181 +
 141.182 +                this.Rows.Add(tr);
 141.183 +                for (int j = 0; j < columns; j++)
 141.184 +                {
 141.185 +                    var tc = new TableCell();
 141.186 +                    tc.Content = cells[i, j];
 141.187 +                    tr.Cells.Add(tc);
 141.188 +                }
 141.189 +            }
 141.190 +
 141.191 +            for (int j = 0; j < columns; j++)
 141.192 +            {
 141.193 +                var tc = new TableColumn();
 141.194 +                if (this.ItemsInRows)
 141.195 +                {
 141.196 +                    ItemsTableField f = this.Fields[j];
 141.197 +                    tc.Alignment = f.Alignment;
 141.198 +                    tc.Width = f.Width;
 141.199 +                }
 141.200 +                else
 141.201 +                {
 141.202 +                    tc.IsHeader = j == 0;
 141.203 +                    tc.Alignment = this.Alignment;
 141.204 +                }
 141.205 +
 141.206 +                this.Columns.Add(tc);
 141.207 +            }
 141.208 +        }
 141.209 +
 141.210 +        /// <summary>
 141.211 +        /// Writes the content of the item.
 141.212 +        /// </summary>
 141.213 +        /// <param name="w">
 141.214 +        /// The writer.
 141.215 +        /// </param>
 141.216 +        public override void WriteContent(IReportWriter w)
 141.217 +        {
 141.218 +            w.WriteTable(this);
 141.219 +        }
 141.220 +
 141.221 +        /// <summary>
 141.222 +        /// The transpose.
 141.223 +        /// </summary>
 141.224 +        /// <param name="input">
 141.225 +        /// The input.
 141.226 +        /// </param>
 141.227 +        /// <returns>
 141.228 +        /// </returns>
 141.229 +        private static string[,] Transpose(string[,] input)
 141.230 +        {
 141.231 +            int rows = input.GetUpperBound(0) + 1;
 141.232 +            int cols = input.GetUpperBound(1) + 1;
 141.233 +            var result = new string[cols, rows];
 141.234 +            for (int i = 0; i < rows; i++)
 141.235 +            {
 141.236 +                for (int j = 0; j < cols; j++)
 141.237 +                {
 141.238 +                    result[j, i] = input[i, j];
 141.239 +                }
 141.240 +            }
 141.241 +
 141.242 +            return result;
 141.243 +        }
 141.244 +
 141.245 +    }
 141.246 +}
 141.247 \ No newline at end of file
   142.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ItemsTableField.cs	Sat Jun 08 16:53:22 2013 +0000
   142.3 @@ -0,0 +1,136 @@
   142.4 +// --------------------------------------------------------------------------------------------------------------------
   142.5 +// <copyright file="ItemsTableField.cs" company="OxyPlot">
   142.6 +//   The MIT License (MIT)
   142.7 +//
   142.8 +//   Copyright (c) 2012 Oystein Bjorke
   142.9 +//
  142.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  142.11 +//   copy of this software and associated documentation files (the
  142.12 +//   "Software"), to deal in the Software without restriction, including
  142.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  142.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  142.15 +//   permit persons to whom the Software is furnished to do so, subject to
  142.16 +//   the following conditions:
  142.17 +//
  142.18 +//   The above copyright notice and this permission notice shall be included
  142.19 +//   in all copies or substantial portions of the Software.
  142.20 +//
  142.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  142.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  142.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  142.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  142.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  142.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  142.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  142.28 +// </copyright>
  142.29 +// <summary>
  142.30 +//   The alignment.
  142.31 +// </summary>
  142.32 +// --------------------------------------------------------------------------------------------------------------------
  142.33 +namespace OxyPlot.Reporting
  142.34 +{
  142.35 +    using System;
  142.36 +    using System.Reflection;
  142.37 +
  142.38 +    /// <summary>
  142.39 +    /// The alignment.
  142.40 +    /// </summary>
  142.41 +    public enum Alignment
  142.42 +    {
  142.43 +        /// <summary>
  142.44 +        /// The left.
  142.45 +        /// </summary>
  142.46 +        Left,
  142.47 +
  142.48 +        /// <summary>
  142.49 +        /// The right.
  142.50 +        /// </summary>
  142.51 +        Right,
  142.52 +
  142.53 +        /// <summary>
  142.54 +        /// The center.
  142.55 +        /// </summary>
  142.56 +        Center
  142.57 +    }
  142.58 +
  142.59 +    /// <summary>
  142.60 +    /// Represents a field in an items table.
  142.61 +    /// </summary>
  142.62 +    public class ItemsTableField
  142.63 +    {
  142.64 +        /// <summary>
  142.65 +        /// Initializes a new instance of the <see cref="ItemsTableField"/> class.
  142.66 +        /// </summary>
  142.67 +        /// <param name="header">
  142.68 +        /// The header.
  142.69 +        /// </param>
  142.70 +        /// <param name="path">
  142.71 +        /// The path.
  142.72 +        /// </param>
  142.73 +        /// <param name="stringFormat">
  142.74 +        /// The string format.
  142.75 +        /// </param>
  142.76 +        /// <param name="alignment">
  142.77 +        /// The alignment.
  142.78 +        /// </param>
  142.79 +        public ItemsTableField(
  142.80 +            string header, string path, string stringFormat = null, Alignment alignment = Alignment.Center)
  142.81 +        {
  142.82 +            this.Header = header;
  142.83 +            this.Path = path;
  142.84 +            this.StringFormat = stringFormat;
  142.85 +            this.Alignment = alignment;
  142.86 +        }
  142.87 +
  142.88 +        /// <summary>
  142.89 +        /// Gets or sets Alignment.
  142.90 +        /// </summary>
  142.91 +        public Alignment Alignment { get; set; }
  142.92 +
  142.93 +        /// <summary>
  142.94 +        /// Gets or sets Header.
  142.95 +        /// </summary>
  142.96 +        public string Header { get; set; }
  142.97 +
  142.98 +        /// <summary>
  142.99 +        /// Gets or sets Path.
 142.100 +        /// </summary>
 142.101 +        public string Path { get; set; }
 142.102 +
 142.103 +        /// <summary>
 142.104 +        /// Gets or sets StringFormat.
 142.105 +        /// </summary>
 142.106 +        public string StringFormat { get; set; }
 142.107 +
 142.108 +        /// <summary>
 142.109 +        /// Gets or sets Width.
 142.110 +        /// </summary>
 142.111 +        public double Width { get; set; }
 142.112 +
 142.113 +        /// <summary>
 142.114 +        /// Gets the text.
 142.115 +        /// </summary>
 142.116 +        /// <param name="item">
 142.117 +        /// The item.
 142.118 +        /// </param>
 142.119 +        /// <param name="formatProvider">
 142.120 +        /// The format provider.
 142.121 +        /// </param>
 142.122 +        /// <returns>
 142.123 +        /// The text.
 142.124 +        /// </returns>
 142.125 +        public string GetText(object item, IFormatProvider formatProvider)
 142.126 +        {
 142.127 +            PropertyInfo pi = item.GetType().GetProperty(this.Path);
 142.128 +            object o = pi.GetValue(item, null);
 142.129 +            var of = o as IFormattable;
 142.130 +            if (of != null)
 142.131 +            {
 142.132 +                return of.ToString(this.StringFormat, formatProvider);
 142.133 +            }
 142.134 +
 142.135 +            return o != null ? o.ToString() : null;
 142.136 +        }
 142.137 +
 142.138 +    }
 142.139 +}
 142.140 \ No newline at end of file
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Paragraph.cs	Sat Jun 08 16:53:22 2013 +0000
   143.3 @@ -0,0 +1,54 @@
   143.4 +// --------------------------------------------------------------------------------------------------------------------
   143.5 +// <copyright file="Paragraph.cs" company="OxyPlot">
   143.6 +//   The MIT License (MIT)
   143.7 +//
   143.8 +//   Copyright (c) 2012 Oystein Bjorke
   143.9 +//
  143.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  143.11 +//   copy of this software and associated documentation files (the
  143.12 +//   "Software"), to deal in the Software without restriction, including
  143.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  143.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  143.15 +//   permit persons to whom the Software is furnished to do so, subject to
  143.16 +//   the following conditions:
  143.17 +//
  143.18 +//   The above copyright notice and this permission notice shall be included
  143.19 +//   in all copies or substantial portions of the Software.
  143.20 +//
  143.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  143.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  143.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  143.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  143.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  143.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  143.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  143.28 +// </copyright>
  143.29 +// <summary>
  143.30 +//   Represents a paragraph.
  143.31 +// </summary>
  143.32 +// --------------------------------------------------------------------------------------------------------------------
  143.33 +namespace OxyPlot.Reporting
  143.34 +{
  143.35 +    /// <summary>
  143.36 +    /// Represents a paragraph.
  143.37 +    /// </summary>
  143.38 +    public class Paragraph : ReportItem
  143.39 +    {
  143.40 +        /// <summary>
  143.41 +        /// Gets or sets Text.
  143.42 +        /// </summary>
  143.43 +        public string Text { get; set; }
  143.44 +
  143.45 +        /// <summary>
  143.46 +        /// The write content.
  143.47 +        /// </summary>
  143.48 +        /// <param name="w">
  143.49 +        /// The w.
  143.50 +        /// </param>
  143.51 +        public override void WriteContent(IReportWriter w)
  143.52 +        {
  143.53 +            w.WriteParagraph(this);
  143.54 +        }
  143.55 +
  143.56 +    }
  143.57 +}
  143.58 \ No newline at end of file
   144.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ParagraphStyle.cs	Sat Jun 08 16:53:22 2013 +0000
   144.3 @@ -0,0 +1,397 @@
   144.4 +// --------------------------------------------------------------------------------------------------------------------
   144.5 +// <copyright file="ParagraphStyle.cs" company="OxyPlot">
   144.6 +//   The MIT License (MIT)
   144.7 +//
   144.8 +//   Copyright (c) 2012 Oystein Bjorke
   144.9 +//
  144.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  144.11 +//   copy of this software and associated documentation files (the
  144.12 +//   "Software"), to deal in the Software without restriction, including
  144.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  144.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  144.15 +//   permit persons to whom the Software is furnished to do so, subject to
  144.16 +//   the following conditions:
  144.17 +//
  144.18 +//   The above copyright notice and this permission notice shall be included
  144.19 +//   in all copies or substantial portions of the Software.
  144.20 +//
  144.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  144.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  144.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  144.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  144.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  144.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  144.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  144.28 +// </copyright>
  144.29 +// <summary>
  144.30 +//   The paragraph style.
  144.31 +// </summary>
  144.32 +// --------------------------------------------------------------------------------------------------------------------
  144.33 +namespace OxyPlot.Reporting
  144.34 +{
  144.35 +    /// <summary>
  144.36 +    /// The paragraph style.
  144.37 +    /// </summary>
  144.38 +    public class ParagraphStyle
  144.39 +    {
  144.40 +        /// <summary>
  144.41 +        /// The default font.
  144.42 +        /// </summary>
  144.43 +        private const string DefaultFont = "Arial";
  144.44 +
  144.45 +        /// <summary>
  144.46 +        /// The default font size.
  144.47 +        /// </summary>
  144.48 +        private const double DefaultFontSize = 11;
  144.49 +
  144.50 +        /// <summary>
  144.51 +        /// The bold.
  144.52 +        /// </summary>
  144.53 +        private bool? bold;
  144.54 +
  144.55 +        /// <summary>
  144.56 +        /// The font family.
  144.57 +        /// </summary>
  144.58 +        private string fontFamily;
  144.59 +
  144.60 +        /// <summary>
  144.61 +        /// The font size.
  144.62 +        /// </summary>
  144.63 +        private double? fontSize;
  144.64 +
  144.65 +        /// <summary>
  144.66 +        /// The italic.
  144.67 +        /// </summary>
  144.68 +        private bool? italic;
  144.69 +
  144.70 +        /// <summary>
  144.71 +        /// The left indentation.
  144.72 +        /// </summary>
  144.73 +        private double? leftIndentation;
  144.74 +
  144.75 +        /// <summary>
  144.76 +        /// The line spacing.
  144.77 +        /// </summary>
  144.78 +        private double? lineSpacing;
  144.79 +
  144.80 +        /// <summary>
  144.81 +        /// The page break before.
  144.82 +        /// </summary>
  144.83 +        private bool? pageBreakBefore;
  144.84 +
  144.85 +        /// <summary>
  144.86 +        /// The right indentation.
  144.87 +        /// </summary>
  144.88 +        private double? rightIndentation;
  144.89 +
  144.90 +        /// <summary>
  144.91 +        /// The spacing after.
  144.92 +        /// </summary>
  144.93 +        private double? spacingAfter;
  144.94 +
  144.95 +        /// <summary>
  144.96 +        /// The spacing before.
  144.97 +        /// </summary>
  144.98 +        private double? spacingBefore;
  144.99 +
 144.100 +        /// <summary>
 144.101 +        /// The text color.
 144.102 +        /// </summary>
 144.103 +        private OxyColor textColor;
 144.104 +
 144.105 +        /// <summary>
 144.106 +        /// Gets or sets BasedOn.
 144.107 +        /// </summary>
 144.108 +        public ParagraphStyle BasedOn { get; set; }
 144.109 +
 144.110 +        /// <summary>
 144.111 +        /// Gets or sets a value indicating whether Bold.
 144.112 +        /// </summary>
 144.113 +        public bool Bold
 144.114 +        {
 144.115 +            get
 144.116 +            {
 144.117 +                if (this.bold != null)
 144.118 +                {
 144.119 +                    return this.bold.Value;
 144.120 +                }
 144.121 +
 144.122 +                if (this.BasedOn != null)
 144.123 +                {
 144.124 +                    return this.BasedOn.Bold;
 144.125 +                }
 144.126 +
 144.127 +                return false;
 144.128 +            }
 144.129 +
 144.130 +            set
 144.131 +            {
 144.132 +                this.bold = value;
 144.133 +            }
 144.134 +        }
 144.135 +
 144.136 +        /// <summary>
 144.137 +        /// Gets or sets FontFamily.
 144.138 +        /// </summary>
 144.139 +        public string FontFamily
 144.140 +        {
 144.141 +            get
 144.142 +            {
 144.143 +                if (this.fontFamily != null)
 144.144 +                {
 144.145 +                    return this.fontFamily;
 144.146 +                }
 144.147 +
 144.148 +                if (this.BasedOn != null)
 144.149 +                {
 144.150 +                    return this.BasedOn.FontFamily;
 144.151 +                }
 144.152 +
 144.153 +                return DefaultFont;
 144.154 +            }
 144.155 +
 144.156 +            set
 144.157 +            {
 144.158 +                this.fontFamily = value;
 144.159 +            }
 144.160 +        }
 144.161 +
 144.162 +        /// <summary>
 144.163 +        /// Gets or sets FontSize.
 144.164 +        /// </summary>
 144.165 +        public double FontSize
 144.166 +        {
 144.167 +            get
 144.168 +            {
 144.169 +                if (this.fontSize != null)
 144.170 +                {
 144.171 +                    return this.fontSize.Value;
 144.172 +                }
 144.173 +
 144.174 +                if (this.BasedOn != null)
 144.175 +                {
 144.176 +                    return this.BasedOn.FontSize;
 144.177 +                }
 144.178 +
 144.179 +                return DefaultFontSize;
 144.180 +            }
 144.181 +
 144.182 +            set
 144.183 +            {
 144.184 +                this.fontSize = value;
 144.185 +            }
 144.186 +        }
 144.187 +
 144.188 +        /// <summary>
 144.189 +        /// Gets or sets a value indicating whether Italic.
 144.190 +        /// </summary>
 144.191 +        public bool Italic
 144.192 +        {
 144.193 +            get
 144.194 +            {
 144.195 +                if (this.italic != null)
 144.196 +                {
 144.197 +                    return this.italic.Value;
 144.198 +                }
 144.199 +
 144.200 +                if (this.BasedOn != null)
 144.201 +                {
 144.202 +                    return this.BasedOn.Italic;
 144.203 +                }
 144.204 +
 144.205 +                return false;
 144.206 +            }
 144.207 +
 144.208 +            set
 144.209 +            {
 144.210 +                this.italic = value;
 144.211 +            }
 144.212 +        }
 144.213 +
 144.214 +        /// <summary>
 144.215 +        /// Gets or sets LeftIndentation.
 144.216 +        /// </summary>
 144.217 +        public double LeftIndentation
 144.218 +        {
 144.219 +            get
 144.220 +            {
 144.221 +                if (this.leftIndentation != null)
 144.222 +                {
 144.223 +                    return this.leftIndentation.Value;
 144.224 +                }
 144.225 +
 144.226 +                if (this.BasedOn != null)
 144.227 +                {
 144.228 +                    return this.BasedOn.LeftIndentation;
 144.229 +                }
 144.230 +
 144.231 +                return 0;
 144.232 +            }
 144.233 +
 144.234 +            set
 144.235 +            {
 144.236 +                this.leftIndentation = value;
 144.237 +            }
 144.238 +        }
 144.239 +
 144.240 +        /// <summary>
 144.241 +        /// Gets or sets LineSpacing.
 144.242 +        /// </summary>
 144.243 +        public double LineSpacing
 144.244 +        {
 144.245 +            get
 144.246 +            {
 144.247 +                if (this.lineSpacing != null)
 144.248 +                {
 144.249 +                    return this.lineSpacing.Value;
 144.250 +                }
 144.251 +
 144.252 +                if (this.BasedOn != null)
 144.253 +                {
 144.254 +                    return this.BasedOn.LineSpacing;
 144.255 +                }
 144.256 +
 144.257 +                return 1;
 144.258 +            }
 144.259 +
 144.260 +            set
 144.261 +            {
 144.262 +                this.lineSpacing = value;
 144.263 +            }
 144.264 +        }
 144.265 +
 144.266 +        /// <summary>
 144.267 +        /// Gets or sets a value indicating whether PageBreakBefore.
 144.268 +        /// </summary>
 144.269 +        public bool PageBreakBefore
 144.270 +        {
 144.271 +            get
 144.272 +            {
 144.273 +                if (this.pageBreakBefore != null)
 144.274 +                {
 144.275 +                    return this.pageBreakBefore.Value;
 144.276 +                }
 144.277 +
 144.278 +                if (this.BasedOn != null)
 144.279 +                {
 144.280 +                    return this.BasedOn.PageBreakBefore;
 144.281 +                }
 144.282 +
 144.283 +                return false;
 144.284 +            }
 144.285 +
 144.286 +            set
 144.287 +            {
 144.288 +                this.pageBreakBefore = value;
 144.289 +            }
 144.290 +        }
 144.291 +
 144.292 +        /// <summary>
 144.293 +        /// Gets or sets RightIndentation.
 144.294 +        /// </summary>
 144.295 +        public double RightIndentation
 144.296 +        {
 144.297 +            get
 144.298 +            {
 144.299 +                if (this.rightIndentation != null)
 144.300 +                {
 144.301 +                    return this.rightIndentation.Value;
 144.302 +                }
 144.303 +
 144.304 +                if (this.BasedOn != null)
 144.305 +                {
 144.306 +                    return this.BasedOn.RightIndentation;
 144.307 +                }
 144.308 +
 144.309 +                return 0;
 144.310 +            }
 144.311 +
 144.312 +            set
 144.313 +            {
 144.314 +                this.rightIndentation = value;
 144.315 +            }
 144.316 +        }
 144.317 +
 144.318 +        /// <summary>
 144.319 +        /// Gets or sets SpacingAfter.
 144.320 +        /// </summary>
 144.321 +        public double SpacingAfter
 144.322 +        {
 144.323 +            get
 144.324 +            {
 144.325 +                if (this.spacingAfter != null)
 144.326 +                {
 144.327 +                    return this.spacingAfter.Value;
 144.328 +                }
 144.329 +
 144.330 +                if (this.BasedOn != null)
 144.331 +                {
 144.332 +                    return this.BasedOn.SpacingAfter;
 144.333 +                }
 144.334 +
 144.335 +                return 0;
 144.336 +            }
 144.337 +
 144.338 +            set
 144.339 +            {
 144.340 +                this.spacingAfter = value;
 144.341 +            }
 144.342 +        }
 144.343 +
 144.344 +        /// <summary>
 144.345 +        /// Gets or sets SpacingBefore.
 144.346 +        /// </summary>
 144.347 +        public double SpacingBefore
 144.348 +        {
 144.349 +            get
 144.350 +            {
 144.351 +                if (this.spacingBefore != null)
 144.352 +                {
 144.353 +                    return this.spacingBefore.Value;
 144.354 +                }
 144.355 +
 144.356 +                if (this.BasedOn != null)
 144.357 +                {
 144.358 +                    return this.BasedOn.SpacingBefore;
 144.359 +                }
 144.360 +
 144.361 +                return 0;
 144.362 +            }
 144.363 +
 144.364 +            set
 144.365 +            {
 144.366 +                this.spacingBefore = value;
 144.367 +            }
 144.368 +        }
 144.369 +
 144.370 +        /// <summary>
 144.371 +        /// Gets or sets TextColor.
 144.372 +        /// </summary>
 144.373 +        public OxyColor TextColor
 144.374 +        {
 144.375 +            get
 144.376 +            {
 144.377 +                if (this.textColor != null)
 144.378 +                {
 144.379 +                    return this.textColor;
 144.380 +                }
 144.381 +
 144.382 +                if (this.BasedOn != null)
 144.383 +                {
 144.384 +                    return this.BasedOn.TextColor;
 144.385 +                }
 144.386 +
 144.387 +                return OxyColors.Black;
 144.388 +            }
 144.389 +
 144.390 +            set
 144.391 +            {
 144.392 +                this.textColor = value;
 144.393 +            }
 144.394 +        }
 144.395 +
 144.396 +        // margin
 144.397 +        // padding
 144.398 +        // borders
 144.399 +    }
 144.400 +}
 144.401 \ No newline at end of file
   145.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Plot.cs	Sat Jun 08 16:53:22 2013 +0000
   145.3 @@ -0,0 +1,40 @@
   145.4 +// --------------------------------------------------------------------------------------------------------------------
   145.5 +// <copyright file="Plot.cs" company="OxyPlot">
   145.6 +//   The MIT License (MIT)
   145.7 +//
   145.8 +//   Copyright (c) 2012 Oystein Bjorke
   145.9 +//
  145.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  145.11 +//   copy of this software and associated documentation files (the
  145.12 +//   "Software"), to deal in the Software without restriction, including
  145.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  145.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  145.15 +//   permit persons to whom the Software is furnished to do so, subject to
  145.16 +//   the following conditions:
  145.17 +//
  145.18 +//   The above copyright notice and this permission notice shall be included
  145.19 +//   in all copies or substantial portions of the Software.
  145.20 +//
  145.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  145.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  145.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  145.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  145.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  145.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  145.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  145.28 +// </copyright>
  145.29 +// --------------------------------------------------------------------------------------------------------------------
  145.30 +namespace OxyPlot.Reporting
  145.31 +{
  145.32 +    public class Plot : Figure
  145.33 +    {
  145.34 +        public PlotModel PlotModel { get; set; }
  145.35 +        public double Width { get; set; }
  145.36 +        public double Height { get; set; }
  145.37 +
  145.38 +        public override void WriteContent(IReportWriter w)
  145.39 +        {
  145.40 +            w.WritePlot(this);
  145.41 +        }
  145.42 +    }
  145.43 +}
  145.44 \ No newline at end of file
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/PlotFigure.cs	Sat Jun 08 16:53:22 2013 +0000
   146.3 @@ -0,0 +1,64 @@
   146.4 +// --------------------------------------------------------------------------------------------------------------------
   146.5 +// <copyright file="PlotFigure.cs" company="OxyPlot">
   146.6 +//   The MIT License (MIT)
   146.7 +//
   146.8 +//   Copyright (c) 2012 Oystein Bjorke
   146.9 +//
  146.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  146.11 +//   copy of this software and associated documentation files (the
  146.12 +//   "Software"), to deal in the Software without restriction, including
  146.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  146.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  146.15 +//   permit persons to whom the Software is furnished to do so, subject to
  146.16 +//   the following conditions:
  146.17 +//
  146.18 +//   The above copyright notice and this permission notice shall be included
  146.19 +//   in all copies or substantial portions of the Software.
  146.20 +//
  146.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  146.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  146.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  146.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  146.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  146.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  146.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  146.28 +// </copyright>
  146.29 +// <summary>
  146.30 +//   Represents a plot figure.
  146.31 +// </summary>
  146.32 +// --------------------------------------------------------------------------------------------------------------------
  146.33 +namespace OxyPlot.Reporting
  146.34 +{
  146.35 +    /// <summary>
  146.36 +    /// Represents a plot figure.
  146.37 +    /// </summary>
  146.38 +    public class PlotFigure : Figure
  146.39 +    {
  146.40 +        /// <summary>
  146.41 +        /// Gets or sets Height.
  146.42 +        /// </summary>
  146.43 +        public double Height { get; set; }
  146.44 +
  146.45 +        /// <summary>
  146.46 +        /// Gets or sets PlotModel.
  146.47 +        /// </summary>
  146.48 +        public PlotModel PlotModel { get; set; }
  146.49 +
  146.50 +        /// <summary>
  146.51 +        /// Gets or sets Width.
  146.52 +        /// </summary>
  146.53 +        public double Width { get; set; }
  146.54 +
  146.55 +        /// <summary>
  146.56 +        /// The write content.
  146.57 +        /// </summary>
  146.58 +        /// <param name="w">
  146.59 +        /// The w.
  146.60 +        /// </param>
  146.61 +        public override void WriteContent(IReportWriter w)
  146.62 +        {
  146.63 +            w.WritePlot(this);
  146.64 +        }
  146.65 +
  146.66 +    }
  146.67 +}
  146.68 \ No newline at end of file
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/PropertyTable.cs	Sat Jun 08 16:53:22 2013 +0000
   147.3 @@ -0,0 +1,114 @@
   147.4 +// --------------------------------------------------------------------------------------------------------------------
   147.5 +// <copyright file="PropertyTable.cs" company="OxyPlot">
   147.6 +//   The MIT License (MIT)
   147.7 +//
   147.8 +//   Copyright (c) 2012 Oystein Bjorke
   147.9 +//
  147.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  147.11 +//   copy of this software and associated documentation files (the
  147.12 +//   "Software"), to deal in the Software without restriction, including
  147.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  147.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  147.15 +//   permit persons to whom the Software is furnished to do so, subject to
  147.16 +//   the following conditions:
  147.17 +//
  147.18 +//   The above copyright notice and this permission notice shall be included
  147.19 +//   in all copies or substantial portions of the Software.
  147.20 +//
  147.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  147.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  147.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  147.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  147.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  147.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  147.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  147.28 +// </copyright>
  147.29 +// <summary>
  147.30 +//   Represents a table of autogenerated property values.
  147.31 +// </summary>
  147.32 +// --------------------------------------------------------------------------------------------------------------------
  147.33 +namespace OxyPlot.Reporting
  147.34 +{
  147.35 +    using System;
  147.36 +    using System.Collections;
  147.37 +    using System.ComponentModel;
  147.38 +
  147.39 +    /// <summary>
  147.40 +    /// Represents a table of autogenerated property values.
  147.41 +    /// </summary>
  147.42 +    /// <remarks>
  147.43 +    /// The PropertyTable autogenerates columns or rows based on reflecting the Items type.
  147.44 +    /// Only [Browsable] properties are included.
  147.45 +    /// </remarks>
  147.46 +    public class PropertyTable : ItemsTable
  147.47 +    {
  147.48 +        /// <summary>
  147.49 +        /// Initializes a new instance of the <see cref="PropertyTable"/> class.
  147.50 +        /// </summary>
  147.51 +        /// <param name="items">
  147.52 +        /// The items.
  147.53 +        /// </param>
  147.54 +        /// <param name="itemsInRows">
  147.55 +        /// The items in rows.
  147.56 +        /// </param>
  147.57 +        public PropertyTable(IEnumerable items, bool itemsInRows)
  147.58 +            : base(itemsInRows)
  147.59 +        {
  147.60 +            this.Alignment = Alignment.Left;
  147.61 +            this.UpdateFields(items);
  147.62 +            this.Items = items;
  147.63 +        }
  147.64 +
  147.65 +        /// <summary>
  147.66 +        /// The get item type.
  147.67 +        /// </summary>
  147.68 +        /// <param name="items">
  147.69 +        /// The items.
  147.70 +        /// </param>
  147.71 +        /// <returns>
  147.72 +        /// </returns>
  147.73 +        private Type GetItemType(IEnumerable items)
  147.74 +        {
  147.75 +            Type result = null;
  147.76 +            foreach (var item in items)
  147.77 +            {
  147.78 +                Type t = item.GetType();
  147.79 +                if (result == null)
  147.80 +                {
  147.81 +                    result = t;
  147.82 +                }
  147.83 +
  147.84 +                if (t != result)
  147.85 +                {
  147.86 +                    return null;
  147.87 +                }
  147.88 +            }
  147.89 +
  147.90 +            return result;
  147.91 +        }
  147.92 +
  147.93 +        /// <summary>
  147.94 +        /// Updates the fields.
  147.95 +        /// </summary>
  147.96 +        /// <param name="items">
  147.97 +        /// The items.
  147.98 +        /// </param>
  147.99 +        private void UpdateFields(IEnumerable items)
 147.100 +        {
 147.101 +            Type type = this.GetItemType(items);
 147.102 +            if (type == null)
 147.103 +            {
 147.104 +                return;
 147.105 +            }
 147.106 +
 147.107 +            this.Columns.Clear();
 147.108 +
 147.109 +            foreach (var pi in type.GetProperties())
 147.110 +            {
 147.111 +                // TODO: support Browsable and Displayname attributes
 147.112 +                var header = pi.Name;
 147.113 +                this.Fields.Add(new ItemsTableField(header, pi.Name, null, Alignment.Left));
 147.114 +            }
 147.115 +        }
 147.116 +    }
 147.117 +}
 147.118 \ No newline at end of file
   148.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Report.cs	Sat Jun 08 16:53:22 2013 +0000
   148.3 @@ -0,0 +1,87 @@
   148.4 +// --------------------------------------------------------------------------------------------------------------------
   148.5 +// <copyright file="Report.cs" company="OxyPlot">
   148.6 +//   The MIT License (MIT)
   148.7 +//
   148.8 +//   Copyright (c) 2012 Oystein Bjorke
   148.9 +//
  148.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  148.11 +//   copy of this software and associated documentation files (the
  148.12 +//   "Software"), to deal in the Software without restriction, including
  148.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  148.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  148.15 +//   permit persons to whom the Software is furnished to do so, subject to
  148.16 +//   the following conditions:
  148.17 +//
  148.18 +//   The above copyright notice and this permission notice shall be included
  148.19 +//   in all copies or substantial portions of the Software.
  148.20 +//
  148.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  148.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  148.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  148.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  148.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  148.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  148.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  148.28 +// </copyright>
  148.29 +// <summary>
  148.30 +//   Represents a report.
  148.31 +// </summary>
  148.32 +// --------------------------------------------------------------------------------------------------------------------
  148.33 +namespace OxyPlot.Reporting
  148.34 +{
  148.35 +    using System.Globalization;
  148.36 +
  148.37 +    /// <summary>
  148.38 +    /// Represents a report.
  148.39 +    /// </summary>
  148.40 +    public class Report : ReportItem
  148.41 +    {
  148.42 +        /// <summary>
  148.43 +        /// Gets the actual culture.
  148.44 +        /// </summary>
  148.45 +        public CultureInfo ActualCulture
  148.46 +        {
  148.47 +            get
  148.48 +            {
  148.49 +                return this.Culture ?? CultureInfo.CurrentCulture;
  148.50 +            }
  148.51 +        }
  148.52 +
  148.53 +        /// <summary>
  148.54 +        /// Gets or sets Author.
  148.55 +        /// </summary>
  148.56 +        public string Author { get; set; }
  148.57 +
  148.58 +        /// <summary>
  148.59 +        /// Gets or sets the culture.
  148.60 +        /// </summary>
  148.61 +        /// <value>
  148.62 +        /// The culture.
  148.63 +        /// </value>
  148.64 +        public CultureInfo Culture { get; set; }
  148.65 +
  148.66 +        /// <summary>
  148.67 +        /// Gets or sets SubTitle.
  148.68 +        /// </summary>
  148.69 +        public string SubTitle { get; set; }
  148.70 +
  148.71 +        /// <summary>
  148.72 +        /// Gets or sets Title.
  148.73 +        /// </summary>
  148.74 +        public string Title { get; set; }
  148.75 +
  148.76 +        /// <summary>
  148.77 +        /// The write.
  148.78 +        /// </summary>
  148.79 +        /// <param name="w">
  148.80 +        /// The w.
  148.81 +        /// </param>
  148.82 +        public override void Write(IReportWriter w)
  148.83 +        {
  148.84 +            this.UpdateParent(this);
  148.85 +            this.UpdateFigureNumbers();
  148.86 +            base.Write(w);
  148.87 +        }
  148.88 +
  148.89 +    }
  148.90 +}
  148.91 \ No newline at end of file
   149.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   149.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ReportItem.cs	Sat Jun 08 16:53:22 2013 +0000
   149.3 @@ -0,0 +1,311 @@
   149.4 +// --------------------------------------------------------------------------------------------------------------------
   149.5 +// <copyright file="ReportItem.cs" company="OxyPlot">
   149.6 +//   The MIT License (MIT)
   149.7 +//
   149.8 +//   Copyright (c) 2012 Oystein Bjorke
   149.9 +//
  149.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  149.11 +//   copy of this software and associated documentation files (the
  149.12 +//   "Software"), to deal in the Software without restriction, including
  149.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  149.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  149.15 +//   permit persons to whom the Software is furnished to do so, subject to
  149.16 +//   the following conditions:
  149.17 +//
  149.18 +//   The above copyright notice and this permission notice shall be included
  149.19 +//   in all copies or substantial portions of the Software.
  149.20 +//
  149.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  149.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  149.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  149.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  149.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  149.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  149.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  149.28 +// </copyright>
  149.29 +// <summary>
  149.30 +//   Represents a report item (abstract base class).
  149.31 +// </summary>
  149.32 +// --------------------------------------------------------------------------------------------------------------------
  149.33 +namespace OxyPlot.Reporting
  149.34 +{
  149.35 +    using System.Collections;
  149.36 +    using System.Collections.Generic;
  149.37 +    using System.Collections.ObjectModel;
  149.38 +
  149.39 +    /// <summary>
  149.40 +    /// Represents a report item (abstract base class).
  149.41 +    /// </summary>
  149.42 +    public abstract class ReportItem
  149.43 +    {
  149.44 +        /// <summary>
  149.45 +        /// Initializes a new instance of the <see cref = "ReportItem" /> class.
  149.46 +        /// </summary>
  149.47 +        protected ReportItem()
  149.48 +        {
  149.49 +            this.Children = new Collection<ReportItem>();
  149.50 +        }
  149.51 +
  149.52 +        /// <summary>
  149.53 +        /// Gets the children.
  149.54 +        /// </summary>
  149.55 +        public Collection<ReportItem> Children { get; private set; }
  149.56 +
  149.57 +        /// <summary>
  149.58 +        /// Gets the report.
  149.59 +        /// </summary>
  149.60 +        public Report Report { get; internal set; }
  149.61 +
  149.62 +        /// <summary>
  149.63 +        /// Adds a report item to the report.
  149.64 +        /// </summary>
  149.65 +        /// <param name="child">
  149.66 +        /// The child.
  149.67 +        /// </param>
  149.68 +        public void Add(ReportItem child)
  149.69 +        {
  149.70 +            this.Children.Add(child);
  149.71 +        }
  149.72 +
  149.73 +        /// <summary>
  149.74 +        /// Adds a drawing to the report.
  149.75 +        /// </summary>
  149.76 +        /// <param name="content">
  149.77 +        /// The content.
  149.78 +        /// </param>
  149.79 +        /// <param name="text">
  149.80 +        /// The text.
  149.81 +        /// </param>
  149.82 +        public void AddDrawing(string content, string text)
  149.83 +        {
  149.84 +            this.Add(new DrawingFigure { Content = content, FigureText = text });
  149.85 +        }
  149.86 +
  149.87 +        /// <summary>
  149.88 +        /// Adds a plot to the report.
  149.89 +        /// </summary>
  149.90 +        /// <param name="plot">The plot model.</param>
  149.91 +        /// <param name="text">The text.</param>
  149.92 +        /// <param name="width">The width.</param>
  149.93 +        /// <param name="height">The height.</param>
  149.94 +        public void AddPlot(PlotModel plot, string text, double width, double height)
  149.95 +        {
  149.96 +            this.Add(new PlotFigure { PlotModel = plot, Width = width, Height = height, FigureText = text });
  149.97 +        }
  149.98 +
  149.99 +        /// <summary>
 149.100 +        /// Adds an equation to the report.
 149.101 +        /// </summary>
 149.102 +        /// <param name="equation">
 149.103 +        /// The equation.
 149.104 +        /// </param>
 149.105 +        /// <param name="caption">
 149.106 +        /// The caption.
 149.107 +        /// </param>
 149.108 +        public void AddEquation(string equation, string caption = null)
 149.109 +        {
 149.110 +            this.Add(new Equation { Content = equation, Caption = caption });
 149.111 +        }
 149.112 +
 149.113 +        /// <summary>
 149.114 +        /// Adds a header to the report.
 149.115 +        /// </summary>
 149.116 +        /// <param name="level">
 149.117 +        /// The level.
 149.118 +        /// </param>
 149.119 +        /// <param name="header">
 149.120 +        /// The header.
 149.121 +        /// </param>
 149.122 +        public void AddHeader(int level, string header)
 149.123 +        {
 149.124 +            this.Add(new Header { Level = level, Text = header });
 149.125 +        }
 149.126 +
 149.127 +        /// <summary>
 149.128 +        /// Adds an image to the report.
 149.129 +        /// </summary>
 149.130 +        /// <param name="src">
 149.131 +        /// The src.
 149.132 +        /// </param>
 149.133 +        /// <param name="text">
 149.134 +        /// The text.
 149.135 +        /// </param>
 149.136 +        public void AddImage(string src, string text)
 149.137 +        {
 149.138 +            this.Add(new Image { Source = src, FigureText = text });
 149.139 +        }
 149.140 +
 149.141 +        /// <summary>
 149.142 +        /// Adds an items table to the report.
 149.143 +        /// </summary>
 149.144 +        /// <param name="title">
 149.145 +        /// The title.
 149.146 +        /// </param>
 149.147 +        /// <param name="items">
 149.148 +        /// The items.
 149.149 +        /// </param>
 149.150 +        /// <param name="fields">
 149.151 +        /// The fields.
 149.152 +        /// </param>
 149.153 +        public void AddItemsTable(string title, IEnumerable items, IList<ItemsTableField> fields)
 149.154 +        {
 149.155 +            this.Add(new ItemsTable { Caption = title, Items = items, Fields = fields });
 149.156 +        }
 149.157 +
 149.158 +        /// <summary>
 149.159 +        /// Adds a paragraph to the report.
 149.160 +        /// </summary>
 149.161 +        /// <param name="content">
 149.162 +        /// The content.
 149.163 +        /// </param>
 149.164 +        public void AddParagraph(string content)
 149.165 +        {
 149.166 +            this.Add(new Paragraph { Text = content });
 149.167 +        }
 149.168 +
 149.169 +        /// <summary>
 149.170 +        /// Adds a property table to the report.
 149.171 +        /// </summary>
 149.172 +        /// <param name="title">
 149.173 +        /// The title.
 149.174 +        /// </param>
 149.175 +        /// <param name="obj">
 149.176 +        /// The object.
 149.177 +        /// </param>
 149.178 +        /// <returns>
 149.179 +        /// A PropertyTable.
 149.180 +        /// </returns>
 149.181 +        public PropertyTable AddPropertyTable(string title, object obj)
 149.182 +        {
 149.183 +            var items = obj as IEnumerable;
 149.184 +            if (items == null)
 149.185 +            {
 149.186 +                items = new[] { obj };
 149.187 +            }
 149.188 +
 149.189 +            var pt = new PropertyTable(items, false) { Caption = title };
 149.190 +            this.Add(pt);
 149.191 +            return pt;
 149.192 +        }
 149.193 +
 149.194 +        /// <summary>
 149.195 +        /// The add table of contents.
 149.196 +        /// </summary>
 149.197 +        /// <param name="b">
 149.198 +        /// The b.
 149.199 +        /// </param>
 149.200 +        public void AddTableOfContents(ReportItem b)
 149.201 +        {
 149.202 +            this.Add(new TableOfContents(b));
 149.203 +        }
 149.204 +
 149.205 +        /// <summary>
 149.206 +        /// The update.
 149.207 +        /// </summary>
 149.208 +        public virtual void Update()
 149.209 +        {
 149.210 +        }
 149.211 +
 149.212 +        /// <summary>
 149.213 +        /// The write.
 149.214 +        /// </summary>
 149.215 +        /// <param name="w">
 149.216 +        /// The w.
 149.217 +        /// </param>
 149.218 +        public virtual void Write(IReportWriter w)
 149.219 +        {
 149.220 +            this.Update();
 149.221 +            this.WriteContent(w);
 149.222 +            foreach (var child in this.Children)
 149.223 +            {
 149.224 +                child.Write(w);
 149.225 +            }
 149.226 +        }
 149.227 +
 149.228 +        /// <summary>
 149.229 +        /// Writes the content of the item.
 149.230 +        /// </summary>
 149.231 +        /// <param name="w">
 149.232 +        /// The writer.
 149.233 +        /// </param>
 149.234 +        public virtual void WriteContent(IReportWriter w)
 149.235 +        {
 149.236 +        }
 149.237 +
 149.238 +        /// <summary>
 149.239 +        /// The update figure numbers.
 149.240 +        /// </summary>
 149.241 +        protected void UpdateFigureNumbers()
 149.242 +        {
 149.243 +            var fc = new FigureCounter();
 149.244 +            this.UpdateFigureNumbers(fc);
 149.245 +        }
 149.246 +
 149.247 +        /// <summary>
 149.248 +        /// Updates the Report property.
 149.249 +        /// </summary>
 149.250 +        /// <param name="report">
 149.251 +        /// The report.
 149.252 +        /// </param>
 149.253 +        protected void UpdateParent(Report report)
 149.254 +        {
 149.255 +            this.Report = report;
 149.256 +            foreach (var child in this.Children)
 149.257 +            {
 149.258 +                child.UpdateParent(report);
 149.259 +            }
 149.260 +        }
 149.261 +
 149.262 +        /// <summary>
 149.263 +        /// The update figure numbers.
 149.264 +        /// </summary>
 149.265 +        /// <param name="fc">
 149.266 +        /// The fc.
 149.267 +        /// </param>
 149.268 +        private void UpdateFigureNumbers(FigureCounter fc)
 149.269 +        {
 149.270 +            var table = this as Table;
 149.271 +            if (table != null)
 149.272 +            {
 149.273 +                table.TableNumber = fc.TableNumber++;
 149.274 +            }
 149.275 +
 149.276 +            var figure = this as Figure;
 149.277 +            if (figure != null)
 149.278 +            {
 149.279 +                figure.FigureNumber = fc.FigureNumber++;
 149.280 +            }
 149.281 +
 149.282 +            foreach (var child in this.Children)
 149.283 +            {
 149.284 +                child.UpdateFigureNumbers(fc);
 149.285 +            }
 149.286 +        }
 149.287 +
 149.288 +        /// <summary>
 149.289 +        /// The figure counter.
 149.290 +        /// </summary>
 149.291 +        private class FigureCounter
 149.292 +        {
 149.293 +            /// <summary>
 149.294 +            /// Initializes a new instance of the <see cref = "FigureCounter" /> class.
 149.295 +            /// </summary>
 149.296 +            public FigureCounter()
 149.297 +            {
 149.298 +                this.FigureNumber = 1;
 149.299 +                this.TableNumber = 1;
 149.300 +            }
 149.301 +
 149.302 +            /// <summary>
 149.303 +            /// Gets or sets FigureNumber.
 149.304 +            /// </summary>
 149.305 +            public int FigureNumber { get; set; }
 149.306 +
 149.307 +            /// <summary>
 149.308 +            /// Gets or sets TableNumber.
 149.309 +            /// </summary>
 149.310 +            public int TableNumber { get; set; }
 149.311 +
 149.312 +        }
 149.313 +    }
 149.314 +}
 149.315 \ No newline at end of file
   150.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ReportSection.cs	Sat Jun 08 16:53:22 2013 +0000
   150.3 @@ -0,0 +1,38 @@
   150.4 +// --------------------------------------------------------------------------------------------------------------------
   150.5 +// <copyright file="ReportSection.cs" company="OxyPlot">
   150.6 +//   The MIT License (MIT)
   150.7 +//
   150.8 +//   Copyright (c) 2012 Oystein Bjorke
   150.9 +//
  150.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  150.11 +//   copy of this software and associated documentation files (the
  150.12 +//   "Software"), to deal in the Software without restriction, including
  150.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  150.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  150.15 +//   permit persons to whom the Software is furnished to do so, subject to
  150.16 +//   the following conditions:
  150.17 +//
  150.18 +//   The above copyright notice and this permission notice shall be included
  150.19 +//   in all copies or substantial portions of the Software.
  150.20 +//
  150.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  150.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  150.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  150.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  150.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  150.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  150.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  150.28 +// </copyright>
  150.29 +// <summary>
  150.30 +//   Represents a report section.
  150.31 +// </summary>
  150.32 +// --------------------------------------------------------------------------------------------------------------------
  150.33 +namespace OxyPlot.Reporting
  150.34 +{
  150.35 +    /// <summary>
  150.36 +    /// Represents a report section.
  150.37 +    /// </summary>
  150.38 +    public class ReportSection : ReportItem
  150.39 +    {
  150.40 +    }
  150.41 +}
  150.42 \ No newline at end of file
   151.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/ReportStyle.cs	Sat Jun 08 16:53:22 2013 +0000
   151.3 @@ -0,0 +1,156 @@
   151.4 +// --------------------------------------------------------------------------------------------------------------------
   151.5 +// <copyright file="ReportStyle.cs" company="OxyPlot">
   151.6 +//   The MIT License (MIT)
   151.7 +//
   151.8 +//   Copyright (c) 2012 Oystein Bjorke
   151.9 +//
  151.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  151.11 +//   copy of this software and associated documentation files (the
  151.12 +//   "Software"), to deal in the Software without restriction, including
  151.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  151.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  151.15 +//   permit persons to whom the Software is furnished to do so, subject to
  151.16 +//   the following conditions:
  151.17 +//
  151.18 +//   The above copyright notice and this permission notice shall be included
  151.19 +//   in all copies or substantial portions of the Software.
  151.20 +//
  151.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  151.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  151.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  151.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  151.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  151.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  151.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  151.28 +// </copyright>
  151.29 +// <summary>
  151.30 +//   The report style.
  151.31 +// </summary>
  151.32 +// --------------------------------------------------------------------------------------------------------------------
  151.33 +namespace OxyPlot.Reporting
  151.34 +{
  151.35 +    /// <summary>
  151.36 +    /// The report style.
  151.37 +    /// </summary>
  151.38 +    public class ReportStyle
  151.39 +    {
  151.40 +        /// <summary>
  151.41 +        /// Initializes a new instance of the <see cref="ReportStyle"/> class.
  151.42 +        /// </summary>
  151.43 +        /// <param name="titleFontFamily">
  151.44 +        /// The title font family.
  151.45 +        /// </param>
  151.46 +        /// <param name="bodyTextFontFamily">
  151.47 +        /// The body text font family.
  151.48 +        /// </param>
  151.49 +        /// <param name="tableTextFontFamily">
  151.50 +        /// The table text font family.
  151.51 +        /// </param>
  151.52 +        public ReportStyle(
  151.53 +            string titleFontFamily = "Arial",
  151.54 +            string bodyTextFontFamily = "Verdana",
  151.55 +            string tableTextFontFamily = "Courier New")
  151.56 +        {
  151.57 +            this.DefaultStyle = new ParagraphStyle { FontFamily = bodyTextFontFamily, FontSize = 11, SpacingAfter = 10 };
  151.58 +
  151.59 +            this.HeaderStyles = new ParagraphStyle[5];
  151.60 +            this.HeaderStyles[0] = new ParagraphStyle
  151.61 +                {
  151.62 +                   BasedOn = this.DefaultStyle, FontFamily = titleFontFamily, SpacingBefore = 12, SpacingAfter = 3
  151.63 +                };
  151.64 +            for (int i = 1; i < this.HeaderStyles.Length; i++)
  151.65 +            {
  151.66 +                this.HeaderStyles[i] = new ParagraphStyle { BasedOn = this.HeaderStyles[i - 1] };
  151.67 +            }
  151.68 +
  151.69 +            for (int i = 0; i < this.HeaderStyles.Length; i++)
  151.70 +            {
  151.71 +                this.HeaderStyles[i].Bold = true;
  151.72 +            }
  151.73 +
  151.74 +            this.HeaderStyles[0].FontSize = 16;
  151.75 +            this.HeaderStyles[1].FontSize = 14;
  151.76 +            this.HeaderStyles[2].FontSize = 13;
  151.77 +            this.HeaderStyles[3].FontSize = 12;
  151.78 +            this.HeaderStyles[4].FontSize = 11;
  151.79 +
  151.80 +            this.HeaderStyles[0].PageBreakBefore = true;
  151.81 +            this.HeaderStyles[1].PageBreakBefore = false;
  151.82 +
  151.83 +            this.BodyTextStyle = new ParagraphStyle { BasedOn = this.DefaultStyle };
  151.84 +            this.FigureTextStyle = new ParagraphStyle { BasedOn = this.DefaultStyle, Italic = true };
  151.85 +
  151.86 +            this.TableTextStyle = new ParagraphStyle
  151.87 +                {
  151.88 +                    BasedOn = this.DefaultStyle,
  151.89 +                    FontFamily = tableTextFontFamily,
  151.90 +                    SpacingAfter = 0,
  151.91 +                    LeftIndentation = 3,
  151.92 +                    RightIndentation = 3
  151.93 +                };
  151.94 +            this.TableHeaderStyle = new ParagraphStyle { BasedOn = this.TableTextStyle, Bold = true };
  151.95 +            this.TableCaptionStyle = new ParagraphStyle
  151.96 +                {
  151.97 +                   BasedOn = this.DefaultStyle, Italic = true, SpacingBefore = 10, SpacingAfter = 3
  151.98 +                };
  151.99 +
 151.100 +            this.Margins = new OxyThickness(25);
 151.101 +
 151.102 +            this.FigureTextFormatString = "Figure {0}. {1}";
 151.103 +            this.TableCaptionFormatString = "Table {0}. {1}";
 151.104 +        }
 151.105 +
 151.106 +        /// <summary>
 151.107 +        /// Gets or sets BodyTextStyle.
 151.108 +        /// </summary>
 151.109 +        public ParagraphStyle BodyTextStyle { get; set; }
 151.110 +
 151.111 +        /// <summary>
 151.112 +        /// Gets or sets DefaultStyle.
 151.113 +        /// </summary>
 151.114 +        public ParagraphStyle DefaultStyle { get; set; }
 151.115 +
 151.116 +        /// <summary>
 151.117 +        /// Gets or sets FigureTextFormatString.
 151.118 +        /// </summary>
 151.119 +        public string FigureTextFormatString { get; set; }
 151.120 +
 151.121 +        /// <summary>
 151.122 +        /// Gets or sets FigureTextStyle.
 151.123 +        /// </summary>
 151.124 +        public ParagraphStyle FigureTextStyle { get; set; }
 151.125 +
 151.126 +        /// <summary>
 151.127 +        /// Gets or sets HeaderStyles.
 151.128 +        /// </summary>
 151.129 +        public ParagraphStyle[] HeaderStyles { get; set; }
 151.130 +
 151.131 +        /// <summary>
 151.132 +        /// Gets or sets the page margins (mm).
 151.133 +        /// </summary>
 151.134 +        public OxyThickness Margins { get; set; }
 151.135 +
 151.136 +        // todo: should the FormatStrings be in the Report class?
 151.137 +
 151.138 +        /// <summary>
 151.139 +        /// Gets or sets TableCaptionFormatString.
 151.140 +        /// </summary>
 151.141 +        public string TableCaptionFormatString { get; set; }
 151.142 +
 151.143 +        /// <summary>
 151.144 +        /// Gets or sets TableCaptionStyle.
 151.145 +        /// </summary>
 151.146 +        public ParagraphStyle TableCaptionStyle { get; set; }
 151.147 +
 151.148 +        /// <summary>
 151.149 +        /// Gets or sets TableHeaderStyle.
 151.150 +        /// </summary>
 151.151 +        public ParagraphStyle TableHeaderStyle { get; set; }
 151.152 +
 151.153 +        /// <summary>
 151.154 +        /// Gets or sets TableTextStyle.
 151.155 +        /// </summary>
 151.156 +        public ParagraphStyle TableTextStyle { get; set; }
 151.157 +
 151.158 +    }
 151.159 +}
 151.160 \ No newline at end of file
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/Table.cs	Sat Jun 08 16:53:22 2013 +0000
   152.3 @@ -0,0 +1,252 @@
   152.4 +// --------------------------------------------------------------------------------------------------------------------
   152.5 +// <copyright file="Table.cs" company="OxyPlot">
   152.6 +//   The MIT License (MIT)
   152.7 +//
   152.8 +//   Copyright (c) 2012 Oystein Bjorke
   152.9 +//
  152.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  152.11 +//   copy of this software and associated documentation files (the
  152.12 +//   "Software"), to deal in the Software without restriction, including
  152.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  152.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  152.15 +//   permit persons to whom the Software is furnished to do so, subject to
  152.16 +//   the following conditions:
  152.17 +//
  152.18 +//   The above copyright notice and this permission notice shall be included
  152.19 +//   in all copies or substantial portions of the Software.
  152.20 +//
  152.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  152.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  152.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  152.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  152.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  152.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  152.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  152.28 +// </copyright>
  152.29 +// <summary>
  152.30 +//   Represents a table column definition.
  152.31 +// </summary>
  152.32 +// --------------------------------------------------------------------------------------------------------------------
  152.33 +namespace OxyPlot.Reporting
  152.34 +{
  152.35 +    using System;
  152.36 +    using System.Collections.Generic;
  152.37 +
  152.38 +    /// <summary>
  152.39 +    /// Represents a table column definition.
  152.40 +    /// </summary>
  152.41 +    public class TableColumn
  152.42 +    {
  152.43 +        /// <summary>
  152.44 +        /// Initializes a new instance of the <see cref = "TableColumn" /> class.
  152.45 +        /// </summary>
  152.46 +        public TableColumn()
  152.47 +        {
  152.48 +            this.Width = double.NaN;
  152.49 +            this.Alignment = Alignment.Center;
  152.50 +        }
  152.51 +
  152.52 +        /// <summary>
  152.53 +        /// Gets or sets the actual width (mm).
  152.54 +        /// </summary>
  152.55 +        /// <value>The actual width.</value>
  152.56 +        public double ActualWidth { get; internal set; }
  152.57 +
  152.58 +        /// <summary>
  152.59 +        /// Gets or sets Alignment.
  152.60 +        /// </summary>
  152.61 +        public Alignment Alignment { get; set; }
  152.62 +
  152.63 +        /// <summary>
  152.64 +        /// Gets or sets a value indicating whether IsHeader.
  152.65 +        /// </summary>
  152.66 +        public bool IsHeader { get; set; }
  152.67 +
  152.68 +        /// <summary>
  152.69 +        /// Gets or sets the width.
  152.70 +        /// NaN: auto width.
  152.71 +        /// Negative numbers: weights
  152.72 +        /// </summary>
  152.73 +        /// <value>The width.</value>
  152.74 +        public double Width { get; set; }
  152.75 +
  152.76 +    }
  152.77 +
  152.78 +    /// <summary>
  152.79 +    /// Represents a table row definition.
  152.80 +    /// </summary>
  152.81 +    public class TableRow
  152.82 +    {
  152.83 +        /// <summary>
  152.84 +        /// Initializes a new instance of the <see cref = "TableRow" /> class.
  152.85 +        /// </summary>
  152.86 +        public TableRow()
  152.87 +        {
  152.88 +            this.Cells = new List<TableCell>();
  152.89 +        }
  152.90 +
  152.91 +        /// <summary>
  152.92 +        /// Gets Cells.
  152.93 +        /// </summary>
  152.94 +        public IList<TableCell> Cells { get; private set; }
  152.95 +
  152.96 +        /// <summary>
  152.97 +        /// Gets or sets a value indicating whether IsHeader.
  152.98 +        /// </summary>
  152.99 +        public bool IsHeader { get; set; }
 152.100 +
 152.101 +    }
 152.102 +
 152.103 +    /// <summary>
 152.104 +    /// Represents a table cell.
 152.105 +    /// </summary>
 152.106 +    public class TableCell
 152.107 +    {
 152.108 +        // public Alignment Alignment { get; set; }
 152.109 +        // public int RowSpan { get; set; }
 152.110 +        // public int ColumnSpan { get; set; }
 152.111 +        /// <summary>
 152.112 +        /// Gets or sets Content.
 152.113 +        /// </summary>
 152.114 +        public string Content { get; set; }
 152.115 +
 152.116 +    }
 152.117 +
 152.118 +    /// <summary>
 152.119 +    /// Represents a table.
 152.120 +    /// </summary>
 152.121 +    public class Table : ReportItem
 152.122 +    {
 152.123 +        /// <summary>
 152.124 +        /// Initializes a new instance of the <see cref = "Table" /> class.
 152.125 +        /// </summary>
 152.126 +        public Table()
 152.127 +        {
 152.128 +            this.Rows = new List<TableRow>();
 152.129 +            this.Columns = new List<TableColumn>();
 152.130 +            this.Width = double.NaN;
 152.131 +        }
 152.132 +
 152.133 +        /// <summary>
 152.134 +        /// Gets or sets the actual width of the table (mm).
 152.135 +        /// </summary>
 152.136 +        /// <value>The actual width.</value>
 152.137 +        public double ActualWidth { get; private set; }
 152.138 +
 152.139 +        /// <summary>
 152.140 +        /// Gets or sets Caption.
 152.141 +        /// </summary>
 152.142 +        public string Caption { get; set; }
 152.143 +
 152.144 +        /// <summary>
 152.145 +        /// Gets Columns.
 152.146 +        /// </summary>
 152.147 +        public IList<TableColumn> Columns { get; private set; }
 152.148 +
 152.149 +        /// <summary>
 152.150 +        /// Gets Rows.
 152.151 +        /// </summary>
 152.152 +        public IList<TableRow> Rows { get; private set; }
 152.153 +
 152.154 +        /// <summary>
 152.155 +        /// Gets or sets TableNumber.
 152.156 +        /// </summary>
 152.157 +        public int TableNumber { get; set; }
 152.158 +
 152.159 +        /// <summary>
 152.160 +        /// Gets or sets the width of the table (mm).
 152.161 +        /// NaN: auto width.
 152.162 +        /// 0..-1: fraction of page width.
 152.163 +        /// </summary>
 152.164 +        public double Width { get; set; }
 152.165 +
 152.166 +        /// <summary>
 152.167 +        /// The get full caption.
 152.168 +        /// </summary>
 152.169 +        /// <param name="style">
 152.170 +        /// The style.
 152.171 +        /// </param>
 152.172 +        /// <returns>
 152.173 +        /// The get full caption.
 152.174 +        /// </returns>
 152.175 +        public string GetFullCaption(ReportStyle style)
 152.176 +        {
 152.177 +            return string.Format(style.TableCaptionFormatString, this.TableNumber, this.Caption);
 152.178 +        }
 152.179 +
 152.180 +        /// <summary>
 152.181 +        /// The update.
 152.182 +        /// </summary>
 152.183 +        public override void Update()
 152.184 +        {
 152.185 +            base.Update();
 152.186 +            this.UpdateWidths();
 152.187 +        }
 152.188 +
 152.189 +        /// <summary>
 152.190 +        /// The write content.
 152.191 +        /// </summary>
 152.192 +        /// <param name="w">
 152.193 +        /// The w.
 152.194 +        /// </param>
 152.195 +        public override void WriteContent(IReportWriter w)
 152.196 +        {
 152.197 +            // todo
 152.198 +        }
 152.199 +
 152.200 +        /// <summary>
 152.201 +        /// The update widths.
 152.202 +        /// </summary>
 152.203 +        private void UpdateWidths()
 152.204 +        {
 152.205 +            if (this.Width < 0)
 152.206 +            {
 152.207 +                this.ActualWidth = 150 * (-this.Width);
 152.208 +            }
 152.209 +            else
 152.210 +            {
 152.211 +                this.ActualWidth = this.Width;
 152.212 +            }
 152.213 +
 152.214 +            // update actual widths of all columns
 152.215 +            double totalWeight = 0;
 152.216 +            double totalWidth = 0;
 152.217 +            foreach (var c in this.Columns)
 152.218 +            {
 152.219 +                if (double.IsNaN(c.Width))
 152.220 +                {
 152.221 +                    // todo: find auto width
 152.222 +                    c.ActualWidth = 40;
 152.223 +                    totalWidth += c.ActualWidth;
 152.224 +                }
 152.225 +
 152.226 +                if (c.Width < 0)
 152.227 +                {
 152.228 +                    totalWeight += -c.Width;
 152.229 +                }
 152.230 +
 152.231 +                if (c.Width >= 0)
 152.232 +                {
 152.233 +                    totalWidth += c.Width;
 152.234 +                    c.ActualWidth = c.Width;
 152.235 +                }
 152.236 +            }
 152.237 +
 152.238 +            if (double.IsNaN(this.ActualWidth))
 152.239 +            {
 152.240 +                this.ActualWidth = Math.Max(150, totalWidth + 100);
 152.241 +            }
 152.242 +
 152.243 +            double w = this.ActualWidth - totalWidth;
 152.244 +            foreach (var c in this.Columns)
 152.245 +            {
 152.246 +                if (c.Width < 0 && totalWeight != 0)
 152.247 +                {
 152.248 +                    double weight = -c.Width;
 152.249 +                    c.ActualWidth = w * (weight / totalWeight);
 152.250 +                }
 152.251 +            }
 152.252 +        }
 152.253 +
 152.254 +    }
 152.255 +}
 152.256 \ No newline at end of file
   153.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/TableColumn.cs	Sat Jun 08 16:53:22 2013 +0000
   153.3 @@ -0,0 +1,63 @@
   153.4 +// --------------------------------------------------------------------------------------------------------------------
   153.5 +// <copyright file="TableColumn.cs" company="OxyPlot">
   153.6 +//   The MIT License (MIT)
   153.7 +//
   153.8 +//   Copyright (c) 2012 Oystein Bjorke
   153.9 +//
  153.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  153.11 +//   copy of this software and associated documentation files (the
  153.12 +//   "Software"), to deal in the Software without restriction, including
  153.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  153.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  153.15 +//   permit persons to whom the Software is furnished to do so, subject to
  153.16 +//   the following conditions:
  153.17 +//
  153.18 +//   The above copyright notice and this permission notice shall be included
  153.19 +//   in all copies or substantial portions of the Software.
  153.20 +//
  153.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  153.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  153.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  153.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  153.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  153.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  153.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  153.28 +// </copyright>
  153.29 +// --------------------------------------------------------------------------------------------------------------------
  153.30 +using System;
  153.31 +using System.Collections.ObjectModel;
  153.32 +using System.Globalization;
  153.33 +
  153.34 +namespace OxyPlot.Reporting
  153.35 +{
  153.36 +    public enum Alignment { Left, Right, Center };
  153.37 +
  153.38 +    public class TableColumn
  153.39 +    {
  153.40 +        public Alignment Alignment { get; set; }
  153.41 +        public string Header { get; set; }
  153.42 +        public string StringFormat { get; set; }
  153.43 +        public string Path { get; set; }
  153.44 +        public double Width { get; set; }
  153.45 +        // public Collection<TableColumn> SubColumns { get; set; }
  153.46 +
  153.47 +        public TableColumn(string header, string path, string stringFormat=null, Alignment alignment=Alignment.Center)
  153.48 +        {
  153.49 +            Header = header;
  153.50 +            Path = path;
  153.51 +            StringFormat = stringFormat;
  153.52 +            Alignment = alignment;
  153.53 +            // SubColumns = new Collection<TableColumn>();
  153.54 +        }
  153.55 +
  153.56 +        public string GetText(object item)
  153.57 +        {
  153.58 +            var pi = item.GetType().GetProperty(Path);
  153.59 +            object o = pi.GetValue(item, null);
  153.60 +            var of = o as IFormattable;
  153.61 +            if (of != null)
  153.62 +                return of.ToString(StringFormat, CultureInfo.InvariantCulture);
  153.63 +            return o!=null ? o.ToString():null;
  153.64 +        }
  153.65 +    }
  153.66 +}
  153.67 \ No newline at end of file
   154.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.2 +++ b/External/OxyPlot/OxyPlot/Reporting/Report/TableOfContents.cs	Sat Jun 08 16:53:22 2013 +0000
   154.3 @@ -0,0 +1,115 @@
   154.4 +// --------------------------------------------------------------------------------------------------------------------
   154.5 +// <copyright file="TableOfContents.cs" company="OxyPlot">
   154.6 +//   The MIT License (MIT)
   154.7 +//
   154.8 +//   Copyright (c) 2012 Oystein Bjorke
   154.9 +//
  154.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  154.11 +//   copy of this software and associated documentation files (the
  154.12 +//   "Software"), to deal in the Software without restriction, including
  154.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  154.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  154.15 +//   permit persons to whom the Software is furnished to do so, subject to
  154.16 +//   the following conditions:
  154.17 +//
  154.18 +//   The above copyright notice and this permission notice shall be included
  154.19 +//   in all copies or substantial portions of the Software.
  154.20 +//
  154.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  154.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  154.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  154.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  154.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  154.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  154.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  154.28 +// </copyright>
  154.29 +// <summary>
  154.30 +//   Represents a table of contents.
  154.31 +// </summary>
  154.32 +// --------------------------------------------------------------------------------------------------------------------
  154.33 +namespace OxyPlot.Reporting
  154.34 +{
  154.35 +    using System.Collections.Generic;
  154.36 +
  154.37 +    /// <summary>
  154.38 +    /// Represents a table of contents.
  154.39 +    /// </summary>
  154.40 +    public class TableOfContents : ItemsTable
  154.41 +    {
  154.42 +        /// <summary>
  154.43 +        /// Initializes a new instance of the <see cref="TableOfContents"/> class.
  154.44 +        /// </summary>
  154.45 +        /// <param name="b">
  154.46 +        /// The b.
  154.47 +        /// </param>
  154.48 +        public TableOfContents(ReportItem b)
  154.49 +        {
  154.50 +            this.Base = b;
  154.51 +            this.Contents = new List<ContentItem>();
  154.52 +            this.Fields.Add(new ItemsTableField(null, "Chapter"));
  154.53 +            this.Fields.Add(new ItemsTableField(null, "Title"));
  154.54 +            this.Items = this.Contents;
  154.55 +        }
  154.56 +
  154.57 +        /// <summary>
  154.58 +        /// Gets or sets Base.
  154.59 +        /// </summary>
  154.60 +        public ReportItem Base { get; set; }
  154.61 +
  154.62 +        /// <summary>
  154.63 +        /// Gets or sets Contents.
  154.64 +        /// </summary>
  154.65 +        public List<ContentItem> Contents { get; set; }
  154.66 +
  154.67 +        /// <summary>
  154.68 +        /// The update.
  154.69 +        /// </summary>
  154.70 +        public override void Update()
  154.71 +        {
  154.72 +            this.Contents.Clear();
  154.73 +            var hh = new HeaderHelper();
  154.74 +            this.Search(this.Base, hh);
  154.75 +            base.Update();
  154.76 +        }
  154.77 +
  154.78 +        /// <summary>
  154.79 +        /// The search.
  154.80 +        /// </summary>
  154.81 +        /// <param name="item">
  154.82 +        /// The item.
  154.83 +        /// </param>
  154.84 +        /// <param name="hh">
  154.85 +        /// The hh.
  154.86 +        /// </param>
  154.87 +        private void Search(ReportItem item, HeaderHelper hh)
  154.88 +        {
  154.89 +            var h = item as Header;
  154.90 +            if (h != null)
  154.91 +            {
  154.92 +                h.Chapter = hh.GetHeader(h.Level);
  154.93 +                this.Contents.Add(new ContentItem { Chapter = h.Chapter, Title = h.Text });
  154.94 +            }
  154.95 +
  154.96 +            foreach (var c in item.Children)
  154.97 +            {
  154.98 +                this.Search(c, hh);
  154.99 +            }
 154.100 +        }
 154.101 +
 154.102 +        /// <summary>
 154.103 +        /// The content item.
 154.104 +        /// </summary>
 154.105 +        public class ContentItem
 154.106 +        {
 154.107 +            /// <summary>
 154.108 +            /// Gets or sets Chapter.
 154.109 +            /// </summary>
 154.110 +            public string Chapter { get; set; }
 154.111 +
 154.112 +            /// <summary>
 154.113 +            /// Gets or sets Title.
 154.114 +            /// </summary>
 154.115 +            public string Title { get; set; }
 154.116 +        }
 154.117 +    }
 154.118 +}
 154.119 \ No newline at end of file
   155.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.2 +++ b/External/OxyPlot/OxyPlot/Reporting/ReportWriters/HtmlReportWriter.cs	Sat Jun 08 16:53:22 2013 +0000
   155.3 @@ -0,0 +1,501 @@
   155.4 +// --------------------------------------------------------------------------------------------------------------------
   155.5 +// <copyright file="HtmlReportWriter.cs" company="OxyPlot">
   155.6 +//   The MIT License (MIT)
   155.7 +//
   155.8 +//   Copyright (c) 2012 Oystein Bjorke
   155.9 +//
  155.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  155.11 +//   copy of this software and associated documentation files (the
  155.12 +//   "Software"), to deal in the Software without restriction, including
  155.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  155.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  155.15 +//   permit persons to whom the Software is furnished to do so, subject to
  155.16 +//   the following conditions:
  155.17 +//
  155.18 +//   The above copyright notice and this permission notice shall be included
  155.19 +//   in all copies or substantial portions of the Software.
  155.20 +//
  155.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  155.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  155.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  155.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  155.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  155.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  155.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  155.28 +// </copyright>
  155.29 +// <summary>
  155.30 +//   Specifies the html element type to use when writing plots.
  155.31 +// </summary>
  155.32 +// --------------------------------------------------------------------------------------------------------------------
  155.33 +namespace OxyPlot.Reporting
  155.34 +{
  155.35 +    using System.Collections.Generic;
  155.36 +    using System.IO;
  155.37 +    using System.Text;
  155.38 +
  155.39 +    /// <summary>
  155.40 +    /// Specifies the html element type to use when writing plots.
  155.41 +    /// </summary>
  155.42 +    public enum HtmlPlotElementType
  155.43 +    {
  155.44 +        /// <summary>
  155.45 +        /// Use the embed tag and reference an external svg file.
  155.46 +        /// </summary>
  155.47 +        Embed,
  155.48 +
  155.49 +        /// <summary>
  155.50 +        /// Use the object tag and reference an external svg file.
  155.51 +        /// </summary>
  155.52 +        Object,
  155.53 +
  155.54 +        /// <summary>
  155.55 +        /// Use the svg tag and include the plot inline.
  155.56 +        /// </summary>
  155.57 +        Svg
  155.58 +    }
  155.59 +
  155.60 +    /// <summary>
  155.61 +    /// HTML5 report writer.
  155.62 +    /// </summary>
  155.63 +    public class HtmlReportWriter : XmlWriterBase, IReportWriter
  155.64 +    {
  155.65 +        /// <summary>
  155.66 +        /// The text measurer.
  155.67 +        /// </summary>
  155.68 +        private readonly IRenderContext textMeasurer;
  155.69 +
  155.70 +        /// <summary>
  155.71 +        /// The figure counter.
  155.72 +        /// </summary>
  155.73 +        private int figureCounter;
  155.74 +
  155.75 +        /// <summary>
  155.76 +        /// The style.
  155.77 +        /// </summary>
  155.78 +        private ReportStyle style;
  155.79 +
  155.80 +        /// <summary>
  155.81 +        /// Initializes a new instance of the <see cref="HtmlReportWriter"/> class.
  155.82 +        /// </summary>
  155.83 +        /// <param name="stream">
  155.84 +        /// The stream.
  155.85 +        /// </param>
  155.86 +        /// <param name="textMeasurer">
  155.87 +        /// The text measurer.
  155.88 +        /// </param>
  155.89 +        public HtmlReportWriter(Stream stream, IRenderContext textMeasurer = null)
  155.90 +            : base(stream)
  155.91 +        {
  155.92 +            this.textMeasurer = textMeasurer;
  155.93 +            this.WriteHtmlElement();
  155.94 +            this.PlotElementType = HtmlPlotElementType.Svg;
  155.95 +        }
  155.96 +
  155.97 +        /// <summary>
  155.98 +        /// Gets or sets the type of the plot element.
  155.99 +        /// </summary>
 155.100 +        /// <value>
 155.101 +        /// The type of the plot element.
 155.102 +        /// </value>
 155.103 +        public HtmlPlotElementType PlotElementType { get; set; }
 155.104 +
 155.105 +        /// <summary>
 155.106 +        /// Closes this instance.
 155.107 +        /// </summary>
 155.108 +        public override void Close()
 155.109 +        {
 155.110 +            this.WriteEndElement();
 155.111 +            this.WriteEndElement();
 155.112 +            base.Close();
 155.113 +        }
 155.114 +
 155.115 +        /// <summary>
 155.116 +        /// Writes the class ID.
 155.117 +        /// </summary>
 155.118 +        /// <param name="className">
 155.119 +        /// The class.
 155.120 +        /// </param>
 155.121 +        /// <param name="id">
 155.122 +        /// The id.
 155.123 +        /// </param>
 155.124 +        public void WriteClassId(string className, string id = null)
 155.125 +        {
 155.126 +            if (className != null)
 155.127 +            {
 155.128 +                this.WriteAttributeString("class", className);
 155.129 +            }
 155.130 +
 155.131 +            if (id != null)
 155.132 +            {
 155.133 +                this.WriteAttributeString("id", id);
 155.134 +            }
 155.135 +        }
 155.136 +
 155.137 +        /// <summary>
 155.138 +        /// Writes the drawing.
 155.139 +        /// </summary>
 155.140 +        /// <param name="d">
 155.141 +        /// The drawing.
 155.142 +        /// </param>
 155.143 +        public void WriteDrawing(DrawingFigure d)
 155.144 +        {
 155.145 +            this.WriteStartFigure();
 155.146 +            this.WriteRaw(d.Content);
 155.147 +            this.WriteEndFigure(d.FigureText);
 155.148 +        }
 155.149 +
 155.150 +        /// <summary>
 155.151 +        /// Writes the equation.
 155.152 +        /// </summary>
 155.153 +        /// <param name="equation">
 155.154 +        /// The equation.
 155.155 +        /// </param>
 155.156 +        public void WriteEquation(Equation equation)
 155.157 +        {
 155.158 +            // todo: MathML?
 155.159 +        }
 155.160 +
 155.161 +        /// <summary>
 155.162 +        /// Writes the header.
 155.163 +        /// </summary>
 155.164 +        /// <param name="h">
 155.165 +        /// The header.
 155.166 +        /// </param>
 155.167 +        public void WriteHeader(Header h)
 155.168 +        {
 155.169 +            if (h.Text == null)
 155.170 +            {
 155.171 +                return;
 155.172 +            }
 155.173 +
 155.174 +            this.WriteStartElement("h" + h.Level);
 155.175 +            this.WriteString(h.ToString());
 155.176 +            this.WriteEndElement();
 155.177 +        }
 155.178 +
 155.179 +        /// <summary>
 155.180 +        /// Writes the image.
 155.181 +        /// </summary>
 155.182 +        /// <param name="i">
 155.183 +        /// The image.
 155.184 +        /// </param>
 155.185 +        public void WriteImage(Image i)
 155.186 +        {
 155.187 +            // this requires the image to be located in the same folder as the html
 155.188 +            string localFileName = i.Source;
 155.189 +            this.WriteStartFigure();
 155.190 +            this.WriteStartElement("img");
 155.191 +            this.WriteAttributeString("src", localFileName);
 155.192 +            this.WriteAttributeString("alt", i.FigureText);
 155.193 +            this.WriteEndElement();
 155.194 +            this.WriteEndFigure(i.FigureText);
 155.195 +        }
 155.196 +
 155.197 +        /// <summary>
 155.198 +        /// Writes the paragraph.
 155.199 +        /// </summary>
 155.200 +        /// <param name="p">
 155.201 +        /// The paragraph.
 155.202 +        /// </param>
 155.203 +        public void WriteParagraph(Paragraph p)
 155.204 +        {
 155.205 +            this.WriteElementString("p", p.Text);
 155.206 +        }
 155.207 +
 155.208 +        /// <summary>
 155.209 +        /// Writes the plot.
 155.210 +        /// </summary>
 155.211 +        /// <param name="plot">
 155.212 +        /// The plot.
 155.213 +        /// </param>
 155.214 +        public void WritePlot(PlotFigure plot)
 155.215 +        {
 155.216 +            this.WriteStartFigure();
 155.217 +            switch (this.PlotElementType)
 155.218 +            {
 155.219 +                case HtmlPlotElementType.Embed:
 155.220 +                case HtmlPlotElementType.Object:
 155.221 +                    // TODO: need a Func<string,Stream> to provide streams for the plot files?
 155.222 +
 155.223 +                    //string source = string.Format(
 155.224 +                    //    "{0}_Plot{1}.svg", Path.GetFileNameWithoutExtension(this.outputFile), plot.FigureNumber);
 155.225 +                    //plot.PlotModel.SaveSvg(this.GetFullFileName(source), plot.Width, plot.Height, this.textMeasurer);
 155.226 +                    //this.WriteStartElement(this.PlotElementType == HtmlPlotElementType.Embed ? "embed" : "object");
 155.227 +                    //this.WriteAttributeString("src", source);
 155.228 +                    //this.WriteAttributeString("type", "image/svg+xml");
 155.229 +                    //this.WriteEndElement();
 155.230 +                    break;
 155.231 +                case HtmlPlotElementType.Svg:
 155.232 +                    this.WriteRaw(plot.PlotModel.ToSvg(plot.Width, plot.Height, false, this.textMeasurer));
 155.233 +                    break;
 155.234 +            }
 155.235 +
 155.236 +            this.WriteEndFigure(plot.FigureText);
 155.237 +        }
 155.238 +
 155.239 +        /// <summary>
 155.240 +        /// The write report.
 155.241 +        /// </summary>
 155.242 +        /// <param name="report">
 155.243 +        /// The report.
 155.244 +        /// </param>
 155.245 +        /// <param name="reportStyle">
 155.246 +        /// The style.
 155.247 +        /// </param>
 155.248 +        public void WriteReport(Report report, ReportStyle reportStyle)
 155.249 +        {
 155.250 +            this.style = reportStyle;
 155.251 +            this.WriteHtmlHeader(report.Title, null, CreateCss(reportStyle));
 155.252 +            report.Write(this);
 155.253 +        }
 155.254 +
 155.255 +        /// <summary>
 155.256 +        /// Writes the items.
 155.257 +        /// </summary>
 155.258 +        /// <param name="t">
 155.259 +        /// The table.
 155.260 +        /// </param>
 155.261 +        public void WriteRows(Table t)
 155.262 +        {
 155.263 +            IList<TableColumn> columns = t.Columns;
 155.264 +
 155.265 +            foreach (var c in columns)
 155.266 +            {
 155.267 +                this.WriteStartElement("col");
 155.268 +                this.WriteAttributeString("align", GetAlignmentString(c.Alignment));
 155.269 +                if (double.IsNaN(c.Width))
 155.270 +                {
 155.271 +                    this.WriteAttributeString("width", c.Width + "pt");
 155.272 +                }
 155.273 +
 155.274 +                this.WriteEndElement();
 155.275 +            }
 155.276 +
 155.277 +            foreach (var row in t.Rows)
 155.278 +            {
 155.279 +                if (row.IsHeader)
 155.280 +                {
 155.281 +                    this.WriteStartElement("thead");
 155.282 +                }
 155.283 +
 155.284 +                this.WriteStartElement("tr");
 155.285 +                int j = 0;
 155.286 +                foreach (var c in row.Cells)
 155.287 +                {
 155.288 +                    bool isHeader = row.IsHeader || t.Columns[j++].IsHeader;
 155.289 +
 155.290 +                    this.WriteStartElement("td");
 155.291 +                    if (isHeader)
 155.292 +                    {
 155.293 +                        this.WriteAttributeString("class", "header");
 155.294 +                    }
 155.295 +
 155.296 +                    this.WriteString(c.Content);
 155.297 +                    this.WriteEndElement();
 155.298 +                }
 155.299 +
 155.300 +                this.WriteEndElement(); // tr
 155.301 +                if (row.IsHeader)
 155.302 +                {
 155.303 +                    this.WriteEndElement(); // thead
 155.304 +                }
 155.305 +            }
 155.306 +        }
 155.307 +
 155.308 +        /// <summary>
 155.309 +        /// Writes the table.
 155.310 +        /// </summary>
 155.311 +        /// <param name="t">
 155.312 +        /// The t.
 155.313 +        /// </param>
 155.314 +        public void WriteTable(Table t)
 155.315 +        {
 155.316 +            if (t.Rows == null || t.Columns == null)
 155.317 +            {
 155.318 +                return;
 155.319 +            }
 155.320 +
 155.321 +            this.WriteStartElement("table");
 155.322 +
 155.323 +            // WriteAttributeString("border", "1");
 155.324 +            // WriteAttributeString("width", "60%");
 155.325 +            if (t.Caption != null)
 155.326 +            {
 155.327 +                this.WriteStartElement("caption");
 155.328 +                this.WriteString(t.GetFullCaption(this.style));
 155.329 +                this.WriteEndElement();
 155.330 +            }
 155.331 +
 155.332 +            this.WriteRows(t);
 155.333 +
 155.334 +            this.WriteEndElement(); // table
 155.335 +        }
 155.336 +
 155.337 +        /// <summary>
 155.338 +        /// Creates the css section.
 155.339 +        /// </summary>
 155.340 +        /// <param name="style">
 155.341 +        /// The style.
 155.342 +        /// </param>
 155.343 +        /// <returns>
 155.344 +        /// The css.
 155.345 +        /// </returns>
 155.346 +        private static string CreateCss(ReportStyle style)
 155.347 +        {
 155.348 +            var css = new StringBuilder();
 155.349 +            css.AppendLine("body { " + ParagraphStyleToCss(style.BodyTextStyle) + " }");
 155.350 +            for (int i = 0; i < style.HeaderStyles.Length; i++)
 155.351 +            {
 155.352 +                css.AppendLine("h" + (i + 1) + " {" + ParagraphStyleToCss(style.HeaderStyles[i]) + " }");
 155.353 +            }
 155.354 +
 155.355 +            css.AppendLine("table caption { " + ParagraphStyleToCss(style.TableCaptionStyle) + " }");
 155.356 +            css.AppendLine("thead { " + ParagraphStyleToCss(style.TableHeaderStyle) + " }");
 155.357 +            css.AppendLine("td { " + ParagraphStyleToCss(style.TableTextStyle) + " }");
 155.358 +            css.AppendLine("td.header { " + ParagraphStyleToCss(style.TableHeaderStyle) + " }");
 155.359 +            css.AppendLine("figuretext { " + ParagraphStyleToCss(style.FigureTextStyle) + " }");
 155.360 +
 155.361 +            css.Append(
 155.362 +                @"body { margin:20pt; }
 155.363 +            table { border: solid 1px black; margin: 8pt; border-collapse:collapse; }
 155.364 +            td { padding: 0 2pt 0 2pt; border-left: solid 1px black; border-right: solid 1px black;}
 155.365 +            thead { border:solid 1px black; }
 155.366 +            .content, .content td { border: none; }
 155.367 +            .figure { margin: 8pt;}
 155.368 +            .table { margin: 8pt;}
 155.369 +            .table caption { margin: 4pt;}
 155.370 +            .table thead td { padding: 2pt;}");
 155.371 +            return css.ToString();
 155.372 +        }
 155.373 +
 155.374 +        /// <summary>
 155.375 +        /// Gets the alignment string.
 155.376 +        /// </summary>
 155.377 +        /// <param name="a">
 155.378 +        /// The alignment type.
 155.379 +        /// </param>
 155.380 +        /// <returns>
 155.381 +        /// An alignment string.
 155.382 +        /// </returns>
 155.383 +        private static string GetAlignmentString(Alignment a)
 155.384 +        {
 155.385 +            return a.ToString().ToLower();
 155.386 +        }
 155.387 +
 155.388 +        /// <summary>
 155.389 +        /// Converts a paragraphes style to css.
 155.390 +        /// </summary>
 155.391 +        /// <param name="s">
 155.392 +        /// The style.
 155.393 +        /// </param>
 155.394 +        /// <returns>
 155.395 +        /// A css string.
 155.396 +        /// </returns>
 155.397 +        private static string ParagraphStyleToCss(ParagraphStyle s)
 155.398 +        {
 155.399 +            var css = new StringBuilder();
 155.400 +            if (s.FontFamily != null)
 155.401 +            {
 155.402 +                css.Append(string.Format("font-family:{0};", s.FontFamily));
 155.403 +            }
 155.404 +
 155.405 +            css.Append(string.Format("font-size:{0}pt;", s.FontSize));
 155.406 +            if (s.Bold)
 155.407 +            {
 155.408 +                css.Append(string.Format("font-weight:bold;"));
 155.409 +            }
 155.410 +
 155.411 +            return css.ToString();
 155.412 +        }
 155.413 +
 155.414 +        /// <summary>
 155.415 +        /// Initializes this instance.
 155.416 +        /// </summary>
 155.417 +        private void WriteHtmlElement()
 155.418 +        {
 155.419 +            this.WriteStartElement("html", "http://www.w3.org/1999/xhtml");
 155.420 +        }
 155.421 +
 155.422 +        /// <summary>
 155.423 +        /// Writes the div.
 155.424 +        /// </summary>
 155.425 +        /// <param name="divstyle">
 155.426 +        /// The style of the div.
 155.427 +        /// </param>
 155.428 +        /// <param name="content">
 155.429 +        /// The content.
 155.430 +        /// </param>
 155.431 +        private void WriteDiv(string divstyle, string content)
 155.432 +        {
 155.433 +            this.WriteStartElement("div");
 155.434 +            this.WriteAttributeString("class", divstyle);
 155.435 +            this.WriteString(content);
 155.436 +            this.WriteEndElement();
 155.437 +        }
 155.438 +
 155.439 +        /// <summary>
 155.440 +        /// Writes the end figure.
 155.441 +        /// </summary>
 155.442 +        /// <param name="text">
 155.443 +        /// The figure text.
 155.444 +        /// </param>
 155.445 +        private void WriteEndFigure(string text)
 155.446 +        {
 155.447 +            this.WriteDiv("figuretext", string.Format("Fig {0}. {1}", this.figureCounter, text));
 155.448 +            this.WriteEndElement();
 155.449 +        }
 155.450 +
 155.451 +        /// <summary>
 155.452 +        /// Writes the HTML header.
 155.453 +        /// </summary>
 155.454 +        /// <param name="title">
 155.455 +        /// The title.
 155.456 +        /// </param>
 155.457 +        /// <param name="cssPath">
 155.458 +        /// The CSS path.
 155.459 +        /// </param>
 155.460 +        /// <param name="cssStyle">
 155.461 +        /// The style.
 155.462 +        /// </param>
 155.463 +        private void WriteHtmlHeader(string title, string cssPath, string cssStyle)
 155.464 +        {
 155.465 +            this.WriteStartElement("head");
 155.466 +
 155.467 +            if (title != null)
 155.468 +            {
 155.469 +                this.WriteElementString("title", title);
 155.470 +            }
 155.471 +
 155.472 +            if (cssPath != null)
 155.473 +            {
 155.474 +                this.WriteStartElement("link");
 155.475 +                this.WriteAttributeString("href", cssPath);
 155.476 +                this.WriteAttributeString("rel", "stylesheet");
 155.477 +                this.WriteAttributeString("type", "text/css");
 155.478 +                this.WriteEndElement(); // link
 155.479 +            }
 155.480 +
 155.481 +            if (cssStyle != null)
 155.482 +            {
 155.483 +                this.WriteStartElement("style");
 155.484 +                this.WriteAttributeString("type", "text/css");
 155.485 +                this.WriteRaw(cssStyle);
 155.486 +                this.WriteEndElement();
 155.487 +            }
 155.488 +
 155.489 +            this.WriteEndElement(); // head
 155.490 +            this.WriteStartElement("body");
 155.491 +        }
 155.492 +
 155.493 +        /// <summary>
 155.494 +        /// Writes the start figure element.
 155.495 +        /// </summary>
 155.496 +        private void WriteStartFigure()
 155.497 +        {
 155.498 +            this.figureCounter++;
 155.499 +            this.WriteStartElement("p");
 155.500 +            this.WriteClassId("figure");
 155.501 +        }
 155.502 +
 155.503 +    }
 155.504 +}
 155.505 \ No newline at end of file
   156.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   156.2 +++ b/External/OxyPlot/OxyPlot/Reporting/ReportWriters/IReportWriter.cs	Sat Jun 08 16:53:22 2013 +0000
   156.3 @@ -0,0 +1,87 @@
   156.4 +// --------------------------------------------------------------------------------------------------------------------
   156.5 +// <copyright file="IReportWriter.cs" company="OxyPlot">
   156.6 +//   The MIT License (MIT)
   156.7 +//
   156.8 +//   Copyright (c) 2012 Oystein Bjorke
   156.9 +//
  156.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  156.11 +//   copy of this software and associated documentation files (the
  156.12 +//   "Software"), to deal in the Software without restriction, including
  156.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  156.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  156.15 +//   permit persons to whom the Software is furnished to do so, subject to
  156.16 +//   the following conditions:
  156.17 +//
  156.18 +//   The above copyright notice and this permission notice shall be included
  156.19 +//   in all copies or substantial portions of the Software.
  156.20 +//
  156.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  156.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  156.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  156.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  156.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  156.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  156.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  156.28 +// </copyright>
  156.29 +// <summary>
  156.30 +//   Interface for Report writers.
  156.31 +// </summary>
  156.32 +// --------------------------------------------------------------------------------------------------------------------
  156.33 +namespace OxyPlot.Reporting
  156.34 +{
  156.35 +    /// <summary>
  156.36 +    /// Interface for Report writers.
  156.37 +    /// </summary>
  156.38 +    public interface IReportWriter
  156.39 +    {
  156.40 +        /// <summary>
  156.41 +        /// Writes the drawing.
  156.42 +        /// </summary>
  156.43 +        /// <param name="drawing">The drawing.</param>
  156.44 +        void WriteDrawing(DrawingFigure drawing);
  156.45 +
  156.46 +        /// <summary>
  156.47 +        /// Writes the equation.
  156.48 +        /// </summary>
  156.49 +        /// <param name="equation">The equation.</param>
  156.50 +        void WriteEquation(Equation equation);
  156.51 +
  156.52 +        /// <summary>
  156.53 +        /// Writes the header.
  156.54 +        /// </summary>
  156.55 +        /// <param name="header">The header.</param>
  156.56 +        void WriteHeader(Header header);
  156.57 +
  156.58 +        /// <summary>
  156.59 +        /// Writes the image.
  156.60 +        /// </summary>
  156.61 +        /// <param name="image">The image.</param>
  156.62 +        void WriteImage(Image image);
  156.63 +
  156.64 +        /// <summary>
  156.65 +        /// Writes the paragraph.
  156.66 +        /// </summary>
  156.67 +        /// <param name="paragraph">The paragraph.</param>
  156.68 +        void WriteParagraph(Paragraph paragraph);
  156.69 +
  156.70 +        /// <summary>
  156.71 +        /// Writes the plot.
  156.72 +        /// </summary>
  156.73 +        /// <param name="plot">The plot.</param>
  156.74 +        void WritePlot(PlotFigure plot);
  156.75 +
  156.76 +        /// <summary>
  156.77 +        /// Writes the report.
  156.78 +        /// </summary>
  156.79 +        /// <param name="report">The report.</param>
  156.80 +        /// <param name="reportStyle">The style.</param>
  156.81 +        void WriteReport(Report report, ReportStyle reportStyle);
  156.82 +
  156.83 +        /// <summary>
  156.84 +        /// Writes the table.
  156.85 +        /// </summary>
  156.86 +        /// <param name="table">The table.</param>
  156.87 +        void WriteTable(Table table);
  156.88 +
  156.89 +    }
  156.90 +}
  156.91 \ No newline at end of file
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/External/OxyPlot/OxyPlot/Reporting/ReportWriters/StringExtensions.cs	Sat Jun 08 16:53:22 2013 +0000
   157.3 @@ -0,0 +1,130 @@
   157.4 +// --------------------------------------------------------------------------------------------------------------------
   157.5 +// <copyright file="StringExtensions.cs" company="OxyPlot">
   157.6 +//   The MIT License (MIT)
   157.7 +//
   157.8 +//   Copyright (c) 2012 Oystein Bjorke
   157.9 +//
  157.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  157.11 +//   copy of this software and associated documentation files (the
  157.12 +//   "Software"), to deal in the Software without restriction, including
  157.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  157.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  157.15 +//   permit persons to whom the Software is furnished to do so, subject to
  157.16 +//   the following conditions:
  157.17 +//
  157.18 +//   The above copyright notice and this permission notice shall be included
  157.19 +//   in all copies or substantial portions of the Software.
  157.20 +//
  157.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  157.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  157.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  157.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  157.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  157.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  157.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  157.28 +// </copyright>
  157.29 +// <summary>
  157.30 +//   The string extensions.
  157.31 +// </summary>
  157.32 +// --------------------------------------------------------------------------------------------------------------------
  157.33 +namespace OxyPlot.Reporting
  157.34 +{
  157.35 +    using System.Collections.Generic;
  157.36 +    using System.Text;
  157.37 +
  157.38 +    /// <summary>
  157.39 +    /// The string extensions.
  157.40 +    /// </summary>
  157.41 +    public static class StringExtensions
  157.42 +    {
  157.43 +        /// <summary>
  157.44 +        /// The repeat.
  157.45 +        /// </summary>
  157.46 +        /// <param name="source">
  157.47 +        /// The source.
  157.48 +        /// </param>
  157.49 +        /// <param name="n">
  157.50 +        /// The n.
  157.51 +        /// </param>
  157.52 +        /// <returns>
  157.53 +        /// The repeat.
  157.54 +        /// </returns>
  157.55 +        public static string Repeat(this string source, int n)
  157.56 +        {
  157.57 +            var sb = new StringBuilder(n * source.Length);
  157.58 +            for (int i = 0; i < n; i++)
  157.59 +            {
  157.60 +                sb.Append(source);
  157.61 +            }
  157.62 +
  157.63 +            return sb.ToString();
  157.64 +        }
  157.65 +
  157.66 +        /// <summary>
  157.67 +        /// The split lines.
  157.68 +        /// </summary>
  157.69 +        /// <param name="s">
  157.70 +        /// The s.
  157.71 +        /// </param>
  157.72 +        /// <param name="lineLength">
  157.73 +        /// The line length.
  157.74 +        /// </param>
  157.75 +        /// <returns>
  157.76 +        /// </returns>
  157.77 +        public static string[] SplitLines(this string s, int lineLength = 80)
  157.78 +        {
  157.79 +            var lines = new List<string>();
  157.80 +
  157.81 +            int i = 0;
  157.82 +            while (i < s.Length)
  157.83 +            {
  157.84 +                int len = FindLineLength(s, i, lineLength);
  157.85 +                lines.Add(len == 0 ? s.Substring(i).Trim() : s.Substring(i, len).Trim());
  157.86 +                i += len;
  157.87 +                if (len == 0)
  157.88 +                {
  157.89 +                    break;
  157.90 +                }
  157.91 +            }
  157.92 +
  157.93 +            return lines.ToArray();
  157.94 +        }
  157.95 +
  157.96 +        /// <summary>
  157.97 +        /// The find line length.
  157.98 +        /// </summary>
  157.99 +        /// <param name="text">
 157.100 +        /// The text.
 157.101 +        /// </param>
 157.102 +        /// <param name="i">
 157.103 +        /// The i.
 157.104 +        /// </param>
 157.105 +        /// <param name="maxLineLength">
 157.106 +        /// The max line length.
 157.107 +        /// </param>
 157.108 +        /// <returns>
 157.109 +        /// The find line length.
 157.110 +        /// </returns>
 157.111 +        private static int FindLineLength(string text, int i, int maxLineLength)
 157.112 +        {
 157.113 +            int i2 = i + 1;
 157.114 +            int len = 0;
 157.115 +            while (i2 < i + maxLineLength && i2 < text.Length)
 157.116 +            {
 157.117 +                i2 = text.IndexOfAny(" \n\r".ToCharArray(), i2 + 1);
 157.118 +                if (i2 == -1)
 157.119 +                {
 157.120 +                    i2 = text.Length;
 157.121 +                }
 157.122 +
 157.123 +                if (i2 - i < maxLineLength)
 157.124 +                {
 157.125 +                    len = i2 - i;
 157.126 +                }
 157.127 +            }
 157.128 +
 157.129 +            return len;
 157.130 +        }
 157.131 +
 157.132 +    }
 157.133 +}
 157.134 \ No newline at end of file
   158.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.2 +++ b/External/OxyPlot/OxyPlot/Reporting/ReportWriters/TextReportWriter.cs	Sat Jun 08 16:53:22 2013 +0000
   158.3 @@ -0,0 +1,289 @@
   158.4 +// --------------------------------------------------------------------------------------------------------------------
   158.5 +// <copyright file="TextReportWriter.cs" company="OxyPlot">
   158.6 +//   The MIT License (MIT)
   158.7 +//
   158.8 +//   Copyright (c) 2012 Oystein Bjorke
   158.9 +//
  158.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  158.11 +//   copy of this software and associated documentation files (the
  158.12 +//   "Software"), to deal in the Software without restriction, including
  158.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  158.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  158.15 +//   permit persons to whom the Software is furnished to do so, subject to
  158.16 +//   the following conditions:
  158.17 +//
  158.18 +//   The above copyright notice and this permission notice shall be included
  158.19 +//   in all copies or substantial portions of the Software.
  158.20 +//
  158.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  158.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  158.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  158.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  158.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  158.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  158.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  158.28 +// </copyright>
  158.29 +// <summary>
  158.30 +//   ANSI text report writer.
  158.31 +// </summary>
  158.32 +// --------------------------------------------------------------------------------------------------------------------
  158.33 +namespace OxyPlot.Reporting
  158.34 +{
  158.35 +    using System;
  158.36 +    using System.IO;
  158.37 +
  158.38 +    /// <summary>
  158.39 +    /// ANSI text report writer.
  158.40 +    /// </summary>
  158.41 +    /// <remarks>
  158.42 +    /// This will not write figures/images.
  158.43 +    /// </remarks>
  158.44 +    public class TextReportWriter : StreamWriter, IReportWriter
  158.45 +    {
  158.46 +        /// <summary>
  158.47 +        /// The table cell separator.
  158.48 +        /// </summary>
  158.49 +        private const string TableCellSeparator = " | ";
  158.50 +
  158.51 +        /// <summary>
  158.52 +        /// The table row end.
  158.53 +        /// </summary>
  158.54 +        private const string TableRowEnd = " |";
  158.55 +
  158.56 +        /// <summary>
  158.57 +        /// The table row start.
  158.58 +        /// </summary>
  158.59 +        private const string TableRowStart = "| ";
  158.60 +
  158.61 +        /// <summary>
  158.62 +        /// The table counter.
  158.63 +        /// </summary>
  158.64 +        private int tableCounter;
  158.65 +
  158.66 +        /// <summary>
  158.67 +        /// Initializes a new instance of the <see cref="TextReportWriter"/> class.
  158.68 +        /// </summary>
  158.69 +        /// <param name="stream">
  158.70 +        /// The stream.
  158.71 +        /// </param>
  158.72 +        public TextReportWriter(Stream stream)
  158.73 +            : base(stream)
  158.74 +        {
  158.75 +            this.MaxLineLength = 60;
  158.76 +        }
  158.77 +
  158.78 +        /// <summary>
  158.79 +        /// Gets or sets MaxLineLength.
  158.80 +        /// </summary>
  158.81 +        public int MaxLineLength { get; set; }
  158.82 +
  158.83 +        /// <summary>
  158.84 +        /// The write drawing.
  158.85 +        /// </summary>
  158.86 +        /// <param name="d">
  158.87 +        /// The d.
  158.88 +        /// </param>
  158.89 +        public void WriteDrawing(DrawingFigure d)
  158.90 +        {
  158.91 +        }
  158.92 +
  158.93 +        /// <summary>
  158.94 +        /// The write equation.
  158.95 +        /// </summary>
  158.96 +        /// <param name="equation">
  158.97 +        /// The equation.
  158.98 +        /// </param>
  158.99 +        public void WriteEquation(Equation equation)
 158.100 +        {
 158.101 +        }
 158.102 +
 158.103 +        /// <summary>
 158.104 +        /// The write header.
 158.105 +        /// </summary>
 158.106 +        /// <param name="h">
 158.107 +        /// The h.
 158.108 +        /// </param>
 158.109 +        public void WriteHeader(Header h)
 158.110 +        {
 158.111 +            if (h.Text == null)
 158.112 +            {
 158.113 +                return;
 158.114 +            }
 158.115 +
 158.116 +            WriteLine(h);
 158.117 +            if (h.Level == 1)
 158.118 +            {
 158.119 +                this.WriteLine("=".Repeat(h.Text.Length));
 158.120 +            }
 158.121 +
 158.122 +            this.WriteLine();
 158.123 +        }
 158.124 +
 158.125 +        /// <summary>
 158.126 +        /// The write image.
 158.127 +        /// </summary>
 158.128 +        /// <param name="i">
 158.129 +        /// The i.
 158.130 +        /// </param>
 158.131 +        public void WriteImage(Image i)
 158.132 +        {
 158.133 +        }
 158.134 +
 158.135 +        /// <summary>
 158.136 +        /// The write paragraph.
 158.137 +        /// </summary>
 158.138 +        /// <param name="p">
 158.139 +        /// The p.
 158.140 +        /// </param>
 158.141 +        public void WriteParagraph(Paragraph p)
 158.142 +        {
 158.143 +            foreach (string line in p.Text.SplitLines(this.MaxLineLength))
 158.144 +            {
 158.145 +                WriteLine(line);
 158.146 +            }
 158.147 +
 158.148 +            this.WriteLine();
 158.149 +        }
 158.150 +
 158.151 +        /// <summary>
 158.152 +        /// The write plot.
 158.153 +        /// </summary>
 158.154 +        /// <param name="plot">
 158.155 +        /// The plot.
 158.156 +        /// </param>
 158.157 +        public void WritePlot(PlotFigure plot)
 158.158 +        {
 158.159 +        }
 158.160 +
 158.161 +        /// <summary>
 158.162 +        /// The write report.
 158.163 +        /// </summary>
 158.164 +        /// <param name="report">
 158.165 +        /// The report.
 158.166 +        /// </param>
 158.167 +        /// <param name="reportStyle">
 158.168 +        /// The style.
 158.169 +        /// </param>
 158.170 +        public void WriteReport(Report report, ReportStyle reportStyle)
 158.171 +        {
 158.172 +            report.Write(this);
 158.173 +        }
 158.174 +
 158.175 +        /// <summary>
 158.176 +        /// The write table.
 158.177 +        /// </summary>
 158.178 +        /// <param name="t">
 158.179 +        /// The t.
 158.180 +        /// </param>
 158.181 +        public void WriteTable(Table t)
 158.182 +        {
 158.183 +            this.tableCounter++;
 158.184 +            this.WriteLine(string.Format("Table {0}. {1}", this.tableCounter, t.Caption));
 158.185 +            this.WriteLine();
 158.186 +            int rows = t.Rows.Count;
 158.187 +            int cols = t.Columns.Count;
 158.188 +
 158.189 +            var columnWidth = new int[cols];
 158.190 +            int totalLength = 0;
 158.191 +            for (int j = 0; j < cols; j++)
 158.192 +            {
 158.193 +                columnWidth[j] = 0;
 158.194 +                foreach (var tr in t.Rows)
 158.195 +                {
 158.196 +                    TableCell cell = tr.Cells[j];
 158.197 +                    string text = cell.Content;
 158.198 +                    columnWidth[j] = Math.Max(columnWidth[j], text != null ? text.Length : 0);
 158.199 +                }
 158.200 +
 158.201 +                totalLength += columnWidth[j];
 158.202 +            }
 158.203 +
 158.204 +            // WriteLine("-".Repeat(totalLength));
 158.205 +            foreach (var tr in t.Rows)
 158.206 +            {
 158.207 +                for (int j = 0; j < cols; j++)
 158.208 +                {
 158.209 +                    TableCell cell = tr.Cells[j];
 158.210 +                    string text = cell.Content;
 158.211 +                    this.Write(GetCellText(j, cols, PadString(text, t.Columns[j].Alignment, columnWidth[j])));
 158.212 +                }
 158.213 +
 158.214 +                this.WriteLine();
 158.215 +            }
 158.216 +
 158.217 +            this.WriteLine();
 158.218 +        }
 158.219 +
 158.220 +        /// <summary>
 158.221 +        /// The get cell text.
 158.222 +        /// </summary>
 158.223 +        /// <param name="i">
 158.224 +        /// The i.
 158.225 +        /// </param>
 158.226 +        /// <param name="count">
 158.227 +        /// The count.
 158.228 +        /// </param>
 158.229 +        /// <param name="p">
 158.230 +        /// The p.
 158.231 +        /// </param>
 158.232 +        /// <returns>
 158.233 +        /// The get cell text.
 158.234 +        /// </returns>
 158.235 +        private static string GetCellText(int i, int count, string p)
 158.236 +        {
 158.237 +            if (i == 0)
 158.238 +            {
 158.239 +                p = TableRowStart + p;
 158.240 +            }
 158.241 +
 158.242 +            if (i + 1 < count)
 158.243 +            {
 158.244 +                p += TableCellSeparator;
 158.245 +            }
 158.246 +
 158.247 +            if (i == count - 1)
 158.248 +            {
 158.249 +                p += TableRowEnd;
 158.250 +            }
 158.251 +
 158.252 +            return p;
 158.253 +        }
 158.254 +
 158.255 +        /// <summary>
 158.256 +        /// The pad string.
 158.257 +        /// </summary>
 158.258 +        /// <param name="text">
 158.259 +        /// The text.
 158.260 +        /// </param>
 158.261 +        /// <param name="alignment">
 158.262 +        /// The alignment.
 158.263 +        /// </param>
 158.264 +        /// <param name="width">
 158.265 +        /// The width.
 158.266 +        /// </param>
 158.267 +        /// <returns>
 158.268 +        /// The pad string.
 158.269 +        /// </returns>
 158.270 +        private static string PadString(string text, Alignment alignment, int width)
 158.271 +        {
 158.272 +            if (text == null)
 158.273 +            {
 158.274 +                return string.Empty.PadLeft(width);
 158.275 +            }
 158.276 +
 158.277 +            switch (alignment)
 158.278 +            {
 158.279 +                case Alignment.Left:
 158.280 +                    return text.PadRight(width);
 158.281 +                case Alignment.Right:
 158.282 +                    return text.PadLeft(width);
 158.283 +                case Alignment.Center:
 158.284 +                    text = text.PadRight((text.Length + width) / 2);
 158.285 +                    return text.PadLeft(width);
 158.286 +            }
 158.287 +
 158.288 +            return null;
 158.289 +        }
 158.290 +
 158.291 +    }
 158.292 +}
 158.293 \ No newline at end of file
   159.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.2 +++ b/External/OxyPlot/OxyPlot/Reporting/ReportWriters/WikiReportWriter.cs	Sat Jun 08 16:53:22 2013 +0000
   159.3 @@ -0,0 +1,308 @@
   159.4 +// --------------------------------------------------------------------------------------------------------------------
   159.5 +// <copyright file="WikiReportWriter.cs" company="OxyPlot">
   159.6 +//   The MIT License (MIT)
   159.7 +//
   159.8 +//   Copyright (c) 2012 Oystein Bjorke
   159.9 +//
  159.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  159.11 +//   copy of this software and associated documentation files (the
  159.12 +//   "Software"), to deal in the Software without restriction, including
  159.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  159.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  159.15 +//   permit persons to whom the Software is furnished to do so, subject to
  159.16 +//   the following conditions:
  159.17 +//
  159.18 +//   The above copyright notice and this permission notice shall be included
  159.19 +//   in all copies or substantial portions of the Software.
  159.20 +//
  159.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  159.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  159.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  159.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  159.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  159.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  159.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  159.28 +// </copyright>
  159.29 +// <summary>
  159.30 +//   Wiki formatting report writer.
  159.31 +// </summary>
  159.32 +// --------------------------------------------------------------------------------------------------------------------
  159.33 +namespace OxyPlot.Reporting
  159.34 +{
  159.35 +    using System;
  159.36 +    using System.IO;
  159.37 +
  159.38 +    /// <summary>
  159.39 +    /// Wiki formatting report writer.
  159.40 +    /// </summary>
  159.41 +    /// <remarks>
  159.42 +    /// This will not write figures/images.
  159.43 +    /// </remarks>
  159.44 +    public class WikiReportWriter : StreamWriter, IReportWriter
  159.45 +    {
  159.46 +        /// <summary>
  159.47 +        /// The table cell separator.
  159.48 +        /// </summary>
  159.49 +        private const string TableCellSeparator = " | ";
  159.50 +
  159.51 +        /// <summary>
  159.52 +        /// The table header cell separator.
  159.53 +        /// </summary>
  159.54 +        private const string TableHeaderCellSeparator = " || ";
  159.55 +
  159.56 +        /// <summary>
  159.57 +        /// The table header row end.
  159.58 +        /// </summary>
  159.59 +        private const string TableHeaderRowEnd = " ||";
  159.60 +
  159.61 +        /// <summary>
  159.62 +        /// The table header row start.
  159.63 +        /// </summary>
  159.64 +        private const string TableHeaderRowStart = "|| ";
  159.65 +
  159.66 +        /// <summary>
  159.67 +        /// The table row end.
  159.68 +        /// </summary>
  159.69 +        private const string TableRowEnd = " |";
  159.70 +
  159.71 +        /// <summary>
  159.72 +        /// The table row start.
  159.73 +        /// </summary>
  159.74 +        private const string TableRowStart = "| ";
  159.75 +
  159.76 +        /// <summary>
  159.77 +        /// The table counter.
  159.78 +        /// </summary>
  159.79 +        private int tableCounter;
  159.80 +
  159.81 +        /// <summary>
  159.82 +        /// Initializes a new instance of the <see cref="WikiReportWriter"/> class.
  159.83 +        /// </summary>
  159.84 +        /// <param name="s">
  159.85 +        /// The s.
  159.86 +        /// </param>
  159.87 +        public WikiReportWriter(Stream s)
  159.88 +            : base(s)
  159.89 +        {
  159.90 +            this.MaxLineLength = 60;
  159.91 +        }
  159.92 +
  159.93 +        /// <summary>
  159.94 +        /// Gets or sets MaxLineLength.
  159.95 +        /// </summary>
  159.96 +        public int MaxLineLength { get; set; }
  159.97 +
  159.98 +        /// <summary>
  159.99 +        /// The write drawing.
 159.100 +        /// </summary>
 159.101 +        /// <param name="d">
 159.102 +        /// The d.
 159.103 +        /// </param>
 159.104 +        public void WriteDrawing(DrawingFigure d)
 159.105 +        {
 159.106 +        }
 159.107 +
 159.108 +        /// <summary>
 159.109 +        /// The write equation.
 159.110 +        /// </summary>
 159.111 +        /// <param name="equation">
 159.112 +        /// The equation.
 159.113 +        /// </param>
 159.114 +        public void WriteEquation(Equation equation)
 159.115 +        {
 159.116 +        }
 159.117 +
 159.118 +        /// <summary>
 159.119 +        /// The write header.
 159.120 +        /// </summary>
 159.121 +        /// <param name="h">
 159.122 +        /// The h.
 159.123 +        /// </param>
 159.124 +        public void WriteHeader(Header h)
 159.125 +        {
 159.126 +            if (h.Text == null)
 159.127 +            {
 159.128 +                return;
 159.129 +            }
 159.130 +
 159.131 +            string prefix = string.Empty;
 159.132 +            for (int i = 0; i < h.Level; i++)
 159.133 +            {
 159.134 +                prefix += "!";
 159.135 +            }
 159.136 +
 159.137 +            this.WriteLine(prefix + " " + h.Text);
 159.138 +        }
 159.139 +
 159.140 +        /// <summary>
 159.141 +        /// The write image.
 159.142 +        /// </summary>
 159.143 +        /// <param name="i">
 159.144 +        /// The i.
 159.145 +        /// </param>
 159.146 +        public void WriteImage(Image i)
 159.147 +        {
 159.148 +        }
 159.149 +
 159.150 +        /// <summary>
 159.151 +        /// The write paragraph.
 159.152 +        /// </summary>
 159.153 +        /// <param name="p">
 159.154 +        /// The p.
 159.155 +        /// </param>
 159.156 +        public void WriteParagraph(Paragraph p)
 159.157 +        {
 159.158 +            foreach (string line in p.Text.SplitLines(this.MaxLineLength))
 159.159 +            {
 159.160 +                WriteLine(line);
 159.161 +            }
 159.162 +
 159.163 +            this.WriteLine();
 159.164 +        }
 159.165 +
 159.166 +        /// <summary>
 159.167 +        /// The write plot.
 159.168 +        /// </summary>
 159.169 +        /// <param name="plot">
 159.170 +        /// The plot.
 159.171 +        /// </param>
 159.172 +        public void WritePlot(PlotFigure plot)
 159.173 +        {
 159.174 +        }
 159.175 +
 159.176 +        /// <summary>
 159.177 +        /// The write report.
 159.178 +        /// </summary>
 159.179 +        /// <param name="report">
 159.180 +        /// The report.
 159.181 +        /// </param>
 159.182 +        /// <param name="reportStyle">
 159.183 +        /// The style.
 159.184 +        /// </param>
 159.185 +        public void WriteReport(Report report, ReportStyle reportStyle)
 159.186 +        {
 159.187 +            report.Write(this);
 159.188 +        }
 159.189 +
 159.190 +        /// <summary>
 159.191 +        /// The write table.
 159.192 +        /// </summary>
 159.193 +        /// <param name="t">
 159.194 +        /// The t.
 159.195 +        /// </param>
 159.196 +        public void WriteTable(Table t)
 159.197 +        {
 159.198 +            this.tableCounter++;
 159.199 +            this.WriteLine(string.Format("Table {0}. {1}", this.tableCounter, t.Caption));
 159.200 +            this.WriteLine();
 159.201 +            int rows = t.Rows.Count;
 159.202 +            int cols = t.Columns.Count;
 159.203 +
 159.204 +            var columnWidth = new int[cols];
 159.205 +            int totalLength = 0;
 159.206 +            for (int j = 0; j < cols; j++)
 159.207 +            {
 159.208 +                columnWidth[j] = 0;
 159.209 +                foreach (var tr in t.Rows)
 159.210 +                {
 159.211 +                    TableCell cell = tr.Cells[j];
 159.212 +                    string text = cell.Content;
 159.213 +                    columnWidth[j] = Math.Max(columnWidth[j], text != null ? text.Length : 0);
 159.214 +                }
 159.215 +
 159.216 +                totalLength += columnWidth[j];
 159.217 +            }
 159.218 +
 159.219 +            // WriteLine("-".Repeat(totalLength));
 159.220 +            foreach (var tr in t.Rows)
 159.221 +            {
 159.222 +                for (int j = 0; j < cols; j++)
 159.223 +                {
 159.224 +                    TableCell cell = tr.Cells[j];
 159.225 +                    string text = cell.Content;
 159.226 +                    bool isHeader = tr.IsHeader || t.Columns[j].IsHeader;
 159.227 +                    this.Write(GetCellText(j, cols, PadString(text, t.Columns[j].Alignment, columnWidth[j]), isHeader));
 159.228 +                }
 159.229 +
 159.230 +                this.WriteLine();
 159.231 +            }
 159.232 +
 159.233 +            this.WriteLine();
 159.234 +        }
 159.235 +
 159.236 +        /// <summary>
 159.237 +        /// The get cell text.
 159.238 +        /// </summary>
 159.239 +        /// <param name="i">
 159.240 +        /// The i.
 159.241 +        /// </param>
 159.242 +        /// <param name="count">
 159.243 +        /// The count.
 159.244 +        /// </param>
 159.245 +        /// <param name="p">
 159.246 +        /// The p.
 159.247 +        /// </param>
 159.248 +        /// <param name="isHeader">
 159.249 +        /// The is header.
 159.250 +        /// </param>
 159.251 +        /// <returns>
 159.252 +        /// The get cell text.
 159.253 +        /// </returns>
 159.254 +        private static string GetCellText(int i, int count, string p, bool isHeader)
 159.255 +        {
 159.256 +            if (i == 0)
 159.257 +            {
 159.258 +                p = isHeader ? TableHeaderRowStart : TableRowStart + p;
 159.259 +            }
 159.260 +
 159.261 +            if (i + 1 < count)
 159.262 +            {
 159.263 +                p += isHeader ? TableHeaderCellSeparator : TableCellSeparator;
 159.264 +            }
 159.265 +
 159.266 +            if (i == count - 1)
 159.267 +            {
 159.268 +                p += isHeader ? TableHeaderRowEnd : TableRowEnd;
 159.269 +            }
 159.270 +
 159.271 +            return p;
 159.272 +        }
 159.273 +
 159.274 +        /// <summary>
 159.275 +        /// The pad string.
 159.276 +        /// </summary>
 159.277 +        /// <param name="text">
 159.278 +        /// The text.
 159.279 +        /// </param>
 159.280 +        /// <param name="alignment">
 159.281 +        /// The alignment.
 159.282 +        /// </param>
 159.283 +        /// <param name="width">
 159.284 +        /// The width.
 159.285 +        /// </param>
 159.286 +        /// <returns>
 159.287 +        /// The pad string.
 159.288 +        /// </returns>
 159.289 +        private static string PadString(string text, Alignment alignment, int width)
 159.290 +        {
 159.291 +            if (text == null)
 159.292 +            {
 159.293 +                return string.Empty.PadLeft(width);
 159.294 +            }
 159.295 +
 159.296 +            switch (alignment)
 159.297 +            {
 159.298 +                case Alignment.Left:
 159.299 +                    return text.PadRight(width);
 159.300 +                case Alignment.Right:
 159.301 +                    return text.PadLeft(width);
 159.302 +                case Alignment.Center:
 159.303 +                    text = text.PadRight((text.Length + width) / 2);
 159.304 +                    return text.PadLeft(width);
 159.305 +            }
 159.306 +
 159.307 +            return null;
 159.308 +        }
 159.309 +
 159.310 +    }
 159.311 +}
 159.312 \ No newline at end of file
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/External/OxyPlot/OxyPlot/Series/AreaSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   160.3 @@ -0,0 +1,295 @@
   160.4 +// --------------------------------------------------------------------------------------------------------------------
   160.5 +// <copyright file="AreaSeries.cs" company="OxyPlot">
   160.6 +//   The MIT License (MIT)
   160.7 +//
   160.8 +//   Copyright (c) 2012 Oystein Bjorke
   160.9 +//
  160.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  160.11 +//   copy of this software and associated documentation files (the
  160.12 +//   "Software"), to deal in the Software without restriction, including
  160.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  160.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  160.15 +//   permit persons to whom the Software is furnished to do so, subject to
  160.16 +//   the following conditions:
  160.17 +//
  160.18 +//   The above copyright notice and this permission notice shall be included
  160.19 +//   in all copies or substantial portions of the Software.
  160.20 +//
  160.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  160.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  160.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  160.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  160.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  160.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  160.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  160.28 +// </copyright>
  160.29 +// <summary>
  160.30 +//   Represents an area series that fills the polygon defined by one or two sets of points.
  160.31 +// </summary>
  160.32 +// --------------------------------------------------------------------------------------------------------------------
  160.33 +namespace OxyPlot.Series
  160.34 +{
  160.35 +    using System;
  160.36 +    using System.Collections.Generic;
  160.37 +
  160.38 +    /// <summary>
  160.39 +    /// Represents an area series that fills the polygon defined by two sets of points or one set of points and a constant.
  160.40 +    /// </summary>
  160.41 +    public class AreaSeries : LineSeries
  160.42 +    {
  160.43 +        /// <summary>
  160.44 +        /// The second list of points.
  160.45 +        /// </summary>
  160.46 +        private readonly List<IDataPoint> points2 = new List<IDataPoint>();
  160.47 +
  160.48 +        /// <summary>
  160.49 +        /// Initializes a new instance of the <see cref = "AreaSeries" /> class.
  160.50 +        /// </summary>
  160.51 +        public AreaSeries()
  160.52 +        {
  160.53 +            this.Reverse2 = true;
  160.54 +        }
  160.55 +
  160.56 +        /// <summary>
  160.57 +        /// Gets or sets a constant value for the area definition.
  160.58 +        /// This is used if DataFieldBase and BaselineValues are null.
  160.59 +        /// </summary>
  160.60 +        /// <value>The baseline.</value>
  160.61 +        public double ConstantY2 { get; set; }
  160.62 +
  160.63 +        /// <summary>
  160.64 +        /// Gets or sets the second X data field.
  160.65 +        /// </summary>
  160.66 +        public string DataFieldX2 { get; set; }
  160.67 +
  160.68 +        /// <summary>
  160.69 +        /// Gets or sets the second Y data field.
  160.70 +        /// </summary>
  160.71 +        public string DataFieldY2 { get; set; }
  160.72 +
  160.73 +        /// <summary>
  160.74 +        /// Gets or sets the area fill color.
  160.75 +        /// </summary>
  160.76 +        /// <value>The fill.</value>
  160.77 +        public OxyColor Fill { get; set; }
  160.78 +
  160.79 +        /// <summary>
  160.80 +        /// Gets the second list of points.
  160.81 +        /// </summary>
  160.82 +        /// <value>The second list of points.</value>
  160.83 +        public List<IDataPoint> Points2
  160.84 +        {
  160.85 +            get
  160.86 +            {
  160.87 +                return this.points2;
  160.88 +            }
  160.89 +        }
  160.90 +
  160.91 +        /// <summary>
  160.92 +        /// Gets or sets a value indicating whether the second
  160.93 +        /// data collection should be reversed.
  160.94 +        /// The first dataset is not reversed, and normally
  160.95 +        /// the second dataset should be reversed to get a
  160.96 +        /// closed polygon.
  160.97 +        /// </summary>
  160.98 +        public bool Reverse2 { get; set; }
  160.99 +
 160.100 +        /// <summary>
 160.101 +        /// Gets the nearest point.
 160.102 +        /// </summary>
 160.103 +        /// <param name="point">The point.</param>
 160.104 +        /// <param name="interpolate">interpolate if set to <c>true</c> .</param>
 160.105 +        /// <returns>A TrackerHitResult for the current hit.</returns>
 160.106 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 160.107 +        {
 160.108 +            if (interpolate)
 160.109 +            {
 160.110 +                var r1 = this.GetNearestInterpolatedPointInternal(this.Points, point);
 160.111 +                if (r1 != null)
 160.112 +                {
 160.113 +                    return r1;
 160.114 +                }
 160.115 +
 160.116 +                var r2 = this.GetNearestInterpolatedPointInternal(this.points2, point);
 160.117 +                if (r2 != null)
 160.118 +                {
 160.119 +                    return r2;
 160.120 +                }
 160.121 +            }
 160.122 +            else
 160.123 +            {
 160.124 +                var result1 = this.GetNearestPointInternal(this.Points, point);
 160.125 +                var result2 = this.GetNearestPointInternal(this.points2, point);
 160.126 +
 160.127 +                if (result1 != null && result2 != null)
 160.128 +                {
 160.129 +                    double dist1 = result1.Position.DistanceTo(point);
 160.130 +                    double dist2 = result2.Position.DistanceTo(point);
 160.131 +                    return dist1 < dist2 ? result1 : result2;
 160.132 +                }
 160.133 +
 160.134 +                if (result1 != null)
 160.135 +                {
 160.136 +                    return result1;
 160.137 +                }
 160.138 +
 160.139 +                if (result2 != null)
 160.140 +                {
 160.141 +                    return result2;
 160.142 +                }
 160.143 +            }
 160.144 +
 160.145 +            return null;
 160.146 +        }
 160.147 +
 160.148 +        /// <summary>
 160.149 +        /// Renders the series on the specified rendering context.
 160.150 +        /// </summary>
 160.151 +        /// <param name="rc">The rendering context.</param>
 160.152 +        /// <param name="model">The owner plot model.</param>
 160.153 +        public override void Render(IRenderContext rc, PlotModel model)
 160.154 +        {
 160.155 +            if (this.Points.Count == 0)
 160.156 +            {
 160.157 +                return;
 160.158 +            }
 160.159 +
 160.160 +            base.VerifyAxes();
 160.161 +
 160.162 +            double minDistSquared = this.MinimumSegmentLength * this.MinimumSegmentLength;
 160.163 +
 160.164 +            var clippingRect = this.GetClippingRect();
 160.165 +
 160.166 +            // Transform all points to screen coordinates
 160.167 +            var points = this.Points;
 160.168 +            int n0 = points.Count;
 160.169 +            IList<ScreenPoint> pts0 = new ScreenPoint[n0];
 160.170 +            for (int i = 0; i < n0; i++)
 160.171 +            {
 160.172 +                pts0[i] = this.XAxis.Transform(points[i].X, points[i].Y, this.YAxis);
 160.173 +            }
 160.174 +
 160.175 +            int n1 = this.points2.Count;
 160.176 +            IList<ScreenPoint> pts1 = new ScreenPoint[n1];
 160.177 +            for (int i = 0; i < n1; i++)
 160.178 +            {
 160.179 +                int j = this.Reverse2 ? n1 - 1 - i : i;
 160.180 +                pts1[j] = this.XAxis.Transform(this.points2[i].X, this.points2[i].Y, this.YAxis);
 160.181 +            }
 160.182 +
 160.183 +            if (this.Smooth)
 160.184 +            {
 160.185 +                var rpts0 = ScreenPointHelper.ResamplePoints(pts0, this.MinimumSegmentLength);
 160.186 +                var rpts1 = ScreenPointHelper.ResamplePoints(pts1, this.MinimumSegmentLength);
 160.187 +
 160.188 +                pts0 = CanonicalSplineHelper.CreateSpline(rpts0, 0.5, null, false, 0.25);
 160.189 +                pts1 = CanonicalSplineHelper.CreateSpline(rpts1, 0.5, null, false, 0.25);
 160.190 +            }
 160.191 +
 160.192 +            // draw the clipped lines
 160.193 +            rc.DrawClippedLine(
 160.194 +                pts0,
 160.195 +                clippingRect,
 160.196 +                minDistSquared,
 160.197 +                this.GetSelectableColor(this.ActualColor),
 160.198 +                this.StrokeThickness,
 160.199 +                this.ActualLineStyle,
 160.200 +                this.LineJoin,
 160.201 +                false);
 160.202 +            rc.DrawClippedLine(
 160.203 +                pts1,
 160.204 +                clippingRect,
 160.205 +                minDistSquared,
 160.206 +                this.GetSelectableColor(this.ActualColor),
 160.207 +                this.StrokeThickness,
 160.208 +                this.ActualLineStyle,
 160.209 +                this.LineJoin,
 160.210 +                false);
 160.211 +
 160.212 +            // combine the two lines and draw the clipped area
 160.213 +            var pts = new List<ScreenPoint>();
 160.214 +            pts.AddRange(pts1);
 160.215 +            pts.AddRange(pts0);
 160.216 +
 160.217 +            // pts = SutherlandHodgmanClipping.ClipPolygon(clippingRect, pts);
 160.218 +            rc.DrawClippedPolygon(pts, clippingRect, minDistSquared, this.GetSelectableFillColor(this.Fill), null);
 160.219 +
 160.220 +            // draw the markers on top
 160.221 +            rc.DrawMarkers(
 160.222 +                pts0,
 160.223 +                clippingRect,
 160.224 +                this.MarkerType,
 160.225 +                null,
 160.226 +                new[] { this.MarkerSize },
 160.227 +                this.MarkerFill,
 160.228 +                this.MarkerStroke,
 160.229 +                this.MarkerStrokeThickness,
 160.230 +                1);
 160.231 +            rc.DrawMarkers(
 160.232 +                pts1,
 160.233 +                clippingRect,
 160.234 +                this.MarkerType,
 160.235 +                null,
 160.236 +                new[] { this.MarkerSize },
 160.237 +                this.MarkerFill,
 160.238 +                this.MarkerStroke,
 160.239 +                this.MarkerStrokeThickness,
 160.240 +                1);
 160.241 +        }
 160.242 +
 160.243 +        /// <summary>
 160.244 +        /// Renders the legend symbol for the line series on the
 160.245 +        /// specified rendering context.
 160.246 +        /// </summary>
 160.247 +        /// <param name="rc">
 160.248 +        /// The rendering context.
 160.249 +        /// </param>
 160.250 +        /// <param name="legendBox">
 160.251 +        /// The bounding rectangle of the legend box.
 160.252 +        /// </param>
 160.253 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 160.254 +        {
 160.255 +            double y0 = (legendBox.Top * 0.2) + (legendBox.Bottom * 0.8);
 160.256 +            double y1 = (legendBox.Top * 0.4) + (legendBox.Bottom * 0.6);
 160.257 +            double y2 = (legendBox.Top * 0.8) + (legendBox.Bottom * 0.2);
 160.258 +
 160.259 +            var pts0 = new[] { new ScreenPoint(legendBox.Left, y0), new ScreenPoint(legendBox.Right, y0) };
 160.260 +            var pts1 = new[] { new ScreenPoint(legendBox.Right, y2), new ScreenPoint(legendBox.Left, y1) };
 160.261 +            var pts = new List<ScreenPoint>();
 160.262 +            pts.AddRange(pts0);
 160.263 +            pts.AddRange(pts1);
 160.264 +            var color = this.GetSelectableColor(this.ActualColor);
 160.265 +            rc.DrawLine(pts0, color, this.StrokeThickness, LineStyleHelper.GetDashArray(this.ActualLineStyle));
 160.266 +            rc.DrawLine(pts1, color, this.StrokeThickness, LineStyleHelper.GetDashArray(this.ActualLineStyle));
 160.267 +            rc.DrawPolygon(pts, this.GetSelectableFillColor(this.Fill), null);
 160.268 +        }
 160.269 +
 160.270 +        /// <summary>
 160.271 +        /// The update data.
 160.272 +        /// </summary>
 160.273 +        protected internal override void UpdateData()
 160.274 +        {
 160.275 +            base.UpdateData();
 160.276 +
 160.277 +            if (this.ItemsSource == null)
 160.278 +            {
 160.279 +                return;
 160.280 +            }
 160.281 +
 160.282 +            this.points2.Clear();
 160.283 +
 160.284 +            // Using reflection on DataFieldX2 and DataFieldY2
 160.285 +            this.AddDataPoints(this.points2, this.ItemsSource, this.DataFieldX2, this.DataFieldY2);
 160.286 +        }
 160.287 +
 160.288 +        /// <summary>
 160.289 +        /// The update max min.
 160.290 +        /// </summary>
 160.291 +        protected internal override void UpdateMaxMin()
 160.292 +        {
 160.293 +            base.UpdateMaxMin();
 160.294 +            this.InternalUpdateMaxMin(this.points2);
 160.295 +        }
 160.296 +
 160.297 +    }
 160.298 +}
 160.299 \ No newline at end of file
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/BarItem.cs	Sat Jun 08 16:53:22 2013 +0000
   161.3 @@ -0,0 +1,64 @@
   161.4 +// --------------------------------------------------------------------------------------------------------------------
   161.5 +// <copyright file="BarItem.cs" company="OxyPlot">
   161.6 +//   The MIT License (MIT)
   161.7 +//
   161.8 +//   Copyright (c) 2012 Oystein Bjorke
   161.9 +//
  161.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  161.11 +//   copy of this software and associated documentation files (the
  161.12 +//   "Software"), to deal in the Software without restriction, including
  161.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  161.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  161.15 +//   permit persons to whom the Software is furnished to do so, subject to
  161.16 +//   the following conditions:
  161.17 +//
  161.18 +//   The above copyright notice and this permission notice shall be included
  161.19 +//   in all copies or substantial portions of the Software.
  161.20 +//
  161.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  161.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  161.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  161.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  161.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  161.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  161.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  161.28 +// </copyright>
  161.29 +// <summary>
  161.30 +//   Represents an item used in the BarSeries.
  161.31 +// </summary>
  161.32 +// --------------------------------------------------------------------------------------------------------------------
  161.33 +namespace OxyPlot.Series
  161.34 +{
  161.35 +    /// <summary>
  161.36 +    /// Represents an item used in the BarSeries.
  161.37 +    /// </summary>
  161.38 +    public class BarItem : BarItemBase
  161.39 +    {
  161.40 +        /// <summary>
  161.41 +        /// Initializes a new instance of the <see cref="BarItem"/> class.
  161.42 +        /// </summary>
  161.43 +        public BarItem()
  161.44 +        {
  161.45 +        }
  161.46 +
  161.47 +        /// <summary>
  161.48 +        /// Initializes a new instance of the <see cref="BarItem"/> class.
  161.49 +        /// </summary>
  161.50 +        /// <param name="value">
  161.51 +        /// The value.
  161.52 +        /// </param>
  161.53 +        /// <param name="categoryIndex">
  161.54 +        /// Index of the category.
  161.55 +        /// </param>
  161.56 +        /// <param name="color">
  161.57 +        /// The color.
  161.58 +        /// </param>
  161.59 +        public BarItem(double value, int categoryIndex = -1, OxyColor color = null)
  161.60 +        {
  161.61 +            this.Value = value;
  161.62 +            this.CategoryIndex = categoryIndex;
  161.63 +            this.Color = color;
  161.64 +        }
  161.65 +
  161.66 +    }
  161.67 +}
  161.68 \ No newline at end of file
   162.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   162.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/BarItemBase.cs	Sat Jun 08 16:53:22 2013 +0000
   162.3 @@ -0,0 +1,83 @@
   162.4 +// --------------------------------------------------------------------------------------------------------------------
   162.5 +// <copyright file="BarItemBase.cs" company="OxyPlot">
   162.6 +//   The MIT License (MIT)
   162.7 +//
   162.8 +//   Copyright (c) 2012 Oystein Bjorke
   162.9 +//
  162.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  162.11 +//   copy of this software and associated documentation files (the
  162.12 +//   "Software"), to deal in the Software without restriction, including
  162.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  162.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  162.15 +//   permit persons to whom the Software is furnished to do so, subject to
  162.16 +//   the following conditions:
  162.17 +//
  162.18 +//   The above copyright notice and this permission notice shall be included
  162.19 +//   in all copies or substantial portions of the Software.
  162.20 +//
  162.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  162.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  162.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  162.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  162.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  162.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  162.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  162.28 +// </copyright>
  162.29 +// <summary>
  162.30 +//   Represents an item used in the BarSeriesBase.
  162.31 +// </summary>
  162.32 +// --------------------------------------------------------------------------------------------------------------------
  162.33 +namespace OxyPlot.Series
  162.34 +{
  162.35 +    /// <summary>
  162.36 +    /// Represents an item used in the BarSeriesBase.
  162.37 +    /// </summary>
  162.38 +    public abstract class BarItemBase : CategorizedItem, ICodeGenerating
  162.39 +    {
  162.40 +        /// <summary>
  162.41 +        /// Initializes a new instance of the <see cref="BarItemBase"/> class. Initializes a new instance of the <see cref="BarItem"/> class.
  162.42 +        /// </summary>
  162.43 +        protected BarItemBase()
  162.44 +        {
  162.45 +            // Label = null;
  162.46 +            this.Value = double.NaN;
  162.47 +            this.Color = null;
  162.48 +        }
  162.49 +
  162.50 +        /// <summary>
  162.51 +        /// Gets or sets the color of the item.
  162.52 +        /// </summary>
  162.53 +        /// <remarks>
  162.54 +        /// If the color is not specified (default), the color of the series will be used.
  162.55 +        /// </remarks>
  162.56 +        public OxyColor Color { get; set; }
  162.57 +
  162.58 +        /// <summary>
  162.59 +        /// Gets or sets the value of the item.
  162.60 +        /// </summary>
  162.61 +        public double Value { get; set; }
  162.62 +
  162.63 +        /// <summary>
  162.64 +        /// Returns c# code that generates this instance.
  162.65 +        /// </summary>
  162.66 +        /// <returns>
  162.67 +        /// C# code.
  162.68 +        /// </returns>
  162.69 +        public virtual string ToCode()
  162.70 +        {
  162.71 +            if (this.Color != null)
  162.72 +            {
  162.73 +                return CodeGenerator.FormatConstructor(
  162.74 +                    this.GetType(), "{0},{1},{2}", this.Value, this.CategoryIndex, this.Color.ToCode());
  162.75 +            }
  162.76 +
  162.77 +            if (this.CategoryIndex != -1)
  162.78 +            {
  162.79 +                return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.Value, this.CategoryIndex);
  162.80 +            }
  162.81 +
  162.82 +            return CodeGenerator.FormatConstructor(this.GetType(), "{0}", this.Value);
  162.83 +        }
  162.84 +
  162.85 +    }
  162.86 +}
  162.87 \ No newline at end of file
   163.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   163.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/BarSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   163.3 @@ -0,0 +1,198 @@
   163.4 +// --------------------------------------------------------------------------------------------------------------------
   163.5 +// <copyright file="BarSeries.cs" company="OxyPlot">
   163.6 +//   The MIT License (MIT)
   163.7 +//
   163.8 +//   Copyright (c) 2012 Oystein Bjorke
   163.9 +//
  163.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  163.11 +//   copy of this software and associated documentation files (the
  163.12 +//   "Software"), to deal in the Software without restriction, including
  163.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  163.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  163.15 +//   permit persons to whom the Software is furnished to do so, subject to
  163.16 +//   the following conditions:
  163.17 +//
  163.18 +//   The above copyright notice and this permission notice shall be included
  163.19 +//   in all copies or substantial portions of the Software.
  163.20 +//
  163.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  163.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  163.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  163.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  163.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  163.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  163.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  163.28 +// </copyright>
  163.29 +// <summary>
  163.30 +//   Represents a series for clustered or stacked bar charts.
  163.31 +// </summary>
  163.32 +// --------------------------------------------------------------------------------------------------------------------
  163.33 +namespace OxyPlot.Series
  163.34 +{
  163.35 +    using System;
  163.36 +
  163.37 +    using OxyPlot.Axes;
  163.38 +
  163.39 +    /// <summary>
  163.40 +    /// Represents a series for clustered or stacked bar charts.
  163.41 +    /// </summary>
  163.42 +    public class BarSeries : BarSeriesBase<BarItem>
  163.43 +    {
  163.44 +        /// <summary>
  163.45 +        /// Initializes a new instance of the <see cref="BarSeries"/> class.
  163.46 +        /// </summary>
  163.47 +        public BarSeries()
  163.48 +        {
  163.49 +            this.BarWidth = 1;
  163.50 +        }
  163.51 +
  163.52 +        /// <summary>
  163.53 +        /// Gets or sets the width (height) of the bars.
  163.54 +        /// </summary>
  163.55 +        /// <value>
  163.56 +        /// The width of the bars.
  163.57 +        /// </value>
  163.58 +        public double BarWidth { get; set; }
  163.59 +
  163.60 +        /// <summary>
  163.61 +        /// Gets or sets the width of the columns/bars (as a fraction of the available space).
  163.62 +        /// </summary>
  163.63 +        /// <returns>
  163.64 +        /// The fractional width.
  163.65 +        /// </returns>
  163.66 +        /// <value>
  163.67 +        /// The width of the bars.
  163.68 +        /// </value>
  163.69 +        /// <remarks>
  163.70 +        /// The available space will be determined by the GapWidth of the CategoryAxis used by this series.
  163.71 +        /// </remarks>
  163.72 +        internal override double GetBarWidth()
  163.73 +        {
  163.74 +            return this.BarWidth;
  163.75 +        }
  163.76 +
  163.77 +        /// <summary>
  163.78 +        /// Gets the actual width/height of the items of this series.
  163.79 +        /// </summary>
  163.80 +        /// <returns>
  163.81 +        /// The width or height.
  163.82 +        /// </returns>
  163.83 +        /// <remarks>
  163.84 +        /// The actual width is also influenced by the GapWidth of the CategoryAxis used by this series.
  163.85 +        /// </remarks>
  163.86 +        protected override double GetActualBarWidth()
  163.87 +        {
  163.88 +            var categoryAxis = this.GetCategoryAxis();
  163.89 +            return this.BarWidth / (1 + categoryAxis.GapWidth) / categoryAxis.MaxWidth;
  163.90 +        }
  163.91 +
  163.92 +        /// <summary>
  163.93 +        /// Gets the category axis.
  163.94 +        /// </summary>
  163.95 +        /// <returns>
  163.96 +        /// The category axis.
  163.97 +        /// </returns>
  163.98 +        protected override CategoryAxis GetCategoryAxis()
  163.99 +        {
 163.100 +            if (!(this.YAxis is CategoryAxis))
 163.101 +            {
 163.102 +                throw new Exception(
 163.103 +                    "A BarSeries requires a CategoryAxis on the y-axis. Use a ColumnSeries if you want vertical bars.");
 163.104 +            }
 163.105 +
 163.106 +            return this.YAxis as CategoryAxis;
 163.107 +        }
 163.108 +
 163.109 +        /// <summary>
 163.110 +        /// Gets the rectangle for the specified values.
 163.111 +        /// </summary>
 163.112 +        /// <param name="baseValue">
 163.113 +        /// The base value of the bar
 163.114 +        /// </param>
 163.115 +        /// <param name="topValue">
 163.116 +        /// The top value of the bar
 163.117 +        /// </param>
 163.118 +        /// <param name="beginValue">
 163.119 +        /// The begin value of the bar
 163.120 +        /// </param>
 163.121 +        /// <param name="endValue">
 163.122 +        /// The end value of the bar
 163.123 +        /// </param>
 163.124 +        /// <returns>
 163.125 +        /// The rectangle.
 163.126 +        /// </returns>
 163.127 +        protected override OxyRect GetRectangle(double baseValue, double topValue, double beginValue, double endValue)
 163.128 +        {
 163.129 +            return OxyRect.Create(this.Transform(baseValue, beginValue), this.Transform(topValue, endValue));
 163.130 +        }
 163.131 +
 163.132 +        /// <summary>
 163.133 +        /// Gets the value axis.
 163.134 +        /// </summary>
 163.135 +        /// <returns>
 163.136 +        /// The value axis.
 163.137 +        /// </returns>
 163.138 +        protected override Axis GetValueAxis()
 163.139 +        {
 163.140 +            return this.XAxis;
 163.141 +        }
 163.142 +
 163.143 +        /// <summary>
 163.144 +        /// Draws the label.
 163.145 +        /// </summary>
 163.146 +        /// <param name="rc">
 163.147 +        /// The render context.
 163.148 +        /// </param>
 163.149 +        /// <param name="clippingRect">
 163.150 +        /// The clipping rect.
 163.151 +        /// </param>
 163.152 +        /// <param name="rect">
 163.153 +        /// The rect.
 163.154 +        /// </param>
 163.155 +        /// <param name="value">
 163.156 +        /// The value.
 163.157 +        /// </param>
 163.158 +        /// <param name="i">
 163.159 +        /// The i.
 163.160 +        /// </param>
 163.161 +        protected override void RenderLabel(IRenderContext rc, OxyRect clippingRect, OxyRect rect, double value, int i)
 163.162 +        {
 163.163 +            var s = StringHelper.Format(
 163.164 +                this.ActualCulture, this.LabelFormatString, this.GetItem(this.ValidItemsIndexInversion[i]), value);
 163.165 +            HorizontalAlignment ha;
 163.166 +            ScreenPoint pt;
 163.167 +            switch (this.LabelPlacement)
 163.168 +            {
 163.169 +                case LabelPlacement.Inside:
 163.170 +                    pt = new ScreenPoint(rect.Right - this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 163.171 +                    ha = HorizontalAlignment.Right;
 163.172 +                    break;
 163.173 +                case LabelPlacement.Middle:
 163.174 +                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2);
 163.175 +                    ha = HorizontalAlignment.Center;
 163.176 +                    break;
 163.177 +                case LabelPlacement.Base:
 163.178 +                    pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 163.179 +                    ha = HorizontalAlignment.Left;
 163.180 +                    break;
 163.181 +                default: // Outside
 163.182 +                    pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 163.183 +                    ha = HorizontalAlignment.Left;
 163.184 +                    break;
 163.185 +            }
 163.186 +
 163.187 +            rc.DrawClippedText(
 163.188 +                clippingRect,
 163.189 +                pt,
 163.190 +                s,
 163.191 +                this.ActualTextColor,
 163.192 +                this.ActualFont,
 163.193 +                this.ActualFontSize,
 163.194 +                this.ActualFontWeight,
 163.195 +                0,
 163.196 +                ha,
 163.197 +                VerticalAlignment.Middle);
 163.198 +        }
 163.199 +
 163.200 +    }
 163.201 +}
 163.202 \ No newline at end of file
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/BarSeriesBase.cs	Sat Jun 08 16:53:22 2013 +0000
   164.3 @@ -0,0 +1,603 @@
   164.4 +// --------------------------------------------------------------------------------------------------------------------
   164.5 +// <copyright file="BarSeriesBase.cs" company="OxyPlot">
   164.6 +//   The MIT License (MIT)
   164.7 +//
   164.8 +//   Copyright (c) 2012 Oystein Bjorke
   164.9 +//
  164.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  164.11 +//   copy of this software and associated documentation files (the
  164.12 +//   "Software"), to deal in the Software without restriction, including
  164.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  164.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  164.15 +//   permit persons to whom the Software is furnished to do so, subject to
  164.16 +//   the following conditions:
  164.17 +//
  164.18 +//   The above copyright notice and this permission notice shall be included
  164.19 +//   in all copies or substantial portions of the Software.
  164.20 +//
  164.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  164.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  164.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  164.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  164.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  164.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  164.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  164.28 +// </copyright>
  164.29 +// <summary>
  164.30 +//   Base class for BarSeries and ColumnSeries.
  164.31 +// </summary>
  164.32 +// --------------------------------------------------------------------------------------------------------------------
  164.33 +namespace OxyPlot.Series
  164.34 +{
  164.35 +    using System;
  164.36 +    using System.Collections.Generic;
  164.37 +    using System.Linq;
  164.38 +
  164.39 +    using OxyPlot.Axes;
  164.40 +
  164.41 +    /// <summary>
  164.42 +    /// Base class for BarSeries and ColumnSeries.
  164.43 +    /// </summary>
  164.44 +    public abstract class BarSeriesBase : CategorizedSeries, IStackableSeries
  164.45 +    {
  164.46 +        /// <summary>
  164.47 +        /// The default fill color.
  164.48 +        /// </summary>
  164.49 +        private OxyColor defaultFillColor;
  164.50 +
  164.51 +        /// <summary>
  164.52 +        /// Initializes a new instance of the <see cref="BarSeriesBase"/> class.
  164.53 +        /// </summary>
  164.54 +        protected BarSeriesBase()
  164.55 +        {
  164.56 +            this.StrokeColor = OxyColors.Black;
  164.57 +            this.StrokeThickness = 0;
  164.58 +            this.TrackerFormatString = "{0}, {1}: {2}";
  164.59 +            this.LabelMargin = 2;
  164.60 +            this.StackGroup = string.Empty;
  164.61 +        }
  164.62 +
  164.63 +        /// <summary>
  164.64 +        /// Gets or sets the base value.
  164.65 +        /// </summary>
  164.66 +        /// <value>
  164.67 +        /// The base value.
  164.68 +        /// </value>
  164.69 +        public double BaseValue { get; set; }
  164.70 +
  164.71 +        /// <summary>
  164.72 +        /// Gets or sets the color field.
  164.73 +        /// </summary>
  164.74 +        public string ColorField { get; set; }
  164.75 +
  164.76 +        /// <summary>
  164.77 +        /// Gets or sets the color of the interior of the bars.
  164.78 +        /// </summary>
  164.79 +        /// <value>
  164.80 +        /// The color.
  164.81 +        /// </value>
  164.82 +        public OxyColor FillColor { get; set; }
  164.83 +
  164.84 +        /// <summary>
  164.85 +        /// Gets the actual fill color.
  164.86 +        /// </summary>
  164.87 +        /// <value>The actual color.</value>
  164.88 +        public OxyColor ActualFillColor
  164.89 +        {
  164.90 +            get { return this.FillColor ?? this.defaultFillColor; }
  164.91 +        }
  164.92 +
  164.93 +        /// <summary>
  164.94 +        /// Gets or sets a value indicating whether this bar series is stacked.
  164.95 +        /// </summary>
  164.96 +        public bool IsStacked { get; set; }
  164.97 +
  164.98 +        /// <summary>
  164.99 +        /// Gets or sets the label format string.
 164.100 +        /// </summary>
 164.101 +        /// <value>
 164.102 +        /// The label format string.
 164.103 +        /// </value>
 164.104 +        public string LabelFormatString { get; set; }
 164.105 +
 164.106 +        /// <summary>
 164.107 +        /// Gets or sets the label margins.
 164.108 +        /// </summary>
 164.109 +        public double LabelMargin { get; set; }
 164.110 +
 164.111 +        /// <summary>
 164.112 +        /// Gets or sets label placements.
 164.113 +        /// </summary>
 164.114 +        public LabelPlacement LabelPlacement { get; set; }
 164.115 +
 164.116 +        /// <summary>
 164.117 +        /// Gets or sets the color of the interior of the bars when the value is negative.
 164.118 +        /// </summary>
 164.119 +        /// <value>
 164.120 +        /// The color.
 164.121 +        /// </value>
 164.122 +        public OxyColor NegativeFillColor { get; set; }
 164.123 +
 164.124 +        /// <summary>
 164.125 +        /// Gets or sets the stack index indication to which stack the series belongs. Default is 0. Hence, all stacked series belong to the same stack.
 164.126 +        /// </summary>
 164.127 +        public string StackGroup { get; set; }
 164.128 +
 164.129 +        /// <summary>
 164.130 +        /// Gets or sets the color of the border around the bars.
 164.131 +        /// </summary>
 164.132 +        /// <value>
 164.133 +        /// The color of the stroke.
 164.134 +        /// </value>
 164.135 +        public OxyColor StrokeColor { get; set; }
 164.136 +
 164.137 +        /// <summary>
 164.138 +        /// Gets or sets the thickness of the bar border strokes.
 164.139 +        /// </summary>
 164.140 +        /// <value>
 164.141 +        /// The stroke thickness.
 164.142 +        /// </value>
 164.143 +        public double StrokeThickness { get; set; }
 164.144 +
 164.145 +        /// <summary>
 164.146 +        /// Gets or sets the value field.
 164.147 +        /// </summary>
 164.148 +        public string ValueField { get; set; }
 164.149 +
 164.150 +        /// <summary>
 164.151 +        /// Gets or sets the valid items
 164.152 +        /// </summary>
 164.153 +        protected internal IList<BarItemBase> ValidItems { get; set; }
 164.154 +
 164.155 +        /// <summary>
 164.156 +        /// Gets or sets the dictionary which stores the index-inversion for the valid items
 164.157 +        /// </summary>
 164.158 +        protected internal Dictionary<int, int> ValidItemsIndexInversion { get; set; }
 164.159 +
 164.160 +        /// <summary>
 164.161 +        /// Gets or sets the actual rectangles for the bars.
 164.162 +        /// </summary>
 164.163 +        protected IList<OxyRect> ActualBarRectangles { get; set; }
 164.164 +
 164.165 +        /// <summary>
 164.166 +        /// Gets the nearest point.
 164.167 +        /// </summary>
 164.168 +        /// <param name="point">
 164.169 +        /// The point.
 164.170 +        /// </param>
 164.171 +        /// <param name="interpolate">
 164.172 +        /// interpolate if set to <c>true</c> .
 164.173 +        /// </param>
 164.174 +        /// <returns>
 164.175 +        /// A TrackerHitResult for the current hit.
 164.176 +        /// </returns>
 164.177 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 164.178 +        {
 164.179 +            if (this.ActualBarRectangles == null || this.ValidItems == null)
 164.180 +            {
 164.181 +                return null;
 164.182 +            }
 164.183 +
 164.184 +            var i = 0;
 164.185 +            foreach (var rectangle in this.ActualBarRectangles)
 164.186 +            {
 164.187 +                if (rectangle.Contains(point))
 164.188 +                {
 164.189 +                    var categoryIndex = this.ValidItems[i].GetCategoryIndex(i);
 164.190 +
 164.191 +                    var dp = new DataPoint(categoryIndex, this.ValidItems[i].Value);
 164.192 +                    var item = this.GetItem(this.ValidItemsIndexInversion[i]);
 164.193 +                    var text = this.GetTrackerText(item, categoryIndex);
 164.194 +                    return new TrackerHitResult(this, dp, point, item, i, text);
 164.195 +                }
 164.196 +
 164.197 +                i++;
 164.198 +            }
 164.199 +
 164.200 +            return null;
 164.201 +        }
 164.202 +
 164.203 +        /// <summary>
 164.204 +        /// Renders the series on the specified rendering context.
 164.205 +        /// </summary>
 164.206 +        /// <param name="rc">
 164.207 +        /// The rendering context.
 164.208 +        /// </param>
 164.209 +        /// <param name="model">
 164.210 +        /// The model.
 164.211 +        /// </param>
 164.212 +        public override void Render(IRenderContext rc, PlotModel model)
 164.213 +        {
 164.214 +            this.ActualBarRectangles = new List<OxyRect>();
 164.215 +
 164.216 +            if (this.ValidItems == null || this.ValidItems.Count == 0)
 164.217 +            {
 164.218 +                return;
 164.219 +            }
 164.220 +
 164.221 +            var clippingRect = this.GetClippingRect();
 164.222 +            var categoryAxis = this.GetCategoryAxis();
 164.223 +
 164.224 +            var actualBarWidth = this.GetActualBarWidth();
 164.225 +            var stackIndex = this.IsStacked ? categoryAxis.StackIndexMapping[this.StackGroup] : 0;
 164.226 +            for (var i = 0; i < this.ValidItems.Count; i++)
 164.227 +            {
 164.228 +                var item = this.ValidItems[i];
 164.229 +                var categoryIndex = this.ValidItems[i].GetCategoryIndex(i);
 164.230 +
 164.231 +                var value = item.Value;
 164.232 +
 164.233 +                // Get base- and topValue
 164.234 +                var baseValue = double.NaN;
 164.235 +                if (this.IsStacked)
 164.236 +                {
 164.237 +                    baseValue = value < 0
 164.238 +                                    ? categoryAxis.NegativeBaseValues[stackIndex, categoryIndex]
 164.239 +                                    : categoryAxis.PositiveBaseValues[stackIndex, categoryIndex];
 164.240 +                }
 164.241 +
 164.242 +                if (double.IsNaN(baseValue))
 164.243 +                {
 164.244 +                    baseValue = this.BaseValue;
 164.245 +                }
 164.246 +
 164.247 +                var topValue = this.IsStacked ? baseValue + value : value;
 164.248 +
 164.249 +                // Calculate offset
 164.250 +                double categoryValue;
 164.251 +                if (this.IsStacked)
 164.252 +                {
 164.253 +                    categoryValue = categoryAxis.GetCategoryValue(categoryIndex, stackIndex, actualBarWidth);
 164.254 +                }
 164.255 +                else
 164.256 +                {
 164.257 +                    categoryValue = categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex];
 164.258 +                }
 164.259 +
 164.260 +                if (this.IsStacked)
 164.261 +                {
 164.262 +                    if (value < 0)
 164.263 +                    {
 164.264 +                        categoryAxis.NegativeBaseValues[stackIndex, categoryIndex] = topValue;
 164.265 +                    }
 164.266 +                    else
 164.267 +                    {
 164.268 +                        categoryAxis.PositiveBaseValues[stackIndex, categoryIndex] = topValue;
 164.269 +                    }
 164.270 +                }
 164.271 +
 164.272 +                var rect = this.GetRectangle(baseValue, topValue, categoryValue, categoryValue + actualBarWidth);
 164.273 +                this.ActualBarRectangles.Add(rect);
 164.274 +
 164.275 +                this.RenderItem(rc, clippingRect, topValue, categoryValue, actualBarWidth, item, rect);
 164.276 +
 164.277 +                if (this.LabelFormatString != null)
 164.278 +                {
 164.279 +                    this.RenderLabel(rc, clippingRect, rect, value, i);
 164.280 +                }
 164.281 +
 164.282 +                if (!this.IsStacked)
 164.283 +                {
 164.284 +                    categoryAxis.BarOffset[categoryIndex] += actualBarWidth;
 164.285 +                }
 164.286 +            }
 164.287 +        }
 164.288 +
 164.289 +        /// <summary>
 164.290 +        /// Renders the legend symbol on the specified rendering context.
 164.291 +        /// </summary>
 164.292 +        /// <param name="rc">
 164.293 +        /// The rendering context.
 164.294 +        /// </param>
 164.295 +        /// <param name="legendBox">
 164.296 +        /// The legend rectangle.
 164.297 +        /// </param>
 164.298 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 164.299 +        {
 164.300 +            var xmid = (legendBox.Left + legendBox.Right) / 2;
 164.301 +            var ymid = (legendBox.Top + legendBox.Bottom) / 2;
 164.302 +            var height = (legendBox.Bottom - legendBox.Top) * 0.8;
 164.303 +            var width = height;
 164.304 +            rc.DrawRectangleAsPolygon(
 164.305 +                new OxyRect(xmid - (0.5 * width), ymid - (0.5 * height), width, height),
 164.306 +                this.GetSelectableColor(this.ActualFillColor),
 164.307 +                this.StrokeColor,
 164.308 +                this.StrokeThickness);
 164.309 +        }
 164.310 +
 164.311 +        /// <summary>
 164.312 +        /// Check if the data series is using the specified axis.
 164.313 +        /// </summary>
 164.314 +        /// <param name="axis">
 164.315 +        /// An axis which should be checked if used
 164.316 +        /// </param>
 164.317 +        /// <returns>
 164.318 +        /// True if the axis is in use.
 164.319 +        /// </returns>
 164.320 +        protected internal override bool IsUsing(Axis axis)
 164.321 +        {
 164.322 +            return this.XAxis == axis || this.YAxis == axis;
 164.323 +        }
 164.324 +
 164.325 +        /// <summary>
 164.326 +        /// The set default values.
 164.327 +        /// </summary>
 164.328 +        /// <param name="model">
 164.329 +        /// The model.
 164.330 +        /// </param>
 164.331 +        protected internal override void SetDefaultValues(PlotModel model)
 164.332 +        {
 164.333 +            if (this.FillColor == null)
 164.334 +            {
 164.335 +                this.defaultFillColor = model.GetDefaultColor();
 164.336 +            }
 164.337 +        }
 164.338 +
 164.339 +        /// <summary>
 164.340 +        /// The update axis max min.
 164.341 +        /// </summary>
 164.342 +        protected internal override void UpdateAxisMaxMin()
 164.343 +        {
 164.344 +            var valueAxis = this.GetValueAxis();
 164.345 +            if (valueAxis.IsVertical())
 164.346 +            {
 164.347 +                valueAxis.Include(this.MinY);
 164.348 +                valueAxis.Include(this.MaxY);
 164.349 +            }
 164.350 +            else
 164.351 +            {
 164.352 +                valueAxis.Include(this.MinX);
 164.353 +                valueAxis.Include(this.MaxX);
 164.354 +            }
 164.355 +        }
 164.356 +
 164.357 +        /// <summary>
 164.358 +        /// Updates the maximum/minimum value on the value axis from the bar values.
 164.359 +        /// </summary>
 164.360 +        protected internal override void UpdateMaxMin()
 164.361 +        {
 164.362 +            base.UpdateMaxMin();
 164.363 +
 164.364 +            if (this.ValidItems == null || this.ValidItems.Count == 0)
 164.365 +            {
 164.366 +                return;
 164.367 +            }
 164.368 +
 164.369 +            var categoryAxis = this.GetCategoryAxis();
 164.370 +
 164.371 +            double minValue = double.MaxValue, maxValue = double.MinValue;
 164.372 +            if (this.IsStacked)
 164.373 +            {
 164.374 +                var labels = this.GetCategoryAxis().Labels;
 164.375 +                for (var i = 0; i < labels.Count; i++)
 164.376 +                {
 164.377 +                    int j = 0;
 164.378 +                    var values =
 164.379 +                        this.ValidItems.Where(item => item.GetCategoryIndex(j++) == i).Select(item => item.Value).Concat(new[] { 0d }).ToList();
 164.380 +                    var minTemp = values.Where(v => v <= 0).Sum();
 164.381 +                    var maxTemp = values.Where(v => v >= 0).Sum();
 164.382 +
 164.383 +                    int stackIndex = categoryAxis.StackIndexMapping[this.StackGroup];
 164.384 +                    var stackedMinValue = categoryAxis.MinValue[stackIndex, i];
 164.385 +                    if (!double.IsNaN(stackedMinValue))
 164.386 +                    {
 164.387 +                        minTemp += stackedMinValue;
 164.388 +                    }
 164.389 +
 164.390 +                    categoryAxis.MinValue[stackIndex, i] = minTemp;
 164.391 +
 164.392 +                    var stackedMaxValue = categoryAxis.MaxValue[stackIndex, i];
 164.393 +                    if (!double.IsNaN(stackedMaxValue))
 164.394 +                    {
 164.395 +                        maxTemp += stackedMaxValue;
 164.396 +                    }
 164.397 +
 164.398 +                    categoryAxis.MaxValue[stackIndex, i] = maxTemp;
 164.399 +
 164.400 +                    minValue = Math.Min(minValue, minTemp + this.BaseValue);
 164.401 +                    maxValue = Math.Max(maxValue, maxTemp + this.BaseValue);
 164.402 +                }
 164.403 +            }
 164.404 +            else
 164.405 +            {
 164.406 +                var values = this.ValidItems.Select(item => item.Value).Concat(new[] { 0d }).ToList();
 164.407 +                minValue = values.Min();
 164.408 +                maxValue = values.Max();
 164.409 +                if (this.BaseValue < minValue)
 164.410 +                {
 164.411 +                    minValue = this.BaseValue;
 164.412 +                }
 164.413 +
 164.414 +                if (this.BaseValue > maxValue)
 164.415 +                {
 164.416 +                    maxValue = this.BaseValue;
 164.417 +                }
 164.418 +            }
 164.419 +
 164.420 +            var valueAxis = this.GetValueAxis();
 164.421 +            if (valueAxis.IsVertical())
 164.422 +            {
 164.423 +                this.MinY = minValue;
 164.424 +                this.MaxY = maxValue;
 164.425 +            }
 164.426 +            else
 164.427 +            {
 164.428 +                this.MinX = minValue;
 164.429 +                this.MaxX = maxValue;
 164.430 +            }
 164.431 +        }
 164.432 +
 164.433 +        /// <summary>
 164.434 +        /// Updates the valid items
 164.435 +        /// </summary>
 164.436 +        protected internal override void UpdateValidData()
 164.437 +        {
 164.438 +            this.ValidItems = new List<BarItemBase>();
 164.439 +            this.ValidItemsIndexInversion = new Dictionary<int, int>();
 164.440 +            var categories = this.GetCategoryAxis().Labels.Count;
 164.441 +            var valueAxis = this.GetValueAxis();
 164.442 +
 164.443 +            int i = 0;
 164.444 +            foreach (var item in this.GetItems())
 164.445 +            {
 164.446 +                var barSeriesItem = item as BarItemBase;
 164.447 +
 164.448 +                if (barSeriesItem != null && item.GetCategoryIndex(i) < categories
 164.449 +                    && valueAxis.IsValidValue(barSeriesItem.Value))
 164.450 +                {
 164.451 +                    this.ValidItemsIndexInversion.Add(this.ValidItems.Count, i);
 164.452 +                    this.ValidItems.Add(barSeriesItem);
 164.453 +                }
 164.454 +
 164.455 +                i++;
 164.456 +            }
 164.457 +        }
 164.458 +
 164.459 +        /// <summary>
 164.460 +        /// Gets the rectangle for the specified values.
 164.461 +        /// </summary>
 164.462 +        /// <param name="baseValue">
 164.463 +        /// The base value of the bar
 164.464 +        /// </param>
 164.465 +        /// <param name="topValue">
 164.466 +        /// The top value of the bar
 164.467 +        /// </param>
 164.468 +        /// <param name="beginValue">
 164.469 +        /// The begin value of the bar
 164.470 +        /// </param>
 164.471 +        /// <param name="endValue">
 164.472 +        /// The end value of the bar
 164.473 +        /// </param>
 164.474 +        /// <returns>
 164.475 +        /// The rectangle.
 164.476 +        /// </returns>
 164.477 +        protected abstract OxyRect GetRectangle(double baseValue, double topValue, double beginValue, double endValue);
 164.478 +
 164.479 +        /// <summary>
 164.480 +        /// Gets the tracker text for the specified item.
 164.481 +        /// </summary>
 164.482 +        /// <param name="item">
 164.483 +        /// The item.
 164.484 +        /// </param>
 164.485 +        /// <param name="categoryIndex">
 164.486 +        /// Category index of the item.
 164.487 +        /// </param>
 164.488 +        /// <returns>
 164.489 +        /// The tracker text.
 164.490 +        /// </returns>
 164.491 +        protected virtual string GetTrackerText(object item, int categoryIndex)
 164.492 +        {
 164.493 +            var barItem = item as BarItemBase;
 164.494 +            if (barItem == null)
 164.495 +            {
 164.496 +                return null;
 164.497 +            }
 164.498 +
 164.499 +            var categoryAxis = this.GetCategoryAxis();
 164.500 +
 164.501 +            var text = StringHelper.Format(
 164.502 +                this.ActualCulture,
 164.503 +                this.TrackerFormatString,
 164.504 +                item,
 164.505 +                this.Title,
 164.506 +                categoryAxis.FormatValueForTracker(categoryIndex),
 164.507 +                barItem.Value);
 164.508 +            return text;
 164.509 +        }
 164.510 +
 164.511 +        /// <summary>
 164.512 +        /// Gets the value axis.
 164.513 +        /// </summary>
 164.514 +        /// <returns>
 164.515 +        /// The value axis.
 164.516 +        /// </returns>
 164.517 +        protected abstract Axis GetValueAxis();
 164.518 +
 164.519 +        /// <summary>
 164.520 +        /// Checks if the specified value is valid.
 164.521 +        /// </summary>
 164.522 +        /// <param name="v">
 164.523 +        /// The value.
 164.524 +        /// </param>
 164.525 +        /// <param name="yaxis">
 164.526 +        /// The y axis.
 164.527 +        /// </param>
 164.528 +        /// <returns>
 164.529 +        /// True if the value is valid.
 164.530 +        /// </returns>
 164.531 +        protected virtual bool IsValidPoint(double v, Axis yaxis)
 164.532 +        {
 164.533 +            return !double.IsNaN(v) && !double.IsInfinity(v);
 164.534 +        }
 164.535 +
 164.536 +        /// <summary>
 164.537 +        /// Renders the bar/column item.
 164.538 +        /// </summary>
 164.539 +        /// <param name="rc">
 164.540 +        /// The render context.
 164.541 +        /// </param>
 164.542 +        /// <param name="clippingRect">
 164.543 +        /// The clipping rectangle.
 164.544 +        /// </param>
 164.545 +        /// <param name="topValue">
 164.546 +        /// The end value of the bar.
 164.547 +        /// </param>
 164.548 +        /// <param name="categoryValue">
 164.549 +        /// The category value.
 164.550 +        /// </param>
 164.551 +        /// <param name="actualBarWidth">
 164.552 +        /// The actual width of the bar.
 164.553 +        /// </param>
 164.554 +        /// <param name="item">
 164.555 +        /// The item.
 164.556 +        /// </param>
 164.557 +        /// <param name="rect">
 164.558 +        /// The rectangle of the bar.
 164.559 +        /// </param>
 164.560 +        protected virtual void RenderItem(
 164.561 +            IRenderContext rc,
 164.562 +            OxyRect clippingRect,
 164.563 +            double topValue,
 164.564 +            double categoryValue,
 164.565 +            double actualBarWidth,
 164.566 +            BarItemBase item,
 164.567 +            OxyRect rect)
 164.568 +        {
 164.569 +            // Get the color of the item
 164.570 +            var actualFillColor = item.Color;
 164.571 +            if (actualFillColor == null)
 164.572 +            {
 164.573 +                actualFillColor = this.ActualFillColor;
 164.574 +                if (item.Value < 0 && this.NegativeFillColor != null)
 164.575 +                {
 164.576 +                    actualFillColor = this.NegativeFillColor;
 164.577 +                }
 164.578 +            }
 164.579 +
 164.580 +            rc.DrawClippedRectangleAsPolygon(
 164.581 +                rect, clippingRect, this.GetSelectableFillColor(actualFillColor), this.StrokeColor, this.StrokeThickness);
 164.582 +        }
 164.583 +
 164.584 +        /// <summary>
 164.585 +        /// Renders the item label.
 164.586 +        /// </summary>
 164.587 +        /// <param name="rc">
 164.588 +        /// The render context
 164.589 +        /// </param>
 164.590 +        /// <param name="clippingRect">
 164.591 +        /// The clipping rectangle
 164.592 +        /// </param>
 164.593 +        /// <param name="rect">
 164.594 +        /// The rectangle of the item.
 164.595 +        /// </param>
 164.596 +        /// <param name="value">
 164.597 +        /// The value of the label.
 164.598 +        /// </param>
 164.599 +        /// <param name="index">
 164.600 +        /// The index of the bar item.
 164.601 +        /// </param>
 164.602 +        protected abstract void RenderLabel(
 164.603 +            IRenderContext rc, OxyRect clippingRect, OxyRect rect, double value, int index);
 164.604 +
 164.605 +    }
 164.606 +}
 164.607 \ No newline at end of file
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/BarSeriesBase{T}.cs	Sat Jun 08 16:53:22 2013 +0000
   165.3 @@ -0,0 +1,113 @@
   165.4 +// --------------------------------------------------------------------------------------------------------------------
   165.5 +// <copyright file="BarSeriesBase{T}.cs" company="OxyPlot">
   165.6 +//   The MIT License (MIT)
   165.7 +//
   165.8 +//   Copyright (c) 2012 Oystein Bjorke
   165.9 +//
  165.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  165.11 +//   copy of this software and associated documentation files (the
  165.12 +//   "Software"), to deal in the Software without restriction, including
  165.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  165.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  165.15 +//   permit persons to whom the Software is furnished to do so, subject to
  165.16 +//   the following conditions:
  165.17 +//
  165.18 +//   The above copyright notice and this permission notice shall be included
  165.19 +//   in all copies or substantial portions of the Software.
  165.20 +//
  165.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  165.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  165.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  165.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  165.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  165.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  165.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  165.28 +// </copyright>
  165.29 +// <summary>
  165.30 +//   Generic base class that provides common properties and methods for the BarSeries and ColumnSeries.
  165.31 +// </summary>
  165.32 +// --------------------------------------------------------------------------------------------------------------------
  165.33 +namespace OxyPlot.Series
  165.34 +{
  165.35 +    using System;
  165.36 +    using System.Collections;
  165.37 +    using System.Collections.Generic;
  165.38 +    using System.Linq;
  165.39 +
  165.40 +    /// <summary>
  165.41 +    /// Generic base class that provides common properties and methods for the BarSeries and ColumnSeries.
  165.42 +    /// </summary>
  165.43 +    /// <typeparam name="T">
  165.44 +    /// The type of the items.
  165.45 +    /// </typeparam>
  165.46 +    public abstract class BarSeriesBase<T> : BarSeriesBase
  165.47 +        where T : BarItemBase, new()
  165.48 +    {
  165.49 +        /// <summary>
  165.50 +        /// Initializes a new instance of the <see cref="BarSeriesBase{T}"/> class. Initializes a new instance of the <see cref="BarSeriesBase&lt;T&gt;"/> class.
  165.51 +        /// </summary>
  165.52 +        protected BarSeriesBase()
  165.53 +        {
  165.54 +            this.Items = new List<T>();
  165.55 +        }
  165.56 +
  165.57 +        /// <summary>
  165.58 +        /// Gets the items.
  165.59 +        /// </summary>
  165.60 +        /// <value>
  165.61 +        /// The items.
  165.62 +        /// </value>
  165.63 +        public IList<T> Items { get; private set; }
  165.64 +
  165.65 +        /// <summary>
  165.66 +        /// Gets the items of this series.
  165.67 +        /// </summary>
  165.68 +        /// <returns>
  165.69 +        /// The items.
  165.70 +        /// </returns>
  165.71 +        protected internal override IList<CategorizedItem> GetItems()
  165.72 +        {
  165.73 +            return this.Items.Cast<CategorizedItem>().ToList();
  165.74 +        }
  165.75 +
  165.76 +        /// <summary>
  165.77 +        /// Updates the data.
  165.78 +        /// </summary>
  165.79 +        protected internal override void UpdateData()
  165.80 +        {
  165.81 +            if (this.ItemsSource == null)
  165.82 +            {
  165.83 +                return;
  165.84 +            }
  165.85 +
  165.86 +            var dest = new List<T>();
  165.87 +
  165.88 +            // Using reflection to add points
  165.89 +            var filler = new ListFiller<T>();
  165.90 +            filler.Add(this.ValueField, (item, value) => item.Value = Convert.ToDouble(value));
  165.91 +            filler.Add(this.ColorField, (item, value) => item.Color = (OxyColor)value);
  165.92 +            filler.Fill(dest, this.ItemsSource);
  165.93 +            this.Items = dest;
  165.94 +        }
  165.95 +
  165.96 +        /// <summary>
  165.97 +        /// Gets the item at the specified index.
  165.98 +        /// </summary>
  165.99 +        /// <param name="i">
 165.100 +        /// The index of the item.
 165.101 +        /// </param>
 165.102 +        /// <returns>
 165.103 +        /// The item of the index.
 165.104 +        /// </returns>
 165.105 +        protected override object GetItem(int i)
 165.106 +        {
 165.107 +            if (this.ItemsSource != null || this.Items == null || this.Items.Count == 0)
 165.108 +            {
 165.109 +                return base.GetItem(i);
 165.110 +            }
 165.111 +
 165.112 +            return this.Items[i];
 165.113 +        }
 165.114 +
 165.115 +    }
 165.116 +}
 165.117 \ No newline at end of file
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/CategorizedItem.cs	Sat Jun 08 16:53:22 2013 +0000
   166.3 @@ -0,0 +1,73 @@
   166.4 +// --------------------------------------------------------------------------------------------------------------------
   166.5 +// <copyright file="CategorizedItem.cs" company="OxyPlot">
   166.6 +//   The MIT License (MIT)
   166.7 +//
   166.8 +//   Copyright (c) 2012 Oystein Bjorke
   166.9 +//
  166.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  166.11 +//   copy of this software and associated documentation files (the
  166.12 +//   "Software"), to deal in the Software without restriction, including
  166.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  166.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  166.15 +//   permit persons to whom the Software is furnished to do so, subject to
  166.16 +//   the following conditions:
  166.17 +//
  166.18 +//   The above copyright notice and this permission notice shall be included
  166.19 +//   in all copies or substantial portions of the Software.
  166.20 +//
  166.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  166.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  166.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  166.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  166.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  166.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  166.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  166.28 +// </copyright>
  166.29 +// <summary>
  166.30 +//   Represents an item in a CategorizedSeries.
  166.31 +// </summary>
  166.32 +// --------------------------------------------------------------------------------------------------------------------
  166.33 +namespace OxyPlot.Series
  166.34 +{
  166.35 +    /// <summary>
  166.36 +    /// Represents an item in a CategorizedSeries.
  166.37 +    /// </summary>
  166.38 +    public abstract class CategorizedItem
  166.39 +    {
  166.40 +        /// <summary>
  166.41 +        /// Initializes a new instance of the <see cref="CategorizedItem"/> class. Initializes a new instance of the <see cref="CategorizedItem"/> class.
  166.42 +        /// </summary>
  166.43 +        protected CategorizedItem()
  166.44 +        {
  166.45 +            this.CategoryIndex = -1;
  166.46 +        }
  166.47 +
  166.48 +        /// <summary>
  166.49 +        /// Gets or sets the index of the category.
  166.50 +        /// </summary>
  166.51 +        /// <value>
  166.52 +        /// The index of the category.
  166.53 +        /// </value>
  166.54 +        public int CategoryIndex { get; set; }
  166.55 +
  166.56 +        /// <summary>
  166.57 +        /// Gets the index of the category.
  166.58 +        /// </summary>
  166.59 +        /// <param name="defaultIndex">
  166.60 +        /// The default index.
  166.61 +        /// </param>
  166.62 +        /// <returns>
  166.63 +        /// The index.
  166.64 +        /// </returns>
  166.65 +        internal int GetCategoryIndex(int defaultIndex)
  166.66 +        {
  166.67 +            if (this.CategoryIndex < 0)
  166.68 +            {
  166.69 +                return defaultIndex;
  166.70 +            }
  166.71 +
  166.72 +            return this.CategoryIndex;
  166.73 +        }
  166.74 +
  166.75 +    }
  166.76 +}
  166.77 \ No newline at end of file
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/CategorizedSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   167.3 @@ -0,0 +1,83 @@
   167.4 +// --------------------------------------------------------------------------------------------------------------------
   167.5 +// <copyright file="CategorizedSeries.cs" company="OxyPlot">
   167.6 +//   The MIT License (MIT)
   167.7 +//
   167.8 +//   Copyright (c) 2012 Oystein Bjorke
   167.9 +//
  167.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  167.11 +//   copy of this software and associated documentation files (the
  167.12 +//   "Software"), to deal in the Software without restriction, including
  167.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  167.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  167.15 +//   permit persons to whom the Software is furnished to do so, subject to
  167.16 +//   the following conditions:
  167.17 +//
  167.18 +//   The above copyright notice and this permission notice shall be included
  167.19 +//   in all copies or substantial portions of the Software.
  167.20 +//
  167.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  167.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  167.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  167.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  167.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  167.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  167.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  167.28 +// </copyright>
  167.29 +// <summary>
  167.30 +//   Base class for series where the items are categorized.
  167.31 +// </summary>
  167.32 +// --------------------------------------------------------------------------------------------------------------------
  167.33 +namespace OxyPlot.Series
  167.34 +{
  167.35 +    using System.Collections.Generic;
  167.36 +
  167.37 +    using OxyPlot.Axes;
  167.38 +
  167.39 +    /// <summary>
  167.40 +    /// Base class for series where the items are categorized.
  167.41 +    /// </summary>
  167.42 +    public abstract class CategorizedSeries : XYAxisSeries
  167.43 +    {
  167.44 +        /// <summary>
  167.45 +        /// Gets or sets the width/height of the columns/bars (as a fraction of the available space).
  167.46 +        /// </summary>
  167.47 +        /// <returns>
  167.48 +        /// The fractional width.
  167.49 +        /// </returns>
  167.50 +        /// <value>
  167.51 +        /// The width of the bars.
  167.52 +        /// </value>
  167.53 +        /// <remarks>
  167.54 +        /// The available space will be determined by the GapWidth of the CategoryAxis used by this series.
  167.55 +        /// </remarks>
  167.56 +        internal abstract double GetBarWidth();
  167.57 +
  167.58 +        /// <summary>
  167.59 +        /// Gets the items of this series.
  167.60 +        /// </summary>
  167.61 +        /// <returns>
  167.62 +        /// The items.
  167.63 +        /// </returns>
  167.64 +        protected internal abstract IList<CategorizedItem> GetItems();
  167.65 +
  167.66 +        /// <summary>
  167.67 +        /// Gets the actual bar width/height of the items in this series.
  167.68 +        /// </summary>
  167.69 +        /// <returns>
  167.70 +        /// The width or height.
  167.71 +        /// </returns>
  167.72 +        /// <remarks>
  167.73 +        /// The actual width is also influenced by the GapWidth of the CategoryAxis used by this series.
  167.74 +        /// </remarks>
  167.75 +        protected abstract double GetActualBarWidth();
  167.76 +
  167.77 +        /// <summary>
  167.78 +        /// Gets the category axis.
  167.79 +        /// </summary>
  167.80 +        /// <returns>
  167.81 +        /// The category axis.
  167.82 +        /// </returns>
  167.83 +        protected abstract CategoryAxis GetCategoryAxis();
  167.84 +
  167.85 +    }
  167.86 +}
  167.87 \ No newline at end of file
   168.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   168.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/ColumnItem.cs	Sat Jun 08 16:53:22 2013 +0000
   168.3 @@ -0,0 +1,64 @@
   168.4 +// --------------------------------------------------------------------------------------------------------------------
   168.5 +// <copyright file="ColumnItem.cs" company="OxyPlot">
   168.6 +//   The MIT License (MIT)
   168.7 +//
   168.8 +//   Copyright (c) 2012 Oystein Bjorke
   168.9 +//
  168.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  168.11 +//   copy of this software and associated documentation files (the
  168.12 +//   "Software"), to deal in the Software without restriction, including
  168.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  168.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  168.15 +//   permit persons to whom the Software is furnished to do so, subject to
  168.16 +//   the following conditions:
  168.17 +//
  168.18 +//   The above copyright notice and this permission notice shall be included
  168.19 +//   in all copies or substantial portions of the Software.
  168.20 +//
  168.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  168.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  168.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  168.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  168.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  168.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  168.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  168.28 +// </copyright>
  168.29 +// <summary>
  168.30 +//   Represents an item used in the ColumnSeries.
  168.31 +// </summary>
  168.32 +// --------------------------------------------------------------------------------------------------------------------
  168.33 +namespace OxyPlot.Series
  168.34 +{
  168.35 +    /// <summary>
  168.36 +    /// Represents an item used in the ColumnSeries.
  168.37 +    /// </summary>
  168.38 +    public class ColumnItem : BarItemBase
  168.39 +    {
  168.40 +        /// <summary>
  168.41 +        /// Initializes a new instance of the <see cref="ColumnItem"/> class.
  168.42 +        /// </summary>
  168.43 +        public ColumnItem()
  168.44 +        {
  168.45 +        }
  168.46 +
  168.47 +        /// <summary>
  168.48 +        /// Initializes a new instance of the <see cref="ColumnItem"/> class.
  168.49 +        /// </summary>
  168.50 +        /// <param name="value">
  168.51 +        /// The value.
  168.52 +        /// </param>
  168.53 +        /// <param name="categoryIndex">
  168.54 +        /// Index of the category.
  168.55 +        /// </param>
  168.56 +        /// <param name="color">
  168.57 +        /// The color.
  168.58 +        /// </param>
  168.59 +        public ColumnItem(double value, int categoryIndex = -1, OxyColor color = null)
  168.60 +        {
  168.61 +            this.Value = value;
  168.62 +            this.CategoryIndex = categoryIndex;
  168.63 +            this.Color = color;
  168.64 +        }
  168.65 +
  168.66 +    }
  168.67 +}
  168.68 \ No newline at end of file
   169.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/ColumnSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   169.3 @@ -0,0 +1,198 @@
   169.4 +// --------------------------------------------------------------------------------------------------------------------
   169.5 +// <copyright file="ColumnSeries.cs" company="OxyPlot">
   169.6 +//   The MIT License (MIT)
   169.7 +//
   169.8 +//   Copyright (c) 2012 Oystein Bjorke
   169.9 +//
  169.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  169.11 +//   copy of this software and associated documentation files (the
  169.12 +//   "Software"), to deal in the Software without restriction, including
  169.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  169.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  169.15 +//   permit persons to whom the Software is furnished to do so, subject to
  169.16 +//   the following conditions:
  169.17 +//
  169.18 +//   The above copyright notice and this permission notice shall be included
  169.19 +//   in all copies or substantial portions of the Software.
  169.20 +//
  169.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  169.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  169.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  169.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  169.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  169.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  169.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  169.28 +// </copyright>
  169.29 +// <summary>
  169.30 +//   Represents a series for clustered or stacked column charts.
  169.31 +// </summary>
  169.32 +// --------------------------------------------------------------------------------------------------------------------
  169.33 +namespace OxyPlot.Series
  169.34 +{
  169.35 +    using System;
  169.36 +
  169.37 +    using OxyPlot.Axes;
  169.38 +
  169.39 +    /// <summary>
  169.40 +    /// Represents a series for clustered or stacked column charts.
  169.41 +    /// </summary>
  169.42 +    public class ColumnSeries : BarSeriesBase<ColumnItem>
  169.43 +    {
  169.44 +        /// <summary>
  169.45 +        /// Initializes a new instance of the <see cref="ColumnSeries"/> class.
  169.46 +        /// </summary>
  169.47 +        public ColumnSeries()
  169.48 +        {
  169.49 +            this.ColumnWidth = 1;
  169.50 +        }
  169.51 +
  169.52 +        /// <summary>
  169.53 +        /// Gets or sets the width of the column.
  169.54 +        /// </summary>
  169.55 +        /// <value>
  169.56 +        /// The width of the column.
  169.57 +        /// </value>
  169.58 +        public double ColumnWidth { get; set; }
  169.59 +
  169.60 +        /// <summary>
  169.61 +        /// Gets or sets the width/height of the columns/bars (as a fraction of the available space).
  169.62 +        /// </summary>
  169.63 +        /// <returns>
  169.64 +        /// The fractional width.
  169.65 +        /// </returns>
  169.66 +        /// <value>
  169.67 +        /// The width of the bars.
  169.68 +        /// </value>
  169.69 +        /// <remarks>
  169.70 +        /// The available space will be determined by the GapWidth of the CategoryAxis used by this series.
  169.71 +        /// </remarks>
  169.72 +        internal override double GetBarWidth()
  169.73 +        {
  169.74 +            return this.ColumnWidth;
  169.75 +        }
  169.76 +
  169.77 +        /// <summary>
  169.78 +        /// Gets the actual width/height of the items of this series.
  169.79 +        /// </summary>
  169.80 +        /// <returns>
  169.81 +        /// The width or height.
  169.82 +        /// </returns>
  169.83 +        /// <remarks>
  169.84 +        /// The actual width is also influenced by the GapWidth of the CategoryAxis used by this series.
  169.85 +        /// </remarks>
  169.86 +        protected override double GetActualBarWidth()
  169.87 +        {
  169.88 +            var categoryAxis = this.GetCategoryAxis();
  169.89 +            return this.ColumnWidth / (1 + categoryAxis.GapWidth) / categoryAxis.MaxWidth;
  169.90 +        }
  169.91 +
  169.92 +        /// <summary>
  169.93 +        /// Gets the category axis.
  169.94 +        /// </summary>
  169.95 +        /// <returns>
  169.96 +        /// The category axis.
  169.97 +        /// </returns>
  169.98 +        protected override CategoryAxis GetCategoryAxis()
  169.99 +        {
 169.100 +            if (!(this.XAxis is CategoryAxis))
 169.101 +            {
 169.102 +                throw new Exception(
 169.103 +                    "A ColumnSeries requires a CategoryAxis on the x-axis. Use a BarSeries if you want horizontal bars.");
 169.104 +            }
 169.105 +
 169.106 +            return this.XAxis as CategoryAxis;
 169.107 +        }
 169.108 +
 169.109 +        /// <summary>
 169.110 +        /// Gets the rectangle for the specified values.
 169.111 +        /// </summary>
 169.112 +        /// <param name="baseValue">
 169.113 +        /// The base value of the bar
 169.114 +        /// </param>
 169.115 +        /// <param name="topValue">
 169.116 +        /// The top value of the bar
 169.117 +        /// </param>
 169.118 +        /// <param name="beginValue">
 169.119 +        /// The begin value of the bar
 169.120 +        /// </param>
 169.121 +        /// <param name="endValue">
 169.122 +        /// The end value of the bar
 169.123 +        /// </param>
 169.124 +        /// <returns>
 169.125 +        /// The rectangle.
 169.126 +        /// </returns>
 169.127 +        protected override OxyRect GetRectangle(double baseValue, double topValue, double beginValue, double endValue)
 169.128 +        {
 169.129 +            return OxyRect.Create(this.Transform(beginValue, baseValue), this.Transform(endValue, topValue));
 169.130 +        }
 169.131 +
 169.132 +        /// <summary>
 169.133 +        /// Gets the value axis.
 169.134 +        /// </summary>
 169.135 +        /// <returns>
 169.136 +        /// The value axis.
 169.137 +        /// </returns>
 169.138 +        protected override Axis GetValueAxis()
 169.139 +        {
 169.140 +            return this.YAxis;
 169.141 +        }
 169.142 +
 169.143 +        /// <summary>
 169.144 +        /// Draws the label.
 169.145 +        /// </summary>
 169.146 +        /// <param name="rc">
 169.147 +        /// The render context.
 169.148 +        /// </param>
 169.149 +        /// <param name="clippingRect">
 169.150 +        /// The clipping rect.
 169.151 +        /// </param>
 169.152 +        /// <param name="rect">
 169.153 +        /// The rect.
 169.154 +        /// </param>
 169.155 +        /// <param name="value">
 169.156 +        /// The value.
 169.157 +        /// </param>
 169.158 +        /// <param name="i">
 169.159 +        /// The i.
 169.160 +        /// </param>
 169.161 +        protected override void RenderLabel(IRenderContext rc, OxyRect clippingRect, OxyRect rect, double value, int i)
 169.162 +        {
 169.163 +            var s = StringHelper.Format(
 169.164 +                this.ActualCulture, this.LabelFormatString, this.GetItem(this.ValidItemsIndexInversion[i]), value);
 169.165 +            ScreenPoint pt;
 169.166 +            VerticalAlignment va;
 169.167 +            switch (this.LabelPlacement)
 169.168 +            {
 169.169 +                case LabelPlacement.Inside:
 169.170 +                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, rect.Top + this.LabelMargin);
 169.171 +                    va = VerticalAlignment.Top;
 169.172 +                    break;
 169.173 +                case LabelPlacement.Middle:
 169.174 +                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Bottom + rect.Top) / 2);
 169.175 +                    va = VerticalAlignment.Middle;
 169.176 +                    break;
 169.177 +                case LabelPlacement.Base:
 169.178 +                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, rect.Bottom - this.LabelMargin);
 169.179 +                    va = VerticalAlignment.Bottom;
 169.180 +                    break;
 169.181 +                default: // outside
 169.182 +                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, rect.Top - this.LabelMargin);
 169.183 +                    va = VerticalAlignment.Bottom;
 169.184 +                    break;
 169.185 +            }
 169.186 +
 169.187 +            rc.DrawClippedText(
 169.188 +                clippingRect,
 169.189 +                pt,
 169.190 +                s,
 169.191 +                this.ActualTextColor,
 169.192 +                this.ActualFont,
 169.193 +                this.ActualFontSize,
 169.194 +                this.ActualFontWeight,
 169.195 +                0,
 169.196 +                HorizontalAlignment.Center,
 169.197 +                va);
 169.198 +        }
 169.199 +
 169.200 +    }
 169.201 +}
 169.202 \ No newline at end of file
   170.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/ErrorColumnItem.cs	Sat Jun 08 16:53:22 2013 +0000
   170.3 @@ -0,0 +1,96 @@
   170.4 +// --------------------------------------------------------------------------------------------------------------------
   170.5 +// <copyright file="ErrorColumnItem.cs" company="OxyPlot">
   170.6 +//   The MIT License (MIT)
   170.7 +//
   170.8 +//   Copyright (c) 2012 Oystein Bjorke
   170.9 +//
  170.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  170.11 +//   copy of this software and associated documentation files (the
  170.12 +//   "Software"), to deal in the Software without restriction, including
  170.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  170.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  170.15 +//   permit persons to whom the Software is furnished to do so, subject to
  170.16 +//   the following conditions:
  170.17 +//
  170.18 +//   The above copyright notice and this permission notice shall be included
  170.19 +//   in all copies or substantial portions of the Software.
  170.20 +//
  170.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  170.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  170.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  170.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  170.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  170.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  170.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  170.28 +// </copyright>
  170.29 +// <summary>
  170.30 +//   Represents an item used in the ErrorColumnSeries.
  170.31 +// </summary>
  170.32 +// --------------------------------------------------------------------------------------------------------------------
  170.33 +namespace OxyPlot.Series
  170.34 +{
  170.35 +    /// <summary>
  170.36 +    /// Represents an item used in the ErrorColumnSeries.
  170.37 +    /// </summary>
  170.38 +    public class ErrorColumnItem : ColumnItem
  170.39 +    {
  170.40 +        /// <summary>
  170.41 +        /// Initializes a new instance of the <see cref="ErrorColumnItem"/> class.
  170.42 +        /// </summary>
  170.43 +        public ErrorColumnItem()
  170.44 +        {
  170.45 +        }
  170.46 +
  170.47 +        /// <summary>
  170.48 +        /// Initializes a new instance of the <see cref="ErrorColumnItem"/> class.
  170.49 +        /// </summary>
  170.50 +        /// <param name="value">
  170.51 +        /// The value.
  170.52 +        /// </param>
  170.53 +        /// <param name="error">
  170.54 +        /// The error.
  170.55 +        /// </param>
  170.56 +        /// <param name="categoryIndex">
  170.57 +        /// Index of the category.
  170.58 +        /// </param>
  170.59 +        /// <param name="color">
  170.60 +        /// The color.
  170.61 +        /// </param>
  170.62 +        public ErrorColumnItem(double value, double error, int categoryIndex = -1, OxyColor color = null)
  170.63 +        {
  170.64 +            this.Value = value;
  170.65 +            this.Error = error;
  170.66 +            this.CategoryIndex = categoryIndex;
  170.67 +            this.Color = color;
  170.68 +        }
  170.69 +
  170.70 +        /// <summary>
  170.71 +        /// Gets or sets the error of the item.
  170.72 +        /// </summary>
  170.73 +        public double Error { get; set; }
  170.74 +
  170.75 +        /// <summary>
  170.76 +        /// Returns c# code that generates this instance.
  170.77 +        /// </summary>
  170.78 +        /// <returns>
  170.79 +        /// C# code.
  170.80 +        /// </returns>
  170.81 +        public override string ToCode()
  170.82 +        {
  170.83 +            if (this.Color != null)
  170.84 +            {
  170.85 +                return CodeGenerator.FormatConstructor(
  170.86 +                    this.GetType(), "{0},{1},{2},{3}", this.Value, this.Error, this.CategoryIndex, this.Color.ToCode());
  170.87 +            }
  170.88 +
  170.89 +            if (this.CategoryIndex != -1)
  170.90 +            {
  170.91 +                return CodeGenerator.FormatConstructor(
  170.92 +                    this.GetType(), "{0},{1},{2}", this.Value, this.Error, this.CategoryIndex);
  170.93 +            }
  170.94 +
  170.95 +            return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.Value, this.Error);
  170.96 +        }
  170.97 +
  170.98 +    }
  170.99 +}
 170.100 \ No newline at end of file
   171.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/ErrorColumnSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   171.3 @@ -0,0 +1,240 @@
   171.4 +// --------------------------------------------------------------------------------------------------------------------
   171.5 +// <copyright file="ErrorColumnSeries.cs" company="OxyPlot">
   171.6 +//   The MIT License (MIT)
   171.7 +//
   171.8 +//   Copyright (c) 2012 Oystein Bjorke
   171.9 +//
  171.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  171.11 +//   copy of this software and associated documentation files (the
  171.12 +//   "Software"), to deal in the Software without restriction, including
  171.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  171.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  171.15 +//   permit persons to whom the Software is furnished to do so, subject to
  171.16 +//   the following conditions:
  171.17 +//
  171.18 +//   The above copyright notice and this permission notice shall be included
  171.19 +//   in all copies or substantial portions of the Software.
  171.20 +//
  171.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  171.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  171.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  171.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  171.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  171.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  171.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  171.28 +// </copyright>
  171.29 +// <summary>
  171.30 +//   Represents a series for clustered or stacked column charts with an error value.
  171.31 +// </summary>
  171.32 +// --------------------------------------------------------------------------------------------------------------------
  171.33 +namespace OxyPlot.Series
  171.34 +{
  171.35 +    using System;
  171.36 +    using System.Collections.Generic;
  171.37 +    using System.Linq;
  171.38 +
  171.39 +    /// <summary>
  171.40 +    /// Represents a series for clustered or stacked column charts with an error value.
  171.41 +    /// </summary>
  171.42 +    public class ErrorColumnSeries : ColumnSeries
  171.43 +    {
  171.44 +        /// <summary>
  171.45 +        /// Initializes a new instance of the <see cref="ErrorColumnSeries"/> class.
  171.46 +        /// </summary>
  171.47 +        public ErrorColumnSeries()
  171.48 +        {
  171.49 +            this.ErrorWidth = 0.4;
  171.50 +            this.ErrorStrokeThickness = 1;
  171.51 +            this.TrackerFormatString = "{0}, {1}: {2}, Error: {Error}";
  171.52 +        }
  171.53 +
  171.54 +        /// <summary>
  171.55 +        /// Gets or sets the stroke thickness of the error line.
  171.56 +        /// </summary>
  171.57 +        /// <value>
  171.58 +        /// The stroke thickness of the error line.
  171.59 +        /// </value>
  171.60 +        public double ErrorStrokeThickness { get; set; }
  171.61 +
  171.62 +        /// <summary>
  171.63 +        /// Gets or sets the width of the error end lines.
  171.64 +        /// </summary>
  171.65 +        /// <value>
  171.66 +        /// The width of the error end lines.
  171.67 +        /// </value>
  171.68 +        public double ErrorWidth { get; set; }
  171.69 +
  171.70 +        /// <summary>
  171.71 +        /// Updates the maximum/minimum value on the value axis from the bar values.
  171.72 +        /// </summary>
  171.73 +        protected internal override void UpdateMaxMin()
  171.74 +        {
  171.75 +            base.UpdateMaxMin();
  171.76 +
  171.77 +            //// Todo: refactor (lots of duplicate code here)
  171.78 +            if (this.ValidItems == null || this.ValidItems.Count == 0)
  171.79 +            {
  171.80 +                return;
  171.81 +            }
  171.82 +
  171.83 +            var categoryAxis = this.GetCategoryAxis();
  171.84 +
  171.85 +            double minValue = double.MaxValue, maxValue = double.MinValue;
  171.86 +            if (this.IsStacked)
  171.87 +            {
  171.88 +                var labels = this.GetCategoryAxis().Labels;
  171.89 +                for (var i = 0; i < labels.Count; i++)
  171.90 +                {
  171.91 +                    int j = 0;
  171.92 +                    var items = this.ValidItems.Where(item => item.GetCategoryIndex(j++) == i).ToList();
  171.93 +                    var values = items.Select(item => item.Value).Concat(new[] { 0d }).ToList();
  171.94 +                    var minTemp = values.Where(v => v <= 0).Sum();
  171.95 +                    var maxTemp = values.Where(v => v >= 0).Sum() + ((ErrorColumnItem)items.Last()).Error;
  171.96 +
  171.97 +                    int stackIndex = categoryAxis.StackIndexMapping[this.StackGroup];
  171.98 +                    var stackedMinValue = categoryAxis.MinValue[stackIndex, i];
  171.99 +                    if (!double.IsNaN(stackedMinValue))
 171.100 +                    {
 171.101 +                        minTemp += stackedMinValue;
 171.102 +                    }
 171.103 +
 171.104 +                    categoryAxis.MinValue[stackIndex, i] = minTemp;
 171.105 +
 171.106 +                    var stackedMaxValue = categoryAxis.MaxValue[stackIndex, i];
 171.107 +                    if (!double.IsNaN(stackedMaxValue))
 171.108 +                    {
 171.109 +                        maxTemp += stackedMaxValue;
 171.110 +                    }
 171.111 +
 171.112 +                    categoryAxis.MaxValue[stackIndex, i] = maxTemp;
 171.113 +
 171.114 +                    minValue = Math.Min(minValue, minTemp + this.BaseValue);
 171.115 +                    maxValue = Math.Max(maxValue, maxTemp + this.BaseValue);
 171.116 +                }
 171.117 +            }
 171.118 +            else
 171.119 +            {
 171.120 +                var valuesMin =
 171.121 +                    this.ValidItems.Select(item => item.Value - ((ErrorColumnItem)item).Error).Concat(new[] { 0d }).
 171.122 +                        ToList();
 171.123 +                var valuesMax =
 171.124 +                    this.ValidItems.Select(item => item.Value + ((ErrorColumnItem)item).Error).Concat(new[] { 0d }).
 171.125 +                        ToList();
 171.126 +                minValue = valuesMin.Min();
 171.127 +                maxValue = valuesMax.Max();
 171.128 +                if (this.BaseValue < minValue)
 171.129 +                {
 171.130 +                    minValue = this.BaseValue;
 171.131 +                }
 171.132 +
 171.133 +                if (this.BaseValue > maxValue)
 171.134 +                {
 171.135 +                    maxValue = this.BaseValue;
 171.136 +                }
 171.137 +            }
 171.138 +
 171.139 +            var valueAxis = this.GetValueAxis();
 171.140 +            if (valueAxis.IsVertical())
 171.141 +            {
 171.142 +                this.MinY = minValue;
 171.143 +                this.MaxY = maxValue;
 171.144 +            }
 171.145 +            else
 171.146 +            {
 171.147 +                this.MinX = minValue;
 171.148 +                this.MaxX = maxValue;
 171.149 +            }
 171.150 +        }
 171.151 +
 171.152 +        /// <summary>
 171.153 +        /// Renders the bar/column item.
 171.154 +        /// </summary>
 171.155 +        /// <param name="rc">
 171.156 +        /// The render context.
 171.157 +        /// </param>
 171.158 +        /// <param name="clippingRect">
 171.159 +        /// The clipping rectangle.
 171.160 +        /// </param>
 171.161 +        /// <param name="topValue">
 171.162 +        /// The end value of the bar.
 171.163 +        /// </param>
 171.164 +        /// <param name="categoryValue">
 171.165 +        /// The category value.
 171.166 +        /// </param>
 171.167 +        /// <param name="actualBarWidth">
 171.168 +        /// The actual width of the bar.
 171.169 +        /// </param>
 171.170 +        /// <param name="item">
 171.171 +        /// The item.
 171.172 +        /// </param>
 171.173 +        /// <param name="rect">
 171.174 +        /// The rectangle of the bar.
 171.175 +        /// </param>
 171.176 +        protected override void RenderItem(
 171.177 +            IRenderContext rc,
 171.178 +            OxyRect clippingRect,
 171.179 +            double topValue,
 171.180 +            double categoryValue,
 171.181 +            double actualBarWidth,
 171.182 +            BarItemBase item,
 171.183 +            OxyRect rect)
 171.184 +        {
 171.185 +            base.RenderItem(rc, clippingRect, topValue, categoryValue, actualBarWidth, item, rect);
 171.186 +
 171.187 +            var errorItem = item as ErrorColumnItem;
 171.188 +            if (errorItem == null)
 171.189 +            {
 171.190 +                return;
 171.191 +            }
 171.192 +
 171.193 +            // Render the error
 171.194 +            var lowerValue = topValue - errorItem.Error;
 171.195 +            var upperValue = topValue + errorItem.Error;
 171.196 +            var left = 0.5 - this.ErrorWidth / 2;
 171.197 +            var right = 0.5 + this.ErrorWidth / 2;
 171.198 +            var leftValue = categoryValue + (left * actualBarWidth);
 171.199 +            var middleValue = categoryValue + (0.5 * actualBarWidth);
 171.200 +            var rightValue = categoryValue + (right * actualBarWidth);
 171.201 +
 171.202 +            var lowerErrorPoint = this.Transform(middleValue, lowerValue);
 171.203 +            var upperErrorPoint = this.Transform(middleValue, upperValue);
 171.204 +            rc.DrawClippedLine(
 171.205 +                new List<ScreenPoint> { lowerErrorPoint, upperErrorPoint },
 171.206 +                clippingRect,
 171.207 +                0,
 171.208 +                this.StrokeColor,
 171.209 +                this.ErrorStrokeThickness,
 171.210 +                LineStyle.Solid,
 171.211 +                OxyPenLineJoin.Miter,
 171.212 +                true);
 171.213 +
 171.214 +            if (this.ErrorWidth > 0)
 171.215 +            {
 171.216 +                var lowerLeftErrorPoint = this.Transform(leftValue, lowerValue);
 171.217 +                var lowerRightErrorPoint = this.Transform(rightValue, lowerValue);
 171.218 +                rc.DrawClippedLine(
 171.219 +                    new List<ScreenPoint> { lowerLeftErrorPoint, lowerRightErrorPoint },
 171.220 +                    clippingRect,
 171.221 +                    0,
 171.222 +                    this.StrokeColor,
 171.223 +                    this.ErrorStrokeThickness,
 171.224 +                    LineStyle.Solid,
 171.225 +                    OxyPenLineJoin.Miter,
 171.226 +                    true);
 171.227 +
 171.228 +                var upperLeftErrorPoint = this.Transform(leftValue, upperValue);
 171.229 +                var upperRightErrorPoint = this.Transform(rightValue, upperValue);
 171.230 +                rc.DrawClippedLine(
 171.231 +                    new List<ScreenPoint> { upperLeftErrorPoint, upperRightErrorPoint },
 171.232 +                    clippingRect,
 171.233 +                    0,
 171.234 +                    this.StrokeColor,
 171.235 +                    this.ErrorStrokeThickness,
 171.236 +                    LineStyle.Solid,
 171.237 +                    OxyPenLineJoin.Miter,
 171.238 +                    true);
 171.239 +            }
 171.240 +        }
 171.241 +
 171.242 +    }
 171.243 +}
 171.244 \ No newline at end of file
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/IStackableSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   172.3 @@ -0,0 +1,50 @@
   172.4 +// --------------------------------------------------------------------------------------------------------------------
   172.5 +// <copyright file="IStackableSeries.cs" company="OxyPlot">
   172.6 +//   The MIT License (MIT)
   172.7 +//
   172.8 +//   Copyright (c) 2012 Oystein Bjorke
   172.9 +//
  172.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  172.11 +//   copy of this software and associated documentation files (the
  172.12 +//   "Software"), to deal in the Software without restriction, including
  172.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  172.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  172.15 +//   permit persons to whom the Software is furnished to do so, subject to
  172.16 +//   the following conditions:
  172.17 +//
  172.18 +//   The above copyright notice and this permission notice shall be included
  172.19 +//   in all copies or substantial portions of the Software.
  172.20 +//
  172.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  172.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  172.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  172.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  172.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  172.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  172.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  172.28 +// </copyright>
  172.29 +// <summary>
  172.30 +//   Specifies a series that can be stacked.
  172.31 +// </summary>
  172.32 +// --------------------------------------------------------------------------------------------------------------------
  172.33 +namespace OxyPlot.Series
  172.34 +{
  172.35 +    /// <summary>
  172.36 +    /// Defines properties for stacked series.
  172.37 +    /// </summary>
  172.38 +    public interface IStackableSeries
  172.39 +    {
  172.40 +        /// <summary>
  172.41 +        /// Gets a value indicating whether this series is stacked.
  172.42 +        /// </summary>
  172.43 +        bool IsStacked { get; }
  172.44 +
  172.45 +        /// <summary>
  172.46 +        /// Gets the stack group.
  172.47 +        /// </summary>
  172.48 +        /// <value>
  172.49 +        /// The stack group.
  172.50 +        /// </value>
  172.51 +        string StackGroup { get; }
  172.52 +    }
  172.53 +}
  172.54 \ No newline at end of file
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/IntervalBarItem.cs	Sat Jun 08 16:53:22 2013 +0000
   173.3 @@ -0,0 +1,110 @@
   173.4 +// --------------------------------------------------------------------------------------------------------------------
   173.5 +// <copyright file="IntervalBarItem.cs" company="OxyPlot">
   173.6 +//   The MIT License (MIT)
   173.7 +//
   173.8 +//   Copyright (c) 2012 Oystein Bjorke
   173.9 +//
  173.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  173.11 +//   copy of this software and associated documentation files (the
  173.12 +//   "Software"), to deal in the Software without restriction, including
  173.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  173.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  173.15 +//   permit persons to whom the Software is furnished to do so, subject to
  173.16 +//   the following conditions:
  173.17 +//
  173.18 +//   The above copyright notice and this permission notice shall be included
  173.19 +//   in all copies or substantial portions of the Software.
  173.20 +//
  173.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  173.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  173.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  173.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  173.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  173.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  173.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  173.28 +// </copyright>
  173.29 +// <summary>
  173.30 +//   Represents an item in an IntervalBarSeries.
  173.31 +// </summary>
  173.32 +// --------------------------------------------------------------------------------------------------------------------
  173.33 +namespace OxyPlot.Series
  173.34 +{
  173.35 +    /// <summary>
  173.36 +    /// Represents an item in an IntervalBarSeries.
  173.37 +    /// </summary>
  173.38 +    public class IntervalBarItem : CategorizedItem, ICodeGenerating
  173.39 +    {
  173.40 +        /// <summary>
  173.41 +        /// Initializes a new instance of the <see cref="IntervalBarItem"/> class.
  173.42 +        /// </summary>
  173.43 +        public IntervalBarItem()
  173.44 +        {
  173.45 +        }
  173.46 +
  173.47 +        /// <summary>
  173.48 +        /// Initializes a new instance of the <see cref="IntervalBarItem"/> class.
  173.49 +        /// </summary>
  173.50 +        /// <param name="start">
  173.51 +        /// The start.
  173.52 +        /// </param>
  173.53 +        /// <param name="end">
  173.54 +        /// The end.
  173.55 +        /// </param>
  173.56 +        /// <param name="title">
  173.57 +        /// The title.
  173.58 +        /// </param>
  173.59 +        /// <param name="color">
  173.60 +        /// The color.
  173.61 +        /// </param>
  173.62 +        public IntervalBarItem(double start, double end, string title = null, OxyColor color = null)
  173.63 +        {
  173.64 +            this.Start = start;
  173.65 +            this.End = end;
  173.66 +            this.Title = title;
  173.67 +            this.Color = color;
  173.68 +        }
  173.69 +
  173.70 +        /// <summary>
  173.71 +        /// Gets or sets the color.
  173.72 +        /// </summary>
  173.73 +        public OxyColor Color { get; set; }
  173.74 +
  173.75 +        /// <summary>
  173.76 +        /// Gets or sets the end value.
  173.77 +        /// </summary>
  173.78 +        public double End { get; set; }
  173.79 +
  173.80 +        /// <summary>
  173.81 +        /// Gets or sets the start value.
  173.82 +        /// </summary>
  173.83 +        public double Start { get; set; }
  173.84 +
  173.85 +        /// <summary>
  173.86 +        /// Gets or sets the title.
  173.87 +        /// </summary>
  173.88 +        public string Title { get; set; }
  173.89 +
  173.90 +        /// <summary>
  173.91 +        /// Returns c# code that generates this instance.
  173.92 +        /// </summary>
  173.93 +        /// <returns>
  173.94 +        /// C# code.
  173.95 +        /// </returns>
  173.96 +        public string ToCode()
  173.97 +        {
  173.98 +            if (this.Color != null)
  173.99 +            {
 173.100 +                return CodeGenerator.FormatConstructor(
 173.101 +                    this.GetType(), "{0},{1},{2},{3}", this.Start, this.End, this.Title, this.Color.ToCode());
 173.102 +            }
 173.103 +
 173.104 +            if (this.Title != null)
 173.105 +            {
 173.106 +                return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1},{2}", this.Start, this.End, this.Title);
 173.107 +            }
 173.108 +
 173.109 +            return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.Start, this.End);
 173.110 +        }
 173.111 +
 173.112 +    }
 173.113 +}
 173.114 \ No newline at end of file
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/IntervalBarSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   174.3 @@ -0,0 +1,515 @@
   174.4 +// --------------------------------------------------------------------------------------------------------------------
   174.5 +// <copyright file="IntervalBarSeries.cs" company="OxyPlot">
   174.6 +//   The MIT License (MIT)
   174.7 +//
   174.8 +//   Copyright (c) 2012 Oystein Bjorke
   174.9 +//
  174.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  174.11 +//   copy of this software and associated documentation files (the
  174.12 +//   "Software"), to deal in the Software without restriction, including
  174.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  174.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  174.15 +//   permit persons to whom the Software is furnished to do so, subject to
  174.16 +//   the following conditions:
  174.17 +//
  174.18 +//   The above copyright notice and this permission notice shall be included
  174.19 +//   in all copies or substantial portions of the Software.
  174.20 +//
  174.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  174.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  174.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  174.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  174.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  174.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  174.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  174.28 +// </copyright>
  174.29 +// <summary>
  174.30 +//   Represents a series for bar charts defined by to/from values.
  174.31 +// </summary>
  174.32 +// --------------------------------------------------------------------------------------------------------------------
  174.33 +namespace OxyPlot.Series
  174.34 +{
  174.35 +    using System;
  174.36 +    using System.Collections.Generic;
  174.37 +    using System.Linq;
  174.38 +
  174.39 +    using OxyPlot.Axes;
  174.40 +
  174.41 +    /// <summary>
  174.42 +    /// Represents a series for bar charts defined by to/from values.
  174.43 +    /// </summary>
  174.44 +    public class IntervalBarSeries : CategorizedSeries, IStackableSeries
  174.45 +    {
  174.46 +        /// <summary>
  174.47 +        /// The default fill color.
  174.48 +        /// </summary>
  174.49 +        private OxyColor defaultFillColor;
  174.50 +
  174.51 +        /// <summary>
  174.52 +        /// Initializes a new instance of the <see cref="IntervalBarSeries"/> class.
  174.53 +        /// </summary>
  174.54 +        public IntervalBarSeries()
  174.55 +        {
  174.56 +            this.Items = new List<IntervalBarItem>();
  174.57 +
  174.58 +            this.StrokeColor = OxyColors.Black;
  174.59 +            this.StrokeThickness = 1;
  174.60 +            this.BarWidth = 1;
  174.61 +
  174.62 +            this.TrackerFormatString = "{0}";
  174.63 +            this.LabelMargin = 4;
  174.64 +
  174.65 +            this.LabelFormatString = "{2}"; // title
  174.66 +
  174.67 +            // this.LabelFormatString = "{0}-{1}"; // Minimum-Maximum
  174.68 +        }
  174.69 +
  174.70 +        /// <summary>
  174.71 +        /// Gets or sets the width of the bars (as a fraction of the available width). The default value is 0.5 (50%)
  174.72 +        /// </summary>
  174.73 +        /// <value>
  174.74 +        /// The width of the bars.
  174.75 +        /// </value>
  174.76 +        public double BarWidth { get; set; }
  174.77 +
  174.78 +        /// <summary>
  174.79 +        /// Gets or sets the default color of the interior of the Maximum bars.
  174.80 +        /// </summary>
  174.81 +        /// <value>
  174.82 +        /// The color.
  174.83 +        /// </value>
  174.84 +        public OxyColor FillColor { get; set; }
  174.85 +
  174.86 +        /// <summary>
  174.87 +        /// Gets the actual fill color.
  174.88 +        /// </summary>
  174.89 +        /// <value>The actual color.</value>
  174.90 +        public OxyColor ActualFillColor
  174.91 +        {
  174.92 +            get { return this.FillColor ?? this.defaultFillColor; }
  174.93 +        }
  174.94 +
  174.95 +        /// <summary>
  174.96 +        /// Gets a value indicating whether IsStacked.
  174.97 +        /// </summary>
  174.98 +        public bool IsStacked
  174.99 +        {
 174.100 +            get
 174.101 +            {
 174.102 +                return true;
 174.103 +            }
 174.104 +        }
 174.105 +
 174.106 +        /// <summary>
 174.107 +        /// Gets the range bar items.
 174.108 +        /// </summary>
 174.109 +        public IList<IntervalBarItem> Items { get; private set; }
 174.110 +
 174.111 +        /// <summary>
 174.112 +        /// Gets or sets the label color.
 174.113 +        /// </summary>
 174.114 +        public OxyColor LabelColor { get; set; }
 174.115 +
 174.116 +        /// <summary>
 174.117 +        /// Gets or sets the label field.
 174.118 +        /// </summary>
 174.119 +        public string LabelField { get; set; }
 174.120 +
 174.121 +        /// <summary>
 174.122 +        /// Gets or sets the format string for the maximum labels.
 174.123 +        /// </summary>
 174.124 +        public string LabelFormatString { get; set; }
 174.125 +
 174.126 +        /// <summary>
 174.127 +        /// Gets or sets the label margins.
 174.128 +        /// </summary>
 174.129 +        public double LabelMargin { get; set; }
 174.130 +
 174.131 +        /// <summary>
 174.132 +        /// Gets or sets the maximum value field.
 174.133 +        /// </summary>
 174.134 +        public string MaximumField { get; set; }
 174.135 +
 174.136 +        /// <summary>
 174.137 +        /// Gets or sets the minimum value field.
 174.138 +        /// </summary>
 174.139 +        public string MinimumField { get; set; }
 174.140 +
 174.141 +        /// <summary>
 174.142 +        /// Gets StackGroup.
 174.143 +        /// </summary>
 174.144 +        public string StackGroup
 174.145 +        {
 174.146 +            get
 174.147 +            {
 174.148 +                return string.Empty;
 174.149 +            }
 174.150 +        }
 174.151 +
 174.152 +        /// <summary>
 174.153 +        /// Gets or sets the color of the border around the bars.
 174.154 +        /// </summary>
 174.155 +        /// <value>
 174.156 +        /// The color of the stroke.
 174.157 +        /// </value>
 174.158 +        public OxyColor StrokeColor { get; set; }
 174.159 +
 174.160 +        /// <summary>
 174.161 +        /// Gets or sets the thickness of the bar border strokes.
 174.162 +        /// </summary>
 174.163 +        /// <value>
 174.164 +        /// The stroke thickness.
 174.165 +        /// </value>
 174.166 +        public double StrokeThickness { get; set; }
 174.167 +
 174.168 +        /// <summary>
 174.169 +        /// Gets or sets the actual rectangles for the maximum bars.
 174.170 +        /// </summary>
 174.171 +        protected internal IList<OxyRect> ActualBarRectangles { get; set; }
 174.172 +
 174.173 +        /// <summary>
 174.174 +        /// Gets or sets the valid items
 174.175 +        /// </summary>
 174.176 +        protected internal IList<IntervalBarItem> ValidItems { get; set; }
 174.177 +
 174.178 +        /// <summary>
 174.179 +        /// Gets or sets the dictionary which stores the index-inversion for the valid items
 174.180 +        /// </summary>
 174.181 +        protected internal Dictionary<int, int> ValidItemsIndexInversion { get; set; }
 174.182 +
 174.183 +        /// <summary>
 174.184 +        /// Gets the point in the dataset that is nearest the specified point.
 174.185 +        /// </summary>
 174.186 +        /// <param name="point">
 174.187 +        /// The point.
 174.188 +        /// </param>
 174.189 +        /// <param name="interpolate">
 174.190 +        /// The interpolate.
 174.191 +        /// </param>
 174.192 +        /// <returns>
 174.193 +        /// A TrackerHitResult for the current hit.
 174.194 +        /// </returns>
 174.195 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 174.196 +        {
 174.197 +            for (int i = 0; i < this.ActualBarRectangles.Count; i++)
 174.198 +            {
 174.199 +                var r = this.ActualBarRectangles[i];
 174.200 +                if (r.Contains(point))
 174.201 +                {
 174.202 +                    var item = (IntervalBarItem)this.GetItem(this.ValidItemsIndexInversion[i]);
 174.203 +                    var categoryIndex = item.GetCategoryIndex(i);
 174.204 +                    double value = (this.ValidItems[i].Start + this.ValidItems[i].End) / 2;
 174.205 +                    var dp = new DataPoint(categoryIndex, value);
 174.206 +                    var text = StringHelper.Format(
 174.207 +                        this.ActualCulture,
 174.208 +                        this.TrackerFormatString,
 174.209 +                        item,
 174.210 +                        this.Items[i].Start,
 174.211 +                        this.Items[i].End,
 174.212 +                        this.Items[i].Title);
 174.213 +                    return new TrackerHitResult(this, dp, point, item, i, text);
 174.214 +                }
 174.215 +            }
 174.216 +
 174.217 +            return null;
 174.218 +        }
 174.219 +
 174.220 +        /// <summary>
 174.221 +        /// Checks if the specified value is valid.
 174.222 +        /// </summary>
 174.223 +        /// <param name="v">
 174.224 +        /// The value.
 174.225 +        /// </param>
 174.226 +        /// <param name="yaxis">
 174.227 +        /// The y axis.
 174.228 +        /// </param>
 174.229 +        /// <returns>
 174.230 +        /// True if the value is valid.
 174.231 +        /// </returns>
 174.232 +        public virtual bool IsValidPoint(double v, Axis yaxis)
 174.233 +        {
 174.234 +            return !double.IsNaN(v) && !double.IsInfinity(v);
 174.235 +        }
 174.236 +
 174.237 +        /// <summary>
 174.238 +        /// Renders the Series on the specified rendering context.
 174.239 +        /// </summary>
 174.240 +        /// <param name="rc">
 174.241 +        /// The rendering context.
 174.242 +        /// </param>
 174.243 +        /// <param name="model">
 174.244 +        /// The model.
 174.245 +        /// </param>
 174.246 +        public override void Render(IRenderContext rc, PlotModel model)
 174.247 +        {
 174.248 +            this.ActualBarRectangles = new List<OxyRect>();
 174.249 +
 174.250 +            if (this.ValidItems.Count == 0)
 174.251 +            {
 174.252 +                return;
 174.253 +            }
 174.254 +
 174.255 +            var clippingRect = this.GetClippingRect();
 174.256 +            var categoryAxis = this.GetCategoryAxis();
 174.257 +
 174.258 +            var actualBarWidth = this.GetActualBarWidth();
 174.259 +            var stackIndex = categoryAxis.StackIndexMapping[this.StackGroup];
 174.260 +
 174.261 +            for (var i = 0; i < this.ValidItems.Count; i++)
 174.262 +            {
 174.263 +                var item = this.ValidItems[i];
 174.264 +
 174.265 +                var categoryIndex = item.GetCategoryIndex(i);
 174.266 +                double categoryValue = categoryAxis.GetCategoryValue(categoryIndex, stackIndex, actualBarWidth);
 174.267 +
 174.268 +                var p0 = this.Transform(item.Start, categoryValue);
 174.269 +                var p1 = this.Transform(item.End, categoryValue + actualBarWidth);
 174.270 +
 174.271 +                var rectangle = OxyRect.Create(p0.X, p0.Y, p1.X, p1.Y);
 174.272 +
 174.273 +                this.ActualBarRectangles.Add(rectangle);
 174.274 +
 174.275 +                rc.DrawClippedRectangleAsPolygon(
 174.276 +                    rectangle,
 174.277 +                    clippingRect,
 174.278 +                    this.GetSelectableFillColor(item.Color ?? this.ActualFillColor),
 174.279 +                    this.StrokeColor,
 174.280 +                    this.StrokeThickness);
 174.281 +
 174.282 +                if (this.LabelFormatString != null)
 174.283 +                {
 174.284 +                    var s = StringHelper.Format(
 174.285 +                        this.ActualCulture, this.LabelFormatString, this.GetItem(i), item.Start, item.End, item.Title);
 174.286 +
 174.287 +                    var pt = new ScreenPoint(
 174.288 +                        (rectangle.Left + rectangle.Right) / 2, (rectangle.Top + rectangle.Bottom) / 2);
 174.289 +
 174.290 +                    rc.DrawClippedText(
 174.291 +                        clippingRect,
 174.292 +                        pt,
 174.293 +                        s,
 174.294 +                        this.ActualTextColor,
 174.295 +                        this.ActualFont,
 174.296 +                        this.ActualFontSize,
 174.297 +                        this.ActualFontWeight,
 174.298 +                        0,
 174.299 +                        HorizontalAlignment.Center,
 174.300 +                        VerticalAlignment.Middle);
 174.301 +                }
 174.302 +            }
 174.303 +        }
 174.304 +
 174.305 +        /// <summary>
 174.306 +        /// Renders the legend symbol on the specified rendering context.
 174.307 +        /// </summary>
 174.308 +        /// <param name="rc">
 174.309 +        /// The rendering context.
 174.310 +        /// </param>
 174.311 +        /// <param name="legendBox">
 174.312 +        /// The legend rectangle.
 174.313 +        /// </param>
 174.314 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 174.315 +        {
 174.316 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 174.317 +            double ymid = (legendBox.Top + legendBox.Bottom) / 2;
 174.318 +            double height = (legendBox.Bottom - legendBox.Top) * 0.8;
 174.319 +            double width = height;
 174.320 +            rc.DrawRectangleAsPolygon(
 174.321 +                new OxyRect(xmid - (0.5 * width), ymid - (0.5 * height), width, height),
 174.322 +                this.GetSelectableFillColor(this.ActualFillColor),
 174.323 +                this.StrokeColor,
 174.324 +                this.StrokeThickness);
 174.325 +        }
 174.326 +
 174.327 +        /// <summary>
 174.328 +        /// Gets or sets the width/height of the columns/bars (as a fraction of the available space).
 174.329 +        /// </summary>
 174.330 +        /// <returns>
 174.331 +        /// The fractional width.
 174.332 +        /// </returns>
 174.333 +        /// <value>
 174.334 +        /// The width of the bars.
 174.335 +        /// </value>
 174.336 +        /// <remarks>
 174.337 +        /// The available space will be determined by the GapWidth of the CategoryAxis used by this series.
 174.338 +        /// </remarks>
 174.339 +        internal override double GetBarWidth()
 174.340 +        {
 174.341 +            return this.BarWidth;
 174.342 +        }
 174.343 +
 174.344 +        /// <summary>
 174.345 +        /// Gets the items of this series.
 174.346 +        /// </summary>
 174.347 +        /// <returns>
 174.348 +        /// The items.
 174.349 +        /// </returns>
 174.350 +        protected internal override IList<CategorizedItem> GetItems()
 174.351 +        {
 174.352 +            return this.Items.Cast<CategorizedItem>().ToList();
 174.353 +        }
 174.354 +
 174.355 +        /// <summary>
 174.356 +        /// Check if the data series is using the specified axis.
 174.357 +        /// </summary>
 174.358 +        /// <param name="axis">
 174.359 +        /// An axis which should be checked if used
 174.360 +        /// </param>
 174.361 +        /// <returns>
 174.362 +        /// True if the axis is in use.
 174.363 +        /// </returns>
 174.364 +        protected internal override bool IsUsing(Axis axis)
 174.365 +        {
 174.366 +            return this.XAxis == axis || this.YAxis == axis;
 174.367 +        }
 174.368 +
 174.369 +        /// <summary>
 174.370 +        /// The set default values.
 174.371 +        /// </summary>
 174.372 +        /// <param name="model">
 174.373 +        /// The model.
 174.374 +        /// </param>
 174.375 +        protected internal override void SetDefaultValues(PlotModel model)
 174.376 +        {
 174.377 +            if (this.FillColor == null)
 174.378 +            {
 174.379 +                this.defaultFillColor = model.GetDefaultColor();
 174.380 +            }
 174.381 +        }
 174.382 +
 174.383 +        /// <summary>
 174.384 +        /// Updates the axis maximum and minimum values.
 174.385 +        /// </summary>
 174.386 +        protected internal override void UpdateAxisMaxMin()
 174.387 +        {
 174.388 +            this.XAxis.Include(this.MinX);
 174.389 +            this.XAxis.Include(this.MaxX);
 174.390 +        }
 174.391 +
 174.392 +        /// <summary>
 174.393 +        /// Updates the data.
 174.394 +        /// </summary>
 174.395 +        protected internal override void UpdateData()
 174.396 +        {
 174.397 +            if (this.ItemsSource != null)
 174.398 +            {
 174.399 +                this.Items.Clear();
 174.400 +
 174.401 +                var filler = new ListFiller<IntervalBarItem>();
 174.402 +                filler.Add(this.MinimumField, (item, value) => item.Start = Convert.ToDouble(value));
 174.403 +                filler.Add(this.MaximumField, (item, value) => item.End = Convert.ToDouble(value));
 174.404 +                filler.FillT(this.Items, this.ItemsSource);
 174.405 +            }
 174.406 +        }
 174.407 +
 174.408 +        /// <summary>
 174.409 +        /// Updates the maximum/minimum value on the value axis from the bar values.
 174.410 +        /// </summary>
 174.411 +        protected internal override void UpdateMaxMin()
 174.412 +        {
 174.413 +            base.UpdateMaxMin();
 174.414 +
 174.415 +            if (this.ValidItems == null || this.ValidItems.Count == 0)
 174.416 +            {
 174.417 +                return;
 174.418 +            }
 174.419 +
 174.420 +            double minValue = double.MaxValue;
 174.421 +            double maxValue = double.MinValue;
 174.422 +
 174.423 +            foreach (var item in this.ValidItems)
 174.424 +            {
 174.425 +                minValue = Math.Min(minValue, item.Start);
 174.426 +                minValue = Math.Min(minValue, item.End);
 174.427 +                maxValue = Math.Max(maxValue, item.Start);
 174.428 +                maxValue = Math.Max(maxValue, item.End);
 174.429 +            }
 174.430 +
 174.431 +            this.MinX = minValue;
 174.432 +            this.MaxX = maxValue;
 174.433 +        }
 174.434 +
 174.435 +        /// <summary>
 174.436 +        /// Updates the valid items
 174.437 +        /// </summary>
 174.438 +        protected internal override void UpdateValidData()
 174.439 +        {
 174.440 +            this.ValidItems = new List<IntervalBarItem>();
 174.441 +            this.ValidItemsIndexInversion = new Dictionary<int, int>();
 174.442 +            var valueAxis = this.GetValueAxis();
 174.443 +
 174.444 +            for (var i = 0; i < this.Items.Count; i++)
 174.445 +            {
 174.446 +                var item = this.Items[i];
 174.447 +                if (valueAxis.IsValidValue(item.Start) && valueAxis.IsValidValue(item.End))
 174.448 +                {
 174.449 +                    this.ValidItemsIndexInversion.Add(this.ValidItems.Count, i);
 174.450 +                    this.ValidItems.Add(item);
 174.451 +                }
 174.452 +            }
 174.453 +        }
 174.454 +
 174.455 +        /// <summary>
 174.456 +        /// Gets the actual width/height of the items of this series.
 174.457 +        /// </summary>
 174.458 +        /// <returns>
 174.459 +        /// The width or height.
 174.460 +        /// </returns>
 174.461 +        /// <remarks>
 174.462 +        /// The actual width is also influenced by the GapWidth of the CategoryAxis used by this series.
 174.463 +        /// </remarks>
 174.464 +        protected override double GetActualBarWidth()
 174.465 +        {
 174.466 +            var categoryAxis = this.GetCategoryAxis();
 174.467 +            return this.BarWidth / (1 + categoryAxis.GapWidth) / categoryAxis.MaxWidth;
 174.468 +        }
 174.469 +
 174.470 +        /// <summary>
 174.471 +        /// Gets the category axis.
 174.472 +        /// </summary>
 174.473 +        /// <returns>
 174.474 +        /// The category axis.
 174.475 +        /// </returns>
 174.476 +        protected override CategoryAxis GetCategoryAxis()
 174.477 +        {
 174.478 +            var categoryAxis = this.YAxis as CategoryAxis;
 174.479 +            if (categoryAxis == null)
 174.480 +            {
 174.481 +                throw new InvalidOperationException("No category axis defined.");
 174.482 +            }
 174.483 +
 174.484 +            return categoryAxis;
 174.485 +        }
 174.486 +
 174.487 +        /// <summary>
 174.488 +        /// Gets the item at the specified index.
 174.489 +        /// </summary>
 174.490 +        /// <param name="i">
 174.491 +        /// The index of the item.
 174.492 +        /// </param>
 174.493 +        /// <returns>
 174.494 +        /// The item of the index.
 174.495 +        /// </returns>
 174.496 +        protected override object GetItem(int i)
 174.497 +        {
 174.498 +            if (this.ItemsSource != null || this.Items == null || this.Items.Count == 0)
 174.499 +            {
 174.500 +                return base.GetItem(i);
 174.501 +            }
 174.502 +
 174.503 +            return this.Items[i];
 174.504 +        }
 174.505 +
 174.506 +        /// <summary>
 174.507 +        /// Gets the value axis.
 174.508 +        /// </summary>
 174.509 +        /// <returns>
 174.510 +        /// The value axis.
 174.511 +        /// </returns>
 174.512 +        private Axis GetValueAxis()
 174.513 +        {
 174.514 +            return this.XAxis;
 174.515 +        }
 174.516 +
 174.517 +    }
 174.518 +}
 174.519 \ No newline at end of file
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/LabelPlacement.cs	Sat Jun 08 16:53:22 2013 +0000
   175.3 @@ -0,0 +1,57 @@
   175.4 +// --------------------------------------------------------------------------------------------------------------------
   175.5 +// <copyright file="LabelPlacement.cs" company="OxyPlot">
   175.6 +//   The MIT License (MIT)
   175.7 +//
   175.8 +//   Copyright (c) 2012 Oystein Bjorke
   175.9 +//
  175.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  175.11 +//   copy of this software and associated documentation files (the
  175.12 +//   "Software"), to deal in the Software without restriction, including
  175.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  175.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  175.15 +//   permit persons to whom the Software is furnished to do so, subject to
  175.16 +//   the following conditions:
  175.17 +//
  175.18 +//   The above copyright notice and this permission notice shall be included
  175.19 +//   in all copies or substantial portions of the Software.
  175.20 +//
  175.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  175.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  175.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  175.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  175.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  175.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  175.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  175.28 +// </copyright>
  175.29 +// <summary>
  175.30 +//   Placement of the labels.
  175.31 +// </summary>
  175.32 +// --------------------------------------------------------------------------------------------------------------------
  175.33 +namespace OxyPlot.Series
  175.34 +{
  175.35 +    /// <summary>
  175.36 +    /// Placement of the labels.
  175.37 +    /// </summary>
  175.38 +    public enum LabelPlacement
  175.39 +    {
  175.40 +        /// <summary>
  175.41 +        /// Placed outside the bar.
  175.42 +        /// </summary>
  175.43 +        Outside,
  175.44 +
  175.45 +        /// <summary>
  175.46 +        /// Placed inside the bar.
  175.47 +        /// </summary>
  175.48 +        Inside,
  175.49 +
  175.50 +        /// <summary>
  175.51 +        /// Placed inside in the middle/center of the bar.
  175.52 +        /// </summary>
  175.53 +        Middle,
  175.54 +
  175.55 +        /// <summary>
  175.56 +        /// Placed inside at the base of the bar.
  175.57 +        /// </summary>
  175.58 +        Base
  175.59 +    }
  175.60 +}
  175.61 \ No newline at end of file
   176.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/RectangleBarItem.cs	Sat Jun 08 16:53:22 2013 +0000
   176.3 @@ -0,0 +1,137 @@
   176.4 +// --------------------------------------------------------------------------------------------------------------------
   176.5 +// <copyright file="RectangleBarItem.cs" company="OxyPlot">
   176.6 +//   The MIT License (MIT)
   176.7 +//
   176.8 +//   Copyright (c) 2012 Oystein Bjorke
   176.9 +//
  176.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  176.11 +//   copy of this software and associated documentation files (the
  176.12 +//   "Software"), to deal in the Software without restriction, including
  176.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  176.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  176.15 +//   permit persons to whom the Software is furnished to do so, subject to
  176.16 +//   the following conditions:
  176.17 +//
  176.18 +//   The above copyright notice and this permission notice shall be included
  176.19 +//   in all copies or substantial portions of the Software.
  176.20 +//
  176.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  176.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  176.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  176.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  176.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  176.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  176.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  176.28 +// </copyright>
  176.29 +// <summary>
  176.30 +//   Represents a rectangle item in a RectangleBarSeries.
  176.31 +// </summary>
  176.32 +// --------------------------------------------------------------------------------------------------------------------
  176.33 +namespace OxyPlot.Series
  176.34 +{
  176.35 +    /// <summary>
  176.36 +    /// Represents a rectangle item in a RectangleBarSeries.
  176.37 +    /// </summary>
  176.38 +    public class RectangleBarItem : ICodeGenerating
  176.39 +    {
  176.40 +        /// <summary>
  176.41 +        /// Initializes a new instance of the <see cref="RectangleBarItem"/> class.
  176.42 +        /// </summary>
  176.43 +        public RectangleBarItem()
  176.44 +        {
  176.45 +        }
  176.46 +
  176.47 +        /// <summary>
  176.48 +        /// Initializes a new instance of the <see cref="RectangleBarItem"/> class.
  176.49 +        /// </summary>
  176.50 +        /// <param name="x0">
  176.51 +        /// The x0.
  176.52 +        /// </param>
  176.53 +        /// <param name="y0">
  176.54 +        /// The y0.
  176.55 +        /// </param>
  176.56 +        /// <param name="x1">
  176.57 +        /// The x1.
  176.58 +        /// </param>
  176.59 +        /// <param name="y1">
  176.60 +        /// The y1.
  176.61 +        /// </param>
  176.62 +        /// <param name="title">
  176.63 +        /// The title.
  176.64 +        /// </param>
  176.65 +        /// <param name="color">
  176.66 +        /// The color.
  176.67 +        /// </param>
  176.68 +        public RectangleBarItem(double x0, double y0, double x1, double y1, string title = null, OxyColor color = null)
  176.69 +        {
  176.70 +            this.X0 = x0;
  176.71 +            this.Y0 = y0;
  176.72 +            this.X1 = x1;
  176.73 +            this.Y1 = y1;
  176.74 +            this.Title = title;
  176.75 +            this.Color = color;
  176.76 +        }
  176.77 +
  176.78 +        /// <summary>
  176.79 +        /// Gets or sets the color.
  176.80 +        /// </summary>
  176.81 +        public OxyColor Color { get; set; }
  176.82 +
  176.83 +        /// <summary>
  176.84 +        /// Gets or sets the title.
  176.85 +        /// </summary>
  176.86 +        public string Title { get; set; }
  176.87 +
  176.88 +        /// <summary>
  176.89 +        /// Gets or sets the x0 coordinate.
  176.90 +        /// </summary>
  176.91 +        public double X0 { get; set; }
  176.92 +
  176.93 +        /// <summary>
  176.94 +        /// Gets or sets the x1 coordinate.
  176.95 +        /// </summary>
  176.96 +        public double X1 { get; set; }
  176.97 +
  176.98 +        /// <summary>
  176.99 +        /// Gets or sets the y0 coordinate.
 176.100 +        /// </summary>
 176.101 +        public double Y0 { get; set; }
 176.102 +
 176.103 +        /// <summary>
 176.104 +        /// Gets or sets the y1 coordinate.
 176.105 +        /// </summary>
 176.106 +        public double Y1 { get; set; }
 176.107 +
 176.108 +        /// <summary>
 176.109 +        /// Returns c# code that generates this instance.
 176.110 +        /// </summary>
 176.111 +        /// <returns>
 176.112 +        /// C# code.
 176.113 +        /// </returns>
 176.114 +        public string ToCode()
 176.115 +        {
 176.116 +            if (this.Color != null)
 176.117 +            {
 176.118 +                return CodeGenerator.FormatConstructor(
 176.119 +                    this.GetType(),
 176.120 +                    "{0},{1},{2},{3},{4},{5}",
 176.121 +                    this.X0,
 176.122 +                    this.Y0,
 176.123 +                    this.X1,
 176.124 +                    this.Y1,
 176.125 +                    this.Title,
 176.126 +                    this.Color.ToCode());
 176.127 +            }
 176.128 +
 176.129 +            if (this.Title != null)
 176.130 +            {
 176.131 +                return CodeGenerator.FormatConstructor(
 176.132 +                    this.GetType(), "{0},{1},{2},{3},{4}", this.X0, this.Y0, this.X1, this.Y1, this.Title);
 176.133 +            }
 176.134 +
 176.135 +            return CodeGenerator.FormatConstructor(
 176.136 +                this.GetType(), "{0},{1},{2},{3}", this.X0, this.Y0, this.X1, this.Y1);
 176.137 +        }
 176.138 +
 176.139 +    }
 176.140 +}
 176.141 \ No newline at end of file
   177.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/RectangleBarSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   177.3 @@ -0,0 +1,337 @@
   177.4 +// --------------------------------------------------------------------------------------------------------------------
   177.5 +// <copyright file="RectangleBarSeries.cs" company="OxyPlot">
   177.6 +//   The MIT License (MIT)
   177.7 +//
   177.8 +//   Copyright (c) 2012 Oystein Bjorke
   177.9 +//
  177.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  177.11 +//   copy of this software and associated documentation files (the
  177.12 +//   "Software"), to deal in the Software without restriction, including
  177.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  177.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  177.15 +//   permit persons to whom the Software is furnished to do so, subject to
  177.16 +//   the following conditions:
  177.17 +//
  177.18 +//   The above copyright notice and this permission notice shall be included
  177.19 +//   in all copies or substantial portions of the Software.
  177.20 +//
  177.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  177.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  177.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  177.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  177.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  177.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  177.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  177.28 +// </copyright>
  177.29 +// <summary>
  177.30 +//   Represents a series for bar charts where the bars are defined by rectangles.
  177.31 +// </summary>
  177.32 +// --------------------------------------------------------------------------------------------------------------------
  177.33 +namespace OxyPlot.Series
  177.34 +{
  177.35 +    using System;
  177.36 +    using System.Collections.Generic;
  177.37 +
  177.38 +    /// <summary>
  177.39 +    /// Represents a series for bar charts where the bars are defined by rectangles.
  177.40 +    /// </summary>
  177.41 +    public class RectangleBarSeries : XYAxisSeries
  177.42 +    {
  177.43 +        /// <summary>
  177.44 +        /// The default fill color.
  177.45 +        /// </summary>
  177.46 +        private OxyColor defaultFillColor;
  177.47 +
  177.48 +        /// <summary>
  177.49 +        /// Initializes a new instance of the <see cref="RectangleBarSeries"/> class.
  177.50 +        /// </summary>
  177.51 +        public RectangleBarSeries()
  177.52 +        {
  177.53 +            this.Items = new List<RectangleBarItem>();
  177.54 +
  177.55 +            this.StrokeColor = OxyColors.Black;
  177.56 +            this.StrokeThickness = 1;
  177.57 +
  177.58 +            this.TrackerFormatString = "{0}";
  177.59 +
  177.60 +            this.LabelFormatString = "{4}"; // title
  177.61 +
  177.62 +            // this.LabelFormatString = "{0}-{1},{2}-{3}"; // X0-X1,Y0-Y1
  177.63 +        }
  177.64 +
  177.65 +        /// <summary>
  177.66 +        /// Gets or sets the default color of the interior of the rectangles.
  177.67 +        /// </summary>
  177.68 +        /// <value>
  177.69 +        /// The color.
  177.70 +        /// </value>
  177.71 +        public OxyColor FillColor { get; set; }
  177.72 +
  177.73 +        /// <summary>
  177.74 +        /// Gets the actual fill color.
  177.75 +        /// </summary>
  177.76 +        /// <value>The actual color.</value>
  177.77 +        public OxyColor ActualFillColor
  177.78 +        {
  177.79 +            get { return this.FillColor ?? this.defaultFillColor; }
  177.80 +        }
  177.81 +
  177.82 +        /// <summary>
  177.83 +        /// Gets the rectangle bar items.
  177.84 +        /// </summary>
  177.85 +        public IList<RectangleBarItem> Items { get; private set; }
  177.86 +
  177.87 +        /// <summary>
  177.88 +        /// Gets or sets the label color.
  177.89 +        /// </summary>
  177.90 +        public OxyColor LabelColor { get; set; }
  177.91 +
  177.92 +        /// <summary>
  177.93 +        /// Gets or sets the format string for the labels.
  177.94 +        /// </summary>
  177.95 +        public string LabelFormatString { get; set; }
  177.96 +
  177.97 +        /// <summary>
  177.98 +        /// Gets or sets the color of the border around the rectangles.
  177.99 +        /// </summary>
 177.100 +        /// <value>
 177.101 +        /// The color of the stroke.
 177.102 +        /// </value>
 177.103 +        public OxyColor StrokeColor { get; set; }
 177.104 +
 177.105 +        /// <summary>
 177.106 +        /// Gets or sets the thickness of the border around the rectangles.
 177.107 +        /// </summary>
 177.108 +        /// <value>
 177.109 +        /// The stroke thickness.
 177.110 +        /// </value>
 177.111 +        public double StrokeThickness { get; set; }
 177.112 +
 177.113 +        /// <summary>
 177.114 +        /// Gets or sets the actual rectangles for the rectangles.
 177.115 +        /// </summary>
 177.116 +        internal IList<OxyRect> ActualBarRectangles { get; set; }
 177.117 +
 177.118 +        /// <summary>
 177.119 +        /// Gets the point in the dataset that is nearest the specified point.
 177.120 +        /// </summary>
 177.121 +        /// <param name="point">
 177.122 +        /// The point.
 177.123 +        /// </param>
 177.124 +        /// <param name="interpolate">
 177.125 +        /// Specifies whether to interpolate or not.
 177.126 +        /// </param>
 177.127 +        /// <returns>
 177.128 +        /// A <see cref="TrackerHitResult"/> for the current hit.
 177.129 +        /// </returns>
 177.130 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 177.131 +        {
 177.132 +            if (this.ActualBarRectangles == null)
 177.133 +            {
 177.134 +                return null;
 177.135 +            }
 177.136 +
 177.137 +            for (int i = 0; i < this.ActualBarRectangles.Count; i++)
 177.138 +            {
 177.139 +                var r = this.ActualBarRectangles[i];
 177.140 +                if (r.Contains(point))
 177.141 +                {
 177.142 +                    double value = (this.Items[i].Y0 + this.Items[i].Y1) / 2;
 177.143 +                    var sp = point;
 177.144 +                    var dp = new DataPoint(i, value);
 177.145 +                    var item = this.GetItem(i);
 177.146 +                    var text = StringHelper.Format(
 177.147 +                        this.ActualCulture,
 177.148 +                        this.TrackerFormatString,
 177.149 +                        item,
 177.150 +                        this.Items[i].X0,
 177.151 +                        this.Items[i].X1,
 177.152 +                        this.Items[i].Y0,
 177.153 +                        this.Items[i].Y1,
 177.154 +                        this.Items[i].Title);
 177.155 +                    return new TrackerHitResult(this, dp, sp, item, i, text);
 177.156 +                }
 177.157 +            }
 177.158 +
 177.159 +            return null;
 177.160 +        }
 177.161 +
 177.162 +        /// <summary>
 177.163 +        /// Checks if the specified value is valid.
 177.164 +        /// </summary>
 177.165 +        /// <param name="v">
 177.166 +        /// The value.
 177.167 +        /// </param>
 177.168 +        /// <returns>
 177.169 +        /// True if the value is valid.
 177.170 +        /// </returns>
 177.171 +        protected virtual bool IsValid(double v)
 177.172 +        {
 177.173 +            return !double.IsNaN(v) && !double.IsInfinity(v);
 177.174 +        }
 177.175 +
 177.176 +        /// <summary>
 177.177 +        /// Renders the Series on the specified rendering context.
 177.178 +        /// </summary>
 177.179 +        /// <param name="rc">
 177.180 +        /// The rendering context.
 177.181 +        /// </param>
 177.182 +        /// <param name="model">
 177.183 +        /// The model.
 177.184 +        /// </param>
 177.185 +        public override void Render(IRenderContext rc, PlotModel model)
 177.186 +        {
 177.187 +            if (this.Items.Count == 0)
 177.188 +            {
 177.189 +                return;
 177.190 +            }
 177.191 +
 177.192 +            var clippingRect = this.GetClippingRect();
 177.193 +
 177.194 +            int i = 0;
 177.195 +
 177.196 +            this.ActualBarRectangles = new List<OxyRect>();
 177.197 +
 177.198 +            foreach (var item in this.Items)
 177.199 +            {
 177.200 +                if (!this.IsValid(item.X0) || !this.IsValid(item.X1)
 177.201 +                    || !this.IsValid(item.Y0) || !this.IsValid(item.Y1))
 177.202 +                {
 177.203 +                    continue;
 177.204 +                }
 177.205 +
 177.206 +                var p0 = this.Transform(item.X0, item.Y0);
 177.207 +                var p1 = this.Transform(item.X1, item.Y1);
 177.208 +
 177.209 +                var rectangle = OxyRect.Create(p0.X, p0.Y, p1.X, p1.Y);
 177.210 +
 177.211 +                this.ActualBarRectangles.Add(rectangle);
 177.212 +
 177.213 +                rc.DrawClippedRectangleAsPolygon(
 177.214 +                    rectangle,
 177.215 +                    clippingRect,
 177.216 +                    this.GetSelectableFillColor(item.Color ?? this.ActualFillColor),
 177.217 +                    this.StrokeColor,
 177.218 +                    this.StrokeThickness);
 177.219 +
 177.220 +                if (this.LabelFormatString != null)
 177.221 +                {
 177.222 +                    var s = StringHelper.Format(
 177.223 +                        this.ActualCulture,
 177.224 +                        this.LabelFormatString,
 177.225 +                        this.GetItem(i),
 177.226 +                        item.X0,
 177.227 +                        item.X1,
 177.228 +                        item.Y0,
 177.229 +                        item.Y1,
 177.230 +                        item.Title);
 177.231 +
 177.232 +                    var pt = new ScreenPoint(
 177.233 +                        (rectangle.Left + rectangle.Right) / 2, (rectangle.Top + rectangle.Bottom) / 2);
 177.234 +
 177.235 +                    rc.DrawClippedText(
 177.236 +                        clippingRect,
 177.237 +                        pt,
 177.238 +                        s,
 177.239 +                        this.ActualTextColor,
 177.240 +                        this.ActualFont,
 177.241 +                        this.ActualFontSize,
 177.242 +                        this.ActualFontWeight,
 177.243 +                        0,
 177.244 +                        HorizontalAlignment.Center,
 177.245 +                        VerticalAlignment.Middle);
 177.246 +                }
 177.247 +
 177.248 +                i++;
 177.249 +            }
 177.250 +        }
 177.251 +
 177.252 +        /// <summary>
 177.253 +        /// Renders the legend symbol on the specified rendering context.
 177.254 +        /// </summary>
 177.255 +        /// <param name="rc">
 177.256 +        /// The rendering context.
 177.257 +        /// </param>
 177.258 +        /// <param name="legendBox">
 177.259 +        /// The legend rectangle.
 177.260 +        /// </param>
 177.261 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 177.262 +        {
 177.263 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 177.264 +            double ymid = (legendBox.Top + legendBox.Bottom) / 2;
 177.265 +            double height = (legendBox.Bottom - legendBox.Top) * 0.8;
 177.266 +            double width = height;
 177.267 +            rc.DrawRectangleAsPolygon(
 177.268 +                new OxyRect(xmid - (0.5 * width), ymid - (0.5 * height), width, height),
 177.269 +                this.GetSelectableFillColor(this.ActualFillColor),
 177.270 +                this.StrokeColor,
 177.271 +                this.StrokeThickness);
 177.272 +        }
 177.273 +
 177.274 +        /// <summary>
 177.275 +        /// Sets the default values.
 177.276 +        /// </summary>
 177.277 +        /// <param name="model">
 177.278 +        /// The model.
 177.279 +        /// </param>
 177.280 +        protected internal override void SetDefaultValues(PlotModel model)
 177.281 +        {
 177.282 +            if (this.FillColor == null)
 177.283 +            {
 177.284 +                this.defaultFillColor = model.GetDefaultColor();
 177.285 +            }
 177.286 +        }
 177.287 +
 177.288 +        /// <summary>
 177.289 +        /// Updates the data.
 177.290 +        /// </summary>
 177.291 +        protected internal override void UpdateData()
 177.292 +        {
 177.293 +            if (this.ItemsSource == null)
 177.294 +            {
 177.295 +                return;
 177.296 +            }
 177.297 +
 177.298 +            this.Items.Clear();
 177.299 +
 177.300 +            // ReflectionHelper.FillList(
 177.301 +            // this.ItemsSource,
 177.302 +            // this.Items,
 177.303 +            // new[] { this.MinimumField, this.MaximumField },
 177.304 +            // (item, value) => item.Minimum = Convert.ToDouble(value),
 177.305 +            // (item, value) => item.Maximum = Convert.ToDouble(value));
 177.306 +            throw new NotImplementedException();
 177.307 +        }
 177.308 +
 177.309 +        /// <summary>
 177.310 +        /// Updates the maximum/minimum value on the value axis from the bar values.
 177.311 +        /// </summary>
 177.312 +        protected internal override void UpdateMaxMin()
 177.313 +        {
 177.314 +            base.UpdateMaxMin();
 177.315 +
 177.316 +            if (this.Items == null || this.Items.Count == 0)
 177.317 +            {
 177.318 +                return;
 177.319 +            }
 177.320 +
 177.321 +            double minValueX = double.MaxValue;
 177.322 +            double maxValueX = double.MinValue;
 177.323 +            double minValueY = double.MaxValue;
 177.324 +            double maxValueY = double.MinValue;
 177.325 +
 177.326 +            foreach (var item in this.Items)
 177.327 +            {
 177.328 +                minValueX = Math.Min(minValueX, Math.Min(item.X0, item.X1));
 177.329 +                maxValueX = Math.Max(maxValueX, Math.Max(item.X1, item.X0));
 177.330 +                minValueY = Math.Min(minValueY, Math.Min(item.Y0, item.Y1));
 177.331 +                maxValueY = Math.Max(maxValueY, Math.Max(item.Y0, item.Y1));
 177.332 +            }
 177.333 +
 177.334 +            this.MinX = minValueX;
 177.335 +            this.MaxX = maxValueX;
 177.336 +            this.MinY = minValueY;
 177.337 +            this.MaxY = maxValueY;
 177.338 +        }
 177.339 +    }
 177.340 +}
 177.341 \ No newline at end of file
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/TornadoBarItem.cs	Sat Jun 08 16:53:22 2013 +0000
   178.3 @@ -0,0 +1,147 @@
   178.4 +// --------------------------------------------------------------------------------------------------------------------
   178.5 +// <copyright file="TornadoBarItem.cs" company="OxyPlot">
   178.6 +//   The MIT License (MIT)
   178.7 +//
   178.8 +//   Copyright (c) 2012 Oystein Bjorke
   178.9 +//
  178.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  178.11 +//   copy of this software and associated documentation files (the
  178.12 +//   "Software"), to deal in the Software without restriction, including
  178.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  178.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  178.15 +//   permit persons to whom the Software is furnished to do so, subject to
  178.16 +//   the following conditions:
  178.17 +//
  178.18 +//   The above copyright notice and this permission notice shall be included
  178.19 +//   in all copies or substantial portions of the Software.
  178.20 +//
  178.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  178.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  178.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  178.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  178.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  178.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  178.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  178.28 +// </copyright>
  178.29 +// <summary>
  178.30 +//   Represents an item for the TornadoBarSeries.
  178.31 +// </summary>
  178.32 +// --------------------------------------------------------------------------------------------------------------------
  178.33 +namespace OxyPlot.Series
  178.34 +{
  178.35 +    /// <summary>
  178.36 +    /// Represents an item for the TornadoBarSeries.
  178.37 +    /// </summary>
  178.38 +    public class TornadoBarItem : CategorizedItem, ICodeGenerating
  178.39 +    {
  178.40 +        /// <summary>
  178.41 +        /// Initializes a new instance of the <see cref="TornadoBarItem"/> class.
  178.42 +        /// </summary>
  178.43 +        public TornadoBarItem()
  178.44 +        {
  178.45 +            this.Minimum = double.NaN;
  178.46 +            this.Maximum = double.NaN;
  178.47 +            this.BaseValue = double.NaN;
  178.48 +            this.MinimumColor = null;
  178.49 +            this.MaximumColor = null;
  178.50 +        }
  178.51 +
  178.52 +        /// <summary>
  178.53 +        /// Initializes a new instance of the <see cref="TornadoBarItem"/> class.
  178.54 +        /// </summary>
  178.55 +        /// <param name="minimum">
  178.56 +        /// The minimum.
  178.57 +        /// </param>
  178.58 +        /// <param name="maximum">
  178.59 +        /// The maximum.
  178.60 +        /// </param>
  178.61 +        /// <param name="baseValue">
  178.62 +        /// The base value.
  178.63 +        /// </param>
  178.64 +        /// <param name="minimumColor">
  178.65 +        /// The minimum color.
  178.66 +        /// </param>
  178.67 +        /// <param name="maximumColor">
  178.68 +        /// The maximum color.
  178.69 +        /// </param>
  178.70 +        public TornadoBarItem(
  178.71 +            double minimum,
  178.72 +            double maximum,
  178.73 +            double baseValue = double.NaN,
  178.74 +            OxyColor minimumColor = null,
  178.75 +            OxyColor maximumColor = null)
  178.76 +        {
  178.77 +            this.Minimum = minimum;
  178.78 +            this.Maximum = maximum;
  178.79 +            this.BaseValue = baseValue;
  178.80 +            this.MinimumColor = minimumColor;
  178.81 +            this.MaximumColor = maximumColor;
  178.82 +        }
  178.83 +
  178.84 +        /// <summary>
  178.85 +        /// Gets or sets the base value.
  178.86 +        /// </summary>
  178.87 +        public double BaseValue { get; set; }
  178.88 +
  178.89 +        /// <summary>
  178.90 +        /// Gets or sets the maximum.
  178.91 +        /// </summary>
  178.92 +        public double Maximum { get; set; }
  178.93 +
  178.94 +        /// <summary>
  178.95 +        /// Gets or sets the color for the maximum bar.
  178.96 +        /// </summary>
  178.97 +        public OxyColor MaximumColor { get; set; }
  178.98 +
  178.99 +        /// <summary>
 178.100 +        /// Gets or sets the minimum value.
 178.101 +        /// </summary>
 178.102 +        public double Minimum { get; set; }
 178.103 +
 178.104 +        /// <summary>
 178.105 +        /// Gets or sets the color for the minimum bar.
 178.106 +        /// </summary>
 178.107 +        public OxyColor MinimumColor { get; set; }
 178.108 +
 178.109 +        /// <summary>
 178.110 +        /// Returns c# code that generates this instance.
 178.111 +        /// </summary>
 178.112 +        /// <returns>
 178.113 +        /// C# code.
 178.114 +        /// </returns>
 178.115 +        public string ToCode()
 178.116 +        {
 178.117 +            if (this.MaximumColor != null)
 178.118 +            {
 178.119 +                return CodeGenerator.FormatConstructor(
 178.120 +                    this.GetType(),
 178.121 +                    "{0},{1},{2},{3},{4}",
 178.122 +                    this.Minimum,
 178.123 +                    this.Maximum,
 178.124 +                    this.BaseValue,
 178.125 +                    this.MinimumColor.ToCode(),
 178.126 +                    this.MaximumColor.ToCode());
 178.127 +            }
 178.128 +
 178.129 +            if (this.MinimumColor != null)
 178.130 +            {
 178.131 +                return CodeGenerator.FormatConstructor(
 178.132 +                    this.GetType(),
 178.133 +                    "{0},{1},{2},{3}",
 178.134 +                    this.Minimum,
 178.135 +                    this.Maximum,
 178.136 +                    this.BaseValue,
 178.137 +                    this.MinimumColor.ToCode());
 178.138 +            }
 178.139 +
 178.140 +            if (!double.IsNaN(this.BaseValue))
 178.141 +            {
 178.142 +                return CodeGenerator.FormatConstructor(
 178.143 +                    this.GetType(), "{0},{1},{2}", this.Minimum, this.Maximum, this.BaseValue);
 178.144 +            }
 178.145 +
 178.146 +            return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.Minimum, this.Maximum);
 178.147 +        }
 178.148 +
 178.149 +    }
 178.150 +}
 178.151 \ No newline at end of file
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/External/OxyPlot/OxyPlot/Series/BarSeries/TornadoBarSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   179.3 @@ -0,0 +1,590 @@
   179.4 +// --------------------------------------------------------------------------------------------------------------------
   179.5 +// <copyright file="TornadoBarSeries.cs" company="OxyPlot">
   179.6 +//   The MIT License (MIT)
   179.7 +//
   179.8 +//   Copyright (c) 2012 Oystein Bjorke
   179.9 +//
  179.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  179.11 +//   copy of this software and associated documentation files (the
  179.12 +//   "Software"), to deal in the Software without restriction, including
  179.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  179.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  179.15 +//   permit persons to whom the Software is furnished to do so, subject to
  179.16 +//   the following conditions:
  179.17 +//
  179.18 +//   The above copyright notice and this permission notice shall be included
  179.19 +//   in all copies or substantial portions of the Software.
  179.20 +//
  179.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  179.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  179.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  179.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  179.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  179.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  179.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  179.28 +// </copyright>
  179.29 +// <summary>
  179.30 +//   Represents a series that can be used to create tornado plots.
  179.31 +// </summary>
  179.32 +// --------------------------------------------------------------------------------------------------------------------
  179.33 +namespace OxyPlot.Series
  179.34 +{
  179.35 +    using System;
  179.36 +    using System.Collections.Generic;
  179.37 +    using System.Linq;
  179.38 +
  179.39 +    using OxyPlot.Axes;
  179.40 +
  179.41 +    /// <summary>
  179.42 +    /// Represents a series that can be used to create tornado plots.
  179.43 +    /// </summary>
  179.44 +    /// <remarks>
  179.45 +    /// See http://en.wikipedia.org/wiki/Tornado_diagram.
  179.46 +    /// </remarks>
  179.47 +    public class TornadoBarSeries : CategorizedSeries
  179.48 +    {
  179.49 +        /// <summary>
  179.50 +        /// The default fill color.
  179.51 +        /// </summary>
  179.52 +        private OxyColor defaultMaximumFillColor;
  179.53 +
  179.54 +        /// <summary>
  179.55 +        /// The default minimum fill color.
  179.56 +        /// </summary>
  179.57 +        private OxyColor defaultMinimumFillColor;
  179.58 +
  179.59 +        /// <summary>
  179.60 +        /// Initializes a new instance of the <see cref="TornadoBarSeries"/> class.
  179.61 +        /// </summary>
  179.62 +        public TornadoBarSeries()
  179.63 +        {
  179.64 +            this.Items = new List<TornadoBarItem>();
  179.65 +
  179.66 +            this.MaximumFillColor = OxyColor.FromRgb(216, 82, 85);
  179.67 +            this.MinimumFillColor = OxyColor.FromRgb(84, 138, 209);
  179.68 +
  179.69 +            this.StrokeColor = OxyColors.Black;
  179.70 +            this.StrokeThickness = 1;
  179.71 +            this.BarWidth = 1;
  179.72 +
  179.73 +            this.TrackerFormatString = "{0}";
  179.74 +            this.LabelMargin = 4;
  179.75 +
  179.76 +            this.MinimumLabelFormatString = "{0}";
  179.77 +            this.MaximumLabelFormatString = "{0}";
  179.78 +        }
  179.79 +
  179.80 +        /// <summary>
  179.81 +        /// Gets or sets the width of the bars (as a fraction of the available width). The default value is 0.5 (50%)
  179.82 +        /// </summary>
  179.83 +        /// <value>
  179.84 +        /// The width of the bars.
  179.85 +        /// </value>
  179.86 +        public double BarWidth { get; set; }
  179.87 +
  179.88 +        /// <summary>
  179.89 +        /// Gets or sets the base value.
  179.90 +        /// </summary>
  179.91 +        /// <value>
  179.92 +        /// The base value.
  179.93 +        /// </value>
  179.94 +        public double BaseValue { get; set; }
  179.95 +
  179.96 +        /// <summary>
  179.97 +        /// Gets the tornado bar items.
  179.98 +        /// </summary>
  179.99 +        /// <value>
 179.100 +        /// The items.
 179.101 +        /// </value>
 179.102 +        public IList<TornadoBarItem> Items { get; private set; }
 179.103 +
 179.104 +        /// <summary>
 179.105 +        /// Gets or sets the label color.
 179.106 +        /// </summary>
 179.107 +        public OxyColor LabelColor { get; set; }
 179.108 +
 179.109 +        /// <summary>
 179.110 +        /// Gets or sets the label field.
 179.111 +        /// </summary>
 179.112 +        public string LabelField { get; set; }
 179.113 +
 179.114 +        /// <summary>
 179.115 +        /// Gets or sets the label margins.
 179.116 +        /// </summary>
 179.117 +        public double LabelMargin { get; set; }
 179.118 +
 179.119 +        /// <summary>
 179.120 +        /// Gets or sets the maximum value field.
 179.121 +        /// </summary>
 179.122 +        public string MaximumField { get; set; }
 179.123 +
 179.124 +        /// <summary>
 179.125 +        /// Gets or sets the color of the interior of the Maximum bars.
 179.126 +        /// </summary>
 179.127 +        /// <value>
 179.128 +        /// The color.
 179.129 +        /// </value>
 179.130 +        public OxyColor MaximumFillColor { get; set; }
 179.131 +
 179.132 +        /// <summary>
 179.133 +        /// Gets the actual fill color.
 179.134 +        /// </summary>
 179.135 +        /// <value>The actual color.</value>
 179.136 +        public OxyColor ActualMaximumFillColor
 179.137 +        {
 179.138 +            get { return this.MaximumFillColor ?? this.defaultMaximumFillColor; }
 179.139 +        }
 179.140 +
 179.141 +        /// <summary>
 179.142 +        /// Gets or sets the format string for the maximum labels.
 179.143 +        /// </summary>
 179.144 +        public string MaximumLabelFormatString { get; set; }
 179.145 +
 179.146 +        /// <summary>
 179.147 +        /// Gets or sets the minimum value field.
 179.148 +        /// </summary>
 179.149 +        public string MinimumField { get; set; }
 179.150 +
 179.151 +        /// <summary>
 179.152 +        /// Gets or sets the default color of the interior of the Minimum bars.
 179.153 +        /// </summary>
 179.154 +        /// <value>
 179.155 +        /// The color.
 179.156 +        /// </value>
 179.157 +        public OxyColor MinimumFillColor { get; set; }
 179.158 +
 179.159 +        /// <summary>
 179.160 +        /// Gets the actual minimum fill color.
 179.161 +        /// </summary>
 179.162 +        /// <value>The actual color.</value>
 179.163 +        public OxyColor ActualMinimumFillColor
 179.164 +        {
 179.165 +            get { return this.MinimumFillColor ?? this.defaultMinimumFillColor; }
 179.166 +        }
 179.167 +
 179.168 +        /// <summary>
 179.169 +        /// Gets or sets the format string for the minimum labels.
 179.170 +        /// </summary>
 179.171 +        public string MinimumLabelFormatString { get; set; }
 179.172 +
 179.173 +        /// <summary>
 179.174 +        /// Gets or sets the color of the border around the bars.
 179.175 +        /// </summary>
 179.176 +        /// <value>
 179.177 +        /// The color of the stroke.
 179.178 +        /// </value>
 179.179 +        public OxyColor StrokeColor { get; set; }
 179.180 +
 179.181 +        /// <summary>
 179.182 +        /// Gets or sets the thickness of the bar border strokes.
 179.183 +        /// </summary>
 179.184 +        /// <value>
 179.185 +        /// The stroke thickness.
 179.186 +        /// </value>
 179.187 +        public double StrokeThickness { get; set; }
 179.188 +
 179.189 +        /// <summary>
 179.190 +        /// Gets or sets the actual rectangles for the maximum bars.
 179.191 +        /// </summary>
 179.192 +		protected internal IList<OxyRect> ActualMaximumBarRectangles { get; set; }
 179.193 +
 179.194 +        /// <summary>
 179.195 +        /// Gets or sets the actual rectangles for the minimum bars.
 179.196 +        /// </summary>
 179.197 +		protected internal IList<OxyRect> ActualMinimumBarRectangles { get; set; }
 179.198 +
 179.199 +        /// <summary>
 179.200 +        /// Gets or sets the valid items
 179.201 +        /// </summary>
 179.202 +		protected internal IList<TornadoBarItem> ValidItems { get; set; }
 179.203 +
 179.204 +        /// <summary>
 179.205 +        /// Gets or sets the dictionary which stores the index-inversion for the valid items
 179.206 +        /// </summary>
 179.207 +        protected internal Dictionary<int, int> ValidItemsIndexInversion { get; set; }
 179.208 +
 179.209 +        /// <summary>
 179.210 +        /// Gets the point in the dataset that is nearest the specified point.
 179.211 +        /// </summary>
 179.212 +        /// <param name="point">
 179.213 +        /// The point.
 179.214 +        /// </param>
 179.215 +        /// <param name="interpolate">
 179.216 +        /// The interpolate.
 179.217 +        /// </param>
 179.218 +        /// <returns>
 179.219 +        /// A TrackerHitResult for the current hit.
 179.220 +        /// </returns>
 179.221 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 179.222 +        {
 179.223 +            for (int i = 0; i < this.ActualMinimumBarRectangles.Count; i++)
 179.224 +            {
 179.225 +                var r = this.ActualMinimumBarRectangles[i];
 179.226 +                if (r.Contains(point))
 179.227 +                {
 179.228 +                    var item = (TornadoBarItem)this.GetItem(this.ValidItemsIndexInversion[i]);
 179.229 +                    var categoryIndex = item.GetCategoryIndex(i);
 179.230 +                    var value = this.ValidItems[i].Minimum;
 179.231 +                    var dp = new DataPoint(categoryIndex, value);
 179.232 +                    var text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, item, value);
 179.233 +                    return new TrackerHitResult(this, dp, point, item, i, text);
 179.234 +                }
 179.235 +
 179.236 +                r = this.ActualMaximumBarRectangles[i];
 179.237 +                if (r.Contains(point))
 179.238 +                {
 179.239 +                    var item = (TornadoBarItem)this.GetItem(this.ValidItemsIndexInversion[i]);
 179.240 +                    var categoryIndex = item.GetCategoryIndex(i);
 179.241 +                    var value = this.ValidItems[i].Maximum;
 179.242 +                    var dp = new DataPoint(categoryIndex, value);
 179.243 +                    var text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, item, value);
 179.244 +                    return new TrackerHitResult(this, dp, point, item, i, text);
 179.245 +                }
 179.246 +            }
 179.247 +
 179.248 +            return null;
 179.249 +        }
 179.250 +
 179.251 +        /// <summary>
 179.252 +        /// Checks if the specified value is valid.
 179.253 +        /// </summary>
 179.254 +        /// <param name="v">
 179.255 +        /// The value.
 179.256 +        /// </param>
 179.257 +        /// <param name="yaxis">
 179.258 +        /// The y axis.
 179.259 +        /// </param>
 179.260 +        /// <returns>
 179.261 +        /// True if the value is valid.
 179.262 +        /// </returns>
 179.263 +        public virtual bool IsValidPoint(double v, Axis yaxis)
 179.264 +        {
 179.265 +            return !double.IsNaN(v) && !double.IsInfinity(v);
 179.266 +        }
 179.267 +
 179.268 +        /// <summary>
 179.269 +        /// Renders the Series on the specified rendering context.
 179.270 +        /// </summary>
 179.271 +        /// <param name="rc">
 179.272 +        /// The rendering context.
 179.273 +        /// </param>
 179.274 +        /// <param name="model">
 179.275 +        /// The model.
 179.276 +        /// </param>
 179.277 +        public override void Render(IRenderContext rc, PlotModel model)
 179.278 +        {
 179.279 +            this.ActualMinimumBarRectangles = new List<OxyRect>();
 179.280 +            this.ActualMaximumBarRectangles = new List<OxyRect>();
 179.281 +
 179.282 +            if (this.ValidItems.Count == 0)
 179.283 +            {
 179.284 +                return;
 179.285 +            }
 179.286 +
 179.287 +            var clippingRect = this.GetClippingRect();
 179.288 +            var categoryAxis = this.GetCategoryAxis();
 179.289 +            var actualBarWidth = this.GetActualBarWidth();
 179.290 +
 179.291 +            for (var i = 0; i < this.ValidItems.Count; i++)
 179.292 +            {
 179.293 +                var item = this.ValidItems[i];
 179.294 +
 179.295 +                var categoryIndex = item.GetCategoryIndex(i);
 179.296 +
 179.297 +                var baseValue = double.IsNaN(item.BaseValue) ? this.BaseValue : item.BaseValue;
 179.298 +
 179.299 +                var p0 = this.Transform(item.Minimum, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex]);
 179.300 +                var p1 = this.Transform(
 179.301 +                    item.Maximum, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex] + actualBarWidth);
 179.302 +                var p2 = this.Transform(baseValue, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex]);
 179.303 +                p2.X = (int)p2.X;
 179.304 +
 179.305 +                var minimumRectangle = OxyRect.Create(p0.X, p0.Y, p2.X, p1.Y);
 179.306 +                var maximumRectangle = OxyRect.Create(p2.X, p0.Y, p1.X, p1.Y);
 179.307 +
 179.308 +                this.ActualMinimumBarRectangles.Add(minimumRectangle);
 179.309 +                this.ActualMaximumBarRectangles.Add(maximumRectangle);
 179.310 +
 179.311 +                rc.DrawClippedRectangleAsPolygon(
 179.312 +                    minimumRectangle,
 179.313 +                    clippingRect,
 179.314 +                    item.MinimumColor ?? this.ActualMinimumFillColor,
 179.315 +                    this.StrokeColor,
 179.316 +                    this.StrokeThickness);
 179.317 +                rc.DrawClippedRectangleAsPolygon(
 179.318 +                    maximumRectangle,
 179.319 +                    clippingRect,
 179.320 +                    item.MaximumColor ?? this.ActualMaximumFillColor,
 179.321 +                    this.StrokeColor,
 179.322 +                    this.StrokeThickness);
 179.323 +
 179.324 +                if (this.MinimumLabelFormatString != null)
 179.325 +                {
 179.326 +                    var s = StringHelper.Format(
 179.327 +                        this.ActualCulture,
 179.328 +                        this.MinimumLabelFormatString,
 179.329 +                        this.GetItem(this.ValidItemsIndexInversion[i]),
 179.330 +                        item.Minimum);
 179.331 +                    var pt = new ScreenPoint(
 179.332 +                        minimumRectangle.Left - this.LabelMargin, (minimumRectangle.Top + minimumRectangle.Bottom) / 2);
 179.333 +
 179.334 +                    rc.DrawClippedText(
 179.335 +                        clippingRect,
 179.336 +                        pt,
 179.337 +                        s,
 179.338 +                        this.ActualTextColor,
 179.339 +                        this.ActualFont,
 179.340 +                        this.ActualFontSize,
 179.341 +                        this.ActualFontWeight,
 179.342 +                        0,
 179.343 +                        HorizontalAlignment.Right,
 179.344 +                        VerticalAlignment.Middle);
 179.345 +                }
 179.346 +
 179.347 +                if (this.MaximumLabelFormatString != null)
 179.348 +                {
 179.349 +                    var s = StringHelper.Format(
 179.350 +                        this.ActualCulture,
 179.351 +                        this.MaximumLabelFormatString,
 179.352 +                        this.GetItem(this.ValidItemsIndexInversion[i]),
 179.353 +                        item.Maximum);
 179.354 +                    var pt = new ScreenPoint(
 179.355 +                        maximumRectangle.Right + this.LabelMargin, (maximumRectangle.Top + maximumRectangle.Bottom) / 2);
 179.356 +
 179.357 +                    rc.DrawClippedText(
 179.358 +                        clippingRect,
 179.359 +                        pt,
 179.360 +                        s,
 179.361 +                        this.ActualTextColor,
 179.362 +                        this.ActualFont,
 179.363 +                        this.ActualFontSize,
 179.364 +                        this.ActualFontWeight,
 179.365 +                        0,
 179.366 +                        HorizontalAlignment.Left,
 179.367 +                        VerticalAlignment.Middle);
 179.368 +                }
 179.369 +            }
 179.370 +        }
 179.371 +
 179.372 +        /// <summary>
 179.373 +        /// Renders the legend symbol on the specified rendering context.
 179.374 +        /// </summary>
 179.375 +        /// <param name="rc">
 179.376 +        /// The rendering context.
 179.377 +        /// </param>
 179.378 +        /// <param name="legendBox">
 179.379 +        /// The legend rectangle.
 179.380 +        /// </param>
 179.381 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 179.382 +        {
 179.383 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 179.384 +            double ymid = (legendBox.Top + legendBox.Bottom) / 2;
 179.385 +            double height = (legendBox.Bottom - legendBox.Top) * 0.8;
 179.386 +            double width = height;
 179.387 +            rc.DrawRectangleAsPolygon(
 179.388 +                new OxyRect(xmid - (0.5 * width), ymid - (0.5 * height), 0.5 * width, height),
 179.389 +                this.ActualMinimumFillColor,
 179.390 +                this.StrokeColor,
 179.391 +                this.StrokeThickness);
 179.392 +            rc.DrawRectangleAsPolygon(
 179.393 +                new OxyRect(xmid, ymid - (0.5 * height), 0.5 * width, height),
 179.394 +                this.ActualMaximumFillColor,
 179.395 +                this.StrokeColor,
 179.396 +                this.StrokeThickness);
 179.397 +        }
 179.398 +
 179.399 +        /// <summary>
 179.400 +        /// Gets or sets the width/height of the columns/bars (as a fraction of the available space).
 179.401 +        /// </summary>
 179.402 +        /// <returns>
 179.403 +        /// The fractional width.
 179.404 +        /// </returns>
 179.405 +        /// <value>
 179.406 +        /// The width of the bars.
 179.407 +        /// </value>
 179.408 +        /// <remarks>
 179.409 +        /// The available space will be determined by the GapWidth of the CategoryAxis used by this series.
 179.410 +        /// </remarks>
 179.411 +        internal override double GetBarWidth()
 179.412 +        {
 179.413 +            return this.BarWidth;
 179.414 +        }
 179.415 +
 179.416 +        /// <summary>
 179.417 +        /// Gets the items of this series.
 179.418 +        /// </summary>
 179.419 +        /// <returns>
 179.420 +        /// The items.
 179.421 +        /// </returns>
 179.422 +        protected internal override IList<CategorizedItem> GetItems()
 179.423 +        {
 179.424 +            return this.Items.Cast<CategorizedItem>().ToList();
 179.425 +        }
 179.426 +
 179.427 +        /// <summary>
 179.428 +        /// Check if the data series is using the specified axis.
 179.429 +        /// </summary>
 179.430 +        /// <param name="axis">
 179.431 +        /// An axis which should be checked if used
 179.432 +        /// </param>
 179.433 +        /// <returns>
 179.434 +        /// True if the axis is in use.
 179.435 +        /// </returns>
 179.436 +        protected internal override bool IsUsing(Axis axis)
 179.437 +        {
 179.438 +            return this.XAxis == axis || this.YAxis == axis;
 179.439 +        }
 179.440 +
 179.441 +        /// <summary>
 179.442 +        /// The set default values.
 179.443 +        /// </summary>
 179.444 +        /// <param name="model">
 179.445 +        /// The model.
 179.446 +        /// </param>
 179.447 +        protected internal override void SetDefaultValues(PlotModel model)
 179.448 +        {
 179.449 +            if (this.MaximumFillColor == null)
 179.450 +            {
 179.451 +                this.defaultMaximumFillColor = model.GetDefaultColor();
 179.452 +            }
 179.453 +
 179.454 +            if (this.MinimumFillColor == null)
 179.455 +            {
 179.456 +                this.defaultMinimumFillColor = model.GetDefaultColor();
 179.457 +            }
 179.458 +        }
 179.459 +
 179.460 +        /// <summary>
 179.461 +        /// Updates the axis maximum and minimum values.
 179.462 +        /// </summary>
 179.463 +        protected internal override void UpdateAxisMaxMin()
 179.464 +        {
 179.465 +            this.XAxis.Include(this.MinX);
 179.466 +            this.XAxis.Include(this.MaxX);
 179.467 +        }
 179.468 +
 179.469 +        /// <summary>
 179.470 +        /// Updates the data.
 179.471 +        /// </summary>
 179.472 +        protected internal override void UpdateData()
 179.473 +        {
 179.474 +            if (this.ItemsSource != null)
 179.475 +            {
 179.476 +                this.Items.Clear();
 179.477 +
 179.478 +                var filler = new ListFiller<TornadoBarItem>();
 179.479 +                filler.Add(this.MinimumField, (item, value) => item.Minimum = Convert.ToDouble(value));
 179.480 +                filler.Add(this.MaximumField, (item, value) => item.Maximum = Convert.ToDouble(value));
 179.481 +                filler.FillT(this.Items, this.ItemsSource);
 179.482 +            }
 179.483 +        }
 179.484 +
 179.485 +        /// <summary>
 179.486 +        /// Updates the maximum/minimum value on the value axis from the bar values.
 179.487 +        /// </summary>
 179.488 +        protected internal override void UpdateMaxMin()
 179.489 +        {
 179.490 +            base.UpdateMaxMin();
 179.491 +
 179.492 +            if (this.ValidItems == null || this.ValidItems.Count == 0)
 179.493 +            {
 179.494 +                return;
 179.495 +            }
 179.496 +
 179.497 +            double minValue = double.MaxValue;
 179.498 +            double maxValue = double.MinValue;
 179.499 +
 179.500 +            foreach (var item in this.ValidItems)
 179.501 +            {
 179.502 +                minValue = Math.Min(minValue, item.Minimum);
 179.503 +                maxValue = Math.Max(maxValue, item.Maximum);
 179.504 +            }
 179.505 +
 179.506 +            this.MinX = minValue;
 179.507 +            this.MaxX = maxValue;
 179.508 +        }
 179.509 +
 179.510 +        /// <summary>
 179.511 +        /// Updates the valid items
 179.512 +        /// </summary>
 179.513 +        protected internal override void UpdateValidData()
 179.514 +        {
 179.515 +            this.ValidItems = new List<TornadoBarItem>();
 179.516 +            this.ValidItemsIndexInversion = new Dictionary<int, int>();
 179.517 +            var valueAxis = this.GetValueAxis();
 179.518 +
 179.519 +            for (var i = 0; i < this.Items.Count; i++)
 179.520 +            {
 179.521 +                var item = this.Items[i];
 179.522 +                if (valueAxis.IsValidValue(item.Minimum) && valueAxis.IsValidValue(item.Maximum))
 179.523 +                {
 179.524 +                    this.ValidItemsIndexInversion.Add(this.ValidItems.Count, i);
 179.525 +                    this.ValidItems.Add(item);
 179.526 +                }
 179.527 +            }
 179.528 +        }
 179.529 +
 179.530 +        /// <summary>
 179.531 +        /// Gets the actual width/height of the items of this series.
 179.532 +        /// </summary>
 179.533 +        /// <returns>
 179.534 +        /// The width or height.
 179.535 +        /// </returns>
 179.536 +        /// <remarks>
 179.537 +        /// The actual width is also influenced by the GapWidth of the CategoryAxis used by this series.
 179.538 +        /// </remarks>
 179.539 +        protected override double GetActualBarWidth()
 179.540 +        {
 179.541 +            var categoryAxis = this.GetCategoryAxis();
 179.542 +            return this.BarWidth / (1 + categoryAxis.GapWidth) / categoryAxis.MaxWidth;
 179.543 +        }
 179.544 +
 179.545 +        /// <summary>
 179.546 +        /// Gets the category axis.
 179.547 +        /// </summary>
 179.548 +        /// <returns>
 179.549 +        /// The category axis.
 179.550 +        /// </returns>
 179.551 +        protected override CategoryAxis GetCategoryAxis()
 179.552 +        {
 179.553 +            var categoryAxis = this.YAxis as CategoryAxis;
 179.554 +            if (categoryAxis == null)
 179.555 +            {
 179.556 +                throw new InvalidOperationException("No category axis defined.");
 179.557 +            }
 179.558 +
 179.559 +            return categoryAxis;
 179.560 +        }
 179.561 +
 179.562 +        /// <summary>
 179.563 +        /// Gets the item at the specified index.
 179.564 +        /// </summary>
 179.565 +        /// <param name="i">
 179.566 +        /// The index of the item.
 179.567 +        /// </param>
 179.568 +        /// <returns>
 179.569 +        /// The item of the index.
 179.570 +        /// </returns>
 179.571 +        protected override object GetItem(int i)
 179.572 +        {
 179.573 +            if (this.ItemsSource != null || this.Items == null || this.Items.Count == 0)
 179.574 +            {
 179.575 +                return base.GetItem(i);
 179.576 +            }
 179.577 +
 179.578 +            return this.Items[i];
 179.579 +        }
 179.580 +
 179.581 +        /// <summary>
 179.582 +        /// Gets the value axis.
 179.583 +        /// </summary>
 179.584 +        /// <returns>
 179.585 +        /// The value axis.
 179.586 +        /// </returns>
 179.587 +        private Axis GetValueAxis()
 179.588 +        {
 179.589 +            return this.XAxis;
 179.590 +        }
 179.591 +
 179.592 +    }
 179.593 +}
 179.594 \ No newline at end of file
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/External/OxyPlot/OxyPlot/Series/BoxPlotItem.cs	Sat Jun 08 16:53:22 2013 +0000
   180.3 @@ -0,0 +1,167 @@
   180.4 +// --------------------------------------------------------------------------------------------------------------------
   180.5 +// <copyright file="BoxPlotItem.cs" company="OxyPlot">
   180.6 +//   The MIT License (MIT)
   180.7 +//
   180.8 +//   Copyright (c) 2012 Oystein Bjorke
   180.9 +//
  180.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  180.11 +//   copy of this software and associated documentation files (the
  180.12 +//   "Software"), to deal in the Software without restriction, including
  180.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  180.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  180.15 +//   permit persons to whom the Software is furnished to do so, subject to
  180.16 +//   the following conditions:
  180.17 +//
  180.18 +//   The above copyright notice and this permission notice shall be included
  180.19 +//   in all copies or substantial portions of the Software.
  180.20 +//
  180.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  180.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  180.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  180.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  180.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  180.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  180.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  180.28 +// </copyright>
  180.29 +// <summary>
  180.30 +//   Represents an item in a BoxPlotSeries.
  180.31 +// </summary>
  180.32 +// --------------------------------------------------------------------------------------------------------------------
  180.33 +namespace OxyPlot.Series
  180.34 +{
  180.35 +    using System.Collections.Generic;
  180.36 +
  180.37 +    /// <summary>
  180.38 +    /// Represents an item in a <see cref="BoxPlotSeries"/>.
  180.39 +    /// </summary>
  180.40 +    public struct BoxPlotItem
  180.41 +    {
  180.42 +        /// <summary>
  180.43 +        /// Initializes a new instance of the <see cref="BoxPlotItem"/> struct.
  180.44 +        /// </summary>
  180.45 +        /// <param name="x">
  180.46 +        /// The x.
  180.47 +        /// </param>
  180.48 +        /// <param name="lowerWhisker">
  180.49 +        /// The lower whisker.
  180.50 +        /// </param>
  180.51 +        /// <param name="boxBottom">
  180.52 +        /// The box bottom.
  180.53 +        /// </param>
  180.54 +        /// <param name="median">
  180.55 +        /// The median.
  180.56 +        /// </param>
  180.57 +        /// <param name="boxTop">
  180.58 +        /// The box top.
  180.59 +        /// </param>
  180.60 +        /// <param name="upperWhisker">
  180.61 +        /// The upper whisker.
  180.62 +        /// </param>
  180.63 +        /// <param name="outliers">
  180.64 +        /// The outliers.
  180.65 +        /// </param>
  180.66 +        /// <param name="tag">
  180.67 +        /// The tag.
  180.68 +        /// </param>
  180.69 +        public BoxPlotItem(
  180.70 +            double x,
  180.71 +            double lowerWhisker,
  180.72 +            double boxBottom,
  180.73 +            double median,
  180.74 +            double boxTop,
  180.75 +            double upperWhisker,
  180.76 +            IList<double> outliers,
  180.77 +            object tag = null)
  180.78 +            : this()
  180.79 +        {
  180.80 +            this.X = x;
  180.81 +            this.LowerWhisker = lowerWhisker;
  180.82 +            this.BoxBottom = boxBottom;
  180.83 +            this.Median = median;
  180.84 +            this.BoxTop = boxTop;
  180.85 +            this.UpperWhisker = upperWhisker;
  180.86 +            this.Outliers = outliers;
  180.87 +            this.Tag = tag;
  180.88 +        }
  180.89 +
  180.90 +        /// <summary>
  180.91 +        /// Gets or sets the box bottom value (usually the 25th percentile, Q1).
  180.92 +        /// </summary>
  180.93 +        /// <value> The lower quartile value. </value>
  180.94 +        public double BoxBottom { get; set; }
  180.95 +
  180.96 +        /// <summary>
  180.97 +        /// Gets or sets the box top value (usually the 75th percentile, Q3)).
  180.98 +        /// </summary>
  180.99 +        /// <value> The box top value. </value>
 180.100 +        public double BoxTop { get; set; }
 180.101 +
 180.102 +        /// <summary>
 180.103 +        /// Gets or sets the lower whisker value.
 180.104 +        /// </summary>
 180.105 +        /// <value> The lower whisker value. </value>
 180.106 +        public double LowerWhisker { get; set; }
 180.107 +
 180.108 +        /// <summary>
 180.109 +        /// Gets or sets the median.
 180.110 +        /// </summary>
 180.111 +        /// <value> The median. </value>
 180.112 +        public double Median { get; set; }
 180.113 +
 180.114 +        /// <summary>
 180.115 +        /// Gets or sets the outliers.
 180.116 +        /// </summary>
 180.117 +        /// <value> The outliers. </value>
 180.118 +        public IList<double> Outliers { get; set; }
 180.119 +
 180.120 +        /// <summary>
 180.121 +        /// Gets or sets the tag.
 180.122 +        /// </summary>
 180.123 +        /// <value> The tag. </value>
 180.124 +        public object Tag { get; set; }
 180.125 +
 180.126 +        /// <summary>
 180.127 +        /// Gets or sets the upper whisker value.
 180.128 +        /// </summary>
 180.129 +        /// <value> The upper whisker value. </value>
 180.130 +        public double UpperWhisker { get; set; }
 180.131 +
 180.132 +        /// <summary>
 180.133 +        /// Gets a list of all the values in the item.
 180.134 +        /// </summary>
 180.135 +        public IList<double> Values
 180.136 +        {
 180.137 +            get
 180.138 +            {
 180.139 +                var values = new List<double> { this.LowerWhisker, this.BoxBottom, this.Median, this.BoxTop, this.UpperWhisker };
 180.140 +                values.AddRange(this.Outliers);
 180.141 +                return values;
 180.142 +            }
 180.143 +        }
 180.144 +
 180.145 +        /// <summary>
 180.146 +        /// Gets or sets the X value.
 180.147 +        /// </summary>
 180.148 +        /// <value> The X value. </value>
 180.149 +        public double X { get; set; }
 180.150 +
 180.151 +        /// <summary>
 180.152 +        /// Returns a <see cref="System.String"/> that represents this instance.
 180.153 +        /// </summary>
 180.154 +        /// <returns>
 180.155 +        /// A <see cref="System.String"/> that represents this instance.
 180.156 +        /// </returns>
 180.157 +        public override string ToString()
 180.158 +        {
 180.159 +            return string.Format(
 180.160 +                "{0} {1} {2} {3} {4} {5} ",
 180.161 +                this.X,
 180.162 +                this.LowerWhisker,
 180.163 +                this.BoxBottom,
 180.164 +                this.Median,
 180.165 +                this.BoxTop,
 180.166 +                this.UpperWhisker);
 180.167 +        }
 180.168 +
 180.169 +    }
 180.170 +}
 180.171 \ No newline at end of file
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/External/OxyPlot/OxyPlot/Series/BoxPlotSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   181.3 @@ -0,0 +1,615 @@
   181.4 +// --------------------------------------------------------------------------------------------------------------------
   181.5 +// <copyright file="BoxPlotSeries.cs" company="OxyPlot">
   181.6 +//   The MIT License (MIT)
   181.7 +//   
   181.8 +//   Copyright (c) 2012 Oystein Bjorke
   181.9 +//   
  181.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  181.11 +//   copy of this software and associated documentation files (the
  181.12 +//   "Software"), to deal in the Software without restriction, including
  181.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  181.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  181.15 +//   permit persons to whom the Software is furnished to do so, subject to
  181.16 +//   the following conditions:
  181.17 +//   
  181.18 +//   The above copyright notice and this permission notice shall be included
  181.19 +//   in all copies or substantial portions of the Software.
  181.20 +//   
  181.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  181.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  181.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  181.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  181.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  181.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  181.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  181.28 +// </copyright>
  181.29 +// <summary>
  181.30 +//   Represents a series for box plots.
  181.31 +// </summary>
  181.32 +// --------------------------------------------------------------------------------------------------------------------
  181.33 +
  181.34 +namespace OxyPlot.Series
  181.35 +{
  181.36 +    using System.Collections.Generic;
  181.37 +    using System.Linq;
  181.38 +
  181.39 +    using OxyPlot.Axes;
  181.40 +
  181.41 +    /// <summary>
  181.42 +    /// Represents a series for box plots.
  181.43 +    /// </summary>
  181.44 +    public class BoxPlotSeries : XYAxisSeries
  181.45 +    {
  181.46 +        /// <summary>
  181.47 +        /// Initializes a new instance of the <see cref="BoxPlotSeries"/> class.
  181.48 +        /// </summary>
  181.49 +        public BoxPlotSeries()
  181.50 +        {
  181.51 +            this.Items = new List<BoxPlotItem>();
  181.52 +            this.TrackerFormatString =
  181.53 +                "X: {1:0.00}\nUpper Whisker: {2:0.00}\nThird Quartil: {3:0.00}\nMedian: {4:0.00}\nFirst Quartil: {5:0.00}\nLower Whisker: {6:0.00}";
  181.54 +            this.OutlierTrackerFormatString = "X: {1:0.00}\nY: {2:0.00}";
  181.55 +            this.Title = null;
  181.56 +            this.Fill = null;
  181.57 +            this.Stroke = OxyColors.Black;
  181.58 +            this.BoxWidth = 0.3;
  181.59 +            this.StrokeThickness = 1;
  181.60 +            this.MedianThickness = 2;
  181.61 +            this.OutlierSize = 2;
  181.62 +            this.OutlierType = MarkerType.Circle;
  181.63 +            this.MedianPointSize = 2;
  181.64 +            this.WhiskerWidth = 0.5;
  181.65 +            this.LineStyle = LineStyle.Solid;
  181.66 +            this.ShowMedianAsDot = false;
  181.67 +            this.ShowBox = true;
  181.68 +        }
  181.69 +
  181.70 +        /// <summary>
  181.71 +        /// Gets or sets the width of the boxes (specified in x-axis units).
  181.72 +        /// </summary>
  181.73 +        /// <value>
  181.74 +        /// The width of the boxes.
  181.75 +        /// </value>
  181.76 +        public double BoxWidth { get; set; }
  181.77 +
  181.78 +        /// <summary>
  181.79 +        /// Gets or sets the fill color. If null, this color will be automatically set.
  181.80 +        /// </summary>
  181.81 +        /// <value>
  181.82 +        /// The fill color.
  181.83 +        /// </value>
  181.84 +        public OxyColor Fill { get; set; }
  181.85 +
  181.86 +        /// <summary>
  181.87 +        /// Gets or sets the box plot items.
  181.88 +        /// </summary>
  181.89 +        /// <value>
  181.90 +        /// The items.
  181.91 +        /// </value>
  181.92 +        public IList<BoxPlotItem> Items { get; set; }
  181.93 +
  181.94 +        /// <summary>
  181.95 +        /// Gets or sets the line style.
  181.96 +        /// </summary>
  181.97 +        /// <value>
  181.98 +        /// The line style.
  181.99 +        /// </value>
 181.100 +        public LineStyle LineStyle { get; set; }
 181.101 +
 181.102 +        /// <summary>
 181.103 +        /// Gets or sets the size of the median point.
 181.104 +        /// </summary>
 181.105 +        /// <remarks>
 181.106 +        /// This property is only used when MedianStyle = Dot.
 181.107 +        /// </remarks>
 181.108 +        public double MedianPointSize { get; set; }
 181.109 +
 181.110 +        /// <summary>
 181.111 +        /// Gets or sets the median thickness, relative to the StrokeThickness.
 181.112 +        /// </summary>
 181.113 +        /// <value>
 181.114 +        /// The median thickness.
 181.115 +        /// </value>
 181.116 +        public double MedianThickness { get; set; }
 181.117 +
 181.118 +        /// <summary>
 181.119 +        /// Gets or sets the diameter of the outlier circles (specified in points).
 181.120 +        /// </summary>
 181.121 +        /// <value>
 181.122 +        /// The size of the outlier.
 181.123 +        /// </value>
 181.124 +        public double OutlierSize { get; set; }
 181.125 +
 181.126 +        /// <summary>
 181.127 +        /// Gets or sets the tracker format string for the outliers.
 181.128 +        /// </summary>
 181.129 +        /// <value>
 181.130 +        /// The tracker format string for the outliers.
 181.131 +        /// </value>
 181.132 +        /// <remarks>
 181.133 +        /// Use {0} for series title, {1} for x- and {2} for y-value.
 181.134 +        /// </remarks>
 181.135 +        public string OutlierTrackerFormatString { get; set; }
 181.136 +
 181.137 +        /// <summary>
 181.138 +        /// Gets or sets the type of the outliers.
 181.139 +        /// </summary>
 181.140 +        /// <value>
 181.141 +        /// The type of the outliers.
 181.142 +        /// </value>
 181.143 +        /// <remarks>
 181.144 +        /// MarkerType.Custom is currently not supported.
 181.145 +        /// </remarks>
 181.146 +        public MarkerType OutlierType { get; set; }
 181.147 +
 181.148 +        /// <summary>
 181.149 +        /// Gets or sets a value indicating whether to show the boxes.
 181.150 +        /// </summary>
 181.151 +        public bool ShowBox { get; set; }
 181.152 +
 181.153 +        /// <summary>
 181.154 +        /// Gets or sets a value indicating whether to show the median as a dot.
 181.155 +        /// </summary>
 181.156 +        public bool ShowMedianAsDot { get; set; }
 181.157 +
 181.158 +        /// <summary>
 181.159 +        /// Gets or sets the stroke.
 181.160 +        /// </summary>
 181.161 +        /// <value>
 181.162 +        /// The stroke.
 181.163 +        /// </value>
 181.164 +        public OxyColor Stroke { get; set; }
 181.165 +
 181.166 +        /// <summary>
 181.167 +        /// Gets or sets the stroke thickness.
 181.168 +        /// </summary>
 181.169 +        /// <value>
 181.170 +        /// The stroke thickness.
 181.171 +        /// </value>
 181.172 +        public double StrokeThickness { get; set; }
 181.173 +
 181.174 +        /// <summary>
 181.175 +        /// Gets or sets the width of the whiskers (relative to the BoxWidth).
 181.176 +        /// </summary>
 181.177 +        /// <value>
 181.178 +        /// The width of the whiskers.
 181.179 +        /// </value>
 181.180 +        public double WhiskerWidth { get; set; }
 181.181 +
 181.182 +        /// <summary>
 181.183 +        /// Gets the nearest point.
 181.184 +        /// </summary>
 181.185 +        /// <param name="point">
 181.186 +        /// The point.
 181.187 +        /// </param>
 181.188 +        /// <param name="interpolate">
 181.189 +        /// interpolate if set to <c>true</c> .
 181.190 +        /// </param>
 181.191 +        /// <returns>
 181.192 +        /// A TrackerHitResult for the current hit.
 181.193 +        /// </returns>
 181.194 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 181.195 +        {
 181.196 +            if (this.XAxis == null || this.YAxis == null)
 181.197 +            {
 181.198 +                return null;
 181.199 +            }
 181.200 +
 181.201 +            double minimumDistance = double.MaxValue;
 181.202 +            var result = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);
 181.203 +            foreach (var item in this.Items)
 181.204 +            {
 181.205 +                foreach (var outlier in item.Outliers)
 181.206 +                {
 181.207 +                    var sp = this.Transform(item.X, outlier);
 181.208 +                    double d = (sp - point).LengthSquared;
 181.209 +                    if (d < minimumDistance)
 181.210 +                    {
 181.211 +                        result.DataPoint = new DataPoint(item.X, outlier);
 181.212 +                        result.Position = sp;
 181.213 +                        result.Item = item;
 181.214 +                        result.Text = StringHelper.Format(
 181.215 +                            this.ActualCulture,
 181.216 +                            this.OutlierTrackerFormatString,
 181.217 +                            item,
 181.218 +                            this.Title,
 181.219 +                            this.XAxis.GetValue(result.DataPoint.X),
 181.220 +                            outlier);
 181.221 +                        minimumDistance = d;
 181.222 +                    }
 181.223 +                }
 181.224 +
 181.225 +                // check if we are inside the box rectangle
 181.226 +                var rect = this.GetBoxRect(item);
 181.227 +                if (rect.Contains(point))
 181.228 +                {
 181.229 +                    result.DataPoint = new DataPoint(item.X, this.YAxis.InverseTransform(point.Y));
 181.230 +                    result.Position = this.Transform(result.DataPoint);
 181.231 +                    result.Item = item;
 181.232 +
 181.233 +                    result.Text = StringHelper.Format(
 181.234 +                        this.ActualCulture,
 181.235 +                        this.TrackerFormatString,
 181.236 +                        item,
 181.237 +                        this.Title,
 181.238 +                        this.XAxis.GetValue(result.DataPoint.X),
 181.239 +                        item.UpperWhisker,
 181.240 +                        item.BoxTop,
 181.241 +                        item.Median,
 181.242 +                        item.BoxBottom,
 181.243 +                        item.LowerWhisker);
 181.244 +
 181.245 +                    minimumDistance = 0;
 181.246 +                }
 181.247 +
 181.248 +                var topWhisker = this.Transform(item.X, item.UpperWhisker);
 181.249 +                var bottomWhisker = this.Transform(item.X, item.LowerWhisker);
 181.250 +
 181.251 +                // check if we are near the line
 181.252 +                var p = ScreenPointHelper.FindPointOnLine(point, topWhisker, bottomWhisker);
 181.253 +                double d2 = (p - point).LengthSquared;
 181.254 +                if (d2 < minimumDistance)
 181.255 +                {
 181.256 +                    result.DataPoint = this.InverseTransform(p);
 181.257 +                    result.Position = this.Transform(result.DataPoint);
 181.258 +                    result.Item = item;
 181.259 +                    result.Text = StringHelper.Format(
 181.260 +                        this.ActualCulture,
 181.261 +                        this.TrackerFormatString,
 181.262 +                        item,
 181.263 +                        this.Title,
 181.264 +                        this.XAxis.GetValue(result.DataPoint.X),
 181.265 +                        item.UpperWhisker,
 181.266 +                        item.BoxTop,
 181.267 +                        item.Median,
 181.268 +                        item.BoxBottom,
 181.269 +                        item.LowerWhisker);
 181.270 +                    minimumDistance = d2;
 181.271 +                }
 181.272 +            }
 181.273 +
 181.274 +            if (minimumDistance < double.MaxValue)
 181.275 +            {
 181.276 +                return result;
 181.277 +            }
 181.278 +
 181.279 +            return null;
 181.280 +        }
 181.281 +
 181.282 +        /// <summary>
 181.283 +        /// Determines whether the specified item contains a valid point.
 181.284 +        /// </summary>
 181.285 +        /// <param name="item">
 181.286 +        /// The item.
 181.287 +        /// </param>
 181.288 +        /// <param name="xaxis">
 181.289 +        /// The x axis.
 181.290 +        /// </param>
 181.291 +        /// <param name="yaxis">
 181.292 +        /// The y axis.
 181.293 +        /// </param>
 181.294 +        /// <returns>
 181.295 +        /// <c>true</c> if the point is valid; otherwise, <c>false</c> .
 181.296 +        /// </returns>
 181.297 +        public virtual bool IsValidPoint(BoxPlotItem item, Axis xaxis, Axis yaxis)
 181.298 +        {
 181.299 +            return !double.IsNaN(item.X) && !double.IsInfinity(item.X) && !item.Values.Any(double.IsNaN)
 181.300 +                   && !item.Values.Any(double.IsInfinity) && (xaxis != null && xaxis.IsValidValue(item.X))
 181.301 +                   && (yaxis != null && item.Values.All(yaxis.IsValidValue));
 181.302 +        }
 181.303 +
 181.304 +        /// <summary>
 181.305 +        /// Renders the series on the specified render context.
 181.306 +        /// </summary>
 181.307 +        /// <param name="rc">
 181.308 +        /// The rendering context.
 181.309 +        /// </param>
 181.310 +        /// <param name="model">
 181.311 +        /// The model.
 181.312 +        /// </param>
 181.313 +        public override void Render(IRenderContext rc, PlotModel model)
 181.314 +        {
 181.315 +            if (this.Items.Count == 0)
 181.316 +            {
 181.317 +                return;
 181.318 +            }
 181.319 +
 181.320 +            var clippingRect = this.GetClippingRect();
 181.321 +
 181.322 +            var outlierScreenPoints = new List<ScreenPoint>();
 181.323 +            var halfBoxWidth = this.BoxWidth * 0.5;
 181.324 +            var halfWhiskerWidth = halfBoxWidth * this.WhiskerWidth;
 181.325 +            var strokeColor = this.GetSelectableColor(this.Stroke);
 181.326 +            var fillColor = this.GetSelectableFillColor(this.Fill);
 181.327 +
 181.328 +            foreach (var item in this.Items)
 181.329 +            {
 181.330 +                // Add the outlier points
 181.331 +                outlierScreenPoints.AddRange(item.Outliers.Select(outlier => this.Transform(item.X, outlier)));
 181.332 +
 181.333 +                var topWhiskerTop = this.Transform(item.X, item.UpperWhisker);
 181.334 +                var topWhiskerBottom = this.Transform(item.X, item.BoxTop);
 181.335 +                var bottomWhiskerTop = this.Transform(item.X, item.BoxBottom);
 181.336 +                var bottomWhiskerBottom = this.Transform(item.X, item.LowerWhisker);
 181.337 +                rc.DrawClippedLine(
 181.338 +                    new[] { topWhiskerTop, topWhiskerBottom },
 181.339 +                    clippingRect,
 181.340 +                    0,
 181.341 +                    strokeColor,
 181.342 +                    this.StrokeThickness,
 181.343 +                    this.LineStyle,
 181.344 +                    OxyPenLineJoin.Miter,
 181.345 +                    true);
 181.346 +                rc.DrawClippedLine(
 181.347 +                    new[] { bottomWhiskerTop, bottomWhiskerBottom },
 181.348 +                    clippingRect,
 181.349 +                    0,
 181.350 +                    strokeColor,
 181.351 +                    this.StrokeThickness,
 181.352 +                    this.LineStyle,
 181.353 +                    OxyPenLineJoin.Miter,
 181.354 +                    true);
 181.355 +
 181.356 +                // Draw the whiskers
 181.357 +                if (this.WhiskerWidth > 0)
 181.358 +                {
 181.359 +                    var topWhiskerLine1 = this.Transform(item.X - halfWhiskerWidth, item.UpperWhisker);
 181.360 +                    var topWhiskerLine2 = this.Transform(item.X + halfWhiskerWidth, item.UpperWhisker);
 181.361 +                    var bottomWhiskerLine1 = this.Transform(item.X - halfWhiskerWidth, item.LowerWhisker);
 181.362 +                    var bottomWhiskerLine2 = this.Transform(item.X + halfWhiskerWidth, item.LowerWhisker);
 181.363 +
 181.364 +                    rc.DrawClippedLine(
 181.365 +                        new[] { topWhiskerLine1, topWhiskerLine2 },
 181.366 +                        clippingRect,
 181.367 +                        0,
 181.368 +                        strokeColor,
 181.369 +                        this.StrokeThickness,
 181.370 +                        LineStyle.Solid,
 181.371 +                        OxyPenLineJoin.Miter,
 181.372 +                        true);
 181.373 +                    rc.DrawClippedLine(
 181.374 +                        new[] { bottomWhiskerLine1, bottomWhiskerLine2 },
 181.375 +                        clippingRect,
 181.376 +                        0,
 181.377 +                        strokeColor,
 181.378 +                        this.StrokeThickness,
 181.379 +                        LineStyle.Solid,
 181.380 +                        OxyPenLineJoin.Miter,
 181.381 +                        true);
 181.382 +                }
 181.383 +
 181.384 +                if (this.ShowBox)
 181.385 +                {
 181.386 +                    // Draw the box
 181.387 +                    var rect = this.GetBoxRect(item);
 181.388 +                    rc.DrawClippedRectangleAsPolygon(rect, clippingRect, fillColor, strokeColor, this.StrokeThickness);
 181.389 +                }
 181.390 +
 181.391 +                if (!this.ShowMedianAsDot)
 181.392 +                {
 181.393 +                    // Draw the median line
 181.394 +                    var medianLeft = this.Transform(item.X - halfBoxWidth, item.Median);
 181.395 +                    var medianRight = this.Transform(item.X + halfBoxWidth, item.Median);
 181.396 +                    rc.DrawClippedLine(
 181.397 +                        new[] { medianLeft, medianRight },
 181.398 +                        clippingRect,
 181.399 +                        0,
 181.400 +                        strokeColor,
 181.401 +                        this.StrokeThickness * this.MedianThickness,
 181.402 +                        LineStyle.Solid,
 181.403 +                        OxyPenLineJoin.Miter,
 181.404 +                        true);
 181.405 +                }
 181.406 +                else
 181.407 +                {
 181.408 +                    var mc = this.Transform(item.X, item.Median);
 181.409 +                    if (clippingRect.Contains(mc))
 181.410 +                    {
 181.411 +                        var ellipseRect = new OxyRect(
 181.412 +                            mc.X - this.MedianPointSize,
 181.413 +                            mc.Y - this.MedianPointSize,
 181.414 +                            this.MedianPointSize * 2,
 181.415 +                            this.MedianPointSize * 2);
 181.416 +                        rc.DrawEllipse(ellipseRect, fillColor, null, 0);
 181.417 +                    }
 181.418 +                }
 181.419 +            }
 181.420 +
 181.421 +            // Draw the outlier(s)
 181.422 +            var markerSizes = outlierScreenPoints.Select(o => this.OutlierSize).ToList();
 181.423 +            rc.DrawMarkers(
 181.424 +                outlierScreenPoints,
 181.425 +                clippingRect,
 181.426 +                this.OutlierType,
 181.427 +                null,
 181.428 +                markerSizes,
 181.429 +                fillColor,
 181.430 +                strokeColor,
 181.431 +                this.StrokeThickness);
 181.432 +        }
 181.433 +
 181.434 +        /// <summary>
 181.435 +        /// Renders the legend symbol on the specified rendering context.
 181.436 +        /// </summary>
 181.437 +        /// <param name="rc">
 181.438 +        /// The rendering context.
 181.439 +        /// </param>
 181.440 +        /// <param name="legendBox">
 181.441 +        /// The legend rectangle.
 181.442 +        /// </param>
 181.443 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 181.444 +        {
 181.445 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 181.446 +            double ybottom = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.7);
 181.447 +            double ytop = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.3);
 181.448 +            double ymid = (ybottom + ytop) * 0.5;
 181.449 +
 181.450 +            var halfBoxWidth = legendBox.Width * 0.24;
 181.451 +            var halfWhiskerWidth = halfBoxWidth * this.WhiskerWidth;
 181.452 +            const double LegendStrokeThickness = 1;
 181.453 +            var strokeColor = this.GetSelectableColor(this.Stroke);
 181.454 +            var fillColor = this.GetSelectableFillColor(this.Fill);
 181.455 +
 181.456 +            rc.DrawLine(
 181.457 +                new[] { new ScreenPoint(xmid, legendBox.Top), new ScreenPoint(xmid, ytop) },
 181.458 +                strokeColor,
 181.459 +                LegendStrokeThickness,
 181.460 +                LineStyle.Solid.GetDashArray(),
 181.461 +                OxyPenLineJoin.Miter,
 181.462 +                true);
 181.463 +
 181.464 +            rc.DrawLine(
 181.465 +                new[] { new ScreenPoint(xmid, ybottom), new ScreenPoint(xmid, legendBox.Bottom) },
 181.466 +                strokeColor,
 181.467 +                LegendStrokeThickness,
 181.468 +                LineStyle.Solid.GetDashArray(),
 181.469 +                OxyPenLineJoin.Miter,
 181.470 +                true);
 181.471 +
 181.472 +            if (this.WhiskerWidth > 0)
 181.473 +            {
 181.474 +                // top whisker
 181.475 +                rc.DrawLine(
 181.476 +                    new[]
 181.477 +                        {
 181.478 +                            new ScreenPoint(xmid - halfWhiskerWidth - 1, legendBox.Bottom),
 181.479 +                            new ScreenPoint(xmid + halfWhiskerWidth, legendBox.Bottom)
 181.480 +                        },
 181.481 +                    strokeColor,
 181.482 +                    LegendStrokeThickness,
 181.483 +                    LineStyle.Solid.GetDashArray(),
 181.484 +                    OxyPenLineJoin.Miter,
 181.485 +                    true);
 181.486 +
 181.487 +                // bottom whisker
 181.488 +                rc.DrawLine(
 181.489 +                    new[]
 181.490 +                        {
 181.491 +                            new ScreenPoint(xmid - halfWhiskerWidth - 1, legendBox.Top),
 181.492 +                            new ScreenPoint(xmid + halfWhiskerWidth, legendBox.Top)
 181.493 +                        },
 181.494 +                    strokeColor,
 181.495 +                    LegendStrokeThickness,
 181.496 +                    LineStyle.Solid.GetDashArray(),
 181.497 +                    OxyPenLineJoin.Miter,
 181.498 +                    true);
 181.499 +            }
 181.500 +
 181.501 +            if (this.ShowBox)
 181.502 +            {
 181.503 +                // box
 181.504 +                rc.DrawRectangleAsPolygon(
 181.505 +                    new OxyRect(xmid - halfBoxWidth, ytop, 2 * halfBoxWidth, ybottom - ytop),
 181.506 +                    fillColor,
 181.507 +                    strokeColor,
 181.508 +                    LegendStrokeThickness);
 181.509 +            }
 181.510 +
 181.511 +            // median
 181.512 +            if (!this.ShowMedianAsDot)
 181.513 +            {
 181.514 +                rc.DrawLine(
 181.515 +                    new[] { new ScreenPoint(xmid - halfBoxWidth, ymid), new ScreenPoint(xmid + halfBoxWidth, ymid) },
 181.516 +                    strokeColor,
 181.517 +                    LegendStrokeThickness * this.MedianThickness,
 181.518 +                    LineStyle.Solid.GetDashArray(),
 181.519 +                    OxyPenLineJoin.Miter,
 181.520 +                    true);
 181.521 +            }
 181.522 +            else
 181.523 +            {
 181.524 +                var ellipseRect = new OxyRect(
 181.525 +                    xmid - this.MedianPointSize,
 181.526 +                    ymid - this.MedianPointSize,
 181.527 +                    this.MedianPointSize * 2,
 181.528 +                    this.MedianPointSize * 2);
 181.529 +                rc.DrawEllipse(ellipseRect, fillColor, null);
 181.530 +            }
 181.531 +        }
 181.532 +
 181.533 +        /// <summary>
 181.534 +        /// Updates the max/minimum values.
 181.535 +        /// </summary>
 181.536 +        protected internal override void UpdateMaxMin()
 181.537 +        {
 181.538 +            base.UpdateMaxMin();
 181.539 +            this.InternalUpdateMaxMin(this.Items);
 181.540 +        }
 181.541 +
 181.542 +        /// <summary>
 181.543 +        /// Updates the max and min of the series.
 181.544 +        /// </summary>
 181.545 +        /// <param name="items">
 181.546 +        /// The items.
 181.547 +        /// </param>
 181.548 +        protected void InternalUpdateMaxMin(IList<BoxPlotItem> items)
 181.549 +        {
 181.550 +            if (items == null || items.Count == 0)
 181.551 +            {
 181.552 +                return;
 181.553 +            }
 181.554 +
 181.555 +            double minx = this.MinX;
 181.556 +            double miny = this.MinY;
 181.557 +            double maxx = this.MaxX;
 181.558 +            double maxy = this.MaxY;
 181.559 +
 181.560 +            foreach (var pt in items)
 181.561 +            {
 181.562 +                if (!this.IsValidPoint(pt, this.XAxis, this.YAxis))
 181.563 +                {
 181.564 +                    continue;
 181.565 +                }
 181.566 +
 181.567 +                var x = pt.X;
 181.568 +                if (x < minx || double.IsNaN(minx))
 181.569 +                {
 181.570 +                    minx = x;
 181.571 +                }
 181.572 +
 181.573 +                if (x > maxx || double.IsNaN(maxx))
 181.574 +                {
 181.575 +                    maxx = x;
 181.576 +                }
 181.577 +
 181.578 +                foreach (var y in pt.Values)
 181.579 +                {
 181.580 +                    if (y < miny || double.IsNaN(miny))
 181.581 +                    {
 181.582 +                        miny = y;
 181.583 +                    }
 181.584 +
 181.585 +                    if (y > maxy || double.IsNaN(maxy))
 181.586 +                    {
 181.587 +                        maxy = y;
 181.588 +                    }
 181.589 +                }
 181.590 +            }
 181.591 +
 181.592 +            this.MinX = minx;
 181.593 +            this.MinY = miny;
 181.594 +            this.MaxX = maxx;
 181.595 +            this.MaxY = maxy;
 181.596 +        }
 181.597 +
 181.598 +        /// <summary>
 181.599 +        /// Gets the screen rectangle for the box.
 181.600 +        /// </summary>
 181.601 +        /// <param name="item">
 181.602 +        /// The box item.
 181.603 +        /// </param>
 181.604 +        /// <returns>
 181.605 +        /// A rectangle.
 181.606 +        /// </returns>
 181.607 +        private OxyRect GetBoxRect(BoxPlotItem item)
 181.608 +        {
 181.609 +            var halfBoxWidth = this.BoxWidth * 0.5;
 181.610 +
 181.611 +            var boxTop = this.Transform(item.X - halfBoxWidth, item.BoxTop);
 181.612 +            var boxBottom = this.Transform(item.X + halfBoxWidth, item.BoxBottom);
 181.613 +
 181.614 +            var rect = new OxyRect(boxTop.X, boxTop.Y, boxBottom.X - boxTop.X, boxBottom.Y - boxTop.Y);
 181.615 +            return rect;
 181.616 +        }
 181.617 +    }
 181.618 +}
 181.619 \ No newline at end of file
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/External/OxyPlot/OxyPlot/Series/CandleStickSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   182.3 @@ -0,0 +1,201 @@
   182.4 +// --------------------------------------------------------------------------------------------------------------------
   182.5 +// <copyright file="CandleStickSeries.cs" company="OxyPlot">
   182.6 +//   The MIT License (MIT)
   182.7 +//
   182.8 +//   Copyright (c) 2012 Oystein Bjorke
   182.9 +//
  182.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  182.11 +//   copy of this software and associated documentation files (the
  182.12 +//   "Software"), to deal in the Software without restriction, including
  182.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  182.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  182.15 +//   permit persons to whom the Software is furnished to do so, subject to
  182.16 +//   the following conditions:
  182.17 +//
  182.18 +//   The above copyright notice and this permission notice shall be included
  182.19 +//   in all copies or substantial portions of the Software.
  182.20 +//
  182.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  182.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  182.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  182.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  182.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  182.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  182.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  182.28 +// </copyright>
  182.29 +// <summary>
  182.30 +//   Represents a series for candlestick charts.
  182.31 +// </summary>
  182.32 +// --------------------------------------------------------------------------------------------------------------------
  182.33 +namespace OxyPlot.Series
  182.34 +{
  182.35 +    using System;
  182.36 +
  182.37 +    /// <summary>
  182.38 +    /// Represents a series for candlestick charts.
  182.39 +    /// </summary>
  182.40 +    /// <remarks>
  182.41 +    /// http://en.wikipedia.org/wiki/Candlestick_chart
  182.42 +    /// http://www.mathworks.com/help/toolbox/finance/candle.html
  182.43 +    /// </remarks>
  182.44 +    public class CandleStickSeries : HighLowSeries
  182.45 +    {
  182.46 +        /// <summary>
  182.47 +        /// Initializes a new instance of the <see cref = "CandleStickSeries" /> class.
  182.48 +        /// </summary>
  182.49 +        public CandleStickSeries()
  182.50 +        {
  182.51 +            this.CandleWidth = 10;
  182.52 +        }
  182.53 +
  182.54 +        /// <summary>
  182.55 +        /// Initializes a new instance of the <see cref="CandleStickSeries"/> class.
  182.56 +        /// </summary>
  182.57 +        /// <param name="title">
  182.58 +        /// The title.
  182.59 +        /// </param>
  182.60 +        public CandleStickSeries(string title)
  182.61 +            : this()
  182.62 +        {
  182.63 +            this.Title = title;
  182.64 +        }
  182.65 +
  182.66 +        /// <summary>
  182.67 +        /// Initializes a new instance of the <see cref="CandleStickSeries"/> class.
  182.68 +        /// </summary>
  182.69 +        /// <param name="color">
  182.70 +        /// The color.
  182.71 +        /// </param>
  182.72 +        /// <param name="strokeThickness">
  182.73 +        /// The stroke thickness.
  182.74 +        /// </param>
  182.75 +        /// <param name="title">
  182.76 +        /// The title.
  182.77 +        /// </param>
  182.78 +        public CandleStickSeries(OxyColor color, double strokeThickness = 1, string title = null)
  182.79 +            : this()
  182.80 +        {
  182.81 +            this.Color = color;
  182.82 +            this.StrokeThickness = strokeThickness;
  182.83 +            this.Title = title;
  182.84 +        }
  182.85 +
  182.86 +        /// <summary>
  182.87 +        /// Gets or sets the width of the candle.
  182.88 +        /// </summary>
  182.89 +        /// <value>The width of the candle.</value>
  182.90 +        public double CandleWidth { get; set; }
  182.91 +
  182.92 +        /// <summary>
  182.93 +        /// Renders the series on the specified rendering context.
  182.94 +        /// </summary>
  182.95 +        /// <param name="rc">
  182.96 +        /// The rendering context.
  182.97 +        /// </param>
  182.98 +        /// <param name="model">
  182.99 +        /// The owner plot model.
 182.100 +        /// </param>
 182.101 +        public override void Render(IRenderContext rc, PlotModel model)
 182.102 +        {
 182.103 +            if (this.Items.Count == 0)
 182.104 +            {
 182.105 +                return;
 182.106 +            }
 182.107 +
 182.108 +            this.VerifyAxes();
 182.109 +
 182.110 +            var clippingRect = this.GetClippingRect();
 182.111 +
 182.112 +            foreach (var v in this.Items)
 182.113 +            {
 182.114 +                if (!this.IsValidItem(v, this.XAxis, this.YAxis))
 182.115 +                {
 182.116 +                    continue;
 182.117 +                }
 182.118 +
 182.119 +                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
 182.120 +                {
 182.121 +                    var high = this.Transform(v.X, v.High);
 182.122 +                    var low = this.Transform(v.X, v.Low);
 182.123 +
 182.124 +                    if (double.IsNaN(v.Open) || double.IsNaN(v.Close))
 182.125 +                    {
 182.126 +                        rc.DrawClippedLine(
 182.127 +                            new[] { low, high },
 182.128 +                            clippingRect,
 182.129 +                            0,
 182.130 +                            this.GetSelectableColor(this.ActualColor),
 182.131 +                            this.StrokeThickness,
 182.132 +                            this.LineStyle,
 182.133 +                            this.LineJoin,
 182.134 +                            false);
 182.135 +                    }
 182.136 +                    else
 182.137 +                    {
 182.138 +                        var open = this.Transform(v.X, v.Open);
 182.139 +                        var close = this.Transform(v.X, v.Close);
 182.140 +                        var max = new ScreenPoint(open.X, Math.Max(open.Y, close.Y));
 182.141 +                        var min = new ScreenPoint(open.X, Math.Min(open.Y, close.Y));
 182.142 +
 182.143 +                        rc.DrawClippedLine(
 182.144 +                            new[] { high, min },
 182.145 +                            clippingRect,
 182.146 +                            0,
 182.147 +                            this.GetSelectableColor(this.ActualColor),
 182.148 +                            this.StrokeThickness,
 182.149 +                            this.LineStyle,
 182.150 +                            this.LineJoin,
 182.151 +                            true);
 182.152 +
 182.153 +                        rc.DrawClippedLine(
 182.154 +                            new[] { max, low },
 182.155 +                            clippingRect,
 182.156 +                            0,
 182.157 +                            this.GetSelectableColor(this.ActualColor),
 182.158 +                            this.StrokeThickness,
 182.159 +                            this.LineStyle,
 182.160 +                            this.LineJoin,
 182.161 +                            true);
 182.162 +                        var openLeft = open;
 182.163 +                        openLeft.X -= this.CandleWidth * 0.5;
 182.164 +                        var closeRight = close;
 182.165 +                        closeRight.X += this.CandleWidth * 0.5;
 182.166 +                        var rect = new OxyRect(openLeft.X, min.Y, this.CandleWidth, max.Y - min.Y);
 182.167 +                        rc.DrawClippedRectangleAsPolygon(
 182.168 +                            rect, clippingRect, v.Open > v.Close ? this.GetSelectableFillColor(this.ActualColor) : null, this.GetSelectableColor(this.ActualColor), this.StrokeThickness);
 182.169 +                    }
 182.170 +                }
 182.171 +            }
 182.172 +        }
 182.173 +
 182.174 +        /// <summary>
 182.175 +        /// Renders the legend symbol for the series on the specified rendering context.
 182.176 +        /// </summary>
 182.177 +        /// <param name="rc">
 182.178 +        /// The rendering context.
 182.179 +        /// </param>
 182.180 +        /// <param name="legendBox">
 182.181 +        /// The bounding rectangle of the legend box.
 182.182 +        /// </param>
 182.183 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 182.184 +        {
 182.185 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 182.186 +            double yopen = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.7);
 182.187 +            double yclose = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.3);
 182.188 +            double[] dashArray = LineStyleHelper.GetDashArray(this.LineStyle);
 182.189 +            rc.DrawLine(
 182.190 +                new[] { new ScreenPoint(xmid, legendBox.Top), new ScreenPoint(xmid, legendBox.Bottom) },
 182.191 +                this.GetSelectableColor(this.ActualColor),
 182.192 +                this.StrokeThickness,
 182.193 +                dashArray,
 182.194 +                OxyPenLineJoin.Miter,
 182.195 +                true);
 182.196 +            rc.DrawRectangleAsPolygon(
 182.197 +                new OxyRect(xmid - (this.CandleWidth * 0.5), yclose, this.CandleWidth, yopen - yclose),
 182.198 +                this.GetSelectableFillColor(this.ActualColor),
 182.199 +                this.GetSelectableColor(this.ActualColor),
 182.200 +                this.StrokeThickness);
 182.201 +        }
 182.202 +
 182.203 +    }
 182.204 +}
 182.205 \ No newline at end of file
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/External/OxyPlot/OxyPlot/Series/ContourSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   183.3 @@ -0,0 +1,770 @@
   183.4 +// --------------------------------------------------------------------------------------------------------------------
   183.5 +// <copyright file="ContourSeries.cs" company="OxyPlot">
   183.6 +//   The MIT License (MIT)
   183.7 +//
   183.8 +//   Copyright (c) 2012 Oystein Bjorke
   183.9 +//
  183.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  183.11 +//   copy of this software and associated documentation files (the
  183.12 +//   "Software"), to deal in the Software without restriction, including
  183.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  183.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  183.15 +//   permit persons to whom the Software is furnished to do so, subject to
  183.16 +//   the following conditions:
  183.17 +//
  183.18 +//   The above copyright notice and this permission notice shall be included
  183.19 +//   in all copies or substantial portions of the Software.
  183.20 +//
  183.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  183.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  183.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  183.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  183.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  183.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  183.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  183.28 +// </copyright>
  183.29 +// <summary>
  183.30 +//   Represents a series for contour plots.
  183.31 +// </summary>
  183.32 +// --------------------------------------------------------------------------------------------------------------------
  183.33 +namespace OxyPlot.Series
  183.34 +{
  183.35 +    using System;
  183.36 +    using System.Collections.Generic;
  183.37 +    using System.Linq;
  183.38 +
  183.39 +    /// <summary>
  183.40 +    /// Represents a series that renders contours.
  183.41 +    /// </summary>
  183.42 +    /// <remarks>
  183.43 +    /// See http://en.wikipedia.org/wiki/Contour_line and http://www.mathworks.se/help/techdoc/ref/contour.html.
  183.44 +    /// </remarks>
  183.45 +    public class ContourSeries : XYAxisSeries
  183.46 +    {
  183.47 +        /// <summary>
  183.48 +        /// The contour collection.
  183.49 +        /// </summary>
  183.50 +        private List<Contour> contours;
  183.51 +
  183.52 +        /// <summary>
  183.53 +        /// The temporary segment collection.
  183.54 +        /// </summary>
  183.55 +        private List<ContourSegment> segments;
  183.56 +
  183.57 +        /// <summary>
  183.58 +        /// The default color.
  183.59 +        /// </summary>
  183.60 +        private OxyColor defaultColor;
  183.61 +
  183.62 +        /// <summary>
  183.63 +        /// Initializes a new instance of the <see cref = "ContourSeries" /> class.
  183.64 +        /// </summary>
  183.65 +        public ContourSeries()
  183.66 +        {
  183.67 +            this.ContourLevelStep = double.NaN;
  183.68 +
  183.69 +            this.LabelSpacing = double.NaN;
  183.70 +            this.LabelStep = 1;
  183.71 +            this.LabelBackground = OxyColor.FromAColor(220, OxyColors.White);
  183.72 +
  183.73 +            this.Color = null;
  183.74 +            this.StrokeThickness = 1.0;
  183.75 +            this.LineStyle = LineStyle.Solid;
  183.76 +
  183.77 +            this.TrackerFormatString = "{1}: {2:0.####}\n{3}: {4:0.####}\n{5}: {6:0.####}";
  183.78 +        }
  183.79 +
  183.80 +        /// <summary>
  183.81 +        /// Gets or sets the color.
  183.82 +        /// </summary>
  183.83 +        /// <value>The color.</value>
  183.84 +        public OxyColor Color { get; set; }
  183.85 +
  183.86 +        /// <summary>
  183.87 +        /// Gets the actual color.
  183.88 +        /// </summary>
  183.89 +        /// <value>The actual color.</value>
  183.90 +        public OxyColor ActualColor
  183.91 +        {
  183.92 +            get { return this.Color ?? this.defaultColor; }
  183.93 +        }
  183.94 +
  183.95 +        /// <summary>
  183.96 +        /// Gets or sets the column coordinates.
  183.97 +        /// </summary>
  183.98 +        /// <value>The column coordinates.</value>
  183.99 +        public double[] ColumnCoordinates { get; set; }
 183.100 +
 183.101 +        /// <summary>
 183.102 +        /// Gets or sets the contour level step size.
 183.103 +        /// This property is not used if the ContourLevels vector is set.
 183.104 +        /// </summary>
 183.105 +        /// <value>The contour level step size.</value>
 183.106 +        public double ContourLevelStep { get; set; }
 183.107 +
 183.108 +        /// <summary>
 183.109 +        /// Gets or sets the contour levels.
 183.110 +        /// </summary>
 183.111 +        /// <value>The contour levels.</value>
 183.112 +        public double[] ContourLevels { get; set; }
 183.113 +
 183.114 +        /// <summary>
 183.115 +        /// Gets or sets the contour colors.
 183.116 +        /// </summary>
 183.117 +        /// <value>The contour colors.</value>
 183.118 +        /// <remarks>
 183.119 +        /// These colors will override the Color of the series.
 183.120 +        /// If there are less colors than the number of contour levels, the colors will cycle.
 183.121 +        /// </remarks>
 183.122 +        public OxyColor[] ContourColors { get; set; }
 183.123 +
 183.124 +        /// <summary>
 183.125 +        /// Gets or sets the data.
 183.126 +        /// </summary>
 183.127 +        /// <value>The data.</value>
 183.128 +        public double[,] Data { get; set; }
 183.129 +
 183.130 +        /// <summary>
 183.131 +        /// Gets or sets the text background color.
 183.132 +        /// </summary>
 183.133 +        /// <value>The text background color.</value>
 183.134 +        public OxyColor LabelBackground { get; set; }
 183.135 +
 183.136 +        /// <summary>
 183.137 +        /// Gets or sets the format string for contour values.
 183.138 +        /// </summary>
 183.139 +        /// <value>The format string.</value>
 183.140 +        public string LabelFormatString { get; set; }
 183.141 +
 183.142 +        /// <summary>
 183.143 +        /// Gets or sets the label spacing.
 183.144 +        /// </summary>
 183.145 +        /// <value>The label spacing.</value>
 183.146 +        public double LabelSpacing { get; set; }
 183.147 +
 183.148 +        /// <summary>
 183.149 +        /// Gets or sets the label step (number of contours per label).
 183.150 +        /// </summary>
 183.151 +        /// <value>The label step.</value>
 183.152 +        public int LabelStep { get; set; }
 183.153 +
 183.154 +        /// <summary>
 183.155 +        /// Gets or sets the line style.
 183.156 +        /// </summary>
 183.157 +        /// <value>The line style.</value>
 183.158 +        public LineStyle LineStyle { get; set; }
 183.159 +
 183.160 +        /// <summary>
 183.161 +        /// Gets or sets the row coordinates.
 183.162 +        /// </summary>
 183.163 +        /// <value>The row coordinates.</value>
 183.164 +        public double[] RowCoordinates { get; set; }
 183.165 +
 183.166 +        /// <summary>
 183.167 +        /// Gets or sets the stroke thickness.
 183.168 +        /// </summary>
 183.169 +        /// <value>The stroke thickness.</value>
 183.170 +        public double StrokeThickness { get; set; }
 183.171 +
 183.172 +        /// <summary>
 183.173 +        /// Calculates the contours.
 183.174 +        /// </summary>
 183.175 +        public void CalculateContours()
 183.176 +        {
 183.177 +            if (this.Data == null)
 183.178 +            {
 183.179 +                return;
 183.180 +            }
 183.181 +
 183.182 +            double[] actualContourLevels = this.ContourLevels;
 183.183 +
 183.184 +            this.segments = new List<ContourSegment>();
 183.185 +            Conrec.RendererDelegate renderer = (startX, startY, endX, endY, contourLevel) =>
 183.186 +                this.segments.Add(new ContourSegment(new DataPoint(startX, startY), new DataPoint(endX, endY), contourLevel));
 183.187 +
 183.188 +            if (actualContourLevels == null)
 183.189 +            {
 183.190 +                double max = this.Data[0, 0];
 183.191 +                double min = this.Data[0, 0];
 183.192 +                for (int i = 0; i < this.Data.GetUpperBound(0); i++)
 183.193 +                {
 183.194 +                    for (int j = 0; j < this.Data.GetUpperBound(1); j++)
 183.195 +                    {
 183.196 +                        max = Math.Max(max, this.Data[i, j]);
 183.197 +                        min = Math.Min(min, this.Data[i, j]);
 183.198 +                    }
 183.199 +                }
 183.200 +
 183.201 +                double actualStep = this.ContourLevelStep;
 183.202 +                if (double.IsNaN(actualStep))
 183.203 +                {
 183.204 +                    double range = max - min;
 183.205 +                    double step = range / 20;
 183.206 +                    actualStep = Math.Pow(10, Math.Floor(step.GetExponent()));
 183.207 +                }
 183.208 +
 183.209 +                max = max.ToUpperMultiple(actualStep);
 183.210 +                min = min.ToLowerMultiple(actualStep);
 183.211 +                actualContourLevels = ArrayHelper.CreateVector(min, max, actualStep);
 183.212 +            }
 183.213 +
 183.214 +            Conrec.Contour(this.Data, this.RowCoordinates, this.ColumnCoordinates, actualContourLevels, renderer);
 183.215 +
 183.216 +            this.JoinContourSegments();
 183.217 +
 183.218 +            if (this.ContourColors != null && this.ContourColors.Length > 0)
 183.219 +            {
 183.220 +                foreach (var c in this.contours)
 183.221 +                {
 183.222 +                    // get the index of the contour's level
 183.223 +                    var index = IndexOf(actualContourLevels, c.ContourLevel);
 183.224 +                    if (index >= 0)
 183.225 +                    {
 183.226 +                        // clamp the index to the range of the ContourColors array
 183.227 +                        index = index % this.ContourColors.Length;
 183.228 +                        c.Color = this.ContourColors[index];
 183.229 +                    }
 183.230 +                }
 183.231 +            }
 183.232 +        }
 183.233 +
 183.234 +        /// <summary>
 183.235 +        /// Gets the point in the dataset that is nearest the specified point.
 183.236 +        /// </summary>
 183.237 +        /// <param name="point">
 183.238 +        /// The point.
 183.239 +        /// </param>
 183.240 +        /// <param name="interpolate">
 183.241 +        /// The interpolate.
 183.242 +        /// </param>
 183.243 +        /// <returns>
 183.244 +        /// A hit result object.
 183.245 +        /// </returns>
 183.246 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 183.247 +        {
 183.248 +            TrackerHitResult result = null;
 183.249 +
 183.250 +            var xaxisTitle = this.XAxis.Title ?? "X";
 183.251 +            var yaxisTitle = this.YAxis.Title ?? "Y";
 183.252 +            var zaxisTitle = "Z";
 183.253 +
 183.254 +            foreach (var c in this.contours)
 183.255 +            {
 183.256 +                var r = interpolate ? this.GetNearestInterpolatedPointInternal(c.Points, point) : this.GetNearestPointInternal(c.Points, point);
 183.257 +                if (r != null)
 183.258 +                {
 183.259 +                    if (result == null || result.Position.DistanceToSquared(point) > r.Position.DistanceToSquared(point))
 183.260 +                    {
 183.261 +                        result = r;
 183.262 +                        result.Text = StringHelper.Format(
 183.263 +                            this.ActualCulture,
 183.264 +                            this.TrackerFormatString,
 183.265 +                            null,
 183.266 +                            this.Title,
 183.267 +                            xaxisTitle,
 183.268 +                            r.DataPoint.X,
 183.269 +                            yaxisTitle,
 183.270 +                            r.DataPoint.Y,
 183.271 +                            zaxisTitle,
 183.272 +                            c.ContourLevel);
 183.273 +                    }
 183.274 +                }
 183.275 +            }
 183.276 +
 183.277 +            return result;
 183.278 +        }
 183.279 +
 183.280 +        /// <summary>
 183.281 +        /// Renders the series on the specified rendering context.
 183.282 +        /// </summary>
 183.283 +        /// <param name="rc">
 183.284 +        /// The rendering context.
 183.285 +        /// </param>
 183.286 +        /// <param name="model">
 183.287 +        /// The model.
 183.288 +        /// </param>
 183.289 +        public override void Render(IRenderContext rc, PlotModel model)
 183.290 +        {
 183.291 +            if (this.contours == null)
 183.292 +            {
 183.293 +                this.CalculateContours();
 183.294 +            }
 183.295 +
 183.296 +            if (this.contours.Count == 0)
 183.297 +            {
 183.298 +                return;
 183.299 +            }
 183.300 +
 183.301 +            this.VerifyAxes();
 183.302 +
 183.303 +            var clippingRect = this.GetClippingRect();
 183.304 +
 183.305 +            var contourLabels = new List<ContourLabel>();
 183.306 +
 183.307 +            foreach (var contour in this.contours)
 183.308 +            {
 183.309 +                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
 183.310 +                {
 183.311 +                    var pts = new ScreenPoint[contour.Points.Count];
 183.312 +                    {
 183.313 +                        int i = 0;
 183.314 +                        foreach (var pt in contour.Points)
 183.315 +                        {
 183.316 +                            pts[i++] = this.Transform(pt.X, pt.Y);
 183.317 +                        }
 183.318 +                    }
 183.319 +
 183.320 +                    rc.DrawClippedLine(
 183.321 +                        pts,
 183.322 +                        clippingRect,
 183.323 +                        4,
 183.324 +                        this.GetSelectableColor(contour.Color ?? this.ActualColor),
 183.325 +                        this.StrokeThickness,
 183.326 +                        this.LineStyle,
 183.327 +                        OxyPenLineJoin.Miter,
 183.328 +                        false);
 183.329 +
 183.330 +                    // rc.DrawClippedPolygon(pts, clippingRect, 4, model.GetDefaultColor(), OxyColors.Black);
 183.331 +                    if (pts.Length > 10)
 183.332 +                    {
 183.333 +                        this.AddContourLabels(contour, pts, clippingRect, contourLabels);
 183.334 +                    }
 183.335 +                }
 183.336 +            }
 183.337 +
 183.338 +            foreach (var cl in contourLabels)
 183.339 +            {
 183.340 +                this.RenderLabelBackground(rc, cl);
 183.341 +            }
 183.342 +
 183.343 +            foreach (var cl in contourLabels)
 183.344 +            {
 183.345 +                this.RenderLabel(rc, cl);
 183.346 +            }
 183.347 +        }
 183.348 +
 183.349 +        /// <summary>
 183.350 +        /// Sets default values from the plotmodel.
 183.351 +        /// </summary>
 183.352 +        /// <param name="model">
 183.353 +        /// The plot model.
 183.354 +        /// </param>
 183.355 +        protected internal override void SetDefaultValues(PlotModel model)
 183.356 +        {
 183.357 +            if (this.Color == null)
 183.358 +            {
 183.359 +                this.LineStyle = model.GetDefaultLineStyle();
 183.360 +                this.defaultColor = model.GetDefaultColor();
 183.361 +            }
 183.362 +        }
 183.363 +
 183.364 +        /// <summary>
 183.365 +        /// Updates the max/min from the datapoints.
 183.366 +        /// </summary>
 183.367 +        protected internal override void UpdateMaxMin()
 183.368 +        {
 183.369 +            this.MinX = this.ColumnCoordinates.Min();
 183.370 +            this.MaxX = this.ColumnCoordinates.Max();
 183.371 +            this.MinY = this.RowCoordinates.Min();
 183.372 +            this.MaxY = this.RowCoordinates.Max();
 183.373 +        }
 183.374 +
 183.375 +        /// <summary>
 183.376 +        /// Determines if two values are close.
 183.377 +        /// </summary>
 183.378 +        /// <param name="x1">
 183.379 +        /// The first value.
 183.380 +        /// </param>
 183.381 +        /// <param name="x2">
 183.382 +        /// The second value.
 183.383 +        /// </param>
 183.384 +        /// <param name="eps">
 183.385 +        /// The squared tolerance.
 183.386 +        /// </param>
 183.387 +        /// <returns>
 183.388 +        /// True if the values are close.
 183.389 +        /// </returns>
 183.390 +        private static bool AreClose(double x1, double x2, double eps = 1e-6)
 183.391 +        {
 183.392 +            double dx = x1 - x2;
 183.393 +            return dx * dx < eps;
 183.394 +        }
 183.395 +
 183.396 +        /// <summary>
 183.397 +        /// Determines if two points are close.
 183.398 +        /// </summary>
 183.399 +        /// <param name="p0">
 183.400 +        /// The first point.
 183.401 +        /// </param>
 183.402 +        /// <param name="p1">
 183.403 +        /// The second point.
 183.404 +        /// </param>
 183.405 +        /// <param name="eps">
 183.406 +        /// The squared tolerance.
 183.407 +        /// </param>
 183.408 +        /// <returns>
 183.409 +        /// True if the points are close.
 183.410 +        /// </returns>
 183.411 +        private static bool AreClose(DataPoint p0, DataPoint p1, double eps = 1e-6)
 183.412 +        {
 183.413 +            double dx = p0.X - p1.X;
 183.414 +            double dy = p0.Y - p1.Y;
 183.415 +            return (dx * dx) + (dy * dy) < eps;
 183.416 +        }
 183.417 +
 183.418 +        /// <summary>
 183.419 +        /// Gets the index of item that is closest to the specified value.
 183.420 +        /// </summary>
 183.421 +        /// <param name="values">A list of values.</param>
 183.422 +        /// <param name="value">A value.</param>
 183.423 +        /// <returns>An index.</returns>
 183.424 +        private static int IndexOf(IList<double> values, double value)
 183.425 +        {
 183.426 +            double min = double.MaxValue;
 183.427 +            int index = -1;
 183.428 +            for (int i = 0; i < values.Count; i++)
 183.429 +            {
 183.430 +                var d = Math.Abs(values[i] - value);
 183.431 +                if (d < min)
 183.432 +                {
 183.433 +                    min = d;
 183.434 +                    index = i;
 183.435 +                }
 183.436 +            }
 183.437 +
 183.438 +            return index;
 183.439 +        }
 183.440 +
 183.441 +        /// <summary>
 183.442 +        /// The add contour labels.
 183.443 +        /// </summary>
 183.444 +        /// <param name="contour">
 183.445 +        /// The contour.
 183.446 +        /// </param>
 183.447 +        /// <param name="pts">
 183.448 +        /// The pts.
 183.449 +        /// </param>
 183.450 +        /// <param name="clippingRect">
 183.451 +        /// The clipping rect.
 183.452 +        /// </param>
 183.453 +        /// <param name="contourLabels">
 183.454 +        /// The contour labels.
 183.455 +        /// </param>
 183.456 +        private void AddContourLabels(
 183.457 +            Contour contour, ScreenPoint[] pts, OxyRect clippingRect, List<ContourLabel> contourLabels)
 183.458 +        {
 183.459 +            // todo: support label spacing and label step
 183.460 +            if (pts.Length < 2)
 183.461 +            {
 183.462 +                return;
 183.463 +            }
 183.464 +
 183.465 +            // Calculate position and angle of the label
 183.466 +            double i = (pts.Length - 1) * 0.5;
 183.467 +            var i0 = (int)i;
 183.468 +            int i1 = i0 + 1;
 183.469 +            double dx = pts[i1].X - pts[i0].X;
 183.470 +            double dy = pts[i1].Y - pts[i0].Y;
 183.471 +            double x = pts[i0].X + (dx * (i - i0));
 183.472 +            double y = pts[i0].Y + (dy * (i - i0));
 183.473 +            if (!clippingRect.Contains(x, y))
 183.474 +            {
 183.475 +                return;
 183.476 +            }
 183.477 +
 183.478 +            var pos = new ScreenPoint(x, y);
 183.479 +            double angle = Math.Atan2(dy, dx) * 180 / Math.PI;
 183.480 +            if (angle > 90)
 183.481 +            {
 183.482 +                angle -= 180;
 183.483 +            }
 183.484 +
 183.485 +            if (angle < -90)
 183.486 +            {
 183.487 +                angle += 180;
 183.488 +            }
 183.489 +
 183.490 +            string text = contour.ContourLevel.ToString(this.LabelFormatString, this.ActualCulture);
 183.491 +            contourLabels.Add(new ContourLabel { Position = pos, Angle = angle, Text = text });
 183.492 +        }
 183.493 +
 183.494 +        /// <summary>
 183.495 +        /// Finds the connected segment.
 183.496 +        /// </summary>
 183.497 +        /// <param name="point">
 183.498 +        /// The point.
 183.499 +        /// </param>
 183.500 +        /// <param name="contourLevel">
 183.501 +        /// The contour level.
 183.502 +        /// </param>
 183.503 +        /// <param name="eps">
 183.504 +        /// The eps.
 183.505 +        /// </param>
 183.506 +        /// <param name="reverse">
 183.507 +        /// reverse the segment if set to <c>true</c>.
 183.508 +        /// </param>
 183.509 +        /// <returns>
 183.510 +        /// The connected segment, or null if no segment was found.
 183.511 +        /// </returns>
 183.512 +        private ContourSegment FindConnectedSegment(DataPoint point, double contourLevel, double eps, out bool reverse)
 183.513 +        {
 183.514 +            reverse = false;
 183.515 +            foreach (var s in this.segments)
 183.516 +            {
 183.517 +                if (!AreClose(s.ContourLevel, contourLevel, eps))
 183.518 +                {
 183.519 +                    continue;
 183.520 +                }
 183.521 +
 183.522 +                if (AreClose(point, s.StartPoint, eps))
 183.523 +                {
 183.524 +                    return s;
 183.525 +                }
 183.526 +
 183.527 +                if (AreClose(point, s.EndPoint, eps))
 183.528 +                {
 183.529 +                    reverse = true;
 183.530 +                    return s;
 183.531 +                }
 183.532 +            }
 183.533 +
 183.534 +            return null;
 183.535 +        }
 183.536 +
 183.537 +        /// <summary>
 183.538 +        /// Joins the contour segments.
 183.539 +        /// </summary>
 183.540 +        /// <param name="eps">
 183.541 +        /// The tolerance for segment ends to connect (squared distance).
 183.542 +        /// </param>
 183.543 +        private void JoinContourSegments(double eps = 1e-10)
 183.544 +        {
 183.545 +            // This is a simple, slow, naïve method - should be improved:
 183.546 +            // http://stackoverflow.com/questions/1436091/joining-unordered-line-segments
 183.547 +            this.contours = new List<Contour>();
 183.548 +            var contourPoints = new List<IDataPoint>();
 183.549 +            int contourPointsCount = 0;
 183.550 +
 183.551 +            ContourSegment firstSegment = null;
 183.552 +            int segmentCount = this.segments.Count;
 183.553 +            while (segmentCount > 0)
 183.554 +            {
 183.555 +                ContourSegment segment1 = null, segment2 = null;
 183.556 +
 183.557 +                if (firstSegment != null)
 183.558 +                {
 183.559 +                    bool reverse;
 183.560 +
 183.561 +                    // Find a segment that is connected to the head of the contour
 183.562 +                    segment1 = this.FindConnectedSegment(
 183.563 +                        (DataPoint)contourPoints[0], firstSegment.ContourLevel, eps, out reverse);
 183.564 +                    if (segment1 != null)
 183.565 +                    {
 183.566 +                        contourPoints.Insert(0, reverse ? segment1.StartPoint : segment1.EndPoint);
 183.567 +                        contourPointsCount++;
 183.568 +                        this.segments.Remove(segment1);
 183.569 +                        segmentCount--;
 183.570 +                    }
 183.571 +
 183.572 +                    // Find a segment that is connected to the tail of the contour
 183.573 +                    segment2 = this.FindConnectedSegment(
 183.574 +                        (DataPoint)contourPoints[contourPointsCount - 1], firstSegment.ContourLevel, eps, out reverse);
 183.575 +                    if (segment2 != null)
 183.576 +                    {
 183.577 +                        contourPoints.Add(reverse ? segment2.StartPoint : segment2.EndPoint);
 183.578 +                        contourPointsCount++;
 183.579 +                        this.segments.Remove(segment2);
 183.580 +                        segmentCount--;
 183.581 +                    }
 183.582 +                }
 183.583 +
 183.584 +                if ((segment1 == null && segment2 == null) || segmentCount == 0)
 183.585 +                {
 183.586 +                    if (contourPointsCount > 0 && firstSegment != null)
 183.587 +                    {
 183.588 +                        this.contours.Add(new Contour(contourPoints, firstSegment.ContourLevel));
 183.589 +                        contourPoints = new List<IDataPoint>();
 183.590 +                        contourPointsCount = 0;
 183.591 +                    }
 183.592 +
 183.593 +                    if (segmentCount > 0)
 183.594 +                    {
 183.595 +                        firstSegment = this.segments.First();
 183.596 +                        contourPoints.Add(firstSegment.StartPoint);
 183.597 +                        contourPoints.Add(firstSegment.EndPoint);
 183.598 +                        contourPointsCount += 2;
 183.599 +                        this.segments.Remove(firstSegment);
 183.600 +                        segmentCount--;
 183.601 +                    }
 183.602 +                }
 183.603 +            }
 183.604 +        }
 183.605 +
 183.606 +        /// <summary>
 183.607 +        /// Renders the contour label.
 183.608 +        /// </summary>
 183.609 +        /// <param name="rc">
 183.610 +        /// The render context.
 183.611 +        /// </param>
 183.612 +        /// <param name="cl">
 183.613 +        /// The contour label.
 183.614 +        /// </param>
 183.615 +        private void RenderLabel(IRenderContext rc, ContourLabel cl)
 183.616 +        {
 183.617 +            if (this.ActualFontSize > 0)
 183.618 +            {
 183.619 +                rc.DrawText(
 183.620 +                    cl.Position,
 183.621 +                    cl.Text,
 183.622 +                    this.ActualTextColor,
 183.623 +                    this.ActualFont,
 183.624 +                    this.ActualFontSize,
 183.625 +                    this.ActualFontWeight,
 183.626 +                    cl.Angle,
 183.627 +                    HorizontalAlignment.Center,
 183.628 +                    VerticalAlignment.Middle);
 183.629 +            }
 183.630 +        }
 183.631 +
 183.632 +        /// <summary>
 183.633 +        /// Renders the contour label background.
 183.634 +        /// </summary>
 183.635 +        /// <param name="rc">
 183.636 +        /// The render context.
 183.637 +        /// </param>
 183.638 +        /// <param name="cl">
 183.639 +        /// The contour label.
 183.640 +        /// </param>
 183.641 +        private void RenderLabelBackground(IRenderContext rc, ContourLabel cl)
 183.642 +        {
 183.643 +            if (this.LabelBackground != null)
 183.644 +            {
 183.645 +                // Calculate background polygon
 183.646 +                var size = rc.MeasureText(cl.Text, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
 183.647 +                double a = cl.Angle / 180 * Math.PI;
 183.648 +                double dx = Math.Cos(a);
 183.649 +                double dy = Math.Sin(a);
 183.650 +
 183.651 +                double ux = dx * 0.6;
 183.652 +                double uy = dy * 0.6;
 183.653 +                double vx = -dy * 0.5;
 183.654 +                double vy = dx * 0.5;
 183.655 +                double x = cl.Position.X;
 183.656 +                double y = cl.Position.Y;
 183.657 +
 183.658 +                var bpts = new[]
 183.659 +                    {
 183.660 +                        new ScreenPoint(x - (size.Width * ux) - (size.Height * vx), y - (size.Width * uy) - (size.Height * vy)),
 183.661 +                        new ScreenPoint(x + (size.Width * ux) - (size.Height * vx), y + (size.Width * uy) - (size.Height * vy)),
 183.662 +                        new ScreenPoint(x + (size.Width * ux) + (size.Height * vx), y + (size.Width * uy) + (size.Height * vy)),
 183.663 +                        new ScreenPoint(x - (size.Width * ux) + (size.Height * vx), y - (size.Width * uy) + (size.Height * vy))
 183.664 +                    };
 183.665 +                rc.DrawPolygon(bpts, this.LabelBackground, null);
 183.666 +            }
 183.667 +        }
 183.668 +
 183.669 +        /// <summary>
 183.670 +        /// Represents a contour.
 183.671 +        /// </summary>
 183.672 +        private class Contour
 183.673 +        {
 183.674 +            /// <summary>
 183.675 +            /// Gets or sets the contour level.
 183.676 +            /// </summary>
 183.677 +            /// <value>The contour level.</value>
 183.678 +            internal readonly double ContourLevel;
 183.679 +
 183.680 +            /// <summary>
 183.681 +            /// Gets or sets the points.
 183.682 +            /// </summary>
 183.683 +            /// <value>The points.</value>
 183.684 +            internal readonly IList<IDataPoint> Points;
 183.685 +
 183.686 +            /// <summary>
 183.687 +            /// Initializes a new instance of the <see cref="Contour"/> class.
 183.688 +            /// </summary>
 183.689 +            /// <param name="points">
 183.690 +            /// The points.
 183.691 +            /// </param>
 183.692 +            /// <param name="contourLevel">
 183.693 +            /// The contour level.
 183.694 +            /// </param>
 183.695 +            public Contour(IList<IDataPoint> points, double contourLevel)
 183.696 +            {
 183.697 +                this.Points = points;
 183.698 +                this.ContourLevel = contourLevel;
 183.699 +            }
 183.700 +
 183.701 +            /// <summary>
 183.702 +            /// Gets or sets the color of the contour.
 183.703 +            /// </summary>
 183.704 +            public OxyColor Color { get; set; }
 183.705 +        }
 183.706 +
 183.707 +        /// <summary>
 183.708 +        /// Represents a contour label.
 183.709 +        /// </summary>
 183.710 +        private class ContourLabel
 183.711 +        {
 183.712 +            /// <summary>
 183.713 +            /// Gets or sets the angle.
 183.714 +            /// </summary>
 183.715 +            /// <value>The angle.</value>
 183.716 +            public double Angle { get; set; }
 183.717 +
 183.718 +            /// <summary>
 183.719 +            /// Gets or sets the position.
 183.720 +            /// </summary>
 183.721 +            /// <value>The position.</value>
 183.722 +            public ScreenPoint Position { get; set; }
 183.723 +
 183.724 +            /// <summary>
 183.725 +            /// Gets or sets the text.
 183.726 +            /// </summary>
 183.727 +            /// <value>The text.</value>
 183.728 +            public string Text { get; set; }
 183.729 +
 183.730 +        }
 183.731 +
 183.732 +        /// <summary>
 183.733 +        /// Represents a contour segment.
 183.734 +        /// </summary>
 183.735 +        private class ContourSegment
 183.736 +        {
 183.737 +            /// <summary>
 183.738 +            /// The contour level.
 183.739 +            /// </summary>
 183.740 +            internal readonly double ContourLevel;
 183.741 +
 183.742 +            /// <summary>
 183.743 +            /// The end point.
 183.744 +            /// </summary>
 183.745 +            internal readonly DataPoint EndPoint;
 183.746 +
 183.747 +            /// <summary>
 183.748 +            /// The start point.
 183.749 +            /// </summary>
 183.750 +            internal readonly DataPoint StartPoint;
 183.751 +
 183.752 +            /// <summary>
 183.753 +            /// Initializes a new instance of the <see cref="ContourSegment"/> class.
 183.754 +            /// </summary>
 183.755 +            /// <param name="startPoint">
 183.756 +            /// The start point.
 183.757 +            /// </param>
 183.758 +            /// <param name="endPoint">
 183.759 +            /// The end point.
 183.760 +            /// </param>
 183.761 +            /// <param name="contourLevel">
 183.762 +            /// The contour level.
 183.763 +            /// </param>
 183.764 +            public ContourSegment(DataPoint startPoint, DataPoint endPoint, double contourLevel)
 183.765 +            {
 183.766 +                this.ContourLevel = contourLevel;
 183.767 +                this.StartPoint = startPoint;
 183.768 +                this.EndPoint = endPoint;
 183.769 +            }
 183.770 +
 183.771 +        }
 183.772 +    }
 183.773 +}
 183.774 \ No newline at end of file
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/External/OxyPlot/OxyPlot/Series/DataPointSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   184.3 @@ -0,0 +1,325 @@
   184.4 +// --------------------------------------------------------------------------------------------------------------------
   184.5 +// <copyright file="DataPointSeries.cs" company="OxyPlot">
   184.6 +//   The MIT License (MIT)
   184.7 +//
   184.8 +//   Copyright (c) 2012 Oystein Bjorke
   184.9 +//
  184.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  184.11 +//   copy of this software and associated documentation files (the
  184.12 +//   "Software"), to deal in the Software without restriction, including
  184.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  184.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  184.15 +//   permit persons to whom the Software is furnished to do so, subject to
  184.16 +//   the following conditions:
  184.17 +//
  184.18 +//   The above copyright notice and this permission notice shall be included
  184.19 +//   in all copies or substantial portions of the Software.
  184.20 +//
  184.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  184.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  184.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  184.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  184.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  184.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  184.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  184.28 +// </copyright>
  184.29 +// <summary>
  184.30 +//   Base class for series that contain a collection of IDataPoints.
  184.31 +// </summary>
  184.32 +// --------------------------------------------------------------------------------------------------------------------
  184.33 +namespace OxyPlot.Series
  184.34 +{
  184.35 +    using System;
  184.36 +    using System.Collections;
  184.37 +    using System.Collections.Generic;
  184.38 +    using System.Reflection;
  184.39 +
  184.40 +    /// <summary>
  184.41 +    /// Provides an abstract base class for series that contain a collection of <see cref="IDataPoint"/>s.
  184.42 +    /// </summary>
  184.43 +    public abstract class DataPointSeries : XYAxisSeries
  184.44 +    {
  184.45 +        /// <summary>
  184.46 +        /// The list of data points.
  184.47 +        /// </summary>
  184.48 +        private IList<IDataPoint> points = new List<IDataPoint>();
  184.49 +
  184.50 +        /// <summary>
  184.51 +        /// Initializes a new instance of the <see cref = "DataPointSeries" /> class.
  184.52 +        /// </summary>
  184.53 +        protected DataPointSeries()
  184.54 +        {
  184.55 +            this.DataFieldX = null;
  184.56 +            this.DataFieldY = null;
  184.57 +        }
  184.58 +
  184.59 +        /// <summary>
  184.60 +        /// Gets or sets a value indicating whether the tracker can interpolate points.
  184.61 +        /// </summary>
  184.62 +        public bool CanTrackerInterpolatePoints { get; set; }
  184.63 +
  184.64 +        /// <summary>
  184.65 +        /// Gets or sets the data field X.
  184.66 +        /// </summary>
  184.67 +        /// <value>The data field X.</value>
  184.68 +        public string DataFieldX { get; set; }
  184.69 +
  184.70 +        /// <summary>
  184.71 +        /// Gets or sets the data field Y.
  184.72 +        /// </summary>
  184.73 +        /// <value>The data field Y.</value>
  184.74 +        public string DataFieldY { get; set; }
  184.75 +
  184.76 +        /// <summary>
  184.77 +        /// Gets or sets the mapping delegate.
  184.78 +        /// Example: series1.Mapping = item => new DataPoint(((MyType)item).Time,((MyType)item).Value);
  184.79 +        /// </summary>
  184.80 +        /// <value>The mapping.</value>
  184.81 +        public Func<object, IDataPoint> Mapping { get; set; }
  184.82 +
  184.83 +        /// <summary>
  184.84 +        /// Gets or sets the points list.
  184.85 +        /// </summary>
  184.86 +        /// <value>The points list.</value>
  184.87 +        public IList<IDataPoint> Points
  184.88 +        {
  184.89 +            get
  184.90 +            {
  184.91 +                return this.points;
  184.92 +            }
  184.93 +
  184.94 +            set
  184.95 +            {
  184.96 +                this.points = value;
  184.97 +            }
  184.98 +        }
  184.99 +
 184.100 +        /// <summary>
 184.101 +        /// Gets or sets a value indicating whether this <see cref = "DataPointSeries" /> is smooth.
 184.102 +        /// </summary>
 184.103 +        /// <value><c>true</c> if smooth; otherwise, <c>false</c>.</value>
 184.104 +        public bool Smooth { get; set; }
 184.105 +
 184.106 +        /// <summary>
 184.107 +        /// Gets the point on the series that is nearest the specified point.
 184.108 +        /// </summary>
 184.109 +        /// <param name="point">The point.</param>
 184.110 +        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
 184.111 +        /// <returns>
 184.112 +        /// A TrackerHitResult for the current hit.
 184.113 +        /// </returns>
 184.114 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 184.115 +        {
 184.116 +            if (interpolate && !this.CanTrackerInterpolatePoints)
 184.117 +            {
 184.118 +                return null;
 184.119 +            }
 184.120 +
 184.121 +            if (interpolate)
 184.122 +            {
 184.123 +                return this.GetNearestInterpolatedPointInternal(this.Points, point);
 184.124 +            }
 184.125 +
 184.126 +            return this.GetNearestPointInternal(this.Points, point);
 184.127 +        }
 184.128 +
 184.129 +        /// <summary>
 184.130 +        /// Gets the item at the specified index.
 184.131 +        /// </summary>
 184.132 +        /// <param name="i">The index of the item.</param>
 184.133 +        /// <returns>The item of the index.</returns>
 184.134 +        protected override object GetItem(int i)
 184.135 +        {
 184.136 +            if (this.ItemsSource == null && this.Points != null && i < this.Points.Count)
 184.137 +            {
 184.138 +                return this.Points[i];
 184.139 +            }
 184.140 +
 184.141 +            return base.GetItem(i);
 184.142 +        }
 184.143 +
 184.144 +        /// <summary>
 184.145 +        /// The update data.
 184.146 +        /// </summary>
 184.147 +        protected internal override void UpdateData()
 184.148 +        {
 184.149 +            if (this.ItemsSource == null)
 184.150 +            {
 184.151 +                return;
 184.152 +            }
 184.153 +
 184.154 +            this.AddDataPoints(this.Points);
 184.155 +        }
 184.156 +
 184.157 +        /// <summary>
 184.158 +        /// Updates the max/min from the datapoints.
 184.159 +        /// </summary>
 184.160 +        protected internal override void UpdateMaxMin()
 184.161 +        {
 184.162 +            base.UpdateMaxMin();
 184.163 +            this.InternalUpdateMaxMin(this.Points);
 184.164 +        }
 184.165 +
 184.166 +        /// <summary>
 184.167 +        /// The add data points.
 184.168 +        /// </summary>
 184.169 +        /// <param name="pts">
 184.170 +        /// The points.
 184.171 +        /// </param>
 184.172 +        protected void AddDataPoints(IList<IDataPoint> pts)
 184.173 +        {
 184.174 +            pts.Clear();
 184.175 +
 184.176 +            // Use the mapping to generate the points
 184.177 +            if (this.Mapping != null)
 184.178 +            {
 184.179 +                foreach (var item in this.ItemsSource)
 184.180 +                {
 184.181 +                    pts.Add(this.Mapping(item));
 184.182 +                }
 184.183 +
 184.184 +                return;
 184.185 +            }
 184.186 +
 184.187 +            // Get DataPoints from the items in ItemsSource
 184.188 +            // if they implement IDataPointProvider
 184.189 +            // If DataFields are set, this is not used
 184.190 +            if (this.DataFieldX == null || this.DataFieldY == null)
 184.191 +            {
 184.192 +                foreach (var item in this.ItemsSource)
 184.193 +                {
 184.194 +                    var dp = item as IDataPoint;
 184.195 +                    if (dp != null)
 184.196 +                    {
 184.197 +                        pts.Add(dp);
 184.198 +                        continue;
 184.199 +                    }
 184.200 +
 184.201 +                    var idpp = item as IDataPointProvider;
 184.202 +                    if (idpp == null)
 184.203 +                    {
 184.204 +                        continue;
 184.205 +                    }
 184.206 +
 184.207 +                    pts.Add(idpp.GetDataPoint());
 184.208 +                }
 184.209 +            }
 184.210 +            else
 184.211 +            {
 184.212 +                // TODO: is there a better way to do this?
 184.213 +                // http://msdn.microsoft.com/en-us/library/bb613546.aspx
 184.214 +
 184.215 +                // Using reflection on DataFieldX and DataFieldY
 184.216 +                this.AddDataPoints((IList)pts, this.ItemsSource, this.DataFieldX, this.DataFieldY);
 184.217 +            }
 184.218 +        }
 184.219 +
 184.220 +        /// <summary>
 184.221 +        /// The add data points.
 184.222 +        /// </summary>
 184.223 +        /// <param name="dest">
 184.224 +        /// The dest.
 184.225 +        /// </param>
 184.226 +        /// <param name="itemsSource">
 184.227 +        /// The items source.
 184.228 +        /// </param>
 184.229 +        /// <param name="dataFieldX">
 184.230 +        /// The data field x.
 184.231 +        /// </param>
 184.232 +        /// <param name="dataFieldY">
 184.233 +        /// The data field y.
 184.234 +        /// </param>
 184.235 +        protected void AddDataPoints(IList dest, IEnumerable itemsSource, string dataFieldX, string dataFieldY)
 184.236 +        {
 184.237 +            PropertyInfo pix = null;
 184.238 +            PropertyInfo piy = null;
 184.239 +            Type t = null;
 184.240 +
 184.241 +            foreach (var o in itemsSource)
 184.242 +            {
 184.243 +                if (pix == null || o.GetType() != t)
 184.244 +                {
 184.245 +                    t = o.GetType();
 184.246 +                    pix = t.GetProperty(dataFieldX);
 184.247 +                    piy = t.GetProperty(dataFieldY);
 184.248 +                    if (pix == null)
 184.249 +                    {
 184.250 +                        throw new InvalidOperationException(
 184.251 +                            string.Format("Could not find data field {0} on type {1}", this.DataFieldX, t));
 184.252 +                    }
 184.253 +
 184.254 +                    if (piy == null)
 184.255 +                    {
 184.256 +                        throw new InvalidOperationException(
 184.257 +                            string.Format("Could not find data field {0} on type {1}", this.DataFieldY, t));
 184.258 +                    }
 184.259 +                }
 184.260 +
 184.261 +                double x = this.ToDouble(pix.GetValue(o, null));
 184.262 +                double y = this.ToDouble(piy.GetValue(o, null));
 184.263 +
 184.264 +                var pp = new DataPoint(x, y);
 184.265 +                dest.Add(pp);
 184.266 +            }
 184.267 +
 184.268 +            //var filler = new ListFiller<DataPoint>();
 184.269 +            //filler.Add(dataFieldX, (item, value) => item.X = this.ToDouble(value));
 184.270 +            //filler.Add(dataFieldY, (item, value) => item.Y = this.ToDouble(value));
 184.271 +            //filler.Fill(dest, itemsSource);
 184.272 +        }
 184.273 +
 184.274 +        /// <summary>
 184.275 +        /// Updates the Max/Min limits from the specified point list.
 184.276 +        /// </summary>
 184.277 +        /// <param name="pts">
 184.278 +        /// The points.
 184.279 +        /// </param>
 184.280 +        protected void InternalUpdateMaxMin(IList<IDataPoint> pts)
 184.281 +        {
 184.282 +            if (pts == null || pts.Count == 0)
 184.283 +            {
 184.284 +                return;
 184.285 +            }
 184.286 +
 184.287 +            double minx = this.MinX;
 184.288 +            double miny = this.MinY;
 184.289 +            double maxx = this.MaxX;
 184.290 +            double maxy = this.MaxY;
 184.291 +
 184.292 +            foreach (var pt in pts)
 184.293 +            {
 184.294 +                if (!this.IsValidPoint(pt, this.XAxis, this.YAxis))
 184.295 +                {
 184.296 +                    continue;
 184.297 +                }
 184.298 +
 184.299 +                double x = pt.X;
 184.300 +                double y = pt.Y;
 184.301 +                if (x < minx || double.IsNaN(minx))
 184.302 +                {
 184.303 +                    minx = x;
 184.304 +                }
 184.305 +
 184.306 +                if (x > maxx || double.IsNaN(maxx))
 184.307 +                {
 184.308 +                    maxx = x;
 184.309 +                }
 184.310 +
 184.311 +                if (y < miny || double.IsNaN(miny))
 184.312 +                {
 184.313 +                    miny = y;
 184.314 +                }
 184.315 +
 184.316 +                if (y > maxy || double.IsNaN(maxy))
 184.317 +                {
 184.318 +                    maxy = y;
 184.319 +                }
 184.320 +            }
 184.321 +
 184.322 +            this.MinX = minx;
 184.323 +            this.MinY = miny;
 184.324 +            this.MaxX = maxx;
 184.325 +            this.MaxY = maxy;
 184.326 +        }
 184.327 +    }
 184.328 +}
 184.329 \ No newline at end of file
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/External/OxyPlot/OxyPlot/Series/DataSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   185.3 @@ -0,0 +1,391 @@
   185.4 +// --------------------------------------------------------------------------------------------------------------------
   185.5 +// <copyright file="DataSeries.cs" company="OxyPlot">
   185.6 +//   The MIT License (MIT)
   185.7 +//
   185.8 +//   Copyright (c) 2012 Oystein Bjorke
   185.9 +//
  185.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  185.11 +//   copy of this software and associated documentation files (the
  185.12 +//   "Software"), to deal in the Software without restriction, including
  185.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  185.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  185.15 +//   permit persons to whom the Software is furnished to do so, subject to
  185.16 +//   the following conditions:
  185.17 +//
  185.18 +//   The above copyright notice and this permission notice shall be included
  185.19 +//   in all copies or substantial portions of the Software.
  185.20 +//
  185.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  185.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  185.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  185.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  185.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  185.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  185.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  185.28 +// </copyright>
  185.29 +// <summary>
  185.30 +//   DataPointProvider interface.
  185.31 +// </summary>
  185.32 +// --------------------------------------------------------------------------------------------------------------------
  185.33 +using System;
  185.34 +using System.Collections;
  185.35 +using System.Collections.Generic;
  185.36 +using System.Collections.ObjectModel;
  185.37 +using System.ComponentModel;
  185.38 +using System.Linq;
  185.39 +using System.Reflection;
  185.40 +
  185.41 +namespace OxyPlot
  185.42 +{
  185.43 +    /// <summary>
  185.44 +    /// DataPointProvider interface.
  185.45 +    /// </summary>
  185.46 +    public interface IDataPointProvider
  185.47 +    {
  185.48 +        /// <summary>
  185.49 +        /// Gets the data point.
  185.50 +        /// </summary>
  185.51 +        /// <returns></returns>
  185.52 +        DataPoint GetDataPoint();
  185.53 +    }
  185.54 +
  185.55 +    public abstract class DataSeries : PlotSeriesBase
  185.56 +    {
  185.57 +        protected IList<DataPoint> points;
  185.58 +
  185.59 +        protected DataSeries()
  185.60 +        {
  185.61 +            points = new Collection<DataPoint>();
  185.62 +            DataFieldX = "X";
  185.63 +            DataFieldY = "Y";
  185.64 +            CanTrackerInterpolatePoints = false;
  185.65 +        }
  185.66 +
  185.67 +        /// <summary>
  185.68 +        /// Gets or sets the items source.
  185.69 +        /// </summary>
  185.70 +        /// <value>The items source.</value>
  185.71 +        public IEnumerable ItemsSource { get; set; }
  185.72 +
  185.73 +        /// <summary>
  185.74 +        /// Gets or sets the data field X.
  185.75 +        /// </summary>
  185.76 +        /// <value>The data field X.</value>
  185.77 +        public string DataFieldX { get; set; }
  185.78 +
  185.79 +        /// <summary>
  185.80 +        /// Gets or sets the data field Y.
  185.81 +        /// </summary>
  185.82 +        /// <value>The data field Y.</value>
  185.83 +        public string DataFieldY { get; set; }
  185.84 +
  185.85 +        /// <summary>
  185.86 +        /// Gets or sets the mapping deleagte.
  185.87 +        /// Example: series1.Mapping = item => new DataPoint(((MyType)item).Time,((MyType)item).Value);
  185.88 +        /// </summary>
  185.89 +        /// <value>The mapping.</value>
  185.90 +        public Func<object, DataPoint> Mapping { get; set; }
  185.91 +
  185.92 +        /// <summary>
  185.93 +        /// Gets or sets the points.
  185.94 +        /// </summary>
  185.95 +        /// <value>The points.</value>
  185.96 +        [Browsable(false)]
  185.97 +        public IList<DataPoint> Points
  185.98 +        {
  185.99 +            get { return points; }
 185.100 +            set { points = value; }
 185.101 +        }
 185.102 +
 185.103 +        /// <summary>
 185.104 +        /// Gets or sets a value indicating whether this <see cref = "DataSeries" /> is smooth.
 185.105 +        /// </summary>
 185.106 +        /// <value><c>true</c> if smooth; otherwise, <c>false</c>.</value>
 185.107 +        public bool Smooth { get; set; }
 185.108 +
 185.109 +        public override void UpdateData()
 185.110 +        {
 185.111 +            if (ItemsSource == null)
 185.112 +            {
 185.113 +                return;
 185.114 +            }
 185.115 +
 185.116 +            points.Clear();
 185.117 +
 185.118 +            // Use the mapping to generate the points
 185.119 +            if (Mapping != null)
 185.120 +            {
 185.121 +                foreach (var item in ItemsSource)
 185.122 +                {
 185.123 +                    points.Add(Mapping(item));
 185.124 +                }
 185.125 +            }
 185.126 +
 185.127 +            // Get DataPoints from the items in ItemsSource
 185.128 +            // if they implement IDataPointProvider
 185.129 +            // If DataFields are set, this is not used
 185.130 +            if (DataFieldX == null || DataFieldY == null)
 185.131 +            {
 185.132 +                foreach (var item in ItemsSource)
 185.133 +                {
 185.134 +                    var idpp = item as IDataPointProvider;
 185.135 +                    if (idpp == null)
 185.136 +                    {
 185.137 +                        continue;
 185.138 +                    }
 185.139 +
 185.140 +                    points.Add(idpp.GetDataPoint());
 185.141 +                }
 185.142 +
 185.143 +                return;
 185.144 +            }
 185.145 +
 185.146 +            // TODO: is there a better way to do this?
 185.147 +            // http://msdn.microsoft.com/en-us/library/bb613546.aspx
 185.148 +
 185.149 +            // Using reflection on DataFieldX and DataFieldY
 185.150 +            AddDataPoints(points, ItemsSource, DataFieldX, DataFieldY);
 185.151 +        }
 185.152 +
 185.153 +        /// <summary>
 185.154 +        /// Converts the value of the specified object to a double precision floating point number.
 185.155 +        /// DateTime objects are converted using DateTimeAxis.ToDouble
 185.156 +        /// TimeSpan objects are converted using TimeSpanAxis.ToDouble
 185.157 +        /// </summary>
 185.158 +        /// <param name="value">The value.</param>
 185.159 +        /// <returns></returns>
 185.160 +        protected virtual double ToDouble(object value)
 185.161 +        {
 185.162 +            if (value is DateTime)
 185.163 +            {
 185.164 +                return DateTimeAxis.ToDouble((DateTime)value);
 185.165 +            }
 185.166 +
 185.167 +            if (value is TimeSpan)
 185.168 +            {
 185.169 +                return ((TimeSpan)value).TotalSeconds;
 185.170 +            }
 185.171 +
 185.172 +            return Convert.ToDouble(value);
 185.173 +        }
 185.174 +
 185.175 +        /// <summary>
 185.176 +        /// Updates the max/min from the datapoints.
 185.177 +        /// </summary>
 185.178 +        public override void UpdateMaxMin()
 185.179 +        {
 185.180 +            base.UpdateMaxMin();
 185.181 +            InternalUpdateMaxMin(points);
 185.182 +        }
 185.183 +
 185.184 +        /// <summary>
 185.185 +        /// Gets the point in the dataset that is nearest the specified point.
 185.186 +        /// </summary>
 185.187 +        /// <param name = "point">The point.</param>
 185.188 +        /// <param name = "dpn">The nearest point (data coordinates).</param>
 185.189 +        /// <param name = "spn">The nearest point (screen coordinates).</param>
 185.190 +        /// <returns></returns>
 185.191 +        public override bool GetNearestPoint(ScreenPoint point, out DataPoint dpn, out ScreenPoint spn)
 185.192 +        {
 185.193 +            spn = default(ScreenPoint);
 185.194 +            dpn = default(DataPoint);
 185.195 +
 185.196 +            double minimumDistance = double.MaxValue;
 185.197 +            foreach (var p in points)
 185.198 +            {
 185.199 +                var sp = AxisBase.Transform(p, XAxis, YAxis);
 185.200 +                double dx = sp.x - point.x;
 185.201 +                double dy = sp.y - point.y;
 185.202 +                double d2 = dx * dx + dy * dy;
 185.203 +
 185.204 +                if (d2 < minimumDistance)
 185.205 +                {
 185.206 +                    dpn = p;
 185.207 +                    spn = sp;
 185.208 +                    minimumDistance = d2;
 185.209 +                }
 185.210 +            }
 185.211 +
 185.212 +            return minimumDistance < double.MaxValue;
 185.213 +        }
 185.214 +
 185.215 +        /// <summary>
 185.216 +        /// Gets the point on the curve that is nearest the specified point.
 185.217 +        /// </summary>
 185.218 +        /// <param name = "point">The point.</param>
 185.219 +        /// <param name = "dpn">The nearest point (data coordinates).</param>
 185.220 +        /// <param name = "spn">The nearest point (screen coordinates).</param>
 185.221 +        /// <returns></returns>
 185.222 +        public override bool GetNearestInterpolatedPoint(ScreenPoint point, out DataPoint dpn, out ScreenPoint spn)
 185.223 +        {
 185.224 +            spn = default(ScreenPoint);
 185.225 +            dpn = default(DataPoint);
 185.226 +
 185.227 +            // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
 185.228 +            double minimumDistance = double.MaxValue;
 185.229 +
 185.230 +            for (int i = 0; i + 1 < points.Count; i++)
 185.231 +            {
 185.232 +                var p1 = points[i];
 185.233 +                var p2 = points[i + 1];
 185.234 +                var sp1 = AxisBase.Transform(p1, XAxis, YAxis);
 185.235 +                var sp2 = AxisBase.Transform(p2, XAxis, YAxis);
 185.236 +
 185.237 +                double sp21X = sp2.x - sp1.x;
 185.238 +                double sp21Y = sp2.y - sp1.y;
 185.239 +                double u1 = (point.x - sp1.x) * sp21X + (point.y - sp1.y) * sp21Y;
 185.240 +                double u2 = sp21X * sp21X + sp21Y * sp21Y;
 185.241 +                double ds = sp21X * sp21X + sp21Y * sp21Y;
 185.242 +
 185.243 +                if (ds < 4)
 185.244 +                {
 185.245 +                    // if the points are very close, we can get numerical problems, just use the first point...
 185.246 +                    u1 = 0; u2 = 1;
 185.247 +                }
 185.248 +
 185.249 +                if (u2 == 0)
 185.250 +                {
 185.251 +                    continue; // P1 && P2 coincident
 185.252 +                }
 185.253 +
 185.254 +                double u = u1 / u2;
 185.255 +                if (u < 0 || u > 1)
 185.256 +                {
 185.257 +                    continue; // outside line
 185.258 +                }
 185.259 +
 185.260 +                double sx = sp1.x + u * sp21X;
 185.261 +                double sy = sp1.y + u * sp21Y;
 185.262 +
 185.263 +                double dx = point.x - sx;
 185.264 +                double dy = point.y - sy;
 185.265 +                double distance = dx * dx + dy * dy;
 185.266 +
 185.267 +                if (distance < minimumDistance)
 185.268 +                {
 185.269 +                    double px = p1.x + u * (p2.x - p1.x);
 185.270 +                    double py = p1.y + u * (p2.y - p1.y);
 185.271 +                    dpn = new DataPoint(px, py);
 185.272 +                    spn = new ScreenPoint(sx, sy);
 185.273 +                    minimumDistance = distance;
 185.274 +                }
 185.275 +            }
 185.276 +
 185.277 +            return minimumDistance < double.MaxValue;
 185.278 +        }
 185.279 +
 185.280 +        protected void AddDataPoints(ICollection<DataPoint> points, IEnumerable itemsSource, string dataFieldX, string dataFieldY)
 185.281 +        {
 185.282 +            PropertyInfo pix = null;
 185.283 +            PropertyInfo piy = null;
 185.284 +            Type t = null;
 185.285 +
 185.286 +            foreach (var o in itemsSource)
 185.287 +            {
 185.288 +                if (pix == null || o.GetType() != t)
 185.289 +                {
 185.290 +                    t = o.GetType();
 185.291 +                    pix = t.GetProperty(dataFieldX);
 185.292 +                    piy = t.GetProperty(dataFieldY);
 185.293 +                    if (pix == null)
 185.294 +                    {
 185.295 +                        throw new InvalidOperationException(string.Format("Could not find data field {0} on type {1}",
 185.296 +                                                                          DataFieldX, t));
 185.297 +                    }
 185.298 +
 185.299 +                    if (piy == null)
 185.300 +                    {
 185.301 +                        throw new InvalidOperationException(string.Format("Could not find data field {0} on type {1}",
 185.302 +                                                                          DataFieldY, t));
 185.303 +                    }
 185.304 +                }
 185.305 +
 185.306 +                var x = ToDouble(pix.GetValue(o, null));
 185.307 +                var y = ToDouble(piy.GetValue(o, null));
 185.308 +
 185.309 +                var pp = new DataPoint(x, y);
 185.310 +                points.Add(pp);
 185.311 +            }
 185.312 +        }
 185.313 +
 185.314 +        /// <summary>
 185.315 +        /// Updates the Max/Min limits from the specified point list.
 185.316 +        /// </summary>
 185.317 +        /// <param name="pts">The PTS.</param>
 185.318 +        protected void InternalUpdateMaxMin(IList<DataPoint> pts)
 185.319 +        {
 185.320 +            if (pts == null || pts.Count == 0)
 185.321 +            {
 185.322 +                return;
 185.323 +            }
 185.324 +
 185.325 +            double minx = MinX;
 185.326 +            double miny = MinY;
 185.327 +            double maxx = MaxX;
 185.328 +            double maxy = MaxY;
 185.329 +
 185.330 +            foreach (var pt in pts)
 185.331 +            {
 185.332 +                if (!IsValidPoint(pt,XAxis,YAxis))
 185.333 +                    continue;
 185.334 +                if (pt.x < minx || double.IsNaN(minx)) minx = pt.x;
 185.335 +                if (pt.x > maxx || double.IsNaN(maxx)) maxx = pt.x;
 185.336 +                if (pt.y < miny || double.IsNaN(miny)) miny = pt.y;
 185.337 +                if (pt.y > maxy || double.IsNaN(maxy)) maxy = pt.y;
 185.338 +            }
 185.339 +
 185.340 +            MinX = minx;
 185.341 +            MinY = miny;
 185.342 +            MaxX = maxx;
 185.343 +            MaxY = maxy;
 185.344 +
 185.345 +            XAxis.Include(MinX);
 185.346 +            XAxis.Include(MaxX);
 185.347 +            YAxis.Include(MinY);
 185.348 +            YAxis.Include(MaxY);
 185.349 +        }
 185.350 +
 185.351 +        /// <summary>
 185.352 +        /// Gets the value from the specified X.
 185.353 +        /// </summary>
 185.354 +        /// <param name = "x">The x.</param>
 185.355 +        /// <returns></returns>
 185.356 +        public double? GetValueFromX(double x)
 185.357 +        {
 185.358 +            for (int i = 0; i + 1 < points.Count; i++)
 185.359 +            {
 185.360 +                if (IsBetween(x, points[i].x, points[i + 1].x))
 185.361 +                {
 185.362 +                    return points[i].y +
 185.363 +                           (points[i + 1].y - points[i].y) /
 185.364 +                           (points[i + 1].x - points[i].x) * (x - points[i].x);
 185.365 +                }
 185.366 +            }
 185.367 +
 185.368 +            return null;
 185.369 +        }
 185.370 +
 185.371 +        private static bool IsBetween(double x, double x0, double x1)
 185.372 +        {
 185.373 +            if (x >= x0 && x <= x1)
 185.374 +            {
 185.375 +                return true;
 185.376 +            }
 185.377 +
 185.378 +            if (x >= x1 && x <= x0)
 185.379 +            {
 185.380 +                return true;
 185.381 +            }
 185.382 +
 185.383 +            return false;
 185.384 +        }
 185.385 +
 185.386 +        public virtual bool IsValidPoint(DataPoint pt, IAxis xAxis, IAxis yAxis)
 185.387 +        {
 185.388 +            return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X)
 185.389 +                   && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y)
 185.390 +                   && (xAxis!=null && xAxis.IsValidValue(pt.X))
 185.391 +                   && (yAxis!=null && yAxis.IsValidValue(pt.Y));
 185.392 +        }
 185.393 +    }
 185.394 +}
 185.395 \ No newline at end of file
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/External/OxyPlot/OxyPlot/Series/FunctionSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   186.3 @@ -0,0 +1,157 @@
   186.4 +// --------------------------------------------------------------------------------------------------------------------
   186.5 +// <copyright file="FunctionSeries.cs" company="OxyPlot">
   186.6 +//   The MIT License (MIT)
   186.7 +//
   186.8 +//   Copyright (c) 2012 Oystein Bjorke
   186.9 +//
  186.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  186.11 +//   copy of this software and associated documentation files (the
  186.12 +//   "Software"), to deal in the Software without restriction, including
  186.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  186.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  186.15 +//   permit persons to whom the Software is furnished to do so, subject to
  186.16 +//   the following conditions:
  186.17 +//
  186.18 +//   The above copyright notice and this permission notice shall be included
  186.19 +//   in all copies or substantial portions of the Software.
  186.20 +//
  186.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  186.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  186.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  186.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  186.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  186.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  186.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  186.28 +// </copyright>
  186.29 +// <summary>
  186.30 +//   Represents a line series that generates its dataset from a function.
  186.31 +// </summary>
  186.32 +// --------------------------------------------------------------------------------------------------------------------
  186.33 +namespace OxyPlot.Series
  186.34 +{
  186.35 +    using System;
  186.36 +
  186.37 +    /// <summary>
  186.38 +    /// Represents a line series that generates its dataset from a function.
  186.39 +    /// </summary>
  186.40 +    /// <remarks>
  186.41 +    /// Define f(x) and make a plot on the range [x0,x1] or define fx(t) and fy(t) and make a plot on the range [t0,t1].
  186.42 +    /// </remarks>
  186.43 +    public class FunctionSeries : LineSeries
  186.44 +    {
  186.45 +        /// <summary>
  186.46 +        /// Initializes a new instance of the <see cref = "FunctionSeries" /> class.
  186.47 +        /// </summary>
  186.48 +        public FunctionSeries()
  186.49 +        {
  186.50 +        }
  186.51 +
  186.52 +        /// <summary>
  186.53 +        /// Initializes a new instance of the <see cref="FunctionSeries"/> class.
  186.54 +        /// </summary>
  186.55 +        /// <param name="f">
  186.56 +        /// The function f(x).
  186.57 +        /// </param>
  186.58 +        /// <param name="x0">
  186.59 +        /// The start x value.
  186.60 +        /// </param>
  186.61 +        /// <param name="x1">
  186.62 +        /// The end x value.
  186.63 +        /// </param>
  186.64 +        /// <param name="dx">
  186.65 +        /// The increment in x.
  186.66 +        /// </param>
  186.67 +        /// <param name="title">
  186.68 +        /// The title (optional).
  186.69 +        /// </param>
  186.70 +        public FunctionSeries(Func<double, double> f, double x0, double x1, double dx, string title = null)
  186.71 +        {
  186.72 +            this.Title = title;
  186.73 +            for (double x = x0; x <= x1 + (dx * 0.5); x += dx)
  186.74 +            {
  186.75 +                this.Points.Add(new DataPoint(x, f(x)));
  186.76 +            }
  186.77 +        }
  186.78 +
  186.79 +        /// <summary>
  186.80 +        /// Initializes a new instance of the <see cref="FunctionSeries"/> class.
  186.81 +        /// </summary>
  186.82 +        /// <param name="f">
  186.83 +        /// The function f(x).
  186.84 +        /// </param>
  186.85 +        /// <param name="x0">
  186.86 +        /// The start x value.
  186.87 +        /// </param>
  186.88 +        /// <param name="x1">
  186.89 +        /// The end x value.
  186.90 +        /// </param>
  186.91 +        /// <param name="n">
  186.92 +        /// The number of points.
  186.93 +        /// </param>
  186.94 +        /// <param name="title">
  186.95 +        /// The title (optional).
  186.96 +        /// </param>
  186.97 +        public FunctionSeries(Func<double, double> f, double x0, double x1, int n, string title = null)
  186.98 +            : this(f, x0, x1, (x1 - x0) / (n - 1), title)
  186.99 +        {
 186.100 +        }
 186.101 +
 186.102 +        /// <summary>
 186.103 +        /// Initializes a new instance of the <see cref="FunctionSeries"/> class.
 186.104 +        /// </summary>
 186.105 +        /// <param name="fx">
 186.106 +        /// The function fx(t).
 186.107 +        /// </param>
 186.108 +        /// <param name="fy">
 186.109 +        /// The function fy(t).
 186.110 +        /// </param>
 186.111 +        /// <param name="t0">
 186.112 +        /// The t0.
 186.113 +        /// </param>
 186.114 +        /// <param name="t1">
 186.115 +        /// The t1.
 186.116 +        /// </param>
 186.117 +        /// <param name="dt">
 186.118 +        /// The increment dt.
 186.119 +        /// </param>
 186.120 +        /// <param name="title">
 186.121 +        /// The title.
 186.122 +        /// </param>
 186.123 +        public FunctionSeries(Func<double, double> fx, Func<double, double> fy, double t0, double t1, double dt, string title = null)
 186.124 +        {
 186.125 +            this.Title = title;
 186.126 +            for (double t = t0; t <= t1 + (dt * 0.5); t += dt)
 186.127 +            {
 186.128 +                this.Points.Add(new DataPoint(fx(t), fy(t)));
 186.129 +            }
 186.130 +        }
 186.131 +
 186.132 +        /// <summary>
 186.133 +        /// Initializes a new instance of the <see cref="FunctionSeries"/> class.
 186.134 +        /// </summary>
 186.135 +        /// <param name="fx">
 186.136 +        /// The function fx(t).
 186.137 +        /// </param>
 186.138 +        /// <param name="fy">
 186.139 +        /// The function fy(t).
 186.140 +        /// </param>
 186.141 +        /// <param name="t0">
 186.142 +        /// The t0.
 186.143 +        /// </param>
 186.144 +        /// <param name="t1">
 186.145 +        /// The t1.
 186.146 +        /// </param>
 186.147 +        /// <param name="n">
 186.148 +        /// The number of points.
 186.149 +        /// </param>
 186.150 +        /// <param name="title">
 186.151 +        /// The title.
 186.152 +        /// </param>
 186.153 +        public FunctionSeries(
 186.154 +            Func<double, double> fx, Func<double, double> fy, double t0, double t1, int n, string title = null)
 186.155 +            : this(fx, fy, t0, t1, (t1 - t0) / (n - 1), title)
 186.156 +        {
 186.157 +        }
 186.158 +
 186.159 +    }
 186.160 +}
 186.161 \ No newline at end of file
   187.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.2 +++ b/External/OxyPlot/OxyPlot/Series/HeatMapSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   187.3 @@ -0,0 +1,238 @@
   187.4 +// --------------------------------------------------------------------------------------------------------------------
   187.5 +// <copyright file="HeatMapSeries.cs" company="OxyPlot">
   187.6 +//   The MIT License (MIT)
   187.7 +//   
   187.8 +//   Copyright (c) 2012 Oystein Bjorke
   187.9 +//   
  187.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  187.11 +//   copy of this software and associated documentation files (the
  187.12 +//   "Software"), to deal in the Software without restriction, including
  187.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  187.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  187.15 +//   permit persons to whom the Software is furnished to do so, subject to
  187.16 +//   the following conditions:
  187.17 +//   
  187.18 +//   The above copyright notice and this permission notice shall be included
  187.19 +//   in all copies or substantial portions of the Software.
  187.20 +//   
  187.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  187.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  187.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  187.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  187.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  187.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  187.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  187.28 +// </copyright>
  187.29 +// <summary>
  187.30 +//   The heat map series.
  187.31 +// </summary>
  187.32 +// --------------------------------------------------------------------------------------------------------------------
  187.33 +
  187.34 +namespace OxyPlot.Series
  187.35 +{
  187.36 +    using System;
  187.37 +    using System.Collections.Generic;
  187.38 +    using System.Linq;
  187.39 +
  187.40 +    using OxyPlot.Axes;
  187.41 +
  187.42 +    /// <summary>
  187.43 +    /// The heat map series.
  187.44 +    /// </summary>
  187.45 +    /// <remarks>
  187.46 +    /// Does not work with Silverlight. Silverlight does not support bitmaps, only PNG and JPG.
  187.47 +    /// </remarks>
  187.48 +    public class HeatMapSeries : XYAxisSeries
  187.49 +    {
  187.50 +        /// <summary>
  187.51 +        /// The hash code of the current data.
  187.52 +        /// </summary>
  187.53 +        private int dataHash;
  187.54 +
  187.55 +        /// <summary>
  187.56 +        /// The image
  187.57 +        /// </summary>
  187.58 +        private OxyImage image;
  187.59 +
  187.60 +        /// <summary>
  187.61 +        /// Gets or sets the x 0.
  187.62 +        /// </summary>
  187.63 +        public double X0 { get; set; }
  187.64 +
  187.65 +        /// <summary>
  187.66 +        /// Gets or sets the x 1.
  187.67 +        /// </summary>
  187.68 +        public double X1 { get; set; }
  187.69 +
  187.70 +        /// <summary>
  187.71 +        /// Gets or sets the y 0.
  187.72 +        /// </summary>
  187.73 +        public double Y0 { get; set; }
  187.74 +
  187.75 +        /// <summary>
  187.76 +        /// Gets or sets the y 1.
  187.77 +        /// </summary>
  187.78 +        public double Y1 { get; set; }
  187.79 +
  187.80 +        /// <summary>
  187.81 +        /// Gets or sets the data.
  187.82 +        /// </summary>
  187.83 +        public double[,] Data { get; set; }
  187.84 +
  187.85 +        /// <summary>
  187.86 +        /// Gets or sets the minimum value of the dataset.
  187.87 +        /// </summary>
  187.88 +        public double MinValue { get; protected set; }
  187.89 +
  187.90 +        /// <summary>
  187.91 +        /// Gets or sets the maximum value of the dataset.
  187.92 +        /// </summary>
  187.93 +        public double MaxValue { get; protected set; }
  187.94 +
  187.95 +        /// <summary>
  187.96 +        /// Gets or sets the color axis.
  187.97 +        /// </summary>
  187.98 +        /// <value>
  187.99 +        /// The color axis.
 187.100 +        /// </value>
 187.101 +        public ColorAxis ColorAxis { get; protected set; }
 187.102 +
 187.103 +        /// <summary>
 187.104 +        /// Gets or sets the color axis key.
 187.105 +        /// </summary>
 187.106 +        /// <value> The color axis key. </value>
 187.107 +        public string ColorAxisKey { get; set; }
 187.108 +
 187.109 +        /// <summary>
 187.110 +        /// Renders the series on the specified render context.
 187.111 +        /// </summary>
 187.112 +        /// <param name="rc">
 187.113 +        /// The rendering context.
 187.114 +        /// </param>
 187.115 +        /// <param name="model">
 187.116 +        /// The model.
 187.117 +        /// </param>
 187.118 +        public override void Render(IRenderContext rc, PlotModel model)
 187.119 +        {
 187.120 +            if (this.Data == null)
 187.121 +            {
 187.122 +                this.image = null;
 187.123 +                return;
 187.124 +            }
 187.125 +
 187.126 +            int m = this.Data.GetLength(0);
 187.127 +            int n = this.Data.GetLength(1);
 187.128 +            double dx = (this.X1 - this.X0) / m;
 187.129 +            double left = this.X0 - (dx * 0.5);
 187.130 +            double right = this.X1 + (dx * 0.5);
 187.131 +            double dy = (this.Y1 - this.Y0) / n;
 187.132 +            double bottom = this.Y0 - (dy * 0.5);
 187.133 +            double top = this.Y1 + (dy * 0.5);
 187.134 +            var s00 = this.Transform(left, bottom);
 187.135 +            var s11 = this.Transform(right, top);
 187.136 +            var rect = OxyRect.Create(s00, s11);
 187.137 +
 187.138 +            if (this.image == null || this.Data.GetHashCode() != this.dataHash)
 187.139 +            {
 187.140 +                this.UpdateImage();
 187.141 +                this.dataHash = this.Data.GetHashCode();
 187.142 +            }
 187.143 +
 187.144 +            if (this.image != null)
 187.145 +            {
 187.146 +                var clip = this.GetClippingRect();
 187.147 +                rc.DrawClippedImage(clip, this.image, rect.Left, rect.Top, rect.Width, rect.Height, 1, true);
 187.148 +            }
 187.149 +        }
 187.150 +
 187.151 +        /// <summary>
 187.152 +        /// Gets the point on the series that is nearest the specified point.
 187.153 +        /// </summary>
 187.154 +        /// <param name="point">
 187.155 +        /// The point.
 187.156 +        /// </param>
 187.157 +        /// <param name="interpolate">
 187.158 +        /// Interpolate the series if this flag is set to <c>true</c>.
 187.159 +        /// </param>
 187.160 +        /// <returns>
 187.161 +        /// A TrackerHitResult for the current hit.
 187.162 +        /// </returns>
 187.163 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 187.164 +        {
 187.165 +            return null;
 187.166 +        }
 187.167 +
 187.168 +        /// <summary>
 187.169 +        /// Ensures that the axes of the series is defined.
 187.170 +        /// </summary>
 187.171 +        protected internal override void EnsureAxes()
 187.172 +        {
 187.173 +            base.EnsureAxes();
 187.174 +
 187.175 +            this.ColorAxis =
 187.176 +                this.PlotModel.GetAxisOrDefault(this.ColorAxisKey, this.PlotModel.DefaultColorAxis) as ColorAxis;
 187.177 +        }
 187.178 +
 187.179 +        /// <summary>
 187.180 +        /// Updates the max/minimum values.
 187.181 +        /// </summary>
 187.182 +        protected internal override void UpdateMaxMin()
 187.183 +        {
 187.184 +            base.UpdateMaxMin();
 187.185 +            
 187.186 +            this.MinX = Math.Min(this.X0, this.X1);
 187.187 +            this.MaxX = Math.Max(this.X0, this.X1);
 187.188 +
 187.189 +            this.MinY = Math.Min(this.Y0, this.Y1);
 187.190 +            this.MaxY = Math.Max(this.Y0, this.Y1);
 187.191 +
 187.192 +            this.MinValue = this.GetData().Min();
 187.193 +            this.MaxValue = this.GetData().Max();
 187.194 +
 187.195 +            this.XAxis.Include(this.MinX);
 187.196 +            this.XAxis.Include(this.MaxX);
 187.197 +
 187.198 +            this.YAxis.Include(this.MinY);
 187.199 +            this.YAxis.Include(this.MaxY);
 187.200 +            
 187.201 +            this.ColorAxis.Include(this.MinValue);
 187.202 +            this.ColorAxis.Include(this.MaxValue);
 187.203 +        }
 187.204 +
 187.205 +        /// <summary>
 187.206 +        /// Gets the data as a sequence (LINQ-friendly).
 187.207 +        /// </summary>
 187.208 +        /// <returns>The sequence of data.</returns>
 187.209 +        protected IEnumerable<double> GetData()
 187.210 +        {
 187.211 +            int m = this.Data.GetLength(0);
 187.212 +            int n = this.Data.GetLength(1);
 187.213 +            for (int i = 0; i < m; i++)
 187.214 +            {
 187.215 +                for (int j = 0; j < n; j++)
 187.216 +                {
 187.217 +                    yield return this.Data[i, j];
 187.218 +                }
 187.219 +            }
 187.220 +        }
 187.221 +
 187.222 +        /// <summary>
 187.223 +        /// Updates the image.
 187.224 +        /// </summary>
 187.225 +        private void UpdateImage()
 187.226 +        {
 187.227 +            int m = this.Data.GetLength(0);
 187.228 +            int n = this.Data.GetLength(1);
 187.229 +            var buffer = new OxyColor[n, m];
 187.230 +            for (int i = 0; i < m; i++)
 187.231 +            {
 187.232 +                for (int j = 0; j < n; j++)
 187.233 +                {
 187.234 +                    buffer[j, i] = this.ColorAxis.GetColor(this.Data[i, j]);
 187.235 +                }
 187.236 +            }
 187.237 +            
 187.238 +            this.image = OxyImage.PngFromArgb(buffer);
 187.239 +        }
 187.240 +    }
 187.241 +}
 187.242 \ No newline at end of file
   188.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   188.2 +++ b/External/OxyPlot/OxyPlot/Series/HighLowItem.cs	Sat Jun 08 16:53:22 2013 +0000
   188.3 @@ -0,0 +1,187 @@
   188.4 +// --------------------------------------------------------------------------------------------------------------------
   188.5 +// <copyright file="HighLowItem.cs" company="OxyPlot">
   188.6 +//   The MIT License (MIT)
   188.7 +//
   188.8 +//   Copyright (c) 2012 Oystein Bjorke
   188.9 +//
  188.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  188.11 +//   copy of this software and associated documentation files (the
  188.12 +//   "Software"), to deal in the Software without restriction, including
  188.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  188.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  188.15 +//   permit persons to whom the Software is furnished to do so, subject to
  188.16 +//   the following conditions:
  188.17 +//
  188.18 +//   The above copyright notice and this permission notice shall be included
  188.19 +//   in all copies or substantial portions of the Software.
  188.20 +//
  188.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  188.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  188.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  188.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  188.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  188.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  188.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  188.28 +// </copyright>
  188.29 +// <summary>
  188.30 +//   Represents an item in a HighLowSeries.
  188.31 +// </summary>
  188.32 +// --------------------------------------------------------------------------------------------------------------------
  188.33 +namespace OxyPlot.Series
  188.34 +{
  188.35 +    /// <summary>
  188.36 +    /// Represents an item in a <see cref="HighLowSeries"/>.
  188.37 +    /// </summary>
  188.38 +    public class HighLowItem
  188.39 +    {
  188.40 +        /// <summary>
  188.41 +        /// The undefined.
  188.42 +        /// </summary>
  188.43 +        public static readonly HighLowItem Undefined = new HighLowItem(double.NaN, double.NaN, double.NaN);
  188.44 +
  188.45 +        /// <summary>
  188.46 +        /// The close.
  188.47 +        /// </summary>
  188.48 +        private double close;
  188.49 +
  188.50 +        /// <summary>
  188.51 +        /// The high.
  188.52 +        /// </summary>
  188.53 +        private double high;
  188.54 +
  188.55 +        /// <summary>
  188.56 +        /// The low.
  188.57 +        /// </summary>
  188.58 +        private double low;
  188.59 +
  188.60 +        /// <summary>
  188.61 +        /// The open.
  188.62 +        /// </summary>
  188.63 +        private double open;
  188.64 +
  188.65 +        /// <summary>
  188.66 +        /// The x.
  188.67 +        /// </summary>
  188.68 +        private double x;
  188.69 +
  188.70 +        /// <summary>
  188.71 +        /// Initializes a new instance of the <see cref="HighLowItem"/> class.
  188.72 +        /// </summary>
  188.73 +        public HighLowItem()
  188.74 +        {
  188.75 +        }
  188.76 +
  188.77 +        /// <summary>
  188.78 +        /// Initializes a new instance of the <see cref="HighLowItem"/> struct.
  188.79 +        /// </summary>
  188.80 +        /// <param name="x">
  188.81 +        /// The x value.
  188.82 +        /// </param>
  188.83 +        /// <param name="high">
  188.84 +        /// The high value.
  188.85 +        /// </param>
  188.86 +        /// <param name="low">
  188.87 +        /// The low value.
  188.88 +        /// </param>
  188.89 +        /// <param name="open">
  188.90 +        /// The open value.
  188.91 +        /// </param>
  188.92 +        /// <param name="close">
  188.93 +        /// The close value.
  188.94 +        /// </param>
  188.95 +        public HighLowItem(double x, double high, double low, double open = double.NaN, double close = double.NaN)
  188.96 +        {
  188.97 +            this.x = x;
  188.98 +            this.high = high;
  188.99 +            this.low = low;
 188.100 +            this.open = open;
 188.101 +            this.close = close;
 188.102 +        }
 188.103 +
 188.104 +        /// <summary>
 188.105 +        /// Gets or sets the close value.
 188.106 +        /// </summary>
 188.107 +        /// <value>The close value.</value>
 188.108 +        public double Close
 188.109 +        {
 188.110 +            get
 188.111 +            {
 188.112 +                return this.close;
 188.113 +            }
 188.114 +
 188.115 +            set
 188.116 +            {
 188.117 +                this.close = value;
 188.118 +            }
 188.119 +        }
 188.120 +
 188.121 +        /// <summary>
 188.122 +        /// Gets or sets the high value.
 188.123 +        /// </summary>
 188.124 +        /// <value>The high value.</value>
 188.125 +        public double High
 188.126 +        {
 188.127 +            get
 188.128 +            {
 188.129 +                return this.high;
 188.130 +            }
 188.131 +
 188.132 +            set
 188.133 +            {
 188.134 +                this.high = value;
 188.135 +            }
 188.136 +        }
 188.137 +
 188.138 +        /// <summary>
 188.139 +        /// Gets or sets the low value.
 188.140 +        /// </summary>
 188.141 +        /// <value>The low value.</value>
 188.142 +        public double Low
 188.143 +        {
 188.144 +            get
 188.145 +            {
 188.146 +                return this.low;
 188.147 +            }
 188.148 +
 188.149 +            set
 188.150 +            {
 188.151 +                this.low = value;
 188.152 +            }
 188.153 +        }
 188.154 +
 188.155 +        /// <summary>
 188.156 +        /// Gets or sets the open value.
 188.157 +        /// </summary>
 188.158 +        /// <value>The open value.</value>
 188.159 +        public double Open
 188.160 +        {
 188.161 +            get
 188.162 +            {
 188.163 +                return this.open;
 188.164 +            }
 188.165 +
 188.166 +            set
 188.167 +            {
 188.168 +                this.open = value;
 188.169 +            }
 188.170 +        }
 188.171 +
 188.172 +        /// <summary>
 188.173 +        /// Gets or sets the X value (time).
 188.174 +        /// </summary>
 188.175 +        /// <value>The X value.</value>
 188.176 +        public double X
 188.177 +        {
 188.178 +            get
 188.179 +            {
 188.180 +                return this.x;
 188.181 +            }
 188.182 +
 188.183 +            set
 188.184 +            {
 188.185 +                this.x = value;
 188.186 +            }
 188.187 +        }
 188.188 +
 188.189 +    }
 188.190 +}
 188.191 \ No newline at end of file
   189.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   189.2 +++ b/External/OxyPlot/OxyPlot/Series/HighLowSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   189.3 @@ -0,0 +1,502 @@
   189.4 +// --------------------------------------------------------------------------------------------------------------------
   189.5 +// <copyright file="HighLowSeries.cs" company="OxyPlot">
   189.6 +//   The MIT License (MIT)
   189.7 +//
   189.8 +//   Copyright (c) 2012 Oystein Bjorke
   189.9 +//
  189.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  189.11 +//   copy of this software and associated documentation files (the
  189.12 +//   "Software"), to deal in the Software without restriction, including
  189.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  189.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  189.15 +//   permit persons to whom the Software is furnished to do so, subject to
  189.16 +//   the following conditions:
  189.17 +//
  189.18 +//   The above copyright notice and this permission notice shall be included
  189.19 +//   in all copies or substantial portions of the Software.
  189.20 +//
  189.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  189.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  189.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  189.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  189.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  189.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  189.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  189.28 +// </copyright>
  189.29 +// <summary>
  189.30 +//   Represents a series for high-low plots.
  189.31 +// </summary>
  189.32 +// --------------------------------------------------------------------------------------------------------------------
  189.33 +namespace OxyPlot.Series
  189.34 +{
  189.35 +    using System;
  189.36 +    using System.Collections.Generic;
  189.37 +
  189.38 +    using OxyPlot.Axes;
  189.39 +
  189.40 +    /// <summary>
  189.41 +    /// Represents a series for high-low plots.
  189.42 +    /// </summary>
  189.43 +    /// <remarks>
  189.44 +    /// See http://www.mathworks.com/help/toolbox/finance/highlowfts.html
  189.45 +    /// </remarks>
  189.46 +    public class HighLowSeries : XYAxisSeries
  189.47 +    {
  189.48 +        /// <summary>
  189.49 +        /// High/low items
  189.50 +        /// </summary>
  189.51 +        private IList<HighLowItem> items;
  189.52 +
  189.53 +        /// <summary>
  189.54 +        /// The default color.
  189.55 +        /// </summary>
  189.56 +        private OxyColor defaultColor;
  189.57 +
  189.58 +        /// <summary>
  189.59 +        /// Initializes a new instance of the <see cref = "HighLowSeries" /> class.
  189.60 +        /// </summary>
  189.61 +        public HighLowSeries()
  189.62 +        {
  189.63 +            this.items = new List<HighLowItem>();
  189.64 +            this.TickLength = 4;
  189.65 +            this.StrokeThickness = 1;
  189.66 +            this.TrackerFormatString = "X: {1:0.00}\nHigh: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}";
  189.67 +        }
  189.68 +
  189.69 +        /// <summary>
  189.70 +        /// Initializes a new instance of the <see cref="HighLowSeries"/> class.
  189.71 +        /// </summary>
  189.72 +        /// <param name="title">
  189.73 +        /// The title.
  189.74 +        /// </param>
  189.75 +        public HighLowSeries(string title)
  189.76 +            : this()
  189.77 +        {
  189.78 +            this.Title = title;
  189.79 +        }
  189.80 +
  189.81 +        /// <summary>
  189.82 +        /// Initializes a new instance of the <see cref="HighLowSeries"/> class.
  189.83 +        /// </summary>
  189.84 +        /// <param name="color">
  189.85 +        /// The color.
  189.86 +        /// </param>
  189.87 +        /// <param name="strokeThickness">
  189.88 +        /// The stroke thickness.
  189.89 +        /// </param>
  189.90 +        /// <param name="title">
  189.91 +        /// The title.
  189.92 +        /// </param>
  189.93 +        public HighLowSeries(OxyColor color, double strokeThickness = 1, string title = null)
  189.94 +            : this()
  189.95 +        {
  189.96 +            this.Color = color;
  189.97 +            this.StrokeThickness = strokeThickness;
  189.98 +            this.Title = title;
  189.99 +        }
 189.100 +
 189.101 +        /// <summary>
 189.102 +        /// Gets or sets the color of the curve.
 189.103 +        /// </summary>
 189.104 +        /// <value>The color.</value>
 189.105 +        public OxyColor Color { get; set; }
 189.106 +
 189.107 +        /// <summary>
 189.108 +        /// Gets the actual color.
 189.109 +        /// </summary>
 189.110 +        /// <value>The actual color.</value>
 189.111 +        public OxyColor ActualColor
 189.112 +        {
 189.113 +            get { return this.Color ?? this.defaultColor; }
 189.114 +        }
 189.115 +
 189.116 +        /// <summary>
 189.117 +        /// Gets or sets the dashes array.
 189.118 +        /// If this is not null it overrides the LineStyle property.
 189.119 +        /// </summary>
 189.120 +        /// <value>The dashes.</value>
 189.121 +        public double[] Dashes { get; set; }
 189.122 +
 189.123 +        /// <summary>
 189.124 +        /// Gets or sets the data field for the Close value.
 189.125 +        /// </summary>
 189.126 +        public string DataFieldClose { get; set; }
 189.127 +
 189.128 +        /// <summary>
 189.129 +        /// Gets or sets the data field for the High value.
 189.130 +        /// </summary>
 189.131 +        public string DataFieldHigh { get; set; }
 189.132 +
 189.133 +        /// <summary>
 189.134 +        /// Gets or sets the data field for the Low value.
 189.135 +        /// </summary>
 189.136 +        public string DataFieldLow { get; set; }
 189.137 +
 189.138 +        /// <summary>
 189.139 +        /// Gets or sets the data field for the Open value.
 189.140 +        /// </summary>
 189.141 +        public string DataFieldOpen { get; set; }
 189.142 +
 189.143 +        /// <summary>
 189.144 +        /// Gets or sets the x data field (time).
 189.145 +        /// </summary>
 189.146 +        public string DataFieldX { get; set; }
 189.147 +
 189.148 +        /// <summary>
 189.149 +        /// Gets or sets the points.
 189.150 +        /// </summary>
 189.151 +        /// <value>The points.</value>
 189.152 +        public IList<HighLowItem> Items
 189.153 +        {
 189.154 +            get
 189.155 +            {
 189.156 +                return this.items;
 189.157 +            }
 189.158 +
 189.159 +            set
 189.160 +            {
 189.161 +                this.items = value;
 189.162 +            }
 189.163 +        }
 189.164 +
 189.165 +        /// <summary>
 189.166 +        /// Gets or sets the line join.
 189.167 +        /// </summary>
 189.168 +        /// <value>The line join.</value>
 189.169 +        public OxyPenLineJoin LineJoin { get; set; }
 189.170 +
 189.171 +        /// <summary>
 189.172 +        /// Gets or sets the line style.
 189.173 +        /// </summary>
 189.174 +        /// <value>The line style.</value>
 189.175 +        public LineStyle LineStyle { get; set; }
 189.176 +
 189.177 +        /// <summary>
 189.178 +        /// Gets or sets the mapping deleagte.
 189.179 +        /// Example: series1.Mapping = item => new HighLowItem(((MyType)item).Time,((MyType)item).Value);
 189.180 +        /// </summary>
 189.181 +        /// <value>The mapping.</value>
 189.182 +        public Func<object, HighLowItem> Mapping { get; set; }
 189.183 +
 189.184 +        /// <summary>
 189.185 +        /// Gets or sets the thickness of the curve.
 189.186 +        /// </summary>
 189.187 +        /// <value>The stroke thickness.</value>
 189.188 +        public double StrokeThickness { get; set; }
 189.189 +
 189.190 +        /// <summary>
 189.191 +        /// Gets or sets the length of the open/close ticks (screen coordinates).
 189.192 +        /// </summary>
 189.193 +        /// <value>The length of the open/close ticks.</value>
 189.194 +        public double TickLength { get; set; }
 189.195 +
 189.196 +        /// <summary>
 189.197 +        /// Gets the point on the series that is nearest the specified point.
 189.198 +        /// </summary>
 189.199 +        /// <param name="point">The point.</param>
 189.200 +        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
 189.201 +        /// <returns>
 189.202 +        /// A TrackerHitResult for the current hit.
 189.203 +        /// </returns>
 189.204 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 189.205 +        {
 189.206 +            if (this.XAxis == null || this.YAxis == null)
 189.207 +            {
 189.208 +                return null;
 189.209 +            }
 189.210 +
 189.211 +            if (interpolate)
 189.212 +            {
 189.213 +                return null;
 189.214 +            }
 189.215 +
 189.216 +            double minimumDistance = double.MaxValue;
 189.217 +            var result = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);
 189.218 +
 189.219 +            Action<DataPoint, HighLowItem, int> check = (p, item, index) =>
 189.220 +                {
 189.221 +                    var sp = this.Transform(p);
 189.222 +                    double dx = sp.x - point.x;
 189.223 +                    double dy = sp.y - point.y;
 189.224 +                    double d2 = (dx * dx) + (dy * dy);
 189.225 +
 189.226 +                    if (d2 < minimumDistance)
 189.227 +                    {
 189.228 +                        result.DataPoint = p;
 189.229 +                        result.Position = sp;
 189.230 +                        result.Item = item;
 189.231 +                        result.Index = index;
 189.232 +                        if (this.TrackerFormatString != null)
 189.233 +                        {
 189.234 +                            result.Text = StringHelper.Format(
 189.235 +                                this.ActualCulture,
 189.236 +                                this.TrackerFormatString,
 189.237 +                                item,
 189.238 +                                this.Title,
 189.239 +                                this.XAxis.GetValue(p.X),
 189.240 +                                item.High,
 189.241 +                                item.Low,
 189.242 +                                item.Open,
 189.243 +                                item.Close);
 189.244 +                        }
 189.245 +
 189.246 +                        minimumDistance = d2;
 189.247 +                    }
 189.248 +                };
 189.249 +            int i = 0;
 189.250 +            foreach (var item in this.items)
 189.251 +            {
 189.252 +                check(new DataPoint(item.X, item.High), item, i);
 189.253 +                check(new DataPoint(item.X, item.Low), item, i);
 189.254 +                check(new DataPoint(item.X, item.Open), item, i);
 189.255 +                check(new DataPoint(item.X, item.Close), item, i++);
 189.256 +            }
 189.257 +
 189.258 +            if (minimumDistance < double.MaxValue)
 189.259 +            {
 189.260 +                return result;
 189.261 +            }
 189.262 +
 189.263 +            return null;
 189.264 +        }
 189.265 +
 189.266 +        /// <summary>
 189.267 +        /// Determines whether the point is valid.
 189.268 +        /// </summary>
 189.269 +        /// <param name="pt">The point.</param>
 189.270 +        /// <param name="xaxis">The x axis.</param>
 189.271 +        /// <param name="yaxis">The y axis.</param>
 189.272 +        /// <returns>
 189.273 +        ///  <c>true</c> if [is valid point] [the specified pt]; otherwise, <c>false</c>.
 189.274 +        /// </returns>
 189.275 +        public virtual bool IsValidItem(HighLowItem pt, Axis xaxis, Axis yaxis)
 189.276 +        {
 189.277 +            return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.High)
 189.278 +                   && !double.IsInfinity(pt.High) && !double.IsNaN(pt.Low) && !double.IsInfinity(pt.Low);
 189.279 +        }
 189.280 +
 189.281 +        /// <summary>
 189.282 +        /// Renders the series on the specified rendering context.
 189.283 +        /// </summary>
 189.284 +        /// <param name="rc">
 189.285 +        /// The rendering context.
 189.286 +        /// </param>
 189.287 +        /// <param name="model">
 189.288 +        /// The owner plot model.
 189.289 +        /// </param>
 189.290 +        public override void Render(IRenderContext rc, PlotModel model)
 189.291 +        {
 189.292 +            if (this.items.Count == 0)
 189.293 +            {
 189.294 +                return;
 189.295 +            }
 189.296 +
 189.297 +            this.VerifyAxes();
 189.298 +
 189.299 +            var clippingRect = this.GetClippingRect();
 189.300 +
 189.301 +            foreach (var v in this.items)
 189.302 +            {
 189.303 +                if (!this.IsValidItem(v, this.XAxis, this.YAxis))
 189.304 +                {
 189.305 +                    continue;
 189.306 +                }
 189.307 +
 189.308 +                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
 189.309 +                {
 189.310 +                    ScreenPoint high = this.Transform(v.X, v.High);
 189.311 +                    ScreenPoint low = this.Transform(v.X, v.Low);
 189.312 +
 189.313 +                    rc.DrawClippedLine(
 189.314 +                        new[] { low, high },
 189.315 +                        clippingRect,
 189.316 +                        0,
 189.317 +                        this.GetSelectableColor(this.ActualColor),
 189.318 +                        this.StrokeThickness,
 189.319 +                        this.LineStyle,
 189.320 +                        this.LineJoin,
 189.321 +                        true);
 189.322 +                    if (!double.IsNaN(v.Open))
 189.323 +                    {
 189.324 +                        ScreenPoint open = this.Transform(v.X, v.Open);
 189.325 +                        ScreenPoint openTick = open;
 189.326 +                        openTick.X -= this.TickLength;
 189.327 +                        rc.DrawClippedLine(
 189.328 +                            new[] { open, openTick },
 189.329 +                            clippingRect,
 189.330 +                            0,
 189.331 +                            this.GetSelectableColor(this.ActualColor),
 189.332 +                            this.StrokeThickness,
 189.333 +                            this.LineStyle,
 189.334 +                            this.LineJoin,
 189.335 +                            true);
 189.336 +                    }
 189.337 +
 189.338 +                    if (!double.IsNaN(v.Close))
 189.339 +                    {
 189.340 +                        ScreenPoint close = this.Transform(v.X, v.Close);
 189.341 +                        ScreenPoint closeTick = close;
 189.342 +                        closeTick.X += this.TickLength;
 189.343 +                        rc.DrawClippedLine(
 189.344 +                            new[] { close, closeTick },
 189.345 +                            clippingRect,
 189.346 +                            0,
 189.347 +                            this.GetSelectableColor(this.ActualColor),
 189.348 +                            this.StrokeThickness,
 189.349 +                            this.LineStyle,
 189.350 +                            this.LineJoin,
 189.351 +                            true);
 189.352 +                    }
 189.353 +                }
 189.354 +            }
 189.355 +        }
 189.356 +
 189.357 +        /// <summary>
 189.358 +        /// Renders the legend symbol for the series on the specified rendering context.
 189.359 +        /// </summary>
 189.360 +        /// <param name="rc">
 189.361 +        /// The rendering context.
 189.362 +        /// </param>
 189.363 +        /// <param name="legendBox">
 189.364 +        /// The bounding rectangle of the legend box.
 189.365 +        /// </param>
 189.366 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 189.367 +        {
 189.368 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 189.369 +            double yopen = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.7);
 189.370 +            double yclose = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.3);
 189.371 +            double[] dashArray = LineStyleHelper.GetDashArray(this.LineStyle);
 189.372 +            var color = this.GetSelectableColor(this.ActualColor);
 189.373 +            rc.DrawLine(
 189.374 +                new[] { new ScreenPoint(xmid, legendBox.Top), new ScreenPoint(xmid, legendBox.Bottom) },
 189.375 +                color,
 189.376 +                this.StrokeThickness,
 189.377 +                dashArray,
 189.378 +                OxyPenLineJoin.Miter,
 189.379 +                true);
 189.380 +            rc.DrawLine(
 189.381 +                new[] { new ScreenPoint(xmid - this.TickLength, yopen), new ScreenPoint(xmid, yopen) },
 189.382 +                color,
 189.383 +                this.StrokeThickness,
 189.384 +                dashArray,
 189.385 +                OxyPenLineJoin.Miter,
 189.386 +                true);
 189.387 +            rc.DrawLine(
 189.388 +                new[] { new ScreenPoint(xmid + this.TickLength, yclose), new ScreenPoint(xmid, yclose) },
 189.389 +                color,
 189.390 +                this.StrokeThickness,
 189.391 +                dashArray,
 189.392 +                OxyPenLineJoin.Miter,
 189.393 +                true);
 189.394 +        }
 189.395 +
 189.396 +        /// <summary>
 189.397 +        /// Sets the default values.
 189.398 +        /// </summary>
 189.399 +        /// <param name="model">
 189.400 +        /// The model.
 189.401 +        /// </param>
 189.402 +        protected internal override void SetDefaultValues(PlotModel model)
 189.403 +        {
 189.404 +            if (this.Color == null)
 189.405 +            {
 189.406 +                this.LineStyle = model.GetDefaultLineStyle();
 189.407 +                this.defaultColor = model.GetDefaultColor();
 189.408 +            }
 189.409 +        }
 189.410 +
 189.411 +        /// <summary>
 189.412 +        /// Updates the data.
 189.413 +        /// </summary>
 189.414 +        protected internal override void UpdateData()
 189.415 +        {
 189.416 +            if (this.ItemsSource == null)
 189.417 +            {
 189.418 +                return;
 189.419 +            }
 189.420 +
 189.421 +            this.items.Clear();
 189.422 +
 189.423 +            // Use the mapping to generate the points
 189.424 +            if (this.Mapping != null)
 189.425 +            {
 189.426 +                foreach (var item in this.ItemsSource)
 189.427 +                {
 189.428 +                    this.items.Add(this.Mapping(item));
 189.429 +                }
 189.430 +
 189.431 +                return;
 189.432 +            }
 189.433 +
 189.434 +            var filler = new ListFiller<HighLowItem>();
 189.435 +            filler.Add(this.DataFieldX, (p, v) => p.X = this.ToDouble(v));
 189.436 +            filler.Add(this.DataFieldHigh, (p, v) => p.High = this.ToDouble(v));
 189.437 +            filler.Add(this.DataFieldLow, (p, v) => p.Low = this.ToDouble(v));
 189.438 +            filler.Add(this.DataFieldOpen, (p, v) => p.Open = this.ToDouble(v));
 189.439 +            filler.Add(this.DataFieldClose, (p, v) => p.Close = this.ToDouble(v));
 189.440 +            filler.FillT(this.items, this.ItemsSource);
 189.441 +        }
 189.442 +
 189.443 +        /// <summary>
 189.444 +        /// Updates the max/min values.
 189.445 +        /// </summary>
 189.446 +        protected internal override void UpdateMaxMin()
 189.447 +        {
 189.448 +            base.UpdateMaxMin();
 189.449 +            this.InternalUpdateMaxMin(this.items);
 189.450 +        }
 189.451 +
 189.452 +        /// <summary>
 189.453 +        /// Updates the Max/Min limits from the specified point list.
 189.454 +        /// </summary>
 189.455 +        /// <param name="pts">
 189.456 +        /// The PTS.
 189.457 +        /// </param>
 189.458 +        protected void InternalUpdateMaxMin(IList<HighLowItem> pts)
 189.459 +        {
 189.460 +            if (pts == null || pts.Count == 0)
 189.461 +            {
 189.462 +                return;
 189.463 +            }
 189.464 +
 189.465 +            double minx = this.MinX;
 189.466 +            double miny = this.MinY;
 189.467 +            double maxx = this.MaxX;
 189.468 +            double maxy = this.MaxY;
 189.469 +
 189.470 +            foreach (var pt in pts)
 189.471 +            {
 189.472 +                if (!this.IsValidItem(pt, this.XAxis, this.YAxis))
 189.473 +                {
 189.474 +                    continue;
 189.475 +                }
 189.476 +
 189.477 +                if (pt.X < minx || double.IsNaN(minx))
 189.478 +                {
 189.479 +                    minx = pt.X;
 189.480 +                }
 189.481 +
 189.482 +                if (pt.X > maxx || double.IsNaN(maxx))
 189.483 +                {
 189.484 +                    maxx = pt.X;
 189.485 +                }
 189.486 +
 189.487 +                if (pt.Low < miny || double.IsNaN(miny))
 189.488 +                {
 189.489 +                    miny = pt.Low;
 189.490 +                }
 189.491 +
 189.492 +                if (pt.High > maxy || double.IsNaN(maxy))
 189.493 +                {
 189.494 +                    maxy = pt.High;
 189.495 +                }
 189.496 +            }
 189.497 +
 189.498 +            this.MinX = minx;
 189.499 +            this.MinY = miny;
 189.500 +            this.MaxX = maxx;
 189.501 +            this.MaxY = maxy;
 189.502 +        }
 189.503 +
 189.504 +    }
 189.505 +}
 189.506 \ No newline at end of file
   190.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   190.2 +++ b/External/OxyPlot/OxyPlot/Series/ITrackableSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   190.3 @@ -0,0 +1,67 @@
   190.4 +// --------------------------------------------------------------------------------------------------------------------
   190.5 +// <copyright file="ITrackableSeries.cs" company="OxyPlot">
   190.6 +//   The MIT License (MIT)
   190.7 +//
   190.8 +//   Copyright (c) 2012 Oystein Bjorke
   190.9 +//
  190.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  190.11 +//   copy of this software and associated documentation files (the
  190.12 +//   "Software"), to deal in the Software without restriction, including
  190.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  190.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  190.15 +//   permit persons to whom the Software is furnished to do so, subject to
  190.16 +//   the following conditions:
  190.17 +//
  190.18 +//   The above copyright notice and this permission notice shall be included
  190.19 +//   in all copies or substantial portions of the Software.
  190.20 +//
  190.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  190.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  190.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  190.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  190.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  190.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  190.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  190.28 +// </copyright>
  190.29 +// <summary>
  190.30 +//   Interface for Series that can be 'tracked'
  190.31 +// </summary>
  190.32 +// --------------------------------------------------------------------------------------------------------------------
  190.33 +namespace OxyPlot.Series
  190.34 +{
  190.35 +    /// <summary>
  190.36 +    /// Provides functionality to return data for a tracker control.
  190.37 +    /// </summary>
  190.38 +    /// <remarks>
  190.39 +    /// The plot control will show a tracker with the current value when moving the mouse over the data.
  190.40 +    /// </remarks>
  190.41 +    public interface ITrackableSeries
  190.42 +    {
  190.43 +        /// <summary>
  190.44 +        /// Gets a format string used for the tracker.
  190.45 +        /// </summary>
  190.46 +        /// <remarks>
  190.47 +        /// The fields that can be used in the format string depends on the series.
  190.48 +        /// </remarks>
  190.49 +        string TrackerFormatString { get; }
  190.50 +
  190.51 +        /// <summary>
  190.52 +        /// Gets the tracker key.
  190.53 +        /// </summary>
  190.54 +        string TrackerKey { get; }
  190.55 +
  190.56 +        /// <summary>
  190.57 +        /// Gets the point on the series that is nearest the specified point.
  190.58 +        /// </summary>
  190.59 +        /// <param name="point">
  190.60 +        /// The point.
  190.61 +        /// </param>
  190.62 +        /// <param name="interpolate">
  190.63 +        /// Interpolate the series if this flag is set to <c>true</c>.
  190.64 +        /// </param>
  190.65 +        /// <returns>
  190.66 +        /// A TrackerHitResult for the current hit.
  190.67 +        /// </returns>
  190.68 +        TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate);
  190.69 +    }
  190.70 +}
  190.71 \ No newline at end of file
   191.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   191.2 +++ b/External/OxyPlot/OxyPlot/Series/ItemsSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   191.3 @@ -0,0 +1,96 @@
   191.4 +// --------------------------------------------------------------------------------------------------------------------
   191.5 +// <copyright file="ItemsSeries.cs" company="OxyPlot">
   191.6 +//   The MIT License (MIT)
   191.7 +//
   191.8 +//   Copyright (c) 2012 Oystein Bjorke
   191.9 +//
  191.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  191.11 +//   copy of this software and associated documentation files (the
  191.12 +//   "Software"), to deal in the Software without restriction, including
  191.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  191.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  191.15 +//   permit persons to whom the Software is furnished to do so, subject to
  191.16 +//   the following conditions:
  191.17 +//
  191.18 +//   The above copyright notice and this permission notice shall be included
  191.19 +//   in all copies or substantial portions of the Software.
  191.20 +//
  191.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  191.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  191.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  191.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  191.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  191.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  191.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  191.28 +// </copyright>
  191.29 +// <summary>
  191.30 +//   Abstract base class for series that can contain items.
  191.31 +// </summary>
  191.32 +// --------------------------------------------------------------------------------------------------------------------
  191.33 +namespace OxyPlot.Series
  191.34 +{
  191.35 +    using System.Collections;
  191.36 +    using System.Linq;
  191.37 +
  191.38 +    /// <summary>
  191.39 +    /// Abstract base class for series that can contain items.
  191.40 +    /// </summary>
  191.41 +    public abstract class ItemsSeries : Series
  191.42 +    {
  191.43 +        /// <summary>
  191.44 +        /// Gets or sets the items source.
  191.45 +        /// </summary>
  191.46 +        /// <value> The items source. </value>
  191.47 +        [CodeGeneration(false)]
  191.48 +        public IEnumerable ItemsSource { get; set; }
  191.49 +
  191.50 +        /// <summary>
  191.51 +        /// Updates the valid items
  191.52 +        /// </summary>
  191.53 +        protected internal override void UpdateValidData()
  191.54 +        {
  191.55 +        }
  191.56 +
  191.57 +        /// <summary>
  191.58 +        /// Gets the item for the specified index.
  191.59 +        /// </summary>
  191.60 +        /// <param name="itemsSource"> The items source. </param>
  191.61 +        /// <param name="index"> The index. </param>
  191.62 +        /// <returns> The get item. </returns>
  191.63 +        /// <remarks>
  191.64 +        /// Returns null if ItemsSource is not set, or the index is outside the boundaries.
  191.65 +        /// </remarks>
  191.66 +        protected static object GetItem(IEnumerable itemsSource, int index)
  191.67 +        {
  191.68 +            if (itemsSource == null || index < 0)
  191.69 +            {
  191.70 +                return null;
  191.71 +            }
  191.72 +
  191.73 +            var list = itemsSource as IList;
  191.74 +            if (list != null)
  191.75 +            {
  191.76 +                if (index < list.Count && index >= 0)
  191.77 +                {
  191.78 +                    return list[index];
  191.79 +                }
  191.80 +
  191.81 +                return null;
  191.82 +            }
  191.83 +
  191.84 +            var i = 0;
  191.85 +            return itemsSource.Cast<object>().FirstOrDefault(item => i++ == index);
  191.86 +        }
  191.87 +
  191.88 +        /// <summary>
  191.89 +        /// Gets the item at the specified index.
  191.90 +        /// </summary>
  191.91 +        /// <param name="i"> The index of the item. </param>
  191.92 +        /// <returns> The item of the index. </returns>
  191.93 +        protected virtual object GetItem(int i)
  191.94 +        {
  191.95 +            return GetItem(this.ItemsSource, i);
  191.96 +        }
  191.97 +
  191.98 +    }
  191.99 +}
 191.100 \ No newline at end of file
   192.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.2 +++ b/External/OxyPlot/OxyPlot/Series/LineLegendPosition.cs	Sat Jun 08 16:53:22 2013 +0000
   192.3 @@ -0,0 +1,52 @@
   192.4 +// --------------------------------------------------------------------------------------------------------------------
   192.5 +// <copyright file="LineLegendPosition.cs" company="OxyPlot">
   192.6 +//   The MIT License (MIT)
   192.7 +//
   192.8 +//   Copyright (c) 2012 Oystein Bjorke
   192.9 +//
  192.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  192.11 +//   copy of this software and associated documentation files (the
  192.12 +//   "Software"), to deal in the Software without restriction, including
  192.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  192.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  192.15 +//   permit persons to whom the Software is furnished to do so, subject to
  192.16 +//   the following conditions:
  192.17 +//
  192.18 +//   The above copyright notice and this permission notice shall be included
  192.19 +//   in all copies or substantial portions of the Software.
  192.20 +//
  192.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  192.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  192.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  192.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  192.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  192.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  192.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  192.28 +// </copyright>
  192.29 +// <summary>
  192.30 +//   Specifies the position of legends rendered on a line series.
  192.31 +// </summary>
  192.32 +// --------------------------------------------------------------------------------------------------------------------
  192.33 +namespace OxyPlot.Series
  192.34 +{
  192.35 +    /// <summary>
  192.36 +    /// Specifies the position of legends rendered on a <see cref="LineSeries"/>.
  192.37 +    /// </summary>
  192.38 +    public enum LineLegendPosition
  192.39 +    {
  192.40 +        /// <summary>
  192.41 +        /// Do not render legend on the line.
  192.42 +        /// </summary>
  192.43 +        None,
  192.44 +
  192.45 +        /// <summary>
  192.46 +        /// Render legend at the start of the line.
  192.47 +        /// </summary>
  192.48 +        Start,
  192.49 +
  192.50 +        /// <summary>
  192.51 +        /// Render legend at the end of the line.
  192.52 +        /// </summary>
  192.53 +        End
  192.54 +    }
  192.55 +}
  192.56 \ No newline at end of file
   193.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   193.2 +++ b/External/OxyPlot/OxyPlot/Series/LineSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   193.3 @@ -0,0 +1,644 @@
   193.4 +// --------------------------------------------------------------------------------------------------------------------
   193.5 +// <copyright file="LineSeries.cs" company="OxyPlot">
   193.6 +//   The MIT License (MIT)
   193.7 +//   
   193.8 +//   Copyright (c) 2012 Oystein Bjorke
   193.9 +//   
  193.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  193.11 +//   copy of this software and associated documentation files (the
  193.12 +//   "Software"), to deal in the Software without restriction, including
  193.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  193.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  193.15 +//   permit persons to whom the Software is furnished to do so, subject to
  193.16 +//   the following conditions:
  193.17 +//   
  193.18 +//   The above copyright notice and this permission notice shall be included
  193.19 +//   in all copies or substantial portions of the Software.
  193.20 +//   
  193.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  193.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  193.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  193.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  193.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  193.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  193.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  193.28 +// </copyright>
  193.29 +// <summary>
  193.30 +//   Represents a line series.
  193.31 +// </summary>
  193.32 +// --------------------------------------------------------------------------------------------------------------------
  193.33 +
  193.34 +namespace OxyPlot.Series
  193.35 +{
  193.36 +    using System;
  193.37 +    using System.Collections.Generic;
  193.38 +
  193.39 +    /// <summary>
  193.40 +    /// Represents a line series.
  193.41 +    /// </summary>
  193.42 +    public class LineSeries : DataPointSeries
  193.43 +    {
  193.44 +        /// <summary>
  193.45 +        /// The divisor value used to calculate tolerance for line smoothing.
  193.46 +        /// </summary>
  193.47 +        private const double ToleranceDivisor = 200;
  193.48 +
  193.49 +        /// <summary>
  193.50 +        /// The default color.
  193.51 +        /// </summary>
  193.52 +        private OxyColor defaultColor;
  193.53 +
  193.54 +        /// <summary>
  193.55 +        /// The smoothed points.
  193.56 +        /// </summary>
  193.57 +        private IList<IDataPoint> smoothedPoints;
  193.58 +
  193.59 +        /// <summary>
  193.60 +        /// Initializes a new instance of the <see cref = "LineSeries" /> class.
  193.61 +        /// </summary>
  193.62 +        public LineSeries()
  193.63 +        {
  193.64 +            this.MinimumSegmentLength = 2;
  193.65 +            this.StrokeThickness = 2;
  193.66 +            this.LineJoin = OxyPenLineJoin.Bevel;
  193.67 +            this.LineStyle = LineStyle.Undefined;
  193.68 +            this.MarkerSize = 3;
  193.69 +            this.MarkerStrokeThickness = 1;
  193.70 +            this.CanTrackerInterpolatePoints = true;
  193.71 +            this.LabelMargin = 6;
  193.72 +        }
  193.73 +
  193.74 +        /// <summary>
  193.75 +        /// Initializes a new instance of the <see cref="LineSeries"/> class.
  193.76 +        /// </summary>
  193.77 +        /// <param name="title">
  193.78 +        /// The title.
  193.79 +        /// </param>
  193.80 +        public LineSeries(string title)
  193.81 +            : this()
  193.82 +        {
  193.83 +            this.Title = title;
  193.84 +        }
  193.85 +
  193.86 +        /// <summary>
  193.87 +        /// Initializes a new instance of the <see cref="LineSeries"/> class.
  193.88 +        /// </summary>
  193.89 +        /// <param name="color">
  193.90 +        /// The color of the line stroke.
  193.91 +        /// </param>
  193.92 +        /// <param name="strokeThickness">
  193.93 +        /// The stroke thickness (optional).
  193.94 +        /// </param>
  193.95 +        /// <param name="title">
  193.96 +        /// The title (optional).
  193.97 +        /// </param>
  193.98 +        public LineSeries(OxyColor color, double strokeThickness = 1, string title = null)
  193.99 +            : this()
 193.100 +        {
 193.101 +            this.Color = color;
 193.102 +            this.StrokeThickness = strokeThickness;
 193.103 +            this.BrokenLineThickness = 0;
 193.104 +            this.Title = title;
 193.105 +        }
 193.106 +
 193.107 +        /// <summary>
 193.108 +        /// Gets or sets the color of the curve.
 193.109 +        /// </summary>
 193.110 +        /// <value>The color.</value>
 193.111 +        public OxyColor Color { get; set; }
 193.112 +
 193.113 +        /// <summary>
 193.114 +        /// Gets or sets the color of the broken line segments.
 193.115 +        /// </summary>
 193.116 +        /// <remarks>
 193.117 +        /// Add <c>DataPoint.Undefined</c> in the Points collection to create breaks in the line.
 193.118 +        /// </remarks>
 193.119 +        public OxyColor BrokenLineColor { get; set; }
 193.120 +
 193.121 +        /// <summary>
 193.122 +        /// Gets or sets the broken line style.
 193.123 +        /// </summary>
 193.124 +        public LineStyle BrokenLineStyle { get; set; }
 193.125 +
 193.126 +        /// <summary>
 193.127 +        /// Gets or sets the broken line thickness.
 193.128 +        /// </summary>
 193.129 +        public double BrokenLineThickness { get; set; }
 193.130 +
 193.131 +        /// <summary>
 193.132 +        /// Gets or sets the dashes array.
 193.133 +        /// If this is not null it overrides the LineStyle property.
 193.134 +        /// </summary>
 193.135 +        /// <value>The dashes.</value>
 193.136 +        public double[] Dashes { get; set; }
 193.137 +
 193.138 +        /// <summary>
 193.139 +        /// Gets or sets the label format string.
 193.140 +        /// </summary>
 193.141 +        /// <value> The label format string. </value>
 193.142 +        public string LabelFormatString { get; set; }
 193.143 +
 193.144 +        /// <summary>
 193.145 +        /// Gets or sets the label margins.
 193.146 +        /// </summary>
 193.147 +        public double LabelMargin { get; set; }
 193.148 +
 193.149 +        /// <summary>
 193.150 +        /// Gets or sets the line join.
 193.151 +        /// </summary>
 193.152 +        /// <value>The line join.</value>
 193.153 +        public OxyPenLineJoin LineJoin { get; set; }
 193.154 +
 193.155 +        /// <summary>
 193.156 +        /// Gets or sets the line style.
 193.157 +        /// </summary>
 193.158 +        /// <value>The line style.</value>
 193.159 +        public LineStyle LineStyle { get; set; }
 193.160 +
 193.161 +        /// <summary>
 193.162 +        /// Gets or sets a value specifying the position of a legend rendered on the line.
 193.163 +        /// </summary>
 193.164 +        /// <value>A value specifying the position of the legend.</value>
 193.165 +        public LineLegendPosition LineLegendPosition { get; set; }
 193.166 +
 193.167 +        /// <summary>
 193.168 +        /// Gets or sets the marker fill color.
 193.169 +        /// </summary>
 193.170 +        /// <value>The marker fill.</value>
 193.171 +        public OxyColor MarkerFill { get; set; }
 193.172 +
 193.173 +        /// <summary>
 193.174 +        /// Gets or sets the marker outline polygon.
 193.175 +        /// If this property is set, the MarkerType will not be used.
 193.176 +        /// </summary>
 193.177 +        /// <value>The marker outline.</value>
 193.178 +        public ScreenPoint[] MarkerOutline { get; set; }
 193.179 +
 193.180 +        /// <summary>
 193.181 +        /// Gets or sets the size of the marker.
 193.182 +        /// </summary>
 193.183 +        /// <value>The size of the marker.</value>
 193.184 +        public double MarkerSize { get; set; }
 193.185 +
 193.186 +        /// <summary>
 193.187 +        /// Gets or sets the marker stroke.
 193.188 +        /// </summary>
 193.189 +        /// <value>The marker stroke.</value>
 193.190 +        public OxyColor MarkerStroke { get; set; }
 193.191 +
 193.192 +        /// <summary>
 193.193 +        /// Gets or sets the marker stroke thickness.
 193.194 +        /// </summary>
 193.195 +        /// <value>The marker stroke thickness.</value>
 193.196 +        public double MarkerStrokeThickness { get; set; }
 193.197 +
 193.198 +        /// <summary>
 193.199 +        /// Gets or sets the type of the marker.
 193.200 +        /// </summary>
 193.201 +        /// <value>The type of the marker.</value>
 193.202 +        /// <remarks>
 193.203 +        /// If MarkerType.Custom is used, the MarkerOutline property must be specified.
 193.204 +        /// </remarks>
 193.205 +        public MarkerType MarkerType { get; set; }
 193.206 +
 193.207 +        /// <summary>
 193.208 +        /// Gets or sets the minimum length of the segment.
 193.209 +        /// Increasing this number will increase performance,
 193.210 +        /// but make the curve less accurate.
 193.211 +        /// </summary>
 193.212 +        /// <value>The minimum length of the segment.</value>
 193.213 +        public double MinimumSegmentLength { get; set; }
 193.214 +
 193.215 +        /// <summary>
 193.216 +        /// Gets or sets the thickness of the curve.
 193.217 +        /// </summary>
 193.218 +        /// <value>The stroke thickness.</value>
 193.219 +        public double StrokeThickness { get; set; }
 193.220 +
 193.221 +        /// <summary>
 193.222 +        /// Gets the actual color.
 193.223 +        /// </summary>
 193.224 +        /// <value>The actual color.</value>
 193.225 +        protected OxyColor ActualColor
 193.226 +        {
 193.227 +            get
 193.228 +            {
 193.229 +                return this.Color ?? this.defaultColor;
 193.230 +            }
 193.231 +        }
 193.232 +
 193.233 +        /// <summary>
 193.234 +        /// Gets the actual line style.
 193.235 +        /// </summary>
 193.236 +        /// <value>
 193.237 +        /// The actual line style.
 193.238 +        /// </value>
 193.239 +        protected LineStyle ActualLineStyle
 193.240 +        {
 193.241 +            get
 193.242 +            {
 193.243 +                return this.LineStyle != LineStyle.Undefined ? this.LineStyle : LineStyle.Solid;
 193.244 +            }
 193.245 +        }
 193.246 +        
 193.247 +        /// <summary>
 193.248 +        /// Gets the smoothed points.
 193.249 +        /// </summary>
 193.250 +        /// <value>The smoothed points.</value>
 193.251 +        protected IList<IDataPoint> SmoothedPoints
 193.252 +        {
 193.253 +            get
 193.254 +            {
 193.255 +                return this.smoothedPoints;
 193.256 +            }
 193.257 +        }
 193.258 +
 193.259 +        /// <summary>
 193.260 +        /// Gets the point on the series that is nearest the specified point.
 193.261 +        /// </summary>
 193.262 +        /// <param name="point">The point.</param>
 193.263 +        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
 193.264 +        /// <returns>
 193.265 +        /// A TrackerHitResult for the current hit.
 193.266 +        /// </returns>
 193.267 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 193.268 +        {
 193.269 +            if (interpolate)
 193.270 +            {
 193.271 +                // Cannot interpolate if there is no line
 193.272 +                if (this.ActualColor == null || this.StrokeThickness.IsZero())
 193.273 +                {
 193.274 +                    return null;
 193.275 +                }
 193.276 +
 193.277 +                if (!this.CanTrackerInterpolatePoints)
 193.278 +                {
 193.279 +                    return null;
 193.280 +                }
 193.281 +            }
 193.282 +
 193.283 +            if (interpolate && this.Smooth && this.SmoothedPoints != null)
 193.284 +            {
 193.285 +                return this.GetNearestInterpolatedPointInternal(this.SmoothedPoints, point);
 193.286 +            }
 193.287 +
 193.288 +            return base.GetNearestPoint(point, interpolate);
 193.289 +        }
 193.290 +
 193.291 +        /// <summary>
 193.292 +        /// Renders the series on the specified rendering context.
 193.293 +        /// </summary>
 193.294 +        /// <param name="rc">
 193.295 +        /// The rendering context.
 193.296 +        /// </param>
 193.297 +        /// <param name="model">
 193.298 +        /// The owner plot model.
 193.299 +        /// </param>
 193.300 +        public override void Render(IRenderContext rc, PlotModel model)
 193.301 +        {
 193.302 +            if (this.Points.Count == 0)
 193.303 +            {
 193.304 +                return;
 193.305 +            }
 193.306 +
 193.307 +            this.VerifyAxes();
 193.308 +
 193.309 +            var clippingRect = this.GetClippingRect();
 193.310 +            var transformedPoints = new List<ScreenPoint>();
 193.311 +            var lineBreakSegments = new List<ScreenPoint>();
 193.312 +
 193.313 +            ScreenPoint lastValidPoint = default(ScreenPoint);
 193.314 +            bool isBroken = false;
 193.315 +            var renderBrokenLineSegments = this.BrokenLineThickness > 0 && this.BrokenLineStyle != LineStyle.None;
 193.316 +
 193.317 +            // Transform all points to screen coordinates
 193.318 +            // Render the line when invalid points occur
 193.319 +            foreach (var point in this.Points)
 193.320 +            {
 193.321 +                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
 193.322 +                {
 193.323 +                    this.RenderPoints(rc, clippingRect, transformedPoints);
 193.324 +                    transformedPoints.Clear();
 193.325 +                    isBroken = true;
 193.326 +                    continue;
 193.327 +                }
 193.328 +
 193.329 +                var pt = this.XAxis.Transform(point.X, point.Y, this.YAxis);
 193.330 +                transformedPoints.Add(pt);
 193.331 +
 193.332 +                if (renderBrokenLineSegments)
 193.333 +                {
 193.334 +                    if (isBroken)
 193.335 +                    {
 193.336 +                        lineBreakSegments.Add(lastValidPoint);
 193.337 +                        lineBreakSegments.Add(pt);
 193.338 +                        isBroken = false;
 193.339 +                    }
 193.340 +
 193.341 +                    lastValidPoint = pt;
 193.342 +                }
 193.343 +            }
 193.344 +
 193.345 +            // Render the remaining points
 193.346 +            this.RenderPoints(rc, clippingRect, transformedPoints);
 193.347 +
 193.348 +            if (renderBrokenLineSegments)
 193.349 +            {
 193.350 +                // Render line breaks
 193.351 +                rc.DrawClippedLineSegments(
 193.352 +                    lineBreakSegments, 
 193.353 +                    clippingRect, 
 193.354 +                    this.BrokenLineColor, 
 193.355 +                    this.BrokenLineThickness, 
 193.356 +                    this.BrokenLineStyle, 
 193.357 +                    this.LineJoin, 
 193.358 +                    false);
 193.359 +            }
 193.360 +
 193.361 +            if (this.LabelFormatString != null)
 193.362 +            {
 193.363 +                // render point labels (not optimized for performance)
 193.364 +                this.RenderPointLabels(rc, clippingRect);
 193.365 +            }
 193.366 +
 193.367 +            if (this.LineLegendPosition != LineLegendPosition.None && this.Points.Count > 0
 193.368 +                && !string.IsNullOrEmpty(this.Title))
 193.369 +            {
 193.370 +                // renders a legend on the line
 193.371 +                this.RenderLegendOnLine(rc, clippingRect);
 193.372 +            }
 193.373 +        }
 193.374 +
 193.375 +        /// <summary>
 193.376 +        /// Renders the legend symbol for the line series on the
 193.377 +        /// specified rendering context.
 193.378 +        /// </summary>
 193.379 +        /// <param name="rc">
 193.380 +        /// The rendering context.
 193.381 +        /// </param>
 193.382 +        /// <param name="legendBox">
 193.383 +        /// The bounding rectangle of the legend box.
 193.384 +        /// </param>
 193.385 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 193.386 +        {
 193.387 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 193.388 +            double ymid = (legendBox.Top + legendBox.Bottom) / 2;
 193.389 +            var pts = new[] { new ScreenPoint(legendBox.Left, ymid), new ScreenPoint(legendBox.Right, ymid) };
 193.390 +            rc.DrawLine(
 193.391 +                pts, 
 193.392 +                this.GetSelectableColor(this.ActualColor), 
 193.393 +                this.StrokeThickness, 
 193.394 +                this.ActualLineStyle.GetDashArray());
 193.395 +            var midpt = new ScreenPoint(xmid, ymid);
 193.396 +            rc.DrawMarker(
 193.397 +                midpt, 
 193.398 +                legendBox, 
 193.399 +                this.MarkerType, 
 193.400 +                this.MarkerOutline, 
 193.401 +                this.MarkerSize, 
 193.402 +                this.MarkerFill, 
 193.403 +                this.MarkerStroke, 
 193.404 +                this.MarkerStrokeThickness);
 193.405 +        }
 193.406 +
 193.407 +        /// <summary>
 193.408 +        /// The set default values.
 193.409 +        /// </summary>
 193.410 +        /// <param name="model">
 193.411 +        /// The model.
 193.412 +        /// </param>
 193.413 +        protected internal override void SetDefaultValues(PlotModel model)
 193.414 +        {
 193.415 +            // todo: should use ActualLineStyle
 193.416 +            if (this.Color == null)
 193.417 +            {
 193.418 +                if (this.LineStyle == LineStyle.Undefined)
 193.419 +                {
 193.420 +                    this.LineStyle = model.GetDefaultLineStyle();
 193.421 +                }
 193.422 +
 193.423 +                this.defaultColor = model.GetDefaultColor();
 193.424 +
 193.425 +                // And MarkerFill will be overridden if not set to null
 193.426 +                if (this.MarkerFill == null)
 193.427 +                {
 193.428 +                    this.MarkerFill = this.defaultColor;
 193.429 +                }
 193.430 +            }
 193.431 +        }
 193.432 +
 193.433 +        /// <summary>
 193.434 +        /// Updates the axes to include the max and min of this series.
 193.435 +        /// </summary>
 193.436 +        protected internal override void UpdateMaxMin()
 193.437 +        {
 193.438 +            if (this.Smooth)
 193.439 +            {
 193.440 +                // Update the max/min from the control points
 193.441 +                base.UpdateMaxMin();
 193.442 +
 193.443 +                // Make sure the smooth points are re-evaluated.
 193.444 +                this.ResetSmoothedPoints();
 193.445 +
 193.446 +                // Update the max/min from the smoothed points
 193.447 +                foreach (var pt in this.SmoothedPoints)
 193.448 +                {
 193.449 +                    this.MinX = Math.Min(this.MinX, pt.X);
 193.450 +                    this.MinY = Math.Min(this.MinY, pt.Y);
 193.451 +                    this.MaxX = Math.Max(this.MaxX, pt.X);
 193.452 +                    this.MaxY = Math.Max(this.MaxY, pt.Y);
 193.453 +                }
 193.454 +            }
 193.455 +            else
 193.456 +            {
 193.457 +                base.UpdateMaxMin();
 193.458 +            }
 193.459 +        }
 193.460 +
 193.461 +        /// <summary>
 193.462 +        /// Renders the point labels.
 193.463 +        /// </summary>
 193.464 +        /// <param name="rc">The render context.</param>
 193.465 +        /// <param name="clippingRect">The clipping rectangle.</param>
 193.466 +        protected void RenderPointLabels(IRenderContext rc, OxyRect clippingRect)
 193.467 +        {
 193.468 +            int index = -1;
 193.469 +            foreach (var point in this.Points)
 193.470 +            {
 193.471 +                index++;
 193.472 +
 193.473 +                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
 193.474 +                {
 193.475 +                    continue;
 193.476 +                }
 193.477 +
 193.478 +                var pt = this.XAxis.Transform(point.X, point.Y, this.YAxis);
 193.479 +                pt.Y -= this.LabelMargin;
 193.480 +
 193.481 +                if (!clippingRect.Contains(pt))
 193.482 +                {
 193.483 +                    continue;
 193.484 +                }
 193.485 +
 193.486 +                var s = StringHelper.Format(
 193.487 +                    this.ActualCulture, this.LabelFormatString, this.GetItem(index), point.X, point.Y);
 193.488 +
 193.489 +#if SUPPORTLABELPLACEMENT
 193.490 +                    switch (this.LabelPlacement)
 193.491 +                    {
 193.492 +                        case LabelPlacement.Inside:
 193.493 +                            pt = new ScreenPoint(rect.Right - this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 193.494 +                            ha = HorizontalAlignment.Right;
 193.495 +                            break;
 193.496 +                        case LabelPlacement.Middle:
 193.497 +                            pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2);
 193.498 +                            ha = HorizontalAlignment.Center;
 193.499 +                            break;
 193.500 +                        case LabelPlacement.Base:
 193.501 +                            pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 193.502 +                            ha = HorizontalAlignment.Left;
 193.503 +                            break;
 193.504 +                        default: // Outside
 193.505 +                            pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
 193.506 +                            ha = HorizontalAlignment.Left;
 193.507 +                            break;
 193.508 +                    }
 193.509 +#endif
 193.510 +
 193.511 +                rc.DrawClippedText(
 193.512 +                    clippingRect, 
 193.513 +                    pt, 
 193.514 +                    s, 
 193.515 +                    this.ActualTextColor, 
 193.516 +                    this.ActualFont, 
 193.517 +                    this.ActualFontSize, 
 193.518 +                    this.ActualFontWeight, 
 193.519 +                    0, 
 193.520 +                    HorizontalAlignment.Center, 
 193.521 +                    VerticalAlignment.Bottom);
 193.522 +            }
 193.523 +        }
 193.524 +
 193.525 +        /// <summary>
 193.526 +        /// Renders a legend on the line.
 193.527 +        /// </summary>
 193.528 +        /// <param name="rc">The render context.</param>
 193.529 +        /// <param name="clippingRect">The clipping rectangle.</param>
 193.530 +        protected void RenderLegendOnLine(IRenderContext rc, OxyRect clippingRect)
 193.531 +        {
 193.532 +            // Find the position
 193.533 +            IDataPoint point;
 193.534 +            var ha = HorizontalAlignment.Left;
 193.535 +            double dx;
 193.536 +            switch (this.LineLegendPosition)
 193.537 +            {
 193.538 +                case LineLegendPosition.Start:
 193.539 +
 193.540 +                    // start position
 193.541 +                    point = this.Points[0];
 193.542 +                    ha = HorizontalAlignment.Right;
 193.543 +                    dx = -4;
 193.544 +                    break;
 193.545 +                default:
 193.546 +
 193.547 +                    // end position
 193.548 +                    point = this.Points[this.Points.Count - 1];
 193.549 +                    dx = 4;
 193.550 +                    break;
 193.551 +            }
 193.552 +
 193.553 +            var pt = this.XAxis.Transform(point.X, point.Y, this.YAxis);
 193.554 +            pt.X += dx;
 193.555 +
 193.556 +            // Render the legend
 193.557 +            rc.DrawClippedText(
 193.558 +                clippingRect, 
 193.559 +                pt, 
 193.560 +                this.Title, 
 193.561 +                this.ActualTextColor, 
 193.562 +                this.ActualFont, 
 193.563 +                this.ActualFontSize, 
 193.564 +                this.ActualFontWeight, 
 193.565 +                0, 
 193.566 +                ha, 
 193.567 +                VerticalAlignment.Middle);
 193.568 +        }
 193.569 +
 193.570 +        /// <summary>
 193.571 +        /// Renders the transformed points.
 193.572 +        /// </summary>
 193.573 +        /// <param name="rc">
 193.574 +        /// The render context.
 193.575 +        /// </param>
 193.576 +        /// <param name="clippingRect">
 193.577 +        /// The clipping rectangle.
 193.578 +        /// </param>
 193.579 +        /// <param name="pointsToRender">
 193.580 +        /// The points to render.
 193.581 +        /// </param>
 193.582 +        protected void RenderPoints(IRenderContext rc, OxyRect clippingRect, IList<ScreenPoint> pointsToRender)
 193.583 +        {
 193.584 +            var screenPoints = pointsToRender;
 193.585 +            if (this.Smooth)
 193.586 +            {
 193.587 +                // spline smoothing (should only be used on small datasets)
 193.588 +                var resampledPoints = ScreenPointHelper.ResamplePoints(pointsToRender, this.MinimumSegmentLength);
 193.589 +                screenPoints = CanonicalSplineHelper.CreateSpline(resampledPoints, 0.5, null, false, 0.25);
 193.590 +            }
 193.591 +
 193.592 +            // clip the line segments with the clipping rectangle
 193.593 +            if (this.StrokeThickness > 0 && this.ActualLineStyle != LineStyle.None)
 193.594 +            {
 193.595 +                this.RenderSmoothedLine(rc, clippingRect, screenPoints);
 193.596 +            }
 193.597 +
 193.598 +            if (this.MarkerType != MarkerType.None)
 193.599 +            {
 193.600 +                rc.DrawMarkers(
 193.601 +                    pointsToRender, 
 193.602 +                    clippingRect, 
 193.603 +                    this.MarkerType, 
 193.604 +                    this.MarkerOutline, 
 193.605 +                    new[] { this.MarkerSize }, 
 193.606 +                    this.MarkerFill, 
 193.607 +                    this.MarkerStroke, 
 193.608 +                    this.MarkerStrokeThickness);
 193.609 +            }
 193.610 +        }
 193.611 +
 193.612 +        /// <summary>
 193.613 +        /// Renders the (smoothed) line.
 193.614 +        /// </summary>
 193.615 +        /// <param name="rc">
 193.616 +        /// The render context.
 193.617 +        /// </param>
 193.618 +        /// <param name="clippingRect">
 193.619 +        /// The clipping rectangle.
 193.620 +        /// </param>
 193.621 +        /// <param name="pointsToRender">
 193.622 +        /// The points to render.
 193.623 +        /// </param>
 193.624 +        protected virtual void RenderSmoothedLine(
 193.625 +            IRenderContext rc, OxyRect clippingRect, IList<ScreenPoint> pointsToRender)
 193.626 +        {
 193.627 +            rc.DrawClippedLine(
 193.628 +                pointsToRender, 
 193.629 +                clippingRect, 
 193.630 +                this.MinimumSegmentLength * this.MinimumSegmentLength, 
 193.631 +                this.GetSelectableColor(this.ActualColor), 
 193.632 +                this.StrokeThickness, 
 193.633 +                this.ActualLineStyle, 
 193.634 +                this.LineJoin, 
 193.635 +                false);
 193.636 +        }
 193.637 +
 193.638 +        /// <summary>
 193.639 +        /// Force the smoothed points to be re-evaluated.
 193.640 +        /// </summary>
 193.641 +        protected void ResetSmoothedPoints()
 193.642 +        {
 193.643 +            double tolerance = Math.Abs(Math.Max(this.MaxX - this.MinX, this.MaxY - this.MinY) / ToleranceDivisor);
 193.644 +            this.smoothedPoints = CanonicalSplineHelper.CreateSpline(this.Points, 0.5, null, false, tolerance);
 193.645 +        }
 193.646 +    }
 193.647 +}
 193.648 \ No newline at end of file
   194.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   194.2 +++ b/External/OxyPlot/OxyPlot/Series/PieSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   194.3 @@ -0,0 +1,481 @@
   194.4 +// --------------------------------------------------------------------------------------------------------------------
   194.5 +// <copyright file="PieSeries.cs" company="OxyPlot">
   194.6 +//   The MIT License (MIT)
   194.7 +//
   194.8 +//   Copyright (c) 2012 Oystein Bjorke
   194.9 +//
  194.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  194.11 +//   copy of this software and associated documentation files (the
  194.12 +//   "Software"), to deal in the Software without restriction, including
  194.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  194.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  194.15 +//   permit persons to whom the Software is furnished to do so, subject to
  194.16 +//   the following conditions:
  194.17 +//
  194.18 +//   The above copyright notice and this permission notice shall be included
  194.19 +//   in all copies or substantial portions of the Software.
  194.20 +//
  194.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  194.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  194.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  194.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  194.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  194.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  194.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  194.28 +// </copyright>
  194.29 +// <summary>
  194.30 +//   Represents a series for pie/circle/doughnut charts.
  194.31 +// </summary>
  194.32 +// --------------------------------------------------------------------------------------------------------------------
  194.33 +namespace OxyPlot.Series
  194.34 +{
  194.35 +    using System;
  194.36 +    using System.Collections.Generic;
  194.37 +    using System.Linq;
  194.38 +
  194.39 +    using OxyPlot.Axes;
  194.40 +
  194.41 +    /// <summary>
  194.42 +    /// Represents a series for pie/circle/doughnut charts.
  194.43 +    /// </summary>
  194.44 +    /// <remarks>
  194.45 +    /// The arc length/central angle/area of each slice is proportional to the quantity it represents. See http://en.wikipedia.org/wiki/Pie_chart
  194.46 +    /// </remarks>
  194.47 +    public class PieSeries : ItemsSeries
  194.48 +    {
  194.49 +        /// <summary>
  194.50 +        /// The slices.
  194.51 +        /// </summary>
  194.52 +        private IList<PieSlice> slices;
  194.53 +
  194.54 +        /// <summary>
  194.55 +        /// Initializes a new instance of the <see cref="PieSeries"/> class.
  194.56 +        /// </summary>
  194.57 +        public PieSeries()
  194.58 +        {
  194.59 +            this.slices = new List<PieSlice>();
  194.60 +
  194.61 +            this.Stroke = OxyColors.White;
  194.62 +            this.StrokeThickness = 1.0;
  194.63 +            this.Diameter = 1.0;
  194.64 +            this.InnerDiameter = 0.0;
  194.65 +            this.StartAngle = 0.0;
  194.66 +            this.AngleSpan = 360.0;
  194.67 +            this.AngleIncrement = 1.0;
  194.68 +
  194.69 +            this.LegendFormat = null;
  194.70 +            this.OutsideLabelFormat = "{2:0} %";
  194.71 +            this.InsideLabelFormat = "{1}";
  194.72 +            this.TickDistance = 0;
  194.73 +            this.TickRadialLength = 6;
  194.74 +            this.TickHorizontalLength = 8;
  194.75 +            this.TickLabelDistance = 4;
  194.76 +            this.InsideLabelPosition = 0.5;
  194.77 +            this.FontSize = 12;
  194.78 +        }
  194.79 +
  194.80 +        /// <summary>
  194.81 +        /// Gets or sets AngleIncrement.
  194.82 +        /// </summary>
  194.83 +        public double AngleIncrement { get; set; }
  194.84 +
  194.85 +        /// <summary>
  194.86 +        /// Gets or sets AngleSpan.
  194.87 +        /// </summary>
  194.88 +        public double AngleSpan { get; set; }
  194.89 +
  194.90 +        /// <summary>
  194.91 +        /// Gets or sets a value indicating whether AreInsideLabelsAngled.
  194.92 +        /// </summary>
  194.93 +        public bool AreInsideLabelsAngled { get; set; }
  194.94 +
  194.95 +        /// <summary>
  194.96 +        /// Gets or sets the name of the property containing the color.
  194.97 +        /// </summary>
  194.98 +        /// <value> The color field. </value>
  194.99 +        public string ColorField { get; set; }
 194.100 +
 194.101 +        /// <summary>
 194.102 +        /// Gets or sets the diameter.
 194.103 +        /// </summary>
 194.104 +        /// <value> The diameter. </value>
 194.105 +        public double Diameter { get; set; }
 194.106 +
 194.107 +        /// <summary>
 194.108 +        /// Gets or sets the exploded distance.
 194.109 +        /// </summary>
 194.110 +        /// <value> The exploded distance. </value>
 194.111 +        public double ExplodedDistance { get; set; }
 194.112 +
 194.113 +        /// <summary>
 194.114 +        /// Gets or sets the inner diameter.
 194.115 +        /// </summary>
 194.116 +        /// <value> The inner diameter. </value>
 194.117 +        public double InnerDiameter { get; set; }
 194.118 +
 194.119 +        /// <summary>
 194.120 +        /// Gets or sets the inside label format.
 194.121 +        /// </summary>
 194.122 +        /// <value> The inside label format. </value>
 194.123 +        public string InsideLabelFormat { get; set; }
 194.124 +
 194.125 +        /// <summary>
 194.126 +        /// Gets or sets the inside label position.
 194.127 +        /// </summary>
 194.128 +        /// <value> The inside label position. </value>
 194.129 +        public double InsideLabelPosition { get; set; }
 194.130 +
 194.131 +        /// <summary>
 194.132 +        /// Gets or sets the is exploded field.
 194.133 +        /// </summary>
 194.134 +        /// <value> The is exploded field. </value>
 194.135 +        public string IsExplodedField { get; set; }
 194.136 +
 194.137 +        /// <summary>
 194.138 +        /// Gets or sets the label field.
 194.139 +        /// </summary>
 194.140 +        /// <value> The label field. </value>
 194.141 +        public string LabelField { get; set; }
 194.142 +
 194.143 +        /// <summary>
 194.144 +        /// Gets or sets the legend format.
 194.145 +        /// </summary>
 194.146 +        /// <value> The legend format. </value>
 194.147 +        public string LegendFormat { get; set; }
 194.148 +
 194.149 +        /// <summary>
 194.150 +        /// Gets or sets the outside label format.
 194.151 +        /// </summary>
 194.152 +        /// <value> The outside label format. </value>
 194.153 +        public string OutsideLabelFormat { get; set; }
 194.154 +
 194.155 +        /// <summary>
 194.156 +        /// Gets or sets the slices.
 194.157 +        /// </summary>
 194.158 +        /// <value> The slices. </value>
 194.159 +        public IList<PieSlice> Slices
 194.160 +        {
 194.161 +            get
 194.162 +            {
 194.163 +                return this.slices;
 194.164 +            }
 194.165 +
 194.166 +            set
 194.167 +            {
 194.168 +                this.slices = value;
 194.169 +            }
 194.170 +        }
 194.171 +
 194.172 +        /// <summary>
 194.173 +        /// Gets or sets the start angle.
 194.174 +        /// </summary>
 194.175 +        /// <value> The start angle. </value>
 194.176 +        public double StartAngle { get; set; }
 194.177 +
 194.178 +        /// <summary>
 194.179 +        /// Gets or sets the stroke.
 194.180 +        /// </summary>
 194.181 +        /// <value> The stroke. </value>
 194.182 +        public OxyColor Stroke { get; set; }
 194.183 +
 194.184 +        /// <summary>
 194.185 +        /// Gets or sets the stroke thickness.
 194.186 +        /// </summary>
 194.187 +        /// <value> The stroke thickness. </value>
 194.188 +        public double StrokeThickness { get; set; }
 194.189 +
 194.190 +        /// <summary>
 194.191 +        /// Gets or sets the tick distance.
 194.192 +        /// </summary>
 194.193 +        /// <value> The tick distance. </value>
 194.194 +        public double TickDistance { get; set; }
 194.195 +
 194.196 +        /// <summary>
 194.197 +        /// Gets or sets the length of the horizontal part of the tick.
 194.198 +        /// </summary>
 194.199 +        /// <value> The length. </value>
 194.200 +        public double TickHorizontalLength { get; set; }
 194.201 +
 194.202 +        /// <summary>
 194.203 +        /// Gets or sets the tick label distance.
 194.204 +        /// </summary>
 194.205 +        /// <value> The tick label distance. </value>
 194.206 +        public double TickLabelDistance { get; set; }
 194.207 +
 194.208 +        /// <summary>
 194.209 +        /// Gets or sets the length of the tick radial.
 194.210 +        /// </summary>
 194.211 +        /// <value> The length of the tick radial. </value>
 194.212 +        public double TickRadialLength { get; set; }
 194.213 +
 194.214 +        /// <summary>
 194.215 +        /// Gets or sets the name of the property containing the value.
 194.216 +        /// </summary>
 194.217 +        /// <value> The value field. </value>
 194.218 +        public string ValueField { get; set; }
 194.219 +
 194.220 +        /// <summary>
 194.221 +        /// Gets the point on the series that is nearest the specified point.
 194.222 +        /// </summary>
 194.223 +        /// <param name="point">
 194.224 +        /// The point.
 194.225 +        /// </param>
 194.226 +        /// <param name="interpolate">
 194.227 +        /// Interpolate the series if this flag is set to <c>true</c> .
 194.228 +        /// </param>
 194.229 +        /// <returns>
 194.230 +        /// A TrackerHitResult for the current hit.
 194.231 +        /// </returns>
 194.232 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 194.233 +        {
 194.234 +            return null;
 194.235 +        }
 194.236 +
 194.237 +        /// <summary>
 194.238 +        /// Renders the series on the specified render context.
 194.239 +        /// </summary>
 194.240 +        /// <param name="rc">
 194.241 +        /// The rendering context.
 194.242 +        /// </param>
 194.243 +        /// <param name="model">
 194.244 +        /// The model.
 194.245 +        /// </param>
 194.246 +        public override void Render(IRenderContext rc, PlotModel model)
 194.247 +        {
 194.248 +            if (this.Slices.Count == 0)
 194.249 +            {
 194.250 +                return;
 194.251 +            }
 194.252 +
 194.253 +            double total = this.slices.Sum(slice => slice.Value);
 194.254 +            if (Math.Abs(total) < double.Epsilon)
 194.255 +            {
 194.256 +                return;
 194.257 +            }
 194.258 +
 194.259 +            // todo: reduce available size due to the labels
 194.260 +            double radius = Math.Min(model.PlotArea.Width, model.PlotArea.Height) / 2;
 194.261 +
 194.262 +            double outerRadius = radius * (this.Diameter - this.ExplodedDistance);
 194.263 +            double innerRadius = radius * this.InnerDiameter;
 194.264 +
 194.265 +            double angle = this.StartAngle;
 194.266 +            var midPoint = new ScreenPoint(
 194.267 +                (model.PlotArea.Left + model.PlotArea.Right) * 0.5, (model.PlotArea.Top + model.PlotArea.Bottom) * 0.5);
 194.268 +
 194.269 +            foreach (var slice in this.slices)
 194.270 +            {
 194.271 +                var outerPoints = new List<ScreenPoint>();
 194.272 +                var innerPoints = new List<ScreenPoint>();
 194.273 +
 194.274 +                double sliceAngle = slice.Value / total * this.AngleSpan;
 194.275 +                double endAngle = angle + sliceAngle;
 194.276 +                double explodedRadius = slice.IsExploded ? this.ExplodedDistance * radius : 0.0;
 194.277 +
 194.278 +                double midAngle = angle + (sliceAngle / 2);
 194.279 +                double midAngleRadians = midAngle * Math.PI / 180;
 194.280 +                var mp = new ScreenPoint(
 194.281 +                    midPoint.X + (explodedRadius * Math.Cos(midAngleRadians)),
 194.282 +                    midPoint.Y + (explodedRadius * Math.Sin(midAngleRadians)));
 194.283 +
 194.284 +                // Create the pie sector points for both outside and inside arcs
 194.285 +                while (true)
 194.286 +                {
 194.287 +                    bool stop = false;
 194.288 +                    if (angle >= endAngle)
 194.289 +                    {
 194.290 +                        angle = endAngle;
 194.291 +                        stop = true;
 194.292 +                    }
 194.293 +
 194.294 +                    double a = angle * Math.PI / 180;
 194.295 +                    var op = new ScreenPoint(mp.X + (outerRadius * Math.Cos(a)), mp.Y + (outerRadius * Math.Sin(a)));
 194.296 +                    outerPoints.Add(op);
 194.297 +                    var ip = new ScreenPoint(mp.X + (innerRadius * Math.Cos(a)), mp.Y + (innerRadius * Math.Sin(a)));
 194.298 +                    if (innerRadius + explodedRadius > 0)
 194.299 +                    {
 194.300 +                        innerPoints.Add(ip);
 194.301 +                    }
 194.302 +
 194.303 +                    if (stop)
 194.304 +                    {
 194.305 +                        break;
 194.306 +                    }
 194.307 +
 194.308 +                    angle += this.AngleIncrement;
 194.309 +                }
 194.310 +
 194.311 +                innerPoints.Reverse();
 194.312 +                if (innerPoints.Count == 0)
 194.313 +                {
 194.314 +                    innerPoints.Add(mp);
 194.315 +                }
 194.316 +
 194.317 +                innerPoints.Add(outerPoints[0]);
 194.318 +
 194.319 +                var points = outerPoints;
 194.320 +                points.AddRange(innerPoints);
 194.321 +
 194.322 +                rc.DrawPolygon(points, slice.ActualFillColor, this.Stroke, this.StrokeThickness, null, OxyPenLineJoin.Bevel);
 194.323 +
 194.324 +                // Render label outside the slice
 194.325 +                if (this.OutsideLabelFormat != null)
 194.326 +                {
 194.327 +                    string label = string.Format(
 194.328 +                        this.OutsideLabelFormat, slice.Value, slice.Label, slice.Value / total * 100);
 194.329 +                    int sign = Math.Sign(Math.Cos(midAngleRadians));
 194.330 +
 194.331 +                    // tick points
 194.332 +                    var tp0 = new ScreenPoint(
 194.333 +                        mp.X + ((outerRadius + this.TickDistance) * Math.Cos(midAngleRadians)),
 194.334 +                        mp.Y + ((outerRadius + this.TickDistance) * Math.Sin(midAngleRadians)));
 194.335 +                    var tp1 = new ScreenPoint(
 194.336 +                        tp0.X + (this.TickRadialLength * Math.Cos(midAngleRadians)),
 194.337 +                        tp0.Y + (this.TickRadialLength * Math.Sin(midAngleRadians)));
 194.338 +                    var tp2 = new ScreenPoint(tp1.X + (this.TickHorizontalLength * sign), tp1.Y);
 194.339 +                    rc.DrawLine(new[] { tp0, tp1, tp2 }, this.Stroke, this.StrokeThickness, null, OxyPenLineJoin.Bevel);
 194.340 +
 194.341 +                    // label
 194.342 +                    var labelPosition = new ScreenPoint(tp2.X + (this.TickLabelDistance * sign), tp2.Y);
 194.343 +                    rc.DrawText(
 194.344 +                        labelPosition,
 194.345 +                        label,
 194.346 +                        this.ActualTextColor,
 194.347 +                        this.ActualFont,
 194.348 +                        this.ActualFontSize,
 194.349 +                        this.ActualFontWeight,
 194.350 +                        0,
 194.351 +                        sign > 0 ? HorizontalAlignment.Left : HorizontalAlignment.Right,
 194.352 +                        VerticalAlignment.Middle);
 194.353 +                }
 194.354 +
 194.355 +                // Render label inside the slice
 194.356 +                if (this.InsideLabelFormat != null)
 194.357 +                {
 194.358 +                    string label = string.Format(
 194.359 +                        this.InsideLabelFormat, slice.Value, slice.Label, slice.Value / total * 100);
 194.360 +                    double r = (innerRadius * (1 - this.InsideLabelPosition)) + (outerRadius * this.InsideLabelPosition);
 194.361 +                    var labelPosition = new ScreenPoint(
 194.362 +                        mp.X + (r * Math.Cos(midAngleRadians)), mp.Y + (r * Math.Sin(midAngleRadians)));
 194.363 +                    double textAngle = 0;
 194.364 +                    if (this.AreInsideLabelsAngled)
 194.365 +                    {
 194.366 +                        textAngle = midAngle;
 194.367 +                        if (Math.Cos(midAngleRadians) < 0)
 194.368 +                        {
 194.369 +                            textAngle += 180;
 194.370 +                        }
 194.371 +                    }
 194.372 +
 194.373 +                    rc.DrawText(
 194.374 +                        labelPosition,
 194.375 +                        label,
 194.376 +                        this.ActualTextColor,
 194.377 +                        this.ActualFont,
 194.378 +                        this.ActualFontSize,
 194.379 +                        this.ActualFontWeight,
 194.380 +                        textAngle,
 194.381 +                        HorizontalAlignment.Center,
 194.382 +                        VerticalAlignment.Middle);
 194.383 +                }
 194.384 +            }
 194.385 +        }
 194.386 +
 194.387 +        /// <summary>
 194.388 +        /// Renders the legend symbol on the specified render context.
 194.389 +        /// </summary>
 194.390 +        /// <param name="rc">
 194.391 +        /// The rendering context.
 194.392 +        /// </param>
 194.393 +        /// <param name="legendBox">
 194.394 +        /// The legend rectangle.
 194.395 +        /// </param>
 194.396 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 194.397 +        {
 194.398 +        }
 194.399 +
 194.400 +        /// <summary>
 194.401 +        /// Check if this data series requires X/Y axes. (e.g. Pie series do not require axes)
 194.402 +        /// </summary>
 194.403 +        /// <returns>
 194.404 +        /// True if no axes are required.
 194.405 +        /// </returns>
 194.406 +        protected internal override bool AreAxesRequired()
 194.407 +        {
 194.408 +            return false;
 194.409 +        }
 194.410 +
 194.411 +        /// <summary>
 194.412 +        /// Ensures that the axes of the series is defined.
 194.413 +        /// </summary>
 194.414 +        protected internal override void EnsureAxes()
 194.415 +        {
 194.416 +        }
 194.417 +
 194.418 +        /// <summary>
 194.419 +        /// Check if the data series is using the specified axis.
 194.420 +        /// </summary>
 194.421 +        /// <param name="axis">
 194.422 +        /// An axis.
 194.423 +        /// </param>
 194.424 +        /// <returns>
 194.425 +        /// True if the axis is in use.
 194.426 +        /// </returns>
 194.427 +        protected internal override bool IsUsing(Axis axis)
 194.428 +        {
 194.429 +            return false;
 194.430 +        }
 194.431 +
 194.432 +        /// <summary>
 194.433 +        /// The set default values.
 194.434 +        /// </summary>
 194.435 +        /// <param name="model">
 194.436 +        /// The model.
 194.437 +        /// </param>
 194.438 +        protected internal override void SetDefaultValues(PlotModel model)
 194.439 +        {
 194.440 +            foreach (var slice in this.Slices)
 194.441 +            {
 194.442 +                if (slice.Fill == null)
 194.443 +                {
 194.444 +                    slice.DefaultFillColor = model.GetDefaultColor();
 194.445 +                }
 194.446 +            }
 194.447 +        }
 194.448 +
 194.449 +        /// <summary>
 194.450 +        /// The update axis max min.
 194.451 +        /// </summary>
 194.452 +        protected internal override void UpdateAxisMaxMin()
 194.453 +        {
 194.454 +        }
 194.455 +
 194.456 +        /// <summary>
 194.457 +        /// Updates the data.
 194.458 +        /// </summary>
 194.459 +        protected internal override void UpdateData()
 194.460 +        {
 194.461 +            if (this.ItemsSource == null)
 194.462 +            {
 194.463 +                return;
 194.464 +            }
 194.465 +
 194.466 +            this.slices.Clear();
 194.467 +
 194.468 +            var filler = new ListFiller<PieSlice>();
 194.469 +            filler.Add(this.LabelField, (item, value) => item.Label = Convert.ToString(value));
 194.470 +            filler.Add(this.ValueField, (item, value) => item.Value = Convert.ToDouble(value));
 194.471 +            filler.Add(this.ColorField, (item, value) => item.Fill = (OxyColor)value);
 194.472 +            filler.Add(this.IsExplodedField, (item, value) => item.IsExploded = (bool)value);
 194.473 +            filler.FillT(this.slices, this.ItemsSource);
 194.474 +        }
 194.475 +
 194.476 +        /// <summary>
 194.477 +        /// The update max min.
 194.478 +        /// </summary>
 194.479 +        protected internal override void UpdateMaxMin()
 194.480 +        {
 194.481 +        }
 194.482 +
 194.483 +    }
 194.484 +}
 194.485 \ No newline at end of file
   195.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   195.2 +++ b/External/OxyPlot/OxyPlot/Series/PieSlice.cs	Sat Jun 08 16:53:22 2013 +0000
   195.3 @@ -0,0 +1,99 @@
   195.4 +// --------------------------------------------------------------------------------------------------------------------
   195.5 +// <copyright file="PieSlice.cs" company="OxyPlot">
   195.6 +//   The MIT License (MIT)
   195.7 +//
   195.8 +//   Copyright (c) 2012 Oystein Bjorke
   195.9 +//
  195.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  195.11 +//   copy of this software and associated documentation files (the
  195.12 +//   "Software"), to deal in the Software without restriction, including
  195.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  195.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  195.15 +//   permit persons to whom the Software is furnished to do so, subject to
  195.16 +//   the following conditions:
  195.17 +//
  195.18 +//   The above copyright notice and this permission notice shall be included
  195.19 +//   in all copies or substantial portions of the Software.
  195.20 +//
  195.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  195.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  195.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  195.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  195.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  195.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  195.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  195.28 +// </copyright>
  195.29 +// <summary>
  195.30 +//   Represent a slice of a PieSeries.
  195.31 +// </summary>
  195.32 +// --------------------------------------------------------------------------------------------------------------------
  195.33 +namespace OxyPlot.Series
  195.34 +{
  195.35 +    /// <summary>
  195.36 +    /// Represent a slice of a <see cref="PieSeries"/>.
  195.37 +    /// </summary>
  195.38 +    public class PieSlice
  195.39 +    {
  195.40 +        /// <summary>
  195.41 +        /// Initializes a new instance of the <see cref = "PieSlice" /> class.
  195.42 +        /// </summary>
  195.43 +        public PieSlice()
  195.44 +        {
  195.45 +        }
  195.46 +
  195.47 +        /// <summary>
  195.48 +        /// Initializes a new instance of the <see cref="PieSlice"/> class.
  195.49 +        /// </summary>
  195.50 +        /// <param name="label">
  195.51 +        /// The label.
  195.52 +        /// </param>
  195.53 +        /// <param name="value">
  195.54 +        /// The value.
  195.55 +        /// </param>
  195.56 +        /// <param name="fill">
  195.57 +        /// The fill.
  195.58 +        /// </param>
  195.59 +        public PieSlice(string label, double value, OxyColor fill = null)
  195.60 +        {
  195.61 +            this.Label = label;
  195.62 +            this.Value = value;
  195.63 +            this.Fill = fill;
  195.64 +        }
  195.65 +
  195.66 +        /// <summary>
  195.67 +        /// Gets or sets Fill.
  195.68 +        /// </summary>
  195.69 +        public OxyColor Fill { get; set; }
  195.70 +
  195.71 +        /// <summary>
  195.72 +        /// Gets the actual fill color.
  195.73 +        /// </summary>
  195.74 +        /// <value>The actual color.</value>
  195.75 +        public OxyColor ActualFillColor
  195.76 +        {
  195.77 +            get { return this.Fill ?? this.DefaultFillColor; }
  195.78 +        }
  195.79 +
  195.80 +        /// <summary>
  195.81 +        /// Gets or sets a value indicating whether IsExploded.
  195.82 +        /// </summary>
  195.83 +        public bool IsExploded { get; set; }
  195.84 +
  195.85 +        /// <summary>
  195.86 +        /// Gets or sets Label.
  195.87 +        /// </summary>
  195.88 +        public string Label { get; set; }
  195.89 +
  195.90 +        /// <summary>
  195.91 +        /// Gets or sets Value.
  195.92 +        /// </summary>
  195.93 +        public double Value { get; set; }
  195.94 +
  195.95 +        /// <summary>
  195.96 +        /// Gets or sets the default fill color.
  195.97 +        /// </summary>
  195.98 +        /// <value>The default fill color.</value>
  195.99 +        internal OxyColor DefaultFillColor { get; set; }
 195.100 +
 195.101 +    }
 195.102 +}
 195.103 \ No newline at end of file
   196.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   196.2 +++ b/External/OxyPlot/OxyPlot/Series/PlotSeriesBase.cs	Sat Jun 08 16:53:22 2013 +0000
   196.3 @@ -0,0 +1,302 @@
   196.4 +// --------------------------------------------------------------------------------------------------------------------
   196.5 +// <copyright file="PlotSeriesBase.cs" company="OxyPlot">
   196.6 +//   The MIT License (MIT)
   196.7 +//
   196.8 +//   Copyright (c) 2012 Oystein Bjorke
   196.9 +//
  196.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  196.11 +//   copy of this software and associated documentation files (the
  196.12 +//   "Software"), to deal in the Software without restriction, including
  196.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  196.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  196.15 +//   permit persons to whom the Software is furnished to do so, subject to
  196.16 +//   the following conditions:
  196.17 +//
  196.18 +//   The above copyright notice and this permission notice shall be included
  196.19 +//   in all copies or substantial portions of the Software.
  196.20 +//
  196.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  196.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  196.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  196.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  196.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  196.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  196.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  196.28 +// </copyright>
  196.29 +// <summary>
  196.30 +//   Abstract base class for Series that contains an X-axis and Y-axis
  196.31 +// </summary>
  196.32 +// --------------------------------------------------------------------------------------------------------------------
  196.33 +namespace OxyPlot
  196.34 +{
  196.35 +    using System;
  196.36 +    using System.Collections;
  196.37 +    using System.Collections.Generic;
  196.38 +    using System.Collections.ObjectModel;
  196.39 +    using System.Linq;
  196.40 +
  196.41 +    /// <summary>
  196.42 +    /// Abstract base class for Series that contains an X-axis and Y-axis
  196.43 +    /// </summary>
  196.44 +    public abstract class PlotSeriesBase : ItemsSeries
  196.45 +    {
  196.46 +        /// <summary>
  196.47 +        /// Gets or sets the maximum x-coordinate of the dataset.
  196.48 +        /// </summary>
  196.49 +        /// <value>The maximum x-coordinate.</value>
  196.50 +        public double MaxX { get; protected set; }
  196.51 +
  196.52 +        /// <summary>
  196.53 +        /// Gets or sets the maximum y-coordinate of the dataset.
  196.54 +        /// </summary>
  196.55 +        /// <value>The maximum y-coordinate.</value>
  196.56 +        public double MaxY { get; protected set; }
  196.57 +
  196.58 +        /// <summary>
  196.59 +        /// Gets or sets the minimum x-coordinate of the dataset.
  196.60 +        /// </summary>
  196.61 +        /// <value>The minimum x-coordinate.</value>
  196.62 +        public double MinX { get; protected set; }
  196.63 +
  196.64 +        /// <summary>
  196.65 +        /// Gets or sets the minimum y-coordinate of the dataset.
  196.66 +        /// </summary>
  196.67 +        /// <value>The minimum y-coordinate.</value>
  196.68 +        public double MinY { get; protected set; }
  196.69 +
  196.70 +        /// <summary>
  196.71 +        /// Gets or sets the x-axis.
  196.72 +        /// </summary>
  196.73 +        /// <value>The x-axis.</value>
  196.74 +        public IAxis XAxis { get; set; }
  196.75 +
  196.76 +        /// <summary>
  196.77 +        /// Gets or sets the x-axis key.
  196.78 +        /// </summary>
  196.79 +        /// <value>The x-axis key.</value>
  196.80 +        public string XAxisKey { get; set; }
  196.81 +
  196.82 +        /// <summary>
  196.83 +        /// Gets or sets the y-axis.
  196.84 +        /// </summary>
  196.85 +        /// <value>The y-axis.</value>
  196.86 +        public IAxis YAxis { get; set; }
  196.87 +
  196.88 +        /// <summary>
  196.89 +        /// Gets or sets the y-axis key.
  196.90 +        /// </summary>
  196.91 +        /// <value>The y-axis key.</value>
  196.92 +        public string YAxisKey { get; set; }
  196.93 +
  196.94 +        /// <summary>
  196.95 +        /// Check if this data series requires X/Y axes.
  196.96 +        /// (e.g. Pie series do not require axes)
  196.97 +        /// </summary>
  196.98 +        /// <returns></returns>
  196.99 +        public override bool AreAxesRequired()
 196.100 +        {
 196.101 +            return true;
 196.102 +        }
 196.103 +
 196.104 +        public override void EnsureAxes(Collection<IAxis> axes, IAxis defaultXAxis, IAxis defaultYAxis)
 196.105 +        {
 196.106 +            if (this.XAxisKey != null)
 196.107 +            {
 196.108 +                this.XAxis = axes.FirstOrDefault(a => a.Key == this.XAxisKey);
 196.109 +            }
 196.110 +
 196.111 +            if (this.YAxisKey != null)
 196.112 +            {
 196.113 +                this.YAxis = axes.FirstOrDefault(a => a.Key == this.YAxisKey);
 196.114 +            }
 196.115 +
 196.116 +            // If axes are not found, use the default axes
 196.117 +            if (this.XAxis == null)
 196.118 +            {
 196.119 +                this.XAxis = defaultXAxis;
 196.120 +            }
 196.121 +
 196.122 +            if (this.YAxis == null)
 196.123 +            {
 196.124 +                this.YAxis = defaultYAxis;
 196.125 +            }
 196.126 +        }
 196.127 +
 196.128 +        /// <summary>
 196.129 +        /// Gets the rectangle the series uses on the screen (screen coordinates).
 196.130 +        /// </summary>
 196.131 +        /// <returns></returns>
 196.132 +        public OxyRect GetScreenRectangle()
 196.133 +        {
 196.134 +            return this.GetClippingRect();
 196.135 +        }
 196.136 +
 196.137 +        public override bool IsUsing(IAxis axis)
 196.138 +        {
 196.139 +            return this.XAxis == axis || this.YAxis == axis;
 196.140 +        }
 196.141 +
 196.142 +        /// <summary>
 196.143 +        /// Renders the Series on the specified rendering context.
 196.144 +        /// </summary>
 196.145 +        /// <param name = "rc">The rendering context.</param>
 196.146 +        /// <param name = "model">The model.</param>
 196.147 +        public override void Render(IRenderContext rc, PlotModel model)
 196.148 +        {
 196.149 +        }
 196.150 +
 196.151 +        /// <summary>
 196.152 +        /// Renders the legend symbol on the specified rendering context.
 196.153 +        /// </summary>
 196.154 +        /// <param name = "rc">The rendering context.</param>
 196.155 +        /// <param name = "legendBox">The legend rectangle.</param>
 196.156 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 196.157 +        {
 196.158 +        }
 196.159 +
 196.160 +        public override void SetDefaultValues(PlotModel model)
 196.161 +        {
 196.162 +        }
 196.163 +
 196.164 +        public override void UpdateData()
 196.165 +        {
 196.166 +        }
 196.167 +
 196.168 +        /// <summary>
 196.169 +        /// Updates the max/minimum values.
 196.170 +        /// </summary>
 196.171 +        public override void UpdateMaxMin()
 196.172 +        {
 196.173 +            this.MinX = this.MinY = this.MaxX = this.MaxY = double.NaN;
 196.174 +        }
 196.175 +
 196.176 +        protected OxyRect GetClippingRect()
 196.177 +        {
 196.178 +            double minX = Math.Min(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
 196.179 +            double minY = Math.Min(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
 196.180 +            double maxX = Math.Max(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
 196.181 +            double maxY = Math.Max(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
 196.182 +
 196.183 +            return new OxyRect(minX, minY, maxX - minX, maxY - minY);
 196.184 +        }
 196.185 +
 196.186 +        /// <summary>
 196.187 +        /// Gets the point on the curve that is nearest the specified point.
 196.188 +        /// </summary>
 196.189 +        /// <param name = "point">The point.</param>
 196.190 +        /// <param name = "dpn">The nearest point (data coordinates).</param>
 196.191 +        /// <param name = "spn">The nearest point (screen coordinates).</param>
 196.192 +        /// <returns></returns>
 196.193 +        protected bool GetNearestInterpolatedPointInternal(
 196.194 +            IList<IDataPoint> points, ScreenPoint point, out DataPoint dpn, out ScreenPoint spn, out int index)
 196.195 +        {
 196.196 +            spn = default(ScreenPoint);
 196.197 +            dpn = default(DataPoint);
 196.198 +            index = -1;
 196.199 +
 196.200 +            // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
 196.201 +            double minimumDistance = double.MaxValue;
 196.202 +
 196.203 +            for (int i = 0; i + 1 < points.Count; i++)
 196.204 +            {
 196.205 +                IDataPoint p1 = points[i];
 196.206 +                IDataPoint p2 = points[i + 1];
 196.207 +                ScreenPoint sp1 = AxisBase.Transform(p1, this.XAxis, this.YAxis);
 196.208 +                ScreenPoint sp2 = AxisBase.Transform(p2, this.XAxis, this.YAxis);
 196.209 +
 196.210 +                double sp21X = sp2.x - sp1.x;
 196.211 +                double sp21Y = sp2.y - sp1.y;
 196.212 +                double u1 = (point.x - sp1.x) * sp21X + (point.y - sp1.y) * sp21Y;
 196.213 +                double u2 = sp21X * sp21X + sp21Y * sp21Y;
 196.214 +                double ds = sp21X * sp21X + sp21Y * sp21Y;
 196.215 +
 196.216 +                if (ds < 4)
 196.217 +                {
 196.218 +                    // if the points are very close, we can get numerical problems, just use the first point...
 196.219 +                    u1 = 0;
 196.220 +                    u2 = 1;
 196.221 +                }
 196.222 +
 196.223 +                if (u2 < double.Epsilon && u2 > -double.Epsilon)
 196.224 +                {
 196.225 +                    continue; // P1 && P2 coincident
 196.226 +                }
 196.227 +
 196.228 +                double u = u1 / u2;
 196.229 +                if (u < 0) u = 0;
 196.230 +                if (u > 1) u = 1;
 196.231 +
 196.232 +                double sx = sp1.x + u * sp21X;
 196.233 +                double sy = sp1.y + u * sp21Y;
 196.234 +
 196.235 +                double dx = point.x - sx;
 196.236 +                double dy = point.y - sy;
 196.237 +                double distance = dx * dx + dy * dy;
 196.238 +
 196.239 +                if (distance < minimumDistance)
 196.240 +                {
 196.241 +                    double px = p1.X + u * (p2.X - p1.X);
 196.242 +                    double py = p1.Y + u * (p2.Y - p1.Y);
 196.243 +                    dpn = new DataPoint(px, py);
 196.244 +                    spn = new ScreenPoint(sx, sy);
 196.245 +                    minimumDistance = distance;
 196.246 +                    index = i;
 196.247 +                }
 196.248 +            }
 196.249 +
 196.250 +            return minimumDistance < double.MaxValue;
 196.251 +        }
 196.252 +
 196.253 +        protected bool GetNearestPointInternal(
 196.254 +            IEnumerable<IDataPoint> points, ScreenPoint point, out DataPoint dpn, out ScreenPoint spn, out int index)
 196.255 +        {
 196.256 +            spn = default(ScreenPoint);
 196.257 +            dpn = default(DataPoint);
 196.258 +            index = -1;
 196.259 +
 196.260 +            double minimumDistance = double.MaxValue;
 196.261 +            int i = 0;
 196.262 +            foreach (DataPoint p in points)
 196.263 +            {
 196.264 +                ScreenPoint sp = AxisBase.Transform(p, this.XAxis, this.YAxis);
 196.265 +                double dx = sp.x - point.x;
 196.266 +                double dy = sp.y - point.y;
 196.267 +                double d2 = dx * dx + dy * dy;
 196.268 +
 196.269 +                if (d2 < minimumDistance)
 196.270 +                {
 196.271 +                    dpn = p;
 196.272 +                    spn = sp;
 196.273 +                    minimumDistance = d2;
 196.274 +                    index = i;
 196.275 +                }
 196.276 +                i++;
 196.277 +            }
 196.278 +
 196.279 +            return minimumDistance < double.MaxValue;
 196.280 +        }
 196.281 +
 196.282 +        /// <summary>
 196.283 +        /// Converts the value of the specified object to a double precision floating point number.
 196.284 +        /// DateTime objects are converted using DateTimeAxis.ToDouble
 196.285 +        /// TimeSpan objects are converted using TimeSpanAxis.ToDouble
 196.286 +        /// </summary>
 196.287 +        /// <param name="value">The value.</param>
 196.288 +        /// <returns></returns>
 196.289 +        protected virtual double ToDouble(object value)
 196.290 +        {
 196.291 +            if (value is DateTime)
 196.292 +            {
 196.293 +                return DateTimeAxis.ToDouble((DateTime)value);
 196.294 +            }
 196.295 +
 196.296 +            if (value is TimeSpan)
 196.297 +            {
 196.298 +                return ((TimeSpan)value).TotalSeconds;
 196.299 +            }
 196.300 +
 196.301 +            return Convert.ToDouble(value);
 196.302 +        }
 196.303 +
 196.304 +    }
 196.305 +}
 196.306 \ No newline at end of file
   197.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   197.2 +++ b/External/OxyPlot/OxyPlot/Series/ScatterPoint.cs	Sat Jun 08 16:53:22 2013 +0000
   197.3 @@ -0,0 +1,232 @@
   197.4 +// --------------------------------------------------------------------------------------------------------------------
   197.5 +// <copyright file="ScatterPoint.cs" company="OxyPlot">
   197.6 +//   The MIT License (MIT)
   197.7 +//
   197.8 +//   Copyright (c) 2012 Oystein Bjorke
   197.9 +//
  197.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  197.11 +//   copy of this software and associated documentation files (the
  197.12 +//   "Software"), to deal in the Software without restriction, including
  197.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  197.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  197.15 +//   permit persons to whom the Software is furnished to do so, subject to
  197.16 +//   the following conditions:
  197.17 +//
  197.18 +//   The above copyright notice and this permission notice shall be included
  197.19 +//   in all copies or substantial portions of the Software.
  197.20 +//
  197.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  197.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  197.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  197.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  197.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  197.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  197.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  197.28 +// </copyright>
  197.29 +// <summary>
  197.30 +//   Represents a point in a ScatterSeries.
  197.31 +// </summary>
  197.32 +// --------------------------------------------------------------------------------------------------------------------
  197.33 +namespace OxyPlot.Series
  197.34 +{
  197.35 +    using System.Diagnostics.CodeAnalysis;
  197.36 +
  197.37 +    /// <summary>
  197.38 +    /// Represents a point in a <see cref="ScatterSeries"/>.
  197.39 +    /// </summary>
  197.40 +    public class ScatterPoint : IDataPoint
  197.41 +    {
  197.42 +        // ReSharper disable InconsistentNaming
  197.43 +
  197.44 +        /// <summary>
  197.45 +        /// The size.
  197.46 +        /// </summary>
  197.47 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
  197.48 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
  197.49 +        internal double size;
  197.50 +
  197.51 +        /// <summary>
  197.52 +        /// The tag.
  197.53 +        /// </summary>
  197.54 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
  197.55 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
  197.56 +        internal object tag;
  197.57 +
  197.58 +        /// <summary>
  197.59 +        /// The value.
  197.60 +        /// </summary>
  197.61 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
  197.62 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
  197.63 +        internal double value;
  197.64 +
  197.65 +        /// <summary>
  197.66 +        /// The x.
  197.67 +        /// </summary>
  197.68 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
  197.69 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
  197.70 +        internal double x;
  197.71 +
  197.72 +        /// <summary>
  197.73 +        /// The y.
  197.74 +        /// </summary>
  197.75 +        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
  197.76 +        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
  197.77 +        internal double y;
  197.78 +
  197.79 +        // ReSharper restore InconsistentNaming
  197.80 +        /// <summary>
  197.81 +        /// Initializes a new instance of the <see cref="ScatterPoint"/> class.
  197.82 +        /// </summary>
  197.83 +        public ScatterPoint()
  197.84 +        {
  197.85 +            this.Size = double.NaN;
  197.86 +            this.Value = double.NaN;
  197.87 +        }
  197.88 +
  197.89 +        /// <summary>
  197.90 +        /// Initializes a new instance of the <see cref="ScatterPoint"/> class.
  197.91 +        /// </summary>
  197.92 +        /// <param name="x">
  197.93 +        /// The x.
  197.94 +        /// </param>
  197.95 +        /// <param name="y">
  197.96 +        /// The y.
  197.97 +        /// </param>
  197.98 +        /// <param name="size">
  197.99 +        /// The size.
 197.100 +        /// </param>
 197.101 +        /// <param name="value">
 197.102 +        /// The value.
 197.103 +        /// </param>
 197.104 +        /// <param name="tag">
 197.105 +        /// The tag.
 197.106 +        /// </param>
 197.107 +        public ScatterPoint(double x, double y, double size = double.NaN, double value = double.NaN, object tag = null)
 197.108 +        {
 197.109 +            this.x = x;
 197.110 +            this.y = y;
 197.111 +            this.size = size;
 197.112 +            this.value = value;
 197.113 +            this.tag = tag;
 197.114 +        }
 197.115 +
 197.116 +        /// <summary>
 197.117 +        /// Gets or sets the size.
 197.118 +        /// </summary>
 197.119 +        /// <value>The size.</value>
 197.120 +        public double Size
 197.121 +        {
 197.122 +            get
 197.123 +            {
 197.124 +                return this.size;
 197.125 +            }
 197.126 +
 197.127 +            set
 197.128 +            {
 197.129 +                this.size = value;
 197.130 +            }
 197.131 +        }
 197.132 +
 197.133 +        /// <summary>
 197.134 +        /// Gets or sets the tag.
 197.135 +        /// </summary>
 197.136 +        /// <value>The tag.</value>
 197.137 +        public object Tag
 197.138 +        {
 197.139 +            get
 197.140 +            {
 197.141 +                return this.tag;
 197.142 +            }
 197.143 +
 197.144 +            set
 197.145 +            {
 197.146 +                this.tag = value;
 197.147 +            }
 197.148 +        }
 197.149 +
 197.150 +        /// <summary>
 197.151 +        /// Gets or sets the value.
 197.152 +        /// </summary>
 197.153 +        /// <value>The value.</value>
 197.154 +        public double Value
 197.155 +        {
 197.156 +            get
 197.157 +            {
 197.158 +                return this.value;
 197.159 +            }
 197.160 +
 197.161 +            set
 197.162 +            {
 197.163 +                this.value = value;
 197.164 +            }
 197.165 +        }
 197.166 +
 197.167 +        /// <summary>
 197.168 +        /// Gets or sets the X.
 197.169 +        /// </summary>
 197.170 +        /// <value>The X.</value>
 197.171 +        public double X
 197.172 +        {
 197.173 +            get
 197.174 +            {
 197.175 +                return this.x;
 197.176 +            }
 197.177 +
 197.178 +            set
 197.179 +            {
 197.180 +                this.x = value;
 197.181 +            }
 197.182 +        }
 197.183 +
 197.184 +        /// <summary>
 197.185 +        /// Gets or sets the Y.
 197.186 +        /// </summary>
 197.187 +        /// <value>The Y.</value>
 197.188 +        public double Y
 197.189 +        {
 197.190 +            get
 197.191 +            {
 197.192 +                return this.y;
 197.193 +            }
 197.194 +
 197.195 +            set
 197.196 +            {
 197.197 +                this.y = value;
 197.198 +            }
 197.199 +        }
 197.200 +
 197.201 +        /// <summary>
 197.202 +        /// Returns C# code that generates this instance.
 197.203 +        /// </summary>
 197.204 +        /// <returns>
 197.205 +        /// C# code.
 197.206 +        /// </returns>
 197.207 +        public string ToCode()
 197.208 +        {
 197.209 +            if (double.IsNaN(this.size) && double.IsNaN(this.value))
 197.210 +            {
 197.211 +                return CodeGenerator.FormatConstructor(this.GetType(), "{0}, {1}", this.x, this.y);
 197.212 +            }
 197.213 +
 197.214 +            if (double.IsNaN(this.value))
 197.215 +            {
 197.216 +                return CodeGenerator.FormatConstructor(this.GetType(), "{0}, {1}, {2}", this.x, this.y, this.size);
 197.217 +            }
 197.218 +
 197.219 +            return CodeGenerator.FormatConstructor(
 197.220 +                this.GetType(), "{0}, {1}, {2}, {3}", this.x, this.y, this.size, this.value);
 197.221 +        }
 197.222 +
 197.223 +        /// <summary>
 197.224 +        /// Returns a <see cref="System.String"/> that represents this instance.
 197.225 +        /// </summary>
 197.226 +        /// <returns>
 197.227 +        /// A <see cref="System.String"/> that represents this instance.
 197.228 +        /// </returns>
 197.229 +        public override string ToString()
 197.230 +        {
 197.231 +            return this.x + " " + this.y;
 197.232 +        }
 197.233 +
 197.234 +    }
 197.235 +}
 197.236 \ No newline at end of file
   198.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   198.2 +++ b/External/OxyPlot/OxyPlot/Series/ScatterSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   198.3 @@ -0,0 +1,621 @@
   198.4 +// --------------------------------------------------------------------------------------------------------------------
   198.5 +// <copyright file="ScatterSeries.cs" company="OxyPlot">
   198.6 +//   The MIT License (MIT)
   198.7 +//   
   198.8 +//   Copyright (c) 2012 Oystein Bjorke
   198.9 +//   
  198.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  198.11 +//   copy of this software and associated documentation files (the
  198.12 +//   "Software"), to deal in the Software without restriction, including
  198.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  198.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  198.15 +//   permit persons to whom the Software is furnished to do so, subject to
  198.16 +//   the following conditions:
  198.17 +//   
  198.18 +//   The above copyright notice and this permission notice shall be included
  198.19 +//   in all copies or substantial portions of the Software.
  198.20 +//   
  198.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  198.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  198.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  198.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  198.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  198.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  198.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  198.28 +// </copyright>
  198.29 +// <summary>
  198.30 +//   Represents a series for scatter plots.
  198.31 +// </summary>
  198.32 +// --------------------------------------------------------------------------------------------------------------------
  198.33 +
  198.34 +namespace OxyPlot.Series
  198.35 +{
  198.36 +    using System;
  198.37 +    using System.Collections;
  198.38 +    using System.Collections.Generic;
  198.39 +
  198.40 +    using OxyPlot.Axes;
  198.41 +
  198.42 +    /// <summary>
  198.43 +    /// Represents a series for scatter plots.
  198.44 +    /// </summary>
  198.45 +    /// <remarks>
  198.46 +    /// See http://en.wikipedia.org/wiki/Scatter_plot
  198.47 +    /// </remarks>
  198.48 +    public class ScatterSeries : DataPointSeries
  198.49 +    {
  198.50 +        /// <summary>
  198.51 +        /// The default fill color.
  198.52 +        /// </summary>
  198.53 +        private OxyColor defaultMarkerFillColor;
  198.54 +
  198.55 +        /// <summary>
  198.56 +        /// Initializes a new instance of the <see cref="ScatterSeries"/> class.
  198.57 +        /// </summary>
  198.58 +        /// <param name="title">
  198.59 +        /// The title.
  198.60 +        /// </param>
  198.61 +        /// <param name="markerFill">
  198.62 +        /// The marker fill color.
  198.63 +        /// </param>
  198.64 +        /// <param name="markerSize">
  198.65 +        /// Size of the markers (If ScatterPoint.Size is set, this value will be overridden).
  198.66 +        /// </param>
  198.67 +        public ScatterSeries(string title, OxyColor markerFill = null, double markerSize = 5)
  198.68 +            : this()
  198.69 +        {
  198.70 +            this.MarkerFill = markerFill;
  198.71 +            this.MarkerSize = markerSize;
  198.72 +            this.Title = title;
  198.73 +        }
  198.74 +
  198.75 +        /// <summary>
  198.76 +        /// Initializes a new instance of the <see cref="ScatterSeries"/> class.
  198.77 +        /// </summary>
  198.78 +        public ScatterSeries()
  198.79 +        {
  198.80 +            this.DataFieldSize = null;
  198.81 +            this.DataFieldValue = null;
  198.82 +
  198.83 +            this.MarkerFill = null;
  198.84 +            this.MarkerSize = 5;
  198.85 +            this.MarkerType = MarkerType.Square;
  198.86 +            this.MarkerStroke = null;
  198.87 +            this.MarkerStrokeThickness = 1.0;
  198.88 +        }
  198.89 +
  198.90 +        /// <summary>
  198.91 +        /// Gets or sets the screen resolution. If this number is greater than 1, bins of that size is created for both x and y directions. Only one point will be drawn in each bin.
  198.92 +        /// </summary>
  198.93 +        public int BinSize { get; set; }
  198.94 +
  198.95 +        /// <summary>
  198.96 +        /// Gets or sets the color map.
  198.97 +        /// </summary>
  198.98 +        /// <value> The color map. </value>
  198.99 +        /// <remarks>
 198.100 +        /// This is used to map scatter point values to colors.
 198.101 +        /// </remarks>
 198.102 +        public ColorAxis ColorAxis { get; set; }
 198.103 +
 198.104 +        /// <summary>
 198.105 +        /// Gets or sets the color axis key.
 198.106 +        /// </summary>
 198.107 +        /// <value> The color axis key. </value>
 198.108 +        public string ColorAxisKey { get; set; }
 198.109 +
 198.110 +        /// <summary>
 198.111 +        /// Gets or sets the data field for the size.
 198.112 +        /// </summary>
 198.113 +        /// <value> The size data field. </value>
 198.114 +        public string DataFieldSize { get; set; }
 198.115 +
 198.116 +        /// <summary>
 198.117 +        /// Gets or sets the tag data field.
 198.118 +        /// </summary>
 198.119 +        /// <value> The tag data field. </value>
 198.120 +        public string DataFieldTag { get; set; }
 198.121 +
 198.122 +        /// <summary>
 198.123 +        /// Gets or sets the value data field.
 198.124 +        /// </summary>
 198.125 +        /// <value> The value data field. </value>
 198.126 +        public string DataFieldValue { get; set; }
 198.127 +
 198.128 +        /// <summary>
 198.129 +        /// Gets or sets the marker fill color. If null, this color will be automatically set.
 198.130 +        /// </summary>
 198.131 +        /// <value> The marker fill color. </value>
 198.132 +        public OxyColor MarkerFill { get; set; }
 198.133 +
 198.134 +        /// <summary>
 198.135 +        /// Gets the actual fill color.
 198.136 +        /// </summary>
 198.137 +        /// <value>The actual color.</value>
 198.138 +        public OxyColor ActualMarkerFillColor
 198.139 +        {
 198.140 +            get { return this.MarkerFill ?? this.defaultMarkerFillColor; }
 198.141 +        }
 198.142 +
 198.143 +        /// <summary>
 198.144 +        /// Gets or sets the marker outline polygon. Set MarkerType to Custom to use this.
 198.145 +        /// </summary>
 198.146 +        /// <value> The marker outline. </value>
 198.147 +        public ScreenPoint[] MarkerOutline { get; set; }
 198.148 +
 198.149 +        /// <summary>
 198.150 +        /// Gets or sets the size of the marker (same size for all items).
 198.151 +        /// </summary>
 198.152 +        /// <value> The size of the markers. </value>
 198.153 +        public double MarkerSize { get; set; }
 198.154 +
 198.155 +        /// <summary>
 198.156 +        /// Gets or sets the marker stroke.
 198.157 +        /// </summary>
 198.158 +        /// <value> The marker stroke. </value>
 198.159 +        public OxyColor MarkerStroke { get; set; }
 198.160 +
 198.161 +        /// <summary>
 198.162 +        /// Gets or sets the marker stroke thickness.
 198.163 +        /// </summary>
 198.164 +        /// <value> The marker stroke thickness. </value>
 198.165 +        public double MarkerStrokeThickness { get; set; }
 198.166 +
 198.167 +        /// <summary>
 198.168 +        /// Gets or sets the type of the marker.
 198.169 +        /// </summary>
 198.170 +        /// <value> The type of the marker. </value>
 198.171 +        /// <remarks>
 198.172 +        /// If MarkerType.Custom is used, the MarkerOutline property must be specified.
 198.173 +        /// </remarks>
 198.174 +        public MarkerType MarkerType { get; set; }
 198.175 +
 198.176 +        /// <summary>
 198.177 +        /// Gets the max value of the points.
 198.178 +        /// </summary>
 198.179 +        public double MaxValue { get; private set; }
 198.180 +
 198.181 +        /// <summary>
 198.182 +        /// Gets the min value of the points.
 198.183 +        /// </summary>
 198.184 +        public double MinValue { get; private set; }
 198.185 +
 198.186 +        /// <summary>
 198.187 +        /// Gets the nearest point.
 198.188 +        /// </summary>
 198.189 +        /// <param name="point">
 198.190 +        /// The point.
 198.191 +        /// </param>
 198.192 +        /// <param name="interpolate">
 198.193 +        /// interpolate if set to <c>true</c> .
 198.194 +        /// </param>
 198.195 +        /// <returns>
 198.196 +        /// A TrackerHitResult for the current hit.
 198.197 +        /// </returns>
 198.198 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 198.199 +        {
 198.200 +            if (this.XAxis == null || this.YAxis == null)
 198.201 +            {
 198.202 +                return null;
 198.203 +            }
 198.204 +
 198.205 +            if (interpolate)
 198.206 +            {
 198.207 +                return null;
 198.208 +            }
 198.209 +
 198.210 +            TrackerHitResult result = null;
 198.211 +            double minimumDistance = double.MaxValue;
 198.212 +            int i = 0;
 198.213 +
 198.214 +            var xaxisTitle = this.XAxis.Title ?? "X";
 198.215 +            var yaxisTitle = this.YAxis.Title ?? "Y";
 198.216 +            var colorAxisTitle = (this.ColorAxis != null ? this.ColorAxis.Title : null) ?? "Z";
 198.217 +
 198.218 +            var formatString = TrackerFormatString;
 198.219 +            if (string.IsNullOrEmpty(this.TrackerFormatString))
 198.220 +            {
 198.221 +                // Create a default format string
 198.222 +                formatString = "{1}: {2}\n{3}: {4}";
 198.223 +                if (this.ColorAxis != null)
 198.224 +                {
 198.225 +                    formatString += "\n{5}: {6}";
 198.226 +                }
 198.227 +            }
 198.228 +
 198.229 +            foreach (var p in this.Points)
 198.230 +            {
 198.231 +                if (p.X < this.XAxis.ActualMinimum || p.X > this.XAxis.ActualMaximum || p.Y < this.YAxis.ActualMinimum || p.Y > this.YAxis.ActualMaximum)
 198.232 +                {
 198.233 +                    i++;
 198.234 +                    continue;
 198.235 +                }
 198.236 +
 198.237 +                var dp = new DataPoint(p.X, p.Y);
 198.238 +                var sp = Axis.Transform(dp, this.XAxis, this.YAxis);
 198.239 +                double dx = sp.x - point.x;
 198.240 +                double dy = sp.y - point.y;
 198.241 +                double d2 = (dx * dx) + (dy * dy);
 198.242 +
 198.243 +                if (d2 < minimumDistance)
 198.244 +                {
 198.245 +                    var item = this.GetItem(i);
 198.246 +
 198.247 +                    object xvalue = this.XAxis.GetValue(dp.X);
 198.248 +                    object yvalue = this.YAxis.GetValue(dp.Y);
 198.249 +                    object zvalue = null;
 198.250 +
 198.251 +                    var scatterPoint = p as ScatterPoint;
 198.252 +                    if (scatterPoint != null)
 198.253 +                    {
 198.254 +                        if (!double.IsNaN(scatterPoint.Value) && !double.IsInfinity(scatterPoint.Value))
 198.255 +                        {
 198.256 +                            zvalue = scatterPoint.Value;
 198.257 +                        }
 198.258 +                    }
 198.259 +
 198.260 +                    var text = StringHelper.Format(
 198.261 +                        this.ActualCulture,
 198.262 +                        formatString,
 198.263 +                        item,
 198.264 +                        this.Title,
 198.265 +                        xaxisTitle,
 198.266 +                        xvalue,
 198.267 +                        yaxisTitle,
 198.268 +                        yvalue,
 198.269 +                        colorAxisTitle,
 198.270 +                        zvalue);
 198.271 +
 198.272 +                    result = new TrackerHitResult(this, dp, sp, item, i, text);
 198.273 +
 198.274 +                    minimumDistance = d2;
 198.275 +                }
 198.276 +
 198.277 +                i++;
 198.278 +            }
 198.279 +
 198.280 +            return result;
 198.281 +        }
 198.282 +
 198.283 +        /// <summary>
 198.284 +        /// Determines whether the specified point is valid.
 198.285 +        /// </summary>
 198.286 +        /// <param name="pt">
 198.287 +        /// The point.
 198.288 +        /// </param>
 198.289 +        /// <param name="xaxis">
 198.290 +        /// The x axis.
 198.291 +        /// </param>
 198.292 +        /// <param name="yaxis">
 198.293 +        /// The y axis.
 198.294 +        /// </param>
 198.295 +        /// <returns>
 198.296 +        /// <c>true</c> if the point is valid; otherwise, <c>false</c> .
 198.297 +        /// </returns>
 198.298 +        public virtual bool IsValidPoint(ScatterPoint pt, Axis xaxis, Axis yaxis)
 198.299 +        {
 198.300 +            return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y)
 198.301 +                   && (xaxis != null && xaxis.IsValidValue(pt.X)) && (yaxis != null && yaxis.IsValidValue(pt.Y));
 198.302 +        }
 198.303 +
 198.304 +        /// <summary>
 198.305 +        /// Renders the series on the specified rendering context.
 198.306 +        /// </summary>
 198.307 +        /// <param name="rc">
 198.308 +        /// The rendering context.
 198.309 +        /// </param>
 198.310 +        /// <param name="model">
 198.311 +        /// The owner plot model.
 198.312 +        /// </param>
 198.313 +        public override void Render(IRenderContext rc, PlotModel model)
 198.314 +        {
 198.315 +            if (this.Points.Count == 0)
 198.316 +            {
 198.317 +                return;
 198.318 +            }
 198.319 +
 198.320 +            OxyRect clippingRect = this.GetClippingRect();
 198.321 +
 198.322 +            var points = this.Points;
 198.323 +            int n = points.Count;
 198.324 +            var groupPoints = new Dictionary<int, IList<ScreenPoint>>();
 198.325 +            var groupSizes = new Dictionary<int, IList<double>>();
 198.326 +
 198.327 +            ScreenPoint[] allPoints = null;
 198.328 +            double[] markerSizes = null;
 198.329 +
 198.330 +            if (this.ColorAxis == null)
 198.331 +            {
 198.332 +                allPoints = new ScreenPoint[n];
 198.333 +                markerSizes = new double[n];
 198.334 +            }
 198.335 +
 198.336 +            // Transform all points to screen coordinates
 198.337 +            for (int i = 0; i < n; i++)
 198.338 +            {
 198.339 +                var dp = new DataPoint(points[i].X, points[i].Y);
 198.340 +                double size = double.NaN;
 198.341 +                double value = double.NaN;
 198.342 +
 198.343 +                var scatterPoint = points[i] as ScatterPoint;
 198.344 +                if (scatterPoint != null)
 198.345 +                {
 198.346 +                    size = scatterPoint.Size;
 198.347 +                    value = scatterPoint.Value;
 198.348 +                }
 198.349 +
 198.350 +                if (double.IsNaN(size))
 198.351 +                {
 198.352 +                    size = this.MarkerSize;
 198.353 +                }
 198.354 +
 198.355 +                var screenPoint = this.XAxis.Transform(dp.X, dp.Y, this.YAxis);
 198.356 +
 198.357 +                if (this.ColorAxis != null)
 198.358 +                {
 198.359 +                    if (!double.IsNaN(value))
 198.360 +                    {
 198.361 +                        int group = this.ColorAxis.GetPaletteIndex(value);
 198.362 +                        if (!groupPoints.ContainsKey(group))
 198.363 +                        {
 198.364 +                            groupPoints.Add(group, new List<ScreenPoint>());
 198.365 +                            groupSizes.Add(group, new List<double>());
 198.366 +                        }
 198.367 +
 198.368 +                        groupPoints[group].Add(screenPoint);
 198.369 +                        groupSizes[group].Add(size);
 198.370 +                    }
 198.371 +                }
 198.372 +                else
 198.373 +                {
 198.374 +                    // ReSharper disable PossibleNullReferenceException
 198.375 +                    allPoints[i] = screenPoint;
 198.376 +                    markerSizes[i] = size;
 198.377 +                    // ReSharper restore PossibleNullReferenceException
 198.378 +                }
 198.379 +            }
 198.380 +
 198.381 +            var binOffset = this.XAxis.Transform(this.MinX, this.MaxY, this.YAxis);
 198.382 +
 198.383 +            // Draw the markers
 198.384 +            if (this.ColorAxis != null)
 198.385 +            {
 198.386 +                var markerIsStrokedOnly = this.MarkerType == MarkerType.Plus || this.MarkerType == MarkerType.Star
 198.387 +                                          || this.MarkerType == MarkerType.Cross;
 198.388 +                foreach (var group in groupPoints)
 198.389 +                {
 198.390 +                    var color = this.ColorAxis.GetColor(group.Key);
 198.391 +                    rc.DrawMarkers(
 198.392 +                        group.Value,
 198.393 +                        clippingRect,
 198.394 +                        this.MarkerType,
 198.395 +                        this.MarkerOutline,
 198.396 +                        groupSizes[group.Key],
 198.397 +                        color,
 198.398 +                        markerIsStrokedOnly ? color : this.MarkerStroke,
 198.399 +                        this.MarkerStrokeThickness,
 198.400 +                        this.BinSize,
 198.401 +                        binOffset);
 198.402 +                }
 198.403 +            }
 198.404 +            else
 198.405 +            {
 198.406 +                rc.DrawMarkers(
 198.407 +                    allPoints,
 198.408 +                    clippingRect,
 198.409 +                    this.MarkerType,
 198.410 +                    this.MarkerOutline,
 198.411 +                    markerSizes,
 198.412 +                    this.ActualMarkerFillColor,
 198.413 +                    this.MarkerStroke,
 198.414 +                    this.MarkerStrokeThickness,
 198.415 +                    this.BinSize,
 198.416 +                    binOffset);
 198.417 +            }
 198.418 +        }
 198.419 +
 198.420 +        /// <summary>
 198.421 +        /// Renders the legend symbol for the line series on the specified rendering context.
 198.422 +        /// </summary>
 198.423 +        /// <param name="rc">
 198.424 +        /// The rendering context.
 198.425 +        /// </param>
 198.426 +        /// <param name="legendBox">
 198.427 +        /// The bounding rectangle of the legend box.
 198.428 +        /// </param>
 198.429 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 198.430 +        {
 198.431 +            double xmid = (legendBox.Left + legendBox.Right) / 2;
 198.432 +            double ymid = (legendBox.Top + legendBox.Bottom) / 2;
 198.433 +
 198.434 +            var midpt = new ScreenPoint(xmid, ymid);
 198.435 +            rc.DrawMarker(
 198.436 +                midpt,
 198.437 +                legendBox,
 198.438 +                this.MarkerType,
 198.439 +                this.MarkerOutline,
 198.440 +                this.MarkerSize,
 198.441 +                this.ActualMarkerFillColor,
 198.442 +                this.MarkerStroke,
 198.443 +                this.MarkerStrokeThickness);
 198.444 +        }
 198.445 +
 198.446 +        /// <summary>
 198.447 +        /// Ensures that the axes of the series is defined.
 198.448 +        /// </summary>
 198.449 +        protected internal override void EnsureAxes()
 198.450 +        {
 198.451 +            base.EnsureAxes();
 198.452 +
 198.453 +            this.ColorAxis = PlotModel.GetAxisOrDefault(this.ColorAxisKey, PlotModel.DefaultColorAxis) as ColorAxis;
 198.454 +        }
 198.455 +
 198.456 +        /// <summary>
 198.457 +        /// Sets the default values.
 198.458 +        /// </summary>
 198.459 +        /// <param name="model">
 198.460 +        /// The model.
 198.461 +        /// </param>
 198.462 +        protected internal override void SetDefaultValues(PlotModel model)
 198.463 +        {
 198.464 +            if (this.MarkerFill == null)
 198.465 +            {
 198.466 +                this.defaultMarkerFillColor = model.GetDefaultColor();
 198.467 +            }
 198.468 +        }
 198.469 +
 198.470 +        /// <summary>
 198.471 +        /// The update data.
 198.472 +        /// </summary>
 198.473 +        protected internal override void UpdateData()
 198.474 +        {
 198.475 +            if (this.ItemsSource == null)
 198.476 +            {
 198.477 +                return;
 198.478 +            }
 198.479 +
 198.480 +            var points = this.Points;
 198.481 +            points.Clear();
 198.482 +
 198.483 +            // Use the mapping to generate the points
 198.484 +            if (this.Mapping != null)
 198.485 +            {
 198.486 +                foreach (var item in this.ItemsSource)
 198.487 +                {
 198.488 +                    points.Add(this.Mapping(item));
 198.489 +                }
 198.490 +
 198.491 +                return;
 198.492 +            }
 198.493 +
 198.494 +            // Get DataPoints from the items in ItemsSource
 198.495 +            // if they implement IScatterPointProvider
 198.496 +            // If DataFields are set, this is not used
 198.497 +            /*if (DataFieldX == null || DataFieldY == null)
 198.498 +            {
 198.499 +                foreach (var item in ItemsSource)
 198.500 +                {
 198.501 +                    var idpp = item as IScatterPointProvider;
 198.502 +                    if (idpp == null)
 198.503 +                    {
 198.504 +                        continue;
 198.505 +                    }
 198.506 +
 198.507 +                    points.Add(idpp.GetScatterPoint());
 198.508 +                }
 198.509 +
 198.510 +                return;
 198.511 +            }*/
 198.512 +
 198.513 +            var dest = new List<IDataPoint>();
 198.514 +
 198.515 +            // Using reflection to add points
 198.516 +            var filler = new ListFiller<ScatterPoint>();
 198.517 +            filler.Add(this.DataFieldX, (item, value) => item.X = Convert.ToDouble(value));
 198.518 +            filler.Add(this.DataFieldY, (item, value) => item.Y = Convert.ToDouble(value));
 198.519 +            filler.Add(this.DataFieldSize, (item, value) => item.Size = Convert.ToDouble(value));
 198.520 +            filler.Add(this.DataFieldValue, (item, value) => item.Value = Convert.ToDouble(value));
 198.521 +            filler.Add(this.DataFieldTag, (item, value) => item.Tag = value);
 198.522 +            filler.Fill(dest, this.ItemsSource);
 198.523 +
 198.524 +            this.Points = dest;
 198.525 +        }
 198.526 +
 198.527 +        /// <summary>
 198.528 +        /// Updates the max/min from the data points.
 198.529 +        /// </summary>
 198.530 +        protected internal override void UpdateMaxMin()
 198.531 +        {
 198.532 +            base.UpdateMaxMin();
 198.533 +            this.InternalUpdateMaxMinValue(this.Points);
 198.534 +        }
 198.535 +
 198.536 +        /// <summary>
 198.537 +        /// Adds scatter points specified by a items source and data fields.
 198.538 +        /// </summary>
 198.539 +        /// <param name="dest">
 198.540 +        /// The destination collection.
 198.541 +        /// </param>
 198.542 +        /// <param name="itemsSource">
 198.543 +        /// The items source.
 198.544 +        /// </param>
 198.545 +        /// <param name="dataFieldX">
 198.546 +        /// The data field x.
 198.547 +        /// </param>
 198.548 +        /// <param name="dataFieldY">
 198.549 +        /// The data field y.
 198.550 +        /// </param>
 198.551 +        /// <param name="dataFieldSize">
 198.552 +        /// The data field size.
 198.553 +        /// </param>
 198.554 +        /// <param name="dataFieldValue">
 198.555 +        /// The data field value.
 198.556 +        /// </param>
 198.557 +        /// <param name="dataFieldTag">
 198.558 +        /// The data field tag.
 198.559 +        /// </param>
 198.560 +        protected void AddScatterPoints(
 198.561 +            IList<ScatterPoint> dest,
 198.562 +            IEnumerable itemsSource,
 198.563 +            string dataFieldX,
 198.564 +            string dataFieldY,
 198.565 +            string dataFieldSize,
 198.566 +            string dataFieldValue,
 198.567 +            string dataFieldTag)
 198.568 +        {
 198.569 +            var filler = new ListFiller<ScatterPoint>();
 198.570 +            filler.Add(dataFieldX, (item, value) => item.X = Convert.ToDouble(value));
 198.571 +            filler.Add(dataFieldY, (item, value) => item.Y = Convert.ToDouble(value));
 198.572 +            filler.Add(dataFieldSize, (item, value) => item.Size = Convert.ToDouble(value));
 198.573 +            filler.Add(dataFieldValue, (item, value) => item.Value = Convert.ToDouble(value));
 198.574 +            filler.Add(dataFieldTag, (item, value) => item.Tag = value);
 198.575 +            filler.FillT(dest, itemsSource);
 198.576 +        }
 198.577 +
 198.578 +        /// <summary>
 198.579 +        /// Updates the Max/Min limits from the values in the specified point list.
 198.580 +        /// </summary>
 198.581 +        /// <param name="pts">
 198.582 +        /// The points.
 198.583 +        /// </param>
 198.584 +        protected void InternalUpdateMaxMinValue(IList<IDataPoint> pts)
 198.585 +        {
 198.586 +            if (pts == null || pts.Count == 0)
 198.587 +            {
 198.588 +                return;
 198.589 +            }
 198.590 +
 198.591 +            double minvalue = double.NaN;
 198.592 +            double maxvalue = double.NaN;
 198.593 +
 198.594 +            foreach (var pt in pts)
 198.595 +            {
 198.596 +                if (!(pt is ScatterPoint))
 198.597 +                {
 198.598 +                    continue;
 198.599 +                }
 198.600 +
 198.601 +                double value = ((ScatterPoint)pt).value;
 198.602 +
 198.603 +                if (value < minvalue || double.IsNaN(minvalue))
 198.604 +                {
 198.605 +                    minvalue = value;
 198.606 +                }
 198.607 +
 198.608 +                if (value > maxvalue || double.IsNaN(maxvalue))
 198.609 +                {
 198.610 +                    maxvalue = value;
 198.611 +                }
 198.612 +            }
 198.613 +
 198.614 +            this.MinValue = minvalue;
 198.615 +            this.MaxValue = maxvalue;
 198.616 +
 198.617 +            if (this.ColorAxis != null)
 198.618 +            {
 198.619 +                this.ColorAxis.Include(this.MinValue);
 198.620 +                this.ColorAxis.Include(this.MaxValue);
 198.621 +            }
 198.622 +        }
 198.623 +    }
 198.624 +}
 198.625 \ No newline at end of file
   199.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   199.2 +++ b/External/OxyPlot/OxyPlot/Series/Series.cs	Sat Jun 08 16:53:22 2013 +0000
   199.3 @@ -0,0 +1,204 @@
   199.4 +// --------------------------------------------------------------------------------------------------------------------
   199.5 +// <copyright file="Series.cs" company="OxyPlot">
   199.6 +//   The MIT License (MIT)
   199.7 +//
   199.8 +//   Copyright (c) 2012 Oystein Bjorke
   199.9 +//
  199.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  199.11 +//   copy of this software and associated documentation files (the
  199.12 +//   "Software"), to deal in the Software without restriction, including
  199.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  199.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  199.15 +//   permit persons to whom the Software is furnished to do so, subject to
  199.16 +//   the following conditions:
  199.17 +//
  199.18 +//   The above copyright notice and this permission notice shall be included
  199.19 +//   in all copies or substantial portions of the Software.
  199.20 +//
  199.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  199.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  199.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  199.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  199.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  199.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  199.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  199.28 +// </copyright>
  199.29 +// <summary>
  199.30 +//   Abstract base class for all series.
  199.31 +// </summary>
  199.32 +// --------------------------------------------------------------------------------------------------------------------
  199.33 +namespace OxyPlot.Series
  199.34 +{
  199.35 +    using System.Globalization;
  199.36 +
  199.37 +    using OxyPlot.Axes;
  199.38 +
  199.39 +    /// <summary>
  199.40 +    /// Provides an abstract base class for plot series.
  199.41 +    /// </summary>
  199.42 +    /// <remarks>
  199.43 +    /// This class contains internal methods that should be called only from the PlotModel.
  199.44 +    /// </remarks>
  199.45 +    public abstract class Series : UIPlotElement, ITrackableSeries
  199.46 +    {
  199.47 +        /// <summary>
  199.48 +        /// Initializes a new instance of the <see cref="Series" /> class.
  199.49 +        /// </summary>
  199.50 +        protected Series()
  199.51 +        {
  199.52 +            this.IsVisible = true;
  199.53 +        }
  199.54 +
  199.55 +        /// <summary>
  199.56 +        /// Gets the actual culture.
  199.57 +        /// </summary>
  199.58 +        /// <remarks>
  199.59 +        /// The culture is defined in the parent PlotModel.
  199.60 +        /// </remarks>
  199.61 +        public CultureInfo ActualCulture
  199.62 +        {
  199.63 +            get
  199.64 +            {
  199.65 +                return this.PlotModel != null ? this.PlotModel.ActualCulture : CultureInfo.CurrentCulture;
  199.66 +            }
  199.67 +        }
  199.68 +
  199.69 +        /// <summary>
  199.70 +        /// Gets or sets the background color of the series. The background area is defined by the x and y axes.
  199.71 +        /// </summary>
  199.72 +        /// <value> The background color. </value>
  199.73 +        public OxyColor Background { get; set; }
  199.74 +
  199.75 +        /// <summary>
  199.76 +        /// Gets or sets a value indicating whether this series is visible.
  199.77 +        /// </summary>
  199.78 +        public bool IsVisible { get; set; }
  199.79 +
  199.80 +        /// <summary>
  199.81 +        /// Gets or sets the title of the Series.
  199.82 +        /// </summary>
  199.83 +        /// <value> The title. </value>
  199.84 +        public string Title { get; set; }
  199.85 +
  199.86 +        /// <summary>
  199.87 +        /// Gets or sets a format string used for the tracker.
  199.88 +        /// </summary>
  199.89 +        public string TrackerFormatString { get; set; }
  199.90 +
  199.91 +        /// <summary>
  199.92 +        /// Gets or sets the key for the tracker to use on this series.
  199.93 +        /// </summary>
  199.94 +        public string TrackerKey { get; set; }
  199.95 +
  199.96 +        /// <summary>
  199.97 +        /// Gets the point on the series that is nearest the specified point.
  199.98 +        /// </summary>
  199.99 +        /// <param name="point">The point.</param>
 199.100 +        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
 199.101 +        /// <returns>
 199.102 +        /// A TrackerHitResult for the current hit.
 199.103 +        /// </returns>
 199.104 +        public abstract TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate);
 199.105 +
 199.106 +        /// <summary>
 199.107 +        /// Renders the series on the specified render context.
 199.108 +        /// </summary>
 199.109 +        /// <param name="rc">
 199.110 +        /// The rendering context.
 199.111 +        /// </param>
 199.112 +        /// <param name="model">
 199.113 +        /// The model.
 199.114 +        /// </param>
 199.115 +        public abstract void Render(IRenderContext rc, PlotModel model);
 199.116 +
 199.117 +        /// <summary>
 199.118 +        /// Renders the legend symbol on the specified render context.
 199.119 +        /// </summary>
 199.120 +        /// <param name="rc">
 199.121 +        /// The rendering context.
 199.122 +        /// </param>
 199.123 +        /// <param name="legendBox">
 199.124 +        /// The legend rectangle.
 199.125 +        /// </param>
 199.126 +        public abstract void RenderLegend(IRenderContext rc, OxyRect legendBox);
 199.127 +
 199.128 +        /// <summary>
 199.129 +        /// Tests if the plot element is hit by the specified point.
 199.130 +        /// </summary>
 199.131 +        /// <param name="point">The point.</param>
 199.132 +        /// <param name="tolerance">The tolerance.</param>
 199.133 +        /// <returns>
 199.134 +        /// A hit test result.
 199.135 +        /// </returns>
 199.136 +        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
 199.137 +        {
 199.138 +            var thr = this.GetNearestPoint(point, true) ?? this.GetNearestPoint(point, false);
 199.139 +
 199.140 +            if (thr != null)
 199.141 +            {
 199.142 +                double distance = thr.Position.DistanceTo(point);
 199.143 +                if (distance > tolerance)
 199.144 +                {
 199.145 +                    return null;
 199.146 +                }
 199.147 +
 199.148 +                return new HitTestResult(thr.Position, thr.Item, thr.Index);
 199.149 +            }
 199.150 +
 199.151 +            return null;
 199.152 +        }
 199.153 +
 199.154 +        /// <summary>
 199.155 +        /// Check if this data series requires X/Y axes. (e.g. Pie series do not require axes)
 199.156 +        /// </summary>
 199.157 +        /// <returns>
 199.158 +        /// True if no axes are required.
 199.159 +        /// </returns>
 199.160 +        protected internal abstract bool AreAxesRequired();
 199.161 +
 199.162 +        /// <summary>
 199.163 +        /// Ensures that the axes of the series is defined.
 199.164 +        /// </summary>
 199.165 +        protected internal abstract void EnsureAxes();
 199.166 +
 199.167 +        /// <summary>
 199.168 +        /// Check if the data series is using the specified axis.
 199.169 +        /// </summary>
 199.170 +        /// <param name="axis">
 199.171 +        /// An axis which should be checked if used
 199.172 +        /// </param>
 199.173 +        /// <returns>
 199.174 +        /// True if the axis is in use.
 199.175 +        /// </returns>
 199.176 +        protected internal abstract bool IsUsing(Axis axis);
 199.177 +
 199.178 +        /// <summary>
 199.179 +        /// Sets default values (colors, line style etc) from the plot model.
 199.180 +        /// </summary>
 199.181 +        /// <param name="model">
 199.182 +        /// A plot model.
 199.183 +        /// </param>
 199.184 +        protected internal abstract void SetDefaultValues(PlotModel model);
 199.185 +
 199.186 +        /// <summary>
 199.187 +        /// Updates the axis maximum and minimum values.
 199.188 +        /// </summary>
 199.189 +        protected internal abstract void UpdateAxisMaxMin();
 199.190 +
 199.191 +        /// <summary>
 199.192 +        /// Updates the data.
 199.193 +        /// </summary>
 199.194 +        protected internal abstract void UpdateData();
 199.195 +
 199.196 +        /// <summary>
 199.197 +        /// Updates the valid data.
 199.198 +        /// </summary>
 199.199 +        protected internal abstract void UpdateValidData();
 199.200 +
 199.201 +        /// <summary>
 199.202 +        /// Updates the maximum and minimum of the series.
 199.203 +        /// </summary>
 199.204 +        protected internal abstract void UpdateMaxMin();
 199.205 +
 199.206 +    }
 199.207 +}
 199.208 \ No newline at end of file
   200.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   200.2 +++ b/External/OxyPlot/OxyPlot/Series/StairStepSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   200.3 @@ -0,0 +1,291 @@
   200.4 +// --------------------------------------------------------------------------------------------------------------------
   200.5 +// <copyright file="StairStepSeries.cs" company="OxyPlot">
   200.6 +//   The MIT License (MIT)
   200.7 +//   
   200.8 +//   Copyright (c) 2012 Oystein Bjorke
   200.9 +//   
  200.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  200.11 +//   copy of this software and associated documentation files (the
  200.12 +//   "Software"), to deal in the Software without restriction, including
  200.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  200.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  200.15 +//   permit persons to whom the Software is furnished to do so, subject to
  200.16 +//   the following conditions:
  200.17 +//   
  200.18 +//   The above copyright notice and this permission notice shall be included
  200.19 +//   in all copies or substantial portions of the Software.
  200.20 +//   
  200.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  200.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  200.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  200.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  200.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  200.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  200.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  200.28 +// </copyright>
  200.29 +// <summary>
  200.30 +//   Represents a series for stair step graphs.
  200.31 +// </summary>
  200.32 +// --------------------------------------------------------------------------------------------------------------------
  200.33 +namespace OxyPlot.Series
  200.34 +{
  200.35 +    using System;
  200.36 +    using System.Collections.Generic;
  200.37 +
  200.38 +    /// <summary>
  200.39 +    /// Represents a series for stair step graphs.
  200.40 +    /// </summary>
  200.41 +    public class StairStepSeries : LineSeries
  200.42 +    {
  200.43 +        /// <summary>
  200.44 +        /// Initializes a new instance of the <see cref = "StairStepSeries" /> class.
  200.45 +        /// </summary>
  200.46 +        public StairStepSeries()
  200.47 +        {
  200.48 +            this.VerticalStrokeThickness = double.NaN;
  200.49 +            this.VerticalLineStyle = this.LineStyle;
  200.50 +        }
  200.51 +
  200.52 +        /// <summary>
  200.53 +        /// Initializes a new instance of the <see cref="StairStepSeries"/> class.
  200.54 +        /// </summary>
  200.55 +        /// <param name="title">
  200.56 +        /// The title.
  200.57 +        /// </param>
  200.58 +        public StairStepSeries(string title)
  200.59 +            : base(title)
  200.60 +        {
  200.61 +            this.VerticalStrokeThickness = double.NaN;
  200.62 +            this.VerticalLineStyle = this.LineStyle;
  200.63 +            this.Title = title;
  200.64 +        }
  200.65 +
  200.66 +        /// <summary>
  200.67 +        /// Initializes a new instance of the <see cref="StairStepSeries"/> class.
  200.68 +        /// </summary>
  200.69 +        /// <param name="color">
  200.70 +        /// The color.
  200.71 +        /// </param>
  200.72 +        /// <param name="strokeThickness">
  200.73 +        /// The stroke thickness.
  200.74 +        /// </param>
  200.75 +        /// <param name="title">
  200.76 +        /// The title.
  200.77 +        /// </param>
  200.78 +        public StairStepSeries(OxyColor color, double strokeThickness = 1, string title = null)
  200.79 +            : base(color, strokeThickness, title)
  200.80 +        {
  200.81 +            this.VerticalStrokeThickness = double.NaN;
  200.82 +            this.VerticalLineStyle = this.LineStyle;
  200.83 +        }
  200.84 +
  200.85 +        /// <summary>
  200.86 +        /// Gets or sets the stroke thickness of the vertical line segments.
  200.87 +        /// </summary>
  200.88 +        /// <remarks>
  200.89 +        /// Set the value to NaN to use the StrokeThickness property for both horizontal and vertical segments.
  200.90 +        /// Using the VerticalStrokeThickness property will have a small performance hit.
  200.91 +        /// </remarks>
  200.92 +        /// <value>The vertical stroke thickness.</value>
  200.93 +        public double VerticalStrokeThickness { get; set; }
  200.94 +
  200.95 +        /// <summary>
  200.96 +        /// Gets or sets the line style of the vertical line segments.
  200.97 +        /// </summary>
  200.98 +        /// <value>The vertical line style.</value>
  200.99 +        public LineStyle VerticalLineStyle { get; set; }
 200.100 +
 200.101 +        /// <summary>
 200.102 +        /// Gets the nearest point.
 200.103 +        /// </summary>
 200.104 +        /// <param name="point">
 200.105 +        /// The point.
 200.106 +        /// </param>
 200.107 +        /// <param name="interpolate">
 200.108 +        /// interpolate if set to <c>true</c> .
 200.109 +        /// </param>
 200.110 +        /// <returns>
 200.111 +        /// A TrackerHitResult for the current hit.
 200.112 +        /// </returns>
 200.113 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 200.114 +        {
 200.115 +            if (this.XAxis == null || this.YAxis == null)
 200.116 +            {
 200.117 +                return null;
 200.118 +            }
 200.119 +
 200.120 +            TrackerHitResult result = null;
 200.121 +
 200.122 +            // http://paulbourke.net/geometry/pointlineplane/
 200.123 +            double minimumDistance = double.MaxValue;
 200.124 +
 200.125 +            for (int i = 0; i + 1 < this.Points.Count; i++)
 200.126 +            {
 200.127 +                var p1 = this.Points[i];
 200.128 +                var p2 = this.Points[i + 1];
 200.129 +                var sp1 = this.Transform(p1.X, p1.Y);
 200.130 +                var sp2 = this.Transform(p2.X, p1.Y);
 200.131 +
 200.132 +                double spdx = sp2.x - sp1.x;
 200.133 +                double spdy = sp2.y - sp1.y;
 200.134 +                double u1 = ((point.x - sp1.x) * spdx) + ((point.y - sp1.y) * spdy);
 200.135 +                double u2 = (spdx * spdx) + (spdy * spdy);
 200.136 +                double ds = (spdx * spdx) + (spdy * spdy);
 200.137 +
 200.138 +                if (ds < 4)
 200.139 +                {
 200.140 +                    // if the points are very close, we can get numerical problems, just use the first point...
 200.141 +                    u1 = 0;
 200.142 +                    u2 = 1;
 200.143 +                }
 200.144 +
 200.145 +                if (Math.Abs(u2) < double.Epsilon)
 200.146 +                {
 200.147 +                    continue; // P1 && P2 coincident
 200.148 +                }
 200.149 +
 200.150 +                double u = u1 / u2;
 200.151 +                if (u < 0 || u > 1)
 200.152 +                {
 200.153 +                    continue; // outside line
 200.154 +                }
 200.155 +
 200.156 +                double sx = sp1.x + (u * spdx);
 200.157 +                double sy = sp1.y + (u * spdy);
 200.158 +
 200.159 +                double dx = point.x - sx;
 200.160 +                double dy = point.y - sy;
 200.161 +                double distance = (dx * dx) + (dy * dy);
 200.162 +
 200.163 +                if (distance < minimumDistance)
 200.164 +                {
 200.165 +                    double px = p1.X + (u * (p2.X - p1.X));
 200.166 +                    double py = p1.Y;
 200.167 +                    result = new TrackerHitResult(
 200.168 +                        this, new DataPoint(px, py), new ScreenPoint(sx, sy), this.GetItem(i), i);
 200.169 +                    minimumDistance = distance;
 200.170 +                }
 200.171 +            }
 200.172 +
 200.173 +            return result;
 200.174 +        }
 200.175 +
 200.176 +        /// <summary>
 200.177 +        /// Renders the LineSeries on the specified rendering context.
 200.178 +        /// </summary>
 200.179 +        /// <param name="rc">
 200.180 +        /// The rendering context.
 200.181 +        /// </param>
 200.182 +        /// <param name="model">
 200.183 +        /// The owner plot model.
 200.184 +        /// </param>
 200.185 +        public override void Render(IRenderContext rc, PlotModel model)
 200.186 +        {
 200.187 +            if (this.Points.Count == 0)
 200.188 +            {
 200.189 +                return;
 200.190 +            }
 200.191 +
 200.192 +            this.VerifyAxes();
 200.193 +
 200.194 +            var clippingRect = this.GetClippingRect();
 200.195 +
 200.196 +            Action<IList<ScreenPoint>, IList<ScreenPoint>> renderPoints = (lpts, mpts) =>
 200.197 +                {
 200.198 +                    var lineStyle = this.ActualLineStyle;
 200.199 +
 200.200 +                    // clip the line segments with the clipping rectangle
 200.201 +                    if (this.StrokeThickness > 0 && lineStyle != LineStyle.None)
 200.202 +                    {
 200.203 +                        var verticalStrokeThickness = double.IsNaN(this.VerticalStrokeThickness)
 200.204 +                                                          ? this.StrokeThickness
 200.205 +                                                          : this.VerticalStrokeThickness;
 200.206 +                        if (!verticalStrokeThickness.Equals(this.StrokeThickness) || this.VerticalLineStyle != lineStyle)
 200.207 +                        {
 200.208 +                            var hlpts = new List<ScreenPoint>();
 200.209 +                            var vlpts = new List<ScreenPoint>();
 200.210 +                            for (int i = 0; i + 2 < lpts.Count; i += 2)
 200.211 +                            {
 200.212 +                                hlpts.Add(lpts[i]);
 200.213 +                                hlpts.Add(lpts[i + 1]);
 200.214 +                                vlpts.Add(lpts[i + 1]);
 200.215 +                                vlpts.Add(lpts[i + 2]);
 200.216 +                            }
 200.217 +
 200.218 +                            rc.DrawClippedLineSegments(
 200.219 +                                hlpts, 
 200.220 +                                clippingRect, 
 200.221 +                                this.GetSelectableColor(this.ActualColor), 
 200.222 +                                this.StrokeThickness, 
 200.223 +                                lineStyle, 
 200.224 +                                this.LineJoin, 
 200.225 +                                false);
 200.226 +                            rc.DrawClippedLineSegments(
 200.227 +                                vlpts, 
 200.228 +                                clippingRect, 
 200.229 +                                this.GetSelectableColor(this.ActualColor), 
 200.230 +                                verticalStrokeThickness, 
 200.231 +                                this.VerticalLineStyle, 
 200.232 +                                this.LineJoin, 
 200.233 +                                false);
 200.234 +                        }
 200.235 +                        else
 200.236 +                        {
 200.237 +                            rc.DrawClippedLine(
 200.238 +                                lpts, 
 200.239 +                                clippingRect, 
 200.240 +                                0, 
 200.241 +                                this.GetSelectableColor(this.ActualColor), 
 200.242 +                                this.StrokeThickness, 
 200.243 +                                lineStyle, 
 200.244 +                                this.LineJoin, 
 200.245 +                                false);
 200.246 +                        }
 200.247 +                    }
 200.248 +
 200.249 +                    if (this.MarkerType != MarkerType.None)
 200.250 +                    {
 200.251 +                        rc.DrawMarkers(
 200.252 +                            mpts, 
 200.253 +                            clippingRect, 
 200.254 +                            this.MarkerType, 
 200.255 +                            this.MarkerOutline, 
 200.256 +                            new[] { this.MarkerSize }, 
 200.257 +                            this.MarkerFill, 
 200.258 +                            this.MarkerStroke, 
 200.259 +                            this.MarkerStrokeThickness);
 200.260 +                    }
 200.261 +                };
 200.262 +
 200.263 +            // Transform all points to screen coordinates
 200.264 +            // Render the line when invalid points occur
 200.265 +            var linePoints = new List<ScreenPoint>();
 200.266 +            var markerPoints = new List<ScreenPoint>();
 200.267 +            double previousY = double.NaN;
 200.268 +            foreach (var point in this.Points)
 200.269 +            {
 200.270 +                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
 200.271 +                {
 200.272 +                    renderPoints(linePoints, markerPoints);
 200.273 +                    linePoints.Clear();
 200.274 +                    markerPoints.Clear();
 200.275 +                    previousY = double.NaN;
 200.276 +                    continue;
 200.277 +                }
 200.278 +
 200.279 +                ScreenPoint transformedPoint = this.Transform(point);
 200.280 +                if (!double.IsNaN(previousY))
 200.281 +                {
 200.282 +                    // Horizontal line from the previous point to the current x-coordinate
 200.283 +                    linePoints.Add(new ScreenPoint(transformedPoint.X, previousY));
 200.284 +                }
 200.285 +
 200.286 +                linePoints.Add(transformedPoint);
 200.287 +                markerPoints.Add(transformedPoint);
 200.288 +                previousY = transformedPoint.Y;
 200.289 +            }
 200.290 +
 200.291 +            renderPoints(linePoints, markerPoints);
 200.292 +        }
 200.293 +    }
 200.294 +}
 200.295 \ No newline at end of file
   201.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.2 +++ b/External/OxyPlot/OxyPlot/Series/StemSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   201.3 @@ -0,0 +1,212 @@
   201.4 +// --------------------------------------------------------------------------------------------------------------------
   201.5 +// <copyright file="StemSeries.cs" company="OxyPlot">
   201.6 +//   The MIT License (MIT)
   201.7 +//   
   201.8 +//   Copyright (c) 2012 Oystein Bjorke
   201.9 +//   
  201.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  201.11 +//   copy of this software and associated documentation files (the
  201.12 +//   "Software"), to deal in the Software without restriction, including
  201.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  201.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  201.15 +//   permit persons to whom the Software is furnished to do so, subject to
  201.16 +//   the following conditions:
  201.17 +//   
  201.18 +//   The above copyright notice and this permission notice shall be included
  201.19 +//   in all copies or substantial portions of the Software.
  201.20 +//   
  201.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  201.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  201.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  201.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  201.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  201.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  201.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  201.28 +// </copyright>
  201.29 +// <summary>
  201.30 +//   Represents a series that plots discrete data in a stem plot.
  201.31 +// </summary>
  201.32 +// --------------------------------------------------------------------------------------------------------------------
  201.33 +namespace OxyPlot.Series
  201.34 +{
  201.35 +    using System.Collections.Generic;
  201.36 +
  201.37 +    /// <summary>
  201.38 +    /// Represents a series that plots discrete data in a stem plot.
  201.39 +    /// </summary>
  201.40 +    /// <remarks>
  201.41 +    /// See <a href="http://en.wikipedia.org/wiki/Stemplot">Stem plot</a> and
  201.42 +    /// <a href="http://www.mathworks.com/help/techdoc/ref/stem.html">stem</a>.
  201.43 +    /// </remarks>
  201.44 +    public class StemSeries : LineSeries
  201.45 +    {
  201.46 +        /// <summary>
  201.47 +        /// Initializes a new instance of the <see cref = "StemSeries" /> class.
  201.48 +        /// </summary>
  201.49 +        public StemSeries()
  201.50 +        {
  201.51 +            this.Base = 0;
  201.52 +        }
  201.53 +
  201.54 +        /// <summary>
  201.55 +        /// Initializes a new instance of the <see cref="StemSeries"/> class.
  201.56 +        /// </summary>
  201.57 +        /// <param name="title">
  201.58 +        /// The title.
  201.59 +        /// </param>
  201.60 +        public StemSeries(string title)
  201.61 +            : base(title)
  201.62 +        {
  201.63 +            this.Title = title;
  201.64 +        }
  201.65 +
  201.66 +        /// <summary>
  201.67 +        /// Initializes a new instance of the <see cref="StemSeries"/> class.
  201.68 +        /// </summary>
  201.69 +        /// <param name="color">
  201.70 +        /// The color of the line stroke.
  201.71 +        /// </param>
  201.72 +        /// <param name="strokeThickness">
  201.73 +        /// The stroke thickness (optional).
  201.74 +        /// </param>
  201.75 +        /// <param name="title">
  201.76 +        /// The title (optional).
  201.77 +        /// </param>
  201.78 +        public StemSeries(OxyColor color, double strokeThickness = 1, string title = null)
  201.79 +            : base(color, strokeThickness, title)
  201.80 +        {
  201.81 +        }
  201.82 +
  201.83 +        /// <summary>
  201.84 +        /// Gets or sets Base.
  201.85 +        /// </summary>
  201.86 +        public double Base { get; set; }
  201.87 +
  201.88 +        /// <summary>
  201.89 +        /// Gets the point on the series that is nearest the specified point.
  201.90 +        /// </summary>
  201.91 +        /// <param name="point">
  201.92 +        /// The point.
  201.93 +        /// </param>
  201.94 +        /// <param name="interpolate">
  201.95 +        /// Interpolate the series if this flag is set to <c>true</c>.
  201.96 +        /// </param>
  201.97 +        /// <returns>
  201.98 +        /// A TrackerHitResult for the current hit.
  201.99 +        /// </returns>
 201.100 +        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
 201.101 +        {
 201.102 +            if (this.XAxis == null || this.YAxis == null)
 201.103 +            {
 201.104 +                return null;
 201.105 +            }
 201.106 +
 201.107 +            if (interpolate)
 201.108 +            {
 201.109 +                return null;
 201.110 +            }
 201.111 +
 201.112 +            TrackerHitResult result = null;
 201.113 +
 201.114 +            // http://paulbourke.net/geometry/pointlineplane/
 201.115 +            double minimumDistance = double.MaxValue;
 201.116 +            var points = this.Points;
 201.117 +
 201.118 +            for (int i = 0; i < points.Count; i++)
 201.119 +            {
 201.120 +                var p1 = points[i];
 201.121 +                var basePoint = new DataPoint(p1.X, this.Base);
 201.122 +                var sp1 = this.Transform(p1);
 201.123 +                var sp2 = this.Transform(basePoint);
 201.124 +                var u = ScreenPointHelper.FindPositionOnLine(point, sp1, sp2);
 201.125 +
 201.126 +                if (double.IsNaN(u))
 201.127 +                {
 201.128 +                    continue;
 201.129 +                }
 201.130 +
 201.131 +                if (u < 0 || u > 1)
 201.132 +                {
 201.133 +                    continue; // outside line
 201.134 +                }
 201.135 +
 201.136 +                var sp = sp1 + ((sp2 - sp1) * u);
 201.137 +                double distance = (point - sp).LengthSquared;
 201.138 +
 201.139 +                if (distance < minimumDistance)
 201.140 +                {
 201.141 +                    result = new TrackerHitResult(
 201.142 +                        this, new DataPoint(p1.X, p1.Y), new ScreenPoint(sp1.x, sp1.y), this.GetItem(i));
 201.143 +                    minimumDistance = distance;
 201.144 +                }
 201.145 +            }
 201.146 +
 201.147 +            return result;
 201.148 +        }
 201.149 +
 201.150 +        /// <summary>
 201.151 +        /// Renders the LineSeries on the specified rendering context.
 201.152 +        /// </summary>
 201.153 +        /// <param name="rc">
 201.154 +        /// The rendering context.
 201.155 +        /// </param>
 201.156 +        /// <param name="model">
 201.157 +        /// The owner plot model.
 201.158 +        /// </param>
 201.159 +        public override void Render(IRenderContext rc, PlotModel model)
 201.160 +        {
 201.161 +            if (this.Points.Count == 0)
 201.162 +            {
 201.163 +                return;
 201.164 +            }
 201.165 +
 201.166 +            this.VerifyAxes();
 201.167 +
 201.168 +            double minDistSquared = this.MinimumSegmentLength * this.MinimumSegmentLength;
 201.169 +
 201.170 +            var clippingRect = this.GetClippingRect();
 201.171 +
 201.172 +            // Transform all points to screen coordinates
 201.173 +            // Render the line when invalid points occur
 201.174 +            var markerPoints = new List<ScreenPoint>();
 201.175 +            foreach (var point in this.Points)
 201.176 +            {
 201.177 +                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
 201.178 +                {
 201.179 +                    continue;
 201.180 +                }
 201.181 +
 201.182 +                var p0 = this.Transform(point.X, this.Base);
 201.183 +                var p1 = this.Transform(point.X, point.Y);
 201.184 +
 201.185 +                if (this.StrokeThickness > 0 && this.ActualLineStyle != LineStyle.None)
 201.186 +                {
 201.187 +                    rc.DrawClippedLine(
 201.188 +                        new[] { p0, p1 }, 
 201.189 +                        clippingRect, 
 201.190 +                        minDistSquared, 
 201.191 +                        this.GetSelectableColor(this.ActualColor), 
 201.192 +                        this.StrokeThickness, 
 201.193 +                        this.ActualLineStyle, 
 201.194 +                        this.LineJoin, 
 201.195 +                        false);
 201.196 +                }
 201.197 +
 201.198 +                markerPoints.Add(p1);
 201.199 +            }
 201.200 +
 201.201 +            if (this.MarkerType != MarkerType.None)
 201.202 +            {
 201.203 +                rc.DrawMarkers(
 201.204 +                    markerPoints, 
 201.205 +                    clippingRect, 
 201.206 +                    this.MarkerType, 
 201.207 +                    this.MarkerOutline, 
 201.208 +                    new[] { this.MarkerSize }, 
 201.209 +                    this.MarkerFill, 
 201.210 +                    this.MarkerStroke, 
 201.211 +                    this.MarkerStrokeThickness);
 201.212 +            }
 201.213 +        }
 201.214 +    }
 201.215 +}
 201.216 \ No newline at end of file
   202.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.2 +++ b/External/OxyPlot/OxyPlot/Series/TwoColorLineSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   202.3 @@ -0,0 +1,163 @@
   202.4 +// --------------------------------------------------------------------------------------------------------------------
   202.5 +// <copyright file="TwoColorLineSeries.cs" company="OxyPlot">
   202.6 +//   The MIT License (MIT)
   202.7 +//
   202.8 +//   Copyright (c) 2012 Oystein Bjorke
   202.9 +//
  202.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  202.11 +//   copy of this software and associated documentation files (the
  202.12 +//   "Software"), to deal in the Software without restriction, including
  202.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  202.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  202.15 +//   permit persons to whom the Software is furnished to do so, subject to
  202.16 +//   the following conditions:
  202.17 +//
  202.18 +//   The above copyright notice and this permission notice shall be included
  202.19 +//   in all copies or substantial portions of the Software.
  202.20 +//
  202.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  202.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  202.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  202.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  202.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  202.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  202.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  202.28 +// </copyright>
  202.29 +// <summary>
  202.30 +//   Represents a two-color line series.
  202.31 +// </summary>
  202.32 +// --------------------------------------------------------------------------------------------------------------------
  202.33 +namespace OxyPlot.Series
  202.34 +{
  202.35 +    using System.Collections.Generic;
  202.36 +
  202.37 +    /// <summary>
  202.38 +    /// Represents a two-color line series.
  202.39 +    /// </summary>
  202.40 +    public class TwoColorLineSeries : LineSeries
  202.41 +    {
  202.42 +        /// <summary>
  202.43 +        /// The default second color.
  202.44 +        /// </summary>
  202.45 +        private OxyColor defaultColor2;
  202.46 +
  202.47 +        /// <summary>
  202.48 +        /// Initializes a new instance of the <see cref = "TwoColorLineSeries" /> class.
  202.49 +        /// </summary>
  202.50 +        public TwoColorLineSeries()
  202.51 +        {
  202.52 +            this.Limit = 0.0;
  202.53 +            this.Color2 = OxyColors.Blue;
  202.54 +            this.LineStyle2 = LineStyle.Solid;
  202.55 +        }
  202.56 +
  202.57 +        /// <summary>
  202.58 +        /// Gets or sets the color for the part of the line that is below the limit.
  202.59 +        /// </summary>
  202.60 +        public OxyColor Color2 { get; set; }
  202.61 +
  202.62 +        /// <summary>
  202.63 +        /// Gets the actual second color.
  202.64 +        /// </summary>
  202.65 +        /// <value>The actual color.</value>
  202.66 +        public OxyColor ActualColor2
  202.67 +        {
  202.68 +            get { return this.Color2 ?? this.defaultColor2; }
  202.69 +        }
  202.70 +
  202.71 +        /// <summary>
  202.72 +        /// Gets or sets the limit.
  202.73 +        /// </summary>
  202.74 +        /// <remarks>
  202.75 +        /// The parts of the line that is below this limit will be rendered with Color2.
  202.76 +        /// The parts of the line that is above the limit will be rendered with Color.
  202.77 +        /// </remarks>
  202.78 +        public double Limit { get; set; }
  202.79 +
  202.80 +        /// <summary>
  202.81 +        /// Gets or sets the line style for the part of the line that is below the limit.
  202.82 +        /// </summary>
  202.83 +        /// <value>The line style.</value>
  202.84 +        public LineStyle LineStyle2 { get; set; }
  202.85 +
  202.86 +        /// <summary>
  202.87 +        /// Gets the actual line style for the part of the line that is below the limit.
  202.88 +        /// </summary>
  202.89 +        /// <value>The line style.</value>
  202.90 +        public LineStyle ActualLineStyle2
  202.91 +        {
  202.92 +            get
  202.93 +            {
  202.94 +                return this.LineStyle2 != LineStyle.Undefined ? this.LineStyle2 : LineStyle.Solid;
  202.95 +            }
  202.96 +        }
  202.97 +
  202.98 +        /// <summary>
  202.99 +        /// The set default values.
 202.100 +        /// </summary>
 202.101 +        /// <param name="model">
 202.102 +        /// The model.
 202.103 +        /// </param>
 202.104 +        protected internal override void SetDefaultValues(PlotModel model)
 202.105 +        {
 202.106 +            if (this.Color2 == null)
 202.107 +            {
 202.108 +                this.LineStyle2 = model.GetDefaultLineStyle();
 202.109 +                this.defaultColor2 = model.GetDefaultColor();
 202.110 +            }
 202.111 +        }
 202.112 +
 202.113 +        /// <summary>
 202.114 +        /// Renders the smoothed line.
 202.115 +        /// </summary>
 202.116 +        /// <param name="rc">
 202.117 +        /// The render context.
 202.118 +        /// </param>
 202.119 +        /// <param name="clippingRect">
 202.120 +        /// The clipping rect.
 202.121 +        /// </param>
 202.122 +        /// <param name="pointsToRender">
 202.123 +        /// The points.
 202.124 +        /// </param>
 202.125 +        protected override void RenderSmoothedLine(IRenderContext rc, OxyRect clippingRect, IList<ScreenPoint> pointsToRender)
 202.126 +        {
 202.127 +            double bottom = clippingRect.Bottom;
 202.128 +
 202.129 +            // todo: this does not work when y axis is reversed
 202.130 +            double y = this.YAxis.Transform(this.Limit);
 202.131 +
 202.132 +            if (y < clippingRect.Top)
 202.133 +            {
 202.134 +                y = clippingRect.Top;
 202.135 +            }
 202.136 +
 202.137 +            if (y > clippingRect.Bottom)
 202.138 +            {
 202.139 +                y = clippingRect.Bottom;
 202.140 +            }
 202.141 +
 202.142 +            clippingRect.Bottom = y;
 202.143 +            rc.DrawClippedLine(
 202.144 +                pointsToRender,
 202.145 +                clippingRect,
 202.146 +                this.MinimumSegmentLength * this.MinimumSegmentLength,
 202.147 +                this.GetSelectableColor(this.ActualColor),
 202.148 +                this.StrokeThickness,
 202.149 +                this.ActualLineStyle,
 202.150 +                this.LineJoin,
 202.151 +                false);
 202.152 +            clippingRect.Top = y;
 202.153 +            clippingRect.Height = bottom - y;
 202.154 +            rc.DrawClippedLine(
 202.155 +                pointsToRender,
 202.156 +                clippingRect,
 202.157 +                this.MinimumSegmentLength * this.MinimumSegmentLength,
 202.158 +                this.GetSelectableColor(this.ActualColor2),
 202.159 +                this.StrokeThickness,
 202.160 +                this.ActualLineStyle2,
 202.161 +                this.LineJoin,
 202.162 +                false);
 202.163 +        }
 202.164 +
 202.165 +    }
 202.166 +}
 202.167 \ No newline at end of file
   203.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.2 +++ b/External/OxyPlot/OxyPlot/Series/XYAxisSeries.cs	Sat Jun 08 16:53:22 2013 +0000
   203.3 @@ -0,0 +1,424 @@
   203.4 +// --------------------------------------------------------------------------------------------------------------------
   203.5 +// <copyright file="XYAxisSeries.cs" company="OxyPlot">
   203.6 +//   The MIT License (MIT)
   203.7 +//   
   203.8 +//   Copyright (c) 2012 Oystein Bjorke
   203.9 +//   
  203.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  203.11 +//   copy of this software and associated documentation files (the
  203.12 +//   "Software"), to deal in the Software without restriction, including
  203.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  203.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  203.15 +//   permit persons to whom the Software is furnished to do so, subject to
  203.16 +//   the following conditions:
  203.17 +//   
  203.18 +//   The above copyright notice and this permission notice shall be included
  203.19 +//   in all copies or substantial portions of the Software.
  203.20 +//   
  203.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  203.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  203.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  203.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  203.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  203.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  203.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  203.28 +// </copyright>
  203.29 +// <summary>
  203.30 +//   Abstract base class for series that contains an X-axis and Y-axis.
  203.31 +// </summary>
  203.32 +// --------------------------------------------------------------------------------------------------------------------
  203.33 +
  203.34 +namespace OxyPlot.Series
  203.35 +{
  203.36 +    using System;
  203.37 +    using System.Collections.Generic;
  203.38 +
  203.39 +    using OxyPlot.Axes;
  203.40 +
  203.41 +    /// <summary>
  203.42 +    /// Provides an abstract base class for series that are related to an X-axis and a Y-axis.
  203.43 +    /// </summary>
  203.44 +    public abstract class XYAxisSeries : ItemsSeries
  203.45 +    {
  203.46 +        /// <summary>
  203.47 +        /// Gets or sets the maximum x-coordinate of the dataset.
  203.48 +        /// </summary>
  203.49 +        /// <value> The maximum x-coordinate. </value>
  203.50 +        public double MaxX { get; protected set; }
  203.51 +
  203.52 +        /// <summary>
  203.53 +        /// Gets or sets the maximum y-coordinate of the dataset.
  203.54 +        /// </summary>
  203.55 +        /// <value> The maximum y-coordinate. </value>
  203.56 +        public double MaxY { get; protected set; }
  203.57 +
  203.58 +        /// <summary>
  203.59 +        /// Gets or sets the minimum x-coordinate of the dataset.
  203.60 +        /// </summary>
  203.61 +        /// <value> The minimum x-coordinate. </value>
  203.62 +        public double MinX { get; protected set; }
  203.63 +
  203.64 +        /// <summary>
  203.65 +        /// Gets or sets the minimum y-coordinate of the dataset.
  203.66 +        /// </summary>
  203.67 +        /// <value> The minimum y-coordinate. </value>
  203.68 +        public double MinY { get; protected set; }
  203.69 +
  203.70 +        /// <summary>
  203.71 +        /// Gets the x-axis.
  203.72 +        /// </summary>
  203.73 +        /// <value> The x-axis. </value>
  203.74 +        public Axis XAxis { get; private set; }
  203.75 +
  203.76 +        /// <summary>
  203.77 +        /// Gets or sets the x-axis key.
  203.78 +        /// </summary>
  203.79 +        /// <value> The x-axis key. </value>
  203.80 +        public string XAxisKey { get; set; }
  203.81 +
  203.82 +        /// <summary>
  203.83 +        /// Gets the y-axis.
  203.84 +        /// </summary>
  203.85 +        /// <value> The y-axis. </value>
  203.86 +        public Axis YAxis { get; private set; }
  203.87 +
  203.88 +        /// <summary>
  203.89 +        /// Gets or sets the y-axis key.
  203.90 +        /// </summary>
  203.91 +        /// <value> The y-axis key. </value>
  203.92 +        public string YAxisKey { get; set; }
  203.93 +
  203.94 +        /// <summary>
  203.95 +        /// Gets the rectangle the series uses on the screen (screen coordinates).
  203.96 +        /// </summary>
  203.97 +        /// <returns>
  203.98 +        /// The rectangle.
  203.99 +        /// </returns>
 203.100 +        public OxyRect GetScreenRectangle()
 203.101 +        {
 203.102 +            return this.GetClippingRect();
 203.103 +        }
 203.104 +
 203.105 +        /// <summary>
 203.106 +        /// Renders the legend symbol on the specified rendering context.
 203.107 +        /// </summary>
 203.108 +        /// <param name="rc">
 203.109 +        /// The rendering context.
 203.110 +        /// </param>
 203.111 +        /// <param name="legendBox">
 203.112 +        /// The legend rectangle.
 203.113 +        /// </param>
 203.114 +        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 203.115 +        {
 203.116 +        }
 203.117 +
 203.118 +        /// <summary>
 203.119 +        /// Transforms from a screen point to a data point by the axes of this series.
 203.120 +        /// </summary>
 203.121 +        /// <param name="p">
 203.122 +        /// The screen point.
 203.123 +        /// </param>
 203.124 +        /// <returns>
 203.125 +        /// A data point.
 203.126 +        /// </returns>
 203.127 +        public DataPoint InverseTransform(ScreenPoint p)
 203.128 +        {
 203.129 +            return this.XAxis.InverseTransform(p.X, p.Y, this.YAxis);
 203.130 +        }
 203.131 +
 203.132 +        /// <summary>
 203.133 +        /// Transforms the specified coordinates to a screen point by the axes of this series.
 203.134 +        /// </summary>
 203.135 +        /// <param name="x">
 203.136 +        /// The x coordinate.
 203.137 +        /// </param>
 203.138 +        /// <param name="y">
 203.139 +        /// The y coordinate.
 203.140 +        /// </param>
 203.141 +        /// <returns>
 203.142 +        /// A screen point.
 203.143 +        /// </returns>
 203.144 +        public ScreenPoint Transform(double x, double y)
 203.145 +        {
 203.146 +            return this.XAxis.Transform(x, y, this.YAxis);
 203.147 +        }
 203.148 +
 203.149 +        /// <summary>
 203.150 +        /// Transforms the specified data point to a screen point by the axes of this series.
 203.151 +        /// </summary>
 203.152 +        /// <param name="p">
 203.153 +        /// The point.
 203.154 +        /// </param>
 203.155 +        /// <returns>
 203.156 +        /// A screen point.
 203.157 +        /// </returns>
 203.158 +        public ScreenPoint Transform(IDataPoint p)
 203.159 +        {
 203.160 +            return this.XAxis.Transform(p.X, p.Y, this.YAxis);
 203.161 +        }
 203.162 +
 203.163 +        /// <summary>
 203.164 +        /// Check if this data series requires X/Y axes. (e.g. Pie series do not require axes)
 203.165 +        /// </summary>
 203.166 +        /// <returns>
 203.167 +        /// The are axes required.
 203.168 +        /// </returns>
 203.169 +        protected internal override bool AreAxesRequired()
 203.170 +        {
 203.171 +            return true;
 203.172 +        }
 203.173 +
 203.174 +        /// <summary>
 203.175 +        /// Ensures that the axes of the series is defined.
 203.176 +        /// </summary>
 203.177 +        protected internal override void EnsureAxes()
 203.178 +        {
 203.179 +            this.XAxis = PlotModel.GetAxisOrDefault(this.XAxisKey, PlotModel.DefaultXAxis);
 203.180 +            this.YAxis = PlotModel.GetAxisOrDefault(this.YAxisKey, PlotModel.DefaultYAxis);
 203.181 +        }
 203.182 +
 203.183 +        /// <summary>
 203.184 +        /// Check if the data series is using the specified axis.
 203.185 +        /// </summary>
 203.186 +        /// <param name="axis">
 203.187 +        /// An axis.
 203.188 +        /// </param>
 203.189 +        /// <returns>
 203.190 +        /// True if the axis is in use.
 203.191 +        /// </returns>
 203.192 +        protected internal override bool IsUsing(Axis axis)
 203.193 +        {
 203.194 +            return false;
 203.195 +        }
 203.196 +
 203.197 +        /// <summary>
 203.198 +        /// Sets default values from the plot model.
 203.199 +        /// </summary>
 203.200 +        /// <param name="model">
 203.201 +        /// The plot model.
 203.202 +        /// </param>
 203.203 +        protected internal override void SetDefaultValues(PlotModel model)
 203.204 +        {
 203.205 +        }
 203.206 +
 203.207 +        /// <summary>
 203.208 +        /// Updates the axes to include the max and min of this series.
 203.209 +        /// </summary>
 203.210 +        protected internal override void UpdateAxisMaxMin()
 203.211 +        {
 203.212 +            this.XAxis.Include(this.MinX);
 203.213 +            this.XAxis.Include(this.MaxX);
 203.214 +            this.YAxis.Include(this.MinY);
 203.215 +            this.YAxis.Include(this.MaxY);
 203.216 +        }
 203.217 +
 203.218 +        /// <summary>
 203.219 +        /// Updates the data.
 203.220 +        /// </summary>
 203.221 +        protected internal override void UpdateData()
 203.222 +        {
 203.223 +        }
 203.224 +
 203.225 +        /// <summary>
 203.226 +        /// Updates the max/minimum values.
 203.227 +        /// </summary>
 203.228 +        protected internal override void UpdateMaxMin()
 203.229 +        {
 203.230 +            this.MinX = this.MinY = this.MaxX = this.MaxY = double.NaN;
 203.231 +        }
 203.232 +
 203.233 +        /// <summary>
 203.234 +        /// Gets the clipping rectangle.
 203.235 +        /// </summary>
 203.236 +        /// <returns>
 203.237 +        /// The clipping rectangle.
 203.238 +        /// </returns>
 203.239 +        protected OxyRect GetClippingRect()
 203.240 +        {
 203.241 +            double minX = Math.Min(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
 203.242 +            double minY = Math.Min(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
 203.243 +            double maxX = Math.Max(this.XAxis.ScreenMin.X, this.XAxis.ScreenMax.X);
 203.244 +            double maxY = Math.Max(this.YAxis.ScreenMin.Y, this.YAxis.ScreenMax.Y);
 203.245 +
 203.246 +            return new OxyRect(minX, minY, maxX - minX, maxY - minY);
 203.247 +        }
 203.248 +
 203.249 +        /// <summary>
 203.250 +        /// Gets the point on the curve that is nearest the specified point.
 203.251 +        /// </summary>
 203.252 +        /// <param name="points">
 203.253 +        /// The point list.
 203.254 +        /// </param>
 203.255 +        /// <param name="point">
 203.256 +        /// The point.
 203.257 +        /// </param>
 203.258 +        /// <returns>
 203.259 +        /// A tracker hit result if a point was found.
 203.260 +        /// </returns>
 203.261 +        protected TrackerHitResult GetNearestInterpolatedPointInternal(IList<IDataPoint> points, ScreenPoint point)
 203.262 +        {
 203.263 +            if (this.XAxis == null || this.YAxis == null || points == null)
 203.264 +            {
 203.265 +                return null;
 203.266 +            }
 203.267 +
 203.268 +            var spn = default(ScreenPoint);
 203.269 +            var dpn = default(DataPoint);
 203.270 +            double index = -1;
 203.271 +
 203.272 +            double minimumDistance = double.MaxValue;
 203.273 +
 203.274 +            for (int i = 0; i + 1 < points.Count; i++)
 203.275 +            {
 203.276 +                var p1 = points[i];
 203.277 +                var p2 = points[i + 1];
 203.278 +                if (!this.IsValidPoint(p1, this.XAxis, this.YAxis) || !this.IsValidPoint(p2, this.XAxis, this.YAxis))
 203.279 +                {
 203.280 +                    continue;
 203.281 +                }
 203.282 +
 203.283 +                var sp1 = this.Transform(p1);
 203.284 +                var sp2 = this.Transform(p2);
 203.285 +
 203.286 +                // Find the nearest point on the line segment.
 203.287 +                var spl = ScreenPointHelper.FindPointOnLine(point, sp1, sp2);
 203.288 +
 203.289 +                if (ScreenPoint.IsUndefined(spl))
 203.290 +                {
 203.291 +                    // P1 && P2 coincident
 203.292 +                    continue;
 203.293 +                }
 203.294 +
 203.295 +                double l2 = (point - spl).LengthSquared;
 203.296 +
 203.297 +                if (l2 < minimumDistance)
 203.298 +                {
 203.299 +                    double u = (spl - sp1).Length / (sp2 - sp1).Length;
 203.300 +                    dpn = new DataPoint(p1.X + (u * (p2.X - p1.X)), p1.Y + (u * (p2.Y - p1.Y)));
 203.301 +                    spn = spl;
 203.302 +                    minimumDistance = l2;
 203.303 +                    index = i + u;
 203.304 +                }
 203.305 +            }
 203.306 +
 203.307 +            if (minimumDistance < double.MaxValue)
 203.308 +            {
 203.309 +                object item = this.GetItem((int)index);
 203.310 +                return new TrackerHitResult(this, dpn, spn, item) { Index = index };
 203.311 +            }
 203.312 +
 203.313 +            return null;
 203.314 +        }
 203.315 +
 203.316 +        /// <summary>
 203.317 +        /// Gets the nearest point.
 203.318 +        /// </summary>
 203.319 +        /// <param name="points">
 203.320 +        /// The points (data coordinates).
 203.321 +        /// </param>
 203.322 +        /// <param name="point">
 203.323 +        /// The point (screen coordinates).
 203.324 +        /// </param>
 203.325 +        /// <returns>
 203.326 +        /// A <see cref="TrackerHitResult"/> if a point was found, null otherwise.
 203.327 +        /// </returns>
 203.328 +        protected TrackerHitResult GetNearestPointInternal(IEnumerable<IDataPoint> points, ScreenPoint point)
 203.329 +        {
 203.330 +            var spn = default(ScreenPoint);
 203.331 +            IDataPoint dpn = default(DataPoint);
 203.332 +            double index = -1;
 203.333 +
 203.334 +            double minimumDistance = double.MaxValue;
 203.335 +            int i = 0;
 203.336 +            foreach (var p in points)
 203.337 +            {
 203.338 +                if (!this.IsValidPoint(p, this.XAxis, this.YAxis))
 203.339 +                {
 203.340 +                    continue;
 203.341 +                }
 203.342 +
 203.343 +                var sp = Axis.Transform(p, this.XAxis, this.YAxis);
 203.344 +                double d2 = (sp - point).LengthSquared;
 203.345 +
 203.346 +                if (d2 < minimumDistance)
 203.347 +                {
 203.348 +                    dpn = p;
 203.349 +                    spn = sp;
 203.350 +                    minimumDistance = d2;
 203.351 +                    index = i;
 203.352 +                }
 203.353 +
 203.354 +                i++;
 203.355 +            }
 203.356 +
 203.357 +            if (minimumDistance < double.MaxValue)
 203.358 +            {
 203.359 +                object item = this.GetItem((int)index);
 203.360 +                return new TrackerHitResult(this, dpn, spn, item) { Index = index };
 203.361 +            }
 203.362 +
 203.363 +            return null;
 203.364 +        }
 203.365 +
 203.366 +        /// <summary>
 203.367 +        /// Determines whether the specified point is valid.
 203.368 +        /// </summary>
 203.369 +        /// <param name="pt">
 203.370 +        /// The point.
 203.371 +        /// </param>
 203.372 +        /// <param name="xaxis">
 203.373 +        /// The x axis.
 203.374 +        /// </param>
 203.375 +        /// <param name="yaxis">
 203.376 +        /// The y axis.
 203.377 +        /// </param>
 203.378 +        /// <returns>
 203.379 +        /// <c>true</c> if the point is valid; otherwise, <c>false</c> .
 203.380 +        /// </returns>
 203.381 +        protected virtual bool IsValidPoint(IDataPoint pt, Axis xaxis, Axis yaxis)
 203.382 +        {
 203.383 +            return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y)
 203.384 +                   && (xaxis != null && xaxis.IsValidValue(pt.X)) && (yaxis != null && yaxis.IsValidValue(pt.Y));
 203.385 +        }
 203.386 +
 203.387 +        /// <summary>
 203.388 +        /// Converts the value of the specified object to a double precision floating point number. DateTime objects are converted using DateTimeAxis.ToDouble and TimeSpan objects are converted using TimeSpanAxis.ToDouble
 203.389 +        /// </summary>
 203.390 +        /// <param name="value">
 203.391 +        /// The value.
 203.392 +        /// </param>
 203.393 +        /// <returns>
 203.394 +        /// The floating point number value.
 203.395 +        /// </returns>
 203.396 +        protected virtual double ToDouble(object value)
 203.397 +        {
 203.398 +            if (value is DateTime)
 203.399 +            {
 203.400 +                return DateTimeAxis.ToDouble((DateTime)value);
 203.401 +            }
 203.402 +
 203.403 +            if (value is TimeSpan)
 203.404 +            {
 203.405 +                return ((TimeSpan)value).TotalSeconds;
 203.406 +            }
 203.407 +
 203.408 +            return Convert.ToDouble(value);
 203.409 +        }
 203.410 +
 203.411 +        /// <summary>
 203.412 +        /// Verifies that both axes are defined.
 203.413 +        /// </summary>
 203.414 +        protected void VerifyAxes()
 203.415 +        {
 203.416 +            if (this.XAxis == null)
 203.417 +            {
 203.418 +                throw new InvalidOperationException("XAxis not defined.");
 203.419 +            }
 203.420 +
 203.421 +            if (this.YAxis == null)
 203.422 +            {
 203.423 +                throw new InvalidOperationException("YAxis not defined.");
 203.424 +            }
 203.425 +        }
 203.426 +    }
 203.427 +}
 203.428 \ No newline at end of file
   204.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   204.2 +++ b/External/OxyPlot/OxyPlot/Svg/NativeMethods.cs	Sat Jun 08 16:53:22 2013 +0000
   204.3 @@ -0,0 +1,246 @@
   204.4 +// --------------------------------------------------------------------------------------------------------------------
   204.5 +// <copyright file="NativeMethods.cs" company="OxyPlot">
   204.6 +//   The MIT License (MIT)
   204.7 +//
   204.8 +//   Copyright (c) 2012 Oystein Bjorke
   204.9 +//
  204.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  204.11 +//   copy of this software and associated documentation files (the
  204.12 +//   "Software"), to deal in the Software without restriction, including
  204.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  204.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  204.15 +//   permit persons to whom the Software is furnished to do so, subject to
  204.16 +//   the following conditions:
  204.17 +//
  204.18 +//   The above copyright notice and this permission notice shall be included
  204.19 +//   in all copies or substantial portions of the Software.
  204.20 +//
  204.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  204.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  204.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  204.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  204.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  204.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  204.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  204.28 +// </copyright>
  204.29 +// <summary>
  204.30 +//   Interface to GDI32 native methods.
  204.31 +// </summary>
  204.32 +// --------------------------------------------------------------------------------------------------------------------
  204.33 +namespace OxyPlot
  204.34 +{
  204.35 +    using System;
  204.36 +    using System.Runtime.InteropServices;
  204.37 +    using System.Text.RegularExpressions;
  204.38 +
  204.39 +    /// <summary>
  204.40 +    /// Provides access to native graphics methods.
  204.41 +    /// </summary>
  204.42 +    public class NativeMethods
  204.43 +    {
  204.44 +        /// <summary>
  204.45 +        /// The delete dc.
  204.46 +        /// </summary>
  204.47 +        /// <param name="hdc">
  204.48 +        /// The hdc.
  204.49 +        /// </param>
  204.50 +        /// <returns>
  204.51 +        /// The delete dc.
  204.52 +        /// </returns>
  204.53 +        [DllImport("gdi32.dll")]
  204.54 +        internal static extern bool DeleteDC(IntPtr hdc);
  204.55 +
  204.56 +        /// <summary>
  204.57 +        /// The delete object.
  204.58 +        /// </summary>
  204.59 +        /// <param name="hgdiobj">
  204.60 +        /// The hgdiobj.
  204.61 +        /// </param>
  204.62 +        /// <returns>
  204.63 +        /// The delete object.
  204.64 +        /// </returns>
  204.65 +        [DllImport("gdi32.dll")]
  204.66 +        internal static extern int DeleteObject(IntPtr hgdiobj);
  204.67 +
  204.68 +        /// <summary>
  204.69 +        /// The get dc.
  204.70 +        /// </summary>
  204.71 +        /// <param name="hWnd">
  204.72 +        /// The h wnd.
  204.73 +        /// </param>
  204.74 +        /// <returns>
  204.75 +        /// </returns>
  204.76 +        [DllImport("user32.dll")]
  204.77 +        internal static extern IntPtr GetDC(IntPtr hWnd);
  204.78 +
  204.79 +        /// <summary>
  204.80 +        /// The get text extent point 32.
  204.81 +        /// </summary>
  204.82 +        /// <param name="hdc">
  204.83 +        /// The hdc.
  204.84 +        /// </param>
  204.85 +        /// <param name="str">
  204.86 +        /// The str.
  204.87 +        /// </param>
  204.88 +        /// <param name="len">
  204.89 +        /// The len.
  204.90 +        /// </param>
  204.91 +        /// <param name="siz">
  204.92 +        /// The siz.
  204.93 +        /// </param>
  204.94 +        /// <returns>
  204.95 +        /// The get text extent point 32.
  204.96 +        /// </returns>
  204.97 +        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
  204.98 +        internal static extern int GetTextExtentPoint32(IntPtr hdc, string str, int len, ref Size siz);
  204.99 +
 204.100 +        /// <summary>
 204.101 +        /// The measure string.
 204.102 +        /// </summary>
 204.103 +        /// <param name="faceName">
 204.104 +        /// The font face name.
 204.105 +        /// </param>
 204.106 +        /// <param name="height">
 204.107 +        /// The height.
 204.108 +        /// </param>
 204.109 +        /// <param name="weight">
 204.110 +        /// The weight.
 204.111 +        /// </param>
 204.112 +        /// <param name="str">
 204.113 +        /// The string.
 204.114 +        /// </param>
 204.115 +        /// <returns>
 204.116 +        /// The size of the rendered string.
 204.117 +        /// </returns>
 204.118 +        public static OxySize MeasureString(string faceName, int height, int weight, string str)
 204.119 +        {
 204.120 +            var lines = Regex.Split(str, "\r\n");
 204.121 +            OxySize result = new OxySize(0, 0);
 204.122 +            foreach (var line in lines)
 204.123 +            {
 204.124 +                var hfont = CreateFont(height, 0, 0, 0, weight, 0, 0, 0, 0, 0, 0, 0, 0, faceName);
 204.125 +                var hdc = GetDC(IntPtr.Zero);
 204.126 +                var oldobj = SelectObject(hdc, hfont);
 204.127 +                var temp = GetTextExtent(hdc, line);
 204.128 +                SelectObject(hdc, oldobj);
 204.129 +                DeleteObject(hfont);
 204.130 +                DeleteDC(hdc);
 204.131 +                var lineSpacing = temp.Height / 3.0;
 204.132 +                result.Height += temp.Height + lineSpacing;
 204.133 +                result.Width = Math.Max(temp.Width * 1.28, result.Width);
 204.134 +            }
 204.135 +
 204.136 +            return result;
 204.137 +        }
 204.138 +
 204.139 +        /// <summary>
 204.140 +        /// The select object.
 204.141 +        /// </summary>
 204.142 +        /// <param name="hdc">
 204.143 +        /// The hdc.
 204.144 +        /// </param>
 204.145 +        /// <param name="hgdiObj">
 204.146 +        /// The hgdi obj.
 204.147 +        /// </param>
 204.148 +        /// <returns>
 204.149 +        /// </returns>
 204.150 +        [DllImport("gdi32.dll")]
 204.151 +        internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiObj);
 204.152 +
 204.153 +        /// <summary>
 204.154 +        /// The create font.
 204.155 +        /// </summary>
 204.156 +        /// <param name="nHeight">
 204.157 +        /// The n height.
 204.158 +        /// </param>
 204.159 +        /// <param name="nWidth">
 204.160 +        /// The n width.
 204.161 +        /// </param>
 204.162 +        /// <param name="nEscapement">
 204.163 +        /// The n escapement.
 204.164 +        /// </param>
 204.165 +        /// <param name="nOrientation">
 204.166 +        /// The n orientation.
 204.167 +        /// </param>
 204.168 +        /// <param name="fnWeight">
 204.169 +        /// The fn weight.
 204.170 +        /// </param>
 204.171 +        /// <param name="fdwItalic">
 204.172 +        /// The fdw italic.
 204.173 +        /// </param>
 204.174 +        /// <param name="fdwUnderline">
 204.175 +        /// The fdw underline.
 204.176 +        /// </param>
 204.177 +        /// <param name="fdwStrikeOut">
 204.178 +        /// The fdw strike out.
 204.179 +        /// </param>
 204.180 +        /// <param name="fdwCharSet">
 204.181 +        /// The fdw char set.
 204.182 +        /// </param>
 204.183 +        /// <param name="fdwOutputPrecision">
 204.184 +        /// The fdw output precision.
 204.185 +        /// </param>
 204.186 +        /// <param name="fdwClipPrecision">
 204.187 +        /// The fdw clip precision.
 204.188 +        /// </param>
 204.189 +        /// <param name="fdwQuality">
 204.190 +        /// The fdw quality.
 204.191 +        /// </param>
 204.192 +        /// <param name="fdwPitchAndFamily">
 204.193 +        /// The fdw pitch and family.
 204.194 +        /// </param>
 204.195 +        /// <param name="lpszFace">
 204.196 +        /// The lpsz face.
 204.197 +        /// </param>
 204.198 +        /// <returns>
 204.199 +        /// </returns>
 204.200 +        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
 204.201 +        private static extern IntPtr CreateFont(
 204.202 +            int nHeight,
 204.203 +            int nWidth,
 204.204 +            int nEscapement,
 204.205 +            int nOrientation,
 204.206 +            int fnWeight,
 204.207 +            uint fdwItalic,
 204.208 +            uint fdwUnderline,
 204.209 +            uint fdwStrikeOut,
 204.210 +            uint fdwCharSet,
 204.211 +            uint fdwOutputPrecision,
 204.212 +            uint fdwClipPrecision,
 204.213 +            uint fdwQuality,
 204.214 +            uint fdwPitchAndFamily,
 204.215 +            string lpszFace);
 204.216 +
 204.217 +        /// <summary>
 204.218 +        /// Gets the text extent.
 204.219 +        /// </summary>
 204.220 +        /// <param name="hdc">The HDC.</param>
 204.221 +        /// <param name="str">The STR.</param>
 204.222 +        /// <returns></returns>
 204.223 +        private static OxySize GetTextExtent(IntPtr hdc, string str)
 204.224 +        {
 204.225 +            Size sz = default(Size);
 204.226 +            sz.cx = 0;
 204.227 +            sz.cy = 0;
 204.228 +            GetTextExtentPoint32(hdc, str, str.Length, ref sz);
 204.229 +            return new OxySize(sz.cx, sz.cy);
 204.230 +        }
 204.231 +
 204.232 +        /// <summary>
 204.233 +        /// The size.
 204.234 +        /// </summary>
 204.235 +        [StructLayout(LayoutKind.Sequential)]
 204.236 +        public struct Size
 204.237 +        {
 204.238 +            /// <summary>
 204.239 +            /// The cx.
 204.240 +            /// </summary>
 204.241 +            public int cx;
 204.242 +
 204.243 +            /// <summary>
 204.244 +            /// The cy.
 204.245 +            /// </summary>
 204.246 +            public int cy;
 204.247 +        }
 204.248 +    }
 204.249 +}
 204.250 \ No newline at end of file
   205.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   205.2 +++ b/External/OxyPlot/OxyPlot/Svg/SvgExporter.cs	Sat Jun 08 16:53:22 2013 +0000
   205.3 @@ -0,0 +1,85 @@
   205.4 +// --------------------------------------------------------------------------------------------------------------------
   205.5 +// <copyright file="SvgExporter.cs" company="OxyPlot">
   205.6 +//   The MIT License (MIT)
   205.7 +//
   205.8 +//   Copyright (c) 2012 Oystein Bjorke
   205.9 +//
  205.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  205.11 +//   copy of this software and associated documentation files (the
  205.12 +//   "Software"), to deal in the Software without restriction, including
  205.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  205.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  205.15 +//   permit persons to whom the Software is furnished to do so, subject to
  205.16 +//   the following conditions:
  205.17 +//
  205.18 +//   The above copyright notice and this permission notice shall be included
  205.19 +//   in all copies or substantial portions of the Software.
  205.20 +//
  205.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  205.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  205.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  205.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  205.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  205.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  205.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  205.28 +// </copyright>
  205.29 +// <summary>
  205.30 +//   Exports plot models to svg.
  205.31 +// </summary>
  205.32 +// --------------------------------------------------------------------------------------------------------------------
  205.33 +namespace OxyPlot
  205.34 +{
  205.35 +    using System.IO;
  205.36 +
  205.37 +    /// <summary>
  205.38 +    /// Exports plots to scalable vector graphics.
  205.39 +    /// </summary>
  205.40 +    public static class SvgExporter
  205.41 +    {
  205.42 +        /// <summary>
  205.43 +        /// Exports the specified model to a stream.
  205.44 +        /// </summary>
  205.45 +        /// <param name="model">The model.</param>
  205.46 +        /// <param name="stream">The output stream.</param>
  205.47 +        /// <param name="width">The width (points).</param>
  205.48 +        /// <param name="height">The height (points).</param>
  205.49 +        /// <param name="isDocument">if set to <c>true</c>, the xml headers will be included (?xml and !DOCTYPE).</param>
  205.50 +        /// <param name="textMeasurer">The text measurer.</param>
  205.51 +        public static void Export(PlotModel model, Stream stream, double width, double height, bool isDocument, IRenderContext textMeasurer)
  205.52 +        {
  205.53 +            using (var rc = new SvgRenderContext(stream, width, height, true, textMeasurer, model.Background))
  205.54 +            {
  205.55 +                model.Update();
  205.56 +                model.Render(rc, width, height);
  205.57 +                rc.Complete();
  205.58 +                rc.Flush();
  205.59 +            }
  205.60 +        }
  205.61 +
  205.62 +        /// <summary>
  205.63 +        /// Exports to string.
  205.64 +        /// </summary>
  205.65 +        /// <param name="model">The model.</param>
  205.66 +        /// <param name="width">The width (points).</param>
  205.67 +        /// <param name="height">The height (points).</param>
  205.68 +        /// <param name="isDocument">if set to <c>true</c>, the xml headers will be included (?xml and !DOCTYPE).</param>
  205.69 +        /// <param name="textMeasurer">The text measurer.</param>
  205.70 +        /// <returns>
  205.71 +        /// The plot as a svg string.
  205.72 +        /// </returns>
  205.73 +        public static string ExportToString(PlotModel model, double width, double height, bool isDocument, IRenderContext textMeasurer)
  205.74 +        {
  205.75 +            string svg;
  205.76 +            using (var ms = new MemoryStream())
  205.77 +            {
  205.78 +                Export(model, ms, width, height, isDocument, textMeasurer);
  205.79 +                ms.Flush();
  205.80 +                ms.Position = 0;
  205.81 +                var sr = new StreamReader(ms);
  205.82 +                svg = sr.ReadToEnd();
  205.83 +            }
  205.84 +
  205.85 +            return svg;
  205.86 +        }
  205.87 +    }
  205.88 +}
  205.89 \ No newline at end of file
   206.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.2 +++ b/External/OxyPlot/OxyPlot/Svg/SvgRenderContext.cs	Sat Jun 08 16:53:22 2013 +0000
   206.3 @@ -0,0 +1,278 @@
   206.4 +// --------------------------------------------------------------------------------------------------------------------
   206.5 +// <copyright file="SvgRenderContext.cs" company="OxyPlot">
   206.6 +//   The MIT License (MIT)
   206.7 +//
   206.8 +//   Copyright (c) 2012 Oystein Bjorke
   206.9 +//
  206.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  206.11 +//   copy of this software and associated documentation files (the
  206.12 +//   "Software"), to deal in the Software without restriction, including
  206.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  206.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  206.15 +//   permit persons to whom the Software is furnished to do so, subject to
  206.16 +//   the following conditions:
  206.17 +//
  206.18 +//   The above copyright notice and this permission notice shall be included
  206.19 +//   in all copies or substantial portions of the Software.
  206.20 +//
  206.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  206.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  206.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  206.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  206.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  206.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  206.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  206.28 +// </copyright>
  206.29 +// <summary>
  206.30 +//   The svg render context.
  206.31 +// </summary>
  206.32 +// --------------------------------------------------------------------------------------------------------------------
  206.33 +namespace OxyPlot
  206.34 +{
  206.35 +    using System;
  206.36 +    using System.Collections.Generic;
  206.37 +    using System.IO;
  206.38 +    using System.Text.RegularExpressions;
  206.39 +
  206.40 +    /// <summary>
  206.41 +    /// Provides a render context for scalable vector graphics output.
  206.42 +    /// </summary>
  206.43 +    public class SvgRenderContext : RenderContextBase, IDisposable
  206.44 +    {
  206.45 +        /// <summary>
  206.46 +        /// The writer.
  206.47 +        /// </summary>
  206.48 +        private readonly SvgWriter w;
  206.49 +
  206.50 +        /// <summary>
  206.51 +        /// The disposed flag.
  206.52 +        /// </summary>
  206.53 +        private bool disposed;
  206.54 +
  206.55 +        /// <summary>
  206.56 +        /// Initializes a new instance of the <see cref="SvgRenderContext" /> class.
  206.57 +        /// </summary>
  206.58 +        /// <param name="s">The s.</param>
  206.59 +        /// <param name="width">The width.</param>
  206.60 +        /// <param name="height">The height.</param>
  206.61 +        /// <param name="isDocument">Create an SVG document if set to <c>true</c>.</param>
  206.62 +        /// <param name="textMeasurer">The text measurer.</param>
  206.63 +        /// <param name="background">The background.</param>
  206.64 +        public SvgRenderContext(Stream s, double width, double height, bool isDocument, IRenderContext textMeasurer, OxyColor background)
  206.65 +        {
  206.66 +            if (textMeasurer == null)
  206.67 +            {
  206.68 +                throw new ArgumentNullException("textMeasurer", "A text measuring render context must be provided.");
  206.69 +            }
  206.70 +
  206.71 +            this.w = new SvgWriter(s, width, height, isDocument);
  206.72 +            this.TextMeasurer = textMeasurer;
  206.73 +            if (background != null)
  206.74 +            {
  206.75 +                this.w.WriteRectangle(0, 0, width, height, this.w.CreateStyle(background, null, 0));
  206.76 +            }
  206.77 +        }
  206.78 +
  206.79 +        /// <summary>
  206.80 +        /// Gets or sets the text measurer.
  206.81 +        /// </summary>
  206.82 +        /// <value>
  206.83 +        /// The text measurer.
  206.84 +        /// </value>
  206.85 +        public IRenderContext TextMeasurer { get; set; }
  206.86 +
  206.87 +        /// <summary>
  206.88 +        /// Closes the svg writer.
  206.89 +        /// </summary>
  206.90 +        public void Close()
  206.91 +        {
  206.92 +            this.w.Close();
  206.93 +        }
  206.94 +
  206.95 +        /// <summary>
  206.96 +        /// Completes the svg element.
  206.97 +        /// </summary>
  206.98 +        public void Complete()
  206.99 +        {
 206.100 +            this.w.Complete();
 206.101 +        }
 206.102 +
 206.103 +        /// <summary>
 206.104 +        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 206.105 +        /// </summary>
 206.106 +        public void Dispose()
 206.107 +        {
 206.108 +            this.Dispose(true);
 206.109 +            GC.SuppressFinalize(this);
 206.110 +        }
 206.111 +
 206.112 +        /// <summary>
 206.113 +        /// Draws an ellipse.
 206.114 +        /// </summary>
 206.115 +        /// <param name="rect">The rectangle.</param>
 206.116 +        /// <param name="fill">The fill color.</param>
 206.117 +        /// <param name="stroke">The stroke color.</param>
 206.118 +        /// <param name="thickness">The thickness.</param>
 206.119 +        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
 206.120 +        {
 206.121 +            this.w.WriteEllipse(
 206.122 +                rect.Left, rect.Top, rect.Width, rect.Height, this.w.CreateStyle(fill, stroke, thickness));
 206.123 +        }
 206.124 +
 206.125 +        /// <summary>
 206.126 +        /// Draws the polyline from the specified points.
 206.127 +        /// </summary>
 206.128 +        /// <param name="points">The points.</param>
 206.129 +        /// <param name="stroke">The stroke color.</param>
 206.130 +        /// <param name="thickness">The stroke thickness.</param>
 206.131 +        /// <param name="dashArray">The dash array.</param>
 206.132 +        /// <param name="lineJoin">The line join type.</param>
 206.133 +        /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
 206.134 +        public override void DrawLine(
 206.135 +            IList<ScreenPoint> points,
 206.136 +            OxyColor stroke,
 206.137 +            double thickness,
 206.138 +            double[] dashArray,
 206.139 +            OxyPenLineJoin lineJoin,
 206.140 +            bool aliased)
 206.141 +        {
 206.142 +            this.w.WritePolyline(points, this.w.CreateStyle(null, stroke, thickness, dashArray, lineJoin));
 206.143 +        }
 206.144 +
 206.145 +        /// <summary>
 206.146 +        /// Draws the polygon from the specified points. The polygon can have stroke and/or fill.
 206.147 +        /// </summary>
 206.148 +        /// <param name="points">The points.</param>
 206.149 +        /// <param name="fill">The fill color.</param>
 206.150 +        /// <param name="stroke">The stroke color.</param>
 206.151 +        /// <param name="thickness">The stroke thickness.</param>
 206.152 +        /// <param name="dashArray">The dash array.</param>
 206.153 +        /// <param name="lineJoin">The line join type.</param>
 206.154 +        /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
 206.155 +        public override void DrawPolygon(
 206.156 +            IList<ScreenPoint> points,
 206.157 +            OxyColor fill,
 206.158 +            OxyColor stroke,
 206.159 +            double thickness,
 206.160 +            double[] dashArray,
 206.161 +            OxyPenLineJoin lineJoin,
 206.162 +            bool aliased)
 206.163 +        {
 206.164 +            this.w.WritePolygon(points, this.w.CreateStyle(fill, stroke, thickness, dashArray, lineJoin));
 206.165 +        }
 206.166 +
 206.167 +        /// <summary>
 206.168 +        /// Draws the rectangle.
 206.169 +        /// </summary>
 206.170 +        /// <param name="rect">The rectangle.</param>
 206.171 +        /// <param name="fill">The fill color.</param>
 206.172 +        /// <param name="stroke">The stroke color.</param>
 206.173 +        /// <param name="thickness">The stroke thickness.</param>
 206.174 +        public override void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
 206.175 +        {
 206.176 +            this.w.WriteRectangle(
 206.177 +                rect.Left, rect.Top, rect.Width, rect.Height, this.w.CreateStyle(fill, stroke, thickness));
 206.178 +        }
 206.179 +
 206.180 +        /// <summary>
 206.181 +        /// Draws the text.
 206.182 +        /// </summary>
 206.183 +        /// <param name="p">The p.</param>
 206.184 +        /// <param name="text">The text.</param>
 206.185 +        /// <param name="c">The c.</param>
 206.186 +        /// <param name="fontFamily">The font family.</param>
 206.187 +        /// <param name="fontSize">Size of the font.</param>
 206.188 +        /// <param name="fontWeight">The font weight.</param>
 206.189 +        /// <param name="rotate">The rotate.</param>
 206.190 +        /// <param name="halign">The horizontal alignment.</param>
 206.191 +        /// <param name="valign">The vertical alignment.</param>
 206.192 +        /// <param name="maxSize">Size of the max.</param>
 206.193 +        public override void DrawText(
 206.194 +            ScreenPoint p,
 206.195 +            string text,
 206.196 +            OxyColor c,
 206.197 +            string fontFamily,
 206.198 +            double fontSize,
 206.199 +            double fontWeight,
 206.200 +            double rotate,
 206.201 +            HorizontalAlignment halign,
 206.202 +            VerticalAlignment valign,
 206.203 +            OxySize? maxSize)
 206.204 +        {
 206.205 +            if (string.IsNullOrEmpty(text))
 206.206 +            {
 206.207 +                return;
 206.208 +            }
 206.209 +
 206.210 +            var lines = Regex.Split(text, "\r\n");
 206.211 +            if (valign == VerticalAlignment.Bottom)
 206.212 +            {
 206.213 +                for (var i = lines.Length - 1; i >= 0; i--)
 206.214 +                {
 206.215 +                    var line = lines[i];
 206.216 +                    var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
 206.217 +                    this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);
 206.218 +
 206.219 +                    p.X += Math.Sin(rotate / 180.0 * Math.PI) * size.Height;
 206.220 +                    p.Y -= Math.Cos(rotate / 180.0 * Math.PI) * size.Height;
 206.221 +                }
 206.222 +            }
 206.223 +            else
 206.224 +            {
 206.225 +                foreach (var line in lines)
 206.226 +                {
 206.227 +                    var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
 206.228 +                    this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);
 206.229 +
 206.230 +                    p.X -= Math.Sin(rotate / 180.0 * Math.PI) * size.Height;
 206.231 +                    p.Y += Math.Cos(rotate / 180.0 * Math.PI) * size.Height;
 206.232 +                }
 206.233 +            }
 206.234 +        }
 206.235 +
 206.236 +        /// <summary>
 206.237 +        /// Flushes this instance.
 206.238 +        /// </summary>
 206.239 +        public void Flush()
 206.240 +        {
 206.241 +            this.w.Flush();
 206.242 +        }
 206.243 +
 206.244 +        /// <summary>
 206.245 +        /// Measures the text.
 206.246 +        /// </summary>
 206.247 +        /// <param name="text">The text.</param>
 206.248 +        /// <param name="fontFamily">The font family.</param>
 206.249 +        /// <param name="fontSize">Size of the font.</param>
 206.250 +        /// <param name="fontWeight">The font weight.</param>
 206.251 +        /// <returns>
 206.252 +        /// The text size.
 206.253 +        /// </returns>
 206.254 +        public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight)
 206.255 +        {
 206.256 +            if (string.IsNullOrEmpty(text))
 206.257 +            {
 206.258 +                return OxySize.Empty;
 206.259 +            }
 206.260 +
 206.261 +            return this.TextMeasurer.MeasureText(text, fontFamily, fontSize, fontWeight);
 206.262 +        }
 206.263 +
 206.264 +        /// <summary>
 206.265 +        /// Releases unmanaged and - optionally - managed resources
 206.266 +        /// </summary>
 206.267 +        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
 206.268 +        private void Dispose(bool disposing)
 206.269 +        {
 206.270 +            if (!this.disposed)
 206.271 +            {
 206.272 +                if (disposing)
 206.273 +                {
 206.274 +                    this.w.Dispose();
 206.275 +                }
 206.276 +            }
 206.277 +
 206.278 +            this.disposed = true;
 206.279 +        }
 206.280 +    }
 206.281 +}
 206.282 \ No newline at end of file
   207.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   207.2 +++ b/External/OxyPlot/OxyPlot/Svg/SvgWriter.cs	Sat Jun 08 16:53:22 2013 +0000
   207.3 @@ -0,0 +1,502 @@
   207.4 +// --------------------------------------------------------------------------------------------------------------------
   207.5 +// <copyright file="SvgWriter.cs" company="OxyPlot">
   207.6 +//   The MIT License (MIT)
   207.7 +//
   207.8 +//   Copyright (c) 2012 Oystein Bjorke
   207.9 +//
  207.10 +//   Permission is hereby granted, free of charge, to any person obtaining a
  207.11 +//   copy of this software and associated documentation files (the
  207.12 +//   "Software"), to deal in the Software without restriction, including
  207.13 +//   without limitation the rights to use, copy, modify, merge, publish,
  207.14 +//   distribute, sublicense, and/or sell copies of the Software, and to
  207.15 +//   permit persons to whom the Software is furnished to do so, subject to
  207.16 +//   the following conditions:
  207.17 +//
  207.18 +//   The above copyright notice and this permission notice shall be included
  207.19 +//   in all copies or substantial portions of the Software.
  207.20 +//
  207.21 +//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  207.22 +//   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  207.23 +//   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  207.24 +//   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  207.25 +//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  207.26 +//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  207.27 +//   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  207.28 +// </copyright>
  207.29 +// <summary>
  207.30 +//   Scalable Vector Graphics writer.
  207.31 +// </summary>
  207.32 +// --------------------------------------------------------------------------------------------------------------------
  207.33 +namespace OxyPlot
  207.34 +{
  207.35 +    using System;
  207.36 +    using System.Collections.Generic;
  207.37 +    using System.Globalization;
  207.38 +    using System.IO;
  207.39 +    using System.Text;
  207.40 +
  207.41 +    /// <summary>
  207.42 +    /// Represents a writer that provides easy generation of Scalable Vector Graphics files.
  207.43 +    /// </summary>
  207.44 +    public class SvgWriter : XmlWriterBase
  207.45 +    {
  207.46 +        /// <summary>
  207.47 +        /// The end is written.
  207.48 +        /// </summary>
  207.49 +        private bool endIsWritten;
  207.50 +
  207.51 +        /// <summary>
  207.52 +        /// Initializes a new instance of the <see cref="SvgWriter"/> class.
  207.53 +        /// </summary>
  207.54 +        /// <param name="stream">
  207.55 +        /// The stream.
  207.56 +        /// </param>
  207.57 +        /// <param name="width">
  207.58 +        /// The width.
  207.59 +        /// </param>
  207.60 +        /// <param name="height">
  207.61 +        /// The height.
  207.62 +        /// </param>
  207.63 +        /// <param name="isDocument">
  207.64 +        /// if set to <c>true</c>, the writer will write the xml headers (?xml and !DOCTYPE).
  207.65 +        /// </param>
  207.66 +        public SvgWriter(Stream stream, double width, double height, bool isDocument = true)
  207.67 +            : base(stream)
  207.68 +        {
  207.69 +            this.IsDocument = isDocument;
  207.70 +            this.NumberFormat = "0.####";
  207.71 +            this.WriteHeader(width, height);
  207.72 +        }
  207.73 +
  207.74 +        /// <summary>
  207.75 +        /// Gets or sets a value indicating whether this writer should produce a stand-alone document.
  207.76 +        /// </summary>
  207.77 +        public bool IsDocument { get; set; }
  207.78 +
  207.79 +        /// <summary>
  207.80 +        /// Gets or sets the number format.
  207.81 +        /// </summary>
  207.82 +        /// <value>The number format.</value>
  207.83 +        public string NumberFormat { get; set; }
  207.84 +
  207.85 +        /// <summary>
  207.86 +        /// Closes the svg document.
  207.87 +        /// </summary>
  207.88 +        public override void Close()
  207.89 +        {
  207.90 +            if (!this.endIsWritten)
  207.91 +            {
  207.92 +                this.Complete();
  207.93 +            }
  207.94 +
  207.95 +            base.Close();
  207.96 +        }
  207.97 +
  207.98 +        /// <summary>
  207.99 +        /// Writes the end of the document.
 207.100 +        /// </summary>
 207.101 +        public void Complete()
 207.102 +        {
 207.103 +            this.WriteEndElement();
 207.104 +            if (this.IsDocument)
 207.105 +            {
 207.106 +                this.WriteEndDocument();
 207.107 +            }
 207.108 +
 207.109 +            this.endIsWritten = true;
 207.110 +        }
 207.111 +
 207.112 +        /// <summary>
 207.113 +        /// Creates a style.
 207.114 +        /// </summary>
 207.115 +        /// <param name="fill">
 207.116 +        /// The fill color.
 207.117 +        /// </param>
 207.118 +        /// <param name="stroke">
 207.119 +        /// The stroke color.
 207.120 +        /// </param>
 207.121 +        /// <param name="thickness">
 207.122 +        /// The stroke thickness.
 207.123 +        /// </param>
 207.124 +        /// <param name="dashArray">
 207.125 +        /// The line dash array.
 207.126 +        /// </param>
 207.127 +        /// <param name="lineJoin">
 207.128 +        /// The line join type.
 207.129 +        /// </param>
 207.130 +        /// <returns>
 207.131 +        /// A style string.
 207.132 +        /// </returns>
 207.133 +        public string CreateStyle(
 207.134 +            OxyColor fill,
 207.135 +            OxyColor stroke,
 207.136 +            double thickness,
 207.137 +            double[] dashArray = null,
 207.138 +            OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
 207.139 +        {
 207.140 +            // http://oreilly.com/catalog/svgess/chapter/ch03.html
 207.141 +            var style = new StringBuilder();
 207.142 +            if (fill == null)
 207.143 +            {
 207.144 +                style.AppendFormat("fill:none;");
 207.145 +            }
 207.146 +            else
 207.147 +            {
 207.148 +                style.AppendFormat("fill:{0};", this.ColorToString(fill));
 207.149 +                if (fill.A != 0xFF)
 207.150 +                {
 207.151 +                    style.AppendFormat(CultureInfo.InvariantCulture, "fill-opacity:{0};", fill.A / 255.0);
 207.152 +                }
 207.153 +            }
 207.154 +
 207.155 +            if (stroke == null)
 207.156 +            {
 207.157 +                style.AppendFormat("stroke:none;");
 207.158 +            }
 207.159 +            else
 207.160 +            {
 207.161 +                string formatString = "stroke:{0};stroke-width:{1:" + this.NumberFormat + "}";
 207.162 +                style.AppendFormat(formatString, this.ColorToString(stroke), thickness);
 207.163 +                switch (lineJoin)
 207.164 +                {
 207.165 +                    case OxyPenLineJoin.Round:
 207.166 +                        style.AppendFormat(";stroke-linejoin:round");
 207.167 +                        break;
 207.168 +                    case OxyPenLineJoin.Bevel:
 207.169 +                        style.AppendFormat(";stroke-linejoin:bevel");
 207.170 +                        break;
 207.171 +                }
 207.172 +
 207.173 +                if (stroke.A != 0xFF)
 207.174 +                {
 207.175 +                    style.AppendFormat(CultureInfo.InvariantCulture, ";stroke-opacity:{0}", stroke.A / 255.0);
 207.176 +                }
 207.177 +
 207.178 +                if (dashArray != null && dashArray.Length > 0)
 207.179 +                {
 207.180 +                    style.Append(";stroke-dasharray:");
 207.181 +                    for (int i = 0; i < dashArray.Length; i++)
 207.182 +                    {
 207.183 +                        style.AppendFormat(
 207.184 +                            CultureInfo.InvariantCulture, "{0}{1}", i > 0 ? "," : string.Empty, dashArray[i]);
 207.185 +                    }
 207.186 +                }
 207.187 +            }
 207.188 +
 207.189 +            return style.ToString();
 207.190 +        }
 207.191 +
 207.192 +        /// <summary>
 207.193 +        /// Writes an ellipse.
 207.194 +        /// </summary>
 207.195 +        /// <param name="x">
 207.196 +        /// The x coordinate of the center.
 207.197 +        /// </param>
 207.198 +        /// <param name="y">
 207.199 +        /// The y coordinate of the center.
 207.200 +        /// </param>
 207.201 +        /// <param name="width">
 207.202 +        /// The width.
 207.203 +        /// </param>
 207.204 +        /// <param name="height">
 207.205 +        /// The height.
 207.206 +        /// </param>
 207.207 +        /// <param name="style">
 207.208 +        /// The style.
 207.209 +        /// </param>
 207.210 +        public void WriteEllipse(double x, double y, double width, double height, string style)
 207.211 +        {
 207.212 +            // http://www.w3.org/TR/SVG/shapes.html#EllipseElement
 207.213 +            this.WriteStartElement("ellipse");
 207.214 +            this.WriteAttributeString("cx", x + (width / 2));
 207.215 +            this.WriteAttributeString("cy", y + (height / 2));
 207.216 +            this.WriteAttributeString("rx", width / 2);
 207.217 +            this.WriteAttributeString("ry", height / 2);
 207.218 +            this.WriteAttributeString("style", style);
 207.219 +            this.WriteEndElement();
 207.220 +        }
 207.221 +
 207.222 +        /// <summary>
 207.223 +        /// Writes a line.
 207.224 +        /// </summary>
 207.225 +        /// <param name="p1">
 207.226 +        /// The first point.
 207.227 +        /// </param>
 207.228 +        /// <param name="p2">
 207.229 +        /// The second point.
 207.230 +        /// </param>
 207.231 +        /// <param name="style">
 207.232 +        /// The style.
 207.233 +        /// </param>
 207.234 +        public void WriteLine(ScreenPoint p1, ScreenPoint p2, string style)
 207.235 +        {
 207.236 +            // http://www.w3.org/TR/SVG/shapes.html#LineElement
 207.237 +            // http://www.w3schools.com/svg/svg_line.asp
 207.238 +            this.WriteStartElement("line");
 207.239 +            this.WriteAttributeString("x1", p1.X);
 207.240 +            this.WriteAttributeString("y1", p1.Y);
 207.241 +            this.WriteAttributeString("x2", p2.X);
 207.242 +            this.WriteAttributeString("y2", p2.Y);
 207.243 +            this.WriteAttributeString("style", style);
 207.244 +            this.WriteEndElement();
 207.245 +        }
 207.246 +
 207.247 +        /// <summary>
 207.248 +        /// Writes a polygon.
 207.249 +        /// </summary>
 207.250 +        /// <param name="points">
 207.251 +        /// The points.
 207.252 +        /// </param>
 207.253 +        /// <param name="style">
 207.254 +        /// The style.
 207.255 +        /// </param>
 207.256 +        public void WritePolygon(IEnumerable<ScreenPoint> points, string style)
 207.257 +        {
 207.258 +            // http://www.w3.org/TR/SVG/shapes.html#PolygonElement
 207.259 +            this.WriteStartElement("polygon");
 207.260 +            this.WriteAttributeString("points", this.PointsToString(points));
 207.261 +            this.WriteAttributeString("style", style);
 207.262 +            this.WriteEndElement();
 207.263 +        }
 207.264 +
 207.265 +        /// <summary>
 207.266 +        /// Writes a polyline.
 207.267 +        /// </summary>
 207.268 +        /// <param name="pts">
 207.269 +        /// The points.
 207.270 +        /// </param>
 207.271 +        /// <param name="style">
 207.272 +        /// The style.
 207.273 +        /// </param>
 207.274 +        public void WritePolyline(IEnumerable<ScreenPoint> pts, string style)
 207.275 +        {
 207.276 +            // http://www.w3.org/TR/SVG/shapes.html#PolylineElement
 207.277 +            this.WriteStartElement("polyline");
 207.278 +            this.WriteAttributeString("points", this.PointsToString(pts));
 207.279 +            this.WriteAttributeString("style", style);
 207.280 +            this.WriteEndElement();
 207.281 +        }
 207.282 +
 207.283 +        /// <summary>
 207.284 +        /// Writes a rectangle.
 207.285 +        /// </summary>
 207.286 +        /// <param name="x">
 207.287 +        /// The x coordinate.
 207.288 +        /// </param>
 207.289 +        /// <param name="y">
 207.290 +        /// The y coordinate.
 207.291 +        /// </param>
 207.292 +        /// <param name="width">
 207.293 +        /// The width.
 207.294 +        /// </param>
 207.295 +        /// <param name="height">
 207.296 +        /// The height.
 207.297 +        /// </param>
 207.298 +        /// <param name="style">
 207.299 +        /// The style.
 207.300 +        /// </param>
 207.301 +        public void WriteRectangle(double x, double y, double width, double height, string style)
 207.302 +        {
 207.303 +            // http://www.w3.org/TR/SVG/shapes.html#RectangleElement
 207.304 +            this.WriteStartElement("rect");
 207.305 +            this.WriteAttributeString("x", x);
 207.306 +            this.WriteAttributeString("y", y);
 207.307 +            this.WriteAttributeString("width", width);
 207.308 +            this.WriteAttributeString("height", height);
 207.309 +            this.WriteAttributeString("style", style);
 207.310 +            this.WriteEndElement();
 207.311 +        }
 207.312 +
 207.313 +        /// <summary>
 207.314 +        /// Writes text.
 207.315 +        /// </summary>
 207.316 +        /// <param name="position">
 207.317 +        /// The position.
 207.318 +        /// </param>
 207.319 +        /// <param name="text">
 207.320 +        /// The text.
 207.321 +        /// </param>
 207.322 +        /// <param name="fill">
 207.323 +        /// The text color.
 207.324 +        /// </param>
 207.325 +        /// <param name="fontFamily">
 207.326 +        /// The font family.
 207.327 +        /// </param>
 207.328 +        /// <param name="fontSize">
 207.329 +        /// The font size.
 207.330 +        /// </param>
 207.331 +        /// <param name="fontWeight">
 207.332 +        /// The font weight.
 207.333 +        /// </param>
 207.334 +        /// <param name="rotate">
 207.335 +        /// The rotation angle.
 207.336 +        /// </param>
 207.337 +        /// <param name="halign">
 207.338 +        /// The horizontal alignment.
 207.339 +        /// </param>
 207.340 +        /// <param name="valign">
 207.341 +        /// The vertical alignment.
 207.342 +        /// </param>
 207.343 +        public void WriteText(
 207.344 +            ScreenPoint position,
 207.345 +            string text,
 207.346 +            OxyColor fill,
 207.347 +            string fontFamily = null,
 207.348 +            double fontSize = 10,
 207.349 +            double fontWeight = FontWeights.Normal,
 207.350 +            double rotate = 0,
 207.351 +            HorizontalAlignment halign = HorizontalAlignment.Left,
 207.352 +            VerticalAlignment valign = VerticalAlignment.Top)
 207.353 +        {
 207.354 +            // http://www.w3.org/TR/SVG/text.html
 207.355 +            this.WriteStartElement("text");
 207.356 +
 207.357 +            // WriteAttributeString("x", position.X);
 207.358 +            // WriteAttributeString("y", position.Y);
 207.359 +            string baselineAlignment = "hanging";
 207.360 +            if (valign == VerticalAlignment.Middle)
 207.361 +            {
 207.362 +                baselineAlignment = "middle";
 207.363 +            }
 207.364 +
 207.365 +            if (valign == VerticalAlignment.Bottom)
 207.366 +            {
 207.367 +                baselineAlignment = "baseline";
 207.368 +            }
 207.369 +
 207.370 +            this.WriteAttributeString("dominant-baseline", baselineAlignment);
 207.371 +
 207.372 +            string textAnchor = "start";
 207.373 +            if (halign == HorizontalAlignment.Center)
 207.374 +            {
 207.375 +                textAnchor = "middle";
 207.376 +            }
 207.377 +
 207.378 +            if (halign == HorizontalAlignment.Right)
 207.379 +            {
 207.380 +                textAnchor = "end";
 207.381 +            }
 207.382 +
 207.383 +            this.WriteAttributeString("text-anchor", textAnchor);
 207.384 +
 207.385 +            string fmt = "translate({0:" + this.NumberFormat + "},{1:" + this.NumberFormat + "})";
 207.386 +            string transform = string.Format(CultureInfo.InvariantCulture, fmt, position.X, position.Y);
 207.387 +            if (Math.Abs(rotate) > 0)
 207.388 +            {
 207.389 +                transform += string.Format(CultureInfo.InvariantCulture, " rotate({0})", rotate);
 207.390 +            }
 207.391 +
 207.392 +            this.WriteAttributeString("transform", transform);
 207.393 +
 207.394 +            if (fontFamily != null)
 207.395 +            {
 207.396 +                this.WriteAttributeString("font-family", fontFamily);
 207.397 +            }
 207.398 +
 207.399 +            if (fontSize > 0)
 207.400 +            {
 207.401 +                this.WriteAttributeString("font-size", fontSize);
 207.402 +            }
 207.403 +
 207.404 +            if (fontWeight > 0)
 207.405 +            {
 207.406 +                this.WriteAttributeString("font-weight", fontWeight);
 207.407 +            }
 207.408 +
 207.409 +            this.WriteAttributeString("fill", this.ColorToString(fill));
 207.410 +
 207.411 +            // WriteAttributeString("style", style);
 207.412 +            this.WriteString(text);
 207.413 +            this.WriteEndElement();
 207.414 +        }
 207.415 +
 207.416 +        /// <summary>
 207.417 +        /// Converts a color to a svg color string.
 207.418 +        /// </summary>
 207.419 +        /// <param name="color">The color.</param>
 207.420 +        /// <returns>The color string.</returns>
 207.421 +        protected string ColorToString(OxyColor color)
 207.422 +        {
 207.423 +            if (color == OxyColors.Black)
 207.424 +            {
 207.425 +                return "black";
 207.426 +            }
 207.427 +
 207.428 +            var formatString = "rgb({0:" + this.NumberFormat + "},{1:" + this.NumberFormat + "},{2:" + this.NumberFormat + "})";
 207.429 +            return string.Format(formatString, color.R, color.G, color.B);
 207.430 +        }
 207.431 +
 207.432 +        /// <summary>
 207.433 +        /// The write attribute string.
 207.434 +        /// </summary>
 207.435 +        /// <param name="name">
 207.436 +        /// The name.
 207.437 +        /// </param>
 207.438 +        /// <param name="value">
 207.439 +        /// The value.
 207.440 +        /// </param>
 207.441 +        protected void WriteAttributeString(string name, double value)
 207.442 +        {
 207.443 +            this.WriteAttributeString(name, value.ToString(this.NumberFormat, CultureInfo.InvariantCulture));
 207.444 +        }
 207.445 +
 207.446 +        /// <summary>
 207.447 +        /// Converts a value to a string or to the specified "auto" string if the value is NaN.
 207.448 +        /// </summary>
 207.449 +        /// <param name="value">The value.</param>
 207.450 +        /// <param name="auto">The string to return if value is NaN.</param>
 207.451 +        /// <returns>A string.</returns>
 207.452 +        private string GetAutoValue(double value, string auto)
 207.453 +        {
 207.454 +            if (double.IsNaN(value))
 207.455 +            {
 207.456 +                return auto;
 207.457 +            }
 207.458 +
 207.459 +            return value.ToString(this.NumberFormat, CultureInfo.InvariantCulture);
 207.460 +        }
 207.461 +
 207.462 +        /// <summary>
 207.463 +        /// Converts a list of points to a string.
 207.464 +        /// </summary>
 207.465 +        /// <param name="points">The points.</param>
 207.466 +        /// <returns>A string.</returns>
 207.467 +        private string PointsToString(IEnumerable<ScreenPoint> points)
 207.468 +        {
 207.469 +            var sb = new StringBuilder();
 207.470 +            string fmt = "{0:" + this.NumberFormat + "},{1:" + this.NumberFormat + "} ";
 207.471 +            foreach (var p in points)
 207.472 +            {
 207.473 +                sb.AppendFormat(CultureInfo.InvariantCulture, fmt, p.X, p.Y);
 207.474 +            }
 207.475 +
 207.476 +            return sb.ToString().Trim();
 207.477 +        }
 207.478 +
 207.479 +        /// <summary>
 207.480 +        /// The write header.
 207.481 +        /// </summary>
 207.482 +        /// <param name="width">
 207.483 +        /// The width.
 207.484 +        /// </param>
 207.485 +        /// <param name="height">
 207.486 +        /// The height.
 207.487 +        /// </param>
 207.488 +        private void WriteHeader(double width, double height)
 207.489 +        {
 207.490 +            // http://www.w3.org/TR/SVG/struct.html#SVGElement
 207.491 +            if (this.IsDocument)
 207.492 +            {
 207.493 +                this.WriteStartDocument(false);
 207.494 +                this.WriteDocType(
 207.495 +                    "svg", "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", null);
 207.496 +            }
 207.497 +
 207.498 +            this.WriteStartElement("svg", "http://www.w3.org/2000/svg");
 207.499 +            this.WriteAttributeString("width", this.GetAutoValue(width, "100%"));
 207.500 +            this.WriteAttributeString("height", this.GetAutoValue(height, "100%"));
 207.501 +            this.WriteAttributeString("version", "1.1");
 207.502 +        }
 207.503 +
 207.504 +    }
 207.505 +}
 207.506 \ No newline at end of file