• WinForm使用原生gdi+绘制自定义曲线图、折线图


    折线图我们可以用chart控件,但是有时候需要一些自定义元素,比如曲线图放大、曲线图缩小、曲线图拖放等,因此自定义更加灵活

    但是自定义有自己的缺点,就是功能有限。

    1.原理

    winform的自定义控件,在onpaint事件里,通过Graphics对象,将x轴、y轴,曲线绘制出来。

    为了每次能够拖拽放大缩小,在每次拖放过程中,加入计算,即计算范围和刻度线位置。

    2.计算

    比如x的范围是  222到999,为了使轴线的刻度为整数,我们将范围扩大到200到1000。为了取得正确的范围,我们需要进行以下计算。

    • 当222的时候,对222取对数,log10(222)=2.34。
    • 2.34取整数部分2,再用10求指数,得10^2=100。
    • 2.34取小于它的最大整数,Math.Floor(2.34)=2。
    • 2乘以100=200。

    同理999也一样,只不过Math.Floor改成Math.Ceiling,取大于它的最小整数

    代码片段如下

      /// <summary>
            /// 获取比value大的或者小的整数值
            /// </summary>
            /// <param name="value">要处理的值</param>
            /// <param name="isBiggerThanValue">是否比value大</param>
            /// <returns></returns>
            private decimal GetProperValue(decimal value, bool isBiggerThanValue)
            {
                var positive = value > 0 ? 1 : -1;
                //负值转换为正,正值为本身
                value = value * positive;
    
                var temp = value;
                int tenPowPart = 0;
                if (temp > 1)
                {
                    while (temp >= 10)
                    {
                        tenPowPart++;
                        temp = value * (decimal)Math.Pow(0.1, tenPowPart);
                    }
    
                    if (isBiggerThanValue)
                    {
                        temp = positive == 1 ? Math.Ceiling(temp) : Math.Floor(temp);
                    }
                    else
                    {
                        temp = positive == 1 ? Math.Floor(temp) : Math.Ceiling(temp);
                    }
    
                    var proper = positive * temp * (decimal)Math.Pow(10, tenPowPart);
    
                    return proper;
                }
                else
                {
                    while (temp < 1m && temp > 0)
                    {
                        tenPowPart++;
                        temp = value * (decimal)Math.Pow(10, tenPowPart);
    
                    }
    
                    if (isBiggerThanValue)
                    {
                        temp = positive == 1 ? Math.Ceiling(temp) : Math.Floor(temp);
                    }
                    else
                    {
                        temp = positive == 1 ? Math.Floor(temp) : Math.Ceiling(temp);
                    }
                    var proper = positive * temp * (decimal)Math.Pow(0.1, tenPowPart);
                    return proper;
                }
            }

    其他计算类似

    3.效果图源码

    源码:

    https://files.cnblogs.com/files/lizhijian/20201127Winform%E7%BB%98%E5%88%B6%E6%9B%B2%E7%BA%BF%E5%9B%BE.zip

  • 相关阅读:
    vue2:p26 webpack利用cleanwebpackplugin自动清理dist目录生成的旧生产文件
    在CentOS中安装和使用nginx
    无法下载外网Docker镜像的解决方案
    gofs使用教程基于golang的开源跨平台文件同步工具
    Stream API 简单介绍入门使用
    .npmrc 项目的 默认安装配置
    ncc koa 后台源码加密打包工具 @vercel/ncc webpack node打包更正规
    koa 文件下载 pdf预览 两个接口 nodejs chromeDownload chromePreview
    koagenerator koa 脚手架
    tag 转 分支 branch
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/14047740.html
Copyright © 2020-2023  润新知