ECharts日历热力图点击事件和选中日期加边框

34 篇文章 1 订阅
29 篇文章 0 订阅
文章展示了如何在Vue.js应用中使用Echarts库创建一个日历热力图子组件,该组件接收并处理父组件传递的数据,显示日总计和月总计信息,同时支持点击事件以获取选中日期的数据。组件内部实现了数据的初始化、监听更新以及Echarts图表的配置和渲染。
摘要由CSDN通过智能技术生成

Echarts日历热力图子组件

<template>
  <div class="calendar">
    <div class="main" id="father">
      <div class="calendar-main" id="calendar-charts" ref="refProp"></div>
      <div class="calendar-footer">
        <div class="day_left">
          <div class="info">
            <div class="title">日总计: {{ infoItem.date}}</div>
            <div
              class="text"
              v-for="(item1, index1) in auditList"
              :key="index1"
            >
              <span :style="{ backgroundColor: item1.bgColor }"
                >{{ item1.name }}:</span
              >
              {{ infoItem[item1.Ename] || 0 }} 项
            </div>
          </div>
        </div>
        <div class="month_right" v-if="monthData">
          <div class="info">
            <div class="title">月总计: {{ month }}</div>
            <div class="text" v-for="(item, index) in monthList" :key="index">
              <span :style="{ backgroundColor: item.bgColor }"
                >{{ item.name }}:</span
              >
              {{ monthData[item.Ename] || 0 }} 天
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import resize from "@/views/dashboard/mixins/resize.js";
import echarts from "echarts";
import moment from "moment";
require("echarts/theme/macarons");

export default {
  mixins: [resize],
  components: {},
  props: {
    monthNum: {
      type: String,
      required: true
    },
    calendarMonthData: {
      type: Object,
      default: function() {
        return {};
      },
      required: true
    }
  },
  name: "CalendarCharts",
  data() {
    return {
      chart: null,
      month: "",
      chartData: {},
      dayNum: [],
      monthData: {}, // 月总数据天数
      infoData: [], // 日总数据列表
      infoItem: {}, // 单日数据项
      auditList: [
        {
          name: "未审核",
          Ename: "unAudit",
          bgColor: "#999",
          id: 1
        },
        {
          name: "一级审核",
          Ename: "firstAudit",
          bgColor: "orange",
          id: 2
        },
        {
          name: "二审无效",
          Ename: "secAuditAgree",
          bgColor: "#ff0033",
          id: 3
        },
        {
          name: "二审有效",
          Ename: "SecAuditDisagree",
          bgColor: "#93FF93",
          id: 4
        }
      ],
      monthList: [
        {
          name: "未审核",
          Ename: "unAuditNum",
          bgColor: "#999",
          id: 1
        },
        {
          name: "一级审核",
          Ename: "firstAuditDayNum",
          bgColor: "orange",
          id: 2
        },
        {
          name: "二审审核",
          Ename: "secAuditDayNum",
          bgColor: "#ff0033",
          id: 3
        }
      ],
    };
  },
  watch: {
    calendarMonthData: {
      deep: true,
      handler(val) {
        // this.infoData = val.infoData
        this.initChart();
      }
    }
  },

  created() {},
  mounted() {
    this.chartData = this.calendarMonthData;
    this.monthData = this.calendarMonthData.Summary;
    this.infoData = this.chartData.infoData;

    this.month = this.monthNum;
    this.month = moment(this.month).format("YYYY-MM");
    this.initChart();
  },
  beforeDestroy() {
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },

  methods: {
    initChart() {
      if (this.chart) {
        this.chart.dispose();
      }
      this.initChartData();
      this.chart = echarts.init(this.$refs.refProp, "macarons");
      this.updateChart();
      this.getNowDate();
    },

    initChartData() {
      //初始化数据
      if (this.calendarMonthData !== null) {
        //#把自身的数据替换成父组件传过来的数据
        this.chartData = this.calendarMonthData;
        this.monthData = this.calendarMonthData.Summary;
        this.infoData = this.chartData.infoData;

        this.month = this.monthNum;
        this.month = moment(this.month).format("YYYY-MM");
      } else {
        this.chartData = {};
        this.monthData = {};
      }
    },

    updateChart() {
      const option = {
        tooltip: {
          trigger: "none" //设置 tooltip.trigger 为 'none'
        },
        visualMap: {
          // 样例
          show: true,
          type: "piecewise",
          orient: "vertical",
          calculable: false,
          splitNumber: 3,
          pieces: [
            { min: 0, max: 0, label: "无数据", color: "#D4D4D4" },
            { min: 1, max: 3, label: "未审核", color: "#999" },
            { min: 4, max: 6, label: "一级审核", color: "#97CBFF" },
            { min: 7, max: 9, label: "二级审核", color: "#0080FF" }
          ],
          left: 550,
          bottom: 10,
          textStyle: {
            fontSize: 10
          },
          inRange: {
            color: ["#D4D4D4", "#999", "#97CBFF", "#0080FF"],
            opacity: 1
          }
        },
        calendar: [
          {
            orient: "vertical",
            left: 90,
            bottom: 0,
            top: 20,
            cellSize: [55, "auto"], // 格子尺寸
            range: this.month,

            dayLabel: {
              margin: 5,
              nameMap: "cn"
            },

            itemStyle: {
              normal: {
                color: "#D4D4D4",
                borderWidth: 4,
                borderColor: "#fff"
              }
            },

            splitLine: {
              show: false
            },
            monthLabel: {
              show: true,
              margin: 30,
              nameMap: "cn",
              formatter: null,
              color: "#666",
              fontSize: 15
            },
            yearLabel: {
              show: false
            },
            selectedLabel: {
              color: "#fff"
            }
          }
        ],
        series: [
          {
            type: "heatmap",
            coordinateSystem: "calendar",
            calendarIndex: 0,
            z: 2,
            data: this.chartData.calendarData,
            label: {
              show: true,
              color: "#409EFF"
            },
            emphasis: {
              // 鼠标悬浮区域样式
              itemStyle: {
                borderWidth: 1,
                borderColor: "#333"
              },
              label: {
                show: true,
                color: "#409EFF"
              }
            },

            label: {
              show: true,
              formatter: function(params) {
                var d = new Date(params.value[0]);
                return d.getDate();
              },
              color: "#000"
            }
          }
        ]
      };
      this.chart.setOption(option);
    },

    // 点击事件,获取选中日期传递给父组件
    getNowDate(params) {
      let that = this; //把this赋给变量that
      that.chart.on("click", function(e) {
        // 高亮颜色
        that.ChangeFontColor(e);
        setTimeout(() => {
          const data = e.data[0];
          that.$emit("getData", data); //用that.$emit即可解决传值问题
          // that.infoData = that.chartData.infoData;
          that.infoItem = that.infoData.find(obj => obj.date === data);
        }, 20);
      });
    },

    // 点击图标改变字体颜色
    ChangeFontColor(params) {
      let seriesIndex = params.seriesIndex;
      let dataIndex = params.dataIndex;
      this.chart.dispatchAction({
        type: "downplay" //取消高亮指定的数据图形。通过seriesName或者seriesIndex指定系列。如果要指定某个数据可以再指定dataIndex或者name。
      });
      this.chart.dispatchAction({
        type: "highlight", //高亮指定的数据图形。通过seriesName或者seriesIndex指定系列。如果要再指定某个数据可以再指定dataIndex或者name。         //取消高亮指定的数据图形。通过seriesName或者seriesIndex指定系列。如果要指定某个数据可以再指定dataIndex或者name。
        seriesIndex: seriesIndex, // 可选,系列 index,可以是一个数组指定多个系列
        dataIndex: dataIndex // 可选,数据的 index
      });
    },

    // 父组件调用,更新日总计的数据
    ChangeInfoData(params) {
      let dataIndex = params.dataIndex;
      const infoData = params.infoData;

      // 获取某个日期的数据
      const data = this.chart.getOption().series[0].data[dataIndex];

      if (infoData !== undefined) {
        this.infoItem = infoData.find(obj => obj.date === data[0]);
      } else {
        this.infoItem = this.infoData.find(obj => obj.date === data[0]);
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.calendar {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 135px;
  // margin: 10px 0px 0px;
  .main {
    display: flex;
    height: auto;
    position: relative;
  }
}

.calendar-main {
  height: auto;
  width: 52%;
  // flex: 1;
}

.calendar-footer {
  display: flex;
  justify-content: space-around;
  margin-left: 30px;
  .title {
    font-size: 16px;
    font-weight: 600;
    text-align: left;
    margin: 0;
  }
  .text {
    line-height: 22px;
    padding: 2px;
    font-size: 14px;
    margin-right: 20px;
    text-align: left;
  }
  .day_left,
  .month_right {
    display: flex;
    margin: 0 30px;
  }
}
</style>

 父组件

<!-- 日历组件 -->
            <el-collapse
              v-model="active"
              accordion
              @change="handleCollapseChange"
            >
              <el-collapse-item title="日历图" name="1">
                <div style="width: 100%; display: flex">
                  <calendar-charts
                    :calendarMonthData="calendarMonthDataObj"
                    :monthNum="time"
                    @getData="getCalendarClickData"
                    ref="calendarRef"
                  ></calendar-charts>
                </div>
              </el-collapse-item>
            </el-collapse>

 切换日期时,选中框问题和日总计问题

this.date = todayTime;
            const dataIndex = parseInt(this.date.split("-").pop(), 10) - 1; // 拿到日期所在的索引
            // 获取echarts实例
            this.$refs.calendarRef.ChangeFontColor({ dataIndex: dataIndex }); // 切换回todayTime的日期,选中 dataIndex 的日期
            this.$refs.calendarRef.ChangeInfoData({ dataIndex: dataIndex }); // 切换回todayTime的日期,更新日总计的数据
getCalendarSummary(query).then(response => {
        this.dateInfoData = response.data.infoData;
        this.calendarMonthDataObj = response.data;
        if (this.date !== "") {
          // 如果有选择日期,则调用子组件方法更新最新的月数据
          const dataIndex = parseInt(this.date.split("-").pop(), 10) - 1; // 拿到日期所在的索引
          this.$refs.calendarRef.ChangeInfoData({
            dataIndex: dataIndex,
            infoData: this.dateInfoData
          }); // 更新日总计的数据
        }
      });

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值