[Blazor] 仪表盘

2023-10-24 14:49:12 浏览数 (2)

视频演示:https://mpvideo.qpic.cn/0bc3t4adgaaa7yabqrrspfsvbh6dgopqamya.f10002.mp4?

JS代码如下:

代码语言:javascript复制
var highlight = '#03b7c9';

var demoData = [
    { name: '电压', value: 220, unit: 'V', pos: ['16.6%', '25%'], range: [0, 400] },
    { name: '电流', value: 32, unit: 'A', pos: ['49.8%', '25%'], range: [0, 60] },
    { name: '功率因数', value: 0.9, pos: ['83%', '25%'], range: [0.1, 1.0], splitNum: 9 },
    { name: '有功功率', value: 6.34, unit: 'kW', pos: ['16.6%', '75%'], range: [0, 50] },
    { name: '有功电能', value: 6.28, unit: 'kWh', pos: ['49.8%', '75%'], range: [0, 50] },
    { name: '电网频率', value: 50, unit: 'Hz', pos: ['83%', '75%'], range: [0, 100] },
];

option = {
    backgroundColor: '#222939',

    series: (function () {
        var result = [];

        demoData.forEach(function (item) {
            result.push(
                // 外围刻度
                {
                    type: 'gauge',
                    center: item.pos,
                    radius: '33.33%', // 1行3个
                    splitNumber: item.splitNum || 10,
                    min: item.range[0],
                    max: item.range[1],
                    startAngle: 225,
                    endAngle: -45,
                    axisLine: {
                        show: true,
                        lineStyle: {
                            width: 2,
                            shadowBlur: 0,
                            color: [[1, highlight]],
                        },
                    },
                    axisTick: {
                        show: true,
                        lineStyle: {
                            color: highlight,
                            width: 1,
                        },
                        length: -5,
                        splitNumber: 10,
                    },
                    splitLine: {
                        show: true,
                        length: -14,
                        lineStyle: {
                            color: highlight,
                        },
                    },
                    axisLabel: {
                        distance: -20,
                        textStyle: {
                            color: highlight,
                            fontSize: '14',
                            fontWeight: 'bold',
                        },
                    },
                    pointer: {
                        show: 0,
                    },
                    detail: {
                        show: 0,
                    },
                },

                // 内侧指针、数值显示
                {
                    name: item.name,
                    type: 'gauge',
                    center: item.pos,
                    radius: '30.33%',
                    startAngle: 225,
                    endAngle: -45,
                    min: item.range[0],
                    max: item.range[1],
                    axisLine: {
                        show: true,
                        lineStyle: {
                            width: 16,
                            color: [[1, 'rgba(255,255,255,.1)']],
                        },
                    },
                    axisTick: {
                        show: 0,
                    },
                    splitLine: {
                        show: 0,
                    },
                    axisLabel: {
                        show: 0,
                    },
                    pointer: {
                        show: true,
                        length: '105%',
                    },
                    detail: {
                        show: true,
                        offsetCenter: [0, '100%'],
                        textStyle: {
                            fontSize: 20,
                            color: '#fff',
                        },
                        formatter: ['{value} '   (item.unit || ''), '{name|'   item.name   '}'].join('n'),
                        rich: {
                            name: {
                                fontSize: 14,
                                lineHeight: 30,
                                color: '#ddd',
                            },
                        },
                    },
                    itemStyle: {
                        normal: {
                            color: highlight,
                        },
                    },
                    data: [
                        {
                            value: item.value,
                        },
                    ],
                    anchor: {
                        show: true,
                        showAbove: true,
                        size: 24,
                        itemStyle: {
                            color: '#fff',
                        },
                    },
                }
            );
        });

        return result;
    })(),
};

本来我打算把eCharts配置项都用Class来做的,曲线之类的都做完了。但是这两天发现有时候还不如直接用匿名方法或者字典来做,这样更灵活。主要代码如下:我只把DeviceData做了封装。

代码语言:javascript复制
protected override void OnInitialized()
  {
    Data  = new List<DeviceData>
{
  new DeviceData { Name = "电压", Value = 220, Unit = "V", Pos = new List<string> { "16.6%", "25%" }, Range = new List<double> { 0, 400 } },
  new DeviceData { Name = "电流", Value = 32, Unit = "A", Pos = new List<string> { "49.8%", "25%" }, Range = new List<double> { 0, 60 } },
  new DeviceData { Name = "功率因数", Value = 0.9, Pos = new List<string> { "83%", "25%" }, Range = new List<double> { 0.1, 1.0 }, SplitNum = 9 },
  new DeviceData { Name = "有功功率", Value = 6.34, Unit = "kW", Pos = new List<string> { "16.6%", "75%" }, Range = new List<double> { 0, 50 } },
  new DeviceData { Name = "有功电能", Value = 6.28, Unit = "kWh", Pos = new List<string> { "49.8%", "75%" }, Range = new List<double> { 0, 50 } },
  new DeviceData { Name = "电网频率", Value = 50, Unit = "Hz", Pos = new List<string> { "83%", "75%" }, Range = new List<double> { 0, 100 } }
};
    // 创建仪表盘系列
    series= new List<Dictionary<string, object>>();
    foreach (var item in Data)
    {
      series.Add(CreateOuterScale(item, highlight));
      series.Add(CreateInnerPointer(item, highlight));
    }
    option =GetOption(series);
  }  private Dictionary<string, object> GetOption(List<Dictionary<string, object>> series)
  {
    return new Dictionary<string, object>
    {
      ["backgroundColor"] = "#222939",
      ["series"] = series
    };
  }

  /// <summary>
  /// 这个函数首先创建一个字典,然后为这个字典设置各种属性,包括类型、中心点、半径、刻度数、最小值、最大值、开始角度、结束角度、轴线、刻度线、分割线、轴标签、指针和细节。所有这些属性都是从DeviceData对象中获取的。
  /// </summary>
  /// <param name="item"></param>
  /// <param name="highlight"></param>
  /// <returns></returns>
  private Dictionary<string, object> CreateOuterScale(DeviceData item, string highlight)
  {
    return new Dictionary<string, object>
    {
      ["type"] = "gauge",
      ["center"] = item.Pos,
      ["radius"] = "33.33%",
      ["splitNumber"] = item.SplitNum != 0 ? item.SplitNum : 10,
      ["min"] = item.Range[0],
      ["max"] = item.Range[1],
      ["startAngle"] = 225,
      ["endAngle"] = -45,
      ["axisLine"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["lineStyle"] = new Dictionary<string, object>
        {
          ["width"] = 2,
          ["shadowBlur"] = 0,
          ["color"] = new List<object> { new List<object> { 1, highlight } }
        }
      },
      ["axisTick"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["lineStyle"] = new Dictionary<string, object>
        {
          ["color"] = highlight,
          ["width"] = 1
        },
        ["length"] = -5,
        ["splitNumber"] = 10
      },
      ["splitLine"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["length"] = -14,
        ["lineStyle"] = new Dictionary<string, object>
        {
          ["color"] = highlight
        }
      },
      ["axisLabel"] = new Dictionary<string, object>
      {
        ["distance"] = -20,
        ["textStyle"] = new Dictionary<string, object>
        {
          ["color"] = highlight,
          ["fontSize"] = 14,
          ["fontWeight"] = "bold"
        }
      },
      ["pointer"] = new Dictionary<string, object>
      {
        ["show"] = 0
      },
      ["detail"] = new Dictionary<string, object>
      {
        ["show"] = 0
      }
    };
  }

  /// <summary>
  /// 接收一个DeviceData对象和一个颜色字符串,然后返回一个表示内侧指针和数值显示的字典
  /// </summary>
  /// <param name="item"></param>
  /// <param name="highlight"></param>
  /// <returns></returns>
  private Dictionary<string, object> CreateInnerPointer(DeviceData item, string highlight)
  {
    return new Dictionary<string, object>
    {
      ["name"] = item.Name,
      ["type"] = "gauge",
      ["center"] = item.Pos,
      ["radius"] = "30.33%",
      ["startAngle"] = 225,
      ["endAngle"] = -45,
      ["min"] = item.Range[0],
      ["max"] = item.Range[1],
      ["axisLine"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["lineStyle"] = new Dictionary<string, object>
        {
          ["width"] = 16,
          ["color"] = new List<object> { new List<object> { 1, "rgba(255,255,255,.1)" } }
        }
      },
      ["axisTick"] = new Dictionary<string, object>
      {
        ["show"] = 0
      },
      ["splitLine"] = new Dictionary<string, object>
      {
        ["show"] = 0
      },
      ["axisLabel"] = new Dictionary<string, object>
      {
        ["show"] = 0
      },
      ["pointer"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["length"] = "105%"
      },
      ["detail"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["offsetCenter"] = new List<string> { "0", "100%" },
        ["textStyle"] = new Dictionary<string, object>
        {
          ["fontSize"] = 20,
          ["color"] = "#fff"
        },
        ["formatter"] = new List<string> { "{value} "   (item.Unit ?? ""), "{name|"   item.Name   "}" }.Aggregate((i, j) => i   "n"   j),
        ["rich"] = new Dictionary<string, object>
        {
          ["name"] = new Dictionary<string, object>
          {
            ["fontSize"] = 14,
            ["lineHeight"] = 30,
            ["color"] = "#ddd"
          }
        }
      },
      ["itemStyle"] = new Dictionary<string, object>
      {
        ["normal"] = new Dictionary<string, object>
        {
          ["color"] = highlight
        }
      },
      ["data"] = new List<Dictionary<string, object>>
    {
      new Dictionary<string, object>
      {
        ["value"] = item.Value
      }
    },
      ["anchor"] = new Dictionary<string, object>
      {
        ["show"] = true,
        ["showAbove"] = true,
        ["size"] = 24,
        ["itemStyle"] = new Dictionary<string, object>
        {
          ["color"] = "#fff"
        }
      }
    };
  }

  public class DeviceData
  {
    public string Name { get; set; }
    public double Value { get; set; }
    public string Unit { get; set; }
    public List<string> Pos { get; set; }
    public List<double> Range { get; set; }
    public int SplitNum { get; set; }
  }

这样只需要实时刷新一些Option就行了

代码语言:javascript复制
    Data[0].Value= _count;
    Data[1].Value= DateTime.Now.Second;
    // 重新构建series列表
    series.Clear();
    foreach (var item in Data)
    {
      series.Add(CreateOuterScale(item, highlight));
      series.Add(CreateInnerPointer(item, highlight));
    }

    // 更新图表数据
    echarts?.SetOption(option);//有效果

0 人点赞