wpf canvas折线图和点图

前台xaml代码

<Window x:Class="SeaTiger8SimulateEnv.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SeaTiger8SimulateEnv"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1200">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="400"/>
            <RowDefinition Height="400"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition Width="400"/>
        </Grid.ColumnDefinitions>
        <Canvas Name="can" Margin="5">
        </Canvas>
    </Grid>
</Window>

后台cs代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Threading;

namespace SeaTiger8SimulateEnv
{
    public partial class MainWindow : Window
    {
        private DispatcherTimer dispatcherTimer = null;
        private int i = 0;
        public Line myLine = new Line();
        public Path myPath = new Path();
        public PathGeometry pg = new PathGeometry();
        public static double intervalX = 50;
        public static double intervalY = 50;
        public static int num = 6;
        public static int scalelHeight = 10;
        //原点 O=(40,350)
        public static int originX = 40;
        public static int originY = 350;
        public static double textXInterval = 2000;
        public static double textYInterval = 1000;
        public static double r2cConvertX ,r2cConvertY;

        public MainWindow()
        {
            InitializeComponent();
            
            dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(TimeCycle);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
            dispatcherTimer.Start();
        }
        private void TimeCycle(object sender, EventArgs e)
        {
            //清空画布
            can.Children.Clear();
            //画坐标轴
            DrawScale();

            //生成画图用的XY 数据
            double[] dataX = new double[] { 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000 };
            double[] dataY = new double[8];
            for (int i = 0; i < dataY.Length ; i++)
            {
                Random rPoint = new Random();
                var a = rPoint.Next(1000, 6000);
                dataY[i] = a;
                Thread.Sleep(10);
            }
            //数据真实值转成canvas上的位置
            var dataX_can = DataConvert(dataX, "X");
            var dataY_can = DataConvert(dataY, "Y");

            //画折线用的点集
            PointCollection coordinatePoints = new PointCollection();
            //画点
            for (int i = 0; i < dataX.Length; i++)
            {
                Ellipse dataEllipse = new Ellipse();
                dataEllipse.Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 0, 0xff));
                dataEllipse.Width = 4;
                dataEllipse.Height = 4;

                Canvas.SetLeft(dataEllipse, dataX_can[i] - dataEllipse.Width / 2);//-4是为了补偿圆点的大小,到精确的位置
                Canvas.SetTop(dataEllipse, dataY_can[i] - dataEllipse.Height / 2);

                this.can.Children.Add(dataEllipse);

                System.Windows.Point linePoint = new System.Windows.Point((int)dataX_can[i], (int)dataY_can[i]);
                coordinatePoints.Add(linePoint);
            }
            Polyline curvePolyline = new Polyline();
            curvePolyline.Stroke = Brushes.Green;
            curvePolyline.StrokeThickness = 2;

            curvePolyline.Points = coordinatePoints;
            this.can.Children.Add(curvePolyline);
        }
        private void DrawScale()
        {
            Line xAxis = new Line();
            xAxis.X1 = 40;
            xAxis.Y1 = 350;
            xAxis.X2 = 350;
            xAxis.Y2 = 350;
            xAxis.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 0, 0));
            xAxis.StrokeThickness = 3;
            xAxis.StrokeStartLineCap = PenLineCap.Round;
            this.can.Children.Add(xAxis);
            Line yAxis = new Line();
            yAxis.X1 = 40;
            yAxis.Y1 = 350;
            yAxis.X2 = 40;
            yAxis.Y2 = 40;
            yAxis.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 0, 0));
            yAxis.StrokeThickness = 3;
            yAxis.StrokeStartLineCap = PenLineCap.Round;
            this.can.Children.Add(yAxis);

            //画坐标轴的箭头
            Path x_axisArrow = new Path();//x轴箭头
            Path y_axisArrow = new Path();//y轴箭头
            x_axisArrow.Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 0, 0));
            y_axisArrow.Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(0, 0, 0));
            PathFigure x_axisFigure = new PathFigure();
            x_axisFigure.IsClosed = true;
            x_axisFigure.StartPoint = new Point(350, 346);                          //路径的起点
            x_axisFigure.Segments.Add(new LineSegment(new Point(350, 354), false)); //第2个点
            x_axisFigure.Segments.Add(new LineSegment(new Point(365, 350), false)); //第3个点
            PathFigure y_axisFigure = new PathFigure();
            y_axisFigure.IsClosed = true;
            y_axisFigure.StartPoint = new Point(36, 40);                          //路径的起点
            y_axisFigure.Segments.Add(new LineSegment(new Point(44, 40), false)); //第2个点
            y_axisFigure.Segments.Add(new LineSegment(new Point(40, 25), false)); //第3个点
            PathGeometry x_axisGeometry = new PathGeometry();
            PathGeometry y_axisGeometry = new PathGeometry();
            x_axisGeometry.Figures.Add(x_axisFigure);
            y_axisGeometry.Figures.Add(y_axisFigure); 
            x_axisArrow.Data = x_axisGeometry;
            y_axisArrow.Data = y_axisGeometry;
            this.can.Children.Add(x_axisArrow);
            this.can.Children.Add(y_axisArrow);
            //XOY字母
            TextBlock textBlockX = new TextBlock();
            textBlockX.Text = "X";
            textBlockX.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            textBlockX.FontSize = 20;
            Canvas.SetLeft(textBlockX, 367);
            Canvas.SetTop(textBlockX, 350);
            can.Children.Add(textBlockX);
            TextBlock textBlockY = new TextBlock();
            textBlockY.Text = "Y";
            textBlockY.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            textBlockY.FontSize = 20;
            Canvas.SetLeft(textBlockY, 20);
            Canvas.SetTop(textBlockY, 10);
            can.Children.Add(textBlockY);
            TextBlock textBlock0 = new TextBlock();
            textBlock0.Text = "0";
            textBlock0.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            textBlock0.FontSize = 20;
            Canvas.SetLeft(textBlock0, 20);
            Canvas.SetTop(textBlock0, 350);
            can.Children.Add(textBlock0);

            //画坐标轴的小竖线
            for (int i = 0; i < num+1; i += 1)//作480个刻度,因为当前x轴长 480px,每10px作一个小刻度,还预留了一些小空间
            {
                Line x_scale = new Line();
                x_scale.StrokeEndLineCap = PenLineCap.Triangle;
                x_scale.StrokeThickness = 1;
                x_scale.Stroke = new SolidColorBrush(Color.FromRgb(0, 0, 0));

                x_scale.X1 = originX + i * intervalX;   //原点x=40,每10px作1个刻度
                x_scale.X2 = x_scale.X1;    //在x轴上的刻度线,起点和终点相同

                x_scale.Y1 = originY;           //与原点坐标的y=280,相同
                x_scale.Y2 = x_scale.Y1 - scalelHeight;//刻度线长度为4px

                if (i < num+1)//由于y轴短一些,所以在此作出判断,只作25个刻度
                {
                    //作出Y轴的刻度
                    Line y_scale = new Line();
                    y_scale.StrokeEndLineCap = PenLineCap.Triangle;
                    y_scale.StrokeThickness = 1;
                    y_scale.Stroke = new SolidColorBrush(Color.FromRgb(0, 0, 0));

                    y_scale.X1 = originX;            //原点x=40,在y轴上的刻度线的起点与原点相同
                    y_scale.X2 = y_scale.X1 + scalelHeight;//刻度线长度为4px

                    y_scale.Y1 = originY - i * intervalY;  //每10px作一个刻度
                    y_scale.Y2 = y_scale.Y1;    //起点和终点y坐标相同
                    this.can.Children.Add(y_scale);
                }
                this.can.Children.Add(x_scale);
            }
            //画坐标轴下的数字
            for (int i = 1; i < num+1; i++)//7 个标签,一共
            {
                TextBlock x_ScaleLabel = new TextBlock();
                TextBlock y_ScaleLabel = new TextBlock();
               
                x_ScaleLabel.Text = (i * textXInterval).ToString();//只给大刻度添加标签,每50px添加一个标签
                
                Canvas.SetLeft(x_ScaleLabel, originX + intervalX * i - 15);//40是原点的坐标,-12是为了让标签看的位置剧中一点
                Canvas.SetTop(x_ScaleLabel, originY + 2);//让标签字往下移一点
                
                y_ScaleLabel.Text = (i * textYInterval).ToString();
                Canvas.SetLeft(y_ScaleLabel, originX - 40);              //-25px是字体大小的偏移
                Canvas.SetTop(y_ScaleLabel, originY - intervalY * i - 8);  //280px是原点的坐标,同样-6是为了让标签不要上坐标轴叠上
                
                this.can.Children.Add(x_ScaleLabel);
                this.can.Children.Add(y_ScaleLabel);
            }
            //计算实际数字与画布上距离的缩放倍数
            r2cConvertX = intervalX / textXInterval;
            r2cConvertY = intervalX / textYInterval;
        }

        private double[] DataConvert(double[] data, string type)
        {
            double[] canvasData = new double[data.Length];
            if (type == "X")
            {
                for (int i = 0; i < data.Length; i++)
                {
                    canvasData[i] = originX + data[i] * r2cConvertX;
                }
            }
            else
            {
                for (int i = 0; i < data.Length; i++)
                {
                    canvasData[i] = originY - data[i] * r2cConvertY;
                }
            }

            return canvasData;
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值