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)
- {
- }
- }
- }
WPF 绘制曲线图的更多相关文章
- 封装:WPF绘制曲线视图
原文:封装:WPF绘制曲线视图 一.目的:绘制简单轻量级的曲线视图 二.实现: 1.动画加载曲线 2.点击图例显示隐藏对应曲线 3.绘制标准基准线 4.绘制蒙板显示标准区域 曲线图示例: 心电图示例: ...
- 使用.net 的Chart控件绘制曲线图
在进行软件开发过程中我们可能会碰到需要生成图表的情况,在.NET中以前经常用GDI去绘制,虽然效果也不错,自从.NET 4.0开始,专门为绘制图表而生的Chart控件出现了,有了它,就可以轻松的绘制你 ...
- WPF绘制党徽(立体效果,Cool)
原文:WPF绘制党徽(立体效果,Cool) 前面用WPF方式绘制了党旗(WPF制作的党旗) ,去年3月份利用C# 及GDI+绘制过党徽,这次使用WPF来绘制党徽. ------------------ ...
- Highcharts绘制曲线图小结
Higcharts绘制曲线图很好用! 虽然说Highcharts官网有API 刚接触这个领域,学有心得,理解不到位之处希望大家多多指教! 项目绘制的曲线是:平均水位随时间的变化而改变的水情走势图. 主 ...
- WPF绘制自定义窗口
原文:WPF绘制自定义窗口 WPF是制作界面的一大利器,下面就用WPF模拟一下360的软件管理界面,360软件管理界面如下: 界面不难,主要有如下几个要素: 窗体的圆角 自定义标题栏及按钮 自定义状态 ...
- WPF绘制深度不同颜色的3D模型填充图和线框图
原文:WPF绘制深度不同颜色的3D模型填充图和线框图 在机械测量过程中,测量的数据需要进行软件处理.通常测量一个零件之后,需要重建零件的3D模型,便于观察测量结果是否与所测工件一致. 重建的3D模型需 ...
- [原译]WPF绘制圆角多边形
原文:[原译]WPF绘制圆角多边形 介绍 最近,我发现我需要个圆角多边形.而且是需要在运行时从用户界面来绘制.WPF有多边形.但是不支持圆角.我搜索了一下.也没找到可行的现成例子.于是就自己做吧.本文 ...
- WPF绘制折线
WPF后台绘制折线,填充到一个GRID下 private void btnPreview_Click(object sender, RoutedEventArgs e) { GridImg.Child ...
- WPF绘制矢量图形模糊的问题
WPF默认提供了抗锯齿功能,通过向外扩展的半透明边缘来实现模糊化.由于WPF采用了设备无关单位,当设备DPI大于系统DPI时,可能会产生像素自动扩展问题,这就导致线条自动向外扩展一个像素,并且与边缘相 ...
随机推荐
- Idea中类上有叉的解决方法
idea中类的头上出现X解决办法 ctrl+alt+s 在弹出的菜单上选择Compiler下的Excludes 右边会有 移除掉,点击ok, 重启idea就可以了
- RestExpress response中addHeader 导致stackOverflow
问题描述: 最近在项目使用中要在restExpress的header中增加一个键值对,同事在使用的时候没有对header的value进行非空判断,于是在测试环境测试的时候就出现了一个异常
- I2C的小结
下面是 I 2 C 总线的一些特征 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地 址 主机可以 ...
- Delphi RTTI的应用(一)
1.获取DbgrdiEH 某一个选项的属性.加载到ComBox procedure TForm1.FormCreate(Sender: TObject); var PropInfo: PPropInf ...
- Mybatis-PageHelper分页插件
PageHelper.startPage 静态方法调用 除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法. 在你需要进行分页 ...
- java中封装类(一)
java中封装类共九个,分别是Boolean,Byte,Short,Integer,Long,Float,Double,Character,Void 其中Void对于使用者并无多大意义,也不可以构造任 ...
- 在delphi中XLSReadWriteII.组件的应用实例(2)
第三方组件:XLSReadWriteII.v.5.20.67_XE3 实例源码如下: unit Unit1; interface uses Winapi.Windows, Winapi.Messa ...
- [转]IIS应用程序池经典模式转集成模式解决方案
经典模式和集成模式的区别: IIS7.0中的Web应用程序有两种配置形式:经典形式和集成形式. 经典形式是为了与之前的版本兼容,运用ISAPI扩展来调用ASP.NET运转库,原先运转于IIS6.0下的 ...
- easyui多图片上传+预览切换+支持IE8
引入css和js: <link href="${pageContext.request.contextPath}/plugin/dialog/dialog.css" rel= ...
- 89. Gray Code返回位运算的所有生成值
[抄题]: The gray code is a binary numeral system where two successive values differ in only one bit. G ...