示例#1
0
        /// <summary>
        /// Converts movements to a graphical line and polygon
        /// </summary>
        /// <param name="results"></param>
        /// <param name="color"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        public static LineAndPolygon ConvertResultsToMovementLineAndPolygon(float[] results, Color color, string label)
        {
            // Create the Line
            var chartLine = new ChartPrimitive();

            chartLine.Color        = color;
            chartLine.Label        = label;
            chartLine.ShowInLegend = true;
            chartLine.HitTest      = true;

            for (int monthNo = 0; monthNo < results.Length; ++monthNo)
            {
                chartLine.AddSmoothHorizontalBar(new Point(monthNo + .5f, results[monthNo]));
            }

            // Create the polygon
            ChartPrimitive polygon = ChartUtilities.ChartLineToBaseLinedPolygon(chartLine);

            color.A              = (byte)(alpha * color.A);
            polygon.Color        = color;
            polygon.ShowInLegend = false;
            polygon.HitTest      = false;

            return(new LineAndPolygon(chartLine, polygon));
        }
        /// <summary>
        /// Gets the UIElement that can be added to the plot
        /// </summary>
        /// <returns></returns>
        public UIElement GetUIElement()
        {
            var path = new Path();

            path.Data           = geometry;
            path.StrokeLineJoin = PenLineJoin.Bevel;

            if (filled)
            {
                path.Stroke = null;
                path.Fill   = dashed
                                ? ChartUtilities.CreateHatch50(color, new Size(2, 2))
                                : (Brush)(new SolidColorBrush(color));
            }
            else
            {
                path.Stroke          = new SolidColorBrush(color);
                path.StrokeThickness = lineThickness;
                path.Fill            = null;
                if (dashed)
                {
                    path.StrokeDashArray = new DoubleCollection(new double[] { 2, 2 });
                }
            }
            return(path);
        }
示例#3
0
 public TestPage()
 {
     InitializeComponent();
     ChartUtilities.AddTestLines(xyLineChart);
     xyLineChart.SubNotes = new string[]
     { "Right Mouse Button To Zoom, Left Mouse Button To Pan, Double-Click To Reset" };
     copyToClipboard.CopyToClipboardDelegate = CopyChartToClipboard;
     copyToClipboard.SaveToFileDelegate      = SaveToFile;
     //xyLineChart.FlipYAxis = true;
     //xyLineChart.PlotAreaOverride = new Rect(new Point(0, -2), new Point(5, 2));
 }
示例#4
0
 /// <summary>
 /// Copies the chart to the clipboard
 /// </summary>
 /// <param name="element"></param>
 /// <param name="width"></param>
 /// <param name="height"></param>
 protected void CopyChartToClipboard(FrameworkElement element, double width, double height)
 {
     try
     {
         ChartUtilities.CopyChartToClipboard(plotToCopy, xyLineChart, width, height);
     }
     catch
     {
         // the above might throw a security exception is used in an xbap
         Trace.WriteLine("Error copying to clipboard");
     }
 }
示例#5
0
        protected void SaveToFile(FrameworkElement element, double width, double height)
        {
            var saveFile = new SaveFileDialog();

            saveFile.Filter          = "png files (*.png)|*.png";
            saveFile.AddExtension    = true;
            saveFile.OverwritePrompt = true;
            saveFile.Title           = "Save Chart To a File";
            saveFile.ValidateNames   = true;

            if (saveFile.ShowDialog() == true)
            {
                ChartUtilities.CopyFrameworkElemenToPNGFile(plotToCopy, width, height, saveFile.FileName);
            }
        }
        /// <summary>
        /// Set the chart transform
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        protected void SetChartTransform(double width, double height)
        {
            // Note This is required even if we are using plotAreaOverride.
            // Calling this method causes some necessary invalidation of the contents that redraws the graphs later.
            // Otherwise, when using plotAreaOverride, the graphs are not redrawn.
            Rect plotArea = ChartUtilities.GetPlotRectangle(primitiveList, 0.1f);

            if (plotAreaOverride.HasValue)
            {
                plotArea = plotAreaOverride.Value;
            }


            // Enforce uniform scaling
            if (UniformScaling)
            {
                // TODO Improve this method
                plotArea.Width = plotArea.Height =
                    Math.Max(plotArea.Width, plotArea.Height);
            }

            scaledMinPoint = plotArea.Location;
            scaledMinPoint.Offset(-plotArea.Width * panZoomCalculator.Pan.X, plotArea.Height * panZoomCalculator.Pan.Y);
            scaledMinPoint.Offset(0.5 * plotArea.Width * (1 - 1 / panZoomCalculator.Zoom.X),
                                  0.5 * plotArea.Height * (1 - 1 / panZoomCalculator.Zoom.Y));

            scaledMaxPoint = scaledMinPoint;
            scaledMaxPoint.Offset(plotArea.Width / panZoomCalculator.Zoom.X, plotArea.Height / panZoomCalculator.Zoom.Y);

            var plotScale = new Point();

            plotScale.X = (width / plotArea.Width) * panZoomCalculator.Zoom.X;
            plotScale.Y = (height / plotArea.Height) * panZoomCalculator.Zoom.Y;

            Matrix shapeMatrix = Matrix.Identity;

            shapeMatrix.Translate(-scaledMinPoint.X, -scaledMinPoint.Y);
            shapeMatrix.Scale(plotScale.X, plotScale.Y);
            shapeTransform.Matrix = shapeMatrix;

            TextCanvasInfo.ScaledMaxPoint = scaledMaxPoint;
            TextCanvasInfo.ScaledMinPoint = scaledMinPoint;
        }
示例#7
0
        /// <summary>
        /// Gets ChartLines and ChartPolygons for the population line, and
        /// the target line.
        /// </summary>
        /// <param name="populationLine"></param>
        /// <param name="results"></param>
        /// <param name="color"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        public static LineAndPolygon ConvertResultsToTargetLineAndPolygon(ChartPrimitive populationLine, float[] results,
                                                                          Color color, string label)
        {
            // Calculate Target Primitives
            var targetLine = new ChartPrimitive();

            targetLine.Color        = color;
            targetLine.Dashed       = true;
            targetLine.Label        = label + " Target";
            targetLine.ShowInLegend = false;
            targetLine.HitTest      = true;

            if (populationLine.Points.Count == results.Length)
            {
                for (int monthNo = 0; monthNo < results.Length; monthNo += 2)
                {
                    targetLine.AddPoint(new Point(monthNo * .5f, results[monthNo]));
                    targetLine.AddPoint(new Point(monthNo * .5f + 1f, results[monthNo + 1]));
                }
            }
            else
            {
                for (int monthNo = 0; monthNo < results.Length; ++monthNo)
                {
                    targetLine.AddPoint(new Point(monthNo, results[monthNo]));
                    targetLine.AddPoint(new Point(monthNo + 1f, results[monthNo]));
                }
            }

            ChartPrimitive targetPolygon = ChartUtilities.LineDiffToPolygon(populationLine, targetLine);

            color.A                    = (byte)(alpha * color.A);
            targetPolygon.Color        = color;
            targetPolygon.Dashed       = true;
            targetPolygon.ShowInLegend = false;
            targetLine.HitTest         = false;

            return(new LineAndPolygon(targetLine, targetPolygon));
        }
示例#8
0
        /// <summary>
        /// Converts population level to a line and polygon
        /// </summary>
        /// <param name="results"></param>
        /// <param name="color"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        public static LineAndPolygon ConvertResultsToPopulationLineAndPolygon(float[] results, Color color, string label)
        {
            var populationLine = new ChartPrimitive();

            populationLine.Color        = color;
            populationLine.Label        = label;
            populationLine.ShowInLegend = true;
            populationLine.HitTest      = true;

            for (int monthNo = 0; monthNo < results.Length; monthNo += 2)
            {
                populationLine.AddPoint(new Point(monthNo * .5f, results[monthNo]));
                populationLine.AddPoint(new Point(monthNo * .5f + 1f, results[monthNo + 1]));
            }

            ChartPrimitive populationPolygon = ChartUtilities.ChartLineToBaseLinedPolygon(populationLine);

            color.A = (byte)(alpha * color.A);
            populationPolygon.Color        = color;
            populationPolygon.ShowInLegend = false;
            populationPolygon.HitTest      = false;

            return(new LineAndPolygon(populationLine, populationPolygon));
        }
        /// <summary>
        /// Draw all the gridlines and labels for the gridlines
        /// </summary>
        /// <param name="size"></param>
        /// <param name="minXY"></param>
        /// <param name="maxXY"></param>
        protected void DrawGridlinesAndLabels(Size size, Point minXY, Point maxXY)
        {
            // Clear the text canvas
            textCanvas.Children.Clear();

            // Create brush for writing text
            Brush axisBrush      = new SolidColorBrush(gridLineColor);
            Brush axisScaleBrush = new SolidColorBrush(gridLineLabelColor);

            // Need to pick appropriate scale increment.
            // Go for a 2Exx, 5Exx, or 1Exx type scale
            double scaleX = 0.0;
            double scaleY = 0.0;

            // Work out all the limits

            if (maxXY.X != minXY.X)
            {
                scaleX = size.Width / (maxXY.X - minXY.X);
            }
            if (maxXY.Y != minXY.Y)
            {
                scaleY = size.Height / (maxXY.Y - minXY.Y);
            }
            double optimalSpacingX = optimalGridLineSpacing.X / scaleX;

            double spacingX = ChartUtilities.ClosestValueInListTimesBaseToInteger(optimalSpacingX,
                                                                                  new double[] { 1, 3, 6 }, 12.0);

            if (spacingX < 2.0)
            {
                spacingX = ChartUtilities.Closest_1_2_5_Pow10(optimalSpacingX);
            }

            double optimalSpacingY = optimalGridLineSpacing.Y / scaleY;
            double spacingY        = ChartUtilities.Closest_1_2_5_Pow10(optimalSpacingY);

            var startXmult = (int)Math.Ceiling(minXY.X / spacingX);
            var endXmult   = (int)Math.Floor(maxXY.X / spacingX);
            var startYmult = (int)Math.Ceiling(minXY.Y / spacingY);
            var endYmult   = (int)Math.Floor(maxXY.Y / spacingY);

            double maxXLabelHeight = 0;

            var pathFigure = new PathFigure();

            // Draw all the vertical gridlines

            for (int lineNo = startXmult; lineNo <= endXmult; ++lineNo)
            {
                double xValue = lineNo * spacingX;
                double xPos   = (xValue - minXY.X) * scaleX;

                var startPoint = new Point(xPos, size.Height);
                var endPoint   = new Point(xPos, 0);

                pathFigure.Segments.Add(new LineSegment(startPoint, false));
                pathFigure.Segments.Add(new LineSegment(endPoint, true));

                var text = new TextBlock();
                text.Text       = xValue.ToString();
                text.Foreground = axisScaleBrush;
                text.Measure(size);

                text.SetValue(Canvas.LeftProperty, xPos - text.DesiredSize.Width * .5);
                text.SetValue(Canvas.TopProperty, size.Height + 1);
                textCanvas.Children.Add(text);
                maxXLabelHeight = Math.Max(maxXLabelHeight, text.DesiredSize.Height);
            }

            xGridlineLabels.Height = maxXLabelHeight + 2;

            // Set string format for vertical text
            double maxYLabelHeight = 0;

            // Draw all the horizontal gridlines

            for (int lineNo = startYmult; lineNo <= endYmult; ++lineNo)
            {
                double yValue = lineNo * spacingY;
                double yPos   = flipYAxis
                                  ?
                                (yValue - maxXY.Y) * scaleY + size.Height
                                  :
                                (-yValue + minXY.Y) * scaleY + size.Height;

                var startPoint = new Point(0, yPos);
                var endPoint   = new Point(size.Width, yPos);

                pathFigure.Segments.Add(new LineSegment(startPoint, false));
                pathFigure.Segments.Add(new LineSegment(endPoint, true));

                var text = new TextBlock();
                text.Text            = yValue.ToString();
                text.LayoutTransform = new RotateTransform(-90);
                text.Measure(size);

                text.SetValue(Canvas.LeftProperty, -text.DesiredSize.Width - 1);
                text.SetValue(Canvas.TopProperty, yPos - text.DesiredSize.Height * .5);
                textCanvas.Children.Add(text);
                maxYLabelHeight = Math.Max(maxYLabelHeight, text.DesiredSize.Width);
            }
            yGridLineLabels.Height = maxYLabelHeight + 2;

            var path = new Path();

            path.Stroke = axisBrush;
            var pathGeometry = new PathGeometry(new[] { pathFigure });

            pathGeometry.Transform = (Transform)textCanvas.RenderTransform.Inverse;
            path.Data = pathGeometry;

            textCanvas.Children.Add(path);
        }