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
}); // 更新日总计的数据
}
});