예제 #1
0
        /// <summary>
        /// Translates a point from the chart dimension to the drawing canvas pixel dimension
        /// </summary>
        /// <param name="canvasInfo">Information about the canvas and its transformations</param>
        /// <param name="valuePoint">A point in the chart with real plot values</param>
        /// <returns>A point in the drawing canvas with pixel values</returns>
        public static Point ToPixel(CanvasTransformInfo canvasInfo, Point valuePoint)
        {
            Canvas canvas         = canvasInfo.Canvas;
            Point  scaledMaxPoint = canvasInfo.ScaledMaxPoint;
            Point  scaledMinPoint = canvasInfo.ScaledMinPoint;

            double scaleX = 0.0;
            double scaleY = 0.0;

            var canvasSize = new Size(canvas.ActualWidth, canvas.ActualHeight);

            if (scaledMaxPoint.X != scaledMinPoint.X)
            {
                scaleX = canvasSize.Width / (scaledMaxPoint.X - scaledMinPoint.X);
            }

            if (scaledMaxPoint.Y != scaledMinPoint.Y)
            {
                scaleY = canvasSize.Height / (scaledMaxPoint.Y - scaledMinPoint.Y);
            }

            double xPos = (valuePoint.X - scaledMinPoint.X) * scaleX;
            double yPos = (valuePoint.Y - scaledMinPoint.Y) * scaleY;

            return(new Point(xPos, yPos));
        }
예제 #2
0
        ///// <summary>
        ///// Convert a DataStream of values into a ChartData object which can be fed into the charts and displayed.
        ///// The default behaviour is to create a smoothed copy and add along with the original data.
        ///// The original data is colored Gray and the smoothed data Red by default.7
        ///// </summary>
        ///// <param name="stream"></param>
        ///// <param name="streamName"></param>
        ///// <returns></returns>
        //public static ChartData ToChartData(DataVector stream, string streamName)
        //{
        //    if (stream == null)
        //        throw new ArgumentNullException();

        //    if (stream.Count == 0)
        //        throw new ArgumentException("Stream must contain at least one element");

        //    var data = stream;
        //    var smoothedData = Numerics.SmoothBySavitzkyGolay(data, 11);

        //    // We know there is at least one element, so Get(0) is safe!
        //    return new ChartData(
        //        stream.Get(0).Unit,
        //        CreateDataItem(data, streamName, Colors.Gray, 1),
        //        CreateDataItem(smoothedData, streamName, Colors.Red, 1));
        //}

        ///// <summary>
        ///// Loads a set of DataInfo elements into a ChartPrimitive, using the Value and Time.Ticks
        ///// properties as values for each element.
        ///// </summary>
        ///// <param name="source"></param>
        ///// <param name="name"></param>
        ///// <param name="color"></param>
        ///// <param name="lineWidth"></param>
        ///// <returns></returns>
        //private static ChartPrimitive CreateDataItem(IEnumerable<DataInfo> source, String name, Color color, int lineWidth)
        //{
        //    var cp = new ChartPrimitive
        //    {
        //        Color = color,
        //        Dashed = false,
        //        Filled = false,
        //        Label = name,
        //        LineThickness = lineWidth,
        //        ShowInLegend = false
        //    };

        //    foreach (DataInfo info in source)
        //        cp.AddPoint(info.Time.TotalMilliseconds, info.Value);

        //    return cp;
        //}


        public static void RenderTextToChartPosition(DrawingContext drawingContext, CanvasTransformInfo canvasInfo,
                                                     string text, Color textColor, Point chartPosition,
                                                     Point pixelOffset, bool flipY, bool centreAligned)
        {
            var typeFace = new Typeface("Arial");

            // Render the marker label beneath or above the marker according
            // to if the Y value is positive or negative
            Point textPos = ToPixel(canvasInfo, chartPosition);

            textPos.Offset(pixelOffset.X, pixelOffset.Y);

            var formattedText = new FormattedText(
                text,
                CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight,
                typeFace,
                10,
                new SolidColorBrush(textColor));

            if (centreAligned)
            {
                formattedText.TextAlignment = TextAlignment.Center;
            }


            // Adjust position and transformation for inverted Y axis.
            // Default behaviour is flipY == false, in case we need to
            // flip the font rendering transform. The drawing canvas
            // has inverted its Y-axis causing the text to render upside-down.
            int transformY = flipY ? 1 : -1;

            textPos.Y *= transformY;

            // Push flip transformation
            drawingContext.PushTransform(new ScaleTransform(1, transformY));

            // Render text
            drawingContext.DrawText(formattedText, textPos);

            // Pop flip transformation
            drawingContext.Pop();
        }
        ///// <summary>
        ///// Convert a DataStream of values into a ChartData object which can be fed into the charts and displayed.
        ///// The default behaviour is to create a smoothed copy and add along with the original data.
        ///// The original data is colored Gray and the smoothed data Red by default.7
        ///// </summary>
        ///// <param name="stream"></param>
        ///// <param name="streamName"></param>
        ///// <returns></returns>
        //public static ChartData ToChartData(DataVector stream, string streamName)
        //{
        //    if (stream == null)
        //        throw new ArgumentNullException();

        //    if (stream.Count == 0)
        //        throw new ArgumentException("Stream must contain at least one element");

        //    var data = stream;
        //    var smoothedData = Numerics.SmoothBySavitzkyGolay(data, 11);

        //    // We know there is at least one element, so Get(0) is safe!
        //    return new ChartData(
        //        stream.Get(0).Unit,
        //        CreateDataItem(data, streamName, Colors.Gray, 1),
        //        CreateDataItem(smoothedData, streamName, Colors.Red, 1));
        //}

        ///// <summary>
        ///// Loads a set of DataInfo elements into a ChartPrimitive, using the Value and Time.Ticks 
        ///// properties as values for each element.
        ///// </summary>
        ///// <param name="source"></param>
        ///// <param name="name"></param>
        ///// <param name="color"></param>
        ///// <param name="lineWidth"></param>
        ///// <returns></returns>
        //private static ChartPrimitive CreateDataItem(IEnumerable<DataInfo> source, String name, Color color, int lineWidth)
        //{
        //    var cp = new ChartPrimitive
        //    {
        //        Color = color,
        //        Dashed = false,
        //        Filled = false,
        //        Label = name,
        //        LineThickness = lineWidth,
        //        ShowInLegend = false
        //    };

        //    foreach (DataInfo info in source)
        //        cp.AddPoint(info.Time.TotalMilliseconds, info.Value);

        //    return cp;
        //}


        public static void RenderTextToChartPosition(DrawingContext drawingContext, CanvasTransformInfo canvasInfo,
                                                     string text, Color textColor, Point chartPosition,
                                                     Point pixelOffset, bool flipY, bool centreAligned)
        {
            var typeFace = new Typeface("Arial");

            // Render the marker label beneath or above the marker according 
            // to if the Y value is positive or negative
            Point textPos = ToPixel(canvasInfo, chartPosition);
            textPos.Offset(pixelOffset.X, pixelOffset.Y);
            
            var formattedText = new FormattedText(
                text,
                CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight,
                typeFace,
                10,
                new SolidColorBrush(textColor));

            if (centreAligned)
                formattedText.TextAlignment = TextAlignment.Center;


            // Adjust position and transformation for inverted Y axis.
            // Default behaviour is flipY == false, in case we need to
            // flip the font rendering transform. The drawing canvas
            // has inverted its Y-axis causing the text to render upside-down.
            int transformY = flipY ? 1 : -1;
            textPos.Y *= transformY;

            // Push flip transformation    
            drawingContext.PushTransform(new ScaleTransform(1, transformY));

            // Render text
            drawingContext.DrawText(formattedText, textPos);

            // Pop flip transformation
            drawingContext.Pop();
        }
        /// <summary>
        /// Translates a point from the chart dimension to the drawing canvas pixel dimension
        /// </summary>
        /// <param name="canvasInfo">Information about the canvas and its transformations</param>
        /// <param name="valuePoint">A point in the chart with real plot values</param>
        /// <returns>A point in the drawing canvas with pixel values</returns>
        public static Point ToPixel(CanvasTransformInfo canvasInfo, Point valuePoint)
        {
            Canvas canvas = canvasInfo.Canvas;
            Point scaledMaxPoint = canvasInfo.ScaledMaxPoint;
            Point scaledMinPoint = canvasInfo.ScaledMinPoint;

            double scaleX = 0.0;
            double scaleY = 0.0;

            var canvasSize = new Size(canvas.ActualWidth, canvas.ActualHeight);

            if (scaledMaxPoint.X != scaledMinPoint.X)
                scaleX = canvasSize.Width/(scaledMaxPoint.X - scaledMinPoint.X);

            if (scaledMaxPoint.Y != scaledMinPoint.Y)
                scaleY = canvasSize.Height/(scaledMaxPoint.Y - scaledMinPoint.Y);

            double xPos = (valuePoint.X - scaledMinPoint.X)*scaleX;
            double yPos = (valuePoint.Y - scaledMinPoint.Y)*scaleY;

            return new Point(xPos, yPos);
        }
        // Keep this line for you BSD License obligations


        #endregion Private Fields

        #region Public Methods

        /// <summary>
        /// Constructor. Initializes all the class fields.
        /// </summary>
        public XYLineChart()
        {
            // This assumes that you are navigating to this scene.
            // If you will normally instantiate it via code and display it
            // manually, you either have to call InitializeComponent by hand or
            // uncomment the following line.

            InitializeComponent();

            TextCanvasInfo = new CanvasTransformInfo();

            primitiveList = new List<ChartPrimitive>();
            markerList = new List<ChartMarkerSet>();
            intervalList = new List<Interval>();
            // Set the Chart Geometry Clip region
            chartClip = new PathGeometry();
            chartClip.AddGeometry(
                new RectangleGeometry(new Rect(0, 0, clippedPlotCanvas.ActualWidth, clippedPlotCanvas.ActualHeight)));
            shapeTransform = new MatrixTransform();
            adornerMarkers = new AdornerChartMarkers(clippedPlotCanvas, shapeTransform, MarkerSets, this);
            adorner = new AdornerCursorCoordinateDrawer(clippedPlotCanvas, shapeTransform);

            optimalGridLineSpacing = new Point(100, 75);

            panZoomCalculator =
                new PanZoomCalculator(new Rect(0, 0, clippedPlotCanvas.ActualWidth, clippedPlotCanvas.ActualHeight));
            panZoomCalculator.Window = new Rect(0, 0, clippedPlotCanvas.ActualWidth, clippedPlotCanvas.ActualHeight);
            panZoomCalculator.PanZoomChanged += panZoomCalculator_PanZoomChanged;

            closestPointPicker = new ClosestPointPicker(new Size(13, 13));
            closestPointPicker.ClosestPointChanged += closestPointPicker_ClosestPointChanged;

            Cursor = Cursors.None;

            TextCanvasInfo.Canvas = textCanvas;

//            UniformScaling = true;

            // Set up all the message handlers for the clipped plot canvas
            AttachEventsToCanvas(this);

            //clippedPlotCanvas.Clip = chartClip;
            clippedPlotCanvas.IsVisibleChanged += clippedPlotCanvas_IsVisibleChanged;
            clippedPlotCanvas.SizeChanged += clippedPlotCanvas_SizeChanged;
        }