zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    sysctl.conf文件详解
    EOF的用法
    centos7下mail邮件的查看删除、禁止部分应用发邮件
    change命令
    mac访达显示路径复制路径
    MacOS修改默认的python版本和pip版本
    mac自带录屏
    excel
列A
去除列B后的数据
    selenium初识:selenium的安装及简单实现百度搜索
    React如何运行从github上下载的代码
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/14047740.html
Copyright © 2011-2022 走看看