前台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;
}
}
}