WinForm使用原生gdi+繪製自定義曲線圖、折線圖
阿新 • • 發佈:2020-11-27
折線圖我們可以用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