自定义刻度尺

渐进颜色

demo

var uc = new UC_Ruler(-10.28f, 0.48f)
{
    Width = 700,
    Height = 70,
}; 

// 硬截断2位,简化显示
var interval = Math.Floor(uc.RulerInterval * 100) / 100;
uc.RulerInterval = (float)interval;
panel1.Controls.Add(uc);

cs

using System;
using System.Drawing;
using System.Windows.Forms;

/// <summary>
/// 刻度尺控件
/// </summary>
public partial class UC_Ruler : UserControl
{
    public UC_Ruler(float startNum, float endNum)
    {
        InitializeComponent();
        StartNum = startNum;
        EndNum = endNum;
    }
    /// <summary>
    /// 开始数字
    /// </summary>
    public float StartNum { get; set; } = 0f;
    /// <summary>
    /// 结束数字
    /// </summary>
    public float EndNum { get; set; } = 10f;

    public override Color BackColor { get; set; } = Color.Transparent;
    public override Color ForeColor { get; set; } = Color.Black;
    public override Font Font { get; set; } = new Font("Arial", 9);
    /// <summary>
    /// 缩放比例
    /// </summary>
    public float Scaling { get; set; } = 1f;
    /// <summary>
    /// 设置刻度尺到左侧的距离
    /// </summary>
    public int OffsetLeft { get; set; } = 5;
    /// <summary>
    /// 刻度线数量
    /// </summary>
    public int TickMarkNum { get; } = 9;
    /// <summary>
    /// 刻度尺长度
    /// </summary>
    public float RulerLength
    {
        get
        {
            if (EndNum <= StartNum)
            {
                throw new ArgumentOutOfRangeException(nameof(EndNum), string.Format("{0}数值必须大于{1}", nameof(EndNum), nameof(StartNum)));
            }
            return EndNum - StartNum;
        }
    }
    private float _interval;
    /// <summary>
    /// 刻度尺间隔
    /// </summary>
    public float RulerInterval
    {
        get
        {
            _interval = RulerLength / (TickMarkNum - 1);
            return _interval;
        }
        set
        {
            _interval = value;
            if (_interval * (TickMarkNum - 1) <= RulerLength)
            {
                var thrink = (RulerLength - _interval * (TickMarkNum - 1)) / 2;
                StartNum += thrink;
                EndNum -= thrink;
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(RulerInterval), string.Format("{0}数值设置过大!", nameof(RulerInterval)));
            }
        }
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        if (EndNum <= StartNum)
        {
            throw new ArgumentOutOfRangeException(nameof(EndNum), string.Format("{0}数值必须大于{1}", nameof(EndNum), nameof(StartNum)));
        }
        var g = e.Graphics;
        int width = panel1.Width;
        int height = panel1.Height;
        var rectangle = new Rectangle(0, 0, width, height);
        // 绘制渐进颜色
        var lineGrBrush = new System.Drawing.Drawing2D.LinearGradientBrush(rectangle,
            Color.FromName("blue"), Color.FromName("red"), System.Drawing.Drawing2D.LinearGradientMode.Horizontal);
        g.FillRectangle(lineGrBrush, rectangle);
        using (var pen = new Pen(ForeColor, 2))
        {
            // 填充颜色
            var brush = new SolidBrush(BackColor);
            g.FillRectangle(brush, rectangle);
            // 边框 top
            g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X + width, rectangle.Y);
            // 边框 right
            g.DrawLine(pen, rectangle.X + width, rectangle.Y, rectangle.X + width, rectangle.Y + height);
            // 边框 bottom
            g.DrawLine(pen, rectangle.X, rectangle.Y + height, rectangle.X + width, rectangle.Y + height);
            // 边框 left
            g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + height);
            // 绘制刻度
            Scaling = width / (TickMarkNum - 1);
            decimal num = Convert.ToDecimal(StartNum);
            for (int i = 0; i < TickMarkNum; i++)
            {
                float x = i * Scaling;
                if (x <= 0)
                {
                    x = OffsetLeft;
                }
                if (x + OffsetLeft >= width)
                {
                    x = width - OffsetLeft;
                }
                var numStr = num.ToString();
                // 字符串大小信息
                SizeF strSize = g.MeasureString(numStr, Font);
                var strWidth = strSize.Width;
                var fontWidth = strWidth / numStr.Length;
                var ptStr = GetStrPoint(x, fontWidth, numStr.Length, height, panel1.Margin.Right, width);
                g.DrawString(numStr, Font, new SolidBrush(ForeColor), ptStr.X, ptStr.Y + 2);
                // top
                g.DrawLine(pen, x, 0, x, OffsetLeft);
                // bottom
                g.DrawLine(pen, x, height, x, height - OffsetLeft);

                num += Convert.ToDecimal(RulerInterval);
            }
        }
    }
    /// <summary>
    /// 获取文本显示坐标
    /// </summary>
    /// <param name="x">刻度线水平位置</param>
    /// <param name="fontWidth">字体宽度</param>
    /// <param name="strLen">文本长度</param>
    /// <param name="lineY">垂直方向位置</param>
    /// <param name="offset">偏移量</param>
    /// <param name="maximum">水平方向最大值</param>
    /// <returns></returns>
    private static PointF GetStrPoint(float x, float fontWidth, int strLen, float lineY, int offset, int maximum)
    {
        float xVal = x - fontWidth * (strLen * 1.0f / 2);
        float yVal = lineY;
        if (xVal < 0)
        {
            xVal = 0;
        }
        if (xVal + fontWidth * strLen > maximum)
        {
            xVal = maximum - fontWidth * strLen + offset;
        }
        return new PointF(xVal, yVal);
    }

}

热力图

 
protected override void OnPaint(PaintEventArgs e)
{
    ......
    var rectangle = new Rectangle(0, 0, width, height);
/*
    // 绘制渐进颜色
    //var lineGrBrush = new System.Drawing.Drawing2D.LinearGradientBrush(rectangle,
    //    Color.FromName("blue"), Color.FromName("red"), System.Drawing.Drawing2D.LinearGradientMode.Horizontal);
    //g.FillRectangle(lineGrBrush, rectangle);

    // Blue-Cyan-Yellow-Red
*/
    var rectW = width / 3f;
    var rect1 = new RectangleF(0, 0, rectW, height);
    var grBrush1 = new System.Drawing.Drawing2D.LinearGradientBrush(rect1,
        Color.FromName("Blue"), Color.FromName("Cyan"), System.Drawing.Drawing2D.LinearGradientMode.Horizontal);  
    g.FillRectangle(grBrush1, rect1);
    var rect2 = new RectangleF(rectW, 0, rectW, height);
    var grBrush2 = new System.Drawing.Drawing2D.LinearGradientBrush(rect2,
        Color.FromName("Cyan"), Color.FromName("Yellow"), System.Drawing.Drawing2D.LinearGradientMode.Horizontal);  
    g.FillRectangle(grBrush2, rect2);
    var rect3 = new RectangleF(rectW * 2, 0, rectW, height);
    var grBrush3 = new System.Drawing.Drawing2D.LinearGradientBrush(rect3,
        Color.FromName("Yellow"), Color.FromName("Red"), System.Drawing.Drawing2D.LinearGradientMode.Horizontal);  
    g.FillRectangle(grBrush3, rect3);

    using (var pen = new Pen(ForeColor, 2))
    {
        // TODO
    }
}
posted @ 2023-11-03 09:53  wesson2019  阅读(14)  评论(0编辑  收藏  举报