1. 程式人生 > 實用技巧 >WinForm使用原生gdi+繪製自定義曲線圖、折線圖

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