欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF 绘制曲线图

程序员文章站 2022-07-04 19:26:23
之前一直用GDI绘图,后面公司要求使用WPF,网上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 绘制曲线图