WPF 绘制曲线图

 之前一直用GDI绘图,后面公司要求使用WPF,网上WPF资料太少(可能自己没找到吧),自己写了个测试用,可以拖动。

 

前端代码

<Window x:Class="Wpf绘图.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="600" Width="800" Loaded="Window_Loaded_1">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ToolBar Grid.Row="0">
            <Label Name="moushPonit" Foreground="Red">11</Label>
        </ToolBar>
        <Canvas Grid.Row="1" Name="MainCanvas" Background="#FFBBBCBF" 
                MouseMove="MainCanvas_MouseMove" 
                MouseLeftButtonDown="MainCanvas_MouseLeftButtonDown" MouseLeftButtonUp="MainCanvas_MouseLeftButtonUp" SizeChanged="MainCanvas_SizeChanged" ClipToBounds="True">
            <Canvas.RenderTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="sfr" />
                    <TranslateTransform x:Name="tlt" />
                </TransformGroup>
            </Canvas.RenderTransform>
        </Canvas>
    </Grid>
</Window>

  

后台代码

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Wpf绘图
{
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {
        /// <summary>
        /// 画板宽度
        /// </summary>
        double BoardWidth { get; set; }
        /// <summary>
        /// 画板高度
        /// </summary>
        double BoardHeight { get; set; }
        /// <summary>
        /// 垂直(纵向)边距(画图区域距离左右两边长度)
        /// </summary>
        double VerticalMargin { get; set; }
        /// <summary>
        /// 平行(横向)边距(画图区域距离左右两边长度)
        /// </summary>
        double HorizontalMargin { get; set; }
        /// <summary>
        /// 水平刻度间距像素
        /// </summary>
        double horizontalBetween { get; set; }
        /// <summary>
        /// 垂直刻度间距像素
        /// </summary>
        double verticalBetween { get; set; }

        /// <summary>
        ///     x轴最大值
        /// </summary>
        public double MaxX { get; set; }

        /// <summary>
        ///     y轴最大值
        /// </summary>
        public double MaxY { get; set; }

        /// <summary>
        ///     x轴最小值
        /// </summary>
        public double MinX { get; set; }

        /// <summary>
        ///     y轴最小值
        /// </summary>
        public double MinY { get; set; }

        /// <summary>
        /// 图表区域宽度
        /// </summary>
        double ChartWidth;
        /// <summary>
        /// 图表区域高度
        /// </summary>
        double CharHeight;
        /// <summary>
        /// 画图区域起点
        /// </summary>
        Point StartPostion;
        /// <summary>
        /// 画图区域终点
        /// </summary>
        Point EndPostion;
        /// <summary>
        /// 数据源
        /// </summary>
        PointCollection DataSourse;


        double MapLocationX = 0;
        double MapLocationY = 0;
        //鼠标按下去的位置
        Point startMovePosition;
        TranslateTransform totalTranslate = new TranslateTransform();
        TranslateTransform tempTranslate = new TranslateTransform();
        ScaleTransform totalScale = new ScaleTransform();
        Double scaleLevel = 1;


        public Window1()
        {
            InitializeComponent();
            DataSourse = GetCollPoint();
        }

        private void MainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startMovePosition = e.GetPosition((Canvas)sender);
        }
        
        private void MainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            /*
            Point endMovePosition = e.GetPosition((Canvas)sender);

            totalTranslate.X += (endMovePosition.X - startMovePosition.X) / scaleLevel;
            totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y) / scaleLevel; 
            */
        }

        private void MainCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            Point currentMousePosition = e.GetPosition((UIElement)sender);
            moushPonit.Content = currentMousePosition.X.ToString() + "," + currentMousePosition.Y.ToString();

            if (e.LeftButton == MouseButtonState.Pressed)
            {
                MapLocationX = MapLocationX + currentMousePosition.X - startMovePosition.X;
                MapLocationY = MapLocationY + currentMousePosition.Y - startMovePosition.Y;

                startMovePosition = currentMousePosition;

                Refresh();
                /*
                Point deltaPt = new Point(0, 0);
                deltaPt.X = (currentMousePosition.X - startMovePosition.X) / scaleLevel;
                deltaPt.Y = (currentMousePosition.Y - startMovePosition.Y) / scaleLevel;

                tempTranslate.X = totalTranslate.X + deltaPt.X;
                tempTranslate.Y = totalTranslate.Y + deltaPt.Y;

                TransformGroup tfGroup = new TransformGroup();
                tfGroup.Children.Add(tempTranslate);
                tfGroup.Children.Add(totalScale);
                foreach (UIElement ue in MainCanvas.Children)
                {
                    ue.RenderTransform = tfGroup;
                }*/
            }

        }

        private void MainCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Refresh();
        }

        private void Refresh()
        {
            InitCanvas();

            //获取y最大值
            if (MaxY < 0.0001)
            {
                MaxY = DataSourse.Max(m => m.Y);
            }
            //MinY = DataSourse.Min(m => m.Y);

            if (MaxX < 0.0001)
            {
                MaxX = DataSourse.Max(m => m.X);
            }
            //MinX = DataSourse.Min(m => m.X);
            if (Math.Abs(MaxX) < 0.000001 || Math.Abs(MaxY) < 0.000001)
            {
                return;
            }

            DrawAxis();
            DrawXAxisTicks();
            DrawYAxisTicks();
            DrawPolyline();
        }

        private void InitCanvas()
        {
            MainCanvas.Children.Clear();

            BoardWidth = MainCanvas.ActualWidth - SystemParameters.VerticalScrollBarWidth;
            BoardHeight = MainCanvas.ActualHeight - SystemParameters.HorizontalScrollBarHeight;
            HorizontalMargin = 40;
            VerticalMargin = 40;
            //horizontalBetween = 50;
            //verticalBetween = 50;
            ChartWidth = BoardWidth - 2 * HorizontalMargin;//画图区域宽度
            CharHeight = BoardHeight - 2 * VerticalMargin; //画图区域高度

            StartPostion = new Point(HorizontalMargin, VerticalMargin);
            EndPostion = new Point(BoardWidth - HorizontalMargin, BoardHeight - VerticalMargin);
            

            
        }

        private void DrawPolyline()
        {
            var polyline = new Polyline();
            foreach (var t in DataSourse)
            {
                polyline.Points.Add(GetRealPoint(t));
            }
            polyline.Stroke = Brushes.Blue;
            MainCanvas.Children.Add(polyline);
        }

        private Point GetRealPoint(Point point)
        {
            var realX = StartPostion.X + (point.X - MinX) * ChartWidth / (MaxX - MinX) + MapLocationX;
            var realY = StartPostion.Y + (MaxY - point.Y) * CharHeight / (MaxY - MinY) + MapLocationY;
            return new Point(realX, realY);
        }

        /// <summary>
        ///  画y轴刻度
        /// </summary>
        private void DrawYAxisTicks()
        {
            if (MinY >= MaxY)
            {
                return;
            }
            if (verticalBetween < 0.0001)
            {
                verticalBetween = (MaxY - MinY) / 10;
            }
            for (var i = MinY; i <= MaxY + 0.01; i += verticalBetween)
            {
                var y = EndPostion.Y - i * CharHeight / (MaxY - MinY) + MapLocationY;
                var marker = new Line
                {
                    X1 = StartPostion.X - 5,
                    Y1 = y,
                    X2 = StartPostion.X,
                    Y2 = y,
                    Stroke = Brushes.Red
                };
                MainCanvas.Children.Add(marker);



                //画y轴字符
                var markText = new TextBlock
                {
                    Text = i.ToString(CultureInfo.InvariantCulture),
                    Width = 30,
                    Foreground = Brushes.Yellow,
                    FontSize = 10,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    TextAlignment = TextAlignment.Right
                };
                MainCanvas.Children.Add(markText);
                Canvas.SetTop(markText, y - 10);
                Canvas.SetLeft(markText, 00);
            }
        }

        /// <summary>
        /// 画x轴标签
        /// </summary>
        private void DrawXAxisTicks()
        {
            if (MinX >= MaxX)
            {
                return;
            }
            if (horizontalBetween < 0.0001)
            {
                horizontalBetween = (MaxX - MinX) / 10;
            }
            for (var i = MinX; i <= MaxX + 0.01; i += horizontalBetween)
            {
                var x = StartPostion.X + i * ChartWidth / (MaxX - MinX) + MapLocationX;
                var marker = new Line
                {
                    X1 = x,
                    Y1 = EndPostion.Y,
                    X2 = x,
                    Y2 = EndPostion.Y+4,
                    Stroke = Brushes.Red
                };
                MainCanvas.Children.Add(marker);

                var gridLine = new Line
                {
                    X1 = x,
                    Y1 = StartPostion.Y,
                    X2 = x,
                    Y2 = EndPostion.Y,
                    StrokeThickness = 1,
                    Stroke = new SolidColorBrush(Colors.AliceBlue)
                };
                MainCanvas.Children.Add(gridLine);

                //画x轴字符
                var text = i.ToString(CultureInfo.InvariantCulture);
                var markText = new TextBlock
                {
                    Text = text,
                    Width = 130,
                    Foreground = Brushes.Yellow,
                    VerticalAlignment = VerticalAlignment.Top,
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    TextAlignment = TextAlignment.Left,
                    FontSize = 15
                };

                //Transform st = new SkewTransform(0, 0);
                //markText.RenderTransform = st;
                MainCanvas.Children.Add(markText);
                Canvas.SetTop(markText, EndPostion.Y + 5);
                Canvas.SetLeft(markText, x);
            }


        }

        /// <summary>
        /// X轴Y轴
        /// </summary>
        private void DrawAxis()
        {
            var xaxis = new Line
            {
                X1 = StartPostion.X,
                Y1 = EndPostion.Y,
                X2 = EndPostion.X,
                Y2 = EndPostion.Y,
                Stroke = new SolidColorBrush(Colors.Black)
            };
            MainCanvas.Children.Add(xaxis);

            var yaxis = new Line
            {
                X1 = StartPostion.X,
                Y1 = StartPostion.Y,
                X2 = StartPostion.X,
                Y2 = EndPostion.Y,
                Stroke = new SolidColorBrush(Colors.Black)
            };
            MainCanvas.Children.Add(yaxis);
        }

        /// <summary>
        /// 获取数据源
        /// </summary>
        /// <returns></returns>
        private PointCollection GetCollPoint()
        {
            PointCollection myPointCollection = new PointCollection() 
            {
                new Point(1,12),
                new Point(2,20),
                new Point(3,50),
                new Point(4,21),
                new Point(6,10),
                new Point(21,90)
            };
            
            return myPointCollection;
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {

        }
    }
}

  

 

 

 

转载于:https://www.cnblogs.com/wangyonglai/p/10553746.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF(Windows Presentation Foundation)是一种用于创建Windows应用程序的框架,可用于创建各种各样的图形用户界面(GUI),包括实时曲线图。 要实现实时曲线图中x轴的自动滚动,可以采取以下步骤: 1. 创建一个WPF应用程序并设置其主窗口。 2. 在XAML中定义一个Canvas元素,它将用于绘制实时曲线图。在Canvas上,您可以添加其他需要的元素,例如坐标轴等。 3. 在代码中,创建一个定时器(例如使用System.Timers.Timer类),以固定的时间间隔触发更新曲线图的操作。 4. 在定时器的Tick事件处理程序中,更新实时曲线图的数据,并重新绘制曲线图。 5. 在绘制曲线图时,可以通过调整x轴的坐标值来实现自动滚动的效果。例如,可以记录最后一个数据点的x轴坐标值,并将所有数据点的x轴坐标值减去该值,以实现滚动效果。 6. 然后,根据新的x轴坐标值重新绘制曲线图。 以下是一个简单示例代码: ```csharp private System.Timers.Timer timer; private double xOffset = 0; public MainWindow() { InitializeComponent(); timer = new System.Timers.Timer(100); // 设置定时器间隔为100毫秒 timer.Elapsed += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, ElapsedEventArgs e) { // 更新曲线图数据 // 调整x轴坐标值 double lastX = GetLastDataPointXValue(); xOffset += lastX; // 重新绘制曲线图 Dispatcher.BeginInvoke(new Action(() => { DrawCurve(); })); } private void DrawCurve() { // 清除Canvas上的所有图形元素 // 根据新的x轴坐标值重新绘制曲线图 double xOffset = 0; foreach (DataPoint dataPoint in dataPoints) { // 计算新的x轴坐标值 double newX = dataPoint.X - xOffset; // 绘制曲线图上的数据点 // 更新x轴坐标值为最新的值 dataPoint.X = newX; } } ``` 这样,每当定时器触发时,曲线图的x轴坐标值都会根据最新的数据进行调整,从而实现自动滚动的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值