wp网站模板,网站打开速度,福建网站开发有限开发公司,在线crm视频在线crm免git日历坐标系? 手动实现github活跃/贡献图 
前言 
在使用github或gitlab时#xff0c;我们总能发现#xff0c;我们一年内的活跃度能够通过一张图直观地展现出来#xff0c;那么你是否好奇它是如何实现的#xff0c;最近工作中也遇到这样类似的需求#xff0c;刚开始打算…git日历坐标系? 手动实现github活跃/贡献图 
前言 
在使用github或gitlab时我们总能发现我们一年内的活跃度能够通过一张图直观地展现出来那么你是否好奇它是如何实现的最近工作中也遇到这样类似的需求刚开始打算使用echarts的日历坐标系但demo测试下来结果不尽人意除了配置麻烦自定义自由度不够以及对于业务需求支持度也不够因此痛定思痛决定动手手写一个自由度更高的组件。而且对于后端数据结构要求很低除了能展示近一年数据还能自定义时间范围有需要的小伙伴可以直接查看源码https://gitee.com/fcli/vue-calendar-map.git 
话不多说先上实现效果图 
布局结构 
本组件主要分为三个部分 1最左侧展示周一至周日部分,每周开始时间从周日或周一开始可自定义修改 
div classweeksdiv classweek周一/divdiv classweek周二/divdiv classweek周三/divdiv classweek周四/divdiv classweek周五/divdiv classweek周六/divdiv classweek周日/div
/div2每一列表示一周的始末时间使用el-tooltip悬浮展示具体时间需要的可以自定义修改展示内容和样式 
div classcolumn v-for(columnData, columnIndex) in allDateData :keycolumnIndexdiv classmy-title{{ columnData.title }}/divdiv classdate-wrapper v-for(dateItem, dateIndex) in columnData.data :keydateIndex:style{ background: getColor(dateItem.number).color }:class{ hiddenDate: (columnIndex  0  dateIndex  prevTodayWeek - 1), active: getColor(dateItem.number).level  hoverLevel }el-tooltip classbox-item effectdark :contentdateItem.date placementtopdiv classdate/div/el-tooltip/div
/div3贡献图例可自定义实现点击筛选等功能 div classoperationdiv classlegenddiv classlevel-desc少/divdiv classlevel level-1 mouseoverhoverLevel  i mouseouthoverLevel  0 v-fori in 5 :keyi:class[level-  i]/divdiv classlevel-desc多/div/div
/div具体实现 
1、首先计算和获取上一年的时间以及是星期几我这里采用dayjs来获取。计算上年今日最接近的周一的时间该时间为起始时间。 // 上年今日
let prevToday  dayjs().subtract(1, year).format(YYYY-MM-DD)
// 上年今日的是星期几,dayjs获取的为0-60是星期日
let prevTodayWeekNum  dayjs(prevToday).format(d) || 7;
prevTodayWeek.value  prevTodayWeekNum;
// 初始日期上年临近的星期一
let firstMondayDate 
prevTodayWeekNum  1? dayjs().subtract(1, year).subtract(prevTodayWeekNum - 1, days).format(YYYY-MM-DD): prevToday; 
2、计算从开始时间到结束时间之间有多少个周计算列数 // 初始日期至今日的天数包括今日
let days  dayjs().diff(dayjs(firstMondayDate), days)  1;
// 每周天数
let columns  7;
// 最大列数周数
let lineNums  Math.ceil(days / columns);3、绘制图表数据判断月份需要展示的位置,可往dateData中自定义添加需要的数据字段。第一列直接根据第一天的月份之后的每列数根据上一周的最后一天减去第一天的月份如果大于1代表月份发生了改变下一列的title显示最新的月份。 // 绘制图表的源数据let dateData: any  [];let monthCN  [一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月];for (let i  0; i  lineNums; i) {// 最近一星期不一定满的let weekColumn  i  lineNums - 1 ? (days % columns ? days % columns : columns) : columns;// 开始计算title月份的图例let theWeekStartMonth  dayjs(firstMondayDate).add(i * 7, days).format(M);let day  dayjs(firstMondayDate).add(i * 7, days).format(DD);//防止开始时月份挤在一起if (i  0  30 - day  15) {theWeekStartMonth  theWeekStartMonth  1;}let theWeekEndMonth  dayjs(firstMondayDate).add(i * 7  weekColumn, days).format(M);let title  i  0 ? monthCN[theWeekStartMonth - 1] : ;let isSwitchMonth  false;if (theWeekEndMonth - theWeekStartMonth) {isSwitchMonth  true;}if (i  dateData[i - 1].isSwitchMonth) {title  monthCN[theWeekEndMonth - 1];}// 图表源数据格式columns列数title列标题isSwitchMonth月份是否发生改变data每格数据dateData.push({columns: weekColumn,title: title,isSwitchMonth: isSwitchMonth,data: []});for (let j  0; j  dateData[i].columns; j) {let date  dayjs(firstMondayDate).add(i * 7  j, days).format(YYYY-MM-DD);// 提交次数在slider范围内再进行次数赋值let number  submissionRecord.value[date];// number提交次数date提交日期dateData[i].data.push({number: number,date: date});}}4根据活跃度或数据量展示不同节点的背景颜色 
const getColor  (number: number)  {let num  number / props.maxData;let level  1;if (num  0) {num  0.1;level  1} else if (num  0  num  0.3) {num  0.3;level  2} else if (num  0.3  num  0.6) {num  0.6;level  3} else if (num  0.9) {num  0.8;level  4} else {num  1;level  5}if (props.maxData  0) {num  0.1;level  1}return { color: rgba(55,126,259,  num  ), level };
}5监听数据的变化动态响应更新组件数据 watch(()  props.timeData, (newValue)  {submissionRecord.value  newValue;init();}, { immediate: true, deep: true })使用示例 
已经打包上传npm有需要的小伙伴可以直接安装使用如果需要自定义修改组件内容可访问git源码自行修改。git地址https://gitee.com/fcli/vue-calendar-map.git 
npm install fcli/vue-calendar-map --save-dev 来安装在项目中使用
import VueCalendarMap from fcli/vue-calendar-map;
const appcreateApp(App)
app.use(VueCalendarMap); 
测试demo 
templatediv classcontentvue-calendar-map :timeDatatimeData :maxDatamaxData/vue-calendar-map/div
/templatescript setup langts
import dayjs from dayjs;
import VueCalendarMap from ./plugin/index.vue;
import {ref} from vue;
components:{VueCalendarMap
}
const maxDataref(190);
const timeDatarefany({})
let tempDate:any{}
for(let i0;i366;i){let datedayjs().subtract(1, year).add(i, days).format(YYYY-MM-DD)tempDate[date](Math.random() * 200).toFixed(0);
}
timeData.valuetempDate;
/script 
参数说明 
属性属性名称类型可选值timeData日期和数量对应对象Object{}maxData最大值Number0 
最后 
本人长期分享一些实用干货和学习总结之类的开源技术文章欢迎有需要的小伙伴点赞收藏和点个关注。