• 使用 Apache ECharts 实现圣都装饰的延期日历图


    使用 Apache ECharts 实现圣都装饰的延期日历图

    用户需求:

    最近朋友选择圣都装饰公司来装修房子,结果公司管理混乱,延期严重,让我帮忙设计一个类似 github 的日历图,方便更直观的查看延期时间。

    需求分析:

    Apache ECharts 自带了“日历坐标系 calendar” ,可以很方便的画出日历图。

    ECharts 网站有很多的示例代码,可以去 https://echarts.apache.org/examples/zh/index.html#chart-type-calendar 网址查看例子。

    获取 Apache ECharts

    ECharts 使用很简单,只需要引入 echarts.js 文件即可。生成环境请使用压缩后的 echarts.min.js 文件。

    在 https://www.jsdelivr.com/package/npm/echarts 选择 dist/echarts.js,点击并保存为 echarts.js 文件。

    引入 Apache ECharts

    在刚才保存 echarts.js 的目录新建一个 index.html 文件,内容如下:

    DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        
        <script src="echarts.js">script>
      head>
    html> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    绘制一个简单的图表

    在绘图前我们需要为 ECharts 准备一个定义了高宽的 DOM 容器。在刚才的例子 head 标签之后,添加:

    <body>
      
      <div id="main" style="width: 600px;height:400px;">div>
    body>
    
    • 1
    • 2
    • 3
    • 4

    然后就可以通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的柱状图,下面是完整代码。

    DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>EChartstitle>
        
        <script src="echarts.js">script>
      head>
      <body>
        
        <div id="main" style="width: 600px;height:400px;">div>
        <script type="text/javascript">
          // 基于准备好的dom,初始化echarts实例
          const mainDiv = document.getElementById('main');
          const myChart = echarts.init(mainDiv);
    
          // 指定图表的配置项和数据
          const option = {
            title: {
              text: 'ECharts 入门示例'
            },
            tooltip: {},
            legend: {
              data: ['销量']
            },
            xAxis: {
              data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
            },
            yAxis: {},
            series: [
              {
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
              }
            ]
          };
    
          // 使用刚指定的配置项和数据显示图表。
          myChart.setOption(option);
        script>
      body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    通过这个小列子,可以看到,使用 Echarts 画图,最重要的就是配置 setOption 参数对象。

    下边我们来实现圣都装修延期日历图。

    圣都延期日历图的实现

    为了使 index.html 里的代码简洁,我们把 option 配置代码,放到外部 js 里。

    index.html 代码如下:

    DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8" />
        
        <script src="echarts.js">script>
    
        
        <script type="text/javascript" src="dayjs.min.js">script>
    
    head>
    
    <body>
        <h1> 圣都装修延期日历 2022 h1>
        
        <div id="main" style="width: 900px;height:800px;">div>
    
        
        <script type="text/javascript" src="shengdu_2.js">script>
        <script>
            var myChart = echarts.init(document.getElementById('main'));
    
            // 变量 option 实在 shengdu_2.js 里定义的 
            // 设置配置项,图片会渲染出来
            myChart.setOption(option);
        script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    Day.js 是一个轻量的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持完全一样。代码可以去网站 https://dayjs.gitee.io/zh-CN/ 下载。

    dayjs 的使用示例:

    // 格式化: 2022-01-25
    dayjs("2022-01-25").format("YYYY-MM-DD")
    
    // 日期转成毫秒数: 1643040000000
    dayjs("2022-01-25").valueOf()
    
    // 毫秒数转成unix时间戳(秒)
    dayjs(1318781876406).unix()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    引入的 shengdu_2.js 文件代码如下:

    // shengdu_2.js
    function get_all_dates() {
      var date = +echarts.number.parseDate("2021-09-28");
      var end = +echarts.number.parseDate("2022-06-22");
      var dayTime = 3600 * 24 * 1000;
      var showDates = [];
    
      // 这里是假期,要排除掉
      const holidays = [
        "2021-10-01",
        "2021-10-02",
        "2021-10-03",
        "2021-10-04",
        "2021-10-05",
        "2021-10-06",
        // '2021-10-07',
    
        "2022-01-01",
        "2022-01-02",
        "2022-01-03",
        "2022-01-31",
        "2022-02-01",
        "2022-02-02",
        "2022-02-03",
        "2022-02-04",
        "2022-02-05",
        "2022-02-06",
        "2022-04-05",
        "2022-05-02",
        "2022-05-03",
        "2022-05-04",
        "2022-06-03",
      ];
    
      n = 0;
      i = 0;
      delayStart = "2022-02-16";
      delayEnd = "2022-06-22";
      for (var time = date; time < end; time += dayTime) {
        // echarts.time.format(time, "yyyy-mm-dd"),
        let d = dayjs(time);
        let n = 0;
        let str = d.format("YYYY-MM-DD");
    
        console.log(d.unix());
    
        if (d.format("ddd") == "Sat" || d.format("ddd") == "Sun") {
          showDates.push([d.format("YYYY-MM-DD"), 501]); // 周末
        } else {
          if (holidays.includes(str)) {
            showDates.push([d.format("YYYY-MM-DD"), 502]); // 法定假日
          } else {
            if (
              time >= dayjs(delayStart).valueOf() &&
              time <= dayjs(delayEnd).valueOf()
            ) {
              i++;
              showDates.push([d.format("YYYY-MM-DD"), i]); // 延期时间
            } else {
              showDates.push([d.format("YYYY-MM-DD"), 500]); // 原排期
            }
          }
        }
      }
      return showDates;
    }
    
    option = {
      // 图标的标题
      title: {
        top: 30,
        left: "center",
        text: "延期日历",
      },
      // 设置鼠标悬浮时展示的文案
      tooltip: {
        formatter: (params) => {
          let msg = " 数值: ";
          if (params.value[1] <= 200) {
            msg = " 延期天数: ";
          } else if(params.value[1]==501) {
            msg = " 休息: ";
          }
          else if(params.value[1]==502) {
            msg = " 假期: ";
          }
          return params.value[0]+ msg + params.value[1].toFixed(2);
        },
      },
      // 
      visualMap: {
        // min: 0,
        // max: 1000,
        type: "piecewise",
        orient: "horizontal",
        left: "center",
        top: 65,
        type: "piecewise",
        pieces: [
          { min: 1, max: 499, label: "延期", color: "red" },
          { value: 0, label: "空", color: "white" },
          { value: 500, label: "排期", color: "green" },
          { value: 501, label: "周末", color: "lightgray" },
          { value: 502, label: "假日", color: "gray" },
        ],
        outOfRange: {
          color: "#eee",
        },
        calculable: true,
      },
      // 日历的配置
      calendar: {
        top: 120,
        left: 30,
        right: 30,
        cellSize: [30, 25],
        range: ["2021-09-01", "2022-07-09"],
        itemStyle: {
          borderWidth: 0.5,
        },
        dayLabel: {
          firstDay: 0, // 从周一开始
        },
        yearLabel: { show: false },
      },
      series: [
        {
          // type: "heatmap",
          type: "scatter",
          coordinateSystem: "calendar",
          // <---- 图标里的数据来源
          data: get_all_dates(),
          itemStyle: {
            color: "#ddb926",
          },
          symbolSize:11,
        },
      ],
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139

    图表的一些参数解析:

    日历图主要设置 calendar 参数。calendar 里的 range 指定了日历的范围。

    ECharts 中的数据,一般存放于 series.data 中。

    series,是设置数据的映射系列。即把数据集( dataset )的行或列映射为系列(series)。
    series.type 设置的是图标的类型。比如 柱状图 bar,折线图 line,饼图 pie,散点图 scatter。上边日历的代码里,用的就是散点图 scatter。

    visualMap 组件定义了把数据的哪个维度映射到什么视觉元素上。现在提供两种类型的 visualMap 组件,一个是 连续的 continuous ,一个是 分段的 piecewise ,通过 visualMap.type 来区分。(本实例使用的 piecewise 分段的)

    上边的日历图例代码里,visualMap 里 pieces 自定义的一些颜色。

    tooltip 设置鼠标悬浮时展示的文案。

    在这里插入图片描述

    感谢阅读。

  • 相关阅读:
    我理解的反射
    java计算机毕业设计环巢湖区域旅游网站MyBatis+系统+LW文档+源码+调试部署
    618大促有哪些值得买的家居好物?618五款必Buy好物
    22 Python的argparse模块
    C# 图片转PDF,PDF增加水印文字
    【闲聊杂谈】ElasticSearch的分布式原理
    Maven 依赖管理
    用Python实现创建十二星座数据分析图表
    学习STM32第十五天
    【算法训练-排序算法 三】【排序应用】合并区间
  • 原文地址:https://blog.csdn.net/cnwyt/article/details/125910170